ref: a15ca68747ff228cf9fd71b541e7941cbe377536
parent: 57380d876cf8ee79ba67e06dca722cc54189ac27
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Sep 19 08:03:14 EDT 2014
Add a pointer to the list of trees in function symbols This modifications allow to split the implementation of functions and all the others procedures that are going to be applied to them (thanks to apply()).
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -1,4 +1,7 @@
+typedef struct symbol Symbol;
+typedef struct node Node;
+
typedef struct {
short size;
uint8_t align;
@@ -6,7 +9,7 @@
bool c_int : 1;
} Type;
-typedef struct symbol {
+struct symbol {
char *name;
bool public : 1;
bool extrn : 1;
@@ -23,11 +26,12 @@
struct {
short locals;
short params;
+ Node **body;
} f;
} u;
-} Symbol;
+};
-typedef struct node {
+struct node {
char op;
char subop;
Type *type;
@@ -39,7 +43,7 @@
char reg;
} u;
struct node *left, *right;
-} Node;
+};
enum nerrors {
EINTNUM, /* too much internal identifiers */
@@ -96,6 +100,7 @@
extern void error(unsigned nerror, ...);
extern void genaddable(Node *np);
-extern void generate(Symbol *sym, Node *list[]);
+extern void generate(Symbol *fun);
extern void genstack(Symbol *fun);
extern void apply(Node *list[], void (*fun)(Node *));
+extern Symbol *parse(void);
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -237,21 +237,21 @@
}
void
-generate(Symbol *sym, Node *list[])
+generate(Symbol *fun)
{
extern char odebug;
- char frame = sym->u.f.locals != 0 || odebug;
+ char frame = fun->u.f.locals != 0 || odebug;
- emit(ADDR, sym->name);
+ emit(ADDR, fun->name);
if (frame) {
emit(PUSH, IX);
emit(LD, IX, SP);
- emit(LDI, HL, -sym->u.f.locals);
+ emit(LDI, HL, -fun->u.f.locals);
emit(ADD, HL, SP);
emit(LD, SP, HL);
}
- apply(list, cgen);
+ apply(fun->u.f.body, cgen);
if (frame) {
emit(LD, SP, IX);
--- a/cc2/main.c
+++ b/cc2/main.c
@@ -9,8 +9,6 @@
#include "cc2.h"
#include "error.h"
-extern void parse(void);
-
char odebug;
void
@@ -30,5 +28,10 @@
int
main(void)
{
- parse();
+ Symbol *fun;
+
+ while (!feof(stdin) && (fun = parse())) {
+ apply(fun->u.f.body, genaddable);
+ generate(fun);
+ }
}
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -20,9 +20,9 @@
};
static Symbol *curfun;
-static Node *stack[NR_STACKSIZ], **stackp = stack;
-static Node *listexp[NR_EXPRESSIONS], **listp = listexp;
-static Node nodepool[NR_NODEPOOL], *newp = nodepool;
+static Node *stack[NR_STACKSIZ], **stackp;
+static Node *listexp[NR_EXPRESSIONS], **listp;
+static Node nodepool[NR_NODEPOOL], *newp;
Type l_int8 = {
@@ -399,17 +399,6 @@
sym->u.l.addr = listp - listexp;
}
-static void
-endfunction(char *token)
-{
- if (!curfun)
- error(ESYNTAX);
- listp = NULL;
- apply(listexp, genaddable);
- generate(curfun, listexp);
- curfun = NULL;
-}
-
static Symbol *
declaration(uint8_t t, char class, char *token)
{
@@ -453,7 +442,7 @@
sym->type = FUN;
curfun = sym;
- listp = listexp;
+ sym->u.f.body = listp = listexp;
newp = nodepool;
}
@@ -473,7 +462,7 @@
curfun->u.f.locals += sym->u.v.type->size;
}
-void
+Symbol *
parse(void)
{
void (*fun)(char *tok);
@@ -481,6 +470,11 @@
int c;
char line[MAXLINE];
+ curfun = NULL;
+ stackp = stack;
+ listp = listexp;
+ newp = nodepool;
+
for (;;) {
switch (c = getchar()) {
case 'L':
@@ -502,10 +496,15 @@
fun = globdcl;
break;
case '}':
- fun = endfunction;
- break;
+ if (!curfun)
+ error(ESYNTAX);
+ return curfun;
case EOF:
- goto found_eof;
+ if (ferror(stdin))
+ error(EFERROR, strerror(errno));
+ if (curfun)
+ goto syntax_error;
+ return NULL;
case '\n':
continue;
default:
@@ -523,11 +522,10 @@
}
found_eof:
- if (ferror(stdin))
- error(EFERROR, strerror(errno));
- if (!curfun)
- return;
+
+ if (!curfun)
+ return curfun;
syntax_error:
error(ESYNTAX);
}
--
⑨