Add arithmetic and boolean operations
This commit is contained in:
parent
54eb1daee6
commit
3241592364
47
templates.h
47
templates.h
|
@ -94,4 +94,51 @@ char* tpoppointer[TPOPPOINTERN] = {
|
||||||
"M=D"
|
"M=D"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TARITHN 7
|
||||||
|
char* tarith[TARITHN] = {
|
||||||
|
"",
|
||||||
|
"@SP",
|
||||||
|
"M=M-1",
|
||||||
|
"A=M",
|
||||||
|
"D=M",
|
||||||
|
"A=A-1",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TNEGN 5
|
||||||
|
char* tneg[TNEGN] = {
|
||||||
|
"",
|
||||||
|
"@SP",
|
||||||
|
"M=M-1",
|
||||||
|
"A=M",
|
||||||
|
"M=-M",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TNOTN 5
|
||||||
|
char* tnot[TNOTN] = {
|
||||||
|
"",
|
||||||
|
"@SP",
|
||||||
|
"M=M-1",
|
||||||
|
"A=M",
|
||||||
|
"M=!M",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCOMPN 15
|
||||||
|
char* tcomp[TCOMPN] = {
|
||||||
|
"",
|
||||||
|
"M=D",
|
||||||
|
"@SP",
|
||||||
|
"M=M-1",
|
||||||
|
"A=M",
|
||||||
|
"D=M",
|
||||||
|
"A=A-1",
|
||||||
|
"D=D-M",
|
||||||
|
"M=1",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"@SP",
|
||||||
|
"A=M-1",
|
||||||
|
"M=0",
|
||||||
|
""
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
75
translator.c
75
translator.c
|
@ -4,6 +4,8 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "translator.h"
|
#include "translator.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
#define CMPLIMIT 1000
|
||||||
|
#define CMPLEN 4
|
||||||
|
|
||||||
void pushtoclean(struct Translator* t, char* topush) {
|
void pushtoclean(struct Translator* t, char* topush) {
|
||||||
int nextsz = sizeof(char*)*(t->tocleanind+1);
|
int nextsz = sizeof(char*)*(t->tocleanind+1);
|
||||||
|
@ -105,6 +107,19 @@ void checkind(struct line* ln, int indlen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* mkcmplab(struct Translator* t, struct line* ln) {
|
||||||
|
t->compcount++;
|
||||||
|
if(t->compcount > CMPLIMIT) {
|
||||||
|
fprintf(stderr, "Reached comparison limit (%i); line %i\n", CMPLIMIT, ln->truen);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int newsz = (CMPLEN+13)*sizeof(char);
|
||||||
|
char* label = (char*)malloc(newsz);
|
||||||
|
snprintf(label, newsz, "COMPARISON-%i", t->compcount);
|
||||||
|
pushtoclean(t, label);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
char* mkind(struct Translator* t, struct line* ln, int indlen) {
|
char* mkind(struct Translator* t, struct line* ln, int indlen) {
|
||||||
checkind(ln, indlen);
|
checkind(ln, indlen);
|
||||||
int newsz = sizeof(char) * (indlen + 2);
|
int newsz = sizeof(char) * (indlen + 2);
|
||||||
|
@ -114,6 +129,22 @@ char* mkind(struct Translator* t, struct line* ln, int indlen) {
|
||||||
return newind;
|
return newind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* atlab(struct Translator* t, char* label, int labellen) {
|
||||||
|
int newsz = sizeof(char) * (labellen + 2);
|
||||||
|
char* newind = (char*)malloc(newsz);
|
||||||
|
snprintf(newind, newsz, "@%s", label);
|
||||||
|
pushtoclean(t, newind);
|
||||||
|
return newind;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* mklab(struct Translator* t, char* label, int labellen) {
|
||||||
|
int newsz = sizeof(char) * (labellen + 3);
|
||||||
|
char* newind = (char*)malloc(newsz);
|
||||||
|
snprintf(newind, newsz, "(%s)", label);
|
||||||
|
pushtoclean(t, newind);
|
||||||
|
return newind;
|
||||||
|
}
|
||||||
|
|
||||||
char* mkstatind(struct Translator* t, struct line* ln, int indlen) {
|
char* mkstatind(struct Translator* t, struct line* ln, int indlen) {
|
||||||
checkind(ln, indlen);
|
checkind(ln, indlen);
|
||||||
int fnamelen = strlen(t->fname);
|
int fnamelen = strlen(t->fname);
|
||||||
|
@ -275,6 +306,32 @@ void pop(struct Translator* t, struct line* ln, int indlen) {
|
||||||
addasmlns(t, ln, tpop, TPOPN);
|
addasmlns(t, ln, tpop, TPOPN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arith(struct Translator* t, struct line* ln, char* op) {
|
||||||
|
tarith[TARITHN-1] = heapstr(t, op);
|
||||||
|
|
||||||
|
addasmlns(t, ln, tarith, TARITHN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void comp(struct Translator* t, struct line* ln, char* op) {
|
||||||
|
char* label = mkcmplab(t, ln);
|
||||||
|
int labellen = strlen(label);
|
||||||
|
|
||||||
|
// @label
|
||||||
|
tcomp[TCOMPN-6] = atlab(t, label, labellen);
|
||||||
|
|
||||||
|
// D;J(op)
|
||||||
|
int opsz = sizeof(char)*6;
|
||||||
|
char* trueop = (char*)malloc(opsz);
|
||||||
|
snprintf(trueop, opsz, "D;J%s", op);
|
||||||
|
tcomp[TCOMPN-5] = trueop;
|
||||||
|
|
||||||
|
// (label)
|
||||||
|
tcomp[TCOMPN-1] = mklab(t, label, labellen);
|
||||||
|
free(label);
|
||||||
|
|
||||||
|
addasmlns(t, ln, tcomp, TCOMPN);
|
||||||
|
};
|
||||||
|
|
||||||
void switchpush(struct Translator* t, struct line* ln) {
|
void switchpush(struct Translator* t, struct line* ln) {
|
||||||
checkopamnt(3, ln);
|
checkopamnt(3, ln);
|
||||||
char* seg = ln->tokens[1];
|
char* seg = ln->tokens[1];
|
||||||
|
@ -314,6 +371,24 @@ void switchop(struct Translator* t, struct line* ln) {
|
||||||
switchpush(t, ln);
|
switchpush(t, ln);
|
||||||
else if(!strcmp(op, "pop"))
|
else if(!strcmp(op, "pop"))
|
||||||
switchpop(t, ln);
|
switchpop(t, ln);
|
||||||
|
else if(!strcmp(op, "add"))
|
||||||
|
arith(t, ln, "M=M+D");
|
||||||
|
else if(!strcmp(op, "sub"))
|
||||||
|
arith(t, ln, "M=M-D");
|
||||||
|
else if(!strcmp(op, "neg"))
|
||||||
|
addasmlns(t, ln, tneg, TNEGN);
|
||||||
|
else if(!strcmp(op, "eq"))
|
||||||
|
comp(t, ln, "EQ");
|
||||||
|
else if(!strcmp(op, "gt"))
|
||||||
|
comp(t, ln, "GT");
|
||||||
|
else if(!strcmp(op, "lt"))
|
||||||
|
comp(t, ln, "LT");
|
||||||
|
else if(!strcmp(op, "and"))
|
||||||
|
arith(t, ln, "M=M&D");
|
||||||
|
else if(!strcmp(op, "or"))
|
||||||
|
arith(t, ln, "M=M|D");
|
||||||
|
else if(!strcmp(op, "not"))
|
||||||
|
addasmlns(t, ln, tnot, TNOTN);
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Unrecognized operation '%s'; line %i\n", op, ln->truen);
|
fprintf(stderr, "Unrecognized operation '%s'; line %i\n", op, ln->truen);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct Translator {
|
||||||
int tocleanind;
|
int tocleanind;
|
||||||
struct lnarray* lns;
|
struct lnarray* lns;
|
||||||
char* fname;
|
char* fname;
|
||||||
|
int compcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
void freetranslator(struct Translator* t);
|
void freetranslator(struct Translator* t);
|
||||||
|
|
Loading…
Reference in New Issue