scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit d68b3d817cf4b252524880eb9408d2f4b3b596ef
parent a1a0f635df0811a394b3662dea887d4ba0eb089b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 21 Sep 2017 12:34:12 +0100

[as] Add temporaries symbols

These symbols are used for constants in the code and
for folded values. They are freed at the end of every
pass.

Diffstat:
as/as.h | 2++
as/expr.c | 19+++++++++++++++----
as/main.c | 14+++++++++++---
as/symbol.c | 24++++++++++++++++++++++++
4 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/as/as.h b/as/as.h @@ -102,6 +102,8 @@ extern void isections(void); extern void writeout(char *name); extern void emit(Section *sec, char *bytes, int nbytes); extern Section *section(char *name); +extern Symbol *tmpsym(TUINT val); +extern void killtmp(void); /* main.c */ extern Symbol *lookup(char *name); diff --git a/as/expr.c b/as/expr.c @@ -14,7 +14,6 @@ enum tokens { IDEN = 1, NUMBER, REG, - CHAR, STRING, SHL, SHR, @@ -22,10 +21,16 @@ enum tokens { LE, }; +union yylval { + TUINT val; + Symbol *sym; +}; + static Alloc *arena; static int yytoken; static char yytext[INTIDENTSIZ+1], *textp, *endp; static size_t yylen; +static union yylval yylval; #define accept(t) (yytoken == (t) ? next() : 0) @@ -121,7 +126,7 @@ binary(int op, Node *l, Node *r) } np = node(NUMBER, l, r); - /* np->sym = tmpsym(val); */ + np->sym = tmpsym(val); return np; division_by_zero: @@ -172,6 +177,9 @@ iden(void) for (endp = textp; isalnum(c = *endp) || c == '_' || c == '.'; ++endp) /* nothing */; + tok2str(); + yylval.sym = lookup(yytext); + return IDEN; } @@ -183,6 +191,9 @@ number(void) for (endp = textp; isxdigit(*endp); ++endp) /* nothing */; + tok2str(); + yylval.sym = tmpsym(atoi(yytext)); /* TODO: parse the string */ + return NUMBER; } @@ -194,7 +205,7 @@ character(void) for (endp = textp+1; *endp != '\''; ++endp) /* nothing */; - return CHAR; + return NUMBER; } static int @@ -261,9 +272,9 @@ primary(void) switch (yytoken) { case NUMBER: case IDEN: - case CHAR: case STRING: np = node(yytoken, NULL, NULL); + np->sym = yylval.sym; next(); break; case '(': diff --git a/as/main.c b/as/main.c @@ -72,6 +72,13 @@ dopass(char *fname) if (fclose(fp)) die("as: error reading from input file '%s'", fname); + if (pass == 2) + writeout("a.out"); + /* + * kill tmp symbols because they are not needed anymore + */ + killtmp(); + return nerrors == 0; } @@ -89,9 +96,10 @@ main(int argc, char *argv[]) usage(); filename = argv[1]; - for (pass = 1; pass <= 2 && dopass(filename); pass++) - /* nothing */; - writeout("a.out"); + for (pass = 1; pass <= 2; pass++) { + if (!dopass(filename)) + return 1; + } return 0; } diff --git a/as/symbol.c b/as/symbol.c @@ -8,6 +8,7 @@ static char sccsid[] = "@(#) ./as/emit.c"; #include "as.h" #define HASHSIZ 64 +#define NALLOC 10 static Section abss = { .name = "abs", @@ -37,6 +38,8 @@ Section *cursec = &text, *headp = &text; int pass; static Symbol *hashtbl[HASHSIZ]; +static Alloc *tmpalloc; + Symbol *linesym; Symbol * @@ -201,6 +204,27 @@ emit(Section *sec, char *bytes, int n) incpc(n); } +Symbol * +tmpsym(TUINT val) +{ + Symbol *sym; + + if (!tmpalloc) + tmpalloc = alloc(sizeof(*sym), NALLOC); + sym = new(tmpalloc); + sym->value = val; + sym->flags = TABS; + + return sym; +} + +void +killtmp(void) +{ + dealloc(tmpalloc); + tmpalloc = NULL; +} + void writeout(char *name) {