Add static and temp segments

This commit is contained in:
Augusto Gunsch 2020-10-31 20:25:00 -03:00
parent 5a0cb9d3bc
commit f0dd1b852b
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
3 changed files with 179 additions and 14 deletions

8
main.c
View File

@ -18,10 +18,10 @@ char* verfname(char* fname) {
break; break;
} }
} }
int size = sizeof(char)*(extind - startind); int size = sizeof(char)*(extind - startind + 1);
char* startstr = fname + (sizeof(char)*startind); char* startstr = fname + (sizeof(char)*startind);
char* retstr = (char*)malloc(size); char* retstr = (char*)malloc(size);
strncpy(retstr, startstr, size); snprintf(retstr, size, "%s", startstr);
return retstr; return retstr;
} }
} }
@ -36,7 +36,6 @@ int main(int argc, char* argv[]) {
} }
// file name validating // file name validating
char* fname = verfname(argv[1]); char* fname = verfname(argv[1]);
printf("%s\n", fname);
FILE* input = fopen(argv[1], "r"); FILE* input = fopen(argv[1], "r");
@ -55,7 +54,7 @@ int main(int argc, char* argv[]) {
// translating // translating
int asmcount = 0; int asmcount = 0;
struct asmln** asmlns = translate(lns, lncount, &asmcount); struct asmln** asmlns = translate(lns, lncount, &asmcount, fname);
// freeing lns // freeing lns
freelns(lns, lncount); freelns(lns, lncount);
@ -66,6 +65,7 @@ int main(int argc, char* argv[]) {
} }
// freeing asmlns // freeing asmlns
free(fname);
freeasmlns(asmlns, asmcount); freeasmlns(asmlns, asmcount);
return 0; return 0;

View File

@ -40,6 +40,8 @@ char* switchseg(struct line* ln) {
return heapstr("@THIS"); return heapstr("@THIS");
if(strcmp(seg, "that") == 0) if(strcmp(seg, "that") == 0)
return heapstr("@THAT"); return heapstr("@THAT");
fprintf(stderr, "Unrecognized segment '%s'; line %i\n", seg, ln->truen);
exit(1);
} }
// produce comment as follows: // produce comment as follows:
@ -67,6 +69,22 @@ char* mkind(char* ind, int indsz) {
return newind; return newind;
} }
char* mkstatind(char* ind, int indsz, char* fname) {
int fnamelen = strlen(fname);
int newsz = sizeof(char) * (fnamelen + indsz + 3);
char* newind = (char*)malloc(newsz);
snprintf(newind, newsz, "@%s.%s", fname, ind);
return newind;
}
char* mktempind(char* ind, int indsz) {
int intind = atoi(ind);
int newsz = sizeof(char) * (indsz + 3);
char* newind = (char*)malloc(newsz);
snprintf(newind, newsz, "@%i", intind+5);
return newind;
}
void checkasmsize(int* size, struct asmln*** lns, int targ) { void checkasmsize(int* size, struct asmln*** lns, int targ) {
if(targ >= (*size)) { if(targ >= (*size)) {
(*size)=targ*2; (*size)=targ*2;
@ -119,12 +137,12 @@ void startpoppush(struct line* ln, struct asmln*** asmlns, int* asmind) {
} }
void pushcons(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) { void pushcons(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) {
checkopamnt(3, ln);
int asmi = *asmind; int asmi = *asmind;
int totalinstrs = 8; int totalinstrs = 8;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs)); checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
// // operation segment i // // push constant i
int indlen = strlen(ln->tokens[2]); int indlen = strlen(ln->tokens[2]);
(*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen)); (*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen));
asmi++; asmi++;
@ -152,10 +170,113 @@ void pushcons(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize
(*asmind) = asmi; (*asmind) = asmi;
} }
void pushstat(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize, char* fname) {
checkopamnt(3, ln);
int asmi = *asmind;
int totalinstrs = 8;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
// // push static i
int indlen = strlen(ln->tokens[2]);
(*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen));
asmi++;
// @fname.i
checkind(ln, indlen);
(*asmlns)[asmi] = mkasmln(ln, mkstatind(ln->tokens[2], indlen, fname));
asmi++;
const int instcount = 6;
const char* instrs[] = {
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1"
};
for(int i = 0; i < instcount; i++) {
(*asmlns)[asmi] = mkasmln(ln, heapstr(instrs[i]));
asmi++;
}
(*asmind) = asmi;
}
void popstat(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize, char* fname) {
checkopamnt(3, ln);
int asmi = *asmind;
int totalinstrs = 8;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
// // pop static i
int indlen = strlen(ln->tokens[2]);
(*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen));
asmi++;
const int instcount = 5;
const char* instrs[] = {
"@SP",
"D=M",
"M=M-1",
"A=D",
"D=M"
};
for(int i = 0; i < instcount; i++) {
(*asmlns)[asmi] = mkasmln(ln, heapstr(instrs[i]));
asmi++;
}
// @fname.i
checkind(ln, indlen);
(*asmlns)[asmi] = mkasmln(ln, mkstatind(ln->tokens[2], indlen, fname));
asmi++;
// M=D
(*asmlns)[asmi] = mkasmln(ln, heapstr("M=D"));
asmi++;
(*asmind) = asmi;
}
void pushtemp(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) {
int asmi = *asmind;
int totalinstrs = 8;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
// // pop static i
int indlen = strlen(ln->tokens[2]);
(*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen));
asmi++;
// @5+i
checkind(ln, indlen);
(*asmlns)[asmi] = mkasmln(ln, mktempind(ln->tokens[2], indlen));
asmi++;
const int instcount = 6;
const char* instrs[] = {
"D=M",
"@SP",
"A=M",
"M=D",
"@SP",
"M=M+1"
};
for(int i = 0; i < instcount; i++) {
(*asmlns)[asmi] = mkasmln(ln, heapstr(instrs[i]));
asmi++;
}
(*asmind) = asmi;
}
void mkpush(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) { void mkpush(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) {
int asmi = *asmind; int asmi = *asmind;
int totalinstrs = 11; int totalinstrs = 11;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs)); checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
startpoppush(ln, asmlns, &asmi); startpoppush(ln, asmlns, &asmi);
@ -179,10 +300,45 @@ void mkpush(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize)
(*asmind) = asmi; (*asmind) = asmi;
} }
void poptemp(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) {
int asmi = *asmind;
int totalinstrs = 7;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
// // pop static i
int indlen = strlen(ln->tokens[2]);
(*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen));
asmi++;
const int instcount = 4;
const char* instrs[] = {
"@SP",
"M=M-1",
"A=M",
"D=M"
};
for(int i = 0; i < instcount; i++) {
(*asmlns)[asmi] = mkasmln(ln, heapstr(instrs[i]));
asmi++;
}
// @5+i
checkind(ln, indlen);
(*asmlns)[asmi] = mkasmln(ln, mktempind(ln->tokens[2], indlen));
asmi++;
// M=D
(*asmlns)[asmi] = mkasmln(ln, heapstr("M=D"));
asmi++;
(*asmind) = asmi;
}
void mkpop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) { void mkpop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) {
int asmi = *asmind; int asmi = *asmind;
int finalasmi = 14; int totalinstrs = 14;
checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+finalasmi)); checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs));
startpoppush(ln, asmlns, &asmi); startpoppush(ln, asmlns, &asmi);
@ -208,17 +364,26 @@ void mkpop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) {
(*asmind) = asmi; (*asmind) = asmi;
} }
void switchop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize, enum operation op) { void switchop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize, enum operation op, char* fname) {
if(op == push) if(op == push)
if(strcmp(ln->tokens[1], "constant") == 0) if(strcmp(ln->tokens[1], "constant") == 0)
pushcons(ln, asmlns, asmind, asmsize); pushcons(ln, asmlns, asmind, asmsize);
else if(strcmp(ln->tokens[1], "static") == 0)
pushstat(ln, asmlns, asmind, asmsize, fname);
else if(strcmp(ln->tokens[1], "temp") == 0)
pushtemp(ln, asmlns, asmind, asmsize);
else else
mkpush(ln, asmlns, asmind, asmsize); mkpush(ln, asmlns, asmind, asmsize);
else if(op == pop) else if(op == pop)
if(strcmp(ln->tokens[1], "static") == 0)
popstat(ln, asmlns, asmind, asmsize, fname);
else if(strcmp(ln->tokens[1], "temp") == 0)
poptemp(ln, asmlns, asmind, asmsize);
else
mkpop(ln, asmlns, asmind, asmsize); mkpop(ln, asmlns, asmind, asmsize);
} }
struct asmln** translate(struct line** lns, int lnscount, int* asmcount) { struct asmln** translate(struct line** lns, int lnscount, int* asmcount, char* fname) {
int sizebet = sizeof(struct asmln*)*(lnscount * 15); int sizebet = sizeof(struct asmln*)*(lnscount * 15);
int asmi = (*asmcount); int asmi = (*asmcount);
struct asmln** asmlns = (struct asmln**)malloc(sizebet); struct asmln** asmlns = (struct asmln**)malloc(sizebet);
@ -226,7 +391,7 @@ struct asmln** translate(struct line** lns, int lnscount, int* asmcount) {
for(int i = 0; i < lnscount; i++) { for(int i = 0; i < lnscount; i++) {
struct line* ln = lns[i]; struct line* ln = lns[i];
enum operation op = getop(ln); enum operation op = getop(ln);
switchop(ln, &asmlns, &asmi, &sizebet, op); switchop(ln, &asmlns, &asmi, &sizebet, op, fname);
} }
(*asmcount) = asmi; (*asmcount) = asmi;

View File

@ -7,5 +7,5 @@ struct asmln {
}; };
void freeasmlns(struct asmln** lns, int count); void freeasmlns(struct asmln** lns, int count);
struct asmln** translate(struct line** lns, int lnscount, int* asmcount); struct asmln** translate(struct line** lns, int lnscount, int* asmcount, char* fname);
#endif #endif