|
@ -161,15 +161,16 @@ void runtimeError(char *fmt, ...); |
|
|
|
|
|
|
|
|
typedef struct input_t |
|
|
typedef struct input_t |
|
|
{ |
|
|
{ |
|
|
oop name; |
|
|
|
|
|
FILE *file; |
|
|
|
|
|
struct input_t *next; |
|
|
|
|
|
int lineNumber; |
|
|
|
|
|
|
|
|
struct input_t *next; |
|
|
|
|
|
oop name; |
|
|
|
|
|
FILE *file; |
|
|
|
|
|
struct _yycontext *yy; |
|
|
|
|
|
int lineNumber; |
|
|
} input_t; |
|
|
} input_t; |
|
|
|
|
|
|
|
|
input_t *inputStack= NULL; |
|
|
input_t *inputStack= NULL; |
|
|
|
|
|
|
|
|
void inputStackPush(char *name) { |
|
|
|
|
|
|
|
|
void inputStackPush(struct _yycontext *yy, char *name) { |
|
|
FILE *file = stdin; |
|
|
FILE *file = stdin; |
|
|
if (NULL != name) { |
|
|
if (NULL != name) { |
|
|
file= fopen(name, "rb"); |
|
|
file= fopen(name, "rb"); |
|
@ -181,21 +182,25 @@ void inputStackPush(char *name) { |
|
|
name= "<stdin>"; |
|
|
name= "<stdin>"; |
|
|
} |
|
|
} |
|
|
input_t *input = malloc(sizeof(input_t)); |
|
|
input_t *input = malloc(sizeof(input_t)); |
|
|
|
|
|
input->next= inputStack; |
|
|
input->name= makeString(name); |
|
|
input->name= makeString(name); |
|
|
input->lineNumber= 1; |
|
|
input->lineNumber= 1; |
|
|
input->file= file; |
|
|
input->file= file; |
|
|
input->next= inputStack; |
|
|
|
|
|
|
|
|
input->yy= yy; |
|
|
inputStack= input; |
|
|
inputStack= input; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
input_t *inputStackPop(void) { |
|
|
input_t *inputStackPop(void) { |
|
|
assert(inputStack); |
|
|
assert(inputStack); |
|
|
|
|
|
fclose(inputStack->file); |
|
|
input_t *first= inputStack; |
|
|
input_t *first= inputStack; |
|
|
inputStack= first->next; |
|
|
inputStack= first->next; |
|
|
return first; |
|
|
return first; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void readEvalPrint(oop scope, char *fileName); |
|
|
|
|
|
|
|
|
int isFalse(oop obj) |
|
|
int isFalse(oop obj) |
|
|
{ |
|
|
{ |
|
|
return obj == null || (isInteger(obj) && (0 == getInteger(obj))); |
|
|
return obj == null || (isInteger(obj) && (0 == getInteger(obj))); |
|
@ -902,10 +907,12 @@ oop new_C_enumerator(oop id, oop attributeSpecifier, oop expression) { |
|
|
return object; |
|
|
return object; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//TODO |
|
|
|
|
|
#define YY_INPUT(buf, result, max_size) \ |
|
|
|
|
|
|
|
|
#define YY_CTX_LOCAL 1 // allocate parser contexts explicitly |
|
|
|
|
|
#define YY_CTX_MEMBERS input_t *input; // pointer back to our input structure |
|
|
|
|
|
|
|
|
|
|
|
#define YY_INPUT(yy, buf, result, max_size) \ |
|
|
{ \ |
|
|
{ \ |
|
|
int yyc= feof(inputStack->file) ? EOF : getc(inputStack->file); \ |
|
|
|
|
|
|
|
|
int yyc= feof(yy->input->file) ? EOF : getc(yy->input->file); \ |
|
|
result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ |
|
|
result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -925,7 +932,7 @@ oop eval(oop scope, oop ast); |
|
|
|
|
|
|
|
|
struct _yycontext; |
|
|
struct _yycontext; |
|
|
|
|
|
|
|
|
int yyparsefrom(int (*yystart)(struct _yycontext *yy)); |
|
|
|
|
|
|
|
|
int yyparsefrom(struct _yycontext *yy, int (*yystart)(struct _yycontext *yy)); |
|
|
|
|
|
|
|
|
int irow= 0, icol= 0; |
|
|
int irow= 0, icol= 0; |
|
|
int gnu= 1; |
|
|
int gnu= 1; |
|
@ -1491,7 +1498,10 @@ hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hex |
|
|
|
|
|
|
|
|
# constant rule |
|
|
# constant rule |
|
|
|
|
|
|
|
|
constant = characterConstant |
|
|
|
|
|
|
|
|
# constant = META_AT @{puts("-----------------------------------------")} |
|
|
|
|
|
# < [a-zA-Z][a-zA-Z0-9]* > |
|
|
|
|
|
# x:@{ printf("<%s>\n", yytext); exit(0) } { $$ = x } |
|
|
|
|
|
constant = characterConstant |
|
|
| floatingConstant |
|
|
| floatingConstant |
|
|
| integerConstant |
|
|
| integerConstant |
|
|
| META_AT m:mvalue |
|
|
| META_AT m:mvalue |
|
@ -1589,8 +1599,8 @@ sCharSequence = ( escapeSequence | !EOL [^\"\\] )* #" |
|
|
# primaryExpression rule |
|
|
# primaryExpression rule |
|
|
|
|
|
|
|
|
primaryExpression = stringLiteral | constant | id |
|
|
primaryExpression = stringLiteral | constant | id |
|
|
| META_AT ( META_LCB x:mstmts |
|
|
|
|
|
| x:mvalue |
|
|
|
|
|
|
|
|
| META_AT ( META_LCB mstmts |
|
|
|
|
|
| mvalue |
|
|
) |
|
|
) |
|
|
| l:LPAREN x:expression r:RPAREN { $$= new_C_subexpr(l, x, r) } |
|
|
| l:LPAREN x:expression r:RPAREN { $$= new_C_subexpr(l, x, r) } |
|
|
| l:LPAREN x:compoundStatement r:RPAREN &{gnu} { $$= new_C_subexpr(l, x, r) } |
|
|
| l:LPAREN x:compoundStatement r:RPAREN &{gnu} { $$= new_C_subexpr(l, x, r) } |
|
@ -1739,7 +1749,7 @@ constantExpression = conditionalExpression |
|
|
|
|
|
|
|
|
# declaration rule |
|
|
# declaration rule |
|
|
|
|
|
|
|
|
declaration = @{ C_declarationBegin() } |
|
|
|
|
|
|
|
|
declaration = @{ C_declarationBegin() } |
|
|
( s:declarationSpecifiers |
|
|
( s:declarationSpecifiers |
|
|
d:initDeclaratorListOpt |
|
|
d:initDeclaratorListOpt |
|
|
t:SEMI { $$= new_C_declaration(s, d, t) } |
|
|
t:SEMI { $$= new_C_declaration(s, d, t) } |
|
@ -2292,7 +2302,7 @@ _FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" |
|
|
# the semicolon has to be explicit with no space eaten afterwards to prevent the |
|
|
# 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 |
|
|
# input buffer from moving past it before redirecting input from the imported file |
|
|
|
|
|
|
|
|
metaCatch = META_AT ( META_IMPORT s:META_STRING ";" { inputStackPush(get(s, String, value)) ; $$= 0 } |
|
|
|
|
|
|
|
|
metaCatch = META_AT ( META_IMPORT s:META_STRING ";" { readEvalPrint(globals, get(s, String, value)) ; $$= 0 } |
|
|
| m:mvalue { $$= m } |
|
|
| m:mvalue { $$= m } |
|
|
| META_LCB s:mstmts { $$= s } |
|
|
| META_LCB s:mstmts { $$= s } |
|
|
) |
|
|
) |
|
@ -3665,21 +3675,23 @@ void printTree(oop element, language id); |
|
|
|
|
|
|
|
|
void readEvalPrint(oop scope, char *fileName) |
|
|
void readEvalPrint(oop scope, char *fileName) |
|
|
{ |
|
|
{ |
|
|
// TODO |
|
|
|
|
|
inputStackPush(fileName); |
|
|
|
|
|
|
|
|
struct _yycontext ctx = { 0, 0 }; |
|
|
|
|
|
inputStackPush(&ctx, fileName); |
|
|
input_t *top= inputStack; |
|
|
input_t *top= inputStack; |
|
|
|
|
|
ctx.input = top; |
|
|
jbRecPush(); |
|
|
jbRecPush(); |
|
|
jb_record *jtop= jbs; |
|
|
jb_record *jtop= jbs; |
|
|
int jbt= sigsetjmp(jbs->jb, 0); |
|
|
int jbt= sigsetjmp(jbs->jb, 0); |
|
|
|
|
|
|
|
|
if (0 == jbt) { |
|
|
if (0 == jbt) { |
|
|
while (yyparse()) { |
|
|
|
|
|
|
|
|
while (yyparse(&ctx)) { |
|
|
if (!yylval) { // EOF |
|
|
if (!yylval) { // EOF |
|
|
fclose(inputStack->file); |
|
|
|
|
|
if (top == inputStack) break; |
|
|
|
|
|
inputStackPop(); |
|
|
|
|
|
assert(inputStack); |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
assert(top == inputStack); |
|
|
|
|
|
break; |
|
|
|
|
|
// fclose(inputStack->file); |
|
|
|
|
|
// if (top == inputStack) break; |
|
|
|
|
|
// inputStackPop(); |
|
|
|
|
|
// assert(inputStack); |
|
|
|
|
|
// continue; |
|
|
} |
|
|
} |
|
|
assert(yylval); |
|
|
assert(yylval); |
|
|
if (null == yylval) { // change of language or input file |
|
|
if (null == yylval) { // change of language or input file |
|
@ -3739,10 +3751,6 @@ oop prim_import(oop scope, oop params) |
|
|
{ |
|
|
{ |
|
|
if (map_hasIntegerKey(params, 0)) { |
|
|
if (map_hasIntegerKey(params, 0)) { |
|
|
char *file= get(get(params, Map, elements)[0].value, String, value); |
|
|
char *file= get(get(params, Map, elements)[0].value, String, value); |
|
|
if (yyctx->__pos < yyctx->__limit) { |
|
|
|
|
|
yyctx->__limit--; |
|
|
|
|
|
ungetc(yyctx->__buf[yyctx->__limit], inputStack->file); |
|
|
|
|
|
} |
|
|
|
|
|
readEvalPrint(scope, file); |
|
|
readEvalPrint(scope, file); |
|
|
} |
|
|
} |
|
|
return null; |
|
|
return null; |
|
@ -3759,34 +3767,23 @@ oop prim_scope(oop scope, oop params) |
|
|
return fixScope(scope); |
|
|
return fixScope(scope); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// TODO |
|
|
|
|
|
oop prim_parseFrom(oop scope, oop params) |
|
|
oop prim_parseFrom(oop scope, oop params) |
|
|
{ |
|
|
{ |
|
|
if (map_size(params) != 1) return null; |
|
|
if (map_size(params) != 1) return null; |
|
|
oop name = get(params, Map, elements)[0].value; |
|
|
oop name = get(params, Map, elements)[0].value; |
|
|
if (!is(String, name)) return null; |
|
|
if (!is(String, name)) return null; |
|
|
char *s = get(name, String, value); |
|
|
char *s = get(name, String, value); |
|
|
struct _yycontext *yy = yyctx; |
|
|
|
|
|
if (!strcmp(s, "declaration")) { |
|
|
|
|
|
oop res = yyparsefrom(yy_declaration) ? __ : null ; |
|
|
|
|
|
yylval = res; |
|
|
|
|
|
return res; |
|
|
|
|
|
} else if (!strcmp(s, "expression")) { |
|
|
|
|
|
oop res = yyparsefrom(yy_expression) ? __ : null ; |
|
|
|
|
|
yylval = res; |
|
|
|
|
|
return res; |
|
|
|
|
|
} else if (!strcmp(s, "statement")) { |
|
|
|
|
|
oop res = yyparsefrom(yy_statement) ? __ : null ; |
|
|
|
|
|
yylval = res; |
|
|
|
|
|
return res; |
|
|
|
|
|
} else if (!strcmp(s, "id")) { |
|
|
|
|
|
oop res = yyparsefrom(yy_id) ? __ : null ; |
|
|
|
|
|
yylval = res; |
|
|
|
|
|
return res; |
|
|
|
|
|
} else if (!strcmp(s, "func")) { |
|
|
|
|
|
oop res = yyparsefrom(yy_functionDefinition) ? __ : null ; |
|
|
|
|
|
yylval = res; |
|
|
|
|
|
return res; |
|
|
|
|
|
|
|
|
assert(inputStack); |
|
|
|
|
|
struct _yycontext *yy = inputStack->yy; |
|
|
|
|
|
if (!strcmp(s, "declaration" )) return yylval = yyparsefrom(yy, yy_declaration ) ? __ : null ; |
|
|
|
|
|
else if (!strcmp(s, "expression" )) return yylval = yyparsefrom(yy, yy_expression ) ? __ : null ; |
|
|
|
|
|
else if (!strcmp(s, "statement" )) return yylval = yyparsefrom(yy, yy_statement ) ? __ : null ; |
|
|
|
|
|
else if (!strcmp(s, "id" )) return yylval = yyparsefrom(yy, yy_id ) ? __ : null ; |
|
|
|
|
|
else if (!strcmp(s, "func" )) return yylval = yyparsefrom(yy, yy_functionDefinition) ? __ : null ; |
|
|
|
|
|
else if (!strcmp(s, "error" )) return yylval = yyparsefrom(yy, yy_error) ? __ : null ; |
|
|
|
|
|
else { |
|
|
|
|
|
fprintf(stderr, "parseFrom: %s not implemented", s); |
|
|
|
|
|
exit(1); |
|
|
} |
|
|
} |
|
|
printf("%s expected\n", s); |
|
|
printf("%s expected\n", s); |
|
|
return null; |
|
|
return null; |
|
|