ADOLF

cJass - дополнение к языку JASS

» опубликован

Что это?

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 Кбайт). На данный момент у нас есть планы, касающиеся многих конструкций, оптимизатора, и всего прочего.


Просмотров: 84 163



Van Damm #1 - 11 лет назад 0
То, чего все так долго ждали, свершилось!
YellowStar #2 - 11 лет назад 0
Вероятно тут ответят на вопросы старой темы. И желательно узнать насчет предложении -.-
Van Damm #3 - 11 лет назад 0
Только дефайны без скобок, остальное - нет.
Chester #4 - 11 лет назад 0
А будет ли сборка JNGP+CJ+PH ?
спасибо, танкисты, они благодарны
Мануал класный!
Van Damm #5 - 11 лет назад 0
Для тех, кто в танке, напишу большими буквами:
[h2][url=http://cjass.xgm.ru/manual-ru][highlight]Руководство пользователя cJass[/highlight][/url][/h2]
Elf_Stratigo #6 - 11 лет назад 0
bb:гж)
У меня вопрос по области видимости:
если мне нравится пользоваться блоком define /enddefine то куда приписывать private?
Nekit1234007 #7 - 11 лет назад 0
define
    private bla=blabla
enddefine
YellowStar #8 - 11 лет назад 0
Собственно для ленивых. Простенький хук позволяющий не писать нудные обнуления переменных.
Вес файла: около 2 кб.
юзать аттачи религия не позволяет? VD
Sunn #9 - 11 лет назад 0
А так, посмотрим.
[size=1][i]Sunn добавил:[/i][/size]
Даа, ридми кошерен... как и то, о чём там написано.
YellowStar #10 - 11 лет назад 0
Для такого файла я бы использовал атач, но мне выдает что расширения файла не верное (.j)
странно как то. Поэтому я и выложил через ссыль.
DragonSpirit #11 - 11 лет назад 0
narayan, в архив закинь..
если файл .j и весит 2 Кб, то лучше под cut загнать. © swdn
Daemonik #12 - 11 лет назад 0
А что это за файл AHU_selfdel.exe?
При открытии WE мне ошибку выдает.
Это сообщение удалено
Chester #14 - 11 лет назад 0
А что там на счет приравнивания к нулю переменных? Будет ли это, если да то как?
как насчет unit var => !var
Van Damm #15 - 11 лет назад 0
При открытии WE мне ошибку выдает.
все баги с этим были исправлены в тот же день
Будет ли это
не будет
Chester #16 - 11 лет назад 0
По какой причине? И возможно ли это сделать с помощью деф ?
Hellfim #17 - 11 лет назад 0
Chester, возможно, делай. Но это никому не нужно =)
adic3x #18 - 11 лет назад 0
обьясните хоть что?
Hellfim #19 - 11 лет назад 0
ADOLF, что-то типо автообнуления локалок.
adic3x #20 - 11 лет назад 0
ясно, этого небудет)
Chester #21 - 11 лет назад 0
А как это сделать с пом деф?
adic3x #22 - 11 лет назад 0
а чем вам не нравиться обычный вариант set var = null ?
Sebra #23 - 11 лет назад 0
А есть ли в планах преобразование выражений как в сишном препроцессоре? Вроде такого:
s=2*Pi*r => s=r*6.2831...
или такого:
whilenot !(a>b) => loop; exitwhen a<=b
И вообще, как бы заглянуть в ваше "планов громадьЁ"? А то многое, чего хочется, видимо там уже есть. Если чего не найдём - скажем. :)
Van Damm #24 - 11 лет назад 0
Sebra, в планах такое есть, этим будет заниматься оптимизатор.
Elf_Stratigo #25 - 11 лет назад 0
[quote=Sebra]s=2*Pi*r => s=r*6.2831...[/quote]
а разве при загрузке варик не считает константы?
Daemonik #26 - 11 лет назад 0
Варик их считывает только в том случае если ты пишешь bj_PI итд
Van Damm #27 - 11 лет назад 0
а разве при загрузке варик не считает константы?
такое он не считает точно
ScorpioT1000 #28 - 11 лет назад 0
считает я думаю.
Elf_Stratigo #29 - 11 лет назад 0
bb:предлагаю придумать дерективы
private:
public:
ну то есть чтобы не перед каждой функцией, переменной, константой, дефином писать их область видимости, а чтобы сразу разбить всё по сегментам)))
(вроде такого нет, правда?)
Sebra #30 - 11 лет назад 0
такое уже предлагалось - вроде в "тудулист" попало.
Кстати я тут вычитал, что вар спокойно понимает числа вида $34 без замены их на 0x34.
Проверил - игнорит доллар, а 0х работает.
NCrashed #31 - 11 лет назад 0
Ура мануал появился!! Безумно рад, теперь каша в голове систематизируется).
Хотелось бы нормальную подсветку кастом функций
ScorpioT1000 #32 - 11 лет назад 0
всем хотелось бы.. тока для этого надо переписывать хайлайтер) вандам вроде начал. или нет ?
adic3x #33 - 11 лет назад 0
txt2:> Кстати я тут вычитал, что вар спокойно понимает числа вида $34 без замены их на 0x34.
проблемы были толи в хелпере векса, толи в пЖасс
1.4.0.3 уже превращает автоматически $ в числах в 0х
private:
public:
сделаю, только позже
считает я думаю.
вар несчитает константы, я приводил пост на сижассе, сейчас найду его
"прекалькуляция" также планируется, но только для литералов
ADOLF добавил:
» как вар работает с константами (англ.)
Here's the JASS code, which we're going to disassemble:
constant real x = 0.
define xx = 0.
void fx () { real const = x, def = xx }
And here's what operations we've got when the above code is run by the game's JASS interpreter:
08C9E0A0 fx+0000 00 00 05 05 00000eaf CREATE_LOCAL const {real (5)}
08C9E0A8 fx+0008 00 05 68 0e 0000024a MOV_VAR_REG x => #68 {real (5)}
08C9E0B0 fx+0010 00 00 68 11 00000eaf MOV_REG_VAR #68 => const
08C9E0B8 fx+0018 00 00 05 05 00000eb0 CREATE_LOCAL def {real (5)}
08C9E0C0 fx+0020 00 05 69 0c 00000000 MOV_VAL_REG 0 => #69 {real (5)}
08C9E0C8 fx+0028 00 00 69 11 00000eb0 MOV_REG_VAR #69 => def
08C9E0D0 fx+0030 00 00 00 27 00000000 RETURN
08C9E0D8 fx+0038 00 00 00 04 00000000 STUB_FUNC_END
As you see, on line 2 the value is taken from the memory area, corresponding with the constant address and placed to the register (it's in bold text). Then the value in the register assigned to the local variable at line 3.
On line 5, direct value is placed to the register (it's in bold text), and then assigned to the second local variable at line 6.
If to make an example in plain asm, the difference is the same as the difference between these two statements:
mov eax, dword ptr [40000000h] ; address
mov eax, 10h ; value
In the first case, you have to look the memory for the address, then find what value is in that memory area and then move the value to the register.
In the second case, you just move the value to the register - it's much faster.
That's why in cJass defines do direct value substitution.
Van Damm #34 - 11 лет назад 0
txt2:Ничего оно не считает =)
Вот простейшая функция:
function fx takes real r returns real
   return 2*r*bj_PI
endfunction
А вот она дизассемблирована:
0E41D2A8         00 00 05 03  00000e98    STUB_FUNC_BEGIN fx
0E41D2B0 fx+0000 00 01 05 08  00000252    CREATE_LOCAL_FROM_STACK r [1] {real (5)}
0E41D2B8 fx+0008 00 04 c3 0c  00000002    MOV_VAL_REG 2 => #c3 {integer (4)}
0E41D2C0 fx+0010 00 00 c3 17  00000000    #c3 = (float)#c3
0E41D2C8 fx+0018 00 00 c3 13  00000000    PUSH #c3
0E41D2D0 fx+0020 00 05 c4 0e  00000252    MOV_VAR_REG r => #c4 {real (5)}
0E41D2D8 fx+0028 00 00 c5 14  00000000    POP #c5
0E41D2E0 fx+0030 c4 c5 c5 22  00000000    #c5 = #c5 * #c4
0E41D2E8 fx+0038 00 00 c5 13  00000000    PUSH #c5
0E41D2F0 fx+0040 00 05 c6 0e  000007ed    MOV_VAR_REG bj_PI => #c6 {real (5)}
0E41D2F8 fx+0048 00 00 c7 14  00000000    POP #c7
0E41D300 fx+0050 c6 c7 c7 22  00000000    #c7 = #c7 * #c6
0E41D308 fx+0058 00 c7 00 0d  00000000    MOV_REG_REG #c7 => #00
0E41D310 fx+0060 00 00 00 27  00000000    RETURN
0E41D318 fx+0068 00 00 00 27  00000000    RETURN
0E41D320 fx+0070 00 00 00 04  00000000    STUB_FUNC_END
откуда ясно видно, что вар просто считает всё подряд =)
adic3x #35 - 11 лет назад 0
ну это все правильно - в ситуации когда вар обрабатывает весь скрипт при выборе карты самое важно скорость этой обработки, и офк ни о какой оптимизации не может быть и речи
Sunn #36 - 11 лет назад 0
[quote=cJass readme][code] function test takes integer num, integer pow returns integer
integer res = 1, i = 0
whilenot (i++ >= pow) {
res *= num
}
return res
endfunction
что транслируется в следующее:
function test takes integer num, integer pow returns integer
local integer res = 1
local integer i = 0
loop
exitwhen (i >= pow)
set i = i + 1
set res = res * num
endloop
return res
endfunction[/code][/quote]
мне кажется, что следует поставить инкремент счетчика цикла в конец его действий, т.к. если мы по счетчику забиваем массив то пропадает нулевой элемент.
adic3x #37 - 11 лет назад 0
Sunn, нет, для забивания массива (например) просто используется другой цикл - do {} whilenot (expr)
читайте рид ми внимательнее
Sebra #38 - 11 лет назад 0
Sunn, Да какая разница, для чего и что мы используем?
Препроцессор cJass получил однозначную команду: посчитать условие и увеличить i.
i должно быть увеличено сразу после вычисления условия, а не там, где кому-то хочется.
Кстати, ADOLF, при невыполнении условия i тоже надо увеличивать! Это ошибка в справке?
Elf_Stratigo #39 - 11 лет назад 0
[code]define HASHTABLETYPE = 0 0=no hash 1=have
define hash = name
library System initializer init
define
{
private void=nothing
private int=integer
private bool=boolean
}
#if HASHTABLETYPE==0
hashtable HashTable=InitHashtable()
setdef hash = HashTable
#endif
void init()
{
hash=hash
}
endlibrary[/code]
почемуто условная трансляция не работает(
п.с. что я садист - можно не сообщать)
adic3x #40 - 11 лет назад 0
при невыполнении условия i тоже надо увеличивать! Это ошибка в справке?
нет... мда, баг. буду фиксить. т.е. постиксный инкремент в инструкции exitwhen должен обрабатывать аналогично ему же в инструкции if
ADOLF добавил:
Elf_Stratigo, у меня сохранило все правильно, поясните подробнее, что именно неработает
Sebra #41 - 11 лет назад 0
Конечно, ветвление же.
Кстати, а почему отказался от варианта i++ => (++i-1) ?
adic3x #42 - 11 лет назад 0
что бы два инкремента одной переменной в обычной инструкции и в подобной работали одинаково
Sebra #43 - 11 лет назад 0
То есть для того, чтобы всегда --i==i-- ?
:)
Elf_Stratigo #44 - 11 лет назад 0
после трансляции получаю код, в котором не убраны директивы условной трансляции:
[code]globals
globals from System:
#if 0==0
hashtable HashTable=InitHashtable()
#endif
endglobals from System
trigger gg_trg_____________________________________001=null
trigger l__library_init
endglobals[/code]
может у меня не последняя версия - есть какойто способ узнать версию AdicHelper?
такто я для уверенности несколько раз позапускал AHupdate.exe - результат - окошко "cJass is up to date."
Van Damm #45 - 11 лет назад 0
Версия показывается если нажать "About AdicHelper" в меню.
У меня твой код работает отлично.
Elf_Stratigo #46 - 11 лет назад 0
bb:если установка "старого образца" меню нету))
ок, переставлю через инсталятор...
adic3x #47 - 11 лет назад 0
эээ, у вас очевидно очень старая версия, раз нет меню...
NCrashed #48 - 11 лет назад 0
возможно, чтобы можно было приват ставить целому блоку дефайна, или хотя бы чтобы асид при этом ошибку выдавал а не вис намертво:
define private { 
    void = nothing
}
NCrashed добавил:
это так, предложение для следующих версий
adic3x #49 - 11 лет назад 0
уф, кто знает. как минимум я сделаю защиту - что бы он говорил что синтаксис еррор
Nekit1234007 #50 - 11 лет назад 0
Есть предложение для оптимизатора, если НЕ используется InitTrig_%trigname% или функция используется не для создания триггера, то удалять gg_trg_%trigname% из глобалок.