jack-compiler/parser/parser-statements.c

144 lines
2.9 KiB
C
Raw Permalink Normal View History

2020-12-22 11:18:54 -05:00
#include <stdlib.h>
#include "parser-expressions.h"
2020-12-31 18:24:27 -05:00
#include "parser-util.h"
2020-12-22 11:18:54 -05:00
#include "parser-statements.h"
2020-12-31 18:24:27 -05:00
/* BEGIN FORWARD DECLARATIONS */
// Miscelaneous
2020-12-27 16:52:28 -05:00
STATEMENT* mkstatement(PARSER* p, STATEMENTTYPE t);
2020-12-31 18:24:27 -05:00
2020-12-22 11:18:54 -05:00
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);
2020-12-31 18:24:27 -05:00
/* END FORWARD DECLARATIONS */
// Miscelaneous
2020-12-27 16:52:28 -05:00
STATEMENT* mkstatement(PARSER* p, STATEMENTTYPE t) {
2020-12-22 11:18:54 -05:00
STATEMENT* s = (STATEMENT*)malloc(sizeof(STATEMENT));
s->type = t;
2020-12-27 16:52:28 -05:00
s->debug = getdebug(p);
2020-12-22 11:18:54 -05:00
return s;
}
2020-12-31 18:24:27 -05:00
// Parsing methods
2020-12-22 12:38:10 -05:00
// Though nullified, will throw errors if the parsing fails while on-going
2020-12-22 11:18:54 -05:00
STATEMENT* parsestatementnullified(PARSER* p) {
2020-12-22 12:38:10 -05:00
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);
2020-12-22 11:18:54 -05:00
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);
2020-12-27 16:52:28 -05:00
STATEMENT* s = mkstatement(p, letstatement);
LETSTATEMENT* letst = (LETSTATEMENT*)malloc(sizeof(LETSTATEMENT));
2020-12-22 11:18:54 -05:00
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;
2020-12-27 16:52:28 -05:00
s->letstatement = letst;
2020-12-22 11:18:54 -05:00
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);
2020-12-27 16:52:28 -05:00
STATEMENT* s = mkstatement(p, ifstatement);
2020-12-22 11:18:54 -05:00
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;
2020-12-27 16:52:28 -05:00
s->ifstatement = ifst;
2020-12-22 11:18:54 -05:00
return s;
}
STATEMENT* parsewhile(PARSER* p) {
next(p);
2020-12-27 16:52:28 -05:00
STATEMENT* s = mkstatement(p, whilestatement);
2020-12-22 11:18:54 -05:00
s->whilestatement = parsecond(p);
return s;
}
STATEMENT* parsedo(PARSER* p) {
next(p);
2020-12-27 16:52:28 -05:00
STATEMENT* s = mkstatement(p, dostatement);
2020-12-22 11:18:54 -05:00
s->dostatement = parsesubroutcall(p);
checkcontent(p, ";");
return s;
}
STATEMENT* parsereturn(PARSER* p) {
next(p);
2020-12-27 16:52:28 -05:00
STATEMENT* s = mkstatement(p, returnstatement);
2020-12-22 11:18:54 -05:00
s->retstatement = parseexpressionnullified(p);
checkcontent(p, ";");
return s;
}