shithub: scc

Download patch

ref: b419af2e240fc9da3ea5fa5b4ecad1c9fc71cbb1
parent: 83925bdbebb1658ac7e26c3dc5181b3ae595d864
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Apr 7 04:45:10 EDT 2016

[cc2] Add defpar() and defvar()

Every target is going to do different things when a parameter
or a variable is declared, so the best thing we can do is to
create new functions to signal them these parsing events.

--- a/cc2/arch/amd64-sysv/code.c
+++ b/cc2/arch/amd64-sysv/code.c
@@ -174,13 +174,28 @@
 }
 
 void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
 {
 	label(sym);
-	if (!alloc || (sym->type.flags & INITF))
+	if (sym->kind == EXTRN || (sym->type.flags & INITF))
 		return;
 	size2asm(&sym->type);
 	puts("0");
+}
+
+void
+defvar(Symbol *sym)
+{
+}
+
+void
+defpar(Symbol *sym)
+{
+}
+
+void
+newfun(void)
+{
 }
 
 void
--- a/cc2/arch/i386-sysv/code.c
+++ b/cc2/arch/i386-sysv/code.c
@@ -173,13 +173,28 @@
 }
 
 void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
 {
 	label(sym);
-	if (!alloc || (sym->type.flags & INITF))
+	if (sym->kind == EXTRN || (sym->type.flags & INITF))
 		return;
 	size2asm(&sym->type);
 	puts("0");
+}
+
+void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
+}
+
+void
+newfun(void)
+{
 }
 
 void
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -109,9 +109,9 @@
 }
 
 void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
 {
-	if (!alloc)
+	if (sym->kind == EXTRN)
 		return;
 	if (sym->kind == GLOB)
 		fputs("export ", stdout);
@@ -119,6 +119,16 @@
 	if (sym->type.flags & INITF)
 		return;
 	printf("\tz\t%llu\n}\n", (unsigned long long) sym->type.size);
+}
+
+void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
 }
 
 void
--- a/cc2/arch/z80/cgen.c
+++ b/cc2/arch/z80/cgen.c
@@ -7,7 +7,73 @@
 {
 }
 
+/*
+ * This is strongly influenced by
+ * http://plan9.bell-labs.com/sys/doc/compiler.ps (/sys/doc/compiler.ps)
+ * calculate addresability as follows
+ *     AUTO => 11          value+fp
+ *     REG => 13           reg
+ *     STATIC => 12        (value)
+ *     CONST => 20         $value
+ */
+static Node *
+address(Node *np)
+{
+	Node *lp, *rp;
+
+	if (!np)
+		return np;
+
+	np->complex = 0;
+	np->address = 0;
+	lp = np->left;
+	rp = np->right;
+	switch (np->op) {
+	case AUTO:
+		np->address = 11;
+		break;
+	case REG:
+		np->address = 13;
+		break;
+	case MEM:
+		np->address = 12;
+		break;
+	case CONST:
+		np->address = 20;
+		break;
+	default:
+		if (lp)
+			address(lp);
+		if (rp)
+			address(rp);
+		break;
+	}
+
+	if (np->address > 10)
+		return np;
+	if (lp)
+		np->complex = lp->complex;
+	if (rp) {
+		int d = np->complex - rp->complex;
+
+		if (d == 0)
+			++np->complex;
+		else if (d < 0)
+			np->complex = rp->complex;
+	}
+	if (np->complex == 0)
+		++np->complex;
+	return np;
+}
+
 void
 addressability(void)
 {
+	Node *np;
+
+	if (!curfun)
+		return;
+
+	for (np = curfun->u.label; np; np = np->stmt)
+		address(np);
 }
--- a/cc2/arch/z80/code.c
+++ b/cc2/arch/z80/code.c
@@ -14,6 +14,7 @@
 };
 
 static int curseg = NOSEG;
+static TSIZE offpar, offvar;
 
 static void
 segment(int seg)
@@ -162,10 +163,48 @@
 }
 
 void
-defsym(Symbol *sym, int alloc)
+newfun()
 {
+	offpar = offvar = 0;
+}
+
+void
+defpar(Symbol *sym)
+{
+	TSIZE align, size;
+
+	if (sym->kind != REG && sym->kind != AUTO)
+		return;
+	align = sym->type.align;
+	size = sym->type.size;
+
+	offpar -= align-1 & ~align;
+	sym->u.off = offpar;
+	offpar -= size;
+	sym->kind = AUTO;
+}
+
+void
+defvar(Symbol *sym)
+{
+	TSIZE align, size;
+
+	if (sym->kind != REG && sym->kind != AUTO)
+		return;
+	align = sym->type.align;
+	size = sym->type.size;
+
+	offvar += align-1 & ~align;
+	sym->u.off = offvar;
+	offvar += size;
+	sym->kind = AUTO;
+}
+
+void
+defglobal(Symbol *sym)
+{
 	label(sym);
-	if (!alloc || (sym->type.flags & INITF))
+	if (sym->kind == EXTRN || (sym->type.flags & INITF))
 		return;
 	size2asm(&sym->type);
 	puts("0");
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -35,6 +35,9 @@
 	MEM      = 'M',
 	AUTO     = 'A',
 	REG      = 'R',
+	CONST    = '#',
+	STRING   = '"',
+	LABEL    = 'L',
 	/* storage class */
 	GLOB     = 'G',
 	EXTRN    = 'X',
@@ -41,8 +44,13 @@
 	PRIVAT   = 'Y',
 	LOCAL    = 'T',
 	MEMBER   = 'M',
-	LABEL    = 'L',
 	/* operands */
+	OMEM     = 'M',
+	OAUTO    = 'A',
+	OREG     = 'R',
+	OCONST   = '#',
+	OSTRING  = '"',
+	OLABEL   = 'L',
 	OADD     = '+',
 	OSUB     = '-',
 	OMUL     = '*',
@@ -74,8 +82,6 @@
 	OPTR     = '@',
 	OSYM     = 'i',
 	OCAST    = 'g',
-	OCONST   = '#',
-	OSTRING  = '"',
 	OINC     = 'i',
 	ODEC     = 'd',
 	/*statements */
@@ -134,6 +140,8 @@
 struct node {
 	char op;
 	Type type;
+	char complex;
+	char address;
 	union {
 		TUINT i;
 		char *s;
@@ -163,8 +171,8 @@
 
 /* code.c */
 extern void data(Node *np);
-extern void defsym(Symbol *sym, int alloc);
-extern void writeout(void), endinit(void);
+extern void writeout(void), endinit(void), newfun(void);
+extern void defvar(Symbol *), defpar(Symbol *), defglobal(Symbol *);
 
 /* node.c */
 extern void cleannodes(void);
@@ -171,6 +179,7 @@
 extern void delnode(Node *np);
 extern void deltree(Node *np);
 extern Node *newnode(void);
+extern Symbol *curfun;
 
 /* symbol.c */
 extern Symbol *getsym(int id);
--- a/cc2/node.c
+++ b/cc2/node.c
@@ -8,14 +8,16 @@
 
 #define NSYMBOLS   32
 
-int inhome;
+Symbol *curfun;
 
 struct arena {
 	Node *mem;
 	struct arena *next;
 };
+
 static struct arena *arena;
 static Node *freep;
+static int inhome;
 
 Node *
 newnode(void)
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -44,14 +44,14 @@
 	void (*parse)(char *token, union tokenop);
 	union tokenop u;
 } optbl[] = {            /*  eval     parse           args */
-	[AUTO]        = {  vardecl,  symbol, .u.op  =         AUTO},
-	[REG]         = {  vardecl,  symbol, .u.op  =          REG},
-	[GLOB]        = {  vardecl,  symbol, .u.op  =          MEM},
-	[EXTRN]       = {  vardecl,  symbol, .u.op  =          MEM},
-	[PRIVAT]      = {  vardecl,  symbol, .u.op  =          MEM},
-	[LOCAL]       = {  vardecl,  symbol, .u.op  =          MEM},
-	[MEMBER]      = {  flddecl,  symbol,                     0},
-	[LABEL]       = { labeldcl,  symbol,                     0},
+	[AUTO]        = {  vardecl,  symbol, .u.op  =        OAUTO},
+	[REG]         = {  vardecl,  symbol, .u.op  =         OREG},
+	[GLOB]        = {  vardecl,  symbol, .u.op  =         OMEM},
+	[EXTRN]       = {  vardecl,  symbol, .u.op  =         OMEM},
+	[PRIVAT]      = {  vardecl,  symbol, .u.op  =         OMEM},
+	[LOCAL]       = {  vardecl,  symbol, .u.op  =         OMEM},
+	[MEMBER]      = {  flddecl,  symbol, .u.op  =         OMEM},
+	[LABEL]       = { labeldcl,  symbol, .u.op  =       OLABEL},
 
 	[INT8]        = {     NULL,    type, .u.arg =    &int8type},
 	[INT16]       = {     NULL,    type, .u.arg =   &int16type},
@@ -130,11 +130,9 @@
 	[OTABLE]      = {     NULL, casetbl,                     0}
 };
 
-static Symbol *curfun;
-static int funpars = -1, sclass, ininit, endf, lineno;
+static int sclass, inpars, ininit, endf, lineno;
 static Node *stmtp;
 static void *stack[STACKSIZ], **sp = stack;
-static Symbol *params[NR_FUNPARAM];
 
 static void
 push(void *elem)
@@ -447,9 +445,9 @@
 static void
 endpars(void)
 {
-	if (!curfun || funpars == -1)
+	if (!curfun || !inpars)
 		error(ESYNTAX);
-	funpars = -1;
+	inpars = 0;
 }
 
 static void
@@ -499,35 +497,28 @@
 static void
 decl(Symbol *sym)
 {
-	int alloc;
 	Type *tp = &sym->type;
 
 	if (tp->flags & FUNF) {
 		curfun = sym;
-		return;
 	} else {
 		switch (sym->kind) {
 		case EXTRN:
-			alloc = 0;
-			break;
 		case GLOB:
 		case PRIVAT:
 		case LOCAL:
-			alloc = 1;
+			defglobal(sym);
 			break;
 		case AUTO:
 		case REG:
-			if (funpars >= 0) {
-				if (funpars == NR_FUNPARAM)
-					error(EOUTPAR);
-				params[funpars++] = sym;
-			}
-			return;
+			if (!curfun)
+				error(ESYNTAX);
+			((inpars) ? defpar : defvar)(sym);
+			break;
 		default:
 			abort();
 		}
 	}
-	defsym(sym, alloc);
 }
 
 static void
@@ -622,8 +613,7 @@
 static void
 beginfun(void)
 {
-	memset(params, 0, sizeof(params));
-	funpars = 0;
+	inpars = 0;
 	pushctx();
 }
 
@@ -633,19 +623,19 @@
 	Node *np;
 
 	np = newnode();
-	np->op = ONOP;
-	addstmt(np);
-	/* TODO: process the function */
 	curfun = NULL;
-	funpars = -1;
+	inpars = 0; /* I know, it is a bit redundant */
 	endf = 1;
-	popctx();
 }
 
 void
 parse(void)
 {
+	cleannodes();  /* remove code of previous function */
+	popctx();  /* remove context of previous function */
+	curfun = NULL;
 	endf = 0;
+
 	while (!endf && nextline())
 		/* nothing */;
 	if (ferror(stdin))