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

Что это?

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 Кбайт). На данный момент у нас есть планы, касающиеся многих конструкций, оптимизатора, и всего прочего.
`
ОЖИДАНИЕ РЕКЛАМЫ...
18
Это очень печально, т.к. не импонирует лицезреть мусор, в виде стандартных аллокаторов вжасса.
3
Подскажите как будет выглядить триггер на сJass

Событие: юнит исп заклинание.
Условие: Заклинание == "AHtb".
Действие: Сделать ничего.

Действительно нужен пример
Заранее спасибо!
3
Основные принципы
Aidekqz добавил:
Aidekqz:
Событие: юнит исп заклинание.
Условие: Заклинание == "AHtb".
Действие: Сделать ничего.
Кто-нибудь поможет?
18
А что тут помогать, идёшь учишь синтаксис и делаешь. Если ты знаешь как сделать, то что ты просишь, на джассе, то при переделке на сджасс не должно быть проблем.
Этот комментарий удален
18
Готового не даю. Ладно, тогда поступим так, ты даёшь код на джассе, а я тебе его переписываю на сджасс.
Nekit1234007 добавил:
Иначе, дальнейший разговор бесполезен.
3
Вот
function Trig_trignobeone_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'ANsh' ) ) then
        return false
    endif
    return true
endfunction

function Trig_trignobeone_Actions takes nothing returns nothing
    call DoNothing(  )
endfunction

//===========================================================================
function InitTrig_trignobeone takes nothing returns nothing
    set gg_trg_trignobeone = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_trignobeone, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_trignobeone, Condition( function Trig_trignobeone_Conditions ) )
    call TriggerAddAction( gg_trg_trignobeone, function Trig_trignobeone_Actions )
endfunction
18
library Spell initializer Init {
	#include "cj_types.j"

	private void OnCast() {
		DoNothing()
	}

	private void Init() {
		trigger t = CreateTrigger()
		TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
		TriggerAddCondition(t, lambda bool() {
			return GetSpellAbilityId() == 'ANsh'
		})
		TriggerAddAction(t, function OnCast)
	}
}
3
Cпасибо
Aidekqz добавил:
хмм, карта не запускается T_T
18
Версия сджасса должна быть не стабильной, например 1.4.2.14.
31
Извините, что не совсем по теме:
Nekit1234007:
А что тут помогать, идёшь учишь синтаксис и делаешь.
Можешь дать ссылочку ещё на синтаксис vJass
24
как насчет введения механизма аннотаций?
например как-то так:
1: аннотация заменяющая ключевое слово optional
//@optional
void SomeFunc(){


}
а может даже и так:
2: аннотация указывающая препроцессору что в следующей строке он должен искать использование лямбда-функции и желательно с остановкой обработки и выдачей ошибки если не находит
пример использования лямбда-функций от ADOLF переделанный с использованием аннотаций

struct sa {
	nothing f () {
		//@lambda
		code c = nothing () {}
	}
}

struct sb {
	nothing f () {
		//@lambda 2
		code c = nothing () { code c = nothing () { DoNothing() } }
	}
}

nothing main () {
	//@lambda
	code a = integer () { return 0x00 }
	//@lambda
	code b = integer () { return 0x00 }
	//@lambda 2
	code c = code () { return nothing () { DoNothing () } }

}

function config takes nothing returns nothing
	//@lambda
	code c = nothing () {}
endfunction

nothing fx () {
	     //@lambda
	    TimerStart(CreateTimer(), 0., false, void () { DoNothing() } )
}

nothing e (code a, code b) {}
//@lambda 2
nothing test () { e( nothing () {}, nothing () {}) }
первое реализовать не так уж сложно даже на ассемблере, а вот на счет второго не уверен, да и не уверен что оно того стоит
ну и безумная идея напоследок
/*
инициализация шаблона
$func, $begin, $body, $end - места вставки заголовка, начала блока, тела и конца блока функции, соответственно
a,b,c - параметры шаблона и места их вставки
*/
//@template beginend(a,b,c) = $func c $begin a $body b $end

/*
макросы, которые будут использованы в качестве параметров шаблона
*/
define ololo1 = { DoNothing() }
define ololo2 = { DoNothing() ; DoNothing() }
define ololo3 = { integer a }

/*
использование шаблона для преобразования функции
*/
//@template beginend ololo1 ololo2 ololo3
void SomeFunc(){

	//какой-то код

}
преобразуется в
void SomeFunc( ololo3 ){
ololo1

	//какой-то код

ololo2
}
или в
void SomeFunc( integer a ){
DoNothing()

	//какой-то код

DoNothing() ; DoNothing()
}
29
prog, все бред и не нужно + аннотации пишутся без двойного слеша.
хотя про optional в принципе нормально, но не нужно все равно.
24
Doc, я предложил инструмент, а конкретные примеры привел исключительно для наглядности. С ненужностью и бредовостью вполне согласен, хотя от последней конструкции не отказался бы.
P.S. Зачем впилил туда эти слеши сам не знаю.
6
Интересный пост на фидбеке от самого Адольфа

1.4.2.21

+ for and forp loops
+ for loop to pick units
+ reworked locals variables processing
+ /alf flag - automaticle flush locals (without "flush locals" instruction)
+ in functions static variable
+ fixed bug with locals, declared in "static if" block
+ and more in next stable release!
Sample of code:
unit fx () {
    real x, y, r
    unit pal = CreateUnit (Player(0), 'Hpal', 0., 0., 0.)
    for (unit u; UnitsInRange(x, y, r)) {
        KillUnit (u)
    }
    for (unit u; UnitsInRange(x, y, r)) {
        for (unit t; UnitsInRange(x, y, r)) {
            KillUnit (t)
        }
    }
    return pal
}

nothing fx () {
    static int i = 0
    for (int i = 0; i < 16; i++) {}
    forp (int i = 0; i < 16; i++) {}
    for (int i = 0; i < 16) {}
    forp (int i = 0; i < 16) {}
    for (int i = 0) {}
}
Also recommend to edit exehack.lua:
-- cJass#1
have_ah = grim.exists("adichelper\\adichelper.exe")
if have_ah then
	ah_menu = wehack.addmenu("cJass")
	ah_enable = TogMenuEntry:New(ah_menu,"Enable AdicParser",nil,true)
	ah_enableopt = TogMenuEntry:New(ah_menu,"Enable AdicOptimizer",nil,true)

	-- Flags

	wehack.addmenuseparator(ah_menu)

	ah_opt_remove = TogMenuEntry:New(ah_menu,"Remove unused code",nil,true)
	ah_alf_flag = TogMenuEntry:New(ah_menu,"Locals auto flush",nil,true)
	ah_igno_cjbj = TogMenuEntry:New(ah_menu,"Compile for default cj and bj",nil,true)

	-- Game version switch
	wehack.addmenuseparator(ah_menu)

	ah_version = MenuEntryGroup:New(ah_menu,"Game version switch")

	ah_ver23m = SwitchMenuEntry:New(ah_version,"Compile for game version 1.23")
	ah_ver24m = SwitchMenuEntry:New(ah_version,"Compile for game version 1.24+",true)

	-- Updater items

	wehack.addmenuseparator(ah_menu)

	if (grim.getregpair(confregpath,"First launch passed") ~= "yes") then
		ah_firstlaunch = true
	end

	if ah_firstlaunch then
		if (wehack.runprocess2("AdicHelper\\AHupdate.exe /ask") == 6) then
			ah_enableupdate = true
		end

		grim.setregstring(confregpath,"First launch passed","yes")
		if ah_enableupdate then
			grim.setregstring(confregpath,"Enable AutoUpdate","on")
		else
			grim.setregstring(confregpath,"Enable AutoUpdate","off")
		end
	end

	ah_enableupdate = TogMenuEntry:New(ah_menu,"Enable AutoUpdate",nil,false)

	if ah_enableupdate.checked then
		wehack.execprocess("adichelper\\AHupdate.exe /silent")
	end

	ah_update = MenuEntry:New(ah_menu,"Check for updates now", function() wehack.execprocess("adichelper\\AHupdate.exe") end)
	ah_updateopt = MenuEntry:New(ah_menu,"AutoUpdate settings", function() wehack.runprocess2("adichelper\\AHupdate.exe /options") end)

	-- About box

	wehack.addmenuseparator(ah_menu)
	ah_aboutm = MenuEntry:New(ah_menu,"About AdicHelper ...",function() wehack.execprocess("adichelper\\adichelper.exe") end)

end
-- /cJass#1

-- cJass#2
	if have_ah and ah_enable.checked then
		cmdline = "AdicHelper\\AdicHelper.exe"
		if ah_version.checked == 1 then
			cmdline = cmdline .. " /v23"
		else
			cmdline = cmdline .. " /v24"
		end
		if jh_debug.checked then
			cmdline = cmdline .. " /dbg"
		end
		if ah_alf_flag.checked then
			cmdline = cmdline .. " /alf"
		end
		if ah_igno_cjbj.checked then
			cmdline = cmdline .. " /ibj=\"0\" /icj=\"0\""
		end
		cmdline = cmdline .. " /mappars=\"" .. mappath.."\""
		adicresult = wehack.runprocess2(cmdline)
		if adicresult == 1 then
			mapvalid = false
			return
		end
	end
-- /cJass#2
2 комментария удалено
25
Ошибочка с wehack.lua
Lua Error

wehack.lua:169: attempt to index global 'MenuEntryGroup' (a nil value)
Hanabishi добавил:
Ругается на
ah_version = MenuEntryGroup:New(ah_menu,"Game version switch")
6
Скачать стабильную версию, использовать инсталятор, руками заменить исполняемый файл. Ругается на небольшую функцию в языке интерпритаторе, которая вводит в возможности редактора создание меню с эмуляцией radiobutton. Альтернатива - убрать связанное с этим, принципе это не критично.
19
Срочно нужно что-то вроде
//! nocjass
...
//! endnocjass
потому-что парсер по прежнему порет textmacro.
2
Столкнулся вот с такой проблемой:
Показываю на простом примере
сJass
scope A initializer Init{

include "cj_types_priv.j"

 void func_0(int i){}
 optional void func_1 () {}

 void func_2 (int i) { BJDebugMsg(I2S(1)); unit u = CreateUnit(Player(0), 'Hpal', 100., 0., 0.) }
 
 private void Init(){
      BJDebugMsg("Init")
      unit pal = CreateUnit (Player(0), 'Hpal', 0., 0., 0.)
      func_2(5)
      flush locals
 }

}
скомпилировано на Jass
...
function A__Init takes nothing returns nothing
    local unit pal
    call BJDebugMsg("Init")
    set pal = CreateUnit(Player(0),0x4870616C,0.,0.,0.)
    call func_2(5)
    set pal=null
endfunction
...
Функции func_2 нет! В результате карта не запускается, но сохраняется без ошибок.
А если закоментить optional , то карта запускается, но func_1 остается:
сJass
scope A initializer Init{

include "cj_types_priv.j"

 void func_0(int i){}
 /*optional*/ void func_1 () {}

 void func_2 (int i) { BJDebugMsg(I2S(1)); unit u = CreateUnit(Player(0), 'Hpal', 100., 0., 0.) }
 
 private void Init(){
      BJDebugMsg("Init")
      unit pal = CreateUnit (Player(0), 'Hpal', 0., 0., 0.)
      func_2(5)
      flush locals
 }

}
скомпилировано на Jass
...
function func_1 takes nothing returns nothing
endfunction

function func_2 takes integer i returns nothing
    local unit u
    call BJDebugMsg(I2S(1))
    set u = CreateUnit(Player(0),0x4870616C,100.,0.,0.)
    endfunction

function A__Init takes nothing returns nothing
    local unit pal
    call BJDebugMsg("Init")
    set pal = CreateUnit(Player(0),0x4870616C,0.,0.,0.)
    call func_2(5)
    set pal = null
endfunction
...
В принципе это не так страшно.
6
Master_chan, Сейчас на фидбеке часто светиться Адольф, напишите там о реквесте, и желательно также покажите нерабочие макросы, может он и исправит.
Некрон71, Ну правильно все, ключевое слово optional используется оптимизатором, и указывает, что данная функция не будет вызываться через ExecuteFunc.
DotaMaster666 добавил:
Вот кстати интересный пост с фидбека
  • Added callback functions:
// This is not a substitute for  initializing libraries,
// because you can not specify which of these
// functions will be called earlier.
//
// Also it will be called after all libs and scopes init.
callback onInit () {
    printf ("Hello World!")
}

// Be called on every spells cast.
callback onUnitSpellCast () {
    printf ("foo")
}

// Be called on 'AHfs' spell cast.
callback onUnitSpellCast ('AHfs') {
    printf ("bar")
}
// (? arg name) - optional arg

onInit                  ()
onUnitAttacked          ()
onUnitDeath             ()
onUnitDecay             ()
onUnitIssuedOrder       (?int order_id)
onUnitIssuedPointOrder  (?int order_id)
onUnitIssuedTargetOrder (?int order_id)
onHeroLevel             ()
onHeroSkill             (?int skill_id)
onUnitSpellChannel      (?int abill_id)
onUnitSpellCast         (?int abill_id)
onUnitSpellEffect       (?int abill_id)
onUnitSpellFinish       (?int abill_id)
onUnitSpellEndcast      (?int abill_id)
onGameLoad              ()
onGameSave              ()
24
bb:Пример адекватный с использованием этой фичи добавьте, а то чот не особо вкурил.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.