scc

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

commit b17f870636b9dea46db7f76c0f69be3192267e19
parent c5e705ef14f8038a051f258fe741919f4988ef7d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 14 May 2014 15:46:59 +0200

First version of structures

This first version accepts struct members, althought is not full
working (type is not correct after field operations), but is enough
to can work.

Diffstat:
Mcc1/cc1.h | 23+++++++++++++----------
Mcc1/code.c | 21+++++++++++++++++++++
Mcc1/decl.c | 5++---
Mcc1/expr.c | 29+++++++++++++++++++++++++++--
4 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -28,9 +28,17 @@ enum { NR_NAMESPACES }; +typedef struct ctype Type; +typedef struct symbol Symbol; + struct funpars; -struct symbol; +typedef struct field { + char *name; + Type *type; + int id; + struct field *next; +} Field; struct ctype { uint8_t op; /* type builder operator */ @@ -43,17 +51,11 @@ struct ctype { unsigned char rank; /* convertion rank */ short nelem; /* number of elements in arrays */ struct funpar *pars; /* function parameters */ - struct field *fields; /* aggregate fields */ + Field *fields; /* aggregate fields */ } u; }; -typedef struct ctype Type; -struct field { - char *name; - int id; - struct field *next; -}; struct funpar { Type *type; @@ -87,7 +89,6 @@ struct symbol { struct symbol *hash; }; -typedef struct symbol Symbol; extern void freesyms(uint8_t ns); @@ -183,6 +184,7 @@ typedef struct node { Symbol *sym; Type *type; char op; + Field *field; } u; struct node *childs[]; } Node; @@ -218,7 +220,8 @@ extern Node *castcode(Node *child, Type *tp), *sizeofcode(Type *tp), *ternarycode(Node *cond, Node *ifyes, Node *ifno), - *symcode(Symbol *sym); + *symcode(Symbol *sym), + *fieldcode(Node *child, struct field *fp); #define SYM(s) ((union unode) {.sym = s}) #define OP(s) ((union unode) {.op = s}) diff --git a/cc1/code.c b/cc1/code.c @@ -5,6 +5,8 @@ #include <cc.h> #include "cc1.h" +#define FIELD(s) ((union unode) {.field = s}) + char *opcodes[] = { [OADD] = "+", [OSUB] = "-", @@ -258,6 +260,25 @@ emitdefault(Symbol *sym) emitlabel(sym); } +void +emitfield(Node *np) +{ + Node *child; + + child = np->childs[0]; + (*child->code)(child); + + printf("\tM%d", np->u.field->id); +} + +Node * +fieldcode(Node *child, struct field *fp) +{ + Node *np = node(emitfield, fp->type, FIELD(fp), 1); + np->childs[0] = child; + return np; +} + Node * castcode(Node *child, Type *tp) { diff --git a/cc1/decl.c b/cc1/decl.c @@ -259,13 +259,11 @@ initializer(register Type *tp) static void newfield(Type *tp, Symbol *sym) { - register struct field *p, *q; + register Field *p, *q; register char *s, *t; - static uint8_t op; static char *err; s = sym->name; - op = tp->op; for (q = p = tp->u.fields; p; q = p, p = p->next) { t = p->name; if (*s == *t && !strcmp(s, t)) @@ -278,6 +276,7 @@ newfield(Type *tp, Symbol *sym) p->name = xstrdup(s); p->next = NULL; p->id = sym->id; + p->type = tp; if (!q) tp->u.fields = p; else diff --git a/cc1/expr.c b/cc1/expr.c @@ -284,6 +284,27 @@ logic(char op, Node *np1, Node *np2) } static Node * +field(Node *np) +{ + Field *fp; + + if (yytoken != IDEN) + error("unexpected '%s'", yytext); + switch (np->typeop) { + case STRUCT: case UNION: + for (fp = np->utype->u.fields; fp; fp = fp->next) { + if (!strcmp(fp->name, yytext)) { + next(); + return fieldcode(np, fp); + } + } + error("field '%s' not found", yytext); + default: + error("struct or union expected"); + } +} + +static Node * array(Node *np1, Node *np2) { Type *tp; @@ -462,8 +483,12 @@ postfix(void) np1 = incdec(np1, (yytoken == INC) ? OINC : ODEC); next(); break; - /* TODO: case '.': */ - /* TODO: case INDIR: */ + case INDIR: + np1 = content(OPTR, np1); + case '.': + next(); + np1 = field(np1); + break; /* TODO: case '(' */ default: return np1;