commit dd604299ecdeb25d1c7d0f4cb77e2478777272ad
parent b6d551944bd495bb30ba7345f5ab77ccca14c295
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 1 Apr 2014 21:42:12 +0200
Merge branch 'bsc'
Diffstat:
M | cc.h | | | 215 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
M | code.c | | | 112 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
D | code.h | | | 10 | ---------- |
M | decl.c | | | 91 | +++++++++++++++++++++++++++++++------------------------------------------------- |
M | error.c | | | 6 | ++++-- |
M | expr.c | | | 223 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
M | lex.c | | | 8 | +++----- |
M | main.c | | | 1 | - |
M | stmt.c | | | 12 | +++++------- |
M | symbol.c | | | 18 | ++++++++---------- |
D | symbol.h | | | 112 | ------------------------------------------------------------------------------- |
D | tokens.h | | | 79 | ------------------------------------------------------------------------------- |
M | types.c | | | 206 | +++++++++++++++++++++---------------------------------------------------------- |
M | wrapper.c | | | 2 | ++ |
14 files changed, 533 insertions(+), 562 deletions(-)
diff --git a/cc.h b/cc.h
@@ -1,12 +1,11 @@
#ifndef CC_H
#define CC_H
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-extern unsigned linenum;
-extern unsigned columnum;
-extern const char *filename;
+#ifndef __bool_true_and_false_defined
+#include <stdbool.h>
+#endif
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
struct user_opt {
unsigned char implicit;
@@ -26,4 +25,210 @@ extern void *xmalloc(size_t size);
extern void *xcalloc(size_t nmemb, size_t size);
extern char *xstrdup(const char *s);
extern void *xrealloc(void *buff, register size_t size);
+
+/* definitions of types */
+
+#define CTX_OUTER 0
+#define CTX_FUNC 1
+
+enum {
+ NS_IDEN = 0,
+ NS_LABEL,
+ NS_TAG,
+ NR_NAMESPACES,
+ NS_KEYWORD,
+ NS_FREE
+};
+
+struct funpars;
+struct symbol;
+
+struct ctype {
+ uint8_t op; /* type builder operator */
+ char letter; /* letter of the type */
+ short nelem; /* number of elements in arrays */
+ unsigned defined : 1; /* type defined (is not a forward reference) */
+ unsigned sign : 1; /* sign type */
+ struct symbol *sym; /* symbol of the tag identifier */
+ struct ctype *type; /* base type */
+ struct ctype *next; /* next element in the hash */
+ union {
+ struct funpar *pars; /* function parameters */
+ struct field *fields; /* aggregate fields */
+ } u;
+};
+
+typedef struct ctype Type;
+
+struct field {
+ struct symbol *sym;
+ struct field *next;
+};
+
+struct funpar {
+ Type *type;
+ struct funpar *next;
+};
+
+/* definition of symbols */
+
+union value {
+ char c;
+ int i;
+ struct symbol *sym;
+ uint8_t ns, token;
+};
+
+struct symbol {
+ char *name;
+ Type *type;
+ short id;
+ uint8_t ctx;
+ uint8_t token;
+ uint8_t ns;
+ struct {
+ bool isglobal : 1;
+ bool isstatic : 1;
+ bool isauto : 1;
+ bool isregister : 1;
+ } s;
+ union value u;
+ struct symbol *next;
+ struct symbol *hash;
+};
+
+typedef struct symbol Symbol;
+
+extern void freesyms(uint8_t ns);
+
+extern Type *qualifier(Type *tp, uint8_t qlf),
+ *ctype(int8_t type, int8_t sign, int8_t size),
+ *mktype(Type *tp,
+ uint8_t op, Symbol *tag, uint16_t nelem);
+
+extern Symbol
+ *lookup(char *s, unsigned char ns),
+ *install(char *s, unsigned char ns);
+
+extern void context(void (*fun)(void));
+
+extern Type *voidtype,
+ *uchartype, *chartype,
+ *uinttype, *inttype,
+ *ushortype, *shortype,
+ *longtype, *ulongtype,
+ *ullongtype, *llongtype,
+ *floattype, *doubletype, *ldoubletype;
+
+#define ISQUAL(t) (isqual((t)->op))
+#define UNQUAL(t) (ISQUAL(t) ? (t)->type : (t))
+#define BTYPE(t) (UNQUAL(t)->op)
+#define isarith(op) ((op) & ARITH)
+#define isaddr(op) ((op) & POINTER)
+#define isrecord(op) ((op) & RECORD)
+#define isqual(op) ((op) & TQUALIFIER)
+
+
+#define ARITH 8
+#define RECORD 16
+#define POINTER 32
+#define ATYPE(x) (ARITH | (x))
+#define RTYPE(x) (RECORD | (x))
+#define PTYPE(x) (POINTER| (x))
+
+#define FTN 1
+#define ENUM 2
+#define TYPENAME 3
+#define VOID 4
+
+#define FLOAT ATYPE(1)
+#define INT ATYPE(2)
+#define BOOL ATYPE(3)
+
+#define STRUCT RTYPE(1)
+#define UNION RTYPE(2)
+
+#define PTR PTYPE(1)
+#define ARY PTYPE(2)
+
+#define CHAR (ARY+1)
+#define DOUBLE (ARY+2)
+#define SHORT (ARY+3)
+#define LONG (ARY+4)
+
+#define COMPLEX (ARY+5)
+#define IMAGINARY (ARY+6)
+#define UNSIGNED (ARY+7)
+#define SIGNED (ARY+8)
+
+#define CONST (1<<0)
+#define VOLATILE (1<<1)
+#define RESTRICT (1<<2)
+
+#define TYPEDEF 1
+#define EXTERN 2
+#define STATIC 3
+#define AUTO 4
+#define REGISTER 5
+
+#define accept(t) ((yytoken == (t)) ? next() : 0)
+#define ahead() yyntoken
+
+enum tokens {
+ TQUALIFIER = 128, TYPE, IDEN, SCLASS,
+ CONSTANT, SIZEOF,
+ INDIR, INC, DEC, SHL, SHR,
+ LE, GE, EQ, NE, AND, OR,
+ MUL_EQ, DIV_EQ, MOD_EQ, ADD_EQ, SUB_EQ, AND_EQ,
+ XOR_EQ, OR_EQ, SHL_EQ, SHR_EQ,
+ ELLIPSIS,
+ CASE, DEFAULT, IF, ELSE, SWITCH, WHILE, DO, FOR, GOTO,
+ CONTINUE, BREAK, RETURN, EOFTOK, NOTOK
+};
+
+union yystype {
+ Symbol *sym;
+ uint8_t token;
+};
+
+extern union yystype yylval;
+extern char yytext[];
+extern uint8_t yytoken, yyntoken;
+
+extern uint8_t next(void);
+extern void expect(uint8_t tok);
+
+
+typedef struct node {
+ void (*code)(struct node *);
+ Type *type;
+ union unode {
+ Symbol *sym;
+ Type *type;
+ char op;
+ } u;
+ struct node *childs[];
+} Node;
+
+typedef void (*Inst)(Node *);
+
+enum {
+ OCAST, OPTR, OADD, OARY, OSIZE, OMUL
+};
+
+extern void
+ emitsym(Node *), emitunary(Node *),
+ emitbin(Node *), emitexp(Node *);
+
+extern Node
+ *node(Inst code, Type *tp, union unode u, uint8_t nchilds),
+ *unarycode(char op, Type *tp, Node *child),
+ *bincode(char op, Type *tp, Node *np1, Node *np2),
+ *castcode(Node *child, Type *tp),
+ *sizeofcode(Type *tp);
+
+#define SYM(s) ((union unode) {.sym = s})
+#define OP(s) ((union unode) {.op = s})
+#define TYP(s) ((union unode) {.type = s})
+
#endif
diff --git a/code.c b/code.c
@@ -2,11 +2,32 @@
#include <stdint.h>
#include <stdio.h>
-#include "symbol.h"
+#include "cc.h"
+
+char *opcodes[] = {
+ [OADD] = "+",
+ [OMUL] = "*",
+ [OARY] = "'",
+ [OSIZE] = "#",
+ [OPTR] = "@"
+};
+
+Node *
+node(Inst code, Type *tp, union unode u, uint8_t nchilds)
+{
+ Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));
+
+ np->code = code;
+ np->type = tp;
+ np->u = u;
+
+ return np;
+}
void
-emitsym(struct symbol *sym)
+emitsym(Node *np)
{
+ Symbol *sym = np->u.sym;
char c;
if (sym->s.isglobal)
@@ -14,26 +35,104 @@ emitsym(struct symbol *sym)
else if (sym->s.isstatic)
c = 'T';
else if (sym->s.isregister)
- c = 'R';
+ c = 'Q';
else
c = 'A';
printf("\t%c%d", c, sym->id);
}
void
-emitfun(struct symbol *sym)
+emitcast(Node *np)
+{
+ Node *child = np->childs[0];
+
+ (*child->code)(child);
+ printf("\t%c%c", np->u.type->letter, np->type->letter);
+}
+
+void
+emitunary(Node *np)
+{
+ Node *child;
+ char op, letter;
+
+ letter = np->type->letter;
+ child = np->childs[0];
+ (*child->code)(child);
+ printf("\t%s%c", opcodes[np->u.op], letter);
+}
+
+void
+emitbin(Node *np)
+{
+ Node *child1, *child2;
+
+ child1 = np->childs[0];
+ child2 = np->childs[1];
+ (*child1->code)(child1);
+ (*child2->code)(child2);
+ printf("\t%s%c", opcodes[np->u.op], np->type->letter);
+}
+
+void
+emitsizeof(Node *np)
+{
+ printf("\t#%c", np->u.type->letter);
+}
+
+void
+emitexp(Node *np)
+{
+ (*np->code)(np);
+ putchar('\n');
+}
+
+void
+emitfun(Symbol *sym)
{
printf("X%s\n", sym->name);
}
void
-emitframe(struct symbol *sym)
+emitframe(Symbol *sym)
{
puts("{");
}
void
-emitret(struct symbol *sym)
+emitret(Symbol *sym)
{
puts("}");
}
+
+Node *
+castcode(Node *child, Type *tp)
+{
+ Node *np = node(emitcast, tp, TYP(child->type), 1);
+
+ np->childs[0] = child;
+ return np;
+}
+
+Node *
+unarycode(char op, Type *tp, Node *child)
+{
+ Node *np = node(emitunary, tp, OP(op), 1);
+ np->childs[0] = child;
+ return np;
+}
+
+Node *
+bincode(char op, Type *tp, Node *np1, Node *np2)
+{
+ Node *np = node(emitbin, tp, OP(op), 2);
+ np->childs[0] = np1;
+ np->childs[1] = np2;
+ return np;
+}
+
+Node *
+sizeofcode(Type *tp)
+{
+ return node(emitsizeof, inttype, TYP(tp), 0);
+}
+\ No newline at end of file
diff --git a/code.h b/code.h
@@ -1,10 +0,0 @@
-
-#ifndef CODE_H_
-#define CODE_H_
-
-struct symbol;
-
-extern void emitsym(struct symbol *sym), emitfun(struct symbol *sym),
- emitframe(struct symbol *sym), emitret(struct symbol *sym);
-
-#endif
diff --git a/decl.c b/decl.c
@@ -5,8 +5,6 @@
#include "sizes.h"
#include "cc.h"
-#include "tokens.h"
-#include "symbol.h"
#include "machine.h"
#define ID_EXPECTED 1
@@ -18,7 +16,7 @@ struct dcldata {
uint8_t op;
union {
unsigned short nelem;
- struct symbol *sym;
+ Symbol *sym;
struct funpars *pars;
uint8_t qlf;
} u;
@@ -51,10 +49,10 @@ fundcl(struct dcldata *dp)
return dp + 1;
}
-static struct symbol *
+static Symbol *
newiden(uint8_t ns)
{
- struct symbol *sym;
+ Symbol *sym;
extern uint8_t curctx;
if (yylval.sym && yylval.sym->ctx == curctx)
@@ -67,7 +65,7 @@ newiden(uint8_t ns)
static struct dcldata *
directdcl(struct dcldata *dp, uint8_t ns, int8_t flags)
{
- register struct symbol *sym;
+ register Symbol *sym;
char *err;
if (accept('(')) {
@@ -133,12 +131,12 @@ too_much_declarators:
error("too much declarators");
}
-static struct symbol *
-declarator(struct ctype *tp, uint8_t ns, int8_t flags)
+static Symbol *
+declarator(Type *tp, uint8_t ns, int8_t flags)
{
struct dcldata data[NR_DECLARATORS+1];
register struct dcldata *bp;
- struct symbol *sym;
+ Symbol *sym;
memset(data, 0, sizeof(data));
data[NR_DECLARATORS].op = 255;
@@ -162,19 +160,19 @@ declarator(struct ctype *tp, uint8_t ns, int8_t flags)
return sym;
}
-static struct ctype *structdcl(void), *enumdcl(void);
+static Type *structdcl(void), *enumdcl(void);
-static struct ctype *
+static Type *
specifier(int8_t *sclass)
{
- struct ctype *tp = NULL;
- int8_t qlf, sign, type, cls, cplex, size, t;
+ Type *tp = NULL;
+ int8_t qlf, sign, type, cls, size, t;
- qlf = sign = type = cls = size = cplex = 0;
+ qlf = sign = type = cls = size = 0;
for (;;) {
register uint8_t *p;
- struct ctype *(*dcl)(void) = NULL;
+ Type *(*dcl)(void) = NULL;
switch (yytoken) {
case SCLASS: p = &cls; break;
@@ -203,8 +201,6 @@ specifier(int8_t *sclass)
}
case SHORT:
p = &size; break;
- case COMPLEX: case IMAGINARY:
- p = &cplex; break;
}
break;
default:
@@ -228,7 +224,6 @@ check_types:
type = INT;
}
if (sign && type != INT && type != CHAR ||
- cplex && type != FLOAT && type != DOUBLE ||
size == SHORT && type != INT ||
size == LONG && type != INT && type != DOUBLE ||
size == LONG+LONG && type != INT) {
@@ -237,7 +232,7 @@ check_types:
if (sclass)
*sclass = cls;
if (!tp)
- tp = ctype(type, sign, size, cplex);
+ tp = ctype(type, sign, size);
return (qlf) ? qualifier(tp, qlf) : tp;
invalid_type:
@@ -245,7 +240,7 @@ invalid_type:
}
static struct node *
-initializer(register struct ctype *tp)
+initializer(register Type *tp)
{
if (accept('{')) {
initializer(tp);
@@ -260,11 +255,10 @@ initializer(register struct ctype *tp)
/* TODO: bitfields */
static void
-newfield(struct ctype *tp, struct symbol *sym)
+newfield(Type *tp, Symbol *sym)
{
register struct field *p, *q;
register char *s, *t;
- static short size, offset;
static uint8_t op;
static char *err;
@@ -281,25 +275,10 @@ newfield(struct ctype *tp, struct symbol *sym)
p = xmalloc(sizeof(*p));
p->next = NULL;
p->sym = sym;
- size = sym->type->size;
- if (!q) {
+ if (!q)
tp->u.fields = p;
- if (op != ENUM) {
- tp->size = size;
- sym->u.offset = 0;
- }
- } else {
+ else
q->next = p;
- if (tp->op == STRUCT) {
- offset = ALIGN(size, tp->size);
- sym->u.offset = offset;
- tp->size = offset + size;
- } else if (op == UNION) {
- sym->u.offset = 0;
- if (tp->size < size)
- tp->size = size;
- }
- }
return;
@@ -313,10 +292,10 @@ error:
}
static void
-fielddcl(struct ctype *base, uint8_t ns)
+fielddcl(Type *base, uint8_t ns)
{
- struct ctype *tp;
- struct symbol *sym;
+ Type *tp;
+ Symbol *sym;
char *err;
switch (yytoken) {
@@ -349,11 +328,11 @@ error:
error(err, yytext);
}
-static struct ctype *
+static Type *
newtag(uint8_t tag)
{
- register struct symbol *sym;
- struct ctype *tp;
+ register Symbol *sym;
+ Type *tp;
extern uint8_t namespace;
if (yytoken == IDEN) {
@@ -377,10 +356,10 @@ bad_tag:
error("'%s' defined as wrong kind of tag", yytext);
}
-static struct ctype *
+static Type *
structdcl(void)
{
- struct ctype *tp;
+ Type *tp;
uint8_t ns, tag;
tag = yylval.token;
@@ -403,11 +382,11 @@ redefined:
error("redefinition of struct/union '%s'", yytext);
}
-static struct ctype *
+static Type *
enumdcl(void)
{
- register struct ctype *tp;
- struct symbol *sym;
+ register Type *tp;
+ Symbol *sym;
int val = 0;
char *err;
@@ -447,8 +426,8 @@ error:
void
decl(void)
{
- struct ctype *tp;
- struct symbol *sym;
+ Type *tp;
+ Symbol *sym;
int8_t sclass;
tp = specifier(&sclass);
@@ -472,9 +451,9 @@ typename(void)
void
extdecl(void)
{
- struct ctype *base;
+ Type *base;
int8_t sclass;
- struct symbol *sym;
+ Symbol *sym;
char *err;
extern void compound(void);
@@ -493,14 +472,14 @@ extdecl(void)
if (yytoken != ';') {
do {
- struct ctype *tp;
+ Type *tp;
sym = declarator(base, NS_IDEN, ID_EXPECTED);
tp = sym->type;
if (!(sclass & STATIC))
sym->s.isglobal = 1;
- if (isfun(BTYPE(tp))) {
+ if (BTYPE(tp) == FTN) {
emitfun(sym);
if (yytoken == '{') {
emitframe(sym);
diff --git a/error.c b/error.c
@@ -1,12 +1,14 @@
#include <stdarg.h>
#include <stdlib.h>
+#include <stdint.h>
#include <stdio.h>
#include "cc.h"
-
-
+extern unsigned linenum;
+extern unsigned columnum;
+extern const char *filename;
static void
warn_helper(char flag, const char *fmt, va_list va)
diff --git a/expr.c b/expr.c
@@ -2,50 +2,22 @@
#include <stdio.h>
#include "cc.h"
-#include "code.h"
-#include "tokens.h"
-#include "symbol.h"
-
-struct node *expr(void);
-
-enum {
- OSYM = 1, OARY, OPTR, OADD,
-};
-
-struct node {
- uint8_t op;
- struct ctype *type;
-
- struct {
- bool constant : 1;
- } f;
- union {
- struct symbol *sym;
- } u;
- struct node *left, *right;
-};
-
-struct node *
-newnode(uint8_t op, struct ctype *tp)
-{
- struct node *np = xcalloc(1, sizeof(*np));
- np->op = op;
- np->type = tp;
- return np;
-}
+#define SWAP(x1, x2, t) (t = x1, x1 = x2, x2 = t)
+
+Node *expr(void);
-static struct node *
+static Node *
primary(void)
{
- register struct node *np;
+ Node *np;
+ Symbol *sym;
switch (yytoken) {
case IDEN:
- if (yylval.sym == NULL)
+ if ((sym = yylval.sym) == NULL)
error("'%s' undeclared", yytext);
- np = newnode(OSYM, yylval.sym->type);
- np->u.sym = yylval.sym;
+ np = node(emitsym, sym->type, SYM(sym), 0);
next();
break;
case CONSTANT:
@@ -58,117 +30,133 @@ primary(void)
expect(')');
break;
default:
- np = NULL;
+ ;
}
return np;
}
-static struct node *
-int2ptr(struct node *np)
+void
+intconv(Node **np1, Node **np2)
{
}
-static struct node *
-ptr2vec(struct node *np)
+void
+floatconv(Node **np1, Node **np2)
{
- struct ctype *tp = np->type;
- struct node *p;
-
- tp = mktype(UNQUAL(tp)->type, ARY, NULL, 0);
- p = newnode(OPTR, tp);
- p->left = np;
- return p;
}
-static struct node *
-ary(struct node *np1)
+static Node *
+add(Node *np1, Node *np2)
{
- struct node *np2, *naux;
- struct ctype *tp;
+ Node *naux;
+ Type *tp1, *tp2;
uint8_t t1, t2, taux;
- /* should be for arrays: A2 A1 RI #1 *R ` */
- /* should be for pointers: A2 @ A1 RI #1 *R ` */
- np2 = expr();
- expect(']');
+ tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np2->type);
+ t1 = tp1->op, t2 = tp2->op;
+
+ switch (t1) {
+ case INT:
+ switch (t2) {
+ case INT:
+ if (tp1 != tp2)
+ intconv(&np1, &np2);
+ break;
+ case FLOAT:
+ SWAP(np1, np2, naux);
+ goto int_float;
+ case PTR: case FTN: case ARY:
+ SWAP(np1, np2, naux);
+ SWAP(t1, t2, taux);
+ goto pointer;
+ default:
+ goto incorrect;
+ }
+ break;
+ case FLOAT:
+ switch (t2) {
+ case FLOAT:
+ if (tp1 != tp2)
+ floatconv(&np1, &np2);
+ break;
+ case INT:
+int_float: np2 = castcode(np2, np1->type);
+ break;
+ default:
+ goto incorrect;
+ }
+ break;
+ case PTR: case FTN: case ARY:
+pointer: tp3 = tp1->type;
+ if (t1 == ARY)
+ tp1 = mktype(tp1->type, PTR, NULL, 0);
+ if (t2 != INT)
+ goto incorrect;
+ np2 = bincode(OMUL, tp1,
+ castcode(np2, tp1),
+ sizeofcode(tp3));
+ break;
+ default:
+ goto incorrect;
+ }
+
+ return bincode(OADD, tp1, np1, np2);
+
+incorrect:
+ error("incorrect arithmetic operands"); /*TODO: print type names */
+}
+
+static Node *
+array(Node *np1, Node *np2)
+{
+ Type *tp;
+ uint8_t t1, t2;
+ char *err;
+
t1 = BTYPE(np1->type);
t2 = BTYPE(np2->type);
-
- if (!isaddr(t1)) {
- taux = t1, t1 = t2, t2 = taux;
- naux = np1, np1 = np2, np2 = naux;
- }
- if (!isaddr(t1))
- error("expected array or pointer");
- if (isptr(t1))
- np1 = ptr2vec(np1);
- if (!isarith(t2))
- error("array subscript is not an integer");
-
- tp = np1->type;
- tp = UNQUAL(tp);
- naux = newnode(OADD, tp);
- naux->left = np1;
- naux->right = int2ptr(np2);
- return naux;
+ if (!isaddr(t1) && !isaddr(t2))
+ goto bad_vector;
+ if (t1 != INT && t2 != INT)
+ goto bad_subs;
+ np1 = add(np1, np2);
+ return unarycode(OARY, np1->type->type , np1);
+
+bad_vector:
+ err = "subscripted value is neither array nor pointer nor vector";
+ goto error;
+bad_subs:
+ err = "array subscript is not an integer";
+error: error(err);
}
-static struct node *
+static Node *
postfix(void)
{
- struct node *np;
+ Node *np1, *np2;
- np = primary();
+ np1 = primary();
for (;;) {
switch (yytoken) {
- case '[': next(); np = ary(np); break;
- default: return np;
+ case '[':
+ next();
+ np2 = expr();
+ np1 = array(np1, np2);
+ expect(']');
+ break;
+ default:
+ return np1;
}
- }
+ }
}
-struct node *
+Node *
expr(void)
{
- register struct node *np;
+ Node *np;
do
np = postfix();
while (yytoken == ',');
-
return np;
}
-
-static void
-evalnode(struct node *np)
-{
- if (!np)
- return;
-
- switch (np->op) {
- case OSYM:
- emitsym(np->u.sym);
- break;
- case OARY:
- evalnode(np->left);
- evalnode(np->right);
- fputs("\t'", stdout);
- break;
- case OPTR:
- evalnode(np->left);
- fputs("\t@", stdout);
- break;
- case OADD:
- evalnode(np->left);
- evalnode(np->right);
- fputs("\t+", stdout);
- break;
- }
-}
-
-void
-eval(struct node *np)
-{
- evalnode(np);
- putchar('\n');
-}
-\ No newline at end of file
diff --git a/lex.c b/lex.c
@@ -6,8 +6,6 @@
#include <ctype.h>
#include "cc.h"
-#include "tokens.h"
-#include "symbol.h"
#include "sizes.h"
static FILE *yyin;
@@ -25,7 +23,7 @@ static char yybuf[IDENTSIZ + 1];
static uint8_t
integer(char *s, char base)
{
- static struct ctype *tp;
+ static Type *tp;
static char ch;
/* TODO: implement again */
@@ -128,7 +126,7 @@ init_keywords(void)
{"while", WHILE, WHILE},
{NULL, 0, 0},
};
- register struct symbol *sym;
+ register Symbol *sym;
for (bp = buff; bp->str; ++bp) {
sym = install(bp->str, NS_KEYWORD);
@@ -142,7 +140,7 @@ iden(void)
{
register char *bp;
register int c;
- struct symbol *sym;
+ Symbol *sym;
for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = c) {
if (!isalnum(c = getc(yyin)) && c != '_')
diff --git a/main.c b/main.c
@@ -3,7 +3,6 @@
#include <stdint.h>
#include "cc.h"
-#include "tokens.h"
extern void extdecl(void), init_keywords(void), open_file(const char *file);
diff --git a/stmt.c b/stmt.c
@@ -1,15 +1,14 @@
+#include <stddef.h>
#include <stdint.h>
-#include "symbol.h"
-#include "tokens.h"
-
+#include "cc.h"
void
compound(void)
{
- extern struct node *expr(void);
extern void decl(void);
+ extern Node *expr(void);
expect('{');
while (!accept('}')) {
@@ -18,8 +17,8 @@ compound(void)
decl();
break;
default:
- eval(expr());
+ emitexp(expr());
}
expect(';');
}
-}
-\ No newline at end of file
+}
diff --git a/symbol.c b/symbol.c
@@ -5,8 +5,6 @@
#include <string.h>
#include "cc.h"
-#include "symbol.h"
-#include "tokens.h"
#define NR_SYM_HASH 32
@@ -14,8 +12,8 @@ uint8_t curctx;
uint8_t namespace = NS_KEYWORD + 1 ;
static struct symtab {
- struct symbol *head;
- struct symbol *htab[NR_SYM_HASH];
+ Symbol *head;
+ Symbol *htab[NR_SYM_HASH];
} symtab [NR_NAMESPACES];
static inline uint8_t
@@ -32,7 +30,7 @@ void
freesyms(uint8_t ns)
{
static struct symtab *tbl;
- register struct symbol *sym;
+ register Symbol *sym;
tbl = &symtab[ns];
for (sym = tbl->head; sym; sym = sym->next) {
@@ -59,12 +57,12 @@ context(void (*fun)(void))
freesyms(NS_TAG);
}
-struct symbol *
+Symbol *
lookup(register char *s, uint8_t ns)
{
extern union yystype yylval;
static struct symtab *tbl;
- register struct symbol *sym;
+ register Symbol *sym;
tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
for (sym = tbl->htab[hash(s)]; sym; sym = sym->hash) {
@@ -76,11 +74,11 @@ lookup(register char *s, uint8_t ns)
return NULL;
}
-struct symbol *
+Symbol *
install(char *s, uint8_t ns)
{
- register struct symbol *sym;
- register struct symbol **t;
+ register Symbol *sym;
+ register Symbol **t;
struct symtab *tbl;
static short id;
diff --git a/symbol.h b/symbol.h
@@ -1,112 +0,0 @@
-
-#ifndef SYMBOL_H
-#define SYMBOL_H
-
-#if ! __bool_true_and_false_are_defined
-#include <stdbool.h>
-#endif
-
-#define CTX_OUTER 0
-#define CTX_FUNC 1
-
-enum {
- NS_IDEN = 0,
- NS_LABEL,
- NS_TAG,
- NR_NAMESPACES,
- NS_KEYWORD,
- NS_FREE
-};
-
-struct funpars;
-struct symbol;
-
-struct ctype {
- uint8_t op; /* type builder operator */
- short size; /* size of variables */
- short nelem; /* number of elements in arrays */
- unsigned defined : 1; /* type defined (is not a forward reference) */
- unsigned cplex : 1; /* complex specifier */
- unsigned imag : 1;
- unsigned sign : 1; /* sign type */
- struct symbol *sym; /* symbol of the tag identifier */
- struct ctype *type; /* base type */
- struct ctype *next; /* next element in the hash */
- union {
- struct funpar *pars; /* function parameters */
- struct field *fields; /* aggregate fields */
- } u;
-};
-
-struct field {
- struct symbol *sym;
- struct field *next;
-};
-
-struct funpar {
- struct ctype *type;
- struct funpar *next;
-};
-
-union value {
- char c;
- int i;
- struct symbol *sym;
- uint8_t ns, token;
- short offset;
-};
-
-struct symbol {
- char *name;
- struct ctype *type;
- short id;
- uint8_t ctx;
- uint8_t token;
- uint8_t ns;
- struct {
- bool isglobal : 1;
- bool isstatic : 1;
- bool isauto : 1;
- bool isregister : 1;
- } s;
- union value u;
- struct symbol *next;
- struct symbol *hash;
-};
-
-extern void freesyms(uint8_t ns);
-
-extern struct ctype *qualifier(struct ctype *tp, uint8_t qlf),
- *ctype(int8_t type, int8_t sign, int8_t size, int8_t cplex),
- *mktype(struct ctype *tp,
- uint8_t op, struct symbol *tag, uint16_t nelem);
-
-extern struct symbol
- *lookup(char *s, unsigned char ns),
- *install(char *s, unsigned char ns);
-
-extern void context(void (*fun)(void));
-
-extern struct ctype *voidtype,
- *uchartype, *chartype,
- *uinttype, *inttype,
- *ushortype, *shortype,
- *longtype, *ulongtype,
- *ullongtype, *llongtype,
- *floattype, *cfloattype, *ifloattype,
- *doubletype, *cdoubletype, *idoubletype,
- *ldoubletype, *cldoubletype,*ildoubletype;
-
-#define ISQUAL(t) (isqual((t)->op))
-#define UNQUAL(t) (ISQUAL(t) ? (t)->type : (t))
-#define BTYPE(t) (UNQUAL(t)->op)
-#define isfun(op) ((op) == FTN)
-#define isptr(op) ((op) == PTR)
-#define isary(op) ((op) == ARY)
-#define isarith(op) ((op) & ARITH)
-#define isaddr(op) ((op) & POINTER)
-#define isrecord(op) ((op) & RECORD)
-#define isqual(op) ((op) & TQUALIFIER)
-
-
-#endif
diff --git a/tokens.h b/tokens.h
@@ -1,79 +0,0 @@
-#ifndef TOKENS_H
-#define TOKENS_H
-
-#if ! __bool_true_false_are_defined
-# include <stdbool.h>
-#endif
-
-#define ARITH 8
-#define RECORD 16
-#define POINTER 32
-#define ATYPE(x) (ARITH | (x))
-#define RTYPE(x) (RECORD | (x))
-#define PTYPE(x) (POINTER| (x))
-
-#define FTN 1
-#define ENUM 2
-#define TYPENAME 3
-#define VOID 4
-
-#define FLOAT ATYPE(1)
-#define INT ATYPE(2)
-#define BOOL ATYPE(3)
-
-#define STRUCT RTYPE(1)
-#define UNION RTYPE(2)
-
-#define PTR PTYPE(1)
-#define ARY PTYPE(2)
-
-#define CHAR (ARY+1)
-#define DOUBLE (ARY+2)
-#define SHORT (ARY+3)
-#define LONG (ARY+4)
-
-#define COMPLEX (ARY+5)
-#define IMAGINARY (ARY+6)
-#define UNSIGNED (ARY+7)
-#define SIGNED (ARY+8)
-
-#define CONST (1<<0)
-#define VOLATILE (1<<1)
-#define RESTRICT (1<<2)
-
-#define TYPEDEF 1
-#define EXTERN 2
-#define STATIC 3
-#define AUTO 4
-#define REGISTER 5
-
-#define accept(t) ((bool) (yytoken == (t) ? next() : 0))
-#define ahead() yyntoken
-
-enum tokens {
- TQUALIFIER = 128, TYPE, IDEN, SCLASS,
- CONSTANT, SIZEOF,
- INDIR, INC, DEC, SHL, SHR,
- LE, GE, EQ, NE, AND, OR,
- MUL_EQ, DIV_EQ, MOD_EQ, ADD_EQ, SUB_EQ, AND_EQ,
- XOR_EQ, OR_EQ, SHL_EQ, SHR_EQ,
- ELLIPSIS,
- CASE, DEFAULT, IF, ELSE, SWITCH, WHILE, DO, FOR, GOTO,
- CONTINUE, BREAK, RETURN, EOFTOK, NOTOK
-};
-
-struct symbol;
-union yystype {
- struct symbol *sym;
- uint8_t token;
-};
-
-extern union yystype yylval;
-extern char yytext[];
-extern uint8_t yytoken, yyntoken;
-
-
-extern uint8_t next(void);
-extern void expect(uint8_t tok);
-
-#endif
diff --git a/types.c b/types.c
@@ -5,106 +5,78 @@
#include "sizes.h"
#include "cc.h"
-#include "tokens.h"
-#include "symbol.h"
#include "machine.h"
#define NR_TYPE_HASH 16
-struct ctype
- *voidtype = &(struct ctype) {
- .op = VOID
+Type
+ *voidtype = &(Type) {
+ .op = VOID,
+ .letter = 'W'
},
- *uchartype = &(struct ctype) {
+ *booltype = &(Type) {
.op = INT,
- .size = CHARSIZE,
+ .letter = 'B'
+ },
+ *uchartype = &(Type) {
+ .op = INT,
+ .letter = 'M',
.sign = 1
},
- *chartype = &(struct ctype) {
+ *chartype = &(Type) {
.op = INT,
- .size = CHARSIZE,
+ .letter = 'C',
},
- *uinttype = &(struct ctype) {
+ *uinttype = &(Type) {
.op = INT,
- .size = INTSIZE,
+ .letter = 'U',
.sign = 1
},
- *inttype = &(struct ctype) {
+ *inttype = &(Type) {
.op = INT,
- .size = INTSIZE,
- .sign = 1
+ .letter = 'I',
},
- *ushortype = &(struct ctype) {
+ *ushortype = &(Type) {
.op = INT,
- .size = SHORTSIZE,
+ .letter = 'E'
},
- *shortype = &(struct ctype) {
+ *shortype = &(Type) {
.op = INT,
- .size = INTSIZE,
+ .letter = 'K',
},
- *longtype = &(struct ctype) {
+ *longtype = &(Type) {
.op = INT,
- .size = LONGSIZE,
+ .letter = 'L'
},
- *ulongtype = &(struct ctype) {
+ *ulongtype = &(Type) {
.op = INT,
- .size = LONGSIZE,
+ .letter = 'Z',
.sign = 1
},
- *ullongtype = &(struct ctype) {
+ *ullongtype = &(Type) {
.op = INT,
- .size = LLONGSIZE,
+ .letter = 'O',
.sign = 1
},
- *llongtype = &(struct ctype) {
+ *llongtype = &(Type) {
.op = INT,
- .size = LLONGSIZE,
- },
- *floattype = &(struct ctype) {
- .op = FLOAT,
- .size = FLOATSIZE
- },
- *cfloattype = &(struct ctype) {
- .op = FLOAT,
- .size = FLOATSIZE,
- .cplex = 1
- },
- *ifloattype = &(struct ctype) {
- .op = FLOAT,
- .size = FLOATSIZE,
- .imag = 1
- },
- *doubletype = &(struct ctype) {
- .op = FLOAT,
- .size = FLOATSIZE
- },
- *cdoubletype = &(struct ctype) {
- .op = FLOAT,
- .size = 0,
- .cplex = 1
- },
- *idoubletype = &(struct ctype) {
- .op = FLOAT,
- .size = 0,
- .imag = 1
+ .letter = 'G',
},
- *ldoubletype = &(struct ctype) {
+ *floattype = &(Type) {
.op = FLOAT,
- .size = LLFLOATSIZE
+ .letter = 'F'
},
- *cldoubletype = &(struct ctype) {
+ *doubletype = &(Type) {
.op = FLOAT,
- .size = 0,
- .cplex = 1
+ .letter = 'D'
},
- *ildoubletype = &(struct ctype) {
+ *ldoubletype = &(Type) {
.op = FLOAT,
- .size = 0,
- .imag = 1
+ .letter = 'H'
};
-struct ctype *
-ctype(int8_t type, int8_t sign, int8_t size, int8_t cplex)
+Type *
+ctype(int8_t type, int8_t sign, int8_t size)
{
if (type == CHAR && !sign)
sign = options.charsign;
@@ -115,6 +87,7 @@ ctype(int8_t type, int8_t sign, int8_t size, int8_t cplex)
switch (type) {
case VOID: return voidtype;
+ case BOOL: return booltype;
case CHAR: return (sign) ? uchartype : chartype;
case INT: switch (size) {
case 0: return (sign) ? uinttype : inttype;
@@ -123,33 +96,21 @@ ctype(int8_t type, int8_t sign, int8_t size, int8_t cplex)
case LONG+LONG: return (sign) ? ullongtype : llongtype;
}
case FLOAT: switch (size) {
- case 0: switch (cplex) {
- case 0: return floattype;
- case COMPLEX: return cfloattype;
- case IMAGINARY: return ifloattype;
- }
- case LONG: switch (cplex) {
- case 0: return doubletype;
- case COMPLEX: return cdoubletype;
- case IMAGINARY: return ifloattype;
- }
- case LONG+LONG: switch (cplex) {
- case 0: return ldoubletype;
- case COMPLEX: return cldoubletype;
- case IMAGINARY: return ildoubletype;
- }
+ case 0: return floattype;
+ case LONG: return doubletype;
+ case LONG+LONG: return ldoubletype;
}
}
}
-struct ctype *
-mktype(struct ctype *tp, uint8_t op,
- struct symbol *sym, uint16_t nelem)
+Type *
+mktype(Type *tp, uint8_t op,
+ Symbol *sym, uint16_t nelem)
{
- static struct ctype *typetab[NR_TYPE_HASH], **tbl;
+ static Type *typetab[NR_TYPE_HASH], **tbl;
static uint8_t t;
- static unsigned short size;
- register struct ctype *bp;
+ register Type *bp;
+ char letter;
t = (op ^ (uint8_t) ((unsigned short) tp >> 3))
& NR_TYPE_HASH-1;
@@ -164,12 +125,12 @@ mktype(struct ctype *tp, uint8_t op,
}
switch (op) {
- case PTR: size = PTRSIZE; break;
- case FTN: size = 0; break;
- case ARY: size = tp->size * nelem; break;
- case ENUM: size = INTSIZE;
- case STRUCT: size = 0; break;
- default: size = tp->size; break;
+ case PTR: letter = 'R'; break;
+ case FTN: letter = 'F'; break;
+ case ARY: letter = 'V'; break;
+ case ENUM: letter = 'E'; break;
+ case STRUCT: letter = 'S'; break;
+ default: abort();
}
bp = xmalloc(sizeof(*bp));
bp->next = *tbl;
@@ -177,12 +138,12 @@ mktype(struct ctype *tp, uint8_t op,
bp->op = op;
bp->nelem = nelem;
bp->sym = sym;
- bp->size = size;
+ bp->letter = letter;
return *tbl = bp;
}
-struct ctype *
-qualifier(struct ctype *tp, uint8_t qlf)
+Type *
+qualifier(Type *tp, uint8_t qlf)
{
uint8_t q = tp->op;
@@ -195,60 +156,3 @@ qualifier(struct ctype *tp, uint8_t qlf)
return mktype(tp, qlf|TQUALIFIER, NULL, 0);
}
-#include <stdio.h>
-
-static void
-ptype(struct ctype *tp)
-{
- uint8_t op;
- struct funpar *fp;
-
- if (!tp)
- return;
- op = tp->op;
- if (op & TQUALIFIER) {
- if (op & CONST)
- fputs("const ", stdout);
- if (op & VOLATILE)
- fputs("volatile ", stdout);
- if (op & RESTRICT)
- fputs("restrict ", stdout);
- } else {
- switch (op) {
- case PTR: fputs("pointer ", stdout); break;
- case ARY: fputs("array ", stdout); break;
- case STRUCT: fputs("struct", stdout); break;
- case UNION: fputs("union", stdout); break;
- case ENUM: fputs("enum", stdout); break;
- case BOOL: fputs("bool", stdout); break;
- case INT:
- printf("int size=%u sign=%u", tp->size, tp->sign);
- break;
- case FLOAT:
- printf("float size=%u cplex=%u", tp->size, tp->cplex);
- break;
- case TYPENAME:
- printf("typename %s type ", tp->sym->name);
- break;
- case FTN:
- fputs("function(", stdout);
- for (fp = tp->u.pars; fp; fp = fp->next) {
- ptype(tp);
- if (fp->next)
- fputs(", ", stdout);
- }
- fputs(") ", stdout);
- break;
- }
- }
- ptype(tp->type);
-}
-
-void
-printtype(struct ctype *tp)
-{
- printf("type = %p ", tp);
- ptype(tp);
- putchar('\n');
-}
-
diff --git a/wrapper.c b/wrapper.c
@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
+
#include "cc.h"