xreate.ATG
No OneTemporary

File Metadata

Created
Wed, Jul 8, 3:46 AM

xreate.ATG

//TODO add ListLiteral
//TODO ExprTyped: assign default(none) type
#include "ast.h"
#include "ExternLayer.h"
#include <string>
#include <stack>
#include <sstream>
#define wprintf(format, ...) \
char __buffer[100]; \
wcstombs(__buffer, format, 100); \
fprintf(stderr, __buffer, __VA_ARGS__)
using namespace std;
COMPILER Xreate
details::inconsistent::AST* root = nullptr; // current program unit
void SemErr(std::initializer_list<std::wstring> msgs){
std::wstringstream output;
for(const auto& msg: msgs){output << msg;}
SemErr(output.str().c_str());
}
void ensureInitalizedAST(){
if (root == nullptr) root = new details::inconsistent::AST();
}
struct {
std::stack<CodeScope*> scopesOld;
CodeScope* scope = nullptr;
} context;
void pushContextScope(CodeScope* scope){
context.scopesOld.push(context.scope);
context.scope = scope;
}
void popContextScope(){
context.scope = context.scopesOld.top();
context.scopesOld.pop();
}
int nextToken()
{
scanner->ResetPeek();
return scanner->Peek()->kind;
}
bool checkTokenAfterIdent(int key){
if (la->kind != _ident) return false;
return nextToken() == key;
}
bool checkParametersList()
{
return la->kind == _ident && nextToken() == _lparen;
}
bool checkInfix()
{
return la->kind == _ident && nextToken() == _ident;
}
bool checkIndex()
{
return la->kind == _ident && nextToken() == _lbrack;
}
bool checkListIndex()
{
return la->kind == _lcurbrack && nextToken() == _lbrack;
}
bool checkFuncDecl()
{
if (la->kind != _ident) return false;
int token2 = nextToken();
int token3 = scanner->Peek()->kind;
return token2 == _assign && token3 == _function;
}
bool checkAssignment()
{
if (la->kind != _ident) return false;
scanner->ResetPeek();
int token2 = scanner->Peek()->kind;
if (token2 == _lcurbrack) {
scanner->Peek();
int token3 = scanner->Peek()->kind;
if (token3 != _rcurbrack) return false;
int token4 = scanner->Peek()->kind;
return token4 == _assign;
}
return token2 == _assign;
}
void recognizeIdentifier(Expression& id, const std::wstring& hint){
if (!context.scope)
SemErr({L"Identifier found in undefined scope: ", hint});
if (!context.scope->recognizeIdentifier(id)){
root->postponeIdentifier(context.scope, id);
}
}
enum SwitchKind{SWITCH_NORMAL, SWITCH_META};
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
any = ANY - '"'.
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
TOKENS
ident = (letter ['-' letter] | '_') {letter ['-' letter] | digit | '_' }.
number = digit{digit}.
string = '"' { any } '"'.
function = "function".
comma = ','.
period = '.'.
lparen = '('.
rparen = ')'.
lbrack = '['.
rbrack = ']'.
lcurbrack = '{'.
rcurbrack = '}'.
equal = "==".
assign = '='.
implic = '-' '>'.
colon = ':'.
tagcolon = "::".
lse = "<=".
lss = "<".
gte = ">=".
gtr = ">".
ne1 = "!=".
ne2= "<>".
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
IGNORE cr + lf + tab
PRODUCTIONS
Xreate = (. Function* function; ensureInitalizedAST(); .)
{( //RuleDecl
InterfaceData | Imprt | GuardSection
| IF(checkFuncDecl()) FDecl<function> (. root->add(function); .)
| TDecl
| SkipModulesSection
)} (. .)
.
Ident<std::wstring& name>=
ident (. name = t->val; .).
// recognition
IdentR<Expression &e> = (. std::wstring name; .)
Ident<name> (. e = Expression(Atom<Identifier_t>(name)); .)
(. recognizeIdentifier(e, name); .).
//versioning
IdentV<Expression& e>= (. std::wstring name; .)
Ident<name> (. e = Expression(Atom<Identifier_t>(name)); .)
[ Version<e> ].
//recognition + versioning
IdentVR<Expression& e>= (. std::wstring name; .)
Ident<name> (. e = Expression(Atom<Identifier_t>(name)); .)
[ Version<e> ] (. recognizeIdentifier(e, name); .)
.
Version<Expression &e>=
lcurbrack (
ident (. SemErr({L"var version as ident is not implemented yet"}); .)
| number (. Attachments::put<versions::VariableVersion>(e, Atom<Number_t>(t->val).get()); .)
) rcurbrack .
FDecl<Function*& f> = (. std::wstring fname; std::wstring argName; TypeAnnotation typIn; TypeAnnotation typOut; Expression binding; .)
Ident<fname> assign
function (. f = new Function(fname); CodeScope* entry = f->getEntryScope(); .)
[lparen Ident<argName> tagcolon ExprAnnotations<binding> (. f->addBinding(Atom<Identifier_t>(argName), move(binding)); .)
{comma Ident<argName> tagcolon ExprAnnotations<binding> (. f->addBinding(Atom <Identifier_t>(argName), move(binding));.)
} rparen]
tagcolon Type<typOut> {';' FnTag<f> }
BDecl<entry> (. const_cast<Expression&>(entry->getBody()).bindType(move(typOut));.)
.
GuardSection<>= (. std::wstring arg, guardI; Expression guardE, guardBinding; Function* f; TypeAnnotation guardT; .)
"guard" lparen
[Ident<arg>] tagcolon Ident<guardI> (. guardE = Expression(Operator::CALL, {Atom<Identifier_t>(guardI)}); bool res = root->recognizeVariantConstructor(guardE); .)
(. if(!res) SemErr(coco_string_create("Can't recognize a guard"));.)
(. if (!arg.empty()) guardE.addBindings({Atom<Identifier_t>(arg)}); .)
(. guardBinding.type = TypeAnnotation(TypeOperator::GUARD, {guardE.type}); guardBinding.type.__valueCustom = Atom<Identifier_t>(guardI).get(); .)
rparen lcurbrack {
FDecl<f> (. f->guard = guardE; if (!arg.empty()){f->addBinding(Atom<Identifier_t>(arg), Expression(guardBinding));} .)
(. root->add(f); .)
} rcurbrack
.
/**
* TYPES
*
*/
TypeTerm<TypePrimitive& typ> = (. std::wstring tid; .)
( "string" (. typ = TypePrimitive::String;.)
| "int" (. typ = TypePrimitive::Int;.)
| "float" (. typ = TypePrimitive::Float;.)
| "bool" (. typ = TypePrimitive::Bool; .)
| "i8" (. typ = TypePrimitive::I8; .)
| "i32" (. typ = TypePrimitive::I32; .)
| "i64" (. typ = TypePrimitive::I64; .)
).
Type<TypeAnnotation& typ> = (. TypeAnnotation typ2; TypePrimitive typ3; std::wstring tid; std::string field; .)
(
TList<typ>
| TRecord<typ>
| TVariant<typ>
| TPred<typ>
| TSlave<typ>
| TRef<typ>
| TypeTerm<typ3> (. typ = typ3; .)
| IF (checkIndex()) Ident<tid> lbrack
TypeIndex<field> (. typ = TypeAnnotation(TypeOperator::ACCESS, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); typ.fields.push_back(field); .)
{comma TypeIndex<field> (. typ.fields.push_back(field); .)
} rbrack
| Ident<tid> (. typ = TypeAnnotation(TypeOperator::ALIAS, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); .)
[lparen Type<typ2> (. typ.__operands.push_back(typ2); .)
{comma Type<typ2> (. typ.__operands.push_back(typ2); .)
} rparen]
| '*' (.typ = TypeAnnotation(); .)
) .
TypeIndex<std::string& name> =
(
number (. name = Atom<Identifier_t>(t->val).get(); .)
| string (. name = Atom<String_t>(t->val).get(); .)
)
.
TList<TypeAnnotation& typ> = (. TypeAnnotation ty; .)
lbrack Type<ty> rbrack (. typ = TypeAnnotation(TypeOperator::ARRAY, {ty}); .)
.
TRecordBody<TypeAnnotation& typ> =
(. TypeAnnotation t; std::wstring key; size_t keyCounter=0;
typ = TypeAnnotation(TypeOperator::RECORD, {});
.)
{
(
IF(checkTokenAfterIdent(_tagcolon)) Ident<key> tagcolon
| (. key = to_wstring(keyCounter++); .)
)
Type<t> [comma] (. typ.__operands.push_back(t); .)
(. typ.fields.push_back(Atom<Identifier_t>(key).get()); .)
}.
TRecord<TypeAnnotation& typ> =
lcurbrack TRecordBody<typ> rcurbrack
(. if(!typ.__operands.size()) SemErr(coco_string_create("Record type can't be empty.")); .)
.
TVariantRec<TypeAnnotation& typ> = (. TypeAnnotation typVoid; .)
lparen TRecordBody<typ> rparen
(. if(typ.__operands.size()==0) typ = typVoid; .)
.
TVariantBody<TypeAnnotation& typ> = (. TypeAnnotation t, typVoid; std::vector<TypeAnnotation> operands; std::vector<Atom<Identifier_t>> keys; std::wstring v; .)
lcurbrack
{ (. t = typVoid; .)
Ident<v> [TVariantRec<t>] (. keys.push_back(Atom<Identifier_t>(v)); operands.push_back(t); .)
[comma]
}
rcurbrack
(. typ = TypeAnnotation(TypeOperator::VARIANT, {});
typ.__operands = operands;
typ.addFields(std::move(keys));
.)
.
TVariant<TypeAnnotation& typ>=
"variant" TVariantBody<typ>
(. if(!typ.__operands.size()) SemErr(coco_string_create("Variant type can't be empty.")); .)
.
TPred<TypeAnnotation& typ>=
"predicate" TVariantBody<typ>
(. if(!typ.__operands.size()) SemErr(coco_string_create("Predicate type can't be empty.")); .)
.
TSlave<TypeAnnotation& typ>=
"slave" (. typ = TypeAnnotation(TypeOperator::SLAVE, {}); .)
lparen
string (. typ.__valueCustom = Atom<String_t>(t->val).get(); .)
rparen
.
TRef<TypeAnnotation& typ>= (. TypeAnnotation typChild; .)
"ref" lparen Type<typChild> rparen (. typ = TypeAnnotation(TypeOperator::REF, {typChild}); .)
.
TDecl = (. TypeAnnotation t; std::wstring tname, arg; std::vector<Atom<Identifier_t>> args; .)
Ident<tname> assign "type"
[lparen Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
{comma Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
} rparen]
Type<t>[period] (. t.addBindings(move(args)); root->add(move(t), Atom<Identifier_t>(tname)); .)
.
ContextDecl<CodeScope * scope> = (. Expression tag; .)
"context" tagcolon
MetaSimpExpr<tag> (. scope->tags.push_back(tag); .)
{';' MetaSimpExpr<tag> (. scope->tags.push_back(tag); .)
}.
VDecl<CodeScope* f> = (. Expression var, value;.)
IdentV<var> assign ExprTyped<value> (. Symbol identSymbol = f->addDefinition(move(var), move(value));
Attachments::put<ExprAlias_A>(value, identSymbol);
.)
.
BDecl<CodeScope* scope> = lcurbrack (. Expression body; pushContextScope(scope); bool flagBodyFound = false; .)
{(IF(checkAssignment()) VDecl<scope> period
// | RuleContextDecl<scope>
| ContextDecl<scope>period
| ExprTyped<body> (. scope->setBody(body); flagBodyFound = true; Attachments::put<ExprAlias_A>(body, Symbol{ScopedSymbol::RetSymbol, scope});.)
)}
rcurbrack (. if(!flagBodyFound) SemErr(coco_string_create("Code block with an empty body!"));
popContextScope();
.)
.
IfDecl<Expression& e> =
(. Expression cond(Operator::AND, {}), condPart;
ManagedScpPtr blockTrue = root->add(new CodeScope(context.scope));
ManagedScpPtr blockFalse = root->add(new CodeScope(context.scope));
e = Expression(Operator::IF, {});
.)
"if" lparen Expr<condPart> (. cond.operands.push_back(condPart); .)
{ comma Expr<condPart> (. cond.operands.push_back(condPart); .)
} rparen (. e.operands.push_back(cond); .)
tagcolon ExprAnnotations<e>
BDecl<&*blockTrue> "else" BDecl<&*blockFalse> (. e.addBlock(blockTrue); e.addBlock(blockFalse); .)
.
LoopDecl<Expression& e> =
(.
Expression eIn, eAcc, eFilters; std::wstring varEl, varAcc, contextClass; Expression tagsEl;
ManagedScpPtr block = root->add(new CodeScope(context.scope));
block->trackExternalSymbs = true;
.)
"loop"
(
"map" lparen Expr<eIn> implic Ident<varEl>
(. e = Expression(Operator::MAP, {eIn}); .)
tagcolon ExprAnnotations<tagsEl> rparen tagcolon ExprAnnotations<e>
(.
e.addBindings({Atom<Identifier_t>(varEl)});
block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
.)
BDecl<&*block>
(. e.addBlock(block); .)
| "fold" lparen Expr<eIn> implic Ident<varEl> tagcolon ExprAnnotations<tagsEl>
['|' Expr<eFilters> ] comma Expr<eAcc> implic Ident<varAcc>rparen
(.
e = Expression(Operator::FOLD, {eIn, eAcc});
e.addBindings({Atom<Identifier_t>(varEl), Atom<Identifier_t>(varAcc)});
.)
tagcolon ExprAnnotations<e>
(.
Expression varAccBindingE; varAccBindingE.type = e.type;
block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
block->addBinding(Atom<Identifier_t>(varAcc), move(varAccBindingE));
.)
BDecl<&*block>
(. e.addBlock(block); .)
| lparen Expr<eAcc> implic Ident<varAcc> rparen
(.
e = Expression(Operator::FOLD_INF, {eAcc});
e.addBindings({Atom<Identifier_t>(varAcc)});
.)
tagcolon ExprAnnotations<e>
(.
Expression varAccBindingE; varAccBindingE.type = e.type;
block->addBinding(Atom<Identifier_t>(varAcc), move(varAccBindingE));
.)
BDecl<&*block>
(. e.addBlock(block); .)
).
// Switches
SwitchDecl<Expression& eSwitch, SwitchKind flagSwitchKind> = (. TypeAnnotation typ; eSwitch = Expression(Operator::SWITCH, {}); Expression eCondition; Expression tag;.)
"switch"
(
SwitchVariantDecl<eSwitch>
| SwitchLateDecl<eSwitch>
| lparen ExprTyped<eCondition> rparen tagcolon ExprAnnotations<eSwitch> (. eSwitch.operands.push_back(eCondition);.)
CaseDecl<eSwitch, flagSwitchKind> {CaseDecl<eSwitch, flagSwitchKind>}
)
.
CaseDecl<Expression& outer, SwitchKind flagSwitchKind> = (. ManagedScpPtr scope = root->add(new CodeScope(context.scope)); Expression condition; .)
"case"
( IF(flagSwitchKind == SWITCH_META)
lparen MetaSimpExpr<condition> rparen BDecl<&*scope> (. Expression exprCase(Operator::CASE, {}); exprCase.addTags({condition}); exprCase.addBlock(scope); outer.addArg(move(exprCase));.)
| "default" BDecl<&*scope> (. Expression exprCase(Operator::CASE_DEFAULT, {});
exprCase.addBlock(scope);
outer.operands.insert(++outer.operands.begin(), exprCase); .)
| lparen CaseParams<&*scope> rparen (. ManagedScpPtr scopeBody = root->add(new CodeScope(&*scope)); Expression exprCase(Operator::CASE, {}); .)
BDecl<&*scopeBody> (. exprCase.addBlock(scope); exprCase.addBlock(scopeBody); outer.addArg(move(exprCase)); .)
).
CaseParams<CodeScope* scope> = (. Expression condition; Expression guard(Operator::LOGIC_AND, {}); pushContextScope(scope); .)
ExprTyped<condition> (. guard.addArg(Expression(condition)); .)
{comma ExprTyped<condition> (. guard.addArg(Expression(condition)); .)
} (. scope->setBody(guard); popContextScope(); .)
.
SwitchLateDecl<Expression& expr> =
(.
std::wstring aliasCondition; Expression exprCondition, aliasAnns;
expr = Expression(Operator::SWITCH_LATE, {});
ManagedScpPtr scope = root->add(new CodeScope(context.scope));
.)
"late" lparen Expr<exprCondition> [implic Ident<aliasCondition>] [tagcolon ExprAnnotations<aliasAnns>] rparen
tagcolon ExprAnnotations<expr> BDecl<&*scope>
(.
expr.addArg(Expression(exprCondition));
expr.addBlock(scope);
std::string alias;
if(aliasCondition.empty()){
if(exprCondition.__state != Expression::IDENT){
SemErr(coco_string_create("An identifier expected in the short form"));
return;
}
//Use exprCondition as identifier
alias = exprCondition.getValueString();
} else {
//Use aliasCondition
alias = Atom<Identifier_t>(move(aliasCondition)).get();
}
expr.addBindings({Atom<Identifier_t>(string(alias))});
scope->addBinding(Atom<Identifier_t>(move(alias)), move(aliasAnns));
.)
.
SwitchVariantDecl<Expression& expr> =
(. Expression varTested; std::wstring varAlias; bool flagAliasFound = false; expr = Expression(Operator::SWITCH_VARIANT, {}); .)
"variant" lparen Expr<varTested> [implic Ident<varAlias>
(. flagAliasFound = true; .)
] [tagcolon ExprAnnotations<varTested>] rparen tagcolon ExprAnnotations<expr>
(. expr.addArg(std::move(varTested));
if (flagAliasFound) {
expr.addBindings({Atom<Identifier_t>(varAlias)});
} else {
if(varTested.__state == Expression::IDENT){
expr.addBindings({Atom<Identifier_t>(string(varTested.getValueString()))});
}
}
.)
CaseVariantDecl<expr> {CaseVariantDecl<expr>}
.
CaseVariantDecl<Expression& expr> = (. ManagedScpPtr scope = root->add(new CodeScope(context.scope)); std::wstring key; scope->addBinding(Atom<Identifier_t>(string(expr.bindings.front())), Expression()); .)
"case" lparen Ident<key> rparen (. expr.addArg(root->recognizeVariantConstructor(Atom<Identifier_t>(std::move(key)))); .)
BDecl<&*scope> (. expr.addBlock(scope); .)
.
IntrinsicDecl<Expression& outer>= (. std::wstring name; .)
"intrinsic"
(
Ident< name>
(. outer = Expression(Operator::CALL_INTRINSIC, {});
outer.setValue(Atom<Identifier_t>(name));
root->recognizeIntrinsic(outer);
.)
lparen [CalleeParams<outer>] rparen
| "query" (. outer = Expression(Operator::QUERY, {}); .)
(
"late" IntrinsicQueryLateDecl<outer>
| lparen [CalleeParams<outer>] rparen
)
).
IntrinsicQueryLateDecl<Expression& expr> =
(.
std::wstring predicateAlias; Expression predicateE, predicateAnns;
expr = Expression(Operator::QUERY_LATE, {});
ManagedScpPtr scope = root->add(new CodeScope(context.scope));
.)
lparen Expr<predicateE> implic Ident<predicateAlias> tagcolon ExprAnnotations<predicateAnns> rparen
tagcolon ExprAnnotations<expr> BDecl<&*scope>
(.
expr.addArg(move(predicateE));
expr.addBindings({Atom<Identifier_t>(wstring(predicateAlias))});
scope->addBinding(Atom<Identifier_t>(move(predicateAlias)), move(predicateAnns));
expr.addBlock(scope);
.)
.
SequenceDecl<Expression& sequence> = (. sequence = Expression(); sequence.setOp(Operator::SEQUENCE); ManagedScpPtr scope = root->add(new CodeScope(context.scope)); .)
"seq" BDecl<&*scope> (. sequence.blocks.push_back(&*scope); scope = root->add(new CodeScope(&*scope)); .)
{ (. scope = root->add(new CodeScope(&*scope)); .)
BDecl<&*scope> (. sequence.blocks.push_back(&*scope); .)
}.
/*============================ INTERFACES ===============================*/
Imprt<> =
"import" "raw" lparen string (. root->__rawImports.push_back(Atom<String_t>(t->val).get()); .)
rparen period.
InterfaceData<> = "interface" lparen
( "dfa" rparen InterfaceDFA
// | "extern-c" rparen InterfaceExternC
| "cfa" rparen InterfaceCFA
).
// InterfaceExternC<> = (. ExternData data; .)
// lcurbrack {ExternHeadersDecl<data> | ExternAliasDecl<data> } rcurbrack
// (. root->addExternData(move(data)); .)
// .
//
// ExternPkgDecl<std::wstring& package> =
// "pkgconfig" lparen
// string (. package = t->val.)
// rparen
// .
//
// ExternAliasDecl<ExternData& data> = (. std::wstring alias, package; .)
// Ident<alias> assign "library" lparen ExternPkgDecl<package> rparen period
// (. data.addLibAlias(Atom<Identifier_t>(alias), Atom<String_t>(package)); .)
// .
//
// ExternHeadersDecl<ExternData& data> = (. std::list<std::string> listInc; std::wstring& package; .)
// "include"
// [lparen
// (
// Ident<alias> (. data.requireLibAlias(Atom<Identifier_t>(alias)); .)
// | ExternPkgDecl<package> (. data.requireLibPackage(Atom<String_t>(package)); .)
// )
// rparen]
// lcurbrack { string (. listInc.push_back(Atom<String_t>(t->val).get()); .)
// [comma] } rcurbrack [period] (. data.requireHeaders(listInc); .)
// .
InterfaceDFA<> = lcurbrack { InstructDecl } rcurbrack .
InstructDecl = (.Operator op; Expression tag;
Expression scheme;
std::vector<Expression>& tags = scheme.operands;
tags.push_back(Expression()); /* return value */ .)
"operator" InstructAlias<op> tagcolon lparen (.scheme.setOp(op); .)
[
MetaSimpExpr<tag> (. tags.push_back(tag); .)
{
comma MetaSimpExpr<tag> (. tags.push_back(tag); .)
}
] rparen [ implic MetaSimpExpr<tag> (. tags[0] = tag; .)
] (. root->addDFAData(move(scheme)); .)
period.
InstructAlias<Operator& op> =
(
"map" (. op = Operator::MAP; .)
| "list_range" (. op = Operator::LIST_RANGE; .)
| "list" (. op = Operator::LIST; .)
| "fold" (. op = Operator::FOLD; .)
| "index" (. op = Operator::INDEX; .)
).
InterfaceCFA<> = lcurbrack { InstructCFADecl } rcurbrack .
InstructCFADecl<> = (.Operator op; Expression tag;
Expression scheme;
std::vector<Expression>& tags = scheme.operands; .)
"operator" InstructAlias<op> tagcolon (. scheme.setOp(op); .)
[
MetaSimpExpr<tag> (. tags.push_back(tag); .)
{
comma MetaSimpExpr<tag> (. tags.push_back(tag); .)
}
] period (. root->addInterfaceData(CFA, move(scheme)); .).
/*============================ METAPROGRAMMING ===============================*/
// TagsDecl<CodeScope* f> = (. Expression tag; TagModifier mod = TagModifier::NONE; .)
// ':' { MetaSimpExpr<tag> (. /*f.addTag(std::move(tag), mod); */ .)
// }.
FnTag<Function* f> = (. Expression tag; TagModifier mod = TagModifier::NONE; .)
MetaSimpExpr<tag>
['-' TagMod<mod>] (. f->addTag(std::move(tag), mod); .).
TagMod<TagModifier& mod> =
( "assert" (. mod = TagModifier::ASSERT; .)
| "require" (. mod = TagModifier::REQUIRE; .)
).
// RuleDecl<> =
// "rule" tagcolon (. RuleArguments args; RuleGuards guards; DomainAnnotation typ; std::wstring arg; .)
// lparen Ident<arg> tagcolon Domain<typ> (. args.add(arg, typ); .)
// {comma Ident<arg> tagcolon Domain<typ> (. args.add(arg, typ); .)
// } rparen
// ["case" RGuard<guards> {comma RGuard<guards>}]
// lcurbrack RBody<args, guards> rcurbrack .
/* - TODO use RGuard for guards-*/
// RuleContextDecl<CodeScope* scope> = (.Expression eHead, eGuards, eBody; .)
// "rule" "context" tagcolon MetaSimpExpr<eHead>
// "case" lparen MetaSimpExpr<eGuards> rparen
// lcurbrack MetaSimpExpr<eBody> rcurbrack (.scope->contextRules.push_back(Expression(Operator::CONTEXT_RULE, {eHead, eGuards, eBody})); .).
// Domain<DomainAnnotation& dom> =
// (
// "function" (. dom = DomainAnnotation::FUNCTION; .)
// | "variable" (. dom = DomainAnnotation::VARIABLE; .)
// ).
// RGuard<RuleGuards& guards>= (. Expression e; .)
// MetaExpr<e> (. guards.add(std::move(e)); .).
// MetaExpr<Expression& e>= (.Operator op; Expression e2; .)
// MetaExpr2<e>
// [MetaOp<op> MetaExpr2<e2> (. e = Expression(op, {e, e2}); .)
// ].
// MetaExpr2<Expression& e>=
// (
// lparen MetaExpr<e> rparen
// | MetaSimpExpr<e>
// ).
MetaSimpExpr<Expression& e>= (. std::wstring i1, infix; Expression e2; .)
(
'-' MetaSimpExpr<e2> (. e = Expression(Operator::NEG, {e2}); .)
| IF(checkParametersList()) Ident<i1>
(. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(i1))});
if (!root->recognizeVariantConstructor(e))
SemErr({L"Undefined predicate: ", i1});
.)
lparen [ MetaCalleeParams<e> ] rparen
| IF(checkInfix()) Ident<i1> Ident<infix> MetaSimpExpr<e2>
(. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(infix))});
e.addArg(Expression(Atom<Identifier_t>(i1)));
e.addArg(std::move(e2));
.)
| IdentR<e>
| number (. e = Expression(Atom<Number_t>(t->val)); .)
).
MetaCalleeParams<Expression& e> = (. Expression e2; .)
MetaSimpExpr<e2> (. e.addArg(Expression(e2)); .)
{comma MetaSimpExpr<e2> (. e.addArg(Expression(e2)); .)
}.
// RBody<const RuleArguments& args, const RuleGuards& guards> =
// (. Expression e; std::wstring msg; .)
// "warning" MetaExpr<e> ["message" string (. msg = t->val; .)
// ] (. root->add(new RuleWarning(RuleArguments(args), RuleGuards(guards), std::move(e), Atom<String_t>(msg))); .)
// .
// MetaOp< Operator& op> =
// implic (. op = Operator::IMPL; .)
// .
/*============================ Expressions ===============================*/
ExprAnnotations<Expression& e> = (. TypeAnnotation typ; std::list<Expression> tags; Expression tag; e.tags.clear();.)
Type<typ> (. e.bindType(move(typ)); .)
{';' MetaSimpExpr<tag> (. tags.push_back(tag); .)
} (. e.addTags(tags); .)
.
ExprTyped<Expression&e> = Expr<e> [tagcolon ExprAnnotations<e>].
Expr< Expression& e> (. Expression e2; .)
= ExprLogicAnd<e>
[ ("or" | "OR") Expr<e2> (. e = Expression(Operator::OR, {e, e2}); .)
]
.
ExprLogicAnd< Expression& e> (. Expression e2; .)
= ExprRel<e>
[ ("and" | "AND") ExprLogicAnd <e2> (. e = Expression(Operator::AND, {e, e2}); .)
]
.
ExprRel< Expression& e> (. Operator op; Expression e2; .)
= ExprArithmAdd<e>
[ RelOp<op> ExprRel<e2> (. e = Expression(op, {e, e2}); .)
]
.
ExprArithmAdd< Expression& e>= (. Operator op; Expression e2; .)
ExprArithmMul< e>
[
AddOp<op>ExprArithmAdd< e2> (. e = Expression(op, {e, e2});.)
].
ExprArithmMul< Expression& e> (. Operator op; Expression e2; .)
= ExprUpdate<e>
[ MulOp< op>
ExprArithmMul< e2> (. e = Expression(op, {e, e2}); .)
].
ExprUpdate<Expression& e>= (. Expression e2; .)
ExprPostfix< e>
[
colon
( IF(checkListIndex()) ListIndexLiteral<e2>
| ListLiteral<e2>) (. e = Expression(Operator::UPDATE, {e, e2}); .)
].
ExprPostfix<Expression& e>
= Term<e>
[ (. e = Expression(Operator::INDEX, {e}); .)
{lbrack CalleeParams<e> rbrack }
].
Term< Expression& e> (. std::wstring name; e = Expression(); .)
=
(IF (checkParametersList()) Ident< name>
(. e = Expression(Operator::CALL, {Atom<Identifier_t>(name)}); root->recognizeVariantConstructor(e); .)
lparen [CalleeParams<e>] rparen
| IdentVR<e>
| ListLiteral<e>
| ListRangeLiteral<e>
| LoopDecl<e>
| IfDecl<e>
| SwitchDecl<e, SWITCH_NORMAL>
| IntrinsicDecl<e>
| SequenceDecl<e>
| number (. e = Expression(Atom<Number_t>(t->val)); .)
| string (. e = Expression(Atom<String_t>(t->val)); .)
| "true" (. e = Expression(Atom<Number_t>(1)); e.bindType(TypePrimitive::Bool); .)
| "false" (. e = Expression(Atom<Number_t>(0)); e.bindType(TypePrimitive::Bool); .)
| "undef" (. e = Expression(Operator::UNDEF, {}); .)
| '-' Term<e> (. e = Expression(Operator::NEG, {e}); .)
| lparen ExprTyped<e> rparen
).
ListLiteral<Expression& e> = (. std::wstring key;
Expression val;
std::list<Atom<Identifier_t>> keys;
e = Expression(Operator::LIST, {});
.)
lcurbrack {
( IF(checkTokenAfterIdent(_assign)) Ident<key> assign
| (. key = L""; .)
) Expr<val> (. keys.push_back(Atom<Identifier_t>(key));
e.operands.push_back(val);
.)
[comma] } rcurbrack (. e.addBindings(keys.begin(), keys.end()); .)
.
ListIndexLiteral<Expression& e> = (. e = Expression(Operator::LIST_INDEX, {});Expression valE;.)
lcurbrack
{ (. Expression idxE(Operator::LIST, {});.)
lbrack CalleeParams<idxE> rbrack
assign Expr<valE>[comma] (. e.operands.push_back(idxE); e.operands.push_back(valE); .)
}
rcurbrack
.
ListRangeLiteral<Expression& e> = (. Expression eFrom, eTo; .)
lbrack Expr<eFrom> ".." Expr<eTo> rbrack (. e = Expression(Operator::LIST_RANGE, {eFrom, eTo}); .)
.
CalleeParams<Expression& e> = (. Expression e2; .)
ExprTyped<e2> (. e.addArg(Expression(e2)); .)
{comma ExprTyped<e2> (. e.addArg(Expression(e2)); .)
}.
AddOp< Operator& op>
= (. op = Operator::ADD; .)
( '+'
| '-' (. op = Operator::SUB; .)
).
MulOp< Operator& op>
= (. op = Operator::MUL; .)
( '*'
| '/' (. op = Operator::DIV; .)
| '%' (. op = Operator::MOD; .)
).
RelOp< Operator& op>
= (. op = Operator::EQU; .)
( equal
| (ne1 | ne2) (. op = Operator::NE; .)
| lse (. op = Operator::LSE; .)
| lss (. op = Operator::LSS; .)
| gte (. op = Operator::GTE; .)
| gtr (. op = Operator::GTR; .)
).
SkipModulesSection = "module" {ANY} (lcurbrack {ANY} rcurbrack | '.').
END Xreate.

Event Timeline