Добавлен , опубликован

Что это?

cJass - это еще одно расширение языка JASS, которое полностью совместимо с популярным vJass. Цель его создания - дать программистам еще больше возможностей по созданию простого и качественного кода. Основными направлениями являются:
  1. Макросредства и стандартная библиотека - избавляют от рутины, позволяя сконцентрироваться на основном коде.
  2. Упрощение синтаксиса - мы не хотим снова начинать спор, какой синтаксис лучше (блоки через begin & end или {}), и более того, мы не навязываем свою точку зрения - все конструкции cJass имеют JASS-style аналоги, тем не менее мы предоставляем выбор.
  3. Оптимизация карты - основная концепция cJass - это то, что все языковые конструкции не должны сказываться на качестве генерируемого кода. Также мы работаем над встроенным оптимизатором.

Как это использовать?

Просто скачайте дистрибутив (пароль для архива: cjass), распакуйте и запустите инсталлятор. У вас уже должен быть установлен Jass New Gen Pack.
Ознакомиться с возможностями можно, прочитав руководство пользователя cJass (off-line версия этого файла также имеется в директории программы).

Что-то не работает!

В настоящий момент мы активно дополняем язык всевозможными конструкциями, поэтому полноценная проверка синтаксиса пока отсутствует. Но мы всегда внимательно изучаем
bug-репорты, которые можно оставить в этой теме.

У меня есть идея: а не плохо бы...

Мы всегда рады выслушать Ваши идеи и предложения по внесению каких либо новых возможностей в язык, расширению стандартной библиотеки и т.д. Иногда мы даже действительно делаем то, что Вы нам предлагаете ;) Наша секция обратной связи ждет Вас!
И напоследок немного истории.
А история программы начинается на ресурсе wc3c.net, когда Vexorian, выслушав предложение от ADOLF'a сделать инструкции инкремента и декремента создает ветку с обсуждением синтаксиса... и благополучно забывает об этом. Тогда ADOLF подумал: "А неплохо было бы сделать свой парсер и включить в него всяких вкусностей". Изначально программа весила меньше заветных 9000 байт, распространялась по сети ICQ/Jabber и ее использовали несколько человек.
Однажды один из ее пользователей - Van Damm (впоследствии стал соавтором) сказал "это очень удобно!" (это было сказано про то, что можно вызывать функции без ключевого слова call) - и тогда мы решили, что если это удобно, почему бы не выложить программу на публичное обозрение. Благодаря zibade у нас появился сайт, где сразу стал отписываться Dark Dragon, который помог выявить львиную долю багов и внес множество интересных предложений.
С тех пор прошло много времени, мы сделали много новых версий, вес программы вырос в 3 раза (сейчас 26 Кбайт). На данный момент у нас есть планы, касающиеся многих конструкций, оптимизатора, и всего прочего.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
23
14 лет назад
0
[b]xpadd91[/b], ну ты трололо.
вируса там никакого нет, ставь спокойно
0
17
14 лет назад
0
BK.Jugg, Я не хочу испорчено комп.Больше троян Результат: 15/41 (36.59%)
Лаборатории вирус нашли уже прошло месяц.
0
37
14 лет назад
0
Ну сиди со своим антивирусом...
0
25
14 лет назад
0
Все содержимое архиво абсолютно безвредно
Это просто изза типа программы
0
30
14 лет назад
0
xpadd91, вы таки можете перечитать 15 страниц темы и убедиться, что вируса нет. На какой-то из них Адольф объяснил почему антивирус так реагирует.
0
35
14 лет назад
0
txt2:""
int GetIncInt (unit u, int i) { i+=GetHeroLevel(u); return i*0x02+i*0x03+i*0x04 }
Как это записать через дефайн, чтобы получить:
i=0x00
if (defineName(i)>0x00) { /*super duper code*/ }
""
Зевс добавил:
Вобщем опять краш и опять карту снесло... фиксите!
Зевс добавил:
Просто слов нет... столько проделанной работы и все впустую! >[ Сделайте принудительный бэкап хотя бы
0
22
14 лет назад
0
xpadd91, дело в автапдейтере,он качает новую версию программы(.exe файл) и антивирусник считает его вирусом,спи спокойно - он не опасен,можешь добавить в список исключений
0
30
14 лет назад
0
#define GetIncInt(u,i) {
	i+=GetHeroLevel(u)
	return i*0x02+i*0x03+i*0x04 }
}
Так не катит?
0
35
14 лет назад
0
И он переведет...
if (i=i+GetHeroLevel(u)
   return i*0x02+i*0x03+i*0x04) then
 /*super duper code*/
endif
...ошибка синтаксиса
0
37
14 лет назад
0
рофл, только функцией, что ты хочешь?) это всеравно надо инкрементить както, а внутри проверки джасс это делать не умеет. не надо усложнять то, что не стоит усложнять
0
18
14 лет назад
0
[code]define TriggerRegisterAnyUnitEventBJ(t,e)=
{
int i=0
do
{
TriggerRegisterPlayerUnitEvent(t,Player(i),e,null)
}whilenot(++i==16)
}[/code]Превращается в вот такой замечательный код:[code]function InitTrig_Sword takes nothing returns nothing
set SomeTrig=CreateTrigger()
call integer i=0 ололо
loop
call TriggerRegisterPlayerUnitEvent(SomeTrig,Player(i),EVENT_PLAYER_UNIT_PICKUP_ITEM,null
set i=i+1
exitwhen (i==16)
endloop
call TriggerAddCondition(SomeTrig,Condition(function Trig_Sword_Conditions))
call TriggerAddAction(SomeTrig,function Trig_Sword_Actions)
endfunction[/code]
0
22
14 лет назад
0
решил попробывать такой код(для себя просто)
define begin = {
define end = }
и
define <begin> = {
define <end> = }
не помогло,ошибка,есть ли какой-то способ(без перекомпиляции)сделать так,как написано выше?
0
35
14 лет назад
0
Nekit1234007,
Старо как мир)
Кстати зачем do когда можно сразу писать whilenot...
0
18
14 лет назад
0
[b]Зевс[/b], если сразу вайлнот писать, как я пишу, то нулевого регистрировать не будет.
2 комментария удалено
0
37
14 лет назад
0
у ду проверка в конце
Этот комментарий удален
0
19
14 лет назад
0
txt2:narayan атакует 14 новыми идеями(искренне надеюсь что новыми=)). Плюс потренировался с новыми тегами. Интересно узнать мнения лично Адольфа (который вероятно находиться в ShadowZone( и уже давно =( ))

1 .__​Typecasting__

Выражаясь простым языком (язык блондинок =D) эта переменная которая являеться как бы хранилищем кучи переменных (т.е в итоге одна переменная разбиваеться на типы, которые присутствуют в функции(карте)). Проще смотреть пример -> их я сделал как можно более простые и понятные.
example [cJass]:
   var a[]
   a[0]="narayan ownz"
   a[5000]=345
   a[5]=CreateUnit(Player(15),'ewsp',0,0,0)
Трансформируеться эта небольшая кучка кода, вот в такой мусор.
example [Jass]:
 local string  array string_a
 local integer array integer_a
 local unit    array unit_a   
 set string_a[0]="narayan ownz"
 set integer_a[5000]=345
 set unit_a[5]=CreateUnit(Player(15),'ewsp',0,0,0)
Теперь немного расширим возможности нашего тайпкаста, поближе к дефолту.
Хочу заметить что Vexorian реализовал некое подобие тайпкаста у себя в vJass
example [Vexorian Type Cast]:

 struct test
 
 static method create takes string key returns thistype
  return thistype(-StringHash(key)) // Сопсно тайпкаст one
 endmethod
 
 static method createA takes thistype key returns integer
  return integer(key) // и two
 endmethod
 
 endstruct
А это мой пример создания тайпкаста в АдикХелпере.
exapmle [cJass]:
 void temp(){
  string s1 = "33.33"
  real f = real(s1)
 
  string s2 = "true"
  boolean b = boolean(s2)
 
  string s = "2z4"
  integer i = integer(s)
 }
Вот тут есть нюансы, так как мы изначально не имеем функции B2I , I2B , B2S , S2B => То нам придеться сделать их самим =). В общем смотрим пример ниже.
example [Jass]:
 function cjparser_b2i takes boolean b returns integer
  if b then
   return 1
  endif
  return 0
 endfunction
 
 function cjparser_i2b takes integer i returns boolean
  return i!=0
 endfunction

 function cjparser_b2s takes boolean b returns string
  if b then
   return "true"
  endif
  return "false"
 endfunction
 
 function cjparser_s2b takes string s returns boolean
  if s=="true" then
   return true
  endif
  return false
 endfunction
 
 function temp takes nothing returns nothing
  string s1 = "33.33"
  real   f  = S2R(s1)
 
  string s2 = "true"
  boolean b = cjparser_s2b(s2)
 
  string s = "2z4"
  integer i = I2S(s)
 endfunction
Кстати если будет нужный полный пакет функций то я могу легко его составить.

2 .__Clone__

Метод клонировшика, как бы "сшивает" две функции вместе (взят с Java). Объяснять довольно сложно, покажу примером.
expample[cJass]:
 int a = 0
 int b = clone(a)
 
 str c[]
 str d[] = clone(c)
 
 c[0] = "temp"
 
 a = 100
 
 b = 50
 
 b = decapsulation(a)
 
 a = 1000
(decapsulation можно заменить unset)
После чего это все видоизменяеться в
example [Jass]:
integer a = 0
integer b = 0

string array c
string array d
// Как бы клонируються переменные по ходу кода.
set c[0] = "temp"
set d[0] = "temp"

set a=100
set b=100
// Как видим b можно ставить отдельно, a при этом не страдает.
set b=50
// прошла декапсуляция, т.е b  не синхронизируеться с a
// а значит не клонируеться более.
set a=1000
Где это удобно юзать? Ну тут как бы есть очень много вещей где я бы мог использовать (в моей текущей наработке с ДгуИ например 0.0)

3 .__instanceof__

Данный метод будет невероятно удобен в использовании статичных ифов или #if. Смотрим примеры.
example[cJass]:
 struct temp{}
 
 struct lx extends temp{}
 
 lx this = lx.create
 boolean b = (lx instanceof struct)
 b = (lx instanceof temp)
 b = (lx instanceof lx)
 b = (lx instanceof string)

 #if b
  lx = "Ya stroka"
 #else
  lx = 1
 #endif
Конвертим код, и после парсера выдает.
example[Jass]:
 struct temp
 endstruct
 
 struct lx extends temp
 endstruct

 local lx this = lx.create()
 local boolean b = true
 set b = true
 set b = true
 set b = false
 set lx= 1

4 *.__Conditional Expression__

Данный тип построения функции по моему "впечатляющий", и достаточно быстрый (плюс смотриться красиво)
example [cJass]:
string s = (3<5?"sex":"mex")
string s2 = (s!="sex"?"vox":"dox")
Что преобразуеться в такую конструкцию. Т.Е s = "sex" ; s2 = "dox"
example [Jass]:
string s
string s2
if 3<5 then
 set s = "sex"
else
 set s = "mex"
endif
if s!= "sex" then
 set s2="vox"
else
 set s2="dox"
endif

5 .__Усиленный массивчег__

Поддержка массивом не только целочисленных, но и прочих типов
example[cJass]:
  unit u=CreateUnit()
  int a[]
  a["x"]=0
  a["xx"]=1
  a[u]=2
example[Jass]:
local unit u=CreateUnit()
local integer array a
set a[Modulo(StringHash("x"),8190)]=0
set a[Modulo(StringHash("xx"),8190)]=1
set a[Modulo(GetHandleId(u),8190)]=2

// Кстати величина цифер может быть большой поэтому можно и под Модуло, если цифр больше 3
Кстати было бы удобно если бы можно было составлять такие дефайны
example[define]

typedef<x[type]='value'>={
 #if type = handle
  x[GetHandleId(type)-0x100000] = value
 #elseif type = integer
  x[type] = value
 #elseif type = string
  x[Modulo(StringHash(type),8190)] = value
 #elseif type = real
  x[R2I(type)] = value
 #endif
}
typedef -> как бы указывает что у нас дефайн проверяет типы, ну в общем просто для красоты =)).

6 .__continue__

О да, я нашел способ реализовать это. Т.Е теперь это возможно и в вк3 =) (а VD не догадывался что это реально(вспоминая наш разговор))
example[cJass]:
whinenot(++i>10){
 if i == 5{continue}
 else{BJDebugMsg("not 5")}
}
Если мы имеем continue у себя в лупе, то луп принимает очень сложную "двойную" так скажем конструкцию. Кстати это невероятно удобно =), плюс добавляет новую фичу с С++ синтаксиса.
example[Jass]:
loop
 set cjparse_continue = true
 loop
  set i=i+1
  exitwhen i>10
  if i == 5 then
   set cjparse_continue = false
   exitwhen true
  else
   call BJDebugMsg("not 5")
  endif
 endloop
 exitwhen cjparse_continue
endloop

7 .__array size__

Фича надстрощик на vJass, берет длинну нашего массива.
example[cJass]:
int x[][20000]
void temp(){
 int z = array(x)
}
Это удобно при составлении кода (например в наработках. Вы написали систему, и в ней можно варьировать размер массива, ну собственно тут и пригодиться)
example[Jass]:
globals
 constant integer size_cjparser_x=20000
 integer array x[size_cjparser_x]
endglobals

function temp takes nothing returns nothing
 local integer z = size_cjparser_x
endfunction
Кстати для страктов и приватных можно добавлять суффиксы соответствующие классу записи =).

8 .__​Typerestricted__

Как бы то же что и тайпкаст, только мы сами указываем типы. (Переменные могут иметь одно и тоже имя, но обязательно разные классы)
example[cJass]:
 array<int,string> a
 <int,bool,unit> b=nill
 array<int,int>a // Ошибка так как нельзя чтобы два однотипичных значения могли иметь одно имя. Парсер просто должен выдавать ошибку
example[Jass]:
 globals
  integer array integer_a
  string  array string_a
  // Так как данные обнулены изначально, то и тут они будут обнулены.
  integer integer_b=0
  boolean boolean_b=false
  unit    unit_b   =null
 endglobals

9 .__namespaces__

Обработчик имен. Т.Е обрабатывает переменные тайпкаста только по их имени.
example[cJass]:
 var a[]
 a[1]="xd"
 a[1]=115.0
 a[2]=11
 a[15]=true
 a[4]="omg"
 namespace a{
  BJDebugMsg(1)
  BJDebugMsg(4)
  BJDebugMsg(15)
 }
example[Jass]:
 local string  array string_a
 local real    array real_a
 local integer array integer_a
 local boolean array boolean_a
 set string_a [1]="xd"
 set real_a   [1]=111.5
 set integer_a[2]=11
 set boolean_a[15]=true
 set string_a [4]="omg"
 //namespace -> запускает все именные функции, и берет ячейку из массива указанную в полях
 call BJDebugMsg(string_a [1])   // ==> BJDebugMsg(1)
 call BJDebugMsg(R2S(real_a[1])) // ==> BJDebugMsg(1)
 call BJDebugMsg(string_a [4])   // ==> BJDebugMsg(4)
 call BJDebugMsg(cjparser_b2s(boolean_a[15]))   // ==> BJDebugMsg(15)
 // endnamespaces

10 .__package__

Данная фича пришла в голову ну случайно =). Собственно сысл заключаеться в том чтобы упаковывать файлы в спецовые WTS файлы(да это увеличит время загрузки зато, без десинков можно делать перевод)
Итак как работает данная система.
Example[cJass]:
package eng{
 STRING_HASH = "My mother say"
}
package rus{
 STRING_HASH = "Моя мама сказала"
}
package ger{
 STRING_HASH = "Githler CAPUT!"
}

void temp(){
 BJDebugMsg(STRING_HASH)
}
Что происходит с package? Она тупо записываються в WTS файлы с указанным именем. В то время как выглядит наша функция в норм версии.
Example[Jass]:
 function temp takes nothing returns nothing
  call BJDebugMsg(GetLocalizedString("STRING_HASH"))
 endfunction
Кстати имена пакетов должны быть строго задекларированы, ну т.е количество версий должно быть строго ограничено т.к количество языков ограничено
Кстати это работает на локальных компах, и удобно в том числе и с юнитами. Т.е я помню ADOLF хотел сделать некий редактор импорта, так вот, советую сделать такого типа фичу как =>
example[cJass]:
abstract package('hfoo') eng{
 name = "Footman"
 tooltipbase = "Human rulzz"
}
abstract package('hfoo') rus{
 name = "Пехотинец"
 tooltipbase = "Хуманы жрут водку"
}

abstract package(mapHandle) eng{
 name = "DotA:AllStars 5000"
 description= "5000 heroes"
}
abstract package(mapHandle) rus{
 name = "ЗнД:Все Звезды 5000"
 description= "5000 героев"
}
Из примера видно,как мы можем использовать "Абстрактный Запаковщик", хотя он использует совсем не абстрактные данные 0.о => т.е записывает в требуемые файлы нужную нам строку.
Бедного футмана, записывают в файл unitData и данный файл клонируют на несколько, учитывая количество переводиммых языков. (т.е самая сложная часть), а вот с мэпхендлом записывает тоже в WTS файл, так как это все в файле конфига обнародуеться (как бы возможно тоже GetLocalizedString)
mapHandle кстати => Берет саму карту, и работает с ней. Имя карты, её дескрипшн (более всроде нечего локализить, ну если только кнопки интерфеса =) аля ДиалогБатоны, но это отдельная история)

11 .__love​My​Magic__

Я люблю красивый код, поэтому хотелось бы предложить такую фичу как класс. Конечно она не будет выполнять предназначеных ему функции (т.е название я тупо взял с Явы можно и переименовать). Фича нам дает небольшое улучшение кодинга.
example[cJass]:
class vector={
 real x
 real y
 real z
}

// Хочу заметить что данные не МАССИВ!!!!

void temp(){
 vector.x=0
 vector.y=0
 vector.z=0
}
Собственно все. Мне так просто удобнее даже программировать (ну т.е я не люблю такой вид записи как IsVisible или Is_Visible Для меня is.visible смотрится нагляднее). Как вариант еще можно заценить такой пример.
example[cJass]:
class is={
 bool visible=false
 bool detected=false
 bool dummy=false

 class not={
  bool created=false
  bool destroy=false
 }

}

void temp(){
 if is.not.created{createTemp()}
 if is.dummy{is.visible=false}
 destroyTemp()
 if is.not.destroy{is.detected=true}
 if is.detected{echo("Чит детектед!")}
}
Отличаеться от стракта тем, что не создает аллокаторов, делокаторов т.е вообще только объявление переменных, но от страктов можно взять такую часть как extends 0.o выглядит это примерно так.
example[cJass]:
class is={
 bool visible=false
 bool detected=false
 bool dummy=false
}
class not extends is={
 bool created=false
 bool destroy=false
}
void temp(){
 if is.not.created{createTemp()}
 if is.dummy{is.visible=false}
 destroyTemp()
 if is.not.destroy{is.detected=true}
 if is.detected{echo("Чит детектед!")}
}

12__inline__

То же что и си.
example[cJass]:
int  size = 0
bool temp = inline PerfectI2B(){return true}

void temp()
{
	if temp
	{
	    ForGroup(CreateGroup(),inline GetSize(size++))
	}
	else
	{
	    ForGroup(CreateGroup(),inline DecSize(size--))
	}
} 
Компилятор процеживает всю эту кашу в.
example[Jass]:
//! file in common.j (файл обновился и добавился в импорт)
//! в файл common.j заносяться лишь те функции которые объявлены глобалками!!!!
//! остальная же котовасия как парситься смотрим ниже
function inline_PerfectI2B takes nothing returns boolean
    return true
endfunction
//! end  in common.j

globals
 integer size = 0
 boolean temp = inline_PerfectI2B() // inline PerfectI2B -> function Moving to our common.j file!!!!!
endglobals

function inline_GetSize takes nothing returns nothing
    set size = size + 1
endfunction

function inline_DecSize takes nothing returns nothing
    set size = size - 1
endfunction

function temp takes nothing returns nothing
	if temp then
	    call ForGroup(CreateGroup(),function inline_GetSize)
	else
	    call ForGroup(CreateGroup(),function inline_DecSize)
	endif
endfunction
Теперь объясню что наш инлайн, не может брать никакие данные, и возвращает он тоже ничто =), но! он может как бы использовать
такие вещи как возвращение чего либо!!! если находиться внутри переменной. Т.Е если bool b = inline => то возвращает булевую
, если реальная, то реальную.
<<
13.__Struct__
Теперь улучшаем структуры! Т.Е мы можем делать дочерние структуры более простым методом. Сейчас покажу на примере
>> example[cJass]:
struct parent
{
    struct childA
	{
	    struct childC
		{
		}
	}
	struct childB
	{
	}
}
Такая вот котовасия перепарситься в более простую вещь.
example[vJass]:
struct parent
endstruct
struct childA extends parent
endstruct
struct childC extends childA
endstruct
struct childB extends parent
endstruct
В итоге мы получаем вполне нормальный код. Т.Е такое действие будет сделать не так уж и трудно.

14 __​Perfect​Name?__

Сомнительная фича которая добавляет перцу к страктам
example[cJass]:
struct
{
 float x
 float y
} perfectstruct;superstack;vector
example[vJass]:
struct perfectstruct
real x
real y
endstruct
struct superstack
real x
real y
endstruct
struct vector
real x
real y
endstruct
Собственно все. Интересно мнения ADOLF`a насчет всех этих идей.
ЗЫ: В ближайшее время предложу еще пару идеи, пока осмысливаю как бы их лучше реализовать, да и хотелось чтобы автор реагировал на них (хотя вероятно у него проблемы ин реал лайф)
Да... Хреново у тебя с новым форматированием... ©VD
0
19
14 лет назад
0
  1. По первому примеру сразу скажу, что нельзя: парсер [b]не[/b] различает типы переменных.
  2. [i]ИМХО[/i], вручную куда удобнее.
  3. Good idea.
  4. Аналогично с #3.
  5. Делается через дефайны, имхо.
  6. Ничего не понял о_О [off]//Но мб это и только мои проблемы :р[/off]
  7. Кодер сам должен знать все свои "размеры", зОМГ.
  8. ======> #1
  9. ======> #1
  10. [style=onine]5/10[/style]
  11. Поправь меня, если я ошибаюсь, но это, вроде, уже и так есть в vJass.
  12. haxyn...
  13. А вот это достойная идея.
  14. Можно, но глупо, имхо.
[off]Все перечисленное выше является [b]личным мнением[/b] товарища [b]FREEZE_ball[/b]а и может никоим образом не совпадать с мнением товарища автора поста, с мнением вышеуказанного товарища автора [b]cJass[/b]а и прочих товарищей авторов. Я предупредил!..[/off]
0
35
14 лет назад
0
define <cjSF_kickPlayer> (p, m, sp) = { /*Крутой код*/ }
 ...
 player p = GetTriggerPlayer()
 string m = "blah blah"
 сjSF_kickPlayer(p,m,"import\\amb\\PlayerKicked.wav")
 ...
В итоге Critical Error: Bad Char (&#209;)... это происходит даже если закоментить весь код в дефайне cjSF_kickPlayer.
Зевс добавил:
Проблема решена... скопировал дефайн и вставил по-новой <<
2 комментария удалено
0
28
14 лет назад
0
[b]Зевс[/b], ты не юзаеш руссгих букв ? =)
0
15
14 лет назад
0
Гуляя по помойке хива, увидел тему про cjass, прошёл по ссылке и:
ответ: "дело в автапдейтере,он качает новую версию программы(.exe файл) (посты выше) ", видимо принудительный апдейт.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.