scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 371dbd08d948b3679df21e8304ecfb20724d0976
parent f2207c0e27fe98dc65368ffb82553c50e20e0458
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 17 Jul 2014 15:09:27 +0200

First version of cc2

This is a first version of cc2 that allows to read a small subset
of the intermediate code. It is a good initial point for it.

Diffstat:
Makefile | 2+-
cc2/Makefile | 18++++++++++++++++++
cc2/main.c | 20++++++++++++++++++++
cc2/parser.c | 197+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
inc/cc.h | 4++--
5 files changed, 238 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ -DIRS = lib cc1 +DIRS = lib cc1 cc2 all clean: for i in $(DIRS) ;\ diff --git a/cc2/Makefile b/cc2/Makefile @@ -0,0 +1,18 @@ + +OBJS = main.o parser.o + +CPPFLAGS = -I../inc +LDFLAGS = -L../lib +LIBS = -lcc + +all: cc2 + +$(OBJS): ../inc/cc.h ../inc/sizes.h + +cc2: $(OBJS) ../lib/libcc.a + $(CC) $(LDFLAGS) $(CFLAGS) $(OBJS) $(LIBS) -o $@ + +clean: + rm -f $(OBJS) + rm -f cc2 + diff --git a/cc2/main.c b/cc2/main.c @@ -0,0 +1,20 @@ + +#include <stddef.h> + +#include <cc.h> +#include <sizes.h> + +extern void parse(void); + +void +esyntax(void) +{ + die("incorrect intermediate file"); +} + +int +main(void) +{ + parse(); +} + diff --git a/cc2/parser.c b/cc2/parser.c @@ -0,0 +1,197 @@ + +#include <ctype.h> +#include <stdio.h> + +#include <cc.h> +#include <sizes.h> + +#define NR_STACKSIZ 32 +#define NR_NODEPOOL 128 +#define NR_EXPRESSIONS 64 + +typedef struct node { + char op; + char type; + union { + short id; + int imm; + } u; + struct node *left, *right; +} Node; + +static Node *stack[NR_STACKSIZ], **stackp = stack; +static Node *listexp[NR_EXPRESSIONS], **listp = &listexp[0]; +static Node nodepool[NR_NODEPOOL], *newp = nodepool; +char vars[1024]; + +extern void esyntax(void); + +static short +getid(void) +{ + int i; + + scanf("%d", &i); + if (i < 0 || i >= 1024) + esyntax(); + return i; +} + +static Node * +newnode(void) +{ + if (newp == &nodepool[NR_NODEPOOL]) + esyntax(); + return newp++; +} + +static void +push(Node *np) +{ + if (stackp == &stack[NR_STACKSIZ]) + esyntax(); + *stackp++ = np; +} + +static Node * +pop(void) +{ + if (stackp == stack) + esyntax(); + return *--stackp; +} + +static void +link(Node *np) +{ + if (listp == &listexp[NR_EXPRESSIONS]) + esyntax(); + *listp++ = np; +} + +static char +gettype(void) +{ + char t; + + switch (t = getchar()) { + case L_INT16: case L_INT8: + return t; + default: + esyntax(); + } +} + +static void +variable(char op) +{ + Node *np = newnode(); + + np->op = op; + np->type = vars[np->u.id = getid()]; + np->left = np->right = NULL; + push(np); +} + +static void +immediate(char op) +{ + Node *np = newnode(); + + np->op = '#'; + np->type = L_INT; + scanf("%d", &np->u.imm); + np->left = np->right = NULL; + push(np); +} + +static void +operator(char op) +{ + Node *np = newnode(); + + np->left = pop(); + np->right = pop(); + np->type = gettype(); + np->op = op; + push(np); +} + +static Node * +getroot(void) +{ + Node *np = *--stackp; + if (stackp != stack) + esyntax(); + return np; +} + +static void (*optbl[])(char) = { + ['+'] = operator, + ['-'] = operator, + ['*'] = operator, + ['/'] = operator, + ['A'] = variable, + ['T'] = variable, + ['G'] = variable, + ['#'] = immediate, + ['\177'] = NULL +}; + +static void +expression(void) +{ + int c; + void (*fun)(char); + + do { + if (!isprint(c = getchar())) + esyntax(); + if ((fun = optbl[c]) == NULL) + esyntax(); + (*fun)(c); + } while ((c = getchar()) == '\t'); + + if (c != '\n') + esyntax(); + link(getroot()); +} + +static void +declaration(char sclass) +{ + short id; + + id = getid(); + getchar(); /* skip tab */ + vars[id] = gettype(); + if (getchar() != '\n') + esyntax(); +} + +int +parse(void) +{ + int c; + + while ((c = getchar()) != EOF) { + switch (c) { + case '\t': + expression(); + break; + case 'L': + /* label */ + break; + case 'S': + /* struct */ + break; + case 'T': case 'A': case 'G': case 'R': + declaration(c); + break; + default: + esyntax(); + break; + } + } +} + diff --git a/inc/cc.h b/inc/cc.h @@ -30,6 +30,7 @@ #define L_UINT16 'N' #define L_UINT32 'Z' #define L_UINT64 'O' +#define L_INT L_INT16 #define L_VOID '0' #define L_POINTER 'P' @@ -60,4 +61,4 @@ extern void *xcalloc(size_t nmemb, size_t size); extern char *xstrdup(const char *s); extern void *xrealloc(void *buff, register size_t size); -#endif- \ No newline at end of file +#endif