|
@ -3,7 +3,7 @@ |
|
|
# Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS) |
|
|
# Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS) |
|
|
# All rights reserved (see LICENSE) |
|
|
# All rights reserved (see LICENSE) |
|
|
# |
|
|
# |
|
|
# Last edited: 2021-07-12 18:54:53 by piumarta on DESKTOP-LTPREOB |
|
|
|
|
|
|
|
|
# Last edited: 2021-08-16 18:55:57 by piumarta on DESKTOP-GMTB276 |
|
|
|
|
|
|
|
|
%{ |
|
|
%{ |
|
|
/* compile: leg -o ccmeta.c ccmeta.leg |
|
|
/* compile: leg -o ccmeta.c ccmeta.leg |
|
@ -32,6 +32,8 @@ |
|
|
/* _DO(Quasiquote) _DO(Unquote) */ \ |
|
|
/* _DO(Quasiquote) _DO(Unquote) */ \ |
|
|
DO_C_PROTOS() |
|
|
DO_C_PROTOS() |
|
|
|
|
|
|
|
|
|
|
|
#define META_PROTO_MAX t_Try |
|
|
|
|
|
|
|
|
#define DO_C_PROTOS() \ |
|
|
#define DO_C_PROTOS() \ |
|
|
_DO(Comment) _DO(Token) \ |
|
|
_DO(Comment) _DO(Token) \ |
|
|
_DO(C_declaration) _DO(C_string) \ |
|
|
_DO(C_declaration) _DO(C_string) \ |
|
@ -687,8 +689,8 @@ void C_declarationBegin(void) { |
|
|
typedeffing = 0; |
|
|
typedeffing = 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int C_declarationAbort(void) { |
|
|
|
|
|
typedeffing = 0; |
|
|
|
|
|
|
|
|
int C_declarationAbort(void) { |
|
|
|
|
|
typedeffing = 0; |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -711,14 +713,14 @@ void C_scopeEnd(void) { |
|
|
assert(actualScope); |
|
|
assert(actualScope); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int declarationId(char *s) { |
|
|
|
|
|
|
|
|
int declarationId(char *s) { |
|
|
if (!typedeffing) return 0; |
|
|
if (!typedeffing) return 0; |
|
|
addId(s); |
|
|
addId(s); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int isTypedefName(char *s) { |
|
|
|
|
|
if (!isTypedefed(s)) return 0; |
|
|
|
|
|
|
|
|
int isTypedefName(char *s) { |
|
|
|
|
|
if (!isTypedefed(s)) return 0; |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -775,7 +777,7 @@ oop new_C_attributeSpec(oop attributeTok, oop llParen, oop lrParen, oop attribut |
|
|
map_set(object, attributeL_symbol, attributeList); |
|
|
map_set(object, attributeL_symbol, attributeList); |
|
|
map_set(object, rlparen_symbol, rlParen); |
|
|
map_set(object, rlparen_symbol, rlParen); |
|
|
map_set(object, rrparen_symbol, rrParen); |
|
|
map_set(object, rrparen_symbol, rrParen); |
|
|
return object; |
|
|
|
|
|
|
|
|
return object; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop new_C_aggregate(oop lParen, oop typeName, oop rParen, oop leftCurly, oop initList, oop comma, oop rightCurly) { |
|
|
oop new_C_aggregate(oop lParen, oop typeName, oop rParen, oop leftCurly, oop initList, oop comma, oop rightCurly) { |
|
@ -862,7 +864,7 @@ oop new_C_enumerator(oop id, oop attributeSpecifier, oop expression) { |
|
|
|
|
|
|
|
|
#define YYSTYPE oop |
|
|
#define YYSTYPE oop |
|
|
|
|
|
|
|
|
YYSTYPE yylval; |
|
|
|
|
|
|
|
|
YYSTYPE yylval= 0; |
|
|
|
|
|
|
|
|
int errorLine= 1; |
|
|
int errorLine= 1; |
|
|
|
|
|
|
|
@ -897,6 +899,7 @@ oop newToken(char *text) |
|
|
{ |
|
|
{ |
|
|
oop obj = newObject(Token_proto); |
|
|
oop obj = newObject(Token_proto); |
|
|
map_set(obj, text_symbol, makeString(text)); |
|
|
map_set(obj, text_symbol, makeString(text)); |
|
|
|
|
|
icol += strlen(text); |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1238,12 +1241,26 @@ oop newTry(oop try, oop exception, oop catch, oop finally) |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
enum language { |
|
|
|
|
|
META = 0, |
|
|
|
|
|
C = 1, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum language lang = C; |
|
|
|
|
|
|
|
|
%} |
|
|
%} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------- C Grammar -------------------------------------------------# |
|
|
|
|
|
|
|
|
#--------------------------------------------- C grammar -------------------------------------------------# |
|
|
|
|
|
|
|
|
start = meta | externalDeclaration |
|
|
|
|
|
|
|
|
# yylval == null => "pseudo" op, e.g., change language -- ignored by REPL |
|
|
|
|
|
# yylval == 0 => end of input file while in META mode only |
|
|
|
|
|
|
|
|
|
|
|
start = META_AT META_LPAREN s:meta_exp META_RPAREN { yylval= s } |
|
|
|
|
|
| META_AT META_LCB { yylval= null; lang= META } |
|
|
|
|
|
| &{ lang == META } - s:meta { yylval= s } |
|
|
|
|
|
| &{ lang == META } - META_RCB { yylval= null; lang= C } |
|
|
|
|
|
| &{ lang == C } s:externalDeclaration { yylval= s } |
|
|
|
|
|
|
|
|
error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } |
|
|
error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } |
|
|
|
|
|
|
|
@ -1532,7 +1549,7 @@ declaration = @{ C_declarationBegin() } |
|
|
@{ C_declarationEnd() } |
|
|
@{ C_declarationEnd() } |
|
|
| |
|
|
| |
|
|
&{ C_declarationAbort() } |
|
|
&{ C_declarationAbort() } |
|
|
) |
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
declarationSpecifiers = @{ int specified= 0 } { listBegin() } |
|
|
declarationSpecifiers = @{ int specified= 0 } { listBegin() } |
|
|
( s:storageClassSpecifier { listAppend(s) } |
|
|
( s:storageClassSpecifier { listAppend(s) } |
|
@ -1568,7 +1585,7 @@ functionStorageClassSpecifier = EXTERN | STATIC |
|
|
|
|
|
|
|
|
# 6.7.2 |
|
|
# 6.7.2 |
|
|
|
|
|
|
|
|
typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX |
|
|
|
|
|
|
|
|
typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX |
|
|
| ( BUILTIN_VA_LIST | _FLOAT128 ) |
|
|
| ( BUILTIN_VA_LIST | _FLOAT128 ) |
|
|
| structOrUnionSpecifier |
|
|
| structOrUnionSpecifier |
|
|
| enumSpecifier |
|
|
| enumSpecifier |
|
@ -1643,7 +1660,7 @@ enumerator = i:id |
|
|
|
|
|
|
|
|
# 6.7.3 |
|
|
# 6.7.3 |
|
|
|
|
|
|
|
|
typeQualifier = CONST | RESTRICT | VOLATILE |
|
|
|
|
|
|
|
|
typeQualifier = CONST | RESTRICT | VOLATILE |
|
|
| __RESTRICT |
|
|
| __RESTRICT |
|
|
|
|
|
|
|
|
# 6.7.4 |
|
|
# 6.7.4 |
|
@ -1814,7 +1831,7 @@ expressionStatement = SEMI |
|
|
|
|
|
|
|
|
# 6.8.4 |
|
|
# 6.8.4 |
|
|
|
|
|
|
|
|
selectionStatement = i:IF l:LPAREN x:expression r:RPAREN s:statement |
|
|
|
|
|
|
|
|
selectionStatement = i:IF l:LPAREN x:expression r:RPAREN s:statement |
|
|
( e:ELSE t:statement | {e=t=newNullObject()} ) { $$= new_C_if(i, l, x, r, s, e, t) } |
|
|
( e:ELSE t:statement | {e=t=newNullObject()} ) { $$= new_C_if(i, l, x, r, s, e, t) } |
|
|
| s:SWITCH l:LPAREN x:expression r:RPAREN t:statement { $$= new_C_switch(s, l, x, r, t) } |
|
|
| s:SWITCH l:LPAREN x:expression r:RPAREN t:statement { $$= new_C_switch(s, l, x, r, t) } |
|
|
|
|
|
|
|
@ -1839,13 +1856,12 @@ jumpStatement = g:GOTO i:id t:SEMI { $$= new_C_goto(g, newNullObject(), i |
|
|
|
|
|
|
|
|
# 6.9 |
|
|
# 6.9 |
|
|
|
|
|
|
|
|
translationUnit = externalDeclaration+ |
|
|
|
|
|
|
|
|
## translationUnit = externalDeclaration+ |
|
|
|
|
|
|
|
|
externalDeclaration = <Space+> { yylval = newComment(yytext); } |
|
|
externalDeclaration = <Space+> { yylval = newComment(yytext); } |
|
|
| ( SEMI &{gnu} |
|
|
| ( SEMI &{gnu} |
|
|
| declaration |
|
|
| declaration |
|
|
| functionDefinition |
|
|
| functionDefinition |
|
|
#| meta |
|
|
|
|
|
| &. &{ errmsg= "declaration expected" } error |
|
|
| &. &{ errmsg= "declaration expected" } error |
|
|
) { yylval= $$; } |
|
|
) { yylval= $$; } |
|
|
|
|
|
|
|
@ -1978,6 +1994,7 @@ COLON = ':' { $$= newToken(":" ) } - |
|
|
COMMA = ',' { $$= newToken("," ) } - |
|
|
COMMA = ',' { $$= newToken("," ) } - |
|
|
QUESTION = '?' { $$= newToken("?" ) } - |
|
|
QUESTION = '?' { $$= newToken("?" ) } - |
|
|
SEMI = ';' { $$= newToken(";" ) } - |
|
|
SEMI = ';' { $$= newToken(";" ) } - |
|
|
|
|
|
|
|
|
PTR = "->" { $$= newToken("->" ) } - |
|
|
PTR = "->" { $$= newToken("->" ) } - |
|
|
|
|
|
|
|
|
DOT = '.' !'.' { $$= newToken("." ) } - |
|
|
DOT = '.' !'.' { $$= newToken("." ) } - |
|
@ -2084,32 +2101,45 @@ __INLINE = '__inline' !IDREST &{gnu} { $$= newToken("__inlin |
|
|
_FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - |
|
|
_FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------- Common rules ----------------------------------------------# |
|
|
|
|
|
|
|
|
#--------------------------------------------- Meta Grammar ----------------------------------------------# |
|
|
|
|
|
|
|
|
- = (blank | comment)* |
|
|
|
|
|
|
|
|
meta = - ( META_IMPORT s:META_STRING META_SEMICOLON { yylval = null; inputStackPush(get(s, String, value)) } |
|
|
|
|
|
| s:meta_stmt { yylval = s } |
|
|
|
|
|
| !. { yylval = 0 } |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
blank = space | eol |
|
|
|
|
|
space = [ \t] |
|
|
|
|
|
eol = ( "\n""\r"* |
|
|
|
|
|
| "\r""\n"* |
|
|
|
|
|
) { inputStack->lineNumber++ } |
|
|
|
|
|
|
|
|
|
|
|
comment = "//" ( ![\n\r] . )* |
|
|
|
|
|
| "/*" ( !"*/" (eol | .) )* "*/" |
|
|
|
|
|
|
|
|
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 grammar ----------------------------------------------# |
|
|
|
|
|
|
|
|
|
|
|
# the semicolon has to be explicit with no space eaten afterwards to prevent the |
|
|
|
|
|
# input buffer from moving past it before redirecting input from the imported file |
|
|
|
|
|
|
|
|
|
|
|
meta = META_IMPORT s:META_STRING ";" { $$ = null; inputStackPush(get(s, String, value)) } |
|
|
|
|
|
| s:meta_stmt { $$ = s } |
|
|
|
|
|
| !. { $$ = 0 } # signal end of current input file |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
meta_block = META_LCB m:meta_makeMap |
|
|
( s:meta_stmt { map_append(m, s) } |
|
|
( s:meta_stmt { map_append(m, s) } |
|
@ -2281,17 +2311,6 @@ meta_makeMap = { $$ = makeMap() } |
|
|
|
|
|
|
|
|
meta_key = META_IDENT | meta_integer |
|
|
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_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_THROW | META_TRY | META_CATCH | META_FINALLY |
|
|
# | META_SYNTAX |
|
|
# | META_SYNTAX |
|
@ -2373,7 +2392,7 @@ META_SEMICOLON = ';' - |
|
|
META_COMMA = ',' - |
|
|
META_COMMA = ',' - |
|
|
META_DOT = '.' - |
|
|
META_DOT = '.' - |
|
|
#META_BACKTICK = '`' - |
|
|
#META_BACKTICK = '`' - |
|
|
#META_AT = '@' - |
|
|
|
|
|
|
|
|
META_AT = '@' - |
|
|
META_LCB = '{' - |
|
|
META_LCB = '{' - |
|
|
META_RCB = '}' - |
|
|
META_RCB = '}' - |
|
|
META_LBRAC = '[' - |
|
|
META_LBRAC = '[' - |
|
@ -3283,7 +3302,7 @@ oop eval(oop scope, oop ast) |
|
|
} |
|
|
} |
|
|
#define _DO(NAME) case t_##NAME: |
|
|
#define _DO(NAME) case t_##NAME: |
|
|
DO_C_PROTOS(); |
|
|
DO_C_PROTOS(); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
#undef _DO |
|
|
#undef _DO |
|
|
} |
|
|
} |
|
|
printf("EVAL "); |
|
|
printf("EVAL "); |
|
@ -3376,6 +3395,9 @@ oop evalArgs(oop scope, oop args) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop AST= NULL; |
|
|
oop AST= NULL; |
|
|
|
|
|
oop outputProgram= 0; |
|
|
|
|
|
|
|
|
|
|
|
void outputNode(oop node); |
|
|
|
|
|
|
|
|
void readEvalPrint(oop scope, char *fileName) |
|
|
void readEvalPrint(oop scope, char *fileName) |
|
|
{ |
|
|
{ |
|
@ -3387,14 +3409,33 @@ void readEvalPrint(oop scope, char *fileName) |
|
|
|
|
|
|
|
|
if (0 == jbt) { |
|
|
if (0 == jbt) { |
|
|
while (yyparse()) { |
|
|
while (yyparse()) { |
|
|
if (opt_v > 1) printf("%s:%i: ", get(inputStack->name, String, value), inputStack->lineNumber); |
|
|
|
|
|
if (!yylval) { |
|
|
|
|
|
|
|
|
if (!yylval) { // EOF |
|
|
fclose(inputStack->file); |
|
|
fclose(inputStack->file); |
|
|
if (top == inputStack) break; |
|
|
if (top == inputStack) break; |
|
|
inputStackPop(); |
|
|
inputStackPop(); |
|
|
assert(inputStack); |
|
|
assert(inputStack); |
|
|
continue; |
|
|
continue; |
|
|
} // EOF |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
assert(yylval); |
|
|
|
|
|
if (null == yylval) { // change of language or input file |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
oop proto = map_get(yylval, __proto___symbol); |
|
|
|
|
|
if (proto == null) { |
|
|
|
|
|
printf("no prototype associated with "); |
|
|
|
|
|
println(yylval); |
|
|
|
|
|
fflush(stdout); |
|
|
|
|
|
fprintf(stderr, "aborting\n"); |
|
|
|
|
|
exit(1); |
|
|
|
|
|
} |
|
|
|
|
|
// proto_number is the enum version of the proto symbol |
|
|
|
|
|
proto_t proto_number = get(map_get(proto, __name___symbol), Symbol, prototype); |
|
|
|
|
|
if (proto_number > META_PROTO_MAX) { |
|
|
|
|
|
if (opt_v > 1) println(yylval); |
|
|
|
|
|
map_append(outputProgram, yylval); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
if (opt_v > 1) printf("%s:%i: ", get(inputStack->name, String, value), inputStack->lineNumber); |
|
|
if (opt_v > 1) println(yylval); |
|
|
if (opt_v > 1) println(yylval); |
|
|
oop res = eval(scope, yylval); |
|
|
oop res = eval(scope, yylval); |
|
|
if (opt_v > 0) println(res); |
|
|
if (opt_v > 0) println(res); |
|
@ -3613,15 +3654,15 @@ void outputNode(oop node) |
|
|
case t_C_prefix: |
|
|
case t_C_prefix: |
|
|
outputNode(map_get(node, operator_symbol)); |
|
|
outputNode(map_get(node, operator_symbol)); |
|
|
outputNode(map_get(node, expression_symbol)); |
|
|
outputNode(map_get(node, expression_symbol)); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
case t_C_postfix: |
|
|
case t_C_postfix: |
|
|
outputNode(map_get(node, expression_symbol)); |
|
|
outputNode(map_get(node, expression_symbol)); |
|
|
outputNode(map_get(node, operator_symbol)); |
|
|
outputNode(map_get(node, operator_symbol)); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
case t_C_unary: |
|
|
case t_C_unary: |
|
|
outputNode(map_get(node, operator_symbol)); |
|
|
outputNode(map_get(node, operator_symbol)); |
|
|
outputNode(map_get(node, expression_symbol)); |
|
|
outputNode(map_get(node, expression_symbol)); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
case t_C_binary: |
|
|
case t_C_binary: |
|
|
outputNode(map_get(node, lhs_symbol)); |
|
|
outputNode(map_get(node, lhs_symbol)); |
|
|
outputNode(map_get(node, binary_symbol)); |
|
|
outputNode(map_get(node, binary_symbol)); |
|
@ -3828,7 +3869,7 @@ void outputValue(oop node) { |
|
|
void printSpace(int depth) { |
|
|
void printSpace(int depth) { |
|
|
for (int i = 0 ; i < depth ; i++) { |
|
|
for (int i = 0 ; i < depth ; i++) { |
|
|
printf(" "); |
|
|
printf(" "); |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void outputTree(oop node, int depth) |
|
|
void outputTree(oop node, int depth) |
|
@ -3893,7 +3934,7 @@ void outputTree(oop node, int depth) |
|
|
OUT(consequent); |
|
|
OUT(consequent); |
|
|
OUT(elseTok); |
|
|
OUT(elseTok); |
|
|
OUT(alternate); |
|
|
OUT(alternate); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
CASE(while) |
|
|
CASE(while) |
|
|
OUT(whileTok); |
|
|
OUT(whileTok); |
|
|
OUT(lparen); |
|
|
OUT(lparen); |
|
@ -3986,15 +4027,15 @@ void outputTree(oop node, int depth) |
|
|
CASE(prefix) |
|
|
CASE(prefix) |
|
|
OUT(operator); |
|
|
OUT(operator); |
|
|
OUT(expression); |
|
|
OUT(expression); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
CASE(postfix) |
|
|
CASE(postfix) |
|
|
OUT(expression); |
|
|
OUT(expression); |
|
|
OUT(operator); |
|
|
OUT(operator); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
CASE(unary) |
|
|
CASE(unary) |
|
|
OUT(operator); |
|
|
OUT(operator); |
|
|
OUT(expression); |
|
|
OUT(expression); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
CASE(binary) |
|
|
CASE(binary) |
|
|
OUT(lhs); |
|
|
OUT(lhs); |
|
|
OUT(binary); |
|
|
OUT(binary); |
|
@ -4190,6 +4231,7 @@ int main(int argc, char **argv) |
|
|
|
|
|
|
|
|
symbol_table= makeMap(); |
|
|
symbol_table= makeMap(); |
|
|
globals= makeMap(); |
|
|
globals= makeMap(); |
|
|
|
|
|
outputProgram= makeMap(); |
|
|
|
|
|
|
|
|
map_set(globals, intern("exit" ), makeFunction(prim_exit, intern("exit" ), null, null, globals, null)); |
|
|
map_set(globals, intern("exit" ), makeFunction(prim_exit, intern("exit" ), null, null, globals, null)); |
|
|
map_set(globals, intern("keys" ), makeFunction(prim_keys, intern("keys" ), null, null, globals, null)); |
|
|
map_set(globals, intern("keys" ), makeFunction(prim_keys, intern("keys" ), null, null, globals, null)); |
|
@ -4259,6 +4301,11 @@ int main(int argc, char **argv) |
|
|
readEvalPrint(globals, NULL); |
|
|
readEvalPrint(globals, NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (size_t i= 0; i < map_size(outputProgram); ++i) { |
|
|
|
|
|
oop element= get(outputProgram, Map, elements)[i].value; |
|
|
|
|
|
outputNode(element); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (opt_g) { |
|
|
if (opt_g) { |
|
|
if (nalloc < 1024) printf("[GC: %lli bytes allocated]\n", nalloc ); |
|
|
if (nalloc < 1024) printf("[GC: %lli bytes allocated]\n", nalloc ); |
|
|
else if (nalloc < 1024*1024) printf("[GC: %lli kB allocated]\n", nalloc / 1024 ); |
|
|
else if (nalloc < 1024*1024) printf("[GC: %lli kB allocated]\n", nalloc / 1024 ); |
|
|