jack-compiler/parser/parser-statements.c

132 lines
2.7 KiB
C

#include <stdlib.h>
#include "parser-expressions.h"
#include "parser-internal.h"
#include "parser-statements.h"
STATEMENT* mkstatement(STATEMENTTYPE t);
STATEMENT* parsestatementnullified(PARSER* p);
STATEMENT* parselet(PARSER* p);
CONDSTATEMENT* parsecond(PARSER* p);
STATEMENT* parseif(PARSER* p);
STATEMENT* parsewhile(PARSER* p);
STATEMENT* parsedo(PARSER* p);
STATEMENT* parsereturn(PARSER* p);
STATEMENT* mkstatement(STATEMENTTYPE t) {
STATEMENT* s = (STATEMENT*)malloc(sizeof(STATEMENT));
s->type = t;
return s;
}
// Though nullified, will throw errors if the parsing fails while on-going
STATEMENT* parsestatementnullified(PARSER* p) {
if(equals(p, "let")) return parselet(p);
if(equals(p, "if")) return parseif(p);
if(equals(p, "while")) return parsewhile(p);
if(equals(p, "do")) return parsedo(p);
if(equals(p, "return")) return parsereturn(p);
return NULL;
}
STATEMENT* parsestatements(PARSER* p) {
STATEMENT* head = parsestatementnullified(p);
STATEMENT* curr = head;
STATEMENT* next;
while(next = parsestatementnullified(p), next != NULL) {
curr->next = next;
curr = next;
}
if(curr != NULL)
curr->next = NULL;
return head;
}
STATEMENT* parselet(PARSER* p) {
next(p);
STATEMENT* s = mkstatement(letstatement);
LETSTATEMENT* letst= (LETSTATEMENT*)malloc(sizeof(LETSTATEMENT));
letst->varname = parseidentifier(p);
if(equals(p, "[")) {
next(p);
letst->arrayind = parseexpression(p);
checkcontent(p, "]");
}
else
letst->arrayind = NULL;
checkcontent(p, "=");
letst->expression = parseexpression(p);
checkcontent(p, ";");
s->type = letstatement;
return s;
}
CONDSTATEMENT* parsecond(PARSER* p) {
checkcontent(p, "(");
CONDSTATEMENT* st = (CONDSTATEMENT*)malloc(sizeof(CONDSTATEMENT));
st->expression = parseexpression(p);
checkcontent(p, ")");
checkcontent(p, "{");
st->statements = parsestatements(p);
checkcontent(p, "}");
return st;
}
STATEMENT* parseif(PARSER* p) {
next(p);
STATEMENT* s = mkstatement(ifstatement);
IFSTATEMENT* ifst = (IFSTATEMENT*)malloc(sizeof(IFSTATEMENT));
ifst->base = parsecond(p);
if(equals(p, "else")) {
next(p);
checkcontent(p, "{");
ifst->elsestatements = parsestatements(p);
checkcontent(p, "}");
}
else
ifst->elsestatements = NULL;
s->type = ifstatement;
return s;
}
STATEMENT* parsewhile(PARSER* p) {
next(p);
STATEMENT* s = mkstatement(whilestatement);
s->whilestatement = parsecond(p);
return s;
}
STATEMENT* parsedo(PARSER* p) {
next(p);
STATEMENT* s = mkstatement(dostatement);
s->dostatement = parsesubroutcall(p);
checkcontent(p, ";");
return s;
}
STATEMENT* parsereturn(PARSER* p) {
next(p);
STATEMENT* s = mkstatement(returnstatement);
s->retstatement = parseexpressionnullified(p);
checkcontent(p, ";");
return s;
}