shithub: scc

Download patch

ref: b17f870636b9dea46db7f76c0f69be3192267e19
parent: c5e705ef14f8038a051f258fe741919f4988ef7d
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed May 14 11:46:59 EDT 2014

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.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -28,9 +28,17 @@
 	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 @@
 		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 *hash;
 };
 
-typedef struct symbol Symbol;
 
 extern void freesyms(uint8_t ns);
 
@@ -183,6 +184,7 @@
 		Symbol *sym;
 		Type *type;
 		char op;
+		Field *field;
 	} u;
 	struct node *childs[];
 } Node;
@@ -218,7 +220,8 @@
 	*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})
--- 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] = "-",
@@ -256,6 +258,25 @@
 {
 	fputs("\tf\t", stdout);
 	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 *
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -259,13 +259,11 @@
 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 @@
 	p->name = xstrdup(s);
 	p->next = NULL;
 	p->id = sym->id;
+	p->type = tp;
 	if (!q)
 		tp->u.fields = p;
 	else
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -284,6 +284,27 @@
 }
 
 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 @@
 			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;