File grammar.y changed (mode: 100644) (index b8c3220..732bc52) |
... |
... |
int main(int argc, char **argv) |
130 |
130 |
%token INTLIT |
%token INTLIT |
131 |
131 |
%token REALLIT |
%token REALLIT |
132 |
132 |
%token UNITTYPEINT |
%token UNITTYPEINT |
133 |
|
%token DERECTIVE |
|
|
133 |
|
%token RETURNBUG |
134 |
134 |
|
|
135 |
135 |
%right EQUALS |
%right EQUALS |
136 |
136 |
%left AND |
%left AND |
|
... |
... |
funcdefns: /* empty */ |
160 |
160 |
; |
; |
161 |
161 |
|
|
162 |
162 |
globdefs: /* empty */ |
globdefs: /* empty */ |
163 |
|
| GLOBALS newline vardecls ENDGLOBALS endglobalsmarker |
|
|
163 |
|
| GLOBALS NEWLINE vardecls ENDGLOBALS endglobalsmarker |
164 |
164 |
| GLOBALS vardecls ENDGLOBALS endglobalsmarker {yyerrorline(0, lineno - 1, "Missing linebreak before global declaration");} |
| GLOBALS vardecls ENDGLOBALS endglobalsmarker {yyerrorline(0, lineno - 1, "Missing linebreak before global declaration");} |
165 |
165 |
; |
; |
166 |
166 |
|
|
|
... |
... |
vardecls: /* empty */ |
171 |
171 |
| vd vardecls |
| vd vardecls |
172 |
172 |
; |
; |
173 |
173 |
|
|
174 |
|
vd: newline |
|
|
174 |
|
vd: NEWLINE |
175 |
175 |
| vardecl |
| vardecl |
176 |
176 |
; |
; |
177 |
177 |
|
|
|
... |
... |
funcdecls: /* empty */ |
179 |
179 |
| fd funcdecls |
| fd funcdecls |
180 |
180 |
; |
; |
181 |
181 |
|
|
182 |
|
fd: newline |
|
|
182 |
|
fd: NEWLINE |
183 |
183 |
| funcdecl |
| funcdecl |
184 |
184 |
; |
; |
185 |
185 |
|
|
|
... |
... |
typedefs: /* empty */ |
187 |
187 |
| td typedefs |
| td typedefs |
188 |
188 |
; |
; |
189 |
189 |
|
|
190 |
|
td: newline |
|
|
190 |
|
td: NEWLINE |
191 |
191 |
| typedef |
| typedef |
192 |
192 |
; |
; |
193 |
193 |
|
|
|
... |
... |
funccall: rid LPAREN exprlistcompl RPAREN { |
305 |
305 |
$$.ty = fd->ret; |
$$.ty = fd->ret; |
306 |
306 |
} |
} |
307 |
307 |
} |
} |
308 |
|
| rid LPAREN exprlistcompl newline { |
|
|
308 |
|
| rid LPAREN exprlistcompl NEWLINE { |
309 |
309 |
yyerrorex(0, "Missing ')'"); |
yyerrorex(0, "Missing ')'"); |
310 |
310 |
struct funcdecl *fd = lookup(&functions, $1.str); |
struct funcdecl *fd = lookup(&functions, $1.str); |
311 |
311 |
if (fd == NULL) { |
if (fd == NULL) { |
|
... |
... |
nativefuncdecl: NATIVE rid TAKES optparam_list RETURNS opttype |
382 |
382 |
} |
} |
383 |
383 |
; |
; |
384 |
384 |
|
|
385 |
|
funcdefn: newline |
|
386 |
|
| funcdefncore |
|
|
385 |
|
funcdefn: NEWLINE |
|
386 |
|
| rbannotation funcdefncore |
387 |
387 |
| statement { yyerrorex(0, "Statement outside of function"); } |
| statement { yyerrorex(0, "Statement outside of function"); } |
388 |
388 |
; |
; |
389 |
389 |
|
|
390 |
|
derectives: /* empty */ |
|
391 |
|
| DERECTIVE derectives |
|
|
390 |
|
rbannotation: /* empty */ |
|
391 |
|
| RETURNBUG NEWLINE { prevreturnbug = returnbug; returnbug = 1; } |
392 |
392 |
; |
; |
393 |
393 |
|
|
394 |
|
funcdefncore: derectives funcbegin localblock codeblock funcend { |
|
|
394 |
|
funcdefncore: funcbegin localblock codeblock funcend { |
395 |
395 |
if(retval != gNothing) { |
if(retval != gNothing) { |
396 |
|
if(!getTypeTag($4.ty)) |
|
|
396 |
|
if(!getTypeTag($3.ty)) |
397 |
397 |
yyerrorline(1, lineno - 1, "Missing return"); |
yyerrorline(1, lineno - 1, "Missing return"); |
398 |
398 |
else if (returnbug) |
else if (returnbug) |
399 |
|
canconvertreturn($4.ty, retval, -1); |
|
|
399 |
|
canconvertreturn($3.ty, retval, -1); |
400 |
400 |
} |
} |
401 |
401 |
} |
} |
402 |
|
| derectives funcbegin localblock codeblock {yyerrorex(0, "Missing endfunction"); clear(¶ms); clear(&locals); clear(&initialized); curtab = &globals;} |
|
|
402 |
|
| funcbegin localblock codeblock {yyerrorex(0, "Missing endfunction"); clear(¶ms); clear(&locals); clear(&initialized); curtab = &globals;} |
403 |
403 |
; |
; |
404 |
404 |
|
|
405 |
|
funcend: ENDFUNCTION { clear(¶ms); clear(&locals); clear(&initialized); curtab = &globals; inblock = 0; inconstant = 0; infunction = 0; } |
|
|
405 |
|
funcend: ENDFUNCTION { clear(¶ms); clear(&locals); clear(&initialized); curtab = &globals; inblock = 0; inconstant = 0; infunction = 0; returnbug = prevreturnbug;} |
406 |
406 |
; |
; |
407 |
407 |
|
|
408 |
408 |
returnorreturns: RETURNS |
returnorreturns: RETURNS |
|
... |
... |
codeblock: /* empty */ { $$.ty = gEmpty; } |
498 |
498 |
} |
} |
499 |
499 |
; |
; |
500 |
500 |
|
|
501 |
|
statement: newline { $$.ty = gEmpty; } |
|
502 |
|
| CALL funccall newline{ $$.ty = gAny;} |
|
|
501 |
|
statement: NEWLINE { $$.ty = gEmpty; } |
|
502 |
|
| CALL funccall NEWLINE{ $$.ty = gAny;} |
503 |
503 |
/*1 2 3 4 5 6 7 8 9 */ |
/*1 2 3 4 5 6 7 8 9 */ |
504 |
|
| IF expr THEN newline codeblock elsifseq elseseq ENDIF newline { |
|
|
504 |
|
| IF expr THEN NEWLINE codeblock elsifseq elseseq ENDIF NEWLINE { |
505 |
505 |
canconvert($2.ty, gBoolean, -1); |
canconvert($2.ty, gBoolean, -1); |
506 |
506 |
$$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty)); |
$$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty)); |
507 |
507 |
} |
} |
508 |
|
| SET rid EQUALS expr newline { if (getVariable($2.str)->isarray) { |
|
|
508 |
|
| SET rid EQUALS expr NEWLINE { if (getVariable($2.str)->isarray) { |
509 |
509 |
char ebuf[1024]; |
char ebuf[1024]; |
510 |
510 |
snprintf(ebuf, 1024, "Index missing for array variable %s", $2.str); |
snprintf(ebuf, 1024, "Index missing for array variable %s", $2.str); |
511 |
511 |
yyerrorline(3, lineno - 1, ebuf); |
yyerrorline(3, lineno - 1, ebuf); |
|
... |
... |
statement: newline { $$.ty = gEmpty; } |
523 |
523 |
put(&initialized, $2.str, (void*)1); |
put(&initialized, $2.str, (void*)1); |
524 |
524 |
} |
} |
525 |
525 |
} |
} |
526 |
|
| SET rid LBRACKET expr RBRACKET EQUALS expr newline{ |
|
|
526 |
|
| SET rid LBRACKET expr RBRACKET EQUALS expr NEWLINE{ |
527 |
527 |
const struct typeandname *tan = getVariable($2.str); |
const struct typeandname *tan = getVariable($2.str); |
528 |
528 |
$$.ty = gAny; |
$$.ty = gAny; |
529 |
529 |
if (tan->ty != gAny) { |
if (tan->ty != gAny) { |
|
... |
... |
statement: newline { $$.ty = gEmpty; } |
538 |
538 |
validateGlobalAssignment($2.str); |
validateGlobalAssignment($2.str); |
539 |
539 |
} |
} |
540 |
540 |
} |
} |
541 |
|
| loopstart newline codeblock loopend newline {$$.ty = $3.ty;} |
|
542 |
|
| loopstart newline codeblock {$$.ty = $3.ty; yyerrorex(0, "Missing endloop");} |
|
543 |
|
| EXITWHEN expr newline { canconvert($2.ty, gBoolean, -1); if (!inloop) yyerrorline(0, lineno - 1, "Exitwhen outside of loop"); $$.ty = gAny;} |
|
544 |
|
| RETURN expr newline { |
|
|
541 |
|
| loopstart NEWLINE codeblock loopend NEWLINE {$$.ty = $3.ty;} |
|
542 |
|
| loopstart NEWLINE codeblock {$$.ty = $3.ty; yyerrorex(0, "Missing endloop");} |
|
543 |
|
| EXITWHEN expr NEWLINE { canconvert($2.ty, gBoolean, -1); if (!inloop) yyerrorline(0, lineno - 1, "Exitwhen outside of loop"); $$.ty = gAny;} |
|
544 |
|
| RETURN expr NEWLINE { |
545 |
545 |
$$.ty = mkretty($2.ty, 1); |
$$.ty = mkretty($2.ty, 1); |
546 |
546 |
if(retval == gNothing) |
if(retval == gNothing) |
547 |
547 |
yyerrorline(1, lineno - 1, "Cannot return value from function that returns nothing"); |
yyerrorline(1, lineno - 1, "Cannot return value from function that returns nothing"); |
548 |
548 |
else if (!returnbug) |
else if (!returnbug) |
549 |
549 |
canconvertreturn($2.ty, retval, 0); |
canconvertreturn($2.ty, retval, 0); |
550 |
550 |
} |
} |
551 |
|
| RETURN newline { |
|
|
551 |
|
| RETURN NEWLINE { |
552 |
552 |
if (retval != gNothing) |
if (retval != gNothing) |
553 |
553 |
yyerrorline(1, lineno - 1, "Return nothing in function that should return value"); |
yyerrorline(1, lineno - 1, "Return nothing in function that should return value"); |
554 |
554 |
$$.ty = mkretty(gAny, 1); |
$$.ty = mkretty(gAny, 1); |
555 |
555 |
} |
} |
556 |
556 |
| DEBUG statement {$$.ty = gAny;} |
| DEBUG statement {$$.ty = gAny;} |
557 |
557 |
/*1 2 3 4 5 6 7 */ |
/*1 2 3 4 5 6 7 */ |
558 |
|
| IF expr THEN newline codeblock elsifseq elseseq { |
|
|
558 |
|
| IF expr THEN NEWLINE codeblock elsifseq elseseq { |
559 |
559 |
canconvert($2.ty, gBoolean, -1); |
canconvert($2.ty, gBoolean, -1); |
560 |
560 |
$$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty)); |
$$.ty = combinetype($5.ty, combinetype($6.ty, $7.ty)); |
561 |
561 |
yyerrorex(0, "Missing endif"); |
yyerrorex(0, "Missing endif"); |
562 |
562 |
} |
} |
563 |
|
| IF expr newline { |
|
|
563 |
|
| IF expr NEWLINE { |
564 |
564 |
canconvert($2.ty, gBoolean, -1); |
canconvert($2.ty, gBoolean, -1); |
565 |
565 |
$$.ty = gAny; |
$$.ty = gAny; |
566 |
566 |
yyerrorex(0, "Missing then or non valid expression"); |
yyerrorex(0, "Missing then or non valid expression"); |
567 |
567 |
} |
} |
568 |
|
| SET funccall newline{$$.ty = gAny; yyerrorline(0, lineno - 1, "Call expected instead of set");} |
|
|
568 |
|
| SET funccall NEWLINE{$$.ty = gAny; yyerrorline(0, lineno - 1, "Call expected instead of set");} |
569 |
569 |
| lvardecl {yyerrorex(0, "Local declaration after first statement");} |
| lvardecl {yyerrorex(0, "Local declaration after first statement");} |
570 |
570 |
| error {$$.ty = gAny; } |
| error {$$.ty = gAny; } |
571 |
571 |
; |
; |
|
... |
... |
loopend: ENDLOOP {inloop--;} |
577 |
577 |
; |
; |
578 |
578 |
|
|
579 |
579 |
elseseq: /* empty */ { $$.ty = gAny; } |
elseseq: /* empty */ { $$.ty = gAny; } |
580 |
|
| ELSE newline codeblock { |
|
|
580 |
|
| ELSE NEWLINE codeblock { |
581 |
581 |
$$.ty = $3.ty; |
$$.ty = $3.ty; |
582 |
582 |
} |
} |
583 |
583 |
; |
; |
584 |
584 |
|
|
585 |
585 |
elsifseq: /* empty */ { $$.ty = mkretty(gEmpty, 1); } |
elsifseq: /* empty */ { $$.ty = mkretty(gEmpty, 1); } |
586 |
586 |
/* 1 2 3 4 5 6 */ |
/* 1 2 3 4 5 6 */ |
587 |
|
| ELSEIF expr THEN newline codeblock elsifseq { |
|
|
587 |
|
| ELSEIF expr THEN NEWLINE codeblock elsifseq { |
588 |
588 |
canconvert($2.ty, gBoolean, -1); |
canconvert($2.ty, gBoolean, -1); |
589 |
589 |
|
|
590 |
590 |
if(typeeq($6.ty, gEmpty)){ |
if(typeeq($6.ty, gEmpty)){ |
|
... |
... |
vartypedecl: type rid { |
775 |
775 |
|
|
776 |
776 |
localblock: endlocalsmarker |
localblock: endlocalsmarker |
777 |
777 |
| lvardecl localblock |
| lvardecl localblock |
778 |
|
| newline localblock |
|
|
778 |
|
| NEWLINE localblock |
779 |
779 |
; |
; |
780 |
780 |
|
|
781 |
781 |
endlocalsmarker: /* empty */ { fCurrent = 0; } |
endlocalsmarker: /* empty */ { fCurrent = 0; } |
|
... |
... |
lvardecl: LOCAL vardecl { } |
786 |
786 |
| typedef { yyerrorex(3,"Types can not be extended inside functions"); } |
| typedef { yyerrorex(3,"Types can not be extended inside functions"); } |
787 |
787 |
; |
; |
788 |
788 |
|
|
789 |
|
vardecl: vartypedecl newline { |
|
|
789 |
|
vardecl: vartypedecl NEWLINE { |
790 |
790 |
const struct typeandname *tan = getVariable($1.str); |
const struct typeandname *tan = getVariable($1.str); |
791 |
791 |
if (tan->isconst) { |
if (tan->isconst) { |
792 |
792 |
yyerrorline(3, lineno - 1, "Constants must be initialized"); |
yyerrorline(3, lineno - 1, "Constants must be initialized"); |
793 |
793 |
} |
} |
794 |
794 |
$$.ty = gNothing; |
$$.ty = gNothing; |
795 |
795 |
} |
} |
796 |
|
| vartypedecl EQUALS expr newline { |
|
|
796 |
|
| vartypedecl EQUALS expr NEWLINE { |
797 |
797 |
const struct typeandname *tan = getVariable($1.str); |
const struct typeandname *tan = getVariable($1.str); |
798 |
798 |
if (tan->isarray) { |
if (tan->isarray) { |
799 |
799 |
yyerrorex(3, "Arrays cannot be directly initialized"); |
yyerrorex(3, "Arrays cannot be directly initialized"); |
|
... |
... |
primtype: HANDLE { $$.ty = lookup(&types, yytext); } |
846 |
846 |
| STRING { $$.ty = lookup(&types, yytext); } |
| STRING { $$.ty = lookup(&types, yytext); } |
847 |
847 |
| CODE { $$.ty = lookup(&types, yytext); } |
| CODE { $$.ty = lookup(&types, yytext); } |
848 |
848 |
; |
; |
849 |
|
|
|
850 |
|
newline: NEWLINE |
|
851 |
|
| DERECTIVE |
|
852 |
|
; |
|