Add assembler
This commit is contained in:
@@ -17,7 +17,6 @@ char* tpushlns[] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"A=D+A",
|
||||
"D=M",
|
||||
"@SP",
|
||||
@@ -29,7 +28,6 @@ char* tpushlns[] = {
|
||||
mktemplate(tpush, tpushlns);
|
||||
|
||||
char* tpushconslns[] = {
|
||||
"",
|
||||
"",
|
||||
"D=A",
|
||||
"@SP",
|
||||
@@ -41,7 +39,6 @@ char* tpushconslns[] = {
|
||||
mktemplate(tpushcons, tpushconslns);
|
||||
|
||||
char* tpushstatlns[] = {
|
||||
"",
|
||||
"",
|
||||
"D=M",
|
||||
"@SP",
|
||||
@@ -60,7 +57,6 @@ char* tpoplns[] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"D=D+A",
|
||||
"@R13",
|
||||
"M=D",
|
||||
@@ -74,7 +70,6 @@ char* tpoplns[] = {
|
||||
mktemplate(tpop, tpoplns);
|
||||
|
||||
char* tpopstatlns[] = {
|
||||
"",
|
||||
"@SP",
|
||||
"AM=M-1",
|
||||
"D=M",
|
||||
@@ -88,7 +83,6 @@ mktemplate(tpoptemp, tpopstatlns);
|
||||
mktemplate(tpoppointer, tpopstatlns);
|
||||
|
||||
char* tarithlns[] = {
|
||||
"",
|
||||
"@SP",
|
||||
"AM=M-1",
|
||||
"D=M",
|
||||
@@ -98,7 +92,6 @@ char* tarithlns[] = {
|
||||
mktemplate(tarith, tarithlns);
|
||||
|
||||
char* tneglns[] = {
|
||||
"",
|
||||
"@SP",
|
||||
"A=M-1",
|
||||
"M=-M",
|
||||
@@ -106,7 +99,6 @@ char* tneglns[] = {
|
||||
mktemplate(tneg, tneglns);
|
||||
|
||||
char* tnotlns[] = {
|
||||
"",
|
||||
"@SP",
|
||||
"A=M-1",
|
||||
"M=!M",
|
||||
@@ -114,7 +106,6 @@ char* tnotlns[] = {
|
||||
mktemplate(tnot, tnotlns);
|
||||
|
||||
char* tcomplns[] = {
|
||||
"",
|
||||
"@SP",
|
||||
"AM=M-1",
|
||||
"D=M",
|
||||
@@ -131,20 +122,17 @@ char* tcomplns[] = {
|
||||
mktemplate(tcomp, tcomplns);
|
||||
|
||||
char* tlabellns[] = {
|
||||
"",
|
||||
""
|
||||
};
|
||||
mktemplate(tlabel, tlabellns);
|
||||
|
||||
char* tgotolns[] = {
|
||||
"",
|
||||
"",
|
||||
"0;JMP"
|
||||
};
|
||||
mktemplate(tgoto, tgotolns);
|
||||
|
||||
char* tifgotolns[] = {
|
||||
"",
|
||||
"@SP",
|
||||
"AM=M-1",
|
||||
"D=M",
|
||||
@@ -154,8 +142,6 @@ char* tifgotolns[] = {
|
||||
mktemplate(tifgoto, tifgotolns);
|
||||
|
||||
char* tcallstartlns[] = {
|
||||
"",
|
||||
"",
|
||||
"D=A",
|
||||
"@SP",
|
||||
"A=M",
|
||||
@@ -204,7 +190,6 @@ char* tframevarslns[] = {
|
||||
mktemplate(tframevars, tframevarslns);
|
||||
|
||||
char* tfunctionlns[] = {
|
||||
"",
|
||||
""
|
||||
};
|
||||
mktemplate(tfunction, tfunctionlns);
|
||||
@@ -219,7 +204,6 @@ char* tfunctionpushlns[] = {
|
||||
mktemplate(tfunctionpush, tfunctionpushlns);
|
||||
|
||||
char* tstartreturnlns[] = {
|
||||
"",
|
||||
"@LCL",
|
||||
"D=M",
|
||||
"@5",
|
||||
|
@@ -5,11 +5,6 @@
|
||||
#include "util.h"
|
||||
#define eq(translator, index, str) !strcmp(translator->currln->tokens[index], str)
|
||||
|
||||
typedef struct {
|
||||
STRINGLIST* head;
|
||||
STRINGLIST* tail;
|
||||
} ASMBLK;
|
||||
|
||||
STRINGLIST* asmln(char* content) {
|
||||
STRINGLIST* ln = (STRINGLIST*)malloc(sizeof(STRINGLIST));
|
||||
ln->content = content;
|
||||
@@ -68,26 +63,6 @@ char* dotat(VMTRANSLATOR* t, char* name, char* n) {
|
||||
return atstr;
|
||||
}
|
||||
|
||||
char* comment(VMTRANSLATOR* t) {
|
||||
int sz = (4 + strlen(t->currln->tokens[0])) * sizeof(char);
|
||||
for(int i = 1; i < t->currln->count; i++)
|
||||
sz += (1 + strlen(t->currln->tokens[i])) * sizeof(char);
|
||||
|
||||
char* com = (char*)malloc(sz);
|
||||
if(t->currln->count == 1)
|
||||
sprintf(com, "// %s", t->currln->tokens[0]);
|
||||
else if(t->currln->count == 2)
|
||||
sprintf(com, "// %s %s", t->currln->tokens[0],
|
||||
t->currln->tokens[1]);
|
||||
else if(t->currln->count == 3)
|
||||
sprintf(com, "// %s %s %s", t->currln->tokens[0],
|
||||
t->currln->tokens[1],
|
||||
t->currln->tokens[2]);
|
||||
|
||||
togarbage(t, com);
|
||||
return com;
|
||||
}
|
||||
|
||||
char* switchsegment(VMTRANSLATOR* t) {
|
||||
if(eq(t, 1, "local"))
|
||||
return mkstr(t, "@LCL");
|
||||
@@ -154,13 +129,6 @@ ASMBLK* copytemplate(TEMPLATE* t) {
|
||||
return blk;
|
||||
}
|
||||
|
||||
ASMBLK* mkasmlns(VMTRANSLATOR* t, TEMPLATE* tp) {
|
||||
// instruction comment
|
||||
tp->items[0] = comment(t);
|
||||
|
||||
return copytemplate(tp);
|
||||
}
|
||||
|
||||
void mergeasmblks(ASMBLK* a, ASMBLK* b) {
|
||||
a->tail->next = b->head;
|
||||
a->tail = b->tail;
|
||||
@@ -173,47 +141,47 @@ void mergeasmblks(ASMBLK* a, ASMBLK* b) {
|
||||
|
||||
ASMBLK* translatepushconst(VMTRANSLATOR* t) {
|
||||
// @i
|
||||
tpushcons.items[1] = at(t, t->currln->tokens[2]);
|
||||
tpushcons.items[0] = at(t, t->currln->tokens[2]);
|
||||
|
||||
return mkasmlns(t, &tpushcons);
|
||||
return copytemplate(&tpushcons);
|
||||
}
|
||||
|
||||
ASMBLK* translatepushstatic(VMTRANSLATOR* t) {
|
||||
// @classname.i
|
||||
tpushstat.items[1] = dotat(t, t->classname, t->currln->tokens[2]);
|
||||
tpushstat.items[0] = dotat(t, t->classname, t->currln->tokens[2]);
|
||||
|
||||
return mkasmlns(t, &tpushstat);
|
||||
return copytemplate(&tpushstat);
|
||||
}
|
||||
|
||||
ASMBLK* translatepushpointer(VMTRANSLATOR* t) {
|
||||
// @THIS/@THAT
|
||||
tpushpointer.items[1] = mkpointerind(t);
|
||||
tpushpointer.items[0] = mkpointerind(t);
|
||||
|
||||
return mkasmlns(t, &tpushpointer);
|
||||
return copytemplate(&tpushpointer);
|
||||
}
|
||||
|
||||
ASMBLK* translatepushtemp(VMTRANSLATOR* t) {
|
||||
// @5+i
|
||||
tpushtemp.items[1] = mktempind(t);
|
||||
tpushtemp.items[0] = mktempind(t);
|
||||
|
||||
return mkasmlns(t, &tpushtemp);
|
||||
return copytemplate(&tpushtemp);
|
||||
}
|
||||
|
||||
void pushpopcommon(VMTRANSLATOR* t, TEMPLATE* tp) {
|
||||
// @segment
|
||||
tp->items[1] = switchsegment(t);
|
||||
tp->items[0] = switchsegment(t);
|
||||
|
||||
// D=M
|
||||
tp->items[2] = mkstr(t, "D=M");
|
||||
tp->items[1] = mkstr(t, "D=M");
|
||||
|
||||
// @i
|
||||
tp->items[3] = at(t, t->currln->tokens[2]);
|
||||
tp->items[2] = at(t, t->currln->tokens[2]);
|
||||
}
|
||||
|
||||
ASMBLK* translatepushgeneric(VMTRANSLATOR* t) {
|
||||
pushpopcommon(t, &tpush);
|
||||
|
||||
return mkasmlns(t, &tpush);
|
||||
return copytemplate(&tpush);
|
||||
}
|
||||
|
||||
ASMBLK* translatepush(VMTRANSLATOR* t) {
|
||||
@@ -235,7 +203,7 @@ ASMBLK* translatepopstatic(VMTRANSLATOR* t) {
|
||||
// M=D
|
||||
tpopstat.items[tpopstat.count-1] = mkstr(t, "M=D");
|
||||
|
||||
return mkasmlns(t, &tpopstat);
|
||||
return copytemplate(&tpopstat);
|
||||
}
|
||||
|
||||
ASMBLK* translatepoppointer(VMTRANSLATOR* t) {
|
||||
@@ -245,7 +213,7 @@ ASMBLK* translatepoppointer(VMTRANSLATOR* t) {
|
||||
// M=D
|
||||
tpoppointer.items[tpoppointer.count-1] = mkstr(t, "M=D");
|
||||
|
||||
return mkasmlns(t, &tpoppointer);
|
||||
return copytemplate(&tpoppointer);
|
||||
}
|
||||
|
||||
ASMBLK* translatepoptemp(VMTRANSLATOR* t) {
|
||||
@@ -254,13 +222,13 @@ ASMBLK* translatepoptemp(VMTRANSLATOR* t) {
|
||||
|
||||
tpoptemp.items[tpoptemp.count-1] = mkstr(t, "M=D");
|
||||
|
||||
return mkasmlns(t, &tpoptemp);
|
||||
return copytemplate(&tpoptemp);
|
||||
}
|
||||
|
||||
ASMBLK* translatepopgeneric(VMTRANSLATOR* t) {
|
||||
pushpopcommon(t, &tpop);
|
||||
|
||||
return mkasmlns(t, &tpop);
|
||||
return copytemplate(&tpop);
|
||||
}
|
||||
|
||||
ASMBLK* translatepop(VMTRANSLATOR* t) {
|
||||
@@ -281,7 +249,7 @@ ASMBLK* translatepop(VMTRANSLATOR* t) {
|
||||
ASMBLK* translatearith(VMTRANSLATOR* t, char* op) {
|
||||
tarith.items[tarith.count-1] = mkstr(t, op);
|
||||
|
||||
return mkasmlns(t, &tarith);
|
||||
return copytemplate(&tarith);
|
||||
}
|
||||
|
||||
ASMBLK* translatecomp(VMTRANSLATOR* t, char* op) {
|
||||
@@ -301,7 +269,7 @@ ASMBLK* translatecomp(VMTRANSLATOR* t, char* op) {
|
||||
// (label)
|
||||
tcomp.items[tcomp.count-1] = enclosingparenthesis(t, label, labellen);
|
||||
|
||||
return mkasmlns(t, &tcomp);
|
||||
return copytemplate(&tcomp);
|
||||
}
|
||||
|
||||
/* END OPERATIONS */
|
||||
@@ -310,25 +278,25 @@ ASMBLK* translatelabel(VMTRANSLATOR* t) {
|
||||
// (classname$label)
|
||||
tlabel.items[tlabel.count-1] = mklab(t);
|
||||
|
||||
return mkasmlns(t, &tlabel);
|
||||
return copytemplate(&tlabel);
|
||||
}
|
||||
|
||||
ASMBLK* translategoto(VMTRANSLATOR* t) {
|
||||
// @label
|
||||
tgoto.items[tgoto.count-2] = mkgotolab(t);
|
||||
|
||||
return mkasmlns(t, &tgoto);
|
||||
return copytemplate(&tgoto);
|
||||
}
|
||||
|
||||
ASMBLK* translateifgoto(VMTRANSLATOR* t) {
|
||||
// @label
|
||||
tifgoto.items[tifgoto.count-2] = mkgotolab(t);
|
||||
|
||||
return mkasmlns(t, &tifgoto);
|
||||
return copytemplate(&tifgoto);
|
||||
}
|
||||
|
||||
ASMBLK* translatereturn(VMTRANSLATOR* t) {
|
||||
ASMBLK* blk = mkasmlns(t, &tstartreturn);
|
||||
ASMBLK* blk = copytemplate(&tstartreturn);
|
||||
|
||||
for(int i = tframevars.count-1; i >= 0; i--) {
|
||||
tretpop.items[tretpop.count-2] = tframevars.items[i];
|
||||
@@ -344,8 +312,8 @@ ASMBLK* translatefunction(VMTRANSLATOR* t) {
|
||||
t->cmpind = 0;
|
||||
|
||||
// (funcname)
|
||||
tfunction.items[1] = mklab(t);
|
||||
ASMBLK* blk = mkasmlns(t, &tfunction);
|
||||
tfunction.items[0] = mklab(t);
|
||||
ASMBLK* blk = copytemplate(&tfunction);
|
||||
|
||||
// repeat nVars times:
|
||||
int nlocals = atoi(t->currln->tokens[2]);
|
||||
@@ -359,7 +327,7 @@ ASMBLK* translatefunction(VMTRANSLATOR* t) {
|
||||
ASMBLK* pushframe(VMTRANSLATOR* t, char* retlab, int retlablen, int* framesize) {
|
||||
tcallstart.items[1] = atraw(t, retlab, retlablen);
|
||||
|
||||
ASMBLK* blk = mkasmlns(t, &tcallstart);
|
||||
ASMBLK* blk = copytemplate(&tcallstart);
|
||||
|
||||
for(int i = 0; i < tframevars.count; i++) {
|
||||
tcallpush.items[0] = tframevars.items[i];
|
||||
@@ -408,9 +376,9 @@ ASMBLK* translateln(VMTRANSLATOR* t) {
|
||||
return translatearith(t, "M=D|M");
|
||||
|
||||
if(eq(t, 0, "neg"))
|
||||
return mkasmlns(t, &tneg);
|
||||
return copytemplate(&tneg);
|
||||
if(eq(t, 0, "not"))
|
||||
return mkasmlns(t, &tnot);
|
||||
return copytemplate(&tnot);
|
||||
|
||||
if(eq(t, 0, "eq"))
|
||||
return translatecomp(t, "EQ");
|
||||
@@ -433,15 +401,13 @@ ASMBLK* translateln(VMTRANSLATOR* t) {
|
||||
return translatecall(t);
|
||||
}
|
||||
|
||||
STRINGLIST* translatevm(VMTRANSLATOR* t) {
|
||||
ASMBLK* translatevm(VMTRANSLATOR* t) {
|
||||
ASMBLK* blk = copytemplate(&tbootstrap);
|
||||
while(t->currln != NULL) {
|
||||
mergeasmblks(blk, translateln(t));
|
||||
t->currln = t->currln->next;
|
||||
}
|
||||
STRINGLIST* output = blk->head;
|
||||
free(blk);
|
||||
return output;
|
||||
return blk;
|
||||
}
|
||||
|
||||
VMTRANSLATOR* mkvmtranslator(char* classname, LINEBLOCK* vmlines) {
|
||||
|
@@ -12,9 +12,14 @@ typedef struct {
|
||||
int retind;
|
||||
} VMTRANSLATOR;
|
||||
|
||||
typedef struct {
|
||||
STRINGLIST* head;
|
||||
STRINGLIST* tail;
|
||||
} ASMBLK;
|
||||
|
||||
STRINGLIST* translatevm(VMTRANSLATOR* t);
|
||||
ASMBLK* translatevm(VMTRANSLATOR* t);
|
||||
VMTRANSLATOR* mkvmtranslator(char* classname, LINEBLOCK* vmlines);
|
||||
void freevmtranslator(VMTRANSLATOR* t);
|
||||
void mergeasmblks(ASMBLK* a, ASMBLK* b);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user