diff --git a/.gitignore b/.gitignore index 1bc915c..0dd1a26 100644 --- a/.gitignore +++ b/.gitignore @@ -154,3 +154,5 @@ $RECYCLE.BIN/ # Mac desktop service store files .DS_Store +/VM.VC.VC.opendb +/VM.VC.db diff --git a/Asm/Asm.vcxproj b/Asm/Asm.vcxproj index 2083441..b1fa5e6 100644 --- a/Asm/Asm.vcxproj +++ b/Asm/Asm.vcxproj @@ -13,18 +13,19 @@ {02E49534-A118-4FF8-8114-F3F5FA873223} Asm + 8.1 Application true - v120 + v140 MultiByte Application false - v120 + v140 true MultiByte @@ -80,7 +81,7 @@ - + diff --git a/Asm/Asm.vcxproj.filters b/Asm/Asm.vcxproj.filters index bce0d64..800f3e4 100644 --- a/Asm/Asm.vcxproj.filters +++ b/Asm/Asm.vcxproj.filters @@ -1,51 +1,51 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 头文件 - - - 头文件 - - - 头文件 - - - 头文件 - - - 头文件 - - - - - 源文件 - - - 源文件 - - - - - 资源文件 - - - 资源文件 - - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + + 资源文件 + + \ No newline at end of file diff --git a/Asm/asm.h b/Asm/asm.h index b1fac93..3d3964f 100644 --- a/Asm/asm.h +++ b/Asm/asm.h @@ -11,180 +11,267 @@ using namespace std; +//-------------------------쳣------------------------ +class MismatchException : public exception { + int line; +public: + MismatchException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Character mismatch"; + } +}; + +class UndeclaredException : public exception { + int line; +public: + UndeclaredException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Variable or function undeclared"; + } +}; + +class MultipleDeclaredException : exception { + int line; +public: + MultipleDeclaredException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Multiple labels are declared"; + } +}; + +class InstructionUnsupportedException : exception { + int line; +public: + InstructionUnsupportedException(int line) : exception(), line(line) { ; } + const char * what() const throw () { + return "Instruction unsupported"; + } +}; + +#define MATCH_REG(l, s) \ + match('$'); \ + l->reg = ((Integer*)s)->value; \ + match(NUM); + +#define MATCH_ADDR(l, s) \ + match('#'); \ + l->addr = ((Integer*)s)->value; \ + match(NUM); + +//------------------------------------------------- + class Asm{ private: + int DS = 0; + int CS = 0; + int SS = 0; Token *s; Lexer *lexer; Codes *cs; map lables; - bool match(int kind){ - if (s->kind == kind){ - s = lexer->scan(); - return true; + map funcs; + // basic opts + inline BYTE match_reg() { + match('$'); + BYTE reg = ((Integer*)s)->value; + match(NUM); + return reg; + } + inline WORD match_addr() { + match('#'); + WORD addr = ((Integer*)s)->value; + match(NUM); + return addr; + } + inline Word* match_word() { + Word *w = (Word*)s; + match(ID); + return w; + } + // labels + Code* add_label(string name) { + if (lables.find(name) == lables.end()) { + lables[name] = new Label(lexer->line, name); + } + return lables[name]; + } + // parser + void match(int kind){ + if (s->kind != kind){ + throw MismatchException(lexer->line); } s = lexer->scan(); - return false; } - Code* data(){ - Data *d = new Data; - d->opt = NULL; - d->line = lexer->line; + void data(){ + match('.'); match(DATA); - d->width = ((Integer*)s)->value; - DS = 0; - CS = d->width; - match(INT); - match(DATA); - return d; + //cs->offset = cs->width; + //cs->width += ((Integer*)s)->value; + //DS = 0; + match(NUM); } - Code* store(){ - Store *l = new Store; - l->line = lexer->line; - l->opt = STORE; - match(STORE); - match('$'); - l->reg = ((Integer*)s)->value; - match(INT); - switch (s->kind){ - case '#':l->opt |= MR_A; match('#'); break; - case '*':l->opt |= MR_B; match('*'); break; - default:break; - } - l->addr = ((Integer*)s)->value; - l->width = 4; - match(INT); - return l; - } - Code* halt(){ - Halt *h = new Halt; - h->line = lexer->line; - h->opt = HALT; - h->width = 1; - match(HALT); - return h; + void stack(){ + match('.'); + match(STACK); + //cs->offset = cs->width; + //cs->width += ((Integer*)s)->value; + //SS = cs->width; + match(NUM); } - Code* load(){ - Load *l = new Load; - l->line = lexer->line; - l->opt = LOAD; - match(LOAD); - match('$'); - l->reg = ((Integer*)s)->value; - match(INT); - switch (s->kind){ - case '#':l->opt |= MR_A; match('#'); break; - case '*':l->opt |= MR_B; match('*'); break; - default:break; - } - l->addr = ((Integer*)s)->value; - match(INT); - l->width = 4; - return l; - } - Code* label(){ - match(LABEL); - if (lables.find(((Word*)s)->word) == lables.end()){ - lables[((Word*)s)->word] = new Label((Word*)s, cs->width); + void code(){ + match('.'); + match(CODE); + s = lexer->scan(); + Code *c = new Code(0, CODE); + while (s->kind == PROC){ + c = match_proc(); + if (c){ + cs->pushCode(c); + } } - else{ - lables[((Word*)s)->word]->offset = cs->width; + match('#'); + } + Code* match_proc(){ + match(PROC); + Word *w = match_word(); + match(':'); + Code *body = match_codes(); + match(ENDP); + Proc *proc = new Proc(lexer->line, w->str, body); + funcs[w->str] = proc; + return proc; + } + Code* match_codes() { + Codes *cs, *c; + cs = new Codes(lexer->line); + while (s->kind != ENDP) { + Code *c; + switch (s->kind) { + case ID:c = match_label(); break; + case CALL: c = match_call(); break; + case LOAD:c = match_load(); break; + case STORE:c = match_store(); break; + case PUSH:c = match_push(); break; + case POP:c = match_pop(); break; + case HALT:c = match_halt(); break; + case JE: + case JNE: + case JB: + case JG: + case JMP: c = match_jmp(); break; + case ADD: + case SUB: + case '+': + case '-': + case '*': + case '/': + case '%': + case '<': + case '>': + case '=':c = match_arith(); break; + case '!': + case '~':c = match_unary(); break; + default: throw InstructionUnsupportedException(lexer->line); break; + } + if (c) { cs->pushCode(c); } } - match(ID); + } + Code* match_label() { + Word *w = match_word(); match(':'); + return add_label(w->str); + } + Code* match_call(){ + match(CALL); + Word *w = match_word(); + if (funcs.find(w->str) != funcs.end()){ + Proc *func = funcs[w->str]; + match(ID); + return new Call(lexer->line, func); + } + throw exception("", 1); return nullptr; } - Code* unary(){ - Unary *u = new Unary; - u->line = lexer->line; + Code* match_load() { + BYTE reg = match_reg(); + WORD addr = match_addr(); + return new Load(lexer->line, reg, addr); + } + Code* match_store(){ + match(STORE); + BYTE reg = match_reg(); + WORD addr = match_addr(); + return new Store(lexer->line, reg, addr); + } + Code* match_push() { + match(PUSH); + BYTE reg = match_reg(); + return new Push(lexer->line, reg); + } + Code* match_pop() { + match(POP); + BYTE reg = match_reg(); + match(NUM); + return new Pop(lexer->line, reg); + } + Code* match_unary(){ match('~'); - u->opt = NEG; - match('$'); - u->reg1 = ((Integer*)s)->value; - match(INT); - match('$'); - u->reg2 = ((Integer*)s)->value; - match(INT); - u->width = 3; - return u; - } - Code* arith(BYTE b){ - Arith *a = new Arith; - a->line = lexer->line; - a->opt = b; - match(s->kind); - match('$'); - a->reg1 = ((Integer*)s)->value; - match(INT); - match('$'); - a->reg2 = ((Integer*)s)->value; - match(INT); - match('$'); - a->reg3 = ((Integer*)s)->value; - match(INT); - a->width = 4; - return a; - } - Code* jmp(BYTE b){ - Jmp *j = new Jmp; - j->line = lexer->line; - j->opt = b; + BYTE reg1 = match_reg(); + BYTE reg2 = match_reg(); + return new Unary(lexer->line, NEG, reg1, reg2); + } + Code* match_arith(){ + BYTE opt = s->kind; match(s->kind); - if (lables.find(((Word*)s)->word) == lables.end()){ - // ûбǩ - j->addr = new Label((Word*)s, cs->width); - lables[((Word*)s)->word] = j->addr; - } - else{ - j->addr = lables[((Word*)s)->word]; - } + BYTE reg1 = match_reg(); + BYTE reg2 = match_reg(); + BYTE reg3 = match_reg(); + return new Arith(lexer->line, opt, reg1, reg2, reg3); + } + Code* match_jmp(){ + match(JMP); + Word *w = match_word(); + Label *label = (Label*)add_label(w->str); match(ID); - j->width = 3; - return j; + return new Jmp(lexer->line, label); + } + Code* match_halt(){ + match(HALT); + return new Halt(lexer->line); } public: - int DS = 0; - int CS = 0; Asm(string fp){ lexer = new Lexer(fp); } void parse(){ - Code *c = new Code; - cs = new Codes; - s = lexer->scan(); - while (s->kind != '#'){ - switch (s->kind){ - case ID:printf("[%3d]find id:%s\n", lexer->line, ((Word*)s)->word.c_str()); break; - case DATA:c = data(); break; - case LOAD:c = load(); break; - case STORE:c = store(); break; - case HALT:c = halt(); break; - case LABEL:c = label(); break; - case JE: c = jmp(JE); break; - case JNE: c = jmp(JNE); break; - case JB: c = jmp(JB); break; - case JG: c = jmp(JG); break; - case JMP: c = jmp(JMP); break; - case '~':c = unary(); break; - case '+':c = arith(ADD); break; - case '-':c = arith(SUB); break; - case '*':c = arith(MUL); break; - case '/':c = arith(DIV); break; - case '%':c = arith(MOD); break; - case '<':c = arith(CMP); break; - case '>':c = arith(CMP); break; - case '=':c = arith(CMP); break; - case '!':c = arith(CMP); break; - default:printf("[%3d]find unsupport cmd '%d'\n", lexer->line, s->kind); break; - } - if (c){ cs->codes.push_back(c); c->offset = cs->width; cs->width += c->width; } - } + cs = new Codes(lexer->line); + data(); + stack(); + code(); } void write(FILE *fp){ + BYTE b = 0x00; fwrite(&DS, sizeof(WORD), 1, fp); fwrite(&CS, sizeof(WORD), 1, fp); - fwrite(&cs->width, sizeof(WORD), 1, fp); + fwrite(&SS, sizeof(WORD), 1, fp); + //fwrite(&cs->width, sizeof(WORD), 1, fp); + //fwrite(&b, sizeof(BYTE)*CS, 1, fp); cs->code(fp); } }; + +//printf("[%03d]data.\n", lexer->line); +//printf("[%03d]stack.\n", lexer->line); +//printf("[%03d]proc.\n", lexer->line); +//printf("[%03d]call.\n", lexer->line); +//printf("[%03d]pop.\n", lexer->line); +//printf("[%03d]push.\n", lexer->line); +//printf("[%03d]load.\n", lexer->line); +//printf("[%03d]store.\n", lexer->line); +//printf("[%03d]label.\n", lexer->line); +//printf("[%03d]unary.\n", lexer->line); +//printf("[%03d]arith.\n", lexer->line); +//printf("[%03d]jmp.\n", lexer->line); +//printf("[%03d]halt.\n", lexer->line); #endif \ No newline at end of file diff --git a/Asm/code.h b/Asm/code.h index 7eff493..074f8a1 100644 --- a/Asm/code.h +++ b/Asm/code.h @@ -3,19 +3,25 @@ typedef unsigned char BYTE; typedef unsigned short int WORD; +typedef unsigned int UINT; -//궨ֱ -enum Tag{ +// ʷԪ +enum Tag{ ID = 256, NUM, REG, RTYPE, ITYPE, JTYPE, END, LABEL, DATA, STACK, CODE, PROC, ENDP, CALL }; + +// ָ +enum Inst{ HALT, - ADD, SUB, MUL, DIV, MOD, CMP,// integer operator - JMP, JNE, JG, JE, JB, JGE, JBE, - LOAD, STORE, - PUSH, POP, - NEG, - MOV, IN, OUT, - SHL, SHR, SAL, SAR, SRL, SRR,// - LOOP, - ID = 256, INT, END, LABEL, DATA, CODE, STACK + ADD, SUB, MUL, DIV, MOD, CMP, // Scalar + JMP, JNE, JG, JE, JB, JGE, JBE, // Jump + LOAD, STORE, // Load/Store + PUSH, POP, // Push/Pop + NEG, // Negtive + MOV, IN, OUT, // I/O + SHL, SHR, SAL, SAR, SRL, SRR, // Shift + LOOP, // Loop }; +// Ĵ +enum Reg{ AX, BX, CX, DX, BP, SI, DI, CS, DS, ES, SS, SP }; + #endif \ No newline at end of file diff --git a/Asm/data.asm b/Asm/data.asm deleted file mode 100644 index 0cbd5a0..0000000 --- a/Asm/data.asm +++ /dev/null @@ -1,61 +0,0 @@ -data 4 data -load $2 #0 -store $2 *0 -load $3 #24 -store $3 *2 -load $4 #10 -store $4 *0 -label L0: -load $0 *0 -load $5 #0 -> $0 $5 $6 -jg L2 -jmp L1 -label L2: -load $0 *0 -load $7 #1 -- $0 $7 $8 -store $8 *0 -load $1 *2 -load $9 #1 -+ $1 $9 $10 -store $10 *2 -jmp L0 -label L1: -label L3: -load $0 *0 -load $11 #10 -< $0 $11 $12 -jb L5 -jmp L4 -label L5: -load $0 *0 -load $13 #1 -+ $0 $13 $14 -store $14 *0 -jmp L3 -label L4: -label L6: -load $1 *2 -load $15 #1 -- $1 $15 $16 -store $16 *2 -load $1 *2 -load $17 #12 -> $1 $17 $18 -jg L6 -jmp L7 -label L7: -load $1 *2 -load $0 *0 -! $1 $0 $19 -jne L9 -jmp L8 -label L9: -load $20 #64 -store $20 *0 -load $21 #32 -store $21 *2 -label L8: -halt -# \ No newline at end of file diff --git a/Asm/data.bin b/Asm/data.bin index d4cc308..ac927f8 100644 Binary files a/Asm/data.bin and b/Asm/data.bin differ diff --git a/Asm/data.s b/Asm/data.s new file mode 100644 index 0000000..12d7eee --- /dev/null +++ b/Asm/data.s @@ -0,0 +1,64 @@ +.data 12 +.stack 1000 +.code +proc play: + sub $sp 0 + load $0 &0 + load $7 1 + - $0 $7 $8 + store $8 &0;a + load $1 &2 + load $9 1 + - $1 $9 $10 + store $10 &2;b + load $2 &4 + load $11 1 + - $2 $11 $12 + store $12 &4;c +endp +proc draw: + ;x @2 + ;y @4 + ;a1 @0 + ;b1 @2 + ;c1 @4 + ;d1 @6 + sub $sp 8 + load $14 @0 + store $14 @0;a1 + load $15 @2 + store $15 @2;b1 + load $16 @0 + store $16 @4;c1 + load $17 @2 + store $17 @6;d1 + load $18 @4 + store $18 @0;e1 + load $19 @6 + store $19 @0;f1 + push $bp + load $bp $sp + sub $sp 2 + call play + add $sp 2 + load $sp $bp + pop $bp +endp +proc main: + ;a @0 + sub $sp 2 + load $26 10 + load $27 11 + push $bp + load $bp $sp + push $27 + push $26 + sub $sp 2 + call draw + add $sp 2 + pop $26 + pop $27 + load $sp $bp + pop $bp +endp +# \ No newline at end of file diff --git a/Asm/inst.h b/Asm/inst.h new file mode 100644 index 0000000..0050502 --- /dev/null +++ b/Asm/inst.h @@ -0,0 +1,236 @@ +#pragma once + +typedef char S1; +typedef short int S2; +typedef int S4; +typedef long int S8; + +typedef unsigned char U1; +typedef unsigned short int U2; +typedef unsigned int U4; +typedef unsigned long int U8; + +typedef float F4; +typedef double F8; + +// ָ +enum Inst { + LBI, LWI, LDI, LQI, LF1I, LF2I, + LAD, LAI, + LB, LW, LD, LQ, LF1, LF2, + SB, SW, SD, SQ, SF1, SF2, + PUSHB, PUSHW, PUSHD, PUSHQ, PUSHF1, PUSHF2, + POPB, POPW, POPD, POPQ, POPF1, POPF2, + MOV, MOVF, MOVD, + JMP, JE, JNE, SLT, INT, DI, EI, HALT, NOP, + AND, OR, XOR, NOT, BT, BS, + SRA, SRL, SL, + ADD, SUB, MUL, DIV, + CAST_IF, CAST_ID, CAST_FI, CAST_FD, CAST_DI, CAST_DF, + FADD, FSUB, FMUL, FDIV, FSLT, + DADD, DSUB, DMUL, DDIV, DSLT +}; + +// Load + +#define EXEC_LBI(); R[RAM[IP+1]]=(S1)RAM[IP+2];\ + IP+=3; + +#define EXEC_LWI(); R[RAM[IP+1]]=(S2)*((S2*)&RAM[IP+2]);\ + IP+=4; + +#define EXEC_LDI(); R[RAM[IP+1]]=(S4)*((S4*)&RAM[IP+2]);\ + IP+=6; + +#define EXEC_LQI(); R[RAM[IP+1]]=(S8)*((S8*)&RAM[IP+2]);\ + IP+=10; + +#define EXEC_LF1I(); RF[RAM[IP+1]]=(F4)*((F4*)&RAM[IP+2]);\ + IP+=6; + +#define EXEC_LF2I(); RF[RAM[IP+1]]=(F8)*((F8*)&RAM[IP+2]);\ + IP+=10; + +#define EXEC_LAD(); R[RAM[IP+1]]=(U8)*((U8*)&RAM[IP+2]);\ + IP+=10; + +#define EXEC_LAI(); R[RAM[IP+1]]=R[RAM[IP+2]]+((S8)*((S8*)&RAM[IP+3]));\ + IP+=11; + +#define EXEC_LB(); R[RAM[IP+1]]=(S8)(*((S1*)&RAM[R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LW(); R[RAM[IP+1]]=(S8)(*((S2*)&RAM[(U8)R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LD(); R[RAM[IP+1]]=(S8)(*((S4*)&RAM[(U8)R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LQ(); R[RAM[IP+1]]=(S8)(*((S8*)&RAM[(U8)R[RAM[IP+2]]]));\ + IP+=3; + +#define EXEC_LF1(); RF[RAM[IP+1]]=*((F4*)&RAM[(U8)R[RAM[IP+2]]]);\ + IP+=3; + +#define EXEC_LF2(); RD[RAM[IP+1]]=*((F8*)&RAM[(U8)R[RAM[IP+2]]]);\ + IP+=3; + +// Store + +#define EXEC_SB(); RAM[R[RAM[IP+2]]]=(S1)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SW(); *((S2*)&RAM[R[RAM[IP+2]]])=(S2)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SD(); *((S4*)&RAM[R[RAM[IP+2]]])=(S4)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SQ(); *((S8*)&RAM[R[RAM[IP+2]]])=(S8)R[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SF1(); *((F4*)&RAM[R[RAM[IP+2]]])=RF[RAM[IP+1]];\ + IP+=3; + +#define EXEC_SF2(); *((F8*)&RAM[R[RAM[IP+2]]])=RD[RAM[IP+1]];\ + IP+=3; + +// Push + +#define EXEC_PUSHB(); SP--;\ + RAM[SP]=(S1)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHW(); SP-=2;\ + *((S2*)&RAM[SP])=(S2)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHD(); SP-=4;\ + *((S4*)&RAM[SP])=(S4)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHQ(); SP-=8;\ + *((S8*)&RAM[SP])=(S8)(R[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHF1(); SP-=4;\ + *((F4*)&RAM[SP])=(F4)(RF[RAM[IP+1]]);\ + IP+=2; + +#define EXEC_PUSHF2(); SP-=8;\ + *((F8*)&RAM[SP])=(F8)(RF[RAM[IP+1]]);\ + IP+=2; + +// Pop + +#define EXEC_POPB(); R[RAM[IP+1]]=(S1)*((S1*)&RAM[SP]);\ + SP+=1;\ + IP+=2; + +#define EXEC_POPW(); R[RAM[IP+1]]=(S2)*((S2*)&RAM[SP]);\ + SP+=2;\ + IP+=2; + +#define EXEC_POPD(); R[RAM[IP+1]]=(S4)*((S4*)&RAM[SP]);\ + SP+=4;\ + IP+=2; + +#define EXEC_POPQ(); R[RAM[IP+1]]=(S8)*((S8*)&RAM[SP]);\ + SP+=8;\ + IP+=2; + +#define EXEC_POPF1(); RF[RAM[IP+1]]=(F4)*((F4*)&RAM[SP]);\ + SP+=4;\ + IP+=2; + +#define EXEC_POPF2(); RD[RAM[IP+1]]=(F8)*((F8*)&RAM[SP]);\ + SP+=8;\ + IP+=2; + +// Mov + +#define EXEC_MOV(); R[RAM[IP+1]]=R[RAM[IP+2]];\ + IP+=3; + +#define EXEC_MOVF(); RF[RAM[IP+1]]=RF[RAM[IP+2]];\ + IP+=3; + +#define EXEC_MOVD(); RD[RAM[IP+1]]=RD[RAM[IP+2]];\ + IP+=3; + +// Jump + +#define EXEC_JMP(); IP=R[RAM[IP+1]]; + +#define EXEC_JE(); if(R[RAM[IP+1]]==R[RAM[IP+2]])\ + IP=R[RAM[IP+3]];\ + else\ + IP+=4; + +#define EXEC_JNE(); if(R[RAM[IP+1]]!=R[RAM[IP+2]])\ + IP=R[RAM[IP+3]];\ + else\ + IP+=4; + +#define EXEC_SLT(); if(R[RAM[IP+2]]> ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_SRL(); R[RAM[IP+1]]=R[RAM[IP+2]] >> R[RAM[IP+3]];\ + IP+=4; + +#define EXEC_SL(); R[RAM[IP+1]]=R[RAM[IP+2]] << R[RAM[IP+3]];\ + IP+=4; + +// Integer Math + +#define EXEC_ADD(); R[RAM[IP+1]]=((S8)R[RAM[IP+2]]) + ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_SUB(); R[RAM[IP+1]]=((S8)R[RAM[IP+2]]) - ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_MUL(); R[RAM[IP+1]]=((S8)R[RAM[IP+2]]) * ((S8)R[RAM[IP+3]]);\ + IP+=4; + +#define EXEC_DIV(); R[RAM[IP+1]]=((S8)R[RAM[IP+3]]) / ((S8)R[RAM[IP+4]]);\ + R[RAM[IP+2]]=((S8)R[RAM[IP+3]]) % ((S8)R[RAM[IP+4]]);\ + IP+=5; \ No newline at end of file diff --git a/Asm/inter.h b/Asm/inter.h index 26504ad..27a4b7e 100644 --- a/Asm/inter.h +++ b/Asm/inter.h @@ -1,23 +1,33 @@ #include "lexer.h" -struct Label{ - Word *w; - WORD offset; - Label(Word *w, int offset) :w(w), offset(offset) { } -}; -struct Code{ +//----------------οRISCָ---------------- +class Code { +protected: BYTE opt; WORD line = 0;// ǰָڻļеλ - WORD width = 0;// ǰռõĿ WORD offset = 0;// ǰεƫ +public: + int getWitdh() { return 0; } + Code(int line, BYTE opt) :line(line), opt(opt) { ; } virtual void code(FILE* fp){ - printf("[%04d][%04d][%04x]", line, width, offset); + printf("[%04d][%04x]", line, offset); } }; -struct Codes :Code{ +class Codes : public Code{ list codes; +public: + Codes(int line) : Code(line, CODE) { ; } + void pushCode(Code *c) { codes.push_back(c); } + int getWidth() { + int width; + list::iterator iter; + for (iter = codes.begin(); iter != codes.end(); iter++) { + width += (*iter)->getWitdh(); + } + return width; + } virtual void code(FILE* fp){ list::iterator iter; for (iter = codes.begin(); iter != codes.end(); iter++){ @@ -26,19 +36,67 @@ struct Codes :Code{ } }; -struct Data :Code{ +class Data : public Code{ + int width; +public: virtual void code(FILE* fp){ Code::code(fp); - printf("data:%2d\n", width); - for (WORD i = 0; i < width; i++){ - fwrite(&opt, sizeof(BYTE), 1, fp); - } + printf("data:\n"); + //for (WORD i = 0; i < width; i++){ + // fwrite(&opt, sizeof(BYTE), 1, fp); + //} + } +}; + +class Label : public Code { + string name; +public: + Label(int line, string name) : Code(line, LABEL), name(name) { ; } +}; + +class Proc : public Code { + string name; + Code *body; +public: + Proc(int line, string name, Code *body) :Code(line, PROC), name(name), body(body) { ; } + virtual void code(FILE* fp) { + Code::code(fp); + body->code(fp); + } +}; + +class Arith : public Code { + BYTE reg1, reg2, reg3; +public: + Arith(int line, BYTE opt, BYTE reg1, WORD reg2, WORD reg3) : Code(line, opt), reg1(reg1), reg2(reg2), reg3(reg3) { ; } + virtual void code(FILE* fp) { + Code::code(fp); + printf("bino\t$%02x $%02x $%02x $%02x\n", opt, reg1, reg2, reg3); + fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®1, sizeof(BYTE), 1, fp); + fwrite(®2, sizeof(BYTE), 1, fp); + fwrite(®3, sizeof(BYTE), 1, fp); } }; -struct Load :Code{ +class Unary : public Code { + BYTE reg1, reg2; +public: + Unary(int line, BYTE opt, BYTE reg1, BYTE reg2) :Code(line, opt), reg1(reg1), reg2(reg2) { ; } + virtual void code(FILE* fp) { + Code::code(fp); + printf("unary\t$%02x $%02x $%02x\n", opt, reg1, reg2); + fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®1, sizeof(BYTE), 1, fp); + fwrite(®2, sizeof(BYTE), 1, fp); + } +}; + +class Load : public Code{ BYTE reg; WORD addr; +public: + Load(int line, BYTE reg, WORD addr) : Code(line, LOAD), reg(reg), addr(addr) { } virtual void code(FILE* fp){ Code::code(fp); printf("load\t$%02x $%02x $%04x\n", opt, reg, addr); @@ -46,58 +104,84 @@ struct Load :Code{ fwrite(®, sizeof(BYTE), 1, fp); fwrite(&addr, sizeof(WORD), 1, fp); } -};// ֱѰַ +}; -struct Store :Code{ +class Store : public Code { BYTE reg; WORD addr; +public: + Store(int line, BYTE reg, WORD addr) : Code(line, STORE), reg(reg), addr(addr) { } virtual void code(FILE* fp){ Code::code(fp); - printf("store\t$%02x $%02x $%04x\n", opt, reg, addr); + printf("store\t$%02x $%02x $%04x\n", STORE, reg, addr); fwrite(&opt, sizeof(BYTE), 1, fp); fwrite(®, sizeof(BYTE), 1, fp); fwrite(&addr, sizeof(WORD), 1, fp); } }; -struct Halt:Code{ +class Push : public Code{ + BYTE reg; +public: + Push(int line, BYTE reg) : Code(line, PUSH), reg(reg) { ; } virtual void code(FILE* fp){ Code::code(fp); - opt = HALT; - printf("halt\t$%02x\n", opt); + printf("push\t$%02x $%02x\n", opt, reg); fwrite(&opt, sizeof(BYTE), 1, fp); + fwrite(®, sizeof(BYTE), 1, fp); } }; -struct Jmp :Code{ - Label *addr; +class Pop : public Code{ + BYTE reg; +public: + Pop(int line, BYTE reg) : Code(line, POP), reg(reg) { ; } virtual void code(FILE* fp){ Code::code(fp); - printf("jmp \t$%02x $%04x\n", opt, addr->offset); + printf("pop\t$%02x $%02x\n", opt, reg); fwrite(&opt, sizeof(BYTE), 1, fp); - fwrite(&addr->offset, sizeof(WORD), 1, fp); + fwrite(®, sizeof(BYTE), 1, fp); } }; -struct Arith :Code{ - BYTE reg1, reg2, reg3; - virtual void code(FILE* fp){ +class Jmp : public Code { + Label *label; +public: + Jmp(int line, Label *label) : Code(line, JMP), label(label) { ; } + virtual void code(FILE* fp) { Code::code(fp); - printf("bino\t$%02x $%02x $%02x $%02x\n", opt, reg1, reg2, reg3); - fwrite(&opt, sizeof(BYTE), 1, fp); - fwrite(®1, sizeof(BYTE), 1, fp); - fwrite(®2, sizeof(BYTE), 1, fp); - fwrite(®3, sizeof(BYTE), 1, fp); + //printf("jmp \t$%02x $%04x\n", opt, addr->offset); + //fwrite(&opt, sizeof(BYTE), 1, fp); + //fwrite(&addr->offset, sizeof(WORD), 1, fp); } }; -struct Unary :Code{ - BYTE reg1, reg2; +class Param : public Code { + BYTE reg;// Ĵ + virtual void code(FILE* fp) { + Code::code(fp); + //printf("param\t$%04x;%s\n", opt, reg); + //fwrite(&opt, sizeof(BYTE), 1, fp); + } +}; + +class Call : public Code { + Proc *func;// +public: + Call(int line, Proc *func) : Code(line, PROC), func(func) { ; } + virtual void code(FILE* fp) { + Code::code(fp); + //printf("call\t$%04x;%s\n", func->offset, func->name.c_str()); + //fwrite(&opt, sizeof(BYTE), 1, fp); + } +}; + +class Halt: public Code { +public: + Halt(int line) : Code(line, HALT) { ; } virtual void code(FILE* fp){ Code::code(fp); - printf("unary\t$%02x $%02x $%02x\n", opt, reg1, reg2); - fwrite(&opt, sizeof(BYTE), 1, fp); - fwrite(®1, sizeof(BYTE), 1, fp); - fwrite(®2, sizeof(BYTE), 1, fp); + //printf("halt\t$%02x\n", opt); + //fwrite(&opt, sizeof(BYTE), 1, fp); } }; \ No newline at end of file diff --git a/Asm/lexer.h b/Asm/lexer.h index 34a6c78..477a015 100644 --- a/Asm/lexer.h +++ b/Asm/lexer.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -30,12 +31,12 @@ struct Token{ }; struct Word :Token{ - string word; - Word(int tag, string word) :Token(tag), word(word) { } + string str; + Word(int tag, string str) :Token(tag), str(str) { } virtual string place(){ - ostringstream s; - s << word; - return s.str(); + ostringstream os; + os << str; + return os.str(); } virtual string code(){ return ""; @@ -44,11 +45,11 @@ struct Word :Token{ struct Type :Word{ int width; - static Type* Int; + static Type *Int, *Reg; Type(int kind, string word, int width) :Word(kind, word), width(width){ } virtual string place(){ ostringstream s; - s << word << ":" << width; + s << str << ":" << width; return s.str(); } virtual string code(){ @@ -56,7 +57,8 @@ struct Type :Word{ } }; -Type* Type::Int = new Type(INT, "int", 2); +Type* Type::Int = new Type(NUM, "int", 2); +Type* Type::Reg = new Type(REG, "int", 1); struct Integer :Token{ int value; @@ -71,6 +73,9 @@ struct Integer :Token{ } }; +#define DEF_KEY_WORD(key, type, value) words[key] = new Integer(type, value) + + // ʷ class Lexer{ ifstream inf; @@ -90,19 +95,66 @@ class Lexer{ public: int line = 1; Lexer(string fp){ + inf.open(fp, ios::in); words["data"] = new Word(DATA, "data"); + words["stack"] = new Word(STACK, "stack"); words["code"] = new Word(CODE, "code"); - words["int"] = new Word(INT, "int"); + // ݲ words["load"] = new Word(LOAD, "load"); words["store"] = new Word(STORE, "store"); + // ָͣ words["halt"] = new Word(HALT, "halt"); - words["label"] = new Word(LABEL, "label"); + // ߼ + words["sub"] = new Word(SUB, "add"); + words["add"] = new Word(ADD, "sub"); + // ջָ + words["push"] = new Word(PUSH, "push"); + words["pop"] = new Word(POP, "pop"); + // תָ words["jmp"] = new Word(JMP, "jmp"); words["jb"] = new Word(JB, "jb"); + words["jbe"] = new Word(JBE, "jbe"); words["je"] = new Word(JE, "je"); - words["jne"] = new Word(JNE, "jne"); + words["jge"] = new Word(JGE, "jge"); words["jg"] = new Word(JG, "jg"); - inf.open(fp, ios::in); + words["jne"] = new Word(JNE, "jne"); + // + words["proc"] = new Word(PROC, "proc"); + words["endp"] = new Word(ENDP, "endp"); + words["call"] = new Word(CALL, "call"); + // μĴ + words["ds"] = new Integer(REG, Reg::DS); + words["cs"] = new Integer(REG, Reg::CS); + words["ss"] = new Integer(REG, Reg::SS); + words["es"] = new Integer(REG, Reg::ES); + // Ĵ + words["bp"] = new Integer(REG, Reg::BP); + words["sp"] = new Integer(REG, Reg::SP); + words["si"] = new Integer(REG, Reg::SI); + words["di"] = new Integer(REG, Reg::DI); + } + // MIPSָ + void MIPS(){ + // R-type + DEF_KEY_WORD("add",RTYPE, 0x00000020); + DEF_KEY_WORD("addu",RTYPE, 0x00000021); + DEF_KEY_WORD("sub",RTYPE, 0x00000022); + DEF_KEY_WORD("subu",RTYPE, 0x00000023); + DEF_KEY_WORD("and",RTYPE, 0x00000024); + DEF_KEY_WORD("or",RTYPE, 0x00000025); + DEF_KEY_WORD("xor",RTYPE, 0x00000026); + DEF_KEY_WORD("nor",RTYPE, 0x00000027); + DEF_KEY_WORD("slt",RTYPE, 0x0000002A); + DEF_KEY_WORD("sltu",RTYPE, 0x0000002B); + DEF_KEY_WORD("sll",RTYPE, 0x00000000); + DEF_KEY_WORD("srl",RTYPE, 0x00000002); + DEF_KEY_WORD("ara",RTYPE, 0x00000003); + DEF_KEY_WORD("add",RTYPE, 0x00000004); + DEF_KEY_WORD("add",RTYPE, 0x00000005); + DEF_KEY_WORD("srav",RTYPE, 0x00000006); + // I-Type + + // J-Type } ~Lexer(){ inf.close(); @@ -115,9 +167,16 @@ class Lexer{ char ch; do{ inf.read(&ch, sizeof(ch)); + if (ch == ';'){ + while (ch != '\n'){ + //printf("skip:%c\n", ch); + inf.read(&ch, sizeof(ch)); + } + } if (ch == '\n')line++; } while (ch == ' ' || ch == '\n' || ch == '\t'); - if (ch == EOF){ + if (inf.eof()){ + printf("end of file\n"); return new Token(END); } if (isalpha(ch)){ @@ -148,7 +207,7 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); inf.seekg(-1, ios::cur); - return new Integer(INT, value); + return new Integer(NUM, value); }else{ printf("ʮ!"); } @@ -159,11 +218,11 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (ch >= '0'&&ch <= '7'); inf.seekg(-1, ios::cur); - return new Integer(INT, value); + return new Integer(NUM, value); }else{ //ʮ0 inf.seekg(-1, ios::cur); - return new Integer(INT, 0); + return new Integer(NUM, 0); } }else{ //0ʮ,5״̬ @@ -172,7 +231,7 @@ class Lexer{ inf.read(&ch, sizeof(ch)); } while (isdigit(ch)); inf.seekg(-1, ios::cur);//һַ - return new Integer(INT, value); + return new Integer(NUM, value); } } return new Token(ch); diff --git a/Asm/main.cpp b/Asm/main.cpp index 7280261..beb3694 100644 --- a/Asm/main.cpp +++ b/Asm/main.cpp @@ -5,9 +5,11 @@ void main(){ FILE file; FILE *fp = &file; // Ŀ - printf("Ŀ\n"); - Asm Asm("data.asm"); + Asm Asm("data.s"); + printf("﷨ʼ\n"); Asm.parse(); + printf("﷨\n"); + printf("࿪ʼ\n"); printf("line width offset\n"); fopen_s(&fp, "data.bin", "w"); Asm.write(fp); @@ -15,13 +17,13 @@ void main(){ printf("\n"); // ִ printf("ִ\n"); - CPU CPU; - CPU.init(); - fopen_s(&fp, "data.bin", "r"); - CPU.load(fp); - fclose(fp); - CPU.execute(); - CPU.store(); + //CPU CPU; + //CPU.init(); + //fopen_s(&fp, "data.bin", "r"); + //CPU.load(fp); + //fclose(fp); + //CPU.execute(); + //CPU.store(); printf("ִн\n"); cin >> a; } \ No newline at end of file diff --git a/Asm/vm.cpp b/Asm/vm.cpp index 20beaa9..f9e3648 100644 --- a/Asm/vm.cpp +++ b/Asm/vm.cpp @@ -8,6 +8,7 @@ void CPU::init(){ void CPU::load(FILE *fp){ fread(&DS, sizeof(WORD), 1, fp); fread(&CS, sizeof(WORD), 1, fp); + fread(&SS, sizeof(WORD), 1, fp); fread(&LENGTH, sizeof(WORD), 1, fp); fread(&RAM, sizeof(BYTE)* LENGTH, 1, fp); printf("DS:%04d,CS:%04d,LENGTH:%04d\n", DS, CS, LENGTH); @@ -181,6 +182,10 @@ void CPU::execute(){ RAM[ABUS + 1] = DBUS >> 8; } break; + case IN: + break; + case OUT: + break; case HALT: break; default: diff --git a/Asm/vm.h b/Asm/vm.h index c0e0f5a..36cf4b4 100644 --- a/Asm/vm.h +++ b/Asm/vm.h @@ -17,8 +17,15 @@ using namespace std; #define BIT_ERR 0x0001 // ڴѰַʽ -#define MR_A 0x00// 0000 -#define MR_B 0x40// 0100ֱѰַ +//#define MR_A 0x80// immѰַ +//#define MR_B 0x40// addrֱѰַ +//#define MR_C 0x20// [addr]Ѱַ +//#define MR_D 0x10// regĴѰַ +//#define MR_E 0x08// [reg]ĴѰַ +//#define MR_F 0x04// offsetѰַ +//#define MR_G 0x02// [BP]ַѰַ +//#define MR_H 0x01// [reg+addr]ַѰַ + // /ֽڲ #define MR_BYTE 0x80 // [111][111][0][0] @@ -62,14 +69,14 @@ class CPU{ private: WORD LENGTH = 0; BYTE REG[0x100]; - WORD SP, BP, SI, DI; // ͨüĴ - WORD CS, DS, ES, SS; // μĴ - WORD IN[0x100], OUT[0x100]; // I/O˿ - WORD IP; // ָ - WORD IBUS, DBUS, ABUS; // ڲ - BYTE RAM[0x10000]; // ڴ - WORD CYCLE = 0; // ִ - ALU ALU; // ALU + WORD SP, BP, SI, DI; // ͨüĴ + WORD CS, DS, ES, SS; // μĴ + WORD PORT[0x100]; // I/O˿ + WORD IP; // ָ + WORD IBUS, DBUS, ABUS; // ڲ + BYTE RAM[0x10000]; // ڴ + WORD CYCLE = 0; // ִ + ALU ALU; // ALU BYTE ReadB(){ return RAM[IP++]; } diff --git a/CPU/CPU.vcxproj b/CPU/CPU.vcxproj index 20c010c..c4dc528 100644 --- a/CPU/CPU.vcxproj +++ b/CPU/CPU.vcxproj @@ -20,18 +20,19 @@ {9C3738FC-3CCD-4F28-ACB3-BDB310F2C523} CPU + 8.1 Application true - v120 + v140 MultiByte Application false - v120 + v140 true MultiByte diff --git a/CPU/CPU.vcxproj.filters b/CPU/CPU.vcxproj.filters index c20d9ac..223971e 100644 --- a/CPU/CPU.vcxproj.filters +++ b/CPU/CPU.vcxproj.filters @@ -1,30 +1,30 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 源文件 - - - 源文件 - - - - - 头文件 - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + \ No newline at end of file diff --git a/Parser/G.txt b/Parser/G.txt new file mode 100644 index 0000000..cd913b1 --- /dev/null +++ b/Parser/G.txt @@ -0,0 +1 @@ +@+(@+(@+@)*@*((@+@)*@+@)+(@+@)*@*(@+@*@))# \ No newline at end of file diff --git a/Parser/Parser.exe b/Parser/Parser.exe new file mode 100644 index 0000000..a8b3f7f Binary files /dev/null and b/Parser/Parser.exe differ diff --git a/Parser/Parser.vcxproj b/Parser/Parser.vcxproj index 8040781..e369b4f 100644 --- a/Parser/Parser.vcxproj +++ b/Parser/Parser.vcxproj @@ -13,18 +13,19 @@ {CF29041C-7B18-4A25-B28C-2660CAFD81F6} Parser + 8.1 Application true - v120 + v140 MultiByte Application false - v120 + v140 true MultiByte @@ -71,15 +72,21 @@ + + + + + + - + diff --git a/Parser/Parser.vcxproj.filters b/Parser/Parser.vcxproj.filters index d3f3096..123a9ff 100644 --- a/Parser/Parser.vcxproj.filters +++ b/Parser/Parser.vcxproj.filters @@ -1,43 +1,61 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 资源文件 - - - - - 源文件 - - - - - 头文件 - - - 头文件 - - - 头文件 - - - - - 资源文件 - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 资源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 资源文件 + + + 头文件 + + + + + 资源文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + \ No newline at end of file diff --git a/Parser/Text.txt b/Parser/Text.txt index 84dec82..ed96c78 100644 --- a/Parser/Text.txt +++ b/Parser/Text.txt @@ -1,22 +1,31 @@ -int a,b; +int a,b,c,d,e,f; -a = 0; -b = 24; - -for(a = 10;a > 0;a = a - 1){ - b = b + 1; +int play(){ + a = a - 1; + b = b - 1; + c = c - 1; } -while(a < 10){ - a = a + 1; +int draw(int x, int y){ + int a1,b1; + a1 = x; + b1 = y; + { + int c1,d1; + c1 = a1; + d1 = b1; + { + int e1,f1; + e1 = c1; + f1 = d1; + } + { + play(); + } + } } -do{ - b = b - 1; -}while(b > 12); - -if(b ! a){ - a = 64; - b = 32; -} -# \ No newline at end of file +int main(){ + int a; + draw(10, 11); +} \ No newline at end of file diff --git a/Parser/builder.cpp b/Parser/builder.cpp new file mode 100644 index 0000000..6d4ee13 --- /dev/null +++ b/Parser/builder.cpp @@ -0,0 +1,21 @@ +#include "builder.h" + +Value * Builder::CreateFAdd(Value * L, Value * R, string name) +{ + return nullptr; +} + +Value * Builder::CreateFSub(Value * L, Value * R, string name) +{ + return nullptr; +} + +Value * Builder::CreateFMul(Value * L, Value * R, string name) +{ + return nullptr; +} + +Value * Builder::CreateFDiv(Value * L, Value * R, string name) +{ + return nullptr; +} diff --git a/Parser/builder.h b/Parser/builder.h new file mode 100644 index 0000000..98f6dcf --- /dev/null +++ b/Parser/builder.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +using namespace std; + +class Value { + +}; + +class Builder { +public: + Value *CreateFAdd(Value *L, Value *R, string name); + Value *CreateFSub(Value *L, Value *R, string name); + Value *CreateFMul(Value *L, Value *R, string name); + Value *CreateFDiv(Value *L, Value *R, string name); +}; \ No newline at end of file diff --git a/Parser/data.asm b/Parser/data.asm deleted file mode 100644 index 304c2ad..0000000 --- a/Parser/data.asm +++ /dev/null @@ -1,60 +0,0 @@ -data 4 data -load $2 #0 -store $2 *0 -load $3 #24 -store $3 *2 -load $4 #10 -store $4 *0 -label L0: -load $0 *0 -load $5 #0 -> $0 $5 $6 -jg L2 -jmp L1 -label L2: -load $0 *0 -load $7 #1 -- $0 $7 $8 -store $8 *0 -load $1 *2 -load $9 #1 -+ $1 $9 $10 -store $10 *2 -jmp L0 -label L1: -label L3: -load $0 *0 -load $11 #10 -< $0 $11 $12 -jb L5 -jmp L4 -label L5: -load $0 *0 -load $13 #1 -+ $0 $13 $14 -store $14 *0 -jmp L3 -label L4: -label L6: -load $1 *2 -load $15 #1 -- $1 $15 $16 -store $16 *2 -load $1 *2 -load $17 #12 -> $1 $17 $18 -jg L6 -jmp L7 -label L7: -load $1 *2 -load $0 *0 -! $1 $0 $19 -jne L9 -jmp L8 -label L9: -load $20 #64 -store $20 *0 -load $21 #32 -store $21 *2 -label L8: -halt diff --git a/Parser/data.s b/Parser/data.s new file mode 100644 index 0000000..a2795cd --- /dev/null +++ b/Parser/data.s @@ -0,0 +1,56 @@ +.data + dw a + dw b + dw c + dw d + dw e + dw f +.stack + db dup(0x1000) +.code +proc play: + sub $sp 0 + loadw $0 a + loadb $7 1 + sub $0 $7 $8 + store a $8 + loadw $1 b + loadb $9 1 + sub $1 $9 $10 + store b $10 + loadw $2 c + loadb $11 1 + sub $2 $11 $12 + store c $12 +endp +proc draw: + ;x @2 + ;y @4 + ;a1 @0 + ;b1 @2 + ;c1 @4 + ;d1 @6 + sub $sp 8 + loadw $14 x + store a1 $14 + loadw $15 y + store b1 $15 + loadw $16 a1 + store c1 $16 + loadw $17 b1 + store d1 $17 + loadw $18 c1 + store e1 $18 + loadw $19 d1 + store f1 $19 + call play 0 +endp +proc main: + ;a @0 + sub $sp 2 + loadb $26 10 + loadb $27 11 + param $27 + param $26 + call draw 2 +endp diff --git a/Parser/inter.cpp b/Parser/inter.cpp new file mode 100644 index 0000000..5ef906e --- /dev/null +++ b/Parser/inter.cpp @@ -0,0 +1,131 @@ +#include "inter.h" + +Value * Stmt::Codegen() +{ +} + +Value * Block::Codegen() +{ + for (Stmt *blk : block) { + blk->Codegen(); + } +} + +Value * BinaryExprAST::Codegen() +{ + lhs->Codegen(); + rhs->Codegen(); +} + +Value * UnaryExprAST::Codegen() +{ + rhs->Codegen(); +} + +Value * VariableExprAST::Codegen() +{ +} + +Value * AssignExprAST::Codegen() +{ + rhs->Codegen(); +} + +Value * ConstantExprAST::Codegen() +{ +} + +Value * AccessExprAST::Codegen() +{ + return nullptr; +} + +Value * MemberExpr::Codegen() +{ + return nullptr; +} + +Value * CallExprAST::Codegen() +{ + vector::iterator iter; + for (ExprAST* expr : args) { + expr->Codegen(); + } + reverse(args.begin(), args.end()); + for (ExprAST* expr : args) { + + } +} + +Value * Decl::Codegen() +{ +} + +Value * IfElse::Codegen() +{ + cond->Codegen(); + body_t->Codegen(); + if (body_f) { + body_f->Codegen(); + } +} + +Value * WhileDo::Codegen() +{ + cond->Codegen(); + body->Codegen(); +} + +Value * DoWhile::Codegen() +{ + body->Codegen(); + cond->Codegen(); +} + +Value * For::Codegen() +{ + init->Codegen(); + cond->Codegen(); + body->Codegen(); + step->Codegen(); +} + +Value * Switch::Codegen() +{ + expr->Codegen(); + for (Case cs : cases) { + cs.second->Codegen(); + } +} + +Value * Break::Codegen() +{ +} + +Value * Continue::Codegen() +{ +} + +Value * Throw::Codegen() +{ +} + +Value * TryCatch::Codegen() +{ + pTry->Codegen(); + pCatch->Codegen(); + pFinally->Codegen(); +} + +Value * FunctionAST::Codegen() +{ +} + +Value * PrototypeAST::Codegen() +{ +} + +Value * ParameterAST::Codegen() +{ + return nullptr; +} diff --git a/Parser/inter.h b/Parser/inter.h index b6e412a..e256149 100644 --- a/Parser/inter.h +++ b/Parser/inter.h @@ -4,264 +4,244 @@ #define __INTER_H_ #include +#include +#include "builder.h" -struct Node{ - virtual void code(FILE *fp){ - } +class Visitor; + +class AST{ + friend class Visitor; +public: + virtual Value * Codegen() = 0; }; -//ʽ -struct Expr :Node{ - char opt; - int label; - static int count; - Expr(char opt) :opt(opt){ label = count++; } - virtual void code(FILE *fp){ - Node::code(fp); +// +class Stmt : public AST{ +public: + int line; + int begin, next; + static int label; + static int newlabel(){ + return label++; } + virtual Value * Codegen() = 0; }; -int Expr::count = 0; - -// ʽ -struct Cond :Expr{ - int True, False; - Expr *E1, *E2; - Cond(char opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} - virtual void code(FILE *fp){ - Expr::code(fp); - E1->code(fp); - E2->code(fp); - fprintf(fp, "%c $%d $%d $%d\n", opt, E1->label, E2->label, label); - switch (opt){ - case '>':fprintf(fp, "jg L%d\n", True); break; - case '=':fprintf(fp, "je L%d\n", True); break; - case '<':fprintf(fp, "jb L%d\n", True); break; - case '!':fprintf(fp, "jne L%d\n", True); break; - default:fprintf(fp, "jmp L%d\n", True); break; - } - fprintf(fp, "jmp L%d\n", False); - } +int Stmt::label = 0; + +// +class Block : public Stmt{ + vector block; +public: + Block(vector &block) : block(block) { } + Value * Codegen(); }; -// ʽ -struct Arith :Expr{ - Expr *E1, *E2; - Arith(char opt, Expr *E1, Expr *E2) :Expr(opt), E1(E1), E2(E2){} - virtual void code(FILE *fp){ - Expr::code(fp); - E1->code(fp); - E2->code(fp); - fprintf(fp, "%c $%d $%d $%d\n", opt, E1->label, E2->label, label); - } +//ʽ +class ExprAST : public Stmt{ +public: + Type *type; + virtual Value * Codegen() = 0; +}; + +class BinaryExprAST : public ExprAST { + int opt; + ExprAST *lhs, *rhs; +public: + BinaryExprAST(int opt, ExprAST *pL, ExprAST *pR) + : opt(opt), lhs(pL), rhs(pR) { } + Value * Codegen(); +}; + +class UnaryExprAST : public ExprAST{ + int opt; + ExprAST *rhs; +public: + UnaryExprAST(int opt, ExprAST *E1) + : opt(opt), rhs(E1){ } + Value * Codegen(); +}; + +class VariableExprAST : public ExprAST { + string name; + Type *type; +public: + VariableExprAST(const string &name, Type *type) : name(name), type(type){ } + Value * Codegen(); +}; + +class AssignExprAST : public VariableExprAST { + ExprAST *rhs; +public: + AssignExprAST(const string &name, ExprAST *rhs) + : VariableExprAST(name), rhs(rhs) { } + Value * Codegen(); +}; + +class ConstantExprAST : public ExprAST { + Integer *num; +public: + ConstantExprAST(Integer *num) : num(num) { } + Value * Codegen(); +}; + +class AccessExprAST : public VariableExprAST { + ExprAST *loc; +public: + AccessExprAST(const string &name, ExprAST *loc) + : VariableExprAST(name), loc(loc) { } + Value * Codegen(); +}; + +class MemberExpr : public ExprAST { + string name; + ExprAST *index; +public: + MemberExpr(const string name, ExprAST *index) + : name(name), index(index) { } + Value * Codegen(); +}; + +class PointerExpr : public ExprAST { + string name; + ExprAST *index; +public: + PointerExpr(const string name, ExprAST *index) + : name(name), index(index) { } }; -struct Unary :Expr{ - Expr *E1; - Unary(char opt, Expr *E1) :Expr(opt), E1(E1){ } - virtual void code(FILE *fp){ - Expr::code(fp); - E1->code(fp); - fprintf(fp, "%c $%d $%d\n", opt, E1->label, label); - } +class CallExprAST : public ExprAST { + string callee; + vector args; +public: + CallExprAST() { args.clear(); } + CallExprAST(const string &callee, vector &args) + : callee(callee), args(args) { ; } + Value * Codegen(); }; -// ID -struct Id :Expr{ - Type *t; - Word *s; - int offset; - Id(Type *t, Word *s, int offset) :Expr('@'), t(t), s(s), offset(offset){ } - virtual void code(FILE *fp){ - Expr::code(fp); - fprintf(fp, "load $%d *%d\n", label, offset); - } +class Decl : Stmt{ + list ids; +public: + Value * Codegen(); }; -struct Number :Expr{ - Integer *s; - Number(Integer *s) :Expr('@'), s(s){ } - virtual void code(FILE *fp){ - Expr::code(fp); - fprintf(fp, "load $%d #%d\n", label, s->value); - } +// +class IfElse : public Stmt{ + ExprAST *cond; + Stmt *body_t; + Stmt *body_f; +public: + IfElse(ExprAST *cond, Stmt *body_t, Stmt *body_f) + : cond(cond), body_t(body_t), body_f(body_f) { } + Value * Codegen(); }; -// -struct Stmt :Node{ - int line; - int begin, next; - static int label; - static int newlabel(){ - return label++; - } - virtual void code(FILE *fp){ - Node::code(fp); - printf("[%04d]", line); - } +class WhileDo : public Stmt{ + ExprAST *cond; + Stmt *body; +public: + WhileDo(ExprAST *cond, Stmt *body) :cond(cond), body(body) { } + Value * Codegen(); }; -// -struct Stmts :Stmt{ - list Ss; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("stmts\n"); - list::iterator iter; - for (iter = Ss.begin(); iter != Ss.end(); iter++){ - (*iter)->code(fp); - } - } +class DoWhile : public Stmt{ + ExprAST *cond; + Stmt *body; +public: + DoWhile(ExprAST *cond, Stmt *body) :cond(cond), body(body) { } + Value * Codegen(); }; -int Stmt::label = 0; +class For : public Stmt{ + ExprAST *init, *cond, *step; + Stmt *body; +public: + For(ExprAST *init, ExprAST *cond, ExprAST *step, Stmt *body) + : init(init), cond(cond), step(step), body(body) { } + Value * Codegen(); +}; -struct Decl :Stmt{ - list ids; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("decl\n"); - int width = 0; - list::iterator iter; - for (iter = ids.begin(); iter != ids.end(); iter++){ - width += (*iter)->t->width; - } - fprintf(fp, "data %d data\n", width); - } +typedef pair Case; + +class Switch : public Stmt { + ExprAST *expr; + vector cases; +public: + Switch(ExprAST *expr, vector> &cases) + : expr(expr), cases(cases) { } + Value * Codegen(); }; -struct Assign :Stmt{ - Id *E1; - Expr *E2; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("assign\n"); - E2->code(fp); - fprintf(fp, "store $%d *%d\n", E2->label, E1->offset); - } +class Break : public Stmt{ + Stmt *stmt; +public: + Break(Stmt *next) : stmt(next) { } + Value * Codegen(); }; -struct If :Stmt{ - Cond *C; - Stmt *S1; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("if\n"); - next = newlabel(); - C->True = newlabel(); - C->False = next; - S1->next = next; - C->code(fp); - fprintf(fp, "label L%d:\n", C->True); - S1->code(fp); - fprintf(fp, "label L%d:\n", next); - } +class Continue : public Stmt{ + Stmt *next; +public: + Continue(Stmt *next) : next(next) { } + Value * Codegen(); }; -struct Else :Stmt{ - Cond *C; - Stmt *S1; - Stmt *S2; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("if-else\n"); - next = newlabel(); - C->True = newlabel(); - C->False = newlabel(); - S1->next = next; - C->code(fp); - fprintf(fp, "label L%d:\n", C->True); - S1->code(fp); - fprintf(fp, "jmp L%d\n", next); - fprintf(fp, "label L%d:\n", C->False); - S2->code(fp); - fprintf(fp, "label L%d:\n", next); +class Throw : public Stmt { + Type* exception; +public: + Throw() { + exception = nullptr; } + Value * Codegen(); }; -struct While :Stmt{ - Cond *C; - Stmt *S1; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("while\n"); - begin = newlabel(); - next = newlabel(); - C->True = newlabel(); - C->False = next; - S1->next = begin; - fprintf(fp, "label L%d:\n", begin); - C->code(fp); - fprintf(fp, "label L%d:\n", C->True); - S1->code(fp); - fprintf(fp, "jmp L%d\n", begin); - fprintf(fp, "label L%d:\n", next); - } +class TryCatch : public Stmt{ + Stmt *pTry, *pCatch, *pFinally; +public: + TryCatch(Stmt* pTry, Stmt* pCatch, Stmt* pFinally) + : pTry(pTry), pCatch(pCatch), pFinally(pFinally) { } + Value * Codegen(); }; +// +typedef map SymbolTable; -struct Do :Stmt{ - Cond *C; - Stmt *S1; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("do-while\n"); - begin = newlabel(); - next = newlabel(); - C->True = begin; - C->False = next; - S1->next = begin; - fprintf(fp, "label L%d:\n", begin); - S1->code(fp); - C->code(fp); - fprintf(fp, "label L%d:\n", next); - } +class ParameterAST : public AST{ + Type *type; + string name; +public: + ParameterAST(Type *type, string name) : type(type), name(name) { } + Value * Codegen(); }; -struct For :Stmt{ - Stmt *S1; - Cond *C; - Stmt *S2; - Stmt *S3; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("for\n"); - begin = newlabel(); - next = newlabel(); - C->True = newlabel(); - C->False = next; - S3->next = begin; - S1->code(fp); - fprintf(fp, "label L%d:\n", begin); - C->code(fp); - fprintf(fp, "label L%d:\n", C->True); - S2->code(fp); - S3->code(fp); - fprintf(fp, "jmp L%d\n", begin); - fprintf(fp, "label L%d:\n", next); - } +class PrototypeAST : public AST{ + Type *type; + string name; + vector args; +public: + PrototypeAST(Type *type, const string &name, vector &args) + : type(type), name(name), args(args) { } + Value * Codegen(); +}; + +class FunctionAST : public AST{ + PrototypeAST *proto; + Stmt *body; +public: + FunctionAST(PrototypeAST *proto, Stmt *body) : proto(proto), body(body) { } + Value * Codegen(); }; -struct Case :Stmt{ - Expr *E; - map Ss; - virtual void code(FILE *fp){ - Stmt::code(fp); - printf("case\n"); - //fprintf(fp, "jmp L%d\n", begin); - //map::iterator iter; - //for (iter = Ss.begin(); iter != Ss.end(); iter++){ - // fprintf(fp, "label L%d:\n", iter->second->begin); - // iter->second->code(fp); - //} - //fprintf(fp, "label L%d:\n", begin); - //E->code(fp); - //for (iter = Ss.begin(); iter != Ss.end(); iter++){ - // fprintf(fp, "label L%d:\n", iter->second->begin); - // fprintf(fp, "= $%d $%d $%d", E->label, ); - // iter->second->code(fp); - //} +class Global { + map symbols; +public: + Value * putId(string name, Type* type) { + symbols[name] = type; + } + Type* getId(string name) { + return symbols[name]; } }; -#endif \ No newline at end of file +#endif // !__INTER_H_ diff --git a/Parser/lexer.h b/Parser/lexer.h index a8cbccd..dc79ed8 100644 --- a/Parser/lexer.h +++ b/Parser/lexer.h @@ -6,15 +6,28 @@ #include #include #include +#include #include #include #include +#include using namespace std; -//궨ֱ enum Tag{ - IF = 256, THEN, ELSE, DO, WHILE, FOR, CASE, ID, INT, END + IF = 256, THEN, ELSE, DO, WHILE, FOR, SWITCH, CASE, BREAK, CONTINUE, TRY, CATCH, FINALLY, THROW, + BASIC, INT, CHAR, + END, + ID, NUM, FUNCTION, + ASSIGN, // ASSIGN + AND, OR, NOT, // LOGIC + BIT_AND, BIT_OR, BIT_NOT, // BIT LOGIC + EQ, NEQ, // REL + LT, LEQ, GEQ, GT, // REL + SHL, SHR, // SHIFT + ADD, SUB, // TERM + MUL, DIV, // FACTOR + INC, DEC // UNARY }; // ʷԪ @@ -26,41 +39,41 @@ struct Token{ s << kind; return s.str(); } - virtual string code(){ - ostringstream s; - s << kind; - return s.str(); - } }; struct Word :Token{ - string word; - Word(int tag, string word) :Token(tag), word(word) { } + string str; + Word(int tag, string word) :Token(tag), str(word) { } virtual string place(){ ostringstream s; - s << word; + s << str; return s.str(); } virtual string code(){ - return ""; + return str; } + const char* getName() { return str.c_str(); } }; struct Type :Word{ int width; - static Type* Int; + static Type *Int, *Float, *Double, *Char, *Void; Type(int kind, string word, int width) :Word(kind, word), width(width){ } virtual string place(){ ostringstream s; - s << word << ":" << width; + s << str << ":" << width; return s.str(); } virtual string code(){ - return ""; + return str; } }; -Type* Type::Int = new Type(INT, "int", 2); +Type* Type::Int = new Type(BASIC, "qw", 4); +Type* Type::Float = new Type(BASIC, "dw", 2); +Type* Type::Double = new Type(BASIC, "qw", 4); +Type* Type::Char = new Type(BASIC, "db", 1); +Type* Type::Void = new Type(BASIC, "void", 0); struct Integer :Token{ int value; @@ -71,18 +84,70 @@ struct Integer :Token{ return s.str(); } virtual string code(){ - return ""; + return "INT"; + } +}; + +class ReadBuffer { +private: + FILE *file; + char *buf; + int front, rear; +public: + const int size = 3; + ReadBuffer() { + front = 0, rear = 0; + } + ~ReadBuffer() { + if (file) + fclose(file); + } + void open(char *filename) { + fopen_s(&file, filename, "rb"); + } + char operator[](int i) { + return buf[(front + i) % size]; + } + char peak() { + return buf[front % size]; + } + void pop() { + if (!isempty()) { + front = (front + 1) % size; + read(); + } + } + bool isempty() { + return (front == rear); + } + bool isfull() { + return ((rear + 1) % size) == front; + } + void read() { + while (!isfull()) { + size_t sz = fread(buf+rear, sizeof(char), 1, file); + if (sz == 0) { + // ֹ + buf[rear-1] = '\0'; + break; + } + rear = (rear + sz) % size; + } } }; // ʷ class Lexer{ - ifstream inf; map words; + ReadBuffer buffer; public: int line = 1; - Lexer(string fp){ - words["int"] = new Word(INT, "int"); + Lexer(){ + words["int"] = Type::Int; + words["char"] = Type::Char; + words["float"] = Type::Float; + words["double"] = Type::Double; + words["void"] = Type::Void; words["if"] = new Word(IF, "if"); words["then"] = new Word(THEN, "then"); words["else"] = new Word(ELSE, "else"); @@ -90,86 +155,137 @@ class Lexer{ words["while"] = new Word(WHILE, "while"); words["for"] = new Word(FOR, "for"); words["case"] = new Word(CASE, "case"); + words["break"] = new Word(BREAK, "break"); + words["continue"] = new Word(CONTINUE, "continue"); words["end"] = new Word(END, "end"); - inf.open(fp, ios::in); + words["try"] = new Word(TRY, "try"); + words["catch"] = new Word(CATCH, "catch"); + words["finally"] = new Word(FINALLY, "finally"); + words["throw"] = new Word(THROW, "throw"); + // Operator + words["&"] = new Word(BIT_AND, "&"); // BIT LOGIC + words["|"] = new Word(BIT_OR, "|"); + words["~"] = new Word(BIT_NOT, "~"); + words["&&"] = new Word(AND, "AND"); // LOGIC + words["||"] = new Word(OR, "OR"); + words["<<"] = new Word(SHL, "SHL"); // SHIFT + words[">>"] = new Word(SHR, "SHR"); + words["=="] = new Word(EQ, "EQ"); // COMP + words["!="] = new Word(NEQ, "NEQ"); + words["<"] = new Word(LT, "LT"); + words["<="] = new Word(LEQ, "LEQ"); + words[">="] = new Word(GEQ, "GEQ"); + words[">"] = new Word(GT, "GT"); } ~Lexer(){ - inf.close(); + printf("~Lexer\n"); words.clear(); - printf("~Lexer"); + } + void open(char *filename) { + buffer.open(filename); + } + Integer* match_integer(ReadBuffer & buffer) { + int value = 0; + char ch = buffer.peak(); + buffer.pop(); + if (ch == '0') { + ch = buffer.peak(); + if (ch == 'x' || ch == 'X') { + ch = buffer.peak(); + buffer.pop(); + if (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')) { + do { + if (isalpha(ch)) { + value = 16 * value + ch - 'A' + 10; + } + else { + value = 16 * value + ch - '0'; + } + ch = buffer.peak(); + buffer.pop(); + } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); + return new Integer(NUM, value); + } + else { + printf("ʮ!"); + return nullptr; + } + } + else if (ch >= '0'&&ch <= '7') { + //˽ + do { + value = 8 * value + ch - '0'; + ch = buffer.peak(); + buffer.pop(); + } while (ch >= '0'&&ch <= '7'); + buffer.read(); + return new Integer(NUM, value); + } + else { + //ʮ0 + buffer.read(); + return new Integer(NUM, 0); + } + } + else { + //0ʮ,5״̬ + do { + value = 10 * value + ch - '0'; + ch = buffer.peak(); + buffer.pop(); + } while (isdigit(ch)); + return new Integer(NUM, value); + } + } + Token* match_operator(ReadBuffer & buffer) { + char ch[3]; + memset(ch, 0, sizeof(char) * 3); + ch[0] = buffer.peak(); + buffer.pop(); + ch[1] = buffer.peak(); + switch (ch[1]) { + case '&': + case '|': + case '<': + case '>': + case '=': + buffer.pop(); + return words[ch]; + break; + default: + break; + } + ch[1] = '\0'; + if (words.find(ch) != words.end()) { + return words[ch]; + } + return new Token(ch[0]); } Token *scan() { - int i = 0; char ch; do{ - inf.read(&ch, sizeof(ch)); + ch = buffer.peak(); if (ch == '\n')line++; + buffer.pop(); } while (ch == ' ' || ch == '\n' || ch == '\t'); - if (ch == EOF){ - return new Token(END); - } if (isalpha(ch)){ string str; do{ str.push_back(ch); - inf.read(&ch, sizeof(ch)); - } while (isalnum(ch)); //1״̬ - inf.seekg(-1, ios::cur);//һַ + ch = buffer.peak(); + buffer.read(); + } while (isalnum(ch) || ch == '_'); if (words.find(str) == words.end()){ return new Word(ID, str); } return words[str]; } if (isdigit(ch)){ - int value = 0; - if (ch == '0'){ - inf.read(&ch, sizeof(ch)); - if (ch == 'x' || ch == 'X'){ - inf.read(&ch, sizeof(ch)); - if (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')){ - do{ - if (isalpha(ch)){ - value = 16 * value + ch - 'A' + 10; - } - else{ - value = 16 * value + ch - '0'; - } - inf.read(&ch, sizeof(ch)); - } while (isdigit(ch) || (ch >= 'a'&&ch <= 'f') || (ch >= 'A'&&ch <= 'F')); - inf.seekg(-1, ios::cur); - return new Integer(INT, value); - } - else{ - printf("ʮ!"); - } - } - else if (ch >= '0'&&ch <= '7'){ - //˽ - do{ - value = 8 * value + ch - '0'; - inf.read(&ch, sizeof(ch)); - } while (ch >= '0'&&ch <= '7'); - inf.seekg(-1, ios::cur); - return new Integer(INT, value); - } - else{ - //ʮ0 - inf.seekg(-1, ios::cur); - return new Integer(INT, 0); - } - } - else{ - //0ʮ,5״̬ - do{ - value = 10 * value + ch - '0'; - inf.read(&ch, sizeof(ch)); - } while (isdigit(ch)); - inf.seekg(-1, ios::cur);//һַ - return new Integer(INT, value); - } + return match_integer(buffer); } - return new Token(ch); + + return match_operator(buffer); } }; diff --git a/Parser/lrparser.h b/Parser/lrparser.h new file mode 100644 index 0000000..f5dbb86 --- /dev/null +++ b/Parser/lrparser.h @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +using namespace std; + +#define acc 0 +#define err 15 + +int Action[12][6] = { + { 5, err, err, 4, err, err }, // 0 + { err, 6, err, err, err, acc }, // + { err, -2, 7, err, -2, -2 }, // 2 E->T. + { err, -4, -4, err, -4, -4 }, // 3 T->F. + { 5, err, err, 4, err, err }, // 4 + { err, -6, -6, err, -6, -6 }, // 5 F->id. + { 5, err, err, 4, err, err }, // + { 5, err, err, 4, err, err }, // + { err, 6, err, err, 11, err }, // + { err, -1, 7, err, -1, -1 }, // 9 E->E+T. + { err, -3, -3, err, -3, -3 }, // 10 T->T*F + { err, -5, -5, err, -5, -5 } // 11 F->(E). +}; + +int GoTo[12][3] = { + { 1, 2, 3 },// 0 + { err, err, err }, // 1 + { err, err, err }, // 2 + { err, err, err }, // 3 + { 8, 2, 3 }, // 4 + { err, err, err }, // 5 + { err, 9, 3 }, // 6 + { err, err, 10 }, // 7 + { err, err, err }, // 8 + { err, err, err }, // 9 + { err, err, err }, // 10 + { err, err, err } // 11 +}; + +string str = "@+*()#"; +string nt = "ETF"; + +struct Symbol{ + char group; + string code; +}; + +int lookup(char c, int state){ + int index = str.find_first_of(c); + //printf("action:%d %c -> %d\n", state, c, Action[state][index]); + return Action[state][index]; +} + +int go(char c, int state){ + int index = nt.find_first_of(c); + //printf("goto:%d %c -> %d\n", state, c, GoTo[state][index]); + return GoTo[state][index]; +} + +void parse(FILE *fp){ + int state = 0, temp = 1; + char c; + stack ss; + stack sts; + ss.push(state); + fread(&c, sizeof(char), 1, fp); + while (temp){ + //cin >> a; + state = ss.top(); + temp = lookup(c, state); + if (temp > 0){ + // + ss.push(temp); + sts.push(c); + // IPָһ + fread(&c, sizeof(char), 1, fp); + }else if (temp < 0){ + // Լ + switch (-temp){ + case 1://E->E+T. + printf("E->E+T.\n"); + ss.pop(); + ss.pop(); + ss.pop(); + sts.pop(); + sts.pop(); + sts.pop(); + // reduce + sts.push('E'); + break; + case 2://E->T. + printf("E->T.\n"); + ss.pop(); + sts.pop(); + // reduce + sts.push('E'); + break; + case 3://T->T*F. + printf("T->T*F.\n"); + ss.pop(); + ss.pop(); + ss.pop(); + sts.pop(); + sts.pop(); + sts.pop(); + // reduce + sts.push('T'); + break; + case 4://T->F. + printf("T->F.\n"); + ss.pop(); + sts.pop(); + // reduce + sts.push('T'); + break; + case 5://F->(E). + printf("F->(E).\n"); + ss.pop(); + ss.pop(); + ss.pop(); + sts.pop(); + sts.pop(); + sts.pop(); + // reduce + sts.push('F'); + break; + case 6://F->id. + printf("F->id.\n"); + ss.pop(); + sts.pop(); + // reduce + sts.push('F'); + break; + default://ERR + printf("error action.\n"); + break; + } + // GoTo + int r = go(sts.top(), ss.top()); + if (r != err){ + ss.push(r); + }else { + temp = 0; + printf("error goto.\n"); + } + }else{ + printf("pass.\n"); + } + } +} \ No newline at end of file diff --git a/Parser/main.cpp b/Parser/main.cpp index 3532a52..ca0af8d 100644 --- a/Parser/main.cpp +++ b/Parser/main.cpp @@ -4,15 +4,21 @@ void main(){ char a; FILE file; FILE *fp = &file; - // м + Parser *p = new Parser(); + printf("ʼ﷨\n"); + AST *st = p->parse("Text.txt"); + printf("﷨\n"); printf("뿪ʼ\n"); - Parser p("Text.txt"); - Stmt *st = p.parse(); printf(" line stmt\n"); - fopen_s(&fp, "data.asm", "w"); - st->code(fp); - fprintf(fp, "halt\n"); + fopen_s(&fp, "data.s", "w"); + st->Codegen(); fclose(fp); printf("\n"); - cin >> a; + delete p; + //fopen_s(&fp, "G.txt", "r"); + //printf("ʼSLR(1)﷨\n"); + //parse(fp); + //printf("SLR(1)﷨\n"); + //fclose(fp); + //cin >> a; } \ No newline at end of file diff --git a/Parser/parser.cpp b/Parser/parser.cpp new file mode 100644 index 0000000..7c1e419 --- /dev/null +++ b/Parser/parser.cpp @@ -0,0 +1,356 @@ +#include "parser.h" + +void Parser::parseBlocks() +{ + while (s->kind == BASIC) { + parseDefinition(); + } +} + +void Parser::parseDefinition() +{ + Type *type = (Type*)s; + match(BASIC); + Word *word = (Word*)s; + match(ID); + if (word->kind != '(') { + global[word->str] = new VariableExprAST(word->str, type); + while (s->kind == ',') { + match(','); + global[word->str] = new VariableExprAST(word->str, type); + match(ID); + } + match(';'); + return; + } + global[word->str] = parseFunction(word->str, type); +} + +PrototypeAST * Parser::parsePrototype(string name, Type * type) +{ + vector args; + match('('); + int offset = 0; + if (s->kind == BASIC) { + Type *type = (Type*)s; + match(BASIC); + args.push_back(new ParameterAST(type, ((Word*)s)->str)); + match(ID); + while (s->kind == ',') { + match(','); + match(BASIC); + args.push_back(new ParameterAST(type, ((Word*)s)->str)); + match(ID); + } + } + match(')'); + return new PrototypeAST(type, name, args); +} + +FunctionAST * Parser::parseFunction(string name, Type * type) +{ + + PrototypeAST *proto = parsePrototype(name, type); + if (proto == nullptr) return 0; + + if (Stmt *body = parseBlock()) + return new FunctionAST(proto, body); + + return 0; +} + +FunctionAST * Parser::parseTopLevelExpr() +{ + if (Stmt *Body = parseStmt()) { + // Make and anonymous proto + PrototypeAST *Proto = new PrototypeAST(Type::Void, "main", std::vector()); + return new FunctionAST(Proto, Body); + } + return 0; +} + +Stmt * Parser::parseStmt() +{ + // ﷨ + switch (s->kind) { + case BASIC: + return parseDeclaration(); + case ID: + return parseExpression(); + case IF: + return parseIfElse(); + case WHILE: + return parseWhileDo(); + case DO: + return parseDoWhile(); + case FOR: + return parseFor(); + case CASE: + return parseSwitch(); + case BREAK: + return parseBreak(); + case CONTINUE: + return parseContinue(); + case TRY: + return parseTryCatch(); + case ';': + match(';'); + return parseStmt(); + case '{': + return parseBlock(); + default: + match(s->kind); + return parseStmt(); + } +} + +Stmt * Parser::parseBlock() +{ + vector block; + match('{'); + while (s->kind != '}') { + Stmt *st = parseStmt(); + if (st) { + block.push_back(st); + } + } + match('}'); + return new Block(block); +} + +Stmt * Parser::parseDeclaration() +{ + Type *type = (Type*)s; + match(BASIC); + top_scope[((Word*)s)->str] = type; + match(ID); + while (s->kind == ',') { + match(','); + top_scope[((Word*)s)->str] = type; + match(ID); + } + match(';'); +} + +Stmt * Parser::parseIfElse() +{ + match(IF); + match('('); + ExprAST *cond = parseExpression(); + match(')'); + Stmt *body_t = parseStmt(); + if (s->kind == ELSE) { + match(ELSE); + Stmt *body_f = parseStmt(); + return new IfElse(cond, body_t, body_f); + } + return new IfElse(cond, body_t, nullptr); +} + +Stmt * Parser::parseWhileDo() +{ + match(WHILE); + match('('); + ExprAST *cond = parseExpression(); + match(')'); + Stmt *body = parseStmt(); + return new WhileDo(cond, body); +} + +Stmt * Parser::parseDoWhile() +{ + match(DO); + Stmt *body = parseStmt(); + blocks.pop(); + match(WHILE); + match('('); + ExprAST *cond = parseExpression(); + match(')'); + match(';'); + return new DoWhile(cond, body); +} + +Stmt * Parser::parseFor() +{ + match(FOR); + match('('); + ExprAST *init = parseExpression(); + match(';'); + ExprAST *cond = parseExpression(); + match(';'); + ExprAST *step = parseExpression(); + match(')'); + Stmt *body = parseStmt(); + return new For(init, cond, step, body); +} + +Stmt * Parser::parseSwitch() +{ + vector cases; + match(SWITCH); + match('('); + ExprAST *expr = parseExpression(); + match(')'); + match(CASE); + while (s->kind == CASE) { + Integer *i = (Integer*)s; + match(INT); + match(':'); + cases.push_back(Case(i->value, parseStmt())); + } + match(END); + return new Switch(expr, cases); +} + +Stmt * Parser::parseBreak() +{ + Break *st = new Break(blocks.top()); + match(BREAK); + match(';'); + return st; +} + +Stmt * Parser::parseContinue() +{ + Continue *st = new Continue(blocks.top()); + st->line = lexer->line; + match(CONTINUE); + match(';'); + return st; +} + +Stmt * Parser::parseThrow() +{ + match(THROW); +} + +Stmt * Parser::parseTryCatch() +{ + match(TRY); + Stmt* pTry = parseStmt(); + match(CATCH); + Stmt* pCatch = parseStmt(); + match(FINALLY); + Stmt* pFinnaly = parseStmt(); + return new TryCatch(pTry, pCatch, pFinnaly); +} + +ExprAST * Parser::parseExpression() +{ + ExprAST *lhs = parsePrimary(); + if (!lhs) return 0; + + return parseBinaryExpr(0, lhs); +} + +ExprAST * Parser::parseBinaryExpr(int ExprPrec, ExprAST * lhs) +{ + // If this is a binop, find its precedence. + while (true) { + int TokPrec = GetTokPrecedence(); + + // If this is a binop that binds at least as tightly as the current binop, + // consume it, otherwise we are done. + if (TokPrec < ExprPrec) + return lhs; + + // Okay, we know this is a binop. + int opt = s->kind; + match(s->kind); + + // Parse the primary expression after the binary operator. + ExprAST *rhs = parsePrimary(); + if (!rhs) return 0; + + // If BinOp binds less tightly with RHS than the operator after RHS, let + // the pending operator take RHS as its LHS. + int NextPrec = GetTokPrecedence(); + if (TokPrec < NextPrec) { + rhs = parseBinaryExpr(TokPrec + 1, rhs); + if (!rhs) return 0; + } + + // Merge LHS/RHS. + lhs = new BinaryExprAST(opt, lhs, rhs); + } +} + +ExprAST * Parser::parsePrimary() +{ + // primary ::= id | num | unary + switch (s->kind) { + case ID: return parseIdentifierExpr(); + case NUM: return parseConstantExpr(); + case '(': return parseBracketsExpr(); + case INC: + case DEC: + case '!': + case '~': + case '-': return parseUnaryExpr(); + default: return 0; + } +} + +ExprAST * Parser::parseIdentifierExpr() +{ + // id ::= id | assign | call + Word *w = (Word*)s; + string id = w->str; + if (global.find(id) != global.end()) { + match(ID); + // assign + if (s->kind == '=') { + match('='); + ExprAST *expr = parseExpression(); + return new AssignExprAST(id, expr); + } + // call + if (s->kind == '(') { + match('('); + vector args; + if (s->kind != ')') { + while (true) { + ExprAST *arg = parseExpression(); + if (arg == nullptr) + return 0; + args.push_back(arg); + + if (s->kind == ')') + break; + + if (s->kind != ',') + return 0; + match(','); + } + match(')'); + return new CallExprAST(id, args); + } + } + return (VariableExprAST*)(global[id]); + } + return nullptr; +} + +ExprAST * Parser::parseConstantExpr() +{ + ExprAST *Result = new ConstantExprAST((Integer*)s); + match(NUM); + return Result; +} + +ExprAST * Parser::parseBracketsExpr() +{ + match('('); + ExprAST *e = parseExpression(); + if (!e) return 0; + if (s->kind != ')') return 0; + match(')'); + return e; +} + +ExprAST * Parser::parseUnaryExpr() +{ + int opt = s->kind; + match(opt); + return new UnaryExprAST(opt, parseExpression()); +} diff --git a/Parser/parser.h b/Parser/parser.h index 55ef721..e038364 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -9,8 +9,9 @@ class Parser{ private: Token *s; Lexer *lexer; - int width = 0; - map m; + stack blocks; + stack symbols; + SymbolTable top_scope, global; bool match(int kind){ if (s->kind == kind){ s = lexer->scan(); @@ -20,212 +21,93 @@ class Parser{ printf("%s not matched.\n", kind); return false; } - void putId(Id *id){ - m[id->s->word] = id; - } - Id* getId(){ - string str = ((Word*)s)->word; - if (m.find(str) == m.end()){ - return nullptr; - } - return m[str]; - } - Stmt* stmt() - { - Stmt *st = nullptr; - switch (s->kind){ - case INT:st = stmt_decl(); break; - case ID:st = stmt_assign(); break; - case IF:st = stmt_if(); break; - case WHILE:st = stmt_while(); break; - case DO:st = stmt_do(); break; - case FOR:st = stmt_for(); break; - case CASE:st = stmt_case(); break; - case ';':match(';'); break; - case '{':st = stmts(); break; - default:match(s->kind); break; - } - return st; - } - Stmt* stmts(){ - Stmts *sts = new Stmts; - sts->line = lexer->line; - match('{'); - while (s->kind != '}'){ - Stmt *st = stmt(); - if (st)sts->Ss.push_back(st); - } - match('}'); - return sts; - } - Stmt* stmt_decl(){ - Decl *d = new Decl; - d->line = lexer->line; - match(INT); - putId(new Id(Type::Int, (Word*)s, width)); - d->ids.push_back(getId()); - width += Type::Int->width; - match(ID); - while (s->kind == ','){ - match(','); - putId(new Id(Type::Int, (Word*)s, width)); - d->ids.push_back(getId()); - width += Type::Int->width; - match(ID); - } - match(';'); - return d; - } - Stmt* stmt_assign(){ - Assign *a = new Assign; - a->line = lexer->line; - a->E1 = getId(); - match(ID); - match('='); - a->E2 = expr_expr(); - return a; - } - Stmt* stmt_if(){ - If *i = new If; - i->line = lexer->line; - match(IF); - match('('); - i->C = expr_cond(); - match(')'); - i->S1 = stmt(); - if (s->kind == ELSE){ - Else *e = new Else; - match(ELSE); - e->line = i->line; - e->C = i->C; - e->S1 = i->S1; - e->S2 = stmt(); - return e; - } - return i; - } - Stmt* stmt_while(){ - While *w = new While; - w->line = lexer->line; - match(WHILE); - match('('); - w->C = expr_cond(); - match(')'); - w->S1 = stmt(); - return w; - } - Stmt* stmt_do(){ - Do *d = new Do; - d->line = lexer->line; - match(DO); - d->S1 = stmt(); - match(WHILE); - match('('); - d->C = expr_cond(); - match(')'); - match(';'); - return d; - } - Stmt* stmt_for(){ - For *f = new For; - f->line = lexer->line; - match(FOR); - match('('); - f->S1 = stmt_assign(); - match(';'); - f->C = expr_cond(); - match(';'); - f->S2 = stmt_assign(); - match(')'); - f->S3 = stmt(); - return f; - } - Stmt* stmt_case(){ - Case *c = new Case; - c->line = lexer->line; - match(CASE); - c->E = expr_expr(); - while (s->kind != END){ - Integer *i = (Integer*)s; - match(INT); - match(':'); - c->Ss[i->value] = stmt(); - } - match(END); - return c; - } - Cond* expr_cond() - { - Expr* e = expr_expr(); - if (s->kind == '<' || s->kind == '>' || s->kind == '=' || s->kind == '!'){ - char opt = s->kind; - match(s->kind); - Expr *r = expr_expr(); - return new Cond(opt, e, r); - } - return nullptr; - } - Expr* expr_expr() - { - Expr* e = expr_term(); - while (s->kind == '+' || s->kind == '-'){ - char opt = s->kind; - match(s->kind); - Expr *r = expr_term(); - e = new Arith(opt, e, r); - } - return e; - } - Expr* expr_term() - { - Expr* e = expr_unary(); - while (s->kind == '*' || s->kind == '/' || s->kind == '%') - { - char opt = s->kind; - match(s->kind); - Expr *r = expr_unary(); - e = new Arith(opt, e, r); - } - return e; - } - Expr* expr_unary(){ - Expr *u; - if (s->kind == '~'){ - match('~'); - u = new Unary('~', expr_unary()); - }else{ - u = expr_factor(); - } - return u; - } - Expr* expr_factor() - { - Expr* e = nullptr; - switch (s->kind){ - case '(': match('('); e = expr_expr(); match(')'); break; - case ID: e = getId(); match(ID); break; - case INT: e = new Number((Integer*)s); match(INT); break; - default: printf("F->('%c')\n", s->kind); match(s->kind); break; - } - return e; + void getNextToken() { + s = lexer->scan(); } + map precedence; + void init_precedence() { + precedence["[]"] = 13; + precedence["()"] = 13; + precedence["->"] = 12; + precedence["."] = 12; + + precedence["!"] = 12; + precedence["~"] = 12; + precedence["++"] = 12; + precedence["--"] = 12; + precedence["-"] = 12; + + precedence["sizeof"] = 11; + + precedence["*"] = 10; + precedence["/"] = 10; + precedence["%"] = 10; + + precedence["+"] = 9; + precedence["-"] = 9; + + precedence["<<"] = 8; + precedence[">>"] = 8; + + precedence["<"] = 7; + precedence["<="] = 7; + precedence[">="] = 7; + precedence[">"] = 7; + + precedence["=="] = 6; + precedence["!="] = 6; + precedence["&"] = 5; + precedence["~"] = 4; + precedence["|"] = 3; + precedence["&&"] = 2; + precedence["||"] = 1; + } + int GetTokPrecedence() { + return precedence[((Word*)s)->str]; + } + bool compare(string &opa, string &opb) { + return precedence[opa] > precedence[opb]; + } +protected: + // ⲿṹ + void parseBlocks(); + void parseDefinition(); + PrototypeAST* parsePrototype(string name, Type *type); + FunctionAST* parseFunction(string name, Type *type); + FunctionAST *parseTopLevelExpr(); + Stmt* parseStmt(); + Stmt* parseBlock(); + Stmt* parseDeclaration(); + Stmt* parseIfElse(); + Stmt* parseWhileDo(); + Stmt* parseDoWhile(); + Stmt* parseFor(); + Stmt* parseSwitch(); + Stmt* parseBreak(); + Stmt* parseContinue(); + Stmt* parseThrow(); + Stmt* parseTryCatch(); + ExprAST* parseExpression(); + ExprAST* parseBinaryExpr(int ExprPrec, ExprAST *lhs); + ExprAST* parsePrimary(); + ExprAST* parseIdentifierExpr(); + ExprAST* parseConstantExpr(); + ExprAST* parseBracketsExpr(); + ExprAST* parseUnaryExpr(); public: - Parser(string fp){ - lexer = new Lexer(fp); + Parser(){ + init_precedence(); + lexer = new Lexer(); } ~Parser(){ - printf("~Parser"); + printf("~Parser\n"); + precedence.clear(); delete lexer; } - Stmt* parse(){ - Stmts *sts = new Stmts; - sts->line = lexer->line; + AST* parse(char *filename){ + lexer->open(filename); s = lexer->scan();// ԤһʷԪԱ﷨ - while (s->kind != '#'){ - Stmt *st = stmt(); - if (st)sts->Ss.push_back(st); - } - return sts; + parseBlocks(); } }; diff --git a/README.md b/README.md new file mode 100644 index 0000000..757e900 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Parser-Asm-VM +一个编译程序,一个汇编程序和一个简单的16位虚拟机,一条龙实现从源代码到汇编程序再到虚拟机机器指令程序的转换过程,并可以在该虚拟机上运行该虚拟机机器指令程序