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:
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;