%{ #include #include #include #include #include "types.h" #include "qbe.h" extern int yylex(); extern int yylineno; extern char *yytext; void yyerror(const char* s); exp *exprs[1024]; int exprcount = 0; function *funcs[1024]; int funccount = 0; exp *newexpr(char name, char op, int val, bool isvar) { exp *e = malloc(sizeof(exp)); e->name = name; e->op = op; e->var = isvar; e->v = val; } void appendexpr(exp *e) { exprs[exprcount] = e; exprcount++; } void appendfunction(function *f) { funcs[funccount] = f; funccount++; } function *copyexprsandclear(char name) { function *f = malloc(sizeof(function)); f->name = name; memcpy(f->exprs, exprs, sizeof(exp) * 1024); f->exprcount = exprcount; exprcount = 0; } %} %union { char funcname; char varname; int intlit; exp *expr; } %token INTLIT %token FUNCTIONNAME %token VARNAME %token FUNCTIONDEC %token PRINT %token INPUT %token RET %token JMP %token JNZ %type EXPR %% PROG : PROG F | F ; F : FUNCTIONDEC FUNCTIONNAME '{' EXPRS '}' {appendfunction(copyexprsandclear($2));} ; EXPRS : EXPRS EXPR {appendexpr($2);} | EXPR {appendexpr($1);} ; EXPR : VARNAME {$$ = newexpr($1, 0, 0, false);} | VARNAME '=' INTLIT {$$ = newexpr($1, '=', $3, false);} | VARNAME '+' INTLIT {$$ = newexpr($1, '+', $3, false);} | VARNAME '-' INTLIT {$$ = newexpr($1, '-', $3, false);} | VARNAME '*' INTLIT {$$ = newexpr($1, '*', $3, false);} | VARNAME '/' INTLIT {$$ = newexpr($1, '/', $3, false);} | VARNAME '=' VARNAME {$$ = newexpr($1, '=', $3, true);} | VARNAME '+' VARNAME {$$ = newexpr($1, '+', $3, true);} | VARNAME '-' VARNAME {$$ = newexpr($1, '-', $3, true);} | VARNAME '*' VARNAME {$$ = newexpr($1, '*', $3, true);} | VARNAME '/' VARNAME {$$ = newexpr($1, '/', $3, true);} | PRINT VARNAME {$$ = newexpr($2, 'p', 0, false);} | VARNAME '=' INPUT {$$ = newexpr($1, 'i', 0, false);} | VARNAME '=' FUNCTIONNAME {$$ = newexpr($1, 'c', $3, false);} | RET VARNAME {$$ = newexpr($2, 'r', 0, false);} | VARNAME ':' {$$ = newexpr($1, 'l', 0, false);} | JMP VARNAME ':' {$$ = newexpr($2, 'j', 0, false);} | JNZ VARNAME VARNAME ':' {$$ = newexpr($3, 'z', $2, false);} ; %% void yyerror(const char *msg) { fprintf(stderr, "%d:%s\n%s\n", yylineno, msg, yytext); } int main() { yyparse(); compile(stdout, funcs, funccount); return 0; }