shithub: scc

Download patch

ref: d7cd0ce876107c05e34c7c00cef311e2023a9352
parent: 0771ecab43a53d473d65baf0d08b6177077e11b4
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Jan 24 13:45:18 EST 2016

[cc2] Generate code for initializers

The only architecture that generates actual code is z80,
in the other cases they are only stubs.

--- a/cc2/arch/amd64-sysv/code.c
+++ b/cc2/arch/amd64-sysv/code.c
@@ -3,7 +3,12 @@
 #include "../../cc2.h"
 
 void
-emit(Node *np)
+data(Node *np)
+{
+}
+
+void
+label(Symbol *sym)
 {
 }
 
--- a/cc2/arch/i386-sysv/code.c
+++ b/cc2/arch/i386-sysv/code.c
@@ -3,7 +3,12 @@
 #include "../../cc2.h"
 
 void
-emit(Node *np)
+data(Node *np)
+{
+}
+
+void
+label(Symbol *sym)
 {
 }
 
--- a/cc2/arch/z80/code.c
+++ b/cc2/arch/z80/code.c
@@ -34,28 +34,46 @@
 {
 }
 
+void
+label(Symbol *sym)
+{
+	int seg, flags = sym->type.flags;
+
+	if (flags & FUNF)
+		seg = CODESEG;
+	else if (flags & INITF)
+		seg = DATASEG;
+	else
+		seg = BSSSEG;
+	segment(seg);
+
+	printf("%s:\n", symname(sym));
+}
+
 static void
-emitsym(Symbol *sym)
+emitstring(Node *np)
 {
 	/*In z80 we can ignore the aligment */
-	if (sym->type.flags & STRF) {
-		fputs(sym->u.s, stdout);
-		free(sym->u.s);
-		sym->u.s = NULL;
-	} else {
-		switch (sym->type.size) {
-		case 1:
-			printf("%02X", (int) (sym->u.i & 0xFF));
-			break;
-		case 2:
-			printf("%04X", (int) (sym->u.i & 0xFFFF));
-			break;
-		case 4:
-			printf("%08X", (long) (sym->u.i & 0xFFFFFFFF));
-			break;
-		default:
-			abort();
-		}
+	printf("\"%s\"", np->u.s);
+	free(np->u.s);
+	np->u.s = NULL;
+}
+
+static void
+emitconst(Node *np)
+{
+	switch (np->type.size) {
+	case 1:
+		printf("%02X", (int) np->u.i & 0xFF);
+		break;
+	case 2:
+		printf("%04X", (int) np->u.i & 0xFFFF);
+		break;
+	case 4:
+		printf("%08X", (long) np->u.i & 0xFFFFFFFF);
+		break;
+	default:
+		abort();
 	}
 }
 
@@ -64,17 +82,30 @@
 {
 	if (!np)
 		return;
-	if (np->op == OSYM) {
-		emitsym(np->sym);
-	} else {
-		emit(np->left);
+
+	switch (np->op) {
+	case OSTRING:
+		emitstring(np);
+		break;
+	case OCONST:
+		emitconst(np);
+		break;
+	case OADDR:
+		emittree(np->left);
+		break;
+	case MEM:
+		fputs(symname(np->u.sym), stdout);
+		break;
+	default:
+		emittree(np->left);
 		printf(" %c ", np->op);
-		emit(np->right);
+		emittree(np->right);
+		break;
 	}
 }
 
 void
-emit(Node *np)
+data(Node *np)
 {
 	char *s;
 
@@ -81,7 +112,6 @@
 	/*
 	 * In z80 we can ignore the alignment
 	 */
-	segment(DATASEG);
 	switch (np->type.size) {
 	case 1:
 		s = "\tDB\t";
@@ -98,6 +128,7 @@
 	}
 	fputs(s, stdout);
 	emittree(np);
+	putchar('\n');
 }
 
 void
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -2,12 +2,11 @@
 enum tflags {
 	SIGNF   =    1,
 	INTF    =    2,
-	DEFTYP  =    4,
-	STRUCTF =    8,
+	STRF    =    8,
 	UNIONF  =    16,
-	FUNCF   =    32,
+	FUNF    =    32,
 	ARYF    =    64,
-	STRF    =   128
+	INITF   =   128
 };
 
 enum op {
@@ -115,13 +114,10 @@
 
 struct symbol {
 	unsigned short id;
+	unsigned short numid;
 	char *name;
 	Type type;
 	char kind;
-	union {
-		TUINT i;
-		char *s;
-	} u;
 	Symbol *next;
 	Symbol *h_next;
 };
@@ -129,7 +125,11 @@
 struct node {
 	char op;
 	Type type;
-	Symbol *sym;
+	union {
+		TUINT i;
+		char *s;
+		Symbol *sym;
+	} u;
 	Node *left, *right;
 	Node *stmt;
 };
@@ -151,7 +151,8 @@
 extern void peephole(void);
 
 /* code.c */
-extern void emit(Node *np);
+extern void label(Symbol *sym);
+extern void data(Node *np);
 extern void writeout(void);
 
 /* node.c */
@@ -165,3 +166,4 @@
 extern void popctx(void);
 extern void pushctx(void);
 extern void freesym(Symbol *sym);
+extern char *symname(Symbol *sym);
--- a/cc2/node.c
+++ b/cc2/node.c
@@ -39,7 +39,6 @@
 
 	np->right = NULL;
 	np->left = NULL;
-	np->sym = NULL;
 	np->stmt = NULL;
 	return np;
 }
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -22,21 +22,9 @@
             elipsistype;
 
 Type funtype = {
-	.flags = DEFTYP | FUNCF
+	.flags = FUNF
 };
 
-Type arrtype = {
-	.flags = DEFTYP | ARYF
-};
-
-Type uniontype = {
-	.flags = DEFTYP | UNIONF
-};
-
-Type strtype = {
-	.flags = DEFTYP | STRUCTF
-};
-
 union tokenop {
 	void *arg;
 	int op;
@@ -44,10 +32,11 @@
 
 typedef void parsefun(char *, union tokenop);
 static parsefun type, symbol, getname, unary, binary, ternary, call,
-                parameter, constant;
+                parameter, constant, aggregate;
 
 typedef void evalfun(void);
-static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, endinit;
+static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit,
+               endinit, array;
 
 static struct decoc {
 	void (*eval)(void);
@@ -80,9 +69,9 @@
 	[ELLIPSIS]    = {NULL, type, .u.arg   = &elipsistype},
 
 	[FUNCTION]    = {NULL, type, .u.arg = &funtype},
-	[VECTOR]      = {NULL, NULL, .u.arg = &arrtype},
-	[UNION]       = {NULL, NULL, .u.arg = &uniontype},
-	[STRUCT]      = {NULL, NULL, .u.arg = &strtype},
+	[VECTOR]      = {array, aggregate},
+	[UNION]       = {NULL, NULL},
+	[STRUCT]      = {NULL, NULL},
 
 	[ONAME]       = {NULL, getname},
 	['{']         = {beginfun},
@@ -161,6 +150,7 @@
 
 	if (++id == 0)
 		error(EIDOVER);
+	return id;
 }
 
 static void
@@ -170,6 +160,15 @@
 }
 
 static void
+aggregate(char *token, union tokenop u)
+{
+	Symbol *sym;
+
+	sym = getsym(atoi(token+1));
+	push(&sym->type);
+}
+
+static void
 getname(char *t, union tokenop u)
 {
 	push((*++t) ? xstrdup(t) : NULL);
@@ -182,7 +181,7 @@
 
 	sclass = *token++;
 	np = newnode();
-	np->sym = getsym(atoi(token));
+	np->u.sym = getsym(atoi(token));
 	np->op = u.op;
 	push(np);
 }
@@ -204,17 +203,14 @@
 {
 	static char letters[] = "0123456789ABCDEF";
 	Node *np = newnode();
-	Symbol *sym = getsym(0);
 	TUINT v;
 	unsigned c;
 
-	np->sym = sym;
 	++token;
 	if (*token == OSTRING) {
-		np->op = OSYM;
-		sym->id = newid();
-		sym->type.flags = STRF;
-		sym->u.s = xstrdup(++token);
+		np->op = OSTRING;
+		np->type.flags = STRF;
+		np->u.s = xstrdup(++token);
 	} else {
 		np->op = OCONST;
 		np->type = *gettype(token++);
@@ -222,7 +218,7 @@
 			v <<= 4;
 			c = strchr(letters, c) - letters;
 		}
-		sym->u.i = v;
+		np->u.i = v;
 	}
 	push(np);
 }
@@ -295,6 +291,8 @@
 begininit(void)
 {
 	ininit = 1;
+	lastsym->type.flags |= INITF;
+	label(lastsym);
 }
 
 static void
@@ -333,6 +331,17 @@
 }
 
 static void
+array(void)
+{
+	Type *tp, *base;
+	Node *np;
+
+	np = pop();
+	base = pop();
+	tp = pop();
+}
+
+static void
 vardecl(void)
 {
 	Type *tp;
@@ -344,11 +353,13 @@
 	tp = pop();
 	np = pop();
 
-	sym = np->sym;
+	sym = np->u.sym;
 	sym->name = name;
 	sym->type = *tp;
 	sym->kind = sclass;
 	lastsym = sym;
+	if (!name)
+		sym->numid = newid();
 
 	if (funpars >= 0) {
 		if (funpars == NR_FUNPARAM)
@@ -365,7 +376,7 @@
 	Node *np = pop();
 
 	if (ininit) {
-		emit(np);
+		data(np);
 		deltree(np);
 		return;
 	}
--- a/cc2/symbol.c
+++ b/cc2/symbol.c
@@ -1,4 +1,5 @@
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -47,7 +48,7 @@
 
 	htab = &symtab[id & NR_SYMHASH-1];
 	for (sym = *htab; sym; sym = sym->h_next) {
-		if (sym->id > 0 && sym->id != id)
+		if (sym->id > 0 && sym->id == id)
 			break;
 	}
 	if (!sym) {
@@ -63,4 +64,16 @@
 		*htab = sym;
 	}
 	return sym;
+}
+
+char *
+symname(Symbol *sym)
+{
+	static char name[20];
+
+	if (sym->name)
+		return sym->name;
+	sprintf(name, ".%d", sym->numid);
+
+	return name;
 }