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

Что это?

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 Кбайт). На данный момент у нас есть планы, касающиеся многих конструкций, оптимизатора, и всего прочего.
`
ОЖИДАНИЕ РЕКЛАМЫ...
23
[b]xpadd91[/b], ну ты трололо.
вируса там никакого нет, ставь спокойно
17
BK.Jugg, Я не хочу испорчено комп.Больше троян Результат: 15/41 (36.59%)
Лаборатории вирус нашли уже прошло месяц.
38
Ну сиди со своим антивирусом...
25
Все содержимое архиво абсолютно безвредно
Это просто изза типа программы
31
xpadd91, вы таки можете перечитать 15 страниц темы и убедиться, что вируса нет. На какой-то из них Адольф объяснил почему антивирус так реагирует.
35
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*/ }
""
Зевс добавил:
Вобщем опять краш и опять карту снесло... фиксите!
Зевс добавил:
Просто слов нет... столько проделанной работы и все впустую! >[ Сделайте принудительный бэкап хотя бы
22
xpadd91, дело в автапдейтере,он качает новую версию программы(.exe файл) и антивирусник считает его вирусом,спи спокойно - он не опасен,можешь добавить в список исключений
31
#define GetIncInt(u,i) {
	i+=GetHeroLevel(u)
	return i*0x02+i*0x03+i*0x04 }
}
Так не катит?
35
И он переведет...
if (i=i+GetHeroLevel(u)
   return i*0x02+i*0x03+i*0x04) then
 /*super duper code*/
endif
...ошибка синтаксиса
38
рофл, только функцией, что ты хочешь?) это всеравно надо инкрементить както, а внутри проверки джасс это делать не умеет. не надо усложнять то, что не стоит усложнять
18
[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]
22
решил попробывать такой код(для себя просто)
define begin = {
define end = }
и
define <begin> = {
define <end> = }
не помогло,ошибка,есть ли какой-то способ(без перекомпиляции)сделать так,как написано выше?
35
Nekit1234007,
Старо как мир)
Кстати зачем do когда можно сразу писать whilenot...
18
[b]Зевс[/b], если сразу вайлнот писать, как я пишу, то нулевого регистрировать не будет.
2 комментария удалено
38
у ду проверка в конце
Этот комментарий удален
19
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
19
  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]
35
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 комментария удалено
15
Гуляя по помойке хива, увидел тему про cjass, прошёл по ссылке и:
ответ: "дело в автапдейтере,он качает новую версию программы(.exe файл) (посты выше) ", видимо принудительный апдейт.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.