From 5a0cb9d3bc88e42302f96fdede7fe2e51196ffc3 Mon Sep 17 00:00:00 2001 From: Augusto Gunsch Date: Sat, 31 Oct 2020 19:00:09 -0300 Subject: [PATCH] Add constant pushing --- main.c | 28 ++++++++++++++++++++++++++++ translator.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index c2bf2f8..36a5691 100644 --- a/main.c +++ b/main.c @@ -1,14 +1,42 @@ #include #include #include +#include #include "parser.h" #include "translator.h" +char* verfname(char* fname) { + int len = strlen(fname); + if(len > 3) { + int extind = len - 3; + char* extstr = fname + (sizeof(char)*extind); + if(strcmp(extstr, ".vm") == 0) { + int startind = 0; + for(int i = extind-1; i >= 0; i--) { + if(fname[i] == '/') { + startind = i+1; + break; + } + } + int size = sizeof(char)*(extind - startind); + char* startstr = fname + (sizeof(char)*startind); + char* retstr = (char*)malloc(size); + strncpy(retstr, startstr, size); + return retstr; + } + } + fprintf(stderr, "Name format must be Xxx.vm\n"); + exit(1); +} + int main(int argc, char* argv[]) { if(argc < 2) { fprintf(stderr, "Usage: %s {file}\n", argv[0]); return 1; } + // file name validating + char* fname = verfname(argv[1]); + printf("%s\n", fname); FILE* input = fopen(argv[1], "r"); diff --git a/translator.c b/translator.c index 2d713e2..f8e3e2d 100644 --- a/translator.c +++ b/translator.c @@ -12,7 +12,7 @@ enum operation getop(struct line* ln) { return push; if(strcmp(tok, "pop") == 0) return pop; - fprintf(stderr, "Invalid operation '%s'; line %i", tok, ln->truen); + fprintf(stderr, "Invalid operation '%s'; line %i\n", tok, ln->truen); exit(1); } @@ -118,9 +118,44 @@ void startpoppush(struct line* ln, struct asmln*** asmlns, int* asmind) { (*asmind) = asmi; } +void pushcons(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) { + int asmi = *asmind; + int totalinstrs = 8; + + checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs)); + + // // operation segment i + int indlen = strlen(ln->tokens[2]); + (*asmlns)[asmi] = mkasmln(ln, mkcom(ln, indlen)); + asmi++; + + // @i + checkind(ln, indlen); + (*asmlns)[asmi] = mkasmln(ln, mkind(ln->tokens[2], indlen)); + asmi++; + + const int instcount = 6; + const char* instrs[] = { + "D=A", + "@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) { int asmi = *asmind; int totalinstrs = 11; + checkasmsize(asmsize, asmlns, sizeof(struct asmln*)*(asmi+totalinstrs)); startpoppush(ln, asmlns, &asmi); @@ -175,7 +210,10 @@ void mkpop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize) { void switchop(struct line* ln, struct asmln*** asmlns, int* asmind, int* asmsize, enum operation op) { if(op == push) - mkpush(ln, asmlns, asmind, asmsize); + if(strcmp(ln->tokens[1], "constant") == 0) + pushcons(ln, asmlns, asmind, asmsize); + else + mkpush(ln, asmlns, asmind, asmsize); else if(op == pop) mkpop(ln, asmlns, asmind, asmsize); }