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:
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)
{