From 7f71bb9df86309f40509ce45701d1f72d02577fb Mon Sep 17 00:00:00 2001 From: Nathan R Date: Fri, 13 Aug 2021 19:35:53 +0200 Subject: [PATCH] added meta rules, new.txt passes TODO : fix assterion line 3291 --- ccmeta.leg | 865 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 645 insertions(+), 220 deletions(-) diff --git a/ccmeta.leg b/ccmeta.leg index 0522ec5..eea80e5 100644 --- a/ccmeta.leg +++ b/ccmeta.leg @@ -243,34 +243,6 @@ oop getMember(oop object, oop key) return map_get(object, key); } -// this follows the __proto__ chain until it finds the key, if it fails it behaves like newMember -oop setVariable(oop object, oop key, oop value) -{ - oop obj= object; - while (!map_hasKey(obj, key)) { - obj= map_get(obj, __proto___symbol); - if (null == obj) { - return map_set(object, key, value); - } - } - return map_set(obj, key, value); -} - -oop getProperty(oop object, oop key) -{ - if (!map_hasKey(object, key)) { - runtimeError("Undefined: .%s", printString(key)); - } - return map_get(object, key); -} - -oop newMap(oop value) -{ - oop map = newObject(Map_proto); - map_set(map, value_symbol, value); - return map; -} - oop newNullObject() { return null; } @@ -405,15 +377,6 @@ oop new_C_functionDef(oop specifiers, oop declarator, oop declarationList, oop c return object; } -// take char *name or oop already interned? -oop newSymbol(oop name) -{ - oop symbol = newObject(Symbol_proto); - // what is the less confusing, name or value? maybe another word like identifier? - map_set(symbol, value_symbol, name); - return symbol; -} - oop new_C_int(char *text) { oop object = newObject(C_int_proto); map_set(object, text_symbol, makeString(text)); @@ -504,82 +467,6 @@ oop new_C_id(char* id) { return object; } -oop newPreIncrement(oop rhs) -{ assert(is(Map, rhs)); - oop proto= map_get(rhs, __proto___symbol); assert(null != proto); - oop name= map_get(proto, __name___symbol); assert(null != name); - proto_t type= get(name, Symbol, prototype); - switch (type) { - case t_GetVariable: proto= PreIncVariable_proto; break; - case t_GetMember: proto= PreIncMember_proto; break; - case t_GetIndex: proto= PreIncIndex_proto; break; - default: { - printf("\nNon-lvalue after ++: "); - println(rhs); - exit(1); - } - } - map_set(rhs, __proto___symbol, proto); - return rhs; -} - -oop newPostIncrement(oop rhs) -{ assert(is(Map, rhs)); - oop proto= map_get(rhs, __proto___symbol); assert(null != proto); - oop name= map_get(proto, __name___symbol); assert(null != name); - proto_t type= get(name, Symbol, prototype); - switch (type) { - case t_GetVariable: proto= PostIncVariable_proto; break; - case t_GetMember: proto= PostIncMember_proto; break; - case t_GetIndex: proto= PostIncIndex_proto; break; - default: { - printf("\nNon-lvalue before ++: "); - println(rhs); - exit(1); - } - } - map_set(rhs, __proto___symbol, proto); - return rhs; -} - -oop newPreDecrement(oop rhs) -{ assert(is(Map, rhs)); - oop proto= map_get(rhs, __proto___symbol); assert(null != proto); - oop name= map_get(proto, __name___symbol); assert(null != name); - proto_t type= get(name, Symbol, prototype); - switch (type) { - case t_GetVariable: proto= PreDecVariable_proto; break; - case t_GetMember: proto= PreDecMember_proto; break; - case t_GetIndex: proto= PreDecIndex_proto; break; - default: { - printf("\nNon-lvalue after ++: "); - println(rhs); - exit(1); - } - } - map_set(rhs, __proto___symbol, proto); - return rhs; -} - -oop newPostDecrement(oop rhs) -{ assert(is(Map, rhs)); - oop proto= map_get(rhs, __proto___symbol); assert(null != proto); - oop name= map_get(proto, __name___symbol); assert(null != name); - proto_t type= get(name, Symbol, prototype); - switch (type) { - case t_GetVariable: proto= PostDecVariable_proto; break; - case t_GetMember: proto= PostDecMember_proto; break; - case t_GetIndex: proto= PostDecIndex_proto; break; - default: { - printf("\nNon-lvalue before ++: "); - println(rhs); - exit(1); - } - } - map_set(rhs, __proto___symbol, proto); - return rhs; -} - oop new_C_sizeOf(oop sizeOfTok, oop lParen, oop typeName, oop rParen) { oop object = newObject(C_sizeOf_proto); map_set(object, sizeOfTok_symbol, sizeOfTok); @@ -635,69 +522,6 @@ oop new_C_compound(oop leftCurly, oop expression, oop rightCurly) { return object; } -oop newAssign(oop proto, oop lhs, oop operator, oop rhs) -{ - oop obj = newObject(proto); - map_set(obj, lhs_symbol, lhs); - map_set(obj, operator_symbol, operator); - map_set(obj, rhs_symbol, rhs); - return obj; -} - -oop newSetMap(oop proto, oop map, oop key, oop operator, oop value) -{ - oop obj = newObject(proto); - map_set(obj, map_symbol, map); - map_set(obj, key_symbol, key); - map_set(obj, operator_symbol, operator); - map_set(obj, value_symbol, value); - return obj; -} - -oop newGetMap(oop proto, oop map, oop key) -{ - oop obj = newObject(proto); - map_set(obj, map_symbol, map); - map_set(obj, key_symbol, key); - return obj; -} - -oop newGetVariable(oop name) -{ - oop id= newObject(GetVariable_proto); - map_set(id, key_symbol, name); - return id; -} - -oop newFunc(oop name, oop param, oop body, oop fixed) -{ - oop func = newObject(Func_proto); - map_set(func, name_symbol, name); - map_set(func, param_symbol, param); - map_set(func, body_symbol, body); - map_set(func, fixed_symbol, fixed); - return func; -} - -oop apply(oop scope, oop this, oop func, oop args, oop ast); - -oop getSyntaxId(int n, oop key) -{ - oop val = map_get(globals, key); - if (!is(Function, val)) return null; - oop fix = get(val, Function, fixed); - if (!isInteger(fix)) return null; - if (n != getInteger(fix)) return null; - return val; -} - -oop getSyntax(int n, oop func) -{ - if (map_get(func, __proto___symbol) != GetVariable_proto) return null; - oop key = map_get(func, key_symbol); - return getSyntaxId(n, key); -} - oop new_C_subexpr (oop lParen, oop declarator, oop rParen) { oop object = newObject(C_subexpr_proto); map_set(object, lparen_symbol, lParen); @@ -727,15 +551,6 @@ oop new_C_array(oop declarator, oop lBracket, oop staticTok, oop typeQualiferL, return object; } -oop newInvoke(oop this, oop name, oop args) -{ - oop obj = newObject(Invoke_proto); - map_set(obj, this_symbol, this); - map_set(obj, name_symbol, name); - map_set(obj, args_symbol, args); - return obj; -} - oop new_C_block(oop bxor, oop typeQualiferL, oop declarator) { oop object = newObject(C_block_proto); map_set(object, bxor_symbol, bxor); @@ -766,16 +581,6 @@ oop new_C_return(oop returnTok, oop expression, oop semicolon) { return object; } -oop newTry(oop try, oop exception, oop catch, oop finally) -{ - oop obj = newObject(Try_proto); - map_set(obj, try_symbol, try); - map_set(obj, exception_symbol, exception); - map_set(obj, catch_symbol, catch); - map_set(obj, finally_symbol, finally); - return obj; -} - oop new_C_exprStatement(oop expression, oop semicolon) { oop object = newObject(C_exprStatement_proto); map_set(object, expression_symbol, expression); @@ -1107,11 +912,338 @@ void setComment(oop ast, oop comment) map_set(ast, comment_symbol, comment); } +/* Meta Functions */ + +oop setVariable(oop object, oop key, oop value) +{ + oop obj= object; + while (!map_hasKey(obj, key)) { + obj= map_get(obj, __proto___symbol); + if (null == obj) { + return map_set(object, key, value); + } + } + return map_set(obj, key, value); +} + +oop getProperty(oop object, oop key) +{ + if (!map_hasKey(object, key)) { + runtimeError("Undefined: .%s", printString(key)); + } + return map_get(object, key); +} + +oop newMap(oop value) +{ + oop map = newObject(Map_proto); + map_set(map, value_symbol, value); + return map; +} + +oop newDeclaration(oop name, oop exp) +{ + oop declaration = newObject(Declaration_proto); + map_set(declaration, lhs_symbol, name); + map_set(declaration, rhs_symbol, exp); + return declaration; +} + +oop newIf(oop cond, oop cons, oop alt) +{ + oop obj = newObject(If_proto); + map_set(obj, condition_symbol, cond); + map_set(obj, consequent_symbol, cons); + map_set(obj, alternate_symbol, alt); + return obj; +} + +oop newWhile(oop cond, oop body) +{ + oop obj = newObject(While_proto); + map_set(obj, condition_symbol, cond); + map_set(obj, body_symbol, body); + return obj; +} + +oop newDo(oop body, oop cond) +{ + oop obj= newObject(Do_proto); + map_set(obj, body_symbol, body); + map_set(obj, condition_symbol, cond); + return obj; +} + +oop newFor(oop init, oop cond, oop step, oop body) +{ + oop obj= newObject(For_proto); + map_set(obj, initialise_symbol, init); + map_set(obj, condition_symbol, cond); + map_set(obj, update_symbol, step); + map_set(obj, body_symbol, body); + return obj; +} + +oop newForIn(oop name, oop expression, oop body) +{ + oop obj= newObject(ForIn_proto); + map_set(obj, name_symbol, name); + map_set(obj, expression_symbol, expression); + map_set(obj, body_symbol, body); + return obj; +} + +oop newSwitch(oop expression, oop labels, oop statements) +{ + oop obj= newObject(Switch_proto); + map_set(obj, expression_symbol, expression); + map_set(obj, labels_symbol, labels); + map_set(obj, statements_symbol, statements); + return obj; +} + +// take char *name or oop already interned? +oop newSymbol(oop name) +{ + oop symbol = newObject(Symbol_proto); + // what is the less confusing, name or value? maybe another word like identifier? + map_set(symbol, value_symbol, name); + return symbol; +} + +oop newInteger(oop value) +{ + oop integer = newObject(Integer_proto); + map_set(integer, value_symbol, value); + return integer; +} + +oop newFloat(oop value) +{ + oop obj = newObject(Float_proto); + map_set(obj, value_symbol, value); + return obj; +} +oop newString(oop str) +{ assert(is(String, str)); + oop string = newObject(String_proto); + map_set(string, value_symbol, str); + return string; +} + +oop newPreIncrement(oop rhs) +{ assert(is(Map, rhs)); + oop proto= map_get(rhs, __proto___symbol); assert(null != proto); + oop name= map_get(proto, __name___symbol); assert(null != name); + proto_t type= get(name, Symbol, prototype); + switch (type) { + case t_GetVariable: proto= PreIncVariable_proto; break; + case t_GetMember: proto= PreIncMember_proto; break; + case t_GetIndex: proto= PreIncIndex_proto; break; + default: { + printf("\nNon-lvalue after ++: "); + println(rhs); + exit(1); + } + } + map_set(rhs, __proto___symbol, proto); + return rhs; +} + +oop newPostIncrement(oop rhs) +{ assert(is(Map, rhs)); + oop proto= map_get(rhs, __proto___symbol); assert(null != proto); + oop name= map_get(proto, __name___symbol); assert(null != name); + proto_t type= get(name, Symbol, prototype); + switch (type) { + case t_GetVariable: proto= PostIncVariable_proto; break; + case t_GetMember: proto= PostIncMember_proto; break; + case t_GetIndex: proto= PostIncIndex_proto; break; + default: { + printf("\nNon-lvalue before ++: "); + println(rhs); + exit(1); + } + } + map_set(rhs, __proto___symbol, proto); + return rhs; +} + +oop newPreDecrement(oop rhs) +{ assert(is(Map, rhs)); + oop proto= map_get(rhs, __proto___symbol); assert(null != proto); + oop name= map_get(proto, __name___symbol); assert(null != name); + proto_t type= get(name, Symbol, prototype); + switch (type) { + case t_GetVariable: proto= PreDecVariable_proto; break; + case t_GetMember: proto= PreDecMember_proto; break; + case t_GetIndex: proto= PreDecIndex_proto; break; + default: { + printf("\nNon-lvalue after ++: "); + println(rhs); + exit(1); + } + } + map_set(rhs, __proto___symbol, proto); + return rhs; +} + +oop newPostDecrement(oop rhs) +{ assert(is(Map, rhs)); + oop proto= map_get(rhs, __proto___symbol); assert(null != proto); + oop name= map_get(proto, __name___symbol); assert(null != name); + proto_t type= get(name, Symbol, prototype); + switch (type) { + case t_GetVariable: proto= PostDecVariable_proto; break; + case t_GetMember: proto= PostDecMember_proto; break; + case t_GetIndex: proto= PostDecIndex_proto; break; + default: { + printf("\nNon-lvalue before ++: "); + println(rhs); + exit(1); + } + } + map_set(rhs, __proto___symbol, proto); + return rhs; +} + +oop newUnary(oop proto, oop rhs) +{ + oop obj = newObject(proto); + map_set(obj, rhs_symbol, rhs); + return obj; +} + +oop newBinary(oop proto, oop lhs, oop rhs) +{ + oop obj = newObject(proto); + map_set(obj, lhs_symbol, lhs); + map_set(obj, rhs_symbol, rhs); + return obj; +} + +oop newAssign(oop proto, oop lhs, oop operator, oop rhs) +{ + oop obj = newObject(proto); + map_set(obj, lhs_symbol, lhs); + map_set(obj, operator_symbol, operator); + map_set(obj, rhs_symbol, rhs); + return obj; +} + +oop newSetMap(oop proto, oop map, oop key, oop operator, oop value) +{ + oop obj = newObject(proto); + map_set(obj, map_symbol, map); + map_set(obj, key_symbol, key); + map_set(obj, operator_symbol, operator); + map_set(obj, value_symbol, value); + return obj; +} + +oop newGetMap(oop proto, oop map, oop key) +{ + oop obj = newObject(proto); + map_set(obj, map_symbol, map); + map_set(obj, key_symbol, key); + return obj; +} + +oop newGetVariable(oop name) +{ + oop id= newObject(GetVariable_proto); + map_set(id, key_symbol, name); + return id; +} + +oop newFunc(oop name, oop param, oop body, oop fixed) +{ + oop func = newObject(Func_proto); + map_set(func, name_symbol, name); + map_set(func, param_symbol, param); + map_set(func, body_symbol, body); + map_set(func, fixed_symbol, fixed); + return func; +} + +oop apply(oop scope, oop this, oop func, oop args, oop ast); + +oop getSyntaxId(int n, oop key) +{ + oop val = map_get(globals, key); + if (!is(Function, val)) return null; + oop fix = get(val, Function, fixed); + if (!isInteger(fix)) return null; + if (n != getInteger(fix)) return null; + return val; +} + +oop getSyntax(int n, oop func) +{ + if (map_get(func, __proto___symbol) != GetVariable_proto) return null; + oop key = map_get(func, key_symbol); + return getSyntaxId(n, key); +} + +oop newCall(oop func, oop args) +{ + oop call = newObject(Call_proto); + map_set(call, func_symbol, func); + map_set(call, args_symbol, args); + return call; +} + +oop newInvoke(oop this, oop name, oop args) +{ + oop obj = newObject(Invoke_proto); + map_set(obj, this_symbol, this); + map_set(obj, name_symbol, name); + map_set(obj, args_symbol, args); + return obj; +} + +oop newBlock(oop statements) +{ + oop obj = newObject(Block_proto); + map_set(obj, statements_symbol, statements); + return obj; +} + +oop newReturn(oop exp) +{ + oop obj = newObject(Return_proto); + map_set(obj, value_symbol, exp); + return obj; +} + +oop newBreak(void) +{ + oop obj = newObject(Break_proto); + return obj; +} + +oop newContinue(void) +{ + oop obj = newObject(Continue_proto); + return obj; +} + +oop newTry(oop try, oop exception, oop catch, oop finally) +{ + oop obj = newObject(Try_proto); + map_set(obj, try_symbol, try); + map_set(obj, exception_symbol, exception); + map_set(obj, catch_symbol, catch); + map_set(obj, finally_symbol, finally); + return obj; +} %} -start = externalDeclaration +#--------------------------------------------- C Grammar -------------------------------------------------# + +start = meta | externalDeclaration error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } @@ -1952,7 +2084,304 @@ __INLINE = '__inline' !IDREST &{gnu} { $$= newToken("__inlin _FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - -#| meta = @ + +#--------------------------------------------- Meta Grammar ----------------------------------------------# + +meta = - ( META_IMPORT s:META_STRING META_SEMICOLON { yylval = null; inputStackPush(get(s, String, value)) } + | s:meta_stmt { yylval = s } + | !. { yylval = 0 } + ) + + +meta_stmt = s:meta_block { $$ = s } + | META_SEMICOLON { $$ = null } + | l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, null) } + | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt META_ELSE f:meta_stmt { $$ = newIf(c, t, f ) } + | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt { $$ = newIf(c, t, null) } + | META_WHILE META_LPAREN c:meta_exp META_RPAREN s:meta_stmt { $$ = newWhile(c, s) } + | META_DO s:meta_stmt META_WHILE META_LPAREN c:meta_exp META_RPAREN { $$ = newDo(s, c) } + | META_FOR META_LPAREN i:meta_ident META_IN e:meta_exp META_RPAREN s:meta_stmt { $$ = newForIn(i, e, s) } + | META_FOR META_LPAREN i:meta_stmt c:meta_stmt u:meta_exp META_RPAREN s:meta_stmt { $$ = newFor(i, c, u, s) } + | s:meta_switch { $$ = s } + | META_RETURN e:meta_exp { $$ = newReturn(e) } + | META_RETURN { $$ = newReturn(null) } + | META_BREAK { $$ = newBreak() } + | META_CONTINUE { $$ = newContinue() } + | META_THROW e:meta_exp { $$ = newUnary(Throw_proto, e) } + | t:meta_try { $$ = t } + | e:meta_exp META_SEMICOLON { $$ = e } + +meta_block = META_LCB m:meta_makeMap + ( s:meta_stmt { map_append(m, s) } + ) * + ( s:meta_exp { map_append(m, s) } + ) ? + META_RCB { $$ = newBlock(m) } + +meta_exp = META_VAR l:meta_ident META_ASSIGN e:meta_exp { $$ = newDeclaration(l, e) } +# | META_SYNTAX l:META_IDENT p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(l, p, e, makeInteger(2))) } +# | META_SYNTAX p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(null, p, e, makeInteger(2))) } +# | META_SYNTAX l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, makeInteger(1)) } +# | META_SYNTAX p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, makeInteger(1)) } + | l:META_IDENT o:meta_assignOp e:meta_exp { $$ = newAssign(Assign_proto, l, o, e) } + | l:meta_postfix META_DOT i:META_IDENT o:meta_assignOp e:meta_exp { $$ = newSetMap(SetMember_proto, l, i, o, e) } + | l:meta_postfix META_LBRAC i:meta_exp META_RBRAC o:meta_assignOp e:meta_exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) } + | l:meta_syntax2 a:meta_argumentList s:meta_block { $$ = (map_append(a, s), apply(globals, globals, l, a, a)) } + | c:meta_cond { $$ = c } + +meta_ident = l:META_IDENT { $$ = l } +# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } + +meta_syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > + &{ null != getSyntaxId(2, intern(yytext)) } - { $$ = getSyntaxId(2, intern(yytext)) } + +meta_try = META_TRY t:meta_stmt i:meta_null c:meta_null f:meta_null + ( META_CATCH META_LPAREN i:META_IDENT META_RPAREN c:meta_stmt ) ? + ( META_FINALLY f:meta_stmt ) ? { $$ = newTry(t, i, c, f) } + +meta_null = { $$ = null } + +meta_assignOp = META_ASSIGN { $$= null } + | META_ASSIGNADD { $$= Add_symbol } + | META_ASSIGNSUB { $$= Sub_symbol } + | META_ASSIGNMUL { $$= Mul_symbol } + | META_ASSIGNDIV { $$= Div_symbol } + | META_ASSIGNMOD { $$= Mod_symbol } + | META_ASSIGNBITOR { $$= Bitor_symbol } + | META_ASSIGNBITXOR { $$= Bitxor_symbol } + | META_ASSIGNBITAND { $$= Bitand_symbol } + | META_ASSIGNSHLEFT { $$= Shleft_symbol } + | META_ASSIGNSHRIGHT { $$= Shright_symbol } + +meta_switch = META_SWITCH META_LPAREN e:meta_exp META_RPAREN + META_LCB statements:meta_makeMap labels:meta_makeMap + ( META_CASE l:meta_exp META_COLON { map_set(labels, eval(globals, l), makeInteger(map_size(statements))) } + | META_DEFAULT META_COLON { map_set(labels, __default___symbol, makeInteger(map_size(statements))) } + | s:meta_stmt { map_append(statements, s) } + )* + META_RCB { $$= newSwitch(e, labels, statements) } + +meta_cond = c:meta_logor META_QUERY t:meta_exp META_COLON f:meta_cond { $$ = newIf(c, t, f) } + | meta_logor + +meta_logor = l:meta_logand + ( META_LOGOR r:meta_logand { l = newBinary(Logor_proto, l, r) } + )* { $$ = l } + +meta_logand = l:meta_bitor + ( META_LOGAND r:meta_bitor { l = newBinary(Logand_proto, l, r) } + )* { $$ = l } + +meta_bitor = l:meta_bitxor + ( META_BITOR r:meta_bitxor { l = newBinary(Bitor_proto, l, r) } + )* { $$ = l } + +meta_bitxor = l:meta_bitand + ( META_BITXOR r:meta_bitand { l = newBinary(Bitxor_proto, l, r) } + )* { $$ = l } + +meta_bitand = l:meta_eq + ( META_BITAND r:meta_eq { l = newBinary(Bitand_proto, l, r) } + )* { $$ = l } + +meta_eq = l:meta_ineq + ( META_EQUAL r:meta_ineq { l = newBinary(Equal_proto, l, r) } + | META_NOTEQ r:meta_ineq { l = newBinary(Noteq_proto, l, r) } + )* { $$ = l } + +meta_ineq = l:meta_shift + ( META_LESS r:meta_shift { l = newBinary(Less_proto, l, r) } + | META_LESSEQ r:meta_shift { l = newBinary(Lesseq_proto, l, r) } + | META_GREATEREQ r:meta_shift { l = newBinary(Greatereq_proto, l, r) } + | META_GREATER r:meta_shift { l = newBinary(Greater_proto, l, r) } + )* { $$ = l } + +meta_shift = l:meta_sum + ( META_SHLEFT r:meta_sum { l = newBinary(Shleft_proto, l, r) } + | META_SHRIGHT r:meta_sum { l = newBinary(Shright_proto, l, r) } + )* { $$ = l } + +meta_sum = l:meta_prod + ( META_PLUS r:meta_prod { l = newBinary(Add_proto, l, r) } + | META_MINUS r:meta_prod { l = newBinary(Sub_proto, l, r) } + )* { $$ = l } + +meta_prod = l:meta_prefix + ( META_MULTI r:meta_prefix { l = newBinary(Mul_proto, l, r) } + | META_DIVIDE r:meta_prefix { l = newBinary(Div_proto, l, r) } + | META_MODULO r:meta_prefix { l = newBinary(Mod_proto, l, r) } + )* { $$ = l } + +meta_prefix = META_PLUS n:meta_prefix { $$= n } + | META_NEGATE n:meta_prefix { $$= newUnary(Neg_proto, n) } + | META_TILDE n:meta_prefix { $$= newUnary(Com_proto, n) } + | META_PLING n:meta_prefix { $$= newUnary(Not_proto, n) } + | META_PLUSPLUS n:meta_prefix { $$= newPreIncrement(n) } + | META_MINUSMINUS n:meta_prefix { $$= newPreDecrement(n) } +# | META_BACKTICK n:meta_prefix { $$ = newUnary(Quasiquote_proto, n) } +# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } + | n:meta_postfix { $$= n } + +meta_postfix = i:meta_value ( META_DOT s:META_IDENT a:meta_argumentList { i = newInvoke(i, s, a) } + | META_DOT s:META_IDENT !meta_assignOp { i = newGetMap(GetMember_proto, i, s) } + | META_LBRAC p:meta_exp META_RBRAC !meta_assignOp { i = newGetMap(GetIndex_proto, i, p) } + | a:meta_argumentList { i = (null != getSyntax(1, i)) ? apply(globals, globals, getSyntax(1, i), a, i) : newCall(i, a) } + | META_PLUSPLUS { i = newPostIncrement(i) } + | META_MINUSMINUS { i = newPostDecrement(i) } + ) * { $$ = i } + +meta_paramList = META_LPAREN m:meta_makeMap + ( i:META_IDENT { map_append(m, i) } + ( META_COMMA i:META_IDENT { map_append(m, i) } + ) * + ) ? + META_RPAREN { $$ = m } + +meta_argumentList = META_LPAREN m:meta_makeMap + ( e:meta_exp { map_append(m, e) } + ( META_COMMA e:meta_exp { map_append(m, e) } + ) * + ) ? + META_RPAREN { $$ = m } + +meta_value = n:META_FLOAT { $$ = newFloat(n) } + | n:meta_integer { $$ = newInteger(n) } + | s:meta_string { $$ = newString(s) } + | s:meta_symbol { $$ = s } + | m:meta_map { $$ = newMap(m) } + | META_NULL { $$ = null } + | i:META_IDENT { $$ = newGetVariable(i) } + | p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, null) } + | META_LPAREN ( i:meta_block | i:meta_exp ) META_RPAREN { $$ = i } + +meta_string = s:META_STRING - { $$ = s } + +META_STRING = META_DQUOTE < (!META_DQUOTE meta_char)* > META_DQUOTE { $$ = makeString(unescape(yytext)) } + +meta_char = '\\' . | . + +meta_symbol = META_HASH ( i:META_IDENT { $$ = newSymbol(i) } + | i:meta_string { $$ = newSymbol(intern(get(i, String, value))) } + ) + +meta_map = META_LCB m:meta_makeMap + ( k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } + ( META_COMMA k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } + ) * + ) ? + META_RCB { $$ = m } + | META_LBRAC m:meta_makeMap + ( v:meta_exp { map_append(m, v) } + ( META_COMMA v:meta_exp { map_append(m, v) } + ) * + ) ? + META_RBRAC { $$ = m } + +meta_makeMap = { $$ = makeMap() } + +meta_key = META_IDENT | meta_integer + +- = (blank | comment)* + +blank = space | eol +space = [ \t] +eol = ( "\n""\r"* + | "\r""\n"* + ) { inputStack->lineNumber++ } + +comment = "//" ( ![\n\r] . )* + | "/*" ( !"*/" (eol | .) )* "*/" + +meta_keyword = META_SWITCH | META_CASE | META_DEFAULT | META_DO | META_FOR | META_IN | META_WHILE | META_IF | META_ELSE | META_NULL | META_RETURN | META_BREAK | META_CONTINUE + | META_THROW | META_TRY | META_CATCH | META_FINALLY +# | META_SYNTAX + +META_IDENT = !meta_keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) } + +meta_integer = i:META_INTEGER { $$ = i } + | '-' i:meta_integer { $$ = makeInteger(-getInteger(i)) } + +META_INTEGER = '0b' < [01]+ > - { $$ = makeInteger(strtol(yytext, 0, 2)) } + | '0x' < [0-9a-fA-F]+ > - { $$ = makeInteger(strtol(yytext, 0, 16)) } + | '0' < [0-7]+ > - { $$ = makeInteger(strtol(yytext, 0, 8)) } + | < [0-9]+ > - { $$ = makeInteger(strtol(yytext, 0, 10)) } + | META_SQUOTE < (!META_SQUOTE meta_char) > META_SQUOTE - { $$ = makeInteger(unescape(yytext)[0]) } + +META_FLOAT = < [-+]* [0-9]+ '.' [0-9]* ('e'[-+]*[0-9]+)? > - { $$ = makeFloat(strtold(yytext, 0)) } + | < [-+]* [0-9]* '.' [0-9]+ ('e'[-+]*[0-9]+)? > - { $$ = makeFloat(strtold(yytext, 0)) } + | < [-+]* [0-9]+ ('e'[-+]*[0-9]+) > - { $$ = makeFloat(strtold(yytext, 0)) } + +#META_FUN = 'fun' ![a-zA-Z0-9_] - +#META_SYNTAX = 'syntax' ![a-zA-Z0-9_] - +META_VAR = 'var' ![a-zA-Z0-9_] - +META_SWITCH = 'switch' ![a-zA-Z0-9_] - +META_CASE = 'case' ![a-zA-Z0-9_] - +META_DEFAULT = 'default' ![a-zA-Z0-9_] - +META_DO = 'do' ![a-zA-Z0-9_] - +META_FOR = 'for' ![a-zA-Z0-9_] - +META_IN = 'in' ![a-zA-Z0-9_] - +META_WHILE = 'while' ![a-zA-Z0-9_] - +META_IF = 'if' ![a-zA-Z0-9_] - +META_ELSE = 'else' ![a-zA-Z0-9_] - +META_NULL = 'null' ![a-zA-Z0-9_] - +META_RETURN = 'return' ![a-zA-Z0-9_] - +META_BREAK = 'break' ![a-zA-Z0-9_] - +META_CONTINUE = 'continue' ![a-zA-Z0-9_] - +META_THROW = 'throw' ![a-zA-Z0-9_] - +META_TRY = 'try' ![a-zA-Z0-9_] - +META_CATCH = 'catch' ![a-zA-Z0-9_] - +META_FINALLY = 'finally' ![a-zA-Z0-9_] - +META_IMPORT = 'import' ![a-zA-Z0-9_] - +META_HASH = '#' - +META_LOGOR = '||' - +META_LOGAND = '&&' - +META_BITOR = '|' ![|=] - +META_BITXOR = '^' ![=] - +META_BITAND = '&' ![&=] - +META_EQUAL = '==' - +META_NOTEQ = '!=' - +META_LESS = '<' ![<=] - +META_LESSEQ = '<=' - +META_GREATEREQ = '>=' - +META_GREATER = '>' ![>=] - +META_SHLEFT = '<<' ![=] - +META_SHRIGHT = '>>' ![=] - +META_PLUS = '+' ![+=] - +META_MINUS = '-' ![-=] - +META_NEGATE = '-' ![-=0-9.] - +META_PLUSPLUS = '++' - +META_MINUSMINUS = '--' - +META_TILDE = '~' - +META_PLING = '!' ![=] - +META_MULTI = '*' ![=] - +META_DIVIDE = '/' ![/=] - +META_MODULO = '%' ![=] - +META_ASSIGN = '=' ![=] - +META_ASSIGNADD = '+=' - +META_ASSIGNSUB = '-=' - +META_ASSIGNMUL = '*=' - +META_ASSIGNDIV = '/=' - +META_ASSIGNMOD = '%=' - +META_ASSIGNBITOR = '|=' - +META_ASSIGNBITXOR = '^=' - +META_ASSIGNBITAND = '&=' - +META_ASSIGNSHLEFT = '<<=' - +META_ASSIGNSHRIGHT = '>>=' - +META_QUERY = '?' - +META_COLON = ':' - +META_SEMICOLON = ';' - +META_COMMA = ',' - +META_DOT = '.' - +#META_BACKTICK = '`' - +#META_AT = '@' - +META_LCB = '{' - +META_RCB = '}' - +META_LBRAC = '[' - +META_RBRAC = ']' - +META_LPAREN = '(' - +META_RPAREN = ')' - +META_DQUOTE = '"' +META_SQUOTE = "'" %% ; @@ -3800,7 +4229,8 @@ int main(int argc, char **argv) fixScope(globals); - /**/ + /* File scope */ + pushScope(); #define _DO(NAME) set(intern(#NAME), Symbol, is_C_keyword, 1); DO_C_KEYWORDS() @@ -3809,29 +4239,8 @@ int main(int argc, char **argv) } #undef _DO - - /* Checking arguments */ - while (argc-- > 1) { - ++argv; - if (!strcmp(*argv, "-t")) toPrint = 1; - } - - /* File scope */ - pushScope(); - - inputStackPush(NULL); - while (yyparse()) { - if (toPrint) printTree(); - else outputNode(yylval); - } - - popScope(); - assert(!actualScope); - return 0; - - /**/ - int repled = 0; + /* Checking arguments */ while (argc-- > 1) { ++argv; if (!strcmp(*argv, "-g")) ++opt_g; @@ -3857,9 +4266,25 @@ int main(int argc, char **argv) else printf("[GC: %.2f GB allocated]\n", (double)nalloc / (1024*1024*1024)); } + popScope(); + assert(!actualScope); return 0; (void)yyAccept; + + /**/ + + inputStackPush(NULL); + while (yyparse()) { + if (toPrint) printTree(); + else outputNode(yylval); + } + + popScope(); + assert(!actualScope); + return 0; + + /**/ } // Local Variables: