scc

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

commit d7cd0ce876107c05e34c7c00cef311e2023a9352
parent 0771ecab43a53d473d65baf0d08b6177077e11b4
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 24 Jan 2016 18:45:18 +0100

[cc2] Generate code for initializers

The only architecture that generates actual code is z80,
in the other cases they are only stubs.

Diffstat:
Mcc2/arch/amd64-sysv/code.c | 7++++++-
Mcc2/arch/i386-sysv/code.c | 7++++++-
Mcc2/arch/z80/code.c | 83++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mcc2/cc2.h | 22++++++++++++----------
Mcc2/node.c | 1-
Mcc2/parser.c | 67+++++++++++++++++++++++++++++++++++++++----------------------------
Mcc2/symbol.c | 15++++++++++++++-
7 files changed, 134 insertions(+), 68 deletions(-)

diff --git a/cc2/arch/amd64-sysv/code.c b/cc2/arch/amd64-sysv/code.c @@ -3,7 +3,12 @@ #include "../../cc2.h" void -emit(Node *np) +data(Node *np) +{ +} + +void +label(Symbol *sym) { } diff --git a/cc2/arch/i386-sysv/code.c b/cc2/arch/i386-sysv/code.c @@ -3,7 +3,12 @@ #include "../../cc2.h" void -emit(Node *np) +data(Node *np) +{ +} + +void +label(Symbol *sym) { } diff --git a/cc2/arch/z80/code.c b/cc2/arch/z80/code.c @@ -34,28 +34,46 @@ code(int op, Node *to, Node *from) { } +void +label(Symbol *sym) +{ + int seg, flags = sym->type.flags; + + if (flags & FUNF) + seg = CODESEG; + else if (flags & INITF) + seg = DATASEG; + else + seg = BSSSEG; + segment(seg); + + printf("%s:\n", symname(sym)); +} + static void -emitsym(Symbol *sym) +emitstring(Node *np) { /*In z80 we can ignore the aligment */ - if (sym->type.flags & STRF) { - fputs(sym->u.s, stdout); - free(sym->u.s); - sym->u.s = NULL; - } else { - switch (sym->type.size) { - case 1: - printf("%02X", (int) (sym->u.i & 0xFF)); - break; - case 2: - printf("%04X", (int) (sym->u.i & 0xFFFF)); - break; - case 4: - printf("%08X", (long) (sym->u.i & 0xFFFFFFFF)); - break; - default: - abort(); - } + printf("\"%s\"", np->u.s); + free(np->u.s); + np->u.s = NULL; +} + +static void +emitconst(Node *np) +{ + switch (np->type.size) { + case 1: + printf("%02X", (int) np->u.i & 0xFF); + break; + case 2: + printf("%04X", (int) np->u.i & 0xFFFF); + break; + case 4: + printf("%08X", (long) np->u.i & 0xFFFFFFFF); + break; + default: + abort(); } } @@ -64,24 +82,36 @@ emittree(Node *np) { if (!np) return; - if (np->op == OSYM) { - emitsym(np->sym); - } else { - emit(np->left); + + switch (np->op) { + case OSTRING: + emitstring(np); + break; + case OCONST: + emitconst(np); + break; + case OADDR: + emittree(np->left); + break; + case MEM: + fputs(symname(np->u.sym), stdout); + break; + default: + emittree(np->left); printf(" %c ", np->op); - emit(np->right); + emittree(np->right); + break; } } void -emit(Node *np) +data(Node *np) { char *s; /* * In z80 we can ignore the alignment */ - segment(DATASEG); switch (np->type.size) { case 1: s = "\tDB\t"; @@ -98,6 +128,7 @@ emit(Node *np) } fputs(s, stdout); emittree(np); + putchar('\n'); } void diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -2,12 +2,11 @@ enum tflags { SIGNF = 1, INTF = 2, - DEFTYP = 4, - STRUCTF = 8, + STRF = 8, UNIONF = 16, - FUNCF = 32, + FUNF = 32, ARYF = 64, - STRF = 128 + INITF = 128 }; enum op { @@ -115,13 +114,10 @@ struct type { struct symbol { unsigned short id; + unsigned short numid; char *name; Type type; char kind; - union { - TUINT i; - char *s; - } u; Symbol *next; Symbol *h_next; }; @@ -129,7 +125,11 @@ struct symbol { struct node { char op; Type type; - Symbol *sym; + union { + TUINT i; + char *s; + Symbol *sym; + } u; Node *left, *right; Node *stmt; }; @@ -151,7 +151,8 @@ extern void generate(void); extern void peephole(void); /* code.c */ -extern void emit(Node *np); +extern void label(Symbol *sym); +extern void data(Node *np); extern void writeout(void); /* node.c */ @@ -165,3 +166,4 @@ extern Symbol *getsym(int id); extern void popctx(void); extern void pushctx(void); extern void freesym(Symbol *sym); +extern char *symname(Symbol *sym); diff --git a/cc2/node.c b/cc2/node.c @@ -39,7 +39,6 @@ newnode(void) np->right = NULL; np->left = NULL; - np->sym = NULL; np->stmt = NULL; return np; } diff --git a/cc2/parser.c b/cc2/parser.c @@ -22,19 +22,7 @@ extern Type int8type, int16type, int32type, int64type, elipsistype; Type funtype = { - .flags = DEFTYP | FUNCF -}; - -Type arrtype = { - .flags = DEFTYP | ARYF -}; - -Type uniontype = { - .flags = DEFTYP | UNIONF -}; - -Type strtype = { - .flags = DEFTYP | STRUCTF + .flags = FUNF }; union tokenop { @@ -44,10 +32,11 @@ union tokenop { typedef void parsefun(char *, union tokenop); static parsefun type, symbol, getname, unary, binary, ternary, call, - parameter, constant; + parameter, constant, aggregate; typedef void evalfun(void); -static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, endinit; +static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, + endinit, array; static struct decoc { void (*eval)(void); @@ -80,9 +69,9 @@ static struct decoc { [ELLIPSIS] = {NULL, type, .u.arg = &elipsistype}, [FUNCTION] = {NULL, type, .u.arg = &funtype}, - [VECTOR] = {NULL, NULL, .u.arg = &arrtype}, - [UNION] = {NULL, NULL, .u.arg = &uniontype}, - [STRUCT] = {NULL, NULL, .u.arg = &strtype}, + [VECTOR] = {array, aggregate}, + [UNION] = {NULL, NULL}, + [STRUCT] = {NULL, NULL}, [ONAME] = {NULL, getname}, ['{'] = {beginfun}, @@ -161,6 +150,7 @@ newid(void) if (++id == 0) error(EIDOVER); + return id; } static void @@ -170,6 +160,15 @@ type(char *token, union tokenop u) } static void +aggregate(char *token, union tokenop u) +{ + Symbol *sym; + + sym = getsym(atoi(token+1)); + push(&sym->type); +} + +static void getname(char *t, union tokenop u) { push((*++t) ? xstrdup(t) : NULL); @@ -182,7 +181,7 @@ symbol(char *token, union tokenop u) sclass = *token++; np = newnode(); - np->sym = getsym(atoi(token)); + np->u.sym = getsym(atoi(token)); np->op = u.op; push(np); } @@ -204,17 +203,14 @@ constant(char *token, union tokenop u) { static char letters[] = "0123456789ABCDEF"; Node *np = newnode(); - Symbol *sym = getsym(0); TUINT v; unsigned c; - np->sym = sym; ++token; if (*token == OSTRING) { - np->op = OSYM; - sym->id = newid(); - sym->type.flags = STRF; - sym->u.s = xstrdup(++token); + np->op = OSTRING; + np->type.flags = STRF; + np->u.s = xstrdup(++token); } else { np->op = OCONST; np->type = *gettype(token++); @@ -222,7 +218,7 @@ constant(char *token, union tokenop u) v <<= 4; c = strchr(letters, c) - letters; } - sym->u.i = v; + np->u.i = v; } push(np); } @@ -295,6 +291,8 @@ static void begininit(void) { ininit = 1; + lastsym->type.flags |= INITF; + label(lastsym); } static void @@ -333,6 +331,17 @@ endpars(void) } static void +array(void) +{ + Type *tp, *base; + Node *np; + + np = pop(); + base = pop(); + tp = pop(); +} + +static void vardecl(void) { Type *tp; @@ -344,11 +353,13 @@ vardecl(void) tp = pop(); np = pop(); - sym = np->sym; + sym = np->u.sym; sym->name = name; sym->type = *tp; sym->kind = sclass; lastsym = sym; + if (!name) + sym->numid = newid(); if (funpars >= 0) { if (funpars == NR_FUNPARAM) @@ -365,7 +376,7 @@ stmt(void) Node *np = pop(); if (ininit) { - emit(np); + data(np); deltree(np); return; } diff --git a/cc2/symbol.c b/cc2/symbol.c @@ -1,4 +1,5 @@ +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -47,7 +48,7 @@ getsym(int id) htab = &symtab[id & NR_SYMHASH-1]; for (sym = *htab; sym; sym = sym->h_next) { - if (sym->id > 0 && sym->id != id) + if (sym->id > 0 && sym->id == id) break; } if (!sym) { @@ -64,3 +65,15 @@ getsym(int id) } return sym; } + +char * +symname(Symbol *sym) +{ + static char name[20]; + + if (sym->name) + return sym->name; + sprintf(name, ".%d", sym->numid); + + return name; +}