Force last function statement to be 'return'

This commit is contained in:
Augusto Gunsch 2021-01-07 19:58:28 -03:00
parent 1784599e72
commit ae03a25542
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
3 changed files with 34 additions and 6 deletions

View File

@ -173,3 +173,15 @@ LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts) {
} }
return head; return head;
} }
LINEBLOCK* compilestatementsretlast(SCOPE* s, STATEMENT* sts, STATEMENT** retlast) {
LINEBLOCK* head = NULL;
STATEMENT* last = NULL;
while(sts != NULL) {
head = mergelnblks(head, compilestatement(s, sts));
last = sts;
sts = sts->next;
}
*retlast = last;
return head;
}

View File

@ -6,4 +6,5 @@
* Single function for compiling statements */ * Single function for compiling statements */
LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts); LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts);
LINEBLOCK* compilestatementsretlast(SCOPE* s, STATEMENT* sts, STATEMENT** retlast);
#endif #endif

View File

@ -12,7 +12,7 @@ int getobjsize(CLASS* c);
LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd); LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd);
// Compiling methods // Compiling methods
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTBODY* b); LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTDEC* d);
LINEBLOCK* compilefundec(SCOPE* s, CLASS* cl, SUBROUTDEC* f); LINEBLOCK* compilefundec(SCOPE* s, CLASS* cl, SUBROUTDEC* f);
LINEBLOCK* compileconstructor(SCOPE* s, CLASS* cl, SUBROUTDEC* con); LINEBLOCK* compileconstructor(SCOPE* s, CLASS* cl, SUBROUTDEC* con);
LINEBLOCK* compilemethod(SCOPE* s, CLASS* cl, SUBROUTDEC* m); LINEBLOCK* compilemethod(SCOPE* s, CLASS* cl, SUBROUTDEC* m);
@ -64,12 +64,27 @@ LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd) {
} }
// Compiling methods // Compiling methods
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTBODY* b) { LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTDEC* d) {
SUBROUTBODY* b = d->body;
SCOPE* myscope = mkscope(s); SCOPE* myscope = mkscope(s);
myscope->currclass = cl; myscope->currclass = cl;
if(b->vardecs != NULL) if(b->vardecs != NULL)
addlocalvars(myscope, b->vardecs); addlocalvars(myscope, b->vardecs);
LINEBLOCK* head = compilestatements(myscope, b->statements);
if(b->statements == NULL) {
eprintf("Subroutine body has no statements; file '%s', line %i\n",
d->debug->file, d->debug->definedat);
exit(1);
}
STATEMENT* last;
LINEBLOCK* head = compilestatementsretlast(myscope, b->statements, &last);
if(last->type != returnstatement) {
eprintf("Subroutine must end with a return statement; file '%s', line %i\n",
last->debug->file, last->debug->definedat);
exit(1);
}
freescope(myscope); freescope(myscope);
return head; return head;
} }
@ -78,7 +93,7 @@ LINEBLOCK* compilefundec(SCOPE* s, CLASS* cl, SUBROUTDEC* f) {
LINE* label = mksubdeclabel(cl, f); LINE* label = mksubdeclabel(cl, f);
if(f->body->statements != NULL) { if(f->body->statements != NULL) {
LINEBLOCK* body = compilefunbody(s, cl, f->body); LINEBLOCK* body = compilefunbody(s, cl, f);
appendlnbefore(body, label); appendlnbefore(body, label);
return body; return body;
} }
@ -99,7 +114,7 @@ LINEBLOCK* compileconstructor(SCOPE* s, CLASS* cl, SUBROUTDEC* con) {
free(size[2]); free(size[2]);
if(con->body != NULL) if(con->body != NULL)
return mergelnblks(blk, compilefunbody(s, cl, con->body)); return mergelnblks(blk, compilefunbody(s, cl, con));
else else
return blk; return blk;
} }
@ -114,7 +129,7 @@ LINEBLOCK* compilemethod(SCOPE* s, CLASS* cl, SUBROUTDEC* m) {
appendln(blk, mkln(poppointer)); appendln(blk, mkln(poppointer));
if(m->body != NULL) if(m->body != NULL)
return mergelnblks(blk, compilefunbody(s, cl, m->body)); return mergelnblks(blk, compilefunbody(s, cl, m));
else else
return blk; return blk;
} }