Рассмотрим такой FTCG-код:
func doStartsWith(_data)
fvar(s,p,b,e,q)
if (isdef(End) and isndef(Start))
error "Either specify only Start, or both Start and End"
return
end
s = Str
p = Substr
b = (isdef(Start)?(', '+Start):'')
e = (isdef(End)?(', '+End):'')
q = '('+Str+').startswith('+p+b+e+')'
if (linked(Result))
println(res, ' = ', q)
event(onResult, res)
else
event(onResult, q)
end
end
Хотелось бы, чтобы код выглядел примерно так:
func doStartsWith(_data)
q = "$Str.startswith($SubStr{, $Start{, $End}}"
save_and_return(onResult, Result, q)
end
На всякий случай поясняю:
1) Имена, начинающиеся на $, рассматриваются кодогенератором как имена соответствующих свойств (точек). Префикс ($) можно задавать в direct.inc. Возможна и такая форма записи:
q = make_code("$Str.startswith($SubStr{, $Start{, $End}}")
2) в блоке {...} записываются необязательные параметры (символ задаётся в direct.inc). Вложенность накладывает ограничения: нельзя задать End, не задавая Start - об этом должен сообщить CodeGen.
3) Синтаксис save_and_return: save_and_return(event, [var, ] code), где event - имя события, происходящего по завершении функции, var - (необязательное) имя переменной, в которой сохранить результат, code - код (целевого языка), генерирующий результат. Оператор присвоения - в direct.inc
// save_and_return(onSomething, Something, SomeFVar)
if (linked(Something))
print (res, ' = ', SomeFVar)
event(onSomething, res)
else
event(SomeFVar)
end
//...skip...
func Something
return(res)
end
P.S. Я не утверждаю, что этим должен заниматься codegen. Пусть это будет препроцессор.