scc

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

commit 9a720370111cf87f4a1a9c2665c5e12f5c04855c
parent 67f3a8cc5d3362bd2f4670721de588a266fbb1cc
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 25 Mar 2014 09:52:32 +0100

Emit name of identifiers in expressions

Diffstat:
MMakefile | 2+-
Mdecl.c | 31++++++++++++++++---------------
Mexpr.c | 27+++++++++++++--------------
Mmain.c | 2++
Msymbol.c | 20++++++++++----------
Msymbol.h | 19++++++++++++++++---
Msyntax.h | 9---------
7 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \ - wrapper.o + wrapper.o code.o stmt.o all: kcc diff --git a/decl.c b/decl.c @@ -443,7 +443,7 @@ error: error(err, yytext); } -struct node * +void decl(void) { struct ctype *tp; @@ -459,9 +459,6 @@ decl(void) initializer(sym->type); } while (accept(',')); } - - expect(';'); - return NULL; } struct node * @@ -471,16 +468,16 @@ typename(void) return NULL; } -struct node * +void extdecl(void) { struct ctype *tp; int8_t sclass; struct symbol *sym; - extern struct symbol *curfun; char *err; + extern void compound(void); - forbid_eof = 1; + forbid_eof = 0; /* TODO: Fix when find EOF */ switch (yytoken) { case IDEN: case TYPE: case SCLASS: case TQUALIFIER: @@ -498,22 +495,26 @@ extdecl(void) extern void printtype(struct ctype *tp); sym = declarator(tp, NS_IDEN, ID_EXPECTED); printtype(sym->type); - /* assign storage class */ - if (isfun(sym)) { + if (!(sclass & STATIC)) + sym->s.isglobal = 1; + if (ISFUN(sym->type)) { if (yytoken == '{') { - curfun = sym; - context(function); + context(compound); freesyms(NS_LABEL); + return; } - } else if (accept('=')) { - initializer(sym->type); + } else { + sym->s.isstatic = 1; + if (sclass & EXTERN) + ; /* TODO: handle extern */ + else if (accept('=')) + initializer(sym->type); } } while (accept(',')); } - forbid_eof = 0; expect(';'); - return NULL; + return; bad_storage: err = "incorrect storage class for file-scope declaration"; diff --git a/expr.c b/expr.c @@ -1,26 +1,26 @@ -#include <stddef.h> #include <stdint.h> #include <stdio.h> #include "cc.h" +#include "code.h" #include "tokens.h" #include "symbol.h" #include "syntax.h" -struct node *expr(void); +struct ctype *expr(void); -static struct node * +static struct ctype * primary(void) { - register struct node *np; - register struct symbol *sym; + register struct ctype *tp; switch (yytoken) { case IDEN: if (yylval.sym == NULL) error("'%s' undeclared", yytext); - /* TODO: Do something */ + emitsym(yylval.sym); + tp = yylval.sym->type; next(); break; case CONSTANT: @@ -29,24 +29,23 @@ primary(void) break; case '(': next(); - np = expr(); + tp = expr(); expect(')'); break; default: - np = NULL; - break; + tp = NULL; } - return np; + return tp; } -struct node * +struct ctype * expr(void) { - register struct node *np; + register struct ctype *tp; do - np = primary(); + tp = primary(); while (yytoken == ','); - return np; + return tp; } diff --git a/main.c b/main.c @@ -12,6 +12,8 @@ struct user_opt options; int main(int argc, char *argv[]) { + extern void extdecl(void); + init_keywords(); open_file(NULL); for (next(); yytoken != EOFTOK; extdecl()); diff --git a/symbol.c b/symbol.c @@ -44,22 +44,19 @@ freesyms(uint8_t ns) } } -struct node * -context(struct node * (*fun)(void)) +void +context(void (*fun)(void)) { uint8_t ns; - struct node *np; ns = namespace; ++curctx; - np = fun(); + fun(); --curctx; namespace = ns; freesyms(NS_IDEN); freesyms(NS_TAG); - - return np; } struct symbol * @@ -87,17 +84,20 @@ install(char *s, uint8_t ns) struct symtab *tbl; static short id; - if (ns == NS_KEYWORD) + if (ns == NS_KEYWORD) { ns = NS_IDEN; - else if (s != NULL) - s = xstrdup(s); + } else { + ++id; + if (s != NULL) + s = xstrdup(s); + } sym = xcalloc(1, sizeof(*sym)); sym->name = s; sym->ctx = curctx; sym->token = IDEN; sym->ns = ns; - sym->id = id++; + sym->id = id; tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns]; sym->next = tbl->head; tbl->head = sym; diff --git a/symbol.h b/symbol.h @@ -2,11 +2,13 @@ #ifndef SYMBOL_H #define SYMBOL_H +#if ! __bool_true_and_false_are_defined +#include <stdbool.h> +#endif + #define CTX_OUTER 0 #define CTX_FUNC 1 -#define isfun(t) 0 - enum { NS_IDEN = 0, NS_LABEL, @@ -61,6 +63,12 @@ struct symbol { uint8_t ctx; uint8_t token; uint8_t ns; + struct { + bool isglobal : 1; + bool isstatic : 1; + bool isauto : 1; + bool isregister : 1; + } s; union value u; struct symbol *next; struct symbol *hash; @@ -77,7 +85,7 @@ extern struct symbol *lookup(char *s, unsigned char ns), *install(char *s, unsigned char ns); -extern struct node *context(struct node * (*fun)(void)); +extern void context(void (*fun)(void)); extern struct ctype *voidtype, *uchartype, *chartype, @@ -89,4 +97,9 @@ extern struct ctype *voidtype, *doubletype, *cdoubletype, *idoubletype, *ldoubletype, *cldoubletype,*ildoubletype; +#define ISQUAL(t) ((t)->op & TQUALIFIER) +#define UNQUAL(t) (ISQUAL(t) ? (t)->type : (t)) +#define ISFUN(t) (UNQUAL(t)->op == FTN) + + #endif diff --git a/syntax.h b/syntax.h @@ -20,14 +20,5 @@ enum opcode { ORETURN, OCASE, ODEFAULT, OFTN, ODEF, O2EXP }; -struct node; -struct symbol; -struct ctype; - -extern struct node *expr(void), *extdecl(void), *decl(void), - *typename(void), *function(void); - -extern struct node *node(unsigned char op, struct node *l, struct node *r); -extern bool walk(register struct node *np, bool (*fun)(struct node *)); #endif