Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F419499
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Dec 20, 1:21 PM
Size
22 KB
Mime Type
text/x-diff
Expires
Sun, Dec 22, 1:21 PM (31 m, 1 s)
Engine
blob
Format
Raw Data
Handle
133003
Attached To
rXR Xreate
View Options
diff --git a/coco/xreate.ATG b/coco/xreate.ATG
index afc8fda..61a41af 100644
--- a/coco/xreate.ATG
+++ b/coco/xreate.ATG
@@ -1,549 +1,550 @@
//TODO add ListLiteral
//TODO ExprTyped: assign default(none) type
#include "ast.h"
#include "ExternLayer.h"
#include <string>
#include <stack>
#define wprintf(format, ...) \
char __buffer[100]; \
wcstombs(__buffer, format, 100); \
fprintf(stderr, __buffer, __VA_ARGS__)
using namespace xreate;
using namespace std;
COMPILER Xreate
xreate::AST root; // current program unit
struct {
std::stack<xreate::CodeScope*> scopesOld;
xreate::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 skipIdent()
{
int kind = 0;
scanner->ResetPeek();
while ((kind = scanner->Peek()->kind) == _colon)
if (scanner->Peek()->kind != _ident)
return 0;
return kind;
}
bool checkParametersList()
{
return la->kind == _ident && skipIdent() == _lparen;
}
bool checkInfix()
{
return la->kind == _ident && skipIdent() == _ident;
}
bool checkIndex()
{
return la->kind == _ident && skipIdent() == _lbrack;
}
bool checkFuncDecl()
{
if (la->kind != _ident) return false;
int xkind = skipIdent();
Token* y = scanner->Peek();
return xkind == _assign && (y->kind == _function || y->kind == _pre);
}
bool checkAssignment()
{
scanner->ResetPeek();
Token* x = scanner->Peek();
return la->kind == _ident && x->kind == _assign;
}
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
any = ANY - '"'.
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
TOKENS
ident = (letter | '_') {letter | digit | '_'}.
number = digit {digit}.
string = '"' { any } '"'.
function = "function".
pre = "pre".
lparen = '('.
rparen = ')'.
lbrack = '['.
rbrack = ']'.
lcurbrack = '{'.
rcurbrack = '}'.
equal = "==".
assign = '='.
implic = '-' '>'.
colon = ':'.
context = "context".
tagcolon = "::".
lse = "<=".
lss = "<".
gte = ">=".
gtr = ">".
ne1 = "!=".
ne2= "<>".
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
IGNORE cr + lf + tab
PRODUCTIONS
Xreate = (. Function* function; .)
{ ( RuleDecl | InterfaceData | Imprt | ContextSection
| IF(checkFuncDecl()) FDecl<function> (. root.add(function); .)
| TDecl ) }.
Ident<std::wstring& name>
= ident {':' ident} (. name = t->val; .).
FDecl<Function*& f> = (. std::wstring fname; std::wstring argName; TypeAnnotation typIn; TypeAnnotation typOut; bool flagIsPrefunct = false; Expression binding; .)
Ident<fname> assign
[pre (. flagIsPrefunct = true; .)]
function (. f = new Function(fname); f->isPrefunction = flagIsPrefunct; CodeScope* entry = f->getEntryScope(); .)
['(' Ident<argName> tagcolon ExprAnnotations<binding> (. f->addBinding(Atom<Identifier_t>(argName), move(binding)); .)
{',' Ident<argName> tagcolon ExprAnnotations<binding> (. f->addBinding(Atom <Identifier_t>(argName), move(binding));.)
} ')']
[ tagcolon
( IF(flagIsPrefunct) FnTag<f>
| Type<typOut> (. f->setReturnType(typOut); .)
)
{';' FnTag<f> }]
BDecl<entry> (. entry->getBody().bindType(move(typOut));.)
.
ContextSection<>= (. Expression context; Function* f; .)
"case" "context" tagcolon MetaSimpExpr<context>
lcurbrack { FDecl<f> (. f->guardContext = context; root.add(f); .)
} rcurbrack.
/**
* TYPES
*
*/
TypeTerm<TypeAtom& typ> = (. std::wstring tid; .)
("string" | "num" | "int" | "i8" | "i32" | "float" | "bool") (. typ = Atom<Type_t>(t->val); .)
.
Type<TypeAnnotation& typ> = (. TypeAnnotation typ2; TypeAtom typ3; std::wstring tid, field; .)
(
TList<typ>
| TStruct<typ>
| TypeTerm<typ3> (. typ = TypeAnnotation(typ3); .)
|IF (checkIndex()) Ident<tid> lbrack
Ident<field> (. typ = TypeAnnotation(TypeOperator::ACCESS, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
{',' Ident<field> (. typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
} rbrack
| Ident<tid> (. typ = TypeAnnotation(TypeOperator::CUSTOM, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); .)
['(' Type<typ2> (. typ.__operator = TypeOperator::CALL; typ.__operands.push_back(typ2); .)
{',' Type<typ2> (. typ.__operands.push_back(typ2); .)
} ')']
) .
TList<TypeAnnotation& typ> = (. TypeAnnotation ty; .)
'[' Type<ty> (. typ = TypeAnnotation(TypeOperator::ARRAY, {ty}); .)
{',' Type<ty> (. typ.__operator = TypeOperator::TUPLE; typ.__operands.push_back(ty); .)
}']'
.
TStruct<TypeAnnotation& typ> = (. TypeAnnotation t; std::wstring field; .)
'{'
Ident<field> tagcolon Type<t> (. typ = TypeAnnotation(TypeOperator::STRUCT, {t}); typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
{',' Ident<field> tagcolon Type<t>} (. typ.__operands.push_back(t); typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
'}'.
TDecl = (. std::wstring ttag; TypeAnnotation t, t1; std::wstring tname, arg; std::vector<Atom<Identifier_t>> args; .)
Ident<tname> assign "type"
(
"alias" Type<t> (. root.add(move(t), Atom<Identifier_t>(tname)); .)
| "variant" lparen Ident<arg> (. t = TypeAnnotation(TypeOperator::VARIANT, {}); args.push_back(Atom<Identifier_t>(arg)); .)
{',' Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
} rparen (. t.addFields(move(args)); root.add(move(t), Atom<Identifier_t>(tname)); .)
| Ident<ttag>
['(' Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
{',' Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
} ')']
Type<t> (. t.addBindings(move(args)); root.add(move(t), Atom<Identifier_t>(tname)); .)
) '.'
.
VDecl<CodeScope* f> = (. std::wstring vname; Expression e;.)
Ident<vname> assign ExprTyped<e> (. f->addDeclaration(Atom<Identifier_t>(vname), move(e)); .)
.
ContextDecl<CodeScope * scope> = (. Expression tag; .)
context tagcolon
MetaSimpExpr<tag> (. scope->tags.push_back(tag); .)
{';' MetaSimpExpr<tag> (. scope->tags.push_back(tag); .)
}.
//TODO forbid multiple body declaration (ExprTyped)
-BDecl<CodeScope* scope> = (. Expression body; pushContextScope(scope); .)
-'{' { (RuleContextDecl<scope> | ContextDecl<scope> '.'
+BDecl<CodeScope* scope> = '{' (. Expression body; pushContextScope(scope);
+ .)
+ { (RuleContextDecl<scope> | ContextDecl<scope> '.'
| IF(checkAssignment()) VDecl<scope> '.'
| ExprTyped<body> (. scope->setBody(body); popContextScope();.)
)} '}'.
IfDecl<Expression& e> = (. Expression cond; ManagedScpPtr blockTrue = root.add(new xreate::CodeScope(context.scope)); ManagedScpPtr blockFalse = root.add(new xreate::CodeScope(context.scope)); .)
"if" '(' Expr<cond> ')' (. e = Expression(Operator::IF, {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 xreate::CodeScope(context.scope)); .)
"loop"
("map" '(' Expr<eIn> implic Ident<varEl> (. e = Expression(Operator::MAP, {eIn}); .)
tagcolon ExprAnnotations<tagsEl> ')' tagcolon ExprAnnotations<e> BDecl<&*block>
(.
e.addBindings({Atom<Identifier_t>(varEl)});
block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
e.addBlock(block);
.)
|"fold"
("inf" '(' Expr<eAcc> implic Ident<varAcc> ')'
(.
e = Expression(Operator::FOLD_INF, {eAcc});
e.addBindings({Atom<Identifier_t>(varAcc)});
.)
tagcolon ExprAnnotations<e> BDecl<&*block>
(.
block->addBinding(Atom<Identifier_t>(varAcc), Expression());
e.addBlock(block);
.)
| '(' Expr<eIn> implic Ident<varEl> tagcolon ExprAnnotations<tagsEl> ['|' Expr<eFilters> ] ',' Expr<eAcc> implic Ident<varAcc>')'
(.
e = Expression(Operator::FOLD, {eIn, eAcc});
e.addBindings({Atom<Identifier_t>(varEl), Atom<Identifier_t>(varAcc)});
.)
tagcolon ExprAnnotations<e> BDecl<&*block>
(.
block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
block->addBinding(Atom<Identifier_t>(varAcc), Expression());
e.addBlock(block);
.)
)
| "context" '(' string (. contextClass = t->val; .)
')' BDecl<&*block>
(. e = Expression(Operator::LOOP_CONTEXT, {Expression(Atom<String_t>(std::move(contextClass)))});
e.addBlock(block);
.)
).
SwitchDecl<Expression& eSwitch> = (. TypeAnnotation typ; eSwitch = Expression(Operator::SWITCH, {}); Expression eCondition; Expression tag;.)
["switch"
( "ad" "hoc" lparen Expr<eCondition> tagcolon MetaSimpExpr<tag> rparen (. eSwitch.op = Operator::SWITCH_ADHOC; eSwitch.operands.push_back(eCondition); eSwitch.tags.emplace(tag.getValueString(), move(tag)); .)
| lparen Expr<eCondition> rparen tagcolon ExprAnnotations<eSwitch> (. eSwitch.operands.push_back(eCondition);.)
)
]
CaseDecl<eSwitch> {CaseDecl<eSwitch>}
.
CaseDecl<Expression& outer> = (. ManagedScpPtr scope = root.add(new xreate::CodeScope(context.scope)); .)
"case"
( "default" BDecl<&*scope> (. Expression exprCase(Operator::CASE_DEFAULT, {});
exprCase.addBlock(scope);
outer.operands.insert(++outer.operands.begin(), exprCase); .)
| CaseParams<&*scope> (. ManagedScpPtr scopeBody = root.add(new xreate::CodeScope(&*scope)); .)
BDecl<&*scopeBody> (. Expression exprCase(Operator::CASE, {});
exprCase.addBlock(scope); exprCase.addBlock(scopeBody); outer.addArg(move(exprCase)); .)
).
CaseParams<CodeScope* scope> = (. Expression e; Expression guard(Operator::LOGIC_AND, {}); pushContextScope(scope); .)
CaseParam<scope, guard>
{',' CaseParam<scope, guard>
} (. scope->setBody(guard); popContextScope(); .).
CaseParam<CodeScope* scope, Expression& guard> = (. Expression condition; .)
(
IF(checkAssignment()) VDecl<scope>
| ExprTyped<condition> (. guard.addArg(move(condition)); .)
).
SequenceDecl<Expression& sequence> =
"sequence" ListLiteral<sequence> (. sequence.setOp(Operator::SEQUENCE); .).
/*============================ INTERFACES ===============================*/
Imprt<> =
"import" "raw" lparen string (. root.__rawImports.push_back(Atom<String_t>(t->val).get()); .)
rparen .
InterfaceData<> = "interface" '('
( "dfa" ')' InterfaceDFA
| "extern-c" ')' InterfaceExternC
| "cfa" ')' InterfaceCFA
| "adhoc" ')' InterfaceAdhoc
).
InterfaceAdhoc<> =
'{' [ PrefunctionSchemeDecl ] '}'.
PrefunctionSchemeDecl<> = (. TypeAnnotation typReturn; std::wstring prefName; Expression exprCases; .)
pre function Ident<prefName> tagcolon Type<typReturn>
'{' SwitchDecl<exprCases> '}'
(. Expression prefData(Operator::CALL, {Atom<Identifier_t>(prefName), exprCases});
prefData.type = typReturn;
root.addInterfaceData(Adhoc, move(prefData));
.).
InterfaceExternC<> = (.xreate::ExternData data; .)
'{' {IncludeExternDecl<data> | LibExternDecl<data> } '}'
(. root.addExternData(move(data)); .)
.
LibExternDecl<xreate::ExternData& data> = (. std::wstring pkgname, libname; .)
Ident<libname> assign "library" tagcolon "pkgconfig"
'(' string (. pkgname = t->val; .)
')' '.' (. data.addLibrary(Atom<Identifier_t>(libname), Atom<String_t>(pkgname)); .)
.
IncludeExternDecl<xreate::ExternData& data> = (. Expression inc; .)
"include" StructLiteral<inc> '.' (. data.addIncludeDecl(move(inc)); .)
.
InterfaceDFA<> = '{' { InstructDecl } '}' .
InstructDecl = (.Operator op; Expression tag;
Expression scheme;
std::vector<Expression>& tags = scheme.operands;
tags.push_back(Expression()); /* return value */ .)
"operator" InstructAlias<op> tagcolon '(' (.scheme.setOp(op); .)
[
MetaSimpExpr<tag> (. tags.push_back(tag); .)
{
',' MetaSimpExpr<tag> (. tags.push_back(tag); .)
}
] ')' [ implic MetaSimpExpr<tag> (. tags[0] = tag; .)
] (. root.addDFAData(move(scheme)); .)
'.'.
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<> = '{' { InstructCFADecl } '}' .
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); .)
{
',' MetaSimpExpr<tag> (. tags.push_back(tag); .)
}
] '.' (. 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; .)
'(' Ident<arg> tagcolon Domain<typ> (. args.add(arg, typ); .)
{',' Ident<arg> tagcolon Domain<typ> (. args.add(arg, typ); .)
} ')'
["case" RGuard<guards> {',' RGuard<guards>}]
'{' RBody<args, guards> '}' .
/* - TODO use RGuard for guards-*/
RuleContextDecl<CodeScope* scope> = (.Expression eHead, eGuards, eBody; .)
"rule" "context" tagcolon MetaSimpExpr<eHead>
"case" MetaSimpExpr<eGuards>
'{' MetaSimpExpr<eBody> '}' (.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>=
(
'(' MetaExpr<e> ')'
| 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))}); .)
'(' [ CalleeParams<e> ] ')'
| 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));
.)
| Ident<i1> (. e = Expression(Atom<Identifier_t>(i1)); .)
).
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; Expression tag; e.tags.clear();.)
Type<typ> (. e.bindType(move(typ)); .)
{';' MetaSimpExpr<tag> (. e.tags.emplace(tag.getValueString(), tag); .)
}.
ExprTyped<Expression&e> = Expr<e> [tagcolon ExprAnnotations<e>].
Expr< Expression& e> (. Operator op; Expression e2; .)
= SimExpr<e>
[ RelOp<op>
SimExpr<e2> (. e = Expression(op, {e, e2}); .)
].
SimExpr< Expression& e> (. Operator op; Expression e2; .)
= Term< e>
{ AddOp< op>
Term< e2> (. e = Expression(op, {e, e2});.)
}.
Term< Expression& e> (. Operator op; Expression e2; .)
= Factor< e>
{ MulOp< op>
Factor< e2> (. e = Expression(op, {e, e2}); .)
}.
Factor< Expression& e> (. std::wstring name; e = Expression(); .)
=
(IF (checkParametersList()) Ident< name>
(. e = Expression(Operator::CALL, {Atom<Identifier_t>(name)}); .)
'(' [CalleeParams<e>] ')'
|IF (checkIndex()) Ident<name>
lbrack CalleeParams<e> rbrack (. e.setOp(Operator::INDEX); e.setValue({Atom<Identifier_t>(name)}); .)
| Ident< name> (. e = Expression(Atom<Identifier_t>(name)); root.recognizeVariantIdentifier(e); .)
| ListLiteral<e> (. /* tuple */.)
| StructLiteral<e> (. /* struct */.)
| SequenceDecl<e>
| LoopDecl<e>
| IfDecl<e>
| SwitchDecl<e>
| AdhocDecl<e>
| number (. e = Expression(Atom<Number_t>(t->val)); .)
| string (. e = Expression(Atom<String_t>(t->val)); .)
| '-' Factor< e> (. e = Expression(Operator::NEG, {e}); .)
| '(' ExprTyped<e> ')'
).
StructLiteral<Expression& e> = (. std::wstring key; Expression val; std::list<Atom<Identifier_t>> keys; .)
'{' Ident<key> '=' Expr<val> (. keys.push_back(Atom<Identifier_t>(key)); e = Expression(Operator::LIST_NAMED, {val}); .)
{',' Ident<key> '=' Expr<val> (.e.addArg(Expression(val)); keys.push_back(Atom<Identifier_t>(key)); .)
} '}' (. e.addBindings(keys.begin(), keys.end()); .)
.
ListLiteral<Expression& e> = (. Expression eFrom, eTo; .)
'['
[ Expr<eFrom> (. e.addArg(Expression(eFrom)); .)
(".." Expr<eTo> (. e.addArg(Expression(eTo)); e.setOp(Operator::LIST_RANGE); .)
|{',' Expr<eFrom> (. e.addArg(Expression(eFrom)); .)
} (. e.setOp(Operator::LIST); .)
) ] ']'.
AdhocDecl<Expression& e> = (. Expression command; .)
"ad" "hoc" Expr<command> (. e.setOp(Operator::ADHOC); e.addArg(std::move(command)); .).
CalleeParams<Expression& e> = (. Expression e2; .)
ExprTyped<e2> (. e.addArg(Expression(e2)); .)
{',' ExprTyped<e2> (. e.addArg(Expression(e2)); .)
}.
AddOp< Operator& op>
= (. op = Operator::ADD; .)
( '+'
| '-' (. op = Operator::SUB; .)
).
MulOp< Operator& op>
= (. op = Operator::MUL; .)
( '*'
| '/' (. op = Operator::DIV; .)
).
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; .)
).
END Xreate.
Event Timeline
Log In to Comment