scc

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

commit a15ca68747ff228cf9fd71b541e7941cbe377536
parent 57380d876cf8ee79ba67e06dca722cc54189ac27
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 19 Sep 2014 12:03:14 +0200

Add a pointer to the list of trees in function symbols

This modifications allow to split the implementation of
functions and all the others procedures that are going to
be applied to them (thanks to apply()).

Diffstat:
Mcc2/cc2.h | 15++++++++++-----
Mcc2/cgen.c | 10+++++-----
Mcc2/main.c | 9++++++---
Mcc2/parser.c | 44+++++++++++++++++++++-----------------------
4 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -1,4 +1,7 @@ +typedef struct symbol Symbol; +typedef struct node Node; + typedef struct { short size; uint8_t align; @@ -6,7 +9,7 @@ typedef struct { bool c_int : 1; } Type; -typedef struct symbol { +struct symbol { char *name; bool public : 1; bool extrn : 1; @@ -23,11 +26,12 @@ typedef struct symbol { struct { short locals; short params; + Node **body; } f; } u; -} Symbol; +}; -typedef struct node { +struct node { char op; char subop; Type *type; @@ -39,7 +43,7 @@ typedef struct node { char reg; } u; struct node *left, *right; -} Node; +}; enum nerrors { EINTNUM, /* too much internal identifiers */ @@ -96,6 +100,7 @@ enum nerrors { extern void error(unsigned nerror, ...); extern void genaddable(Node *np); -extern void generate(Symbol *sym, Node *list[]); +extern void generate(Symbol *fun); extern void genstack(Symbol *fun); extern void apply(Node *list[], void (*fun)(Node *)); +extern Symbol *parse(void); diff --git a/cc2/cgen.c b/cc2/cgen.c @@ -237,21 +237,21 @@ cgen(Node *np) } void -generate(Symbol *sym, Node *list[]) +generate(Symbol *fun) { extern char odebug; - char frame = sym->u.f.locals != 0 || odebug; + char frame = fun->u.f.locals != 0 || odebug; - emit(ADDR, sym->name); + emit(ADDR, fun->name); if (frame) { emit(PUSH, IX); emit(LD, IX, SP); - emit(LDI, HL, -sym->u.f.locals); + emit(LDI, HL, -fun->u.f.locals); emit(ADD, HL, SP); emit(LD, SP, HL); } - apply(list, cgen); + apply(fun->u.f.body, cgen); if (frame) { emit(LD, SP, IX); diff --git a/cc2/main.c b/cc2/main.c @@ -9,8 +9,6 @@ #include "cc2.h" #include "error.h" -extern void parse(void); - char odebug; void @@ -30,5 +28,10 @@ error(unsigned nerror, ...) int main(void) { - parse(); + Symbol *fun; + + while (!feof(stdin) && (fun = parse())) { + apply(fun->u.f.body, genaddable); + generate(fun); + } } diff --git a/cc2/parser.c b/cc2/parser.c @@ -20,9 +20,9 @@ enum { }; static Symbol *curfun; -static Node *stack[NR_STACKSIZ], **stackp = stack; -static Node *listexp[NR_EXPRESSIONS], **listp = listexp; -static Node nodepool[NR_NODEPOOL], *newp = nodepool; +static Node *stack[NR_STACKSIZ], **stackp; +static Node *listexp[NR_EXPRESSIONS], **listp; +static Node nodepool[NR_NODEPOOL], *newp; Type l_int8 = { @@ -399,17 +399,6 @@ deflabel(char *token) sym->u.l.addr = listp - listexp; } -static void -endfunction(char *token) -{ - if (!curfun) - error(ESYNTAX); - listp = NULL; - apply(listexp, genaddable); - generate(curfun, listexp); - curfun = NULL; -} - static Symbol * declaration(uint8_t t, char class, char *token) { @@ -453,7 +442,7 @@ globdcl(char *token) sym->type = FUN; curfun = sym; - listp = listexp; + sym->u.f.body = listp = listexp; newp = nodepool; } @@ -473,7 +462,7 @@ localdcl(char *token) curfun->u.f.locals += sym->u.v.type->size; } -void +Symbol * parse(void) { void (*fun)(char *tok); @@ -481,6 +470,11 @@ parse(void) int c; char line[MAXLINE]; + curfun = NULL; + stackp = stack; + listp = listexp; + newp = nodepool; + for (;;) { switch (c = getchar()) { case 'L': @@ -502,10 +496,15 @@ parse(void) fun = globdcl; break; case '}': - fun = endfunction; - break; + if (!curfun) + error(ESYNTAX); + return curfun; case EOF: - goto found_eof; + if (ferror(stdin)) + error(EFERROR, strerror(errno)); + if (curfun) + goto syntax_error; + return NULL; case '\n': continue; default: @@ -523,11 +522,10 @@ parse(void) } found_eof: - if (ferror(stdin)) - error(EFERROR, strerror(errno)); - if (!curfun) - return; + + if (!curfun) + return curfun; syntax_error: error(ESYNTAX); }