diff options
Diffstat (limited to 'c.l')
-rw-r--r-- | c.l | 69 |
1 files changed, 60 insertions, 9 deletions
@@ -2,13 +2,14 @@ #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <stdarg.h> #include <string.h> +#include <ctype.h> #include "type.h" +#include "ir.h" #include "y.tab.h" -#undef DEBUG - int yylex(void); int lineno=1; @@ -19,12 +20,17 @@ static enum state { SPTR } state = STERM; +static bool asm_mode = false; + __attribute__((format (printf, 1, 2))) void pdebug(const char *format, ...); -#define RETS(val_) {pdebug(#val_ ": %s\n", yytext); yylval.id = strdup(yytext); return val_;} -#define RET_TYPE(val_, ty_) {pdebug(#val_ ": %s (" #ty_ ")\n", yytext); yylval.type = ty_; return val_;} -#define RET(val_) {pdebug(#val_ "\n"); return val_;} +#define RETS(val_) RETS_S(val_, yytext) +#define RETS_S(val_, str_) do {pdebug(#val_ ": %s\n", (str_)); yylval.id = strdup((str_)); return (val_);} while (0) +#define RET_TYPE(val_, ty_) do {pdebug(#val_ ": %s (" #ty_ ")\n", yytext); yylval.type = ty_; return (val_);} while (0) +#define RET_INSTYPE(val_, it_) do {pdebug(#val_ ": " #it_ "\n"); yylval.instype = (it_); return (val_);} while (0) +#define RET_REF(val_, r_) do {pdebug(#val_ ": " #r_ "\n"); yylval.ref = (r_); return (val_);} while (0) +#define RET(val_) do {pdebug(#val_ "\n"); return val_;} while (0) %} @@ -37,6 +43,9 @@ DIGITS {DIGIT}{DIGIT}* NUM -?{DIGITS} +/* An inclusive state; all other rules will still fire */ +%s ASM_MODE +/* An exclusive state; no other rules will fire */ %x C_COMMENT @@ -51,17 +60,57 @@ else { RET(ELSE); } while { RET(WHILE); } for { RET(FOR); } return { state = STERM; RET(RETURN); } +asm { asm_mode = true; BEGIN(ASM_MODE); RET(ASM); } + +{ID} { + state = SOP; + if (asm_mode) { + int len = strlen(yytext); + char name[len + 1]; + for (int i = 0; i < len; i++) name[i] = tolower(yytext[i]); + name[len] = '\0'; + if (strcmp(name, "add") == 0) RET_INSTYPE(ASMINS2, INS_ADD); + else if (strcmp(name, "sub") == 0) RET_INSTYPE(ASMINS2, INS_SUB); + else if (strcmp(name, "mul") == 0) RET_INSTYPE(ASMINS2, INS_MUL); + else if (strcmp(name, "div") == 0) RET_INSTYPE(ASMINS2, INS_DIV); + else if (strcmp(name, "mod") == 0) RET_INSTYPE(ASMINS2, INS_MOD); + else if (strcmp(name, "test") == 0) RET_INSTYPE(ASMINS2, INS_TEST); + else if (strcmp(name, "cmp") == 0) RET_INSTYPE(ASMINS2, INS_CMP); + else if (strcmp(name, "mov") == 0) RET_INSTYPE(ASMINS2, INS_MOV); + else if (strcmp(name, "neg") == 0) RET_INSTYPE(ASMINS1, INS_NEG); + else if (strcmp(name, "not") == 0) RET_INSTYPE(ASMINS1, INS_NOT); + else if (strcmp(name, "push") == 0) RET_INSTYPE(ASMINS1, INS_PUSH); + else if (strcmp(name, "pop") == 0) RET_INSTYPE(ASMINS1, INS_POP); + else if (strcmp(name, "hwi") == 0) RET_INSTYPE(ASMINS1, INS_HWI); + else if (strcmp(name, "ret") == 0) RET_INSTYPE(ASMINS0, INS_RET); + else if (strcmp(name, "brk") == 0) RET_INSTYPE(ASMINS0, INS_BRK); + else if (strcmp(name, "jmp") == 0) RET_INSTYPE(ASMINS_NAME, INS_JMP); + else if (strcmp(name, "call") == 0) RET_INSTYPE(ASMINS_NAME, INS_CALL); + else if (strcmp(name, "a") == 0) RET_REF(ASMREG, ref_reg(REG_A)); + else if (strcmp(name, "b") == 0) RET_REF(ASMREG, ref_reg(REG_B)); + else if (strcmp(name, "c") == 0) RET_REF(ASMREG, ref_reg(REG_C)); + else if (strcmp(name, "d") == 0) RET_REF(ASMREG, ref_reg(REG_D)); + else if (strcmp(name, "x") == 0) RET_REF(ASMREG, ref_reg(REG_X)); + else if (strcmp(name, "y") == 0) RET_REF(ASMREG, ref_reg(REG_Y)); + else if (strcmp(name, "sp") == 0) RET_REF(ASMREG, ref_reg(REG_SP)); + else if (strcmp(name, "bp") == 0) RET_REF(ASMREG, ref_reg(REG_BP)); + else RETS(ID); + } else { + RETS(ID); + } + } -{ID} { state = SOP; RETS(ID); } +<ASM_MODE>[+-] { pdebug("%c in ASM_MODE\n", yytext[0]); return yytext[0]; } +<ASM_MODE>@{ID} { pdebug("'%s'\n", yytext); RETS_S(ASMVARNAME, yytext + 1); } "//"[^\n]* {} "/*" { pdebug("C_COMMENT... "); fflush(stdout); BEGIN(C_COMMENT); } <C_COMMENT>"*/" { pdebug("done\n"); BEGIN(INITIAL); } <C_COMMENT>. {} -<C_COMMENT>\n { lineno++; } +<C_COMMENT>\n { lineno++; if (asm_mode) RET(NEWLINE); } -\n { lineno++; } +\n { lineno++; if (asm_mode) RET(NEWLINE); } [ \t]+ {} "+" { state = STERM; RETS(ADDOP); } @@ -74,7 +123,7 @@ return { state = STERM; RET(RETURN); } "-" { switch (state) { case SOP: state = STERM; RETS(ADDOP); - case STERM: state = STERM; RETS(NEGATE); + case STERM: state = STERM; RET(NEGATE); default: fprintf(stderr, "Unexpected '-'\n"); exit(1); } } @@ -98,6 +147,8 @@ return { state = STERM; RET(RETURN); } ")" { state = SOP; pdebug("')'\n"); return ')'; } +"}" { state = STERM; pdebug("'}'\n"); asm_mode = false; BEGIN(INITIAL); return '}'; } + . { pdebug(".: %c\n", yytext[0]); return yytext[0]; } |