shithub: scc

Download patch

ref: e0b2f47525a1dc50a5089d2f472f1b51fbb0b483
parent: 87f8ea372e925ddb1ab531130bfd3e989e73c5b5
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Apr 25 06:33:28 EDT 2014

Create directory cc1

We are going to begin with the backend of the compiler
so it is a good idea to have two different directories.

--- a/.gitignore
+++ /dev/null
@@ -1,4 +1,0 @@
-*.o
-makefile
-cc1
-TODO
--- a/Makefile
+++ /dev/null
@@ -1,21 +1,0 @@
-
-OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
-	wrapper.o code.o stmt.o
-
-
-all: cc1
-
-$(OBJS) : cc1.h
-
-cc1: $(OBJS)
-	$(CC) $(LDFLAGS) $(CFLAGS) $(LIBS) $(OBJS) -o $@
-
-clean:
-	rm -f $(OBJS)
-	rm -f cc1
-
-distclean: clean
-	rm -f *~
-	rm -f tags
-	rm -f cscope.*
-	rm -f makefile
--- a/cc1.h
+++ /dev/null
@@ -1,259 +1,0 @@
-#ifndef CC_H
-#define CC_H
-
-#ifndef __bool_true_and_false_defined
-#include <stdbool.h>
-#endif
-
-
-struct user_opt {
-	unsigned char implicit;
-	unsigned char mixdcls;
-	unsigned char npromote;
-	unsigned char useless;
-	unsigned char charsign;
-	unsigned char pcompare;
-};
-
-extern  struct user_opt options;
-
-extern void error(const char *fmt, ...);
-extern void die(const char *fmt, ...);
-extern void warn(signed char flag, const char *fmt, ...);
-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_FREE
-};
-
-struct funpars;
-struct symbol;
-
-#define RANK_BOOL    0
-#define RANK_SCHAR   1
-#define RANK_UCHAR   2
-#define RANK_SHORT   3
-#define RANK_USHORT  4
-#define RANK_INT     5
-#define RANK_UINT    6
-#define RANK_LONG    7
-#define RANK_ULONG   8
-#define RANK_LLONG   9
-#define RANK_ULLONG  10
-#define RANK_FLOAT   11
-#define RANK_DOUBLE  12
-#define RANK_LDOUBLE 13
-
-struct ctype {
-	uint8_t op;           /* type builder operator */
-	char letter;          /* letter of the type */
-	bool defined : 1; /* type defined (is not a forward reference) */
-	bool 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 {
-		unsigned char rank;   /* convertion rank */
-		short nelem;          /* number of elements in arrays */
-		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 */
-
-
-
-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;
-		bool isdefined : 1;
-	} s;
-	union {
-		int i;
-		char *s;
-		struct symbol *sym;
-		uint8_t ns, token;
-	} 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);
-
-typedef struct caselist Caselist;
-typedef void Ctxfun(Symbol *, Symbol *, Caselist *);
-
-extern Ctxfun compound;
-extern void context(Ctxfun *fun,
-                    Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
-
-extern Type *typename(void);
-
-extern Type *voidtype, *pvoidtype, *booltype,
-	*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 isqual(op)   ((op) & TQUALIFIER)
-#define isconst(op) (((op) & (TQUALIFIER|CONST)) == \
-                                     (TQUALIFIER|CONST))
-
-
-enum {
-	FTN = 1, ENUM, TYPENAME, VOID, FLOAT, INT, BOOL,
-	STRUCT, UNION, PTR, ARY, CHAR, DOUBLE, SHORT,
-	LONG, COMPLEX, UNSIGNED, SIGNED
-};
-
-#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, STRING,
-	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;
-	Type *utype;
-	uint8_t typeop;
-	struct {
-		bool lvalue : 1;
-		bool symbol: 1;
-		bool constant : 1;
-	} b;
-	union unode {
-		Symbol *sym;
-		Type *type;
-		char op;
-	} u;
-	struct node *childs[];
-} Node;
-
-enum {
-	OCAST = 1, OPTR, OADD, OARY, OSIZE, OMUL, OSUB,
-	OINC, ODEC, ODIV, OMOD, OSHL, OSHR,
-	OBAND, OBXOR, OBOR, OASSIGN, OA_MUL, OA_DIV,
-	OA_MOD, OA_ADD, OA_SUB, OA_SHL, OA_SHR,
-	OA_AND, OA_XOR, OA_OR, OADDR,ONEG, OCPL, OEXC,
-	OCOMMA,
-	/*
-	  * Complementary relational operators only differ in less
-	 * significant bit
-	 */
-	OEQ = 0x40, ONE, OLT, OGE, OLE, OGT, OAND, OOR
-};
-
-extern void
-	emitdcl(Symbol *), emitsframe(Symbol *), emiteframe(Symbol *),
-	emitsym(Node *), emitunary(Node *),
-	emitbin(Node *), emitexp(Node *),
-	emitprint(Node *), emitlabel(Symbol *), emitjump(Symbol *, Node *),
-	emitbloop(void), emiteloop(void),
-	emitswitch(short, Node *), emitcase(Symbol *, Node *),
-	emitdefault(Symbol *);
-
-extern Node
-	*node(void (*code)(Node *),
-	      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), 
-	*ternarycode(Node *cond, Node *ifyes, Node *ifno),
-	*symcode(Symbol *sym);
-
-#define SYM(s) ((union unode) {.sym = s})
-#define OP(s) ((union unode) {.op = s})
-#define TYP(s) ((union unode) {.type = s})
-#define NEGATE(n, v) ((n)->u.op ^= (v))
-/* TODO: remove some of these ugly macros */
-#define ISNODEBIN(n) ((n)->code == emitbin)
-#define ISNODECMP(n) (ISNODEBIN(n) && (n)->u.op & 0x40)
-
-extern Node *expr(void);
-extern void extdecl(void), decl(void);
-
-#endif
--- /dev/null
+++ b/cc1/.gitignore
@@ -1,0 +1,4 @@
+*.o
+makefile
+cc1
+TODO
--- /dev/null
+++ b/cc1/Makefile
@@ -1,0 +1,22 @@
+
+OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
+	wrapper.o code.o stmt.o
+
+CFLAGS += -fno-diagnostics-show-caret -g
+
+all: cc1
+
+$(OBJS) : cc1.h
+
+cc1: $(OBJS)
+	$(CC) $(LDFLAGS) $(CFLAGS) $(LIBS) $(OBJS) -o $@
+
+clean:
+	rm -f $(OBJS)
+	rm -f cc1
+
+distclean: clean
+	rm -f *~
+	rm -f tags
+	rm -f cscope.*
+	rm -f makefile
--- /dev/null
+++ b/cc1/cc1.h
@@ -1,0 +1,259 @@
+#ifndef CC_H
+#define CC_H
+
+#ifndef __bool_true_and_false_defined
+#include <stdbool.h>
+#endif
+
+
+struct user_opt {
+	unsigned char implicit;
+	unsigned char mixdcls;
+	unsigned char npromote;
+	unsigned char useless;
+	unsigned char charsign;
+	unsigned char pcompare;
+};
+
+extern  struct user_opt options;
+
+extern void error(const char *fmt, ...);
+extern void die(const char *fmt, ...);
+extern void warn(signed char flag, const char *fmt, ...);
+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_FREE
+};
+
+struct funpars;
+struct symbol;
+
+#define RANK_BOOL    0
+#define RANK_SCHAR   1
+#define RANK_UCHAR   2
+#define RANK_SHORT   3
+#define RANK_USHORT  4
+#define RANK_INT     5
+#define RANK_UINT    6
+#define RANK_LONG    7
+#define RANK_ULONG   8
+#define RANK_LLONG   9
+#define RANK_ULLONG  10
+#define RANK_FLOAT   11
+#define RANK_DOUBLE  12
+#define RANK_LDOUBLE 13
+
+struct ctype {
+	uint8_t op;           /* type builder operator */
+	char letter;          /* letter of the type */
+	bool defined : 1; /* type defined (is not a forward reference) */
+	bool 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 {
+		unsigned char rank;   /* convertion rank */
+		short nelem;          /* number of elements in arrays */
+		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 */
+
+
+
+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;
+		bool isdefined : 1;
+	} s;
+	union {
+		int i;
+		char *s;
+		struct symbol *sym;
+		uint8_t ns, token;
+	} 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);
+
+typedef struct caselist Caselist;
+typedef void Ctxfun(Symbol *, Symbol *, Caselist *);
+
+extern Ctxfun compound;
+extern void context(Ctxfun *fun,
+                    Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
+
+extern Type *typename(void);
+
+extern Type *voidtype, *pvoidtype, *booltype,
+	*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 isqual(op)   ((op) & TQUALIFIER)
+#define isconst(op) (((op) & (TQUALIFIER|CONST)) == \
+                                     (TQUALIFIER|CONST))
+
+
+enum {
+	FTN = 1, ENUM, TYPENAME, VOID, FLOAT, INT, BOOL,
+	STRUCT, UNION, PTR, ARY, CHAR, DOUBLE, SHORT,
+	LONG, COMPLEX, UNSIGNED, SIGNED
+};
+
+#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, STRING,
+	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;
+	Type *utype;
+	uint8_t typeop;
+	struct {
+		bool lvalue : 1;
+		bool symbol: 1;
+		bool constant : 1;
+	} b;
+	union unode {
+		Symbol *sym;
+		Type *type;
+		char op;
+	} u;
+	struct node *childs[];
+} Node;
+
+enum {
+	OCAST = 1, OPTR, OADD, OARY, OSIZE, OMUL, OSUB,
+	OINC, ODEC, ODIV, OMOD, OSHL, OSHR,
+	OBAND, OBXOR, OBOR, OASSIGN, OA_MUL, OA_DIV,
+	OA_MOD, OA_ADD, OA_SUB, OA_SHL, OA_SHR,
+	OA_AND, OA_XOR, OA_OR, OADDR,ONEG, OCPL, OEXC,
+	OCOMMA,
+	/*
+	  * Complementary relational operators only differ in less
+	 * significant bit
+	 */
+	OEQ = 0x40, ONE, OLT, OGE, OLE, OGT, OAND, OOR
+};
+
+extern void
+	emitdcl(Symbol *), emitsframe(Symbol *), emiteframe(Symbol *),
+	emitsym(Node *), emitunary(Node *),
+	emitbin(Node *), emitexp(Node *),
+	emitprint(Node *), emitlabel(Symbol *), emitjump(Symbol *, Node *),
+	emitbloop(void), emiteloop(void),
+	emitswitch(short, Node *), emitcase(Symbol *, Node *),
+	emitdefault(Symbol *);
+
+extern Node
+	*node(void (*code)(Node *),
+	      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), 
+	*ternarycode(Node *cond, Node *ifyes, Node *ifno),
+	*symcode(Symbol *sym);
+
+#define SYM(s) ((union unode) {.sym = s})
+#define OP(s) ((union unode) {.op = s})
+#define TYP(s) ((union unode) {.type = s})
+#define NEGATE(n, v) ((n)->u.op ^= (v))
+/* TODO: remove some of these ugly macros */
+#define ISNODEBIN(n) ((n)->code == emitbin)
+#define ISNODECMP(n) (ISNODEBIN(n) && (n)->u.op & 0x40)
+
+extern Node *expr(void);
+extern void extdecl(void), decl(void);
+
+#endif
--- /dev/null
+++ b/cc1/code.c
@@ -1,0 +1,313 @@
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "cc1.h"
+
+char *opcodes[] = {
+	[OADD] = "+",
+	[OSUB] = "-",
+	[OMUL] = "*",
+	[OARY] = "'",
+	[OINC] = ";+",
+	[ODEC] =  ";=",
+	[OSIZE] = "#",
+	[OPTR] = "@",
+	[OMOD] = "*",
+	[ODIV] = "/",
+	[OSHL] = "l",
+	[OSHR]  = "r",
+	[OLT] = "<",
+	[OGT] = ">",
+	[OGE] = "]",
+	[OLE] =  "[",
+	[OEQ] = "=",
+	[ONE] = "!",
+	[OBAND] = "&",
+	[OBXOR]  = "^",
+	[OBOR] = "|",
+	[OASSIGN] = ":",
+	[OA_MUL] = ":*",
+	[OA_DIV] = ":/",
+	[OA_MOD] = ":%",
+	[OA_ADD] = ":+",
+	[OA_SUB] = ":-",
+	[OA_SHL] = ":l",
+	[OA_SHR] = ":r",
+	[OA_AND] = ":&",
+	[OA_XOR] = ":^",
+	[OA_OR] = ":|",
+	[OADDR] = "a",
+	[ONEG] = "_",
+	[OCPL] = "~",
+	[OAND] = "m",
+	[OOR] = "s",
+	[OCOMMA] = ","
+};
+
+Node *
+node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds)
+{
+	Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));
+
+	np->code = code;
+	np->type = tp;
+	np->utype = UNQUAL(tp);
+	np->typeop = np->utype->op;
+	np->u = u;
+	np->b.symbol = np->b.lvalue = 0;
+
+	return np;
+}
+
+static void
+emitsym2(Symbol *sym)
+{
+	char c;
+
+	if (sym->s.isglobal)
+		c = 'G';
+	else if (sym->s.isstatic)
+		c = 'T';
+	else if (sym->s.isregister)
+		c = 'Q';
+	else
+		c = 'A';
+	printf("%c%d", c, sym->id);
+}
+
+static void
+emitconst(Node *np)
+{
+	register char *bp, c;
+	Symbol *sym = np->u.sym;
+
+	if (np->type == inttype) {
+		printf("#%x", sym->u.i);
+	} else {
+		putchar('"');
+		for (bp = sym->u.s; c = *bp; ++bp)
+			printf("%02x", (unsigned) c);
+	}
+}
+
+void
+emitsym(Node *np)
+{
+	putchar('\t');
+	(np->b.constant) ? emitconst(np) : emitsym2(np->u.sym);
+}
+
+static void
+emittype(Type *tp)
+{
+	putchar(tp->letter);
+}
+
+void
+emitdcl(Symbol *sym)
+{
+	emitsym2(sym);
+	putchar('\t');
+	emittype(sym->type);
+	putchar('\n');
+}
+
+void
+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
+emitternary(Node *np)
+{
+	Node *cond, *ifyes, *ifno;
+
+	cond = np->childs[0];
+	ifyes = np->childs[1];
+	ifno = np->childs[2];
+	(*cond->code)(cond);
+	(*ifyes->code)(ifyes);
+	(*ifno->code)(ifno);
+	printf("\t?%c", np->type->letter);
+}
+
+void
+emitsizeof(Node *np)
+{
+	printf("\t#%c", np->u.type->letter);
+}
+
+void
+emitexp(Node *np)
+{
+	if (np)
+		(*np->code)(np);
+	putchar('\n');
+}
+
+void
+emitprint(Node *np)
+{
+	(*np->code)(np);
+	printf("\tk%c\n", np->type->letter);
+}
+
+void
+emitfun(Symbol *sym)
+{
+	printf("%c%d\tn%s\n",
+	       sym->s.isglobal ? 'X' : 'Y', sym->id, sym->name);
+}
+
+void
+emitsframe(Symbol *sym)
+{
+	puts("{");
+}
+
+void
+emiteframe(Symbol *sym)
+{
+	puts("}");
+}
+
+void
+emitret(Type *tp)
+{
+	fputs("\ty", stdout);
+	emittype(tp);
+}
+
+void
+emitlabel(Symbol *sym)
+{
+	printf("L%d\n", sym->id);
+}
+
+void
+emitbloop(void)
+{
+	puts("\td");
+}
+
+void
+emiteloop(void)
+{
+	puts("\tb");
+}
+
+void
+emitjump(Symbol *sym, Node *np)
+{
+	printf("\tj\tL%d", sym->id);
+	if (!np)
+		putchar('\n');
+	else
+		emitexp(np);
+}
+
+void
+emitswitch(short nr, Node *np)
+{
+	printf("\teI\t#%0x", nr);
+	emitexp(np);
+}
+
+void
+emitcase(Symbol *sym, Node *np)
+{
+	fputs("\tw\t", stdout);
+	printf("L%d", sym->id);
+	emitexp(np);
+}
+
+void
+emitdefault(Symbol *sym)
+{
+	fputs("\tf\t", stdout);
+	emitlabel(sym);
+}
+
+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)
+{
+	if (!tp->defined)
+		error("invalid use of indefined type");
+	return node(emitsizeof, inttype, TYP(tp), 0);
+}
+
+Node *
+ternarycode(Node *cond, Node *ifyes, Node *ifno)
+{
+	Node *np= node(emitternary, ifyes->type, OP(0), 3);
+	np->childs[0] = cond;
+	np->childs[1] = ifyes;
+	np->childs[2] = ifno;
+	return np;
+}
+
+Node *
+symcode(Symbol *sym)
+{
+	Node *np;
+
+	np = node(emitsym, sym->type, SYM(sym), 0);
+	np->b.symbol = 1;
+	np->b.constant = 1;
+	return np;
+}
--- /dev/null
+++ b/cc1/decl.c
@@ -1,0 +1,536 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "sizes.h"
+#include "cc1.h"
+
+#define ID_EXPECTED     1
+#define ID_ACCEPTED     2
+
+int8_t forbid_eof;
+
+struct dcldata {
+	uint8_t op;
+	union {
+		unsigned short nelem;
+		Symbol *sym;
+		struct funpars *pars;
+		uint8_t qlf;
+	} u;
+};
+
+static struct dcldata
+	*declarator0(struct dcldata *dp, uint8_t ns, int8_t flags);
+
+static struct dcldata *
+arydcl(struct dcldata *dp)
+{
+	expect('[');
+	expect(']');
+	if (dp->op == 255)
+		error("too much declarators");
+	dp->u.nelem = 0;
+	dp->op = ARY;
+	return dp + 1;
+}
+
+static struct dcldata *
+fundcl(struct dcldata *dp)
+{
+	expect('(');
+	expect(')');;
+	if (dp->op == 255)
+		error("too much declarators");
+	dp->op = FTN;
+	dp->u.pars = NULL;
+	return dp + 1;
+}
+
+static Symbol *
+newiden(uint8_t ns)
+{
+	Symbol *sym;
+	extern uint8_t curctx;
+
+	if (yylval.sym && yylval.sym->ctx == curctx)
+		error("redeclaration of '%s'", yytext);
+	sym = install(yytext, ns);
+	next();
+	return sym;
+}
+
+static struct dcldata *
+directdcl(struct dcldata *dp, uint8_t ns, int8_t flags)
+{
+	register Symbol *sym;
+	char *err;
+
+	if (accept('(')) {
+		dp = declarator0(dp, ns, flags);
+		expect(')');
+	} else if (flags) {
+		if (yytoken != IDEN) {
+			if (flags & ID_EXPECTED)
+				goto expected;
+			sym = install("", ns);
+		} else {
+			sym = newiden(ns);
+		}
+		dp->op = IDEN;
+		dp->u.sym = sym;
+		++dp;
+	}
+
+	for (;;) {
+		switch (yytoken) {
+		case '(':  dp = fundcl(dp); break;
+		case '[':  dp = arydcl(dp); break;
+		default:   return dp;
+		}
+	}
+
+expected:
+	error("expected '(' or identifier before of '%s'" , yytext);
+}
+
+static struct dcldata*
+declarator0(struct dcldata *dp, uint8_t ns, int8_t flags)
+{
+	uint8_t buffer[NR_DECLARATORS];
+	register uint8_t *bp, n, qlf;
+
+	bp = buffer;
+	for (n = 0; accept('*'); ++n) {
+		if (n == NR_DECLARATORS)
+			goto too_much_declarators;
+		qlf = 0;
+		if (yytoken == TQUALIFIER) {
+			qlf |= yylval.token;
+			next();
+		}
+		*bp++ = qlf;
+	}
+
+	dp = directdcl(dp, ns, flags);
+
+	bp = buffer;
+	while (n--) {
+		if (dp->op == 255)
+			goto too_much_declarators;
+		dp->op = PTR;
+		dp->u.qlf = *bp++;
+		++dp;
+	}
+
+	return dp;
+
+too_much_declarators:
+	error("too much declarators");
+}
+
+static Symbol *
+declarator(Type *tp, uint8_t ns, int8_t flags)
+{
+	struct dcldata data[NR_DECLARATORS+1];
+	register struct dcldata *bp;
+	Symbol *sym = NULL;
+	static Symbol dummy;
+
+	memset(data, 0, sizeof(data));
+	data[NR_DECLARATORS].op = 255;
+	for (bp = declarator0(data, ns, flags); bp >= data; --bp) {
+		switch (bp->op) {
+		case PTR:
+			tp = qualifier(mktype(tp, PTR, NULL, 0), bp->u.qlf);
+			break;
+		case ARY:
+			tp = mktype(tp, ARY, NULL, bp->u.nelem);
+			break;
+		case FTN:
+			tp = mktype(tp, FTN, NULL, 0);
+			break;
+		case IDEN:
+			sym = bp->u.sym;
+			break;
+		}
+	}
+	if (!sym)
+		sym = &dummy;
+	sym->type = tp;
+	return sym;
+}
+
+static Type *structdcl(void), *enumdcl(void);
+
+static Type *
+specifier(int8_t *sclass)
+{
+	Type *tp = NULL;
+	int8_t qlf, sign, type, cls, size, t;
+
+	qlf = sign = type = cls = size = 0;
+
+	for (;;) {
+		register uint8_t *p;
+		Type *(*dcl)(void) = NULL;
+
+		switch (yytoken) {
+		case SCLASS: p = &cls; break;
+		case TQUALIFIER:
+			if ((qlf |= yylval.token) & RESTRICT)
+				goto invalid_type;
+			next();
+			continue;
+		case TYPE:
+			switch (yylval.token) {
+			case ENUM:
+				dcl = enumdcl; p = &type; break;
+			case STRUCT: case UNION:
+				dcl = structdcl; p = &type; break;
+			case TYPENAME:
+				tp = yylval.sym->type;
+			case VOID:   case BOOL:  case CHAR:
+			case INT:    case FLOAT: case DOUBLE:
+				p = &type; break;
+			case SIGNED: case UNSIGNED:
+				p = &sign; break;
+			case LONG:
+				if (size == LONG) {
+					size = LONG+LONG;
+					break;
+				}
+			case SHORT:
+				p = &size; break;
+			}
+			break;
+		default:
+			goto check_types;
+		}
+		if (*p)
+			goto invalid_type;
+		*p = yylval.token;
+		if (dcl)
+			tp = dcl();
+		else
+			next();
+	}
+
+check_types:
+	if (!type) {
+		if (!sign && !size) {
+			warn(options.implicit,
+			     "type defaults to 'int' in declaration");
+		}
+		type = INT;
+	}
+	if (sign && type != INT && type != CHAR ||
+	    size == SHORT && type != INT ||
+	    size == LONG  && type != INT && type != DOUBLE ||
+	    size == LONG+LONG && type != INT) {
+		goto invalid_type;
+	}
+	if (sclass)
+		*sclass = cls;
+	if (!tp)
+		tp = ctype(type, sign, size);
+	return (qlf) ? qualifier(tp, qlf) : tp;
+
+invalid_type:
+	error("invalid type specification");
+}
+
+static struct node *
+initializer(register Type *tp)
+{
+	if (accept('{')) {
+		initializer(tp);
+		expect('}');
+	} else {
+		do {
+			expr();
+		} while (accept(','));
+	}
+}
+
+/* TODO: bitfields */
+
+static void
+newfield(Type *tp, Symbol *sym)
+{
+	register struct field *p, *q;
+	register char *s, *t;
+	static uint8_t op;
+	static char *err;
+
+	s = sym->name;
+	op = tp->op;
+	for (q = p = tp->u.fields; p; q = p, p = p->next) {
+		t = p->sym->name;
+		if (*s == *t && !strcmp(s, t))
+			goto duplicated_name;
+		if (op == ENUM && sym->u.i == p->sym->u.i)
+			goto duplicated_value;
+	}
+
+	p = xmalloc(sizeof(*p));
+	p->next = NULL;
+	p->sym = sym;
+	if (!q)
+		tp->u.fields = p;
+	else
+		q->next = p;
+
+	return;
+
+duplicated_name:
+	err = "duplicated fields '%s' and '%s'";
+	goto error;
+duplicated_value:
+	err = "duplicated enumeration fields '%s' and '%s'";
+error:
+	error(err, s, t);
+}
+
+static void
+fielddcl(Type *base, uint8_t ns)
+{
+	Type *tp;
+	Symbol *sym;
+	char *err;
+
+	switch (yytoken) {
+	case SCLASS:
+		goto bad_storage;
+	case IDEN: case TYPE: case TQUALIFIER:
+		tp = specifier(NULL);
+	case ';':
+		break;
+	default:
+		goto dcl_expected;
+	}
+
+	if (yytoken != ';') {
+		do {
+			sym = declarator(tp, ns, ID_EXPECTED);
+			newfield(tp, sym);
+		} while (accept(','));
+	}
+
+	expect(';');
+	return;
+
+bad_storage:
+	err = "storage class '%s' in struct/union field";
+	goto error;
+dcl_expected:
+	err = "declaration expected";
+error:
+	error(err, yytext);
+}
+
+static Type *
+newtag(uint8_t tag)
+{
+	register Symbol *sym;
+	Type *tp;
+	extern uint8_t namespace;
+
+	if (yytoken == IDEN) {
+		sym = lookup(yytext, NS_TAG);
+		if (sym) {
+			if (sym->type->op != tag)
+				goto bad_tag;
+		} else {
+			sym = install(yytext, NS_TAG);
+		}
+		next();
+	} else {
+		sym = install("", NS_TAG);
+	}
+	tp = sym->type = mktype(NULL, tag, NULL, 0);
+	sym->u.ns = ++namespace;
+	tp->sym = sym;
+	return tp;
+
+bad_tag:
+	error("'%s' defined as wrong kind of tag", yytext);
+}
+
+static Type *
+structdcl(void)
+{
+	Type *tp;
+	uint8_t ns, tag;
+
+	tag = yylval.token;
+	next();
+	tp = newtag(tag);
+	tp->u.fields = NULL;
+	ns = tp->sym->u.ns;
+	if (accept('{')) {
+		if (tp->defined)
+			goto redefined;
+		tp->defined = 1;
+		while (!accept('}'))
+			 fielddcl(tp, ns);
+	}
+
+	return tp;
+
+redefined:
+	error("redefinition of struct/union '%s'", yytext);
+}
+
+static Type *
+enumdcl(void)
+{
+	register Type *tp;
+	Symbol *sym;
+	int val = 0;
+	char *err;
+
+	next();
+	tp = newtag(ENUM);
+	if (yytoken != ';') {
+		expect('{');
+		if (tp->defined)
+			goto redefined;
+		tp->defined = 1;
+		while (yytoken != '}') {
+			if (yytoken != IDEN)
+				goto iden_expected;
+			sym = newiden(NS_IDEN);
+			sym->type = inttype;
+			if (accept('='))
+				initializer(inttype);
+			sym->u.i = val++;
+			newfield(tp, sym);
+			if (!accept(','))
+				break;
+		}
+		expect('}');
+	}
+
+	return tp;
+
+redefined:
+	err = "redefinition of enumeration '%s'";
+	goto error;
+iden_expected:
+	err = "identifier expected";
+error:
+	error(err, yytext);
+}
+
+void
+decl(void)
+{
+	Type *tp;
+	Symbol *sym;
+	int8_t sclass;
+
+	tp = specifier(&sclass);
+	if (yytoken != ';') {
+		do {
+			 sym = declarator(tp, NS_IDEN, ID_EXPECTED);
+			switch (sclass) {
+			case REGISTER: sym->s.isregister = 1; break;
+			case STATIC: sym->s.isstatic = 1; break;
+			case EXTERN: /* TODO: */; break;
+			case TYPEDEF: /* TODO: */;break;
+			case AUTO: default: sym->s.isauto = 1;
+			}
+			if (accept('='))
+				initializer(sym->type); /* TODO: emit initializer */
+			emitdcl(sym);
+		} while (accept(','));
+	}
+	expect(';');
+}
+
+Type *
+typename(void)
+{
+	uint8_t sclass;
+	Type *tp;
+	Symbol *sym;
+
+	tp = specifier(&sclass);
+	if (sclass)
+		error("class storage in type name");
+	sym = declarator(tp, NS_IDEN, 0);
+	return  sym->type;
+}
+
+void
+extdecl(void)
+{
+	Type *base;
+	int8_t sclass;
+	Symbol *sym;
+	char *err;
+
+	forbid_eof = 0; /* TODO: Fix when find EOF */
+
+	switch (yytoken) {
+	case IDEN: case TYPE: case SCLASS: case TQUALIFIER:
+		base = specifier(&sclass);
+		if (sclass == REGISTER || sclass == AUTO)
+			goto bad_storage;
+	case ';':
+		break;
+	case '@':
+		next();
+		emitprint(expr());
+		goto semicolon;
+	default:
+		goto dcl_expected;
+	}
+
+	if (yytoken != ';') {
+		do {
+			Type *tp;
+
+			sym = declarator(base, NS_IDEN, ID_EXPECTED);
+			tp = sym->type;
+
+			if (!(sclass & STATIC))
+				sym->s.isglobal = 1;
+			if (BTYPE(tp) == FTN) {
+				if (yytoken == '{') {
+					extern Symbol *curfun;
+
+					curfun = sym;
+					emitfun(sym);
+					emitsframe(sym);
+					context(compound, NULL, NULL, NULL);
+					emiteframe(sym); /* FIX: sym is not used */
+					freesyms(NS_LABEL);
+					return;
+				}
+			} else {
+				sym->s.isstatic = 1;
+				if (sclass & EXTERN)
+					; /* TODO: handle extern */
+				else if (accept('='))
+					initializer(tp);
+				emitdcl(sym);
+
+			}
+		} while (accept(','));
+	}
+
+semicolon:
+	expect(';');
+	return;
+
+bad_storage:
+	err = "incorrect storage class for file-scope declaration";
+	goto error;
+dcl_expected:
+	err = "declaration expected";
+error:
+	error(err);
+}
--- /dev/null
+++ b/cc1/error.c
@@ -1,0 +1,52 @@
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "cc1.h"
+
+extern unsigned linenum;
+extern unsigned columnum;
+extern const char *filename;
+
+static void
+warn_helper(signed char flag, const char *fmt, va_list va)
+{
+	if (!flag)
+		return;
+	fprintf(stderr, "%s:%s:%u: ",
+		(!flag) ? "warning" : "error", filename, linenum);
+	vfprintf(stderr, fmt, va);
+	putc('\n', stderr);
+	if (flag < 0)
+		exit(EXIT_FAILURE); /* TODO: uhmmmm */
+}
+
+void
+warn(signed char flag, const char *fmt, ...)
+{
+	va_list va;
+	va_start(va, fmt);
+	warn_helper(flag, fmt, va);
+	va_end(va);
+}
+
+void
+error(const char *fmt, ...)
+{
+	va_list va;
+	va_start(va, fmt);
+	warn_helper(-1, fmt, va);
+	va_end(va);
+}
+
+void
+die(const char *fmt, ...)
+{
+	va_list va;
+	va_start(va, fmt);
+	fprintf(stderr, fmt, va);
+	va_end(va);
+	exit(EXIT_FAILURE);
+}
--- /dev/null
+++ b/cc1/expr.c
@@ -1,0 +1,758 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include "cc1.h"
+
+static Symbol *zero, *one;
+
+Node *expr(void);
+
+void
+init_expr(void)
+{
+	static Symbol dummy0, dummy1;
+
+	dummy0.type = dummy1.type = inttype;
+	dummy0.u.i = 0;
+	dummy1.u.i = 1;
+	zero = &dummy0;
+	one = &dummy1;
+}
+
+static Node *
+promote(Node *np)
+{
+	Type *tp;
+	uint8_t r;
+
+	if (options.npromote)
+		return np;
+	tp = np->utype;
+	r = tp->u.rank;
+	if  (r > RANK_UINT || tp == inttype || tp == uinttype)
+		return np;
+	return castcode(np, (r == RANK_UINT) ? uinttype : inttype);
+}
+
+static void
+typeconv(Node **p1, Node **p2)
+{
+	Type *tp1, *tp2;
+	Node *np1, *np2;
+	int8_t n;
+
+	np1 = promote(*p1);
+	np2 = promote(*p2);
+
+	tp1 = np1->utype;
+	tp2 = np2->utype;
+	if (tp1 != tp2) {
+		if ((n = tp1->u.rank - tp2->u.rank) > 0)
+			np2 = castcode(np2, tp1);
+		else if (n < 0)
+			np1 = castcode(np1, tp2);
+	}
+	*p1 = np1;
+	*p2 = np2;
+}
+
+Node *
+eval(Node *np)
+{
+	if (!ISNODECMP(np))
+		return np;
+	return ternarycode(np, symcode(one), symcode(zero));
+}
+
+static Node *
+integerop(char op, Node *np1, Node *np2)
+{
+	np1 = eval(np1);
+	np2 = eval(np2);
+	if (np1->typeop != INT || np2->typeop != INT)
+		error("operator requires integer operands");
+	typeconv(&np1, &np2);
+	return bincode(op, np1->type, np1, np2);
+}
+
+static Node *
+integeruop(char op, Node *np)
+{
+	np = eval(np);
+	if (np->typeop != INT)
+		error("unary operator requires integer operand");
+	return unarycode(op, np->type, np);
+}
+
+static Node *
+addr2ptr(Node *np)
+{
+	Type *tp;
+
+	tp = mktype(np->utype->type, PTR, NULL, 0);
+	return unarycode(OADDR, tp, np);
+}
+
+/*
+ * Convert a Node to a type
+ */
+Node *
+convert(Node *np, Type *tp, char iscast)
+{
+	Type *utp;
+	uint8_t t;
+
+	if (np->type == tp)
+		return np;
+
+	utp = UNQUAL(tp);
+	t = utp->op;
+
+	switch (np->typeop) {
+	case ENUM: case INT: case FLOAT:
+		switch (t) {
+		case PTR:
+			if (!iscast || np->typeop == FLOAT)
+				return NULL;
+		case INT: case FLOAT: case ENUM: case VOID:
+			break;
+		default:
+			return NULL;
+		}
+		break;
+	case PTR:
+		switch (t) {
+		case ENUM: case INT: case VOID: /* TODO: allow p = 0 */
+			if (!iscast)
+				return NULL;;
+			break;
+		case ARY: case FTN:
+			np = addr2ptr(np);
+		case PTR:
+			if (iscast ||
+			    utp == pvoidtype ||
+			    np->utype == pvoidtype) {
+				/* TODO:
+				 * we assume conversion between pointers
+				 * do not need any operation, but due to
+				 * alignment problems that may be false
+				 */
+				np->type = tp;
+				np->utype = utp;
+				return np;
+			}
+		default:
+			return NULL;
+		}
+	default:
+			return NULL;
+	}
+	return castcode(np, tp);
+}
+
+static Node *
+parithmetic(char op, Node *np1, Node *np2)
+{
+	Type *tp;
+	Node *size;
+	char *err;
+
+	tp = np1->utype;
+	size = sizeofcode(tp->type);
+	if (np2->typeop == ARY)
+		np2 = addr2ptr(np2);
+
+	if (op == OSUB && np2->typeop == PTR) {
+		if (tp != np2->utype)
+			goto incorrect;
+		np1 = bincode(OSUB, inttype, np1, np2);
+		return bincode(ODIV, inttype, np1, size);
+	}
+	if (np2->typeop != INT)
+		goto incorrect;
+	np2 = castcode(promote(np2), tp);
+	np2 = bincode(OMUL, tp, np2, size);
+	return bincode(op, tp, np1, np2);
+
+incorrect:
+	error("incorrect arithmetic operands");
+}
+
+static Node *
+arithmetic(char op, Node *np1, Node *np2)
+{
+	np1 = eval(np1);
+	np2 = eval(np2);
+	switch (np1->typeop) {
+	case INT: case FLOAT:
+		switch (np2->typeop) {
+		case INT: case FLOAT:
+			typeconv(&np1, &np2);
+			break;
+		case ARY:
+			np2 = addr2ptr(np2);
+		case PTR:
+			if (op == OADD || op == OSUB)
+				return parithmetic(op, np2, np1);
+		default:
+			goto incorrect;
+		}
+		break;
+	case ARY:
+		np1 = addr2ptr(np1);
+	case PTR:
+		return parithmetic(op, np1, np2);
+	default:
+	incorrect:
+		error("incorrect arithmetic operands");
+	}
+
+	return bincode(op, np1->type, np1, np2);
+}
+
+/*
+ * FIXME:
+ * Pointers to the same basic type after removing type qualifiers
+ * can be compared. It means that utype pointer must be a field
+ * of the type, not of the Node, because in other case is
+ * hard doing this check
+ */
+static Node *
+pcompare(char op, Node *np1, Node *np2)
+{
+	if (np2->typeop == INT && np2->b.symbol && np2->u.sym->u.i == 0) {
+		np2 = castcode(np2, pvoidtype);
+	} else if (np2->typeop != PTR) {
+		error("incompatibles type in comparision");
+	} else {
+		warn(options.pcompare,
+		     "comparision between different pointer types");
+	}
+
+	return bincode(op, np1->type, np1, np2);
+}
+
+static Node *
+compare(char op, Node *np1, Node *np2)
+{
+	np1 = eval(np1);
+	np2 = eval(np2);
+	switch (np1->typeop) {
+	case INT: case FLOAT:
+		switch (np1->typeop) {
+		case INT: case FLOAT:
+			typeconv(&np1, &np2);
+			break;
+		case ARY: case FTN:
+			np2 = addr2ptr(np2);
+		case PTR:
+			return pcompare(op, np2, np1);
+		default:
+			goto nocompat;
+		}
+		break;
+	case ARY: case FTN:
+		np1 = addr2ptr(np1);
+	case PTR:
+		return pcompare(op, np1, np2);
+	default:
+	nocompat:
+		error("incompatibles type in comparision");
+	}
+
+	return bincode(op, inttype, np1, np2);
+}
+
+static Node *
+exp2cond(Node *np, char neg)
+{
+	if (ISNODECMP(np)) {
+		NEGATE(np, neg);
+		return np;
+	}
+
+	return compare(ONE ^ neg, np, symcode(zero));
+}
+
+static Node *
+logic(char op, Node *np1, Node *np2)
+{
+	np1 = exp2cond(np1, 0);
+	np2 = exp2cond(np2, 0);
+	return bincode(op, inttype, np1, np2);
+}
+
+static Node *
+array(Node *np1, Node *np2)
+{
+	Type *tp;
+	char *err;
+
+	if (np1->typeop != INT && np2->typeop != INT)
+		goto bad_subs;
+	np1 = arithmetic(OADD, np1, np2);
+	tp = np1->type;
+	if (tp->op != PTR)
+		goto bad_vector;
+	np1 =  unarycode(OARY, tp->type , np1);
+	np1->b.lvalue = 1;
+	return 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);
+}
+
+Node *
+iszero(Node *np)
+{
+	if (ISNODECMP(np))
+		return np;
+	return compare(ONE, np, symcode(zero));
+}
+
+static Node *
+assignop(char op, Node *np1, Node *np2)
+{
+	if ((np2 = convert(np2, np1->type, 0)) == NULL)
+		error("incompatible types when assigning");
+	return bincode(op, np1->type, np1, np2);
+}
+
+static Node *
+incdec(Node *np, char op)
+{
+	char *err;
+	Type *tp = np->utype;
+
+	if (!np->b.lvalue)
+		goto nolvalue;
+	if (np->utype == voidtype)
+		goto voidassign;
+	if (isconst(tp->op))
+		goto const_mod;
+
+	switch (np->typeop) {
+	case PTR:
+		if (!tp->defined)
+			goto nocomplete;
+	case INT: case FLOAT:
+		return arithmetic(op, np, symcode(one));
+	default:
+		goto bad_type;
+	}
+
+voidassign:
+	err = "invalid use of void expression";
+	goto error;
+nolvalue:
+	err = "lvalue required in operation";
+	goto error;
+nocomplete:
+	err = "invalid use of indefined type";
+	goto error;
+bad_type:
+	err = "incorrect type in arithmetic operation";
+	goto error;
+const_mod:
+	err = "const value modified";
+error:
+	error(err);
+}
+
+static Node *
+address(char op, Node *np)
+{
+	char *err;
+
+	if (!np->b.lvalue)
+		goto no_lvalue;
+	if (np->b.symbol && np->u.sym->s.isregister)
+		goto reg_address;
+	return unarycode(op, mktype(np->type, PTR, NULL, 0), np);
+
+no_lvalue:
+	err = "lvalue required in unary expression";
+	goto error;
+reg_address:
+	err = "address of register variable '%s' requested";
+error:
+	error(err);
+}
+
+static Node *
+content(char op, Node *np)
+{
+	switch (np->typeop) {
+	case ARY: case FTN:
+		np = addr2ptr(np);
+	case PTR:
+		np = unarycode(op, np->utype->type, np);
+		np->b.lvalue = 1;
+		return np;
+	default:
+		error("invalid argument of unary '*'");
+	}
+}
+
+static Node *
+negation(char op, Node *np)
+{
+	switch (np->typeop) {
+	case FTN: case ARY:
+		np = addr2ptr(np);
+	case INT: case FLOAT: case PTR:
+		return exp2cond(np, 1);
+	default:
+		error("invalid argument of unary '!'");
+	}
+}
+
+/*************************************************************
+ * grammar functions                                         *
+ *************************************************************/
+static Node *
+primary(void)
+{
+	Node *np;
+	Symbol *sym;
+
+	switch (yytoken) {
+	case STRING: case CONSTANT: case IDEN:
+		if ((sym = yylval.sym) == NULL)
+			error("'%s' undeclared", yytext);
+		np = symcode(yylval.sym);
+		if (yytoken == IDEN) {
+			np->b.lvalue = 1;
+			np->b.constant = 0;
+		}
+		next();
+		break;
+	case '(':
+		next();
+		np = expr();
+		expect(')');
+		break;
+	default:
+		error("unexpected '%s'", yytext);
+	}
+	return np;
+}
+
+static Node *
+postfix(void)
+{
+	register Node *np1, *np2;
+
+	np1 = primary();
+	for (;;) {
+		switch (yytoken) {
+		case '[':
+			next();
+			np2 = expr();
+			np1 = array(np1, np2);
+			expect(']');
+			break;
+		case DEC: case INC:
+			np1 = incdec(np1,  (yytoken == INC) ? OINC : ODEC);
+			next();
+			break;
+		/* TODO: case '.': */
+		/* TODO: case INDIR: */
+		/* TODO: case '(' */
+		default:
+			return np1;
+		}
+	}
+}
+
+static Node *cast(void);
+
+static Node *
+unary(void)
+{
+	register Node *(*fun)(char, Node *);
+	register char op;
+	Type *tp;
+	char *err;
+
+	switch (yytoken) {
+	case SIZEOF:
+		next();
+		if (yytoken == '(' && ahead() == TYPE) {
+			next();
+			tp = typename();
+			expect(')');
+		} else {
+			tp = unary()->type;
+			/* TODO: Free memory */
+		}
+		return sizeofcode(tp);
+	case INC: case DEC:
+		op = (yytoken == INC) ? OA_ADD : OA_SUB;
+		next();
+		return incdec(unary(), op);
+	case '!': op = 0; fun = negation; break;
+	case '+': op = OADD; fun = integeruop; break;
+	case '-': op = OSUB; fun = integeruop; break;
+	case '~': op = ONEG; fun = integeruop; break;
+	case '&': op = OADDR; fun = address; break;
+	case '*': op = OPTR; fun = content; break;
+	default: return postfix();
+	}
+
+	next();
+	return (*fun)(op, cast());
+}
+
+static Node *
+cast(void)
+{
+	Type *tp;
+	register Node *np1, *np2;
+
+	if (yytoken == '(') {
+		switch(ahead()) {
+		case TQUALIFIER: case TYPE:
+			next();
+			tp = typename();
+			expect(')');
+			np1 = eval(cast());
+			if ((np2 = convert(np1,  tp, 1)) == NULL)
+				error("bad type convertion requested");
+			np2->b.lvalue = np1->b.lvalue;
+			return np2;
+		default:
+			break;
+		}
+	}
+
+	return unary();
+}
+
+static Node *
+mul(void)
+{
+	register Node *np, *(*fun)(char, Node *, Node *);
+	register char op;
+
+	np = cast();
+	for (;;) {
+		switch (yytoken) {
+		case '*': op = OMUL; fun = arithmetic; break;
+		case '/': op = ODIV; fun = arithmetic; break;
+		case '%': op = OMOD; fun = integerop;   break;
+		default: return np;
+		}
+		next();
+		np = (*fun)(op, np, cast());
+	}
+}
+
+static Node *
+add(void)
+{
+	register char op;
+	register Node *np;
+
+	np = mul();
+	for (;;) {
+		switch (yytoken) {
+		case '+': op = OADD; break;
+		case '-': op = OSUB; break;
+		default:  return np;
+		}
+		next();
+		np = arithmetic(op, np, mul());
+	}
+}
+
+static Node *
+shift(void)
+{
+	register char op;
+	register Node *np;
+
+	np = add();
+	for (;;) {
+		switch (yytoken) {
+		case SHL: op = OSHL; break;
+		case SHR: op = OSHR; break;
+		default:  return np;
+		}
+		next();
+		np = integerop(op, np, add());
+	}
+}
+
+static Node *
+relational(void)
+{
+	register char op;
+	register Node *np;
+
+	np = shift();
+	for (;;) {
+		switch (yytoken) {
+		case '<': op = OLT; break;
+		case '>': op = OGT; break;
+		case GE:  op = OGE; break;
+		case LE:  op = OLE; break;
+		default:  return np;
+		}
+		next();
+		np = compare(op, np, shift());
+	}
+}
+
+static Node *
+eq(void)
+{
+	register char op;
+	register Node *np;
+
+	np = relational();
+	for (;;) {
+		switch (yytoken) {
+		case EQ: op = OEQ; break;
+		case NE: op = ONE; break;
+		default: return np;
+		}
+		next();
+		np = compare(op, np, relational());
+	}
+}
+
+static Node *
+bit_and(void)
+{
+	register Node *np;
+
+	np = eq();
+	while (accept('&'))
+		np = integerop(OBAND, np, eq());
+	return np;
+}
+
+static Node *
+bit_xor(void)
+{
+	register Node *np;
+
+	np = bit_and();
+	while (accept('^'))
+		np = integerop(OBXOR,  np, bit_and());
+	return np;
+}
+
+static Node *
+bit_or(void)
+{
+	register Node *np;
+
+	np = bit_xor();
+	while (accept('|'))
+		np = integerop(OBOR, np, bit_xor());
+	return np;
+}
+
+static Node *
+and(void)
+{
+	register Node *np;
+
+	np = bit_or();
+	while (accept(AND))
+		np = logic(OAND, np, bit_or());
+	return np;
+}
+
+static Node *
+or(void)
+{
+	register Node *np;
+
+	np = and();
+	while (accept(OR))
+		np = logic(OOR, np, and());
+	return np;
+}
+
+static Node *
+ternary(void)
+{
+	Node *np, *ifyes, *ifno;
+
+	np = or();
+	while (accept('?')) {
+		ifyes = promote(expr());
+		expect(':');
+		ifno = promote(ternary());
+		typeconv(&ifyes, &ifno);
+		np = ternarycode(iszero(np), ifyes, ifno);
+	}
+	return np;
+}
+
+static Node *
+assign(void)
+{
+	register Node *np, *(*fun)(char , Node *, Node *);
+	register char op;
+	char *err;
+
+	np = ternary();
+	for (;;) {
+		switch (yytoken) {
+		case '=':    op = OASSIGN; fun = assignop;   break;
+		case MUL_EQ: op = OA_MUL;  fun = arithmetic; break;
+		case DIV_EQ: op = OA_DIV;  fun = arithmetic; break;
+		case MOD_EQ: op = OA_MOD;  fun = integerop;  break;
+		case ADD_EQ: op = OA_ADD;  fun = arithmetic; break;
+		case SUB_EQ: op = OA_SUB;  fun = arithmetic; break;
+		case SHL_EQ: op = OA_SHL;  fun = integerop;  break;
+		case SHR_EQ: op = OA_SHR;  fun = integerop;  break;
+		case AND_EQ: op = OA_AND;  fun = integerop;  break;
+		case XOR_EQ: op = OA_XOR;  fun = integerop;  break;
+		case OR_EQ:  op = OA_OR;   fun = integerop;  break;
+		default: return np;
+		}
+		if (!np->b.lvalue)
+			goto nolvalue;
+		if (np->utype == voidtype)
+			goto voidassign;
+		if (isconst(np->type->op))
+			goto const_mod;
+		next();
+		np = (fun)(op, np, eval(assign()));
+	}
+voidassign:
+	err = "invalid use of void expression";
+	goto error;
+const_mod:
+	err = "const value modified";
+	goto error;
+nolvalue:
+	err = "lvalue required as left operand of assignment";
+	goto error;
+error:
+	error(err);
+}
+
+Node *
+expr(void)
+{
+	register Node *np1, *np2;
+
+	np1 = assign();
+	while (accept(',')) {
+		np2 = assign();
+		np1 = bincode(OCOMMA, np2->type, np1, np2);
+	}
+
+	return np1;
+}
--- /dev/null
+++ b/cc1/lex.c
@@ -1,0 +1,438 @@
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "cc1.h"
+#include "sizes.h"
+
+static FILE *yyin;
+const char *filename;
+unsigned linenum;
+
+uint8_t yytoken, yyntoken;;
+union yystype yylval;
+char yytext[IDENTSIZ + 1];
+
+static union yystype yynlval;
+static char yybuf[IDENTSIZ + 1];
+
+static uint8_t
+integer(char *s, char base)
+{
+	static Type *tp;
+	static Symbol *sym;
+	static char ch, size, sign;
+	static long v;
+
+	size = sign = 0;
+type:
+	switch (ch = toupper(getc(yyin))) {
+	case 'L':
+		if (size == LONG + LONG)
+			goto wrong_type;
+		size += LONG;
+		goto type;
+	case 'U':
+		if (sign == UNSIGNED)
+			goto wrong_type;
+		goto type;
+	default:
+		ungetc(ch, yyin);
+		tp = ctype(INT, sign, size);
+		break;
+	wrong_type:
+		error("invalid suffix in integer constant");
+	}
+
+	sym = install("", NS_IDEN);
+	sym->type = tp;
+	v = strtol(yybuf, NULL, base);
+	if (tp == inttype)
+		sym->u.i = v;
+	yynlval.sym = sym;
+	return CONSTANT;
+}
+
+static uint8_t
+number(void)
+{
+	register char ch, *bp;
+	static char base;
+
+	if ((ch = getc(yyin)) == '0') {
+		if (toupper(ch = getc(yyin)) == 'X') {
+			base = 16;
+		} else {
+			base = 8;
+			ungetc(ch, yyin);
+		}
+	} else {
+		base = 10;
+		ungetc(ch, yyin);
+	}
+
+	for (bp = yybuf ; bp < &yybuf[IDENTSIZ]; *bp++ = ch) {
+		ch = getc(yyin);
+		switch (base) {
+		case 8:
+			if (ch >= '7')
+				goto end;
+			/* passthru */
+		case 10:
+			if (!isdigit(ch))
+				goto end;
+			break;
+		case 16:
+			if (!isxdigit(ch))
+				goto end;
+			break;
+		}
+	}
+
+end:
+	if (bp == &yybuf[IDENTSIZ])
+		error("identifier too long %s", yybuf);
+	*bp = '\0';
+	ungetc(ch, yyin);
+	return integer(yybuf, base);
+}
+
+static char *
+escape(char *s)
+{
+	char c;
+
+repeat:
+	switch (getc(yyin)) {
+	case '\\': c = '\''; break;
+	case 'a': c = '\a'; break;
+	case 'f': c = '\f'; break;
+	case 'n': c = '\n'; break;
+	case 'r': c = '\r'; break;
+	case 't': c = '\t'; break;
+	case 'v': c = '\v'; break;
+	case '\'': c = '\\'; break;
+	case '"': c ='"'; break;
+	case '?': c = '?'; break;
+	case 'x': /* TODO: */
+	case '0': /* TODO: */
+	case 'u': /* TODO: */
+	case '\n':
+		 ++linenum;
+		if ((c = getc(yyin)) == '\\')
+			goto repeat;
+		break;
+	default:
+		warn(1, "unknown escape sequence");
+		return s;
+	}
+
+	*s = c;
+	return ++s;
+}
+
+static uint8_t
+character(void)
+{
+	static char c;
+	register Symbol *sym;
+
+	getc(yyin);   /* discard the initial ' */
+	c = getc(yyin);
+	if (c == '\\')
+		escape(&c);
+	if (getc(yyin) != '\'')
+		error("invalid character constant");
+	sym = install("", NS_IDEN);
+	sym->u.i = c;
+	sym->type = inttype;
+	yynlval.sym = sym;
+	return CONSTANT;
+}
+
+static uint8_t
+string(void)
+{
+	static char buf[STRINGSIZ+1];
+	register char *bp;
+	register int c;
+	static Symbol *sym;
+
+	getc(yyin); /* discard the initial " */
+
+	for (bp = buf; bp < &buf[STRINGSIZ]; ) {
+		switch (c = getc(yyin)) {
+		case EOF:
+			error("found EOF while parsing");
+		case '"':
+			goto end_string;
+		case '\\':
+			bp = escape(bp);
+			break;
+		default:
+			*bp++ = c;
+		}
+	}
+
+end_string:
+	if (bp == &buf[IDENTSIZ])
+		error("string too long");
+	*bp = '\0';
+	sym = install("", NS_IDEN);
+	sym->u.s = xstrdup(buf);
+	sym->type = mktype(chartype, PTR, NULL, 0);
+	yynlval.sym = sym;
+	return STRING;
+}
+
+void
+init_keywords(void)
+{
+	static struct {
+		char *str;
+		uint8_t token, value;
+	} *bp, buff[] = {
+		{"auto", SCLASS, AUTO},
+		{"break", BREAK, BREAK},
+		{"_Bool", TYPE, BOOL},
+		{"case", CASE, CASE},
+		{"char", TYPE, CHAR},
+		{"const", TQUALIFIER, CONST},
+		{"continue", CONTINUE, CONTINUE},
+		{"default", DEFAULT, DEFAULT},
+		{"do", DO, DO},
+		{"double", TYPE, DOUBLE},
+		{"else", ELSE, ELSE},
+		{"enum", TYPE, ENUM},
+		{"extern", SCLASS, EXTERN},
+		{"float", TYPE, FLOAT},
+		{"for", FOR, FOR},
+		{"goto", GOTO, GOTO},
+		{"if", IF, IF},
+		{"int", TYPE, INT},
+		{"long", TYPE, LONG},
+		{"register", SCLASS, REGISTER},
+		{"restrict", TQUALIFIER, RESTRICT},
+		{"return", RETURN, RETURN},
+		{"short", TYPE, SHORT},
+		{"signed", TYPE, SIGNED},
+		{"sizeof", SIZEOF, SIZEOF},
+		{"static", SCLASS, STATIC},
+		{"struct", TYPE, STRUCT},
+		{"switch", SWITCH, SWITCH},
+		{"typedef", SCLASS, TYPEDEF},
+		{"union", TYPE, UNION},
+		{"unsigned", TYPE, UNSIGNED},
+		{"void", TYPE, VOID},
+		{"volatile", TQUALIFIER, VOLATILE},
+		{"while", WHILE, WHILE},
+		{NULL, 0, 0},
+	};
+	register Symbol *sym;
+	extern short symid;
+
+	for (bp = buff; bp->str; ++bp) {
+		sym = install(bp->str, NS_IDEN);
+		sym->token = bp->token;
+		sym->u.token = bp->value;
+	}
+	symid = 0;
+}
+
+static uint8_t
+iden(void)
+{
+	register char *bp;
+	register int c;
+	Symbol *sym;
+
+	for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = c) {
+		if (!isalnum(c = getc(yyin)) && c != '_')
+			break;
+	}
+	if (bp == &yybuf[IDENTSIZ])
+		error("identifier too long %s", yybuf);
+	*bp = '\0';
+	ungetc(c, yyin);
+
+	sym = lookup(yybuf, NS_IDEN);
+	if (!sym || sym->token == IDEN) {
+		yynlval.sym = sym;
+		return IDEN;
+	}
+	yynlval.token = sym->u.token;
+	return sym->token;
+}
+
+static uint8_t
+follow(int expect, int ifyes, int ifno)
+{
+	register int c = getc(yyin);
+
+	if (c == expect) {
+		yybuf[1] = c;
+		yybuf[2] = 0;
+		return ifyes;
+	}
+	ungetc(c, yyin);
+	return ifno;
+}
+
+static uint8_t
+minus(void)
+{
+	register int c = getc(yyin);
+
+	yybuf[1] = c;
+	yybuf[2] = '\0';
+	switch (c) {
+	case '-': return DEC;
+	case '>': return INDIR;
+	case '=': return SUB_EQ;
+	default:
+		yybuf[1] = '\0';
+		ungetc(c, yyin);
+		return '-';
+	}
+}
+
+static uint8_t
+plus(void)
+{
+	register int c = getc(yyin);
+
+	yybuf[1] = c;
+	yybuf[2] = '\0';
+	switch (c) {
+	case '+': return INC;
+	case '=': return ADD_EQ;
+	default:
+		yybuf[1] = '\0';
+		ungetc(c, yyin);
+		return '+';
+	}
+}
+
+static uint8_t
+relational(uint8_t op, uint8_t equal, uint8_t shift, uint8_t assig)
+{
+	register int c = getc(yyin);
+
+	yybuf[1] = c;
+	yybuf[2] = '\0';
+
+	if (c == '=')
+		return equal;
+	if (c == op)
+		return follow('=', assig, shift);
+	ungetc(c, yyin);
+	yybuf[1] = '\0';
+	return op;
+}
+
+static uint8_t
+logic(uint8_t op, uint8_t equal, uint8_t logic)
+{
+	register int c = getc(yyin);
+
+	yybuf[1] = c;
+	yybuf[2] = '\0';
+
+	if (c == '=')
+		return equal;
+	if (c == op)
+		return logic;
+	ungetc(c, yyin);
+	yybuf[1] = '\0';
+	return op;
+}
+
+static uint8_t
+operator(void)
+{
+	register uint8_t c = getc(yyin);
+
+	yybuf[0] = c;
+	yybuf[1] = '\0';
+	switch (c) {
+	case '<': return relational('<', LE, SHL, SHL_EQ);
+	case '>': return relational('>', GE, SHR, SHR_EQ);
+	case '&': return logic('&', AND_EQ, AND);
+	case '|': return logic('|', OR_EQ, OR);
+	case '=': return follow('=', EQ, '=');
+	case '^': return follow('=', XOR_EQ, '^');
+	case '*': return follow('=', MUL_EQ, '*');
+	case '/': return follow('=', DIV_EQ, '/');
+	case '!': return follow('=', NE, '!');
+	case '-': return minus();
+	case '+': return plus();
+	default: return c;
+	}
+}
+
+uint8_t
+next(void)
+{
+	static int c;
+	extern int8_t forbid_eof;
+
+	strcpy(yytext, yybuf);
+	yylval = yynlval;
+	if ((yytoken = yyntoken) == EOFTOK) {
+		if (forbid_eof)
+			error("Find EOF while parsing");
+		goto ret;
+	}
+
+	while (isspace(c = getc(yyin))) {
+		if (c == '\n')
+			++linenum;
+	}
+
+	if (c == EOF) {
+		yyntoken = EOFTOK;
+		goto ret;
+	}
+
+	ungetc(c, yyin);
+	if (isalpha(c) || c == '_')
+		yyntoken = iden();
+	else if (isdigit(c))
+		yyntoken = number();
+	else if (c == '"')
+		yyntoken = string();
+	else if (c == '\'')
+		yyntoken = character();
+	else
+		yyntoken = operator();
+
+ret:	return yytoken;
+}
+
+void
+expect(register uint8_t tok)
+{
+	if (yytoken != tok)
+		error("unexpected %s", yytext);
+	next();
+}
+
+void
+open_file(register const char *file)
+{
+	if (yyin != NULL)
+		fclose(yyin);
+	if (file == NULL) {
+		yyin = stdin;
+		filename = "(stdin)";
+	} else {
+		if ((yyin = fopen(file, "r")) == NULL)
+			die("file '%s' not found", file);
+		filename = file;
+	}
+	linenum = 1;
+	next();      /* prefetch first token */
+}
--- /dev/null
+++ b/cc1/main.c
@@ -1,0 +1,25 @@
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "cc1.h"
+
+extern void init_keywords(void),
+	open_file(const char *file),  init_expr(void);
+
+struct user_opt options;
+
+int
+main(int argc, char *argv[])
+{
+	//setvbuf(stdin, NULL, _IONBF, 0);
+	//setvbuf(stdout, NULL, _IONBF, 0);
+	init_keywords();
+	init_expr();
+	open_file(NULL);
+	for (next(); yytoken != EOFTOK; extdecl());
+		/* nothing */;
+
+	return 0;
+}
--- /dev/null
+++ b/cc1/opcode.txt
@@ -1,0 +1,133 @@
+Ax -> automatic variable number x
+Tx -> static variable number x
+Gx -> global variable with name x
+Xx -> global function with name x
+Yx -> static function with name x
+Lx -> label number x
+Px -> parameter number x
+Mx -> member number x
+
+@  -> content of variable
+#x -> size of type x (R, I, C, W, N, Z, Q, H, Sx, Ux)
+#x -> integer constant of value x
+##x -> float constant of value x
+#%x -> long constant of value x
+" -> begin of string, each element is coded in decimal and comma (better in hexa!!)
+a  -> take address
+:x -> assign of type x
++x -> sum of type x
+-x -> substraction of type x
+*x -> multiplication of type x
+/x -> division of type x
+;  -> used in post operators (A2++ -> A2 #1 ;+I)
+:  -> used in pre operators  (++A2 -> A2 #1 :+I)
+.  -> struct field
+_x -> sign negation of type x
+~x -> logic negation of type x
+%x -> modulo of type x
+lx -> left shift of type x
+rx -> right shift of type x
+>x -> greater than of type x
+<x -> less than of type x
+[x -> less or equal of type x
+]x -> greater or equal of type x
+=x -> equal of type x
+!x -> not equal of type x
+&x -> logical and of type x
+|x -> logical or of type x
+^x -> logical exor of type x
+m  -> and (last two stack values)
+s  -> or (last two stack values)
+`  -> index array (*(val1 + val2))
+:yx -> operation y and assign of type x
+:x -> assign of type x
+?x -> ternary of type x (cond val1 val2)
+cx -> call to function of type x
+px -> pass parameter to function of type x
+Fx -> x number of parameters passed in a function call
+,  -> comma operator (last two stack values)
+d  -> begin of loop
+b  -> end of loop
+j  -> jump (next stack value is the label)
+yx -> return of type x
+ex -> switch of type x
+w  -> case (next stack value is label and next is value)
+n  -> no operation (it is used in ! and in for conditions)
+E  -> no operation (it is used to mark end of function declaration)
+
+Conversions:
+----------
+Sx -> struct number x
+Ux -> union number x
+Vx -> vector number x
+R -> pointer
+I -> integer
+C -> char
+W -> long
+N -> unsigned
+Z -> unsigned long
+Q -> float
+H -> double
+F -> function
+
+
+xy -> conversion from y to x
+
+
+Examples:
+---------
+
+int
+main()
+{
+	int i;
+	float v = 3.0;
+
+	i = i != v;
+}
+
+->
+
+Xmain	I	F	E
+{
+A1	I
+A2	I
+A3	Q
+	A3	##4130000	QH	:Q
+	A1	A1	QI	A3	!Q	#1	#0	?I	:I
+}
+
+-------------------------------------------
+
+struct pepe {
+	int i, j;
+	struct p2 {
+		int k;
+	} k;
+};
+
+int
+main()
+{
+	int i;
+	struct pepe p;
+
+	i += p.i + p.k.k;
+}
+
+->
+
+S4	(
+M5	I
+)
+S1	(
+M2	I
+M3	I
+M6	S4
+)
+Xmain	I	F	E
+{
+A7	I
+A8	S1
+	A7	A8	M2	.	A8	M6	.	M5	.	+I	:+I
+}
--- /dev/null
+++ b/cc1/sizes.h
@@ -1,0 +1,88 @@
+#ifndef SIZES_H
+#define SIZES_H
+
+/*
+ * 15 nesting levels of compound statements, iteration control
+ * structures, and selection control structures
+ */
+#define NR_BLOCK       15
+/*
+ * 8 nesting levels of conditional inclusion
+ */
+#define NR_COND   8
+/*
+ * number of defined structs/unions in one translation unit
+ */
+#define NR_MAXSTRUCTS 127
+/*
+ * 12 pointer, array, and function declarators (in any combinations)
+ *  modifying an arithmetic, a structure, a union, or an incomplete type
+ *  in a declaration
+ */
+#define NR_DECLARATORS  12
+/*
+ * 31 declarators nested by parentheses within a full declarator.
+ */
+#define NR_SUBTYPE     31
+/*
+ * 32 expressions nested by parentheses within a full expression
+ */
+#define NR_SUBEXPR     32
+/*
+ * 31 significant initial characters in an internal identifier or a
+ * macro name
+ */
+#define IDENTSIZ       31
+/*
+ * 511 external identifiers in one translation unit
+ */
+#define NR_EXT_IDENT   511
+/*
+ * 127 identifiers with block scope declared in one block
+ */
+#define NR_INT_IDENT   127
+/*
+ * 31 parameters in one function definition * 6 significant initial
+ * characters in an external identifier.
+ */
+#define NR_FUNPARAM    31
+/*
+ * 31 parameters in one macro definition
+ */
+#define NR_MACROARG    31
+/*
+ * 509 characters in a logical source line.
+ */
+#define LINESIZ     509
+/*
+ * 509 characters in a character string literal or wide string literal
+ * (after concatenation)
+ */
+#define STRINGSIZ   509
+/*
+ * 8 nesting levels for #include'd files
+ */
+#define NR_INCLUDE   9
+/*
+ * 257 case labels for a switch statement (excluding those for any
+ * nested switch statements)
+ */
+#define NR_SWITCH  257
+/*
+ * 127 members in a single structure or union
+ */
+#define NR_FIELDS  127
+/*
+ * 127 enumeration constants in a single enumeration
+ */
+#define NR_ENUM_CTES 127
+/*
+ * 15 levels of nested structure or union definitions in a single
+ *  struct-declaration-list
+ */
+#define NR_STRUCT_LEVEL 15
+/*
+ * 32767 bytes in an object (in a hosted environment only)
+ */
+#define OBJECTSIZ  32767
+#endif
--- /dev/null
+++ b/cc1/stmt.c
@@ -1,0 +1,329 @@
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "cc1.h"
+
+struct scase {
+	Symbol *label;
+	Node *expr;
+	struct scase *next;
+};
+
+struct caselist {
+	short nr;
+	Symbol *deflabel;
+	struct scase *head;
+};
+
+Symbol *curfun;
+
+extern Node *convert(Node *np, Type *tp1, char iscast);
+extern Node *iszero(Node *np), *eval(Node *np);
+static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
+
+static Symbol *
+label(char *s, char define)
+{
+	Symbol *sym;
+
+	if (s) {
+		if ((sym = lookup(s, NS_LABEL)) != NULL) {
+			if (define && sym->s.isdefined)
+				error("label '%s' already defined", s);
+			else
+				sym->s.isdefined = 1;
+			return sym;
+		}
+	} else {
+		s = "";
+	}
+
+	sym = install(s, NS_LABEL);
+	sym->s.isdefined = define;
+	return sym;
+}
+
+static void
+stmtexp(void)
+{
+	if (accept(';'))
+		return;
+	emitexp(expr());
+	expect(';');
+}
+
+static Node *
+condition(void)
+{
+	Node *np;
+
+	expect('(');
+	np = iszero(expr());
+	expect(')');
+	return np;
+}
+
+static void
+While(Caselist *lswitch)
+{
+	Symbol *begin, *cond, *end;
+	Node *np;
+
+	begin = label(NULL, 1);
+	end = label(NULL, 1);
+	cond = label(NULL, 1);
+
+	expect(WHILE);
+	np = condition();
+	emitjump(cond, NULL);
+	emitbloop();
+	emitlabel(begin);
+	stmt(end, begin, lswitch);
+	emitlabel(cond);
+	emitjump(begin, np);
+	emiteloop();
+	emitlabel(end);
+}
+
+static void
+For(Caselist *lswitch)
+{
+	Symbol *begin, *cond, *end;
+	Node *econd = NULL, *einc = NULL;
+
+	begin = label(NULL, 1);
+	end = label(NULL, 1);
+	cond = label(NULL, 1);
+
+	expect(FOR);
+	expect('(');
+	stmtexp();
+
+	if (yytoken != ';')
+		econd = expr();
+	expect(';');
+	if (yytoken != ')')
+		einc = expr();
+	expect(')');
+
+	emitjump(cond, NULL);
+	emitbloop();
+	emitlabel(begin);
+	stmt(end, begin, lswitch);
+	if (einc)
+		emitexp(einc);
+	emitlabel(cond);
+	emitjump(begin, econd);
+	emiteloop();
+	emitlabel(end);
+}
+
+static void
+Dowhile(Caselist *lswitch)
+{
+	Symbol *begin= label(NULL, 1), *end = label(NULL, 1);
+
+
+	expect(DO);
+	emitbloop();
+	emitlabel(begin);
+	stmt(end, begin, lswitch);
+	expect(WHILE);
+	emitjump(begin, condition());
+	emiteloop();
+	emitlabel(end);
+}
+
+static void
+Return(void)
+{
+	Node *np;
+	Type *tp = curfun->type->type;
+
+	expect(RETURN);
+	np  =  (yytoken == ';') ? NULL : eval(expr());
+	expect(';');
+	if (!np) {
+		if (tp != voidtype)
+			warn(1, "function returning non void returns no value");
+		tp = voidtype;
+	} else if (np->type != tp) {
+		if (tp == voidtype)
+			warn(1, "function returning void returns a value");
+		else if ((np = convert(np, tp, 0)) == NULL)
+			error("incorrect type in return");
+	}
+	emitret(tp);
+	emitexp(np);
+}
+
+static void
+Break(Symbol *lbreak)
+{
+	expect(BREAK);
+	if (!lbreak)
+		error("break statement not within loop or switch");
+	emitjump(lbreak, NULL);
+	expect(';');
+}
+
+static void
+Label(void)
+{
+	emitlabel(label(yytext, 1));
+
+	expect(IDEN);
+	expect(':');
+}
+
+static void
+Continue(Symbol *lcont)
+{
+	expect(CONTINUE);
+	if (!lcont)
+		error("continue statement not within loop");
+	emitjump(lcont, NULL);
+	expect(';');
+}
+
+static void
+Goto(void)
+{
+	expect(GOTO);
+
+	if (yytoken != IDEN)
+		error("unexpected '%s'", yytext);
+	emitjump(label(yytext, 0), NULL);
+	next();
+	expect(';');
+}
+
+static void
+Switch(Symbol *lcont)
+{
+	Caselist lcase = {.nr = 0, .head = NULL, .deflabel = NULL};
+	struct scase *p;
+	Symbol *lbreak = label(NULL, 1), *lcond = label(NULL, 1);
+	Node *cond;
+
+	expect(SWITCH);
+	expect ('(');
+	cond = eval(expr());
+	expect (')');
+	/* TODO: check integer type */
+	emitjump(lcond, NULL);
+	stmt(lbreak, lcont, &lcase);
+	emitlabel(lcond);
+	emitswitch(lcase.nr, cond);
+	for (p = lcase.head; p; p = p->next)
+		emitcase(p->label, p->expr);
+	if (lcase.deflabel)
+		emitdefault(lcase.deflabel);
+	emitlabel(lbreak);
+	/* TODO: free memory */
+}
+
+static void
+Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	Node *np;
+	Symbol *lcase = label(NULL, 1);
+	struct scase *pcase;
+
+	if (!lswitch)
+		error("case label not within a switch statement");
+	expect(CASE);
+	if (yytoken == ':')
+		error("expected expression before ':'");
+	np = eval(expr());
+	/* TODO: check integer type */
+	expect(':');
+	emitlabel(lcase);
+	pcase = xmalloc(sizeof(*pcase));
+	pcase->expr = np;
+	pcase->label = lcase;
+	pcase->next = lswitch->head;
+	lswitch->head = pcase;
+	++lswitch->nr;
+}
+
+static void
+Default(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	Symbol *ldefault = label(NULL, 1);
+
+	expect(DEFAULT);
+	expect(':');
+	emitlabel(ldefault);
+	lswitch->deflabel = ldefault;
+}
+
+static void
+If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	Symbol *end, *lelse = label(NULL, 1);
+	Node *np;
+
+	expect(IF);
+	np = condition();
+	NEGATE(np, 1);
+	emitjump(lelse, np);
+	stmt(lbreak, lcont, lswitch);
+	if (accept(ELSE)) {
+		end = label(NULL, 1);
+		emitjump(end, NULL);
+		emitlabel(lelse);
+		stmt(lbreak, lcont, lswitch);
+		emitlabel(end);
+	} else {
+		emitlabel(lelse);
+	}
+}
+
+void
+compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	expect('{');
+	for (;;) {
+		switch (yytoken) {
+		case '}':
+			next();
+			return;
+		case TYPE: case SCLASS: case TQUALIFIER:
+			decl();
+			break;
+		default:
+			stmt(lbreak, lcont, lswitch);
+		}
+	}
+}
+
+static void
+stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+
+repeat:
+	switch (yytoken) {
+	case '{':      compound(lbreak, lcont, lswitch); break;
+	case RETURN:   Return(); break;
+	case WHILE:    While(lswitch); break;
+	case FOR:      For(lswitch); break;
+	case DO:       Dowhile(lswitch); break;
+	case IF:       If(lbreak, lcont, lswitch); break;
+	case BREAK:    Break(lbreak); break;
+	case CONTINUE: Continue(lcont); break;
+	case GOTO:     Goto(); break;
+	case SWITCH:   Switch(lcont); break;
+	case CASE:     Case(lbreak, lcont, lswitch); break;
+	case DEFAULT:  Default(lbreak, lcont, lswitch); break;
+	case IDEN:
+		if (ahead() == ':') {
+			Label();
+			goto repeat;
+		}
+	default:       stmtexp(); break;
+	}
+}
+
--- /dev/null
+++ b/cc1/symbol.c
@@ -1,0 +1,103 @@
+
+#include <stdint.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cc1.h"
+
+#define NR_SYM_HASH 32
+
+uint8_t curctx;
+uint8_t namespace = NS_FREE + 1;
+short symid;
+
+static struct symtab {
+	Symbol *head;
+	Symbol *htab[NR_SYM_HASH];
+} symtab [NR_NAMESPACES];
+
+static inline uint8_t
+hash(register const char *s)
+{
+	register uint8_t h, ch;
+
+	for (h = 0; ch = *s++; h += ch)
+		/* nothing */;
+	return h & NR_SYM_HASH - 1;
+}
+
+void
+freesyms(uint8_t ns)
+{
+	static struct symtab *tbl;
+	register Symbol *sym, *next;
+
+	tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
+	for (sym = tbl->head; sym; sym = next) {
+		if (sym->ctx <= curctx)
+			break;
+		if (ns == NS_LABEL && !sym->s.isdefined)
+			error("label '%s' is not defined", sym->name);
+		tbl->htab[hash(sym->name)] = sym->hash;
+		next = tbl->head = sym->next;
+		free(sym->name);
+		free(sym);
+	}
+}
+
+void
+context(Ctxfun *fun, Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	uint8_t ns;
+
+	ns = namespace;
+	++curctx;
+	(*fun)(lbreak, lcont, lswitch);
+	--curctx;
+	namespace = ns;
+
+	freesyms(NS_IDEN);
+	freesyms(NS_TAG);
+}
+
+Symbol *
+lookup(register char *s, uint8_t ns)
+{
+	extern union yystype yylval;
+	static struct symtab *tbl;
+	register Symbol *sym;
+
+	tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
+	for (sym = tbl->htab[hash(s)]; sym; sym = sym->hash) {
+		register char *t = sym->name;
+		if (sym->ns == ns && t && *t == *s && !strcmp(t, s))
+			return sym;
+	}
+
+	return NULL;
+}
+
+Symbol *
+install(char *s, uint8_t ns)
+{
+	register Symbol *sym, **t;
+	struct symtab *tbl;
+
+	sym = xcalloc(1, sizeof(*sym));
+	sym->name = xstrdup(s);
+	sym->ctx = curctx;
+	sym->token = IDEN;
+	sym->ns = ns;
+	sym->id = symid++;
+	tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
+	sym->next = tbl->head;
+	tbl->head = sym;
+
+
+	t = &tbl->htab[hash(s)];
+	sym->hash = *t;
+	*t = sym;
+
+	return sym;
+}
--- /dev/null
+++ b/cc1/types.c
@@ -1,0 +1,198 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sizes.h"
+#include "cc1.h"
+
+#define NR_TYPE_HASH 16
+
+Type
+	*voidtype = &(Type) {
+		.op = VOID,
+		.letter = 'W'
+	},
+	*pvoidtype = &(Type) {
+		.op = PTR,
+		.letter = 'R'
+	},
+	*booltype = &(Type) {
+		.op = INT,
+		.letter = 'B',
+		.defined = 1,
+		.u.rank = RANK_BOOL
+	},
+	*schartype = &(Type) {
+		.op = INT,
+		.letter = 'C',
+		.defined = 1,
+		.u.rank = RANK_SCHAR
+	},
+	*uchartype = &(Type) {
+		.op = INT,
+		.letter = 'M',
+		.sign = 1,
+		.defined = 1,
+		.u.rank = RANK_UCHAR
+	},
+	*chartype = &(Type) {
+		.op = INT,
+		.letter = 'M',
+		.sign = 1,
+		.defined = 1,
+		.u.rank = RANK_UCHAR
+	},
+	*ushortype = &(Type) {
+		.op = INT,
+		.letter = 'E',
+		.defined = 1,
+		.u.rank = RANK_USHORT
+	},
+	*shortype = &(Type) {
+		.op = INT,
+		.letter = 'K',
+		.defined = 1,
+		.u.rank = RANK_SHORT
+	},
+	*uinttype = &(Type) {
+		.op = INT,
+		.letter = 'U',
+		.sign = 1,
+		.defined = 1,
+		.u.rank = RANK_UINT
+	},
+	*inttype = &(Type) {
+		.op = INT,
+		.letter = 'I',
+		.defined = 1,
+		.u.rank = RANK_INT
+	},
+	*longtype = &(Type) {
+		.op = INT,
+		.letter = 'L',
+		.defined = 1,
+		.u.rank = RANK_LONG
+	},
+	*ulongtype = &(Type) {
+		.op = INT,
+		.letter = 'Z',
+		.sign = 1,
+		.defined = 1,
+		.u.rank = RANK_ULONG
+	},
+	*ullongtype = &(Type) {
+		.op = INT,
+		.letter = 'O',
+		.sign = 1,
+		.defined = 1,
+		.u.rank = RANK_ULLONG
+	},
+	*llongtype = &(Type) {
+		.op = INT,
+		.letter = 'J',
+		.defined = 1,
+		.u.rank = RANK_LLONG
+	},
+	*floattype = &(Type) {
+		.op = FLOAT,
+		.letter = 'F',
+		.defined = 1,
+		.u.rank = RANK_FLOAT
+	},
+	*doubletype = &(Type) {
+		.op = FLOAT,
+		.letter = 'D',
+		.defined = 1,
+		.u.rank = RANK_DOUBLE
+	},
+	*ldoubletype = &(Type) {
+		.op = FLOAT,
+		.letter = 'H',
+		.defined = 1,
+		.u.rank = RANK_LDOUBLE
+	};
+
+Type *
+ctype(int8_t type, int8_t sign, int8_t size)
+{
+	if (type == DOUBLE)
+		type = FLOAT, size += LONG;
+
+	switch (type) {
+	case CHAR: if (sign == 0)
+					return chartype;
+				return (sign == UNSIGNED) ?  uchartype : schartype;
+	case VOID:            return voidtype;
+	case BOOL:            return booltype;
+	case INT: switch (size) {
+		case 0:          return (sign == UNSIGNED) ? uinttype   : inttype;
+		case SHORT:      return (sign == UNSIGNED) ? ushortype  : shortype;
+		case LONG:       return (sign == UNSIGNED) ? ulongtype  : longtype;
+		case LONG+LONG:  return (sign == UNSIGNED) ? ullongtype : llongtype;
+		}
+	case FLOAT: switch (size) {
+		case 0:          return floattype;
+		case LONG:       return doubletype;
+		case LONG+LONG:  return ldoubletype;
+		}
+	}
+}
+
+Type *
+mktype(Type *tp, uint8_t op,
+       Symbol *sym, uint16_t nelem)
+{
+	static Type *typetab[NR_TYPE_HASH], **tbl;
+	static uint8_t t;
+	register Type *bp;
+	char letter;
+
+	if (op == PTR && tp == voidtype)
+		return pvoidtype;
+	t = (op  ^  (uint8_t) ((unsigned short) tp >> 3))
+	         & NR_TYPE_HASH-1;
+	tbl = &typetab[t];
+	if (op != FTN || op != STRUCT || op != UNION || op != ENUM) {
+		for (bp = *tbl; bp; bp = bp->next) {
+			if (bp->type == tp && bp->op == op &&
+			    bp->sym == sym && bp->u.nelem == nelem) {
+				return bp;
+			}
+		}
+	}
+
+	switch (op) {
+	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: letter = tp->letter;
+	}
+	bp = xmalloc(sizeof(*bp));
+	bp->next = *tbl;
+	bp->type = tp;
+	bp->op = op;
+	bp->u.nelem = nelem;
+	bp->sym = sym;
+	bp->letter = letter;
+	return *tbl = bp;
+}
+
+Type *
+qualifier(Type *tp, uint8_t qlf)
+{
+	uint8_t q = tp->op;
+
+	if (!qlf)
+		return tp;
+	if (q & TQUALIFIER) {
+		if (q == qlf)
+			return tp;
+		tp = tp->type;
+		qlf |= q;
+	}
+	return mktype(tp, qlf|TQUALIFIER, NULL, 0);
+}
+
--- /dev/null
+++ b/cc1/wrapper.c
@@ -1,0 +1,53 @@
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdint.h>
+
+#include "cc1.h"
+
+
+static void
+out_of_memory(void)
+{
+	/* TODO: deal with out of memory errors */
+	error("out of memory");
+}
+
+void *
+xmalloc(size_t size)
+{
+	register void *p = malloc(size);
+
+	if (!p)
+		out_of_memory();
+	return p;
+}
+
+void *
+xcalloc(size_t nmemb, size_t size)
+{
+	register size_t nbytes = nmemb * size;
+	register void *p = xmalloc(nbytes);
+
+	return memset(p, nbytes, 0);
+}
+
+char *
+xstrdup(const char *s)
+{
+	register size_t len = strlen(s) + 1;
+	register char *p = xmalloc(len);
+
+	return memcpy(p, s, len);
+}
+
+void *
+xrealloc(void *buff, register size_t size)
+{
+	register void *p = realloc(buff, size);
+
+	if (!p)
+		out_of_memory();
+	return p;
+}
--- a/code.c
+++ /dev/null
@@ -1,313 +1,0 @@
-
-#include <stdint.h>
-#include <stdio.h>
-
-#include "cc1.h"
-
-char *opcodes[] = {
-	[OADD] = "+",
-	[OSUB] = "-",
-	[OMUL] = "*",
-	[OARY] = "'",
-	[OINC] = ";+",
-	[ODEC] =  ";=",
-	[OSIZE] = "#",
-	[OPTR] = "@",
-	[OMOD] = "*",
-	[ODIV] = "/",
-	[OSHL] = "l",
-	[OSHR]  = "r",
-	[OLT] = "<",
-	[OGT] = ">",
-	[OGE] = "]",
-	[OLE] =  "[",
-	[OEQ] = "=",
-	[ONE] = "!",
-	[OBAND] = "&",
-	[OBXOR]  = "^",
-	[OBOR] = "|",
-	[OASSIGN] = ":",
-	[OA_MUL] = ":*",
-	[OA_DIV] = ":/",
-	[OA_MOD] = ":%",
-	[OA_ADD] = ":+",
-	[OA_SUB] = ":-",
-	[OA_SHL] = ":l",
-	[OA_SHR] = ":r",
-	[OA_AND] = ":&",
-	[OA_XOR] = ":^",
-	[OA_OR] = ":|",
-	[OADDR] = "a",
-	[ONEG] = "_",
-	[OCPL] = "~",
-	[OAND] = "m",
-	[OOR] = "s",
-	[OCOMMA] = ","
-};
-
-Node *
-node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds)
-{
-	Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));
-
-	np->code = code;
-	np->type = tp;
-	np->utype = UNQUAL(tp);
-	np->typeop = np->utype->op;
-	np->u = u;
-	np->b.symbol = np->b.lvalue = 0;
-
-	return np;
-}
-
-static void
-emitsym2(Symbol *sym)
-{
-	char c;
-
-	if (sym->s.isglobal)
-		c = 'G';
-	else if (sym->s.isstatic)
-		c = 'T';
-	else if (sym->s.isregister)
-		c = 'Q';
-	else
-		c = 'A';
-	printf("%c%d", c, sym->id);
-}
-
-static void
-emitconst(Node *np)
-{
-	register char *bp, c;
-	Symbol *sym = np->u.sym;
-
-	if (np->type == inttype) {
-		printf("#%x", sym->u.i);
-	} else {
-		putchar('"');
-		for (bp = sym->u.s; c = *bp; ++bp)
-			printf("%02x", (unsigned) c);
-	}
-}
-
-void
-emitsym(Node *np)
-{
-	putchar('\t');
-	(np->b.constant) ? emitconst(np) : emitsym2(np->u.sym);
-}
-
-static void
-emittype(Type *tp)
-{
-	putchar(tp->letter);
-}
-
-void
-emitdcl(Symbol *sym)
-{
-	emitsym2(sym);
-	putchar('\t');
-	emittype(sym->type);
-	putchar('\n');
-}
-
-void
-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
-emitternary(Node *np)
-{
-	Node *cond, *ifyes, *ifno;
-
-	cond = np->childs[0];
-	ifyes = np->childs[1];
-	ifno = np->childs[2];
-	(*cond->code)(cond);
-	(*ifyes->code)(ifyes);
-	(*ifno->code)(ifno);
-	printf("\t?%c", np->type->letter);
-}
-
-void
-emitsizeof(Node *np)
-{
-	printf("\t#%c", np->u.type->letter);
-}
-
-void
-emitexp(Node *np)
-{
-	if (np)
-		(*np->code)(np);
-	putchar('\n');
-}
-
-void
-emitprint(Node *np)
-{
-	(*np->code)(np);
-	printf("\tk%c\n", np->type->letter);
-}
-
-void
-emitfun(Symbol *sym)
-{
-	printf("%c%d\tn%s\n",
-	       sym->s.isglobal ? 'X' : 'Y', sym->id, sym->name);
-}
-
-void
-emitsframe(Symbol *sym)
-{
-	puts("{");
-}
-
-void
-emiteframe(Symbol *sym)
-{
-	puts("}");
-}
-
-void
-emitret(Type *tp)
-{
-	fputs("\ty", stdout);
-	emittype(tp);
-}
-
-void
-emitlabel(Symbol *sym)
-{
-	printf("L%d\n", sym->id);
-}
-
-void
-emitbloop(void)
-{
-	puts("\td");
-}
-
-void
-emiteloop(void)
-{
-	puts("\tb");
-}
-
-void
-emitjump(Symbol *sym, Node *np)
-{
-	printf("\tj\tL%d", sym->id);
-	if (!np)
-		putchar('\n');
-	else
-		emitexp(np);
-}
-
-void
-emitswitch(short nr, Node *np)
-{
-	printf("\teI\t#%0x", nr);
-	emitexp(np);
-}
-
-void
-emitcase(Symbol *sym, Node *np)
-{
-	fputs("\tw\t", stdout);
-	printf("L%d", sym->id);
-	emitexp(np);
-}
-
-void
-emitdefault(Symbol *sym)
-{
-	fputs("\tf\t", stdout);
-	emitlabel(sym);
-}
-
-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)
-{
-	if (!tp->defined)
-		error("invalid use of indefined type");
-	return node(emitsizeof, inttype, TYP(tp), 0);
-}
-
-Node *
-ternarycode(Node *cond, Node *ifyes, Node *ifno)
-{
-	Node *np= node(emitternary, ifyes->type, OP(0), 3);
-	np->childs[0] = cond;
-	np->childs[1] = ifyes;
-	np->childs[2] = ifno;
-	return np;
-}
-
-Node *
-symcode(Symbol *sym)
-{
-	Node *np;
-
-	np = node(emitsym, sym->type, SYM(sym), 0);
-	np->b.symbol = 1;
-	np->b.constant = 1;
-	return np;
-}
--- a/decl.c
+++ /dev/null
@@ -1,536 +1,0 @@
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "sizes.h"
-#include "cc1.h"
-
-#define ID_EXPECTED     1
-#define ID_ACCEPTED     2
-
-int8_t forbid_eof;
-
-struct dcldata {
-	uint8_t op;
-	union {
-		unsigned short nelem;
-		Symbol *sym;
-		struct funpars *pars;
-		uint8_t qlf;
-	} u;
-};
-
-static struct dcldata
-	*declarator0(struct dcldata *dp, uint8_t ns, int8_t flags);
-
-static struct dcldata *
-arydcl(struct dcldata *dp)
-{
-	expect('[');
-	expect(']');
-	if (dp->op == 255)
-		error("too much declarators");
-	dp->u.nelem = 0;
-	dp->op = ARY;
-	return dp + 1;
-}
-
-static struct dcldata *
-fundcl(struct dcldata *dp)
-{
-	expect('(');
-	expect(')');;
-	if (dp->op == 255)
-		error("too much declarators");
-	dp->op = FTN;
-	dp->u.pars = NULL;
-	return dp + 1;
-}
-
-static Symbol *
-newiden(uint8_t ns)
-{
-	Symbol *sym;
-	extern uint8_t curctx;
-
-	if (yylval.sym && yylval.sym->ctx == curctx)
-		error("redeclaration of '%s'", yytext);
-	sym = install(yytext, ns);
-	next();
-	return sym;
-}
-
-static struct dcldata *
-directdcl(struct dcldata *dp, uint8_t ns, int8_t flags)
-{
-	register Symbol *sym;
-	char *err;
-
-	if (accept('(')) {
-		dp = declarator0(dp, ns, flags);
-		expect(')');
-	} else if (flags) {
-		if (yytoken != IDEN) {
-			if (flags & ID_EXPECTED)
-				goto expected;
-			sym = install("", ns);
-		} else {
-			sym = newiden(ns);
-		}
-		dp->op = IDEN;
-		dp->u.sym = sym;
-		++dp;
-	}
-
-	for (;;) {
-		switch (yytoken) {
-		case '(':  dp = fundcl(dp); break;
-		case '[':  dp = arydcl(dp); break;
-		default:   return dp;
-		}
-	}
-
-expected:
-	error("expected '(' or identifier before of '%s'" , yytext);
-}
-
-static struct dcldata*
-declarator0(struct dcldata *dp, uint8_t ns, int8_t flags)
-{
-	uint8_t buffer[NR_DECLARATORS];
-	register uint8_t *bp, n, qlf;
-
-	bp = buffer;
-	for (n = 0; accept('*'); ++n) {
-		if (n == NR_DECLARATORS)
-			goto too_much_declarators;
-		qlf = 0;
-		if (yytoken == TQUALIFIER) {
-			qlf |= yylval.token;
-			next();
-		}
-		*bp++ = qlf;
-	}
-
-	dp = directdcl(dp, ns, flags);
-
-	bp = buffer;
-	while (n--) {
-		if (dp->op == 255)
-			goto too_much_declarators;
-		dp->op = PTR;
-		dp->u.qlf = *bp++;
-		++dp;
-	}
-
-	return dp;
-
-too_much_declarators:
-	error("too much declarators");
-}
-
-static Symbol *
-declarator(Type *tp, uint8_t ns, int8_t flags)
-{
-	struct dcldata data[NR_DECLARATORS+1];
-	register struct dcldata *bp;
-	Symbol *sym = NULL;
-	static Symbol dummy;
-
-	memset(data, 0, sizeof(data));
-	data[NR_DECLARATORS].op = 255;
-	for (bp = declarator0(data, ns, flags); bp >= data; --bp) {
-		switch (bp->op) {
-		case PTR:
-			tp = qualifier(mktype(tp, PTR, NULL, 0), bp->u.qlf);
-			break;
-		case ARY:
-			tp = mktype(tp, ARY, NULL, bp->u.nelem);
-			break;
-		case FTN:
-			tp = mktype(tp, FTN, NULL, 0);
-			break;
-		case IDEN:
-			sym = bp->u.sym;
-			break;
-		}
-	}
-	if (!sym)
-		sym = &dummy;
-	sym->type = tp;
-	return sym;
-}
-
-static Type *structdcl(void), *enumdcl(void);
-
-static Type *
-specifier(int8_t *sclass)
-{
-	Type *tp = NULL;
-	int8_t qlf, sign, type, cls, size, t;
-
-	qlf = sign = type = cls = size = 0;
-
-	for (;;) {
-		register uint8_t *p;
-		Type *(*dcl)(void) = NULL;
-
-		switch (yytoken) {
-		case SCLASS: p = &cls; break;
-		case TQUALIFIER:
-			if ((qlf |= yylval.token) & RESTRICT)
-				goto invalid_type;
-			next();
-			continue;
-		case TYPE:
-			switch (yylval.token) {
-			case ENUM:
-				dcl = enumdcl; p = &type; break;
-			case STRUCT: case UNION:
-				dcl = structdcl; p = &type; break;
-			case TYPENAME:
-				tp = yylval.sym->type;
-			case VOID:   case BOOL:  case CHAR:
-			case INT:    case FLOAT: case DOUBLE:
-				p = &type; break;
-			case SIGNED: case UNSIGNED:
-				p = &sign; break;
-			case LONG:
-				if (size == LONG) {
-					size = LONG+LONG;
-					break;
-				}
-			case SHORT:
-				p = &size; break;
-			}
-			break;
-		default:
-			goto check_types;
-		}
-		if (*p)
-			goto invalid_type;
-		*p = yylval.token;
-		if (dcl)
-			tp = dcl();
-		else
-			next();
-	}
-
-check_types:
-	if (!type) {
-		if (!sign && !size) {
-			warn(options.implicit,
-			     "type defaults to 'int' in declaration");
-		}
-		type = INT;
-	}
-	if (sign && type != INT && type != CHAR ||
-	    size == SHORT && type != INT ||
-	    size == LONG  && type != INT && type != DOUBLE ||
-	    size == LONG+LONG && type != INT) {
-		goto invalid_type;
-	}
-	if (sclass)
-		*sclass = cls;
-	if (!tp)
-		tp = ctype(type, sign, size);
-	return (qlf) ? qualifier(tp, qlf) : tp;
-
-invalid_type:
-	error("invalid type specification");
-}
-
-static struct node *
-initializer(register Type *tp)
-{
-	if (accept('{')) {
-		initializer(tp);
-		expect('}');
-	} else {
-		do {
-			expr();
-		} while (accept(','));
-	}
-}
-
-/* TODO: bitfields */
-
-static void
-newfield(Type *tp, Symbol *sym)
-{
-	register struct field *p, *q;
-	register char *s, *t;
-	static uint8_t op;
-	static char *err;
-
-	s = sym->name;
-	op = tp->op;
-	for (q = p = tp->u.fields; p; q = p, p = p->next) {
-		t = p->sym->name;
-		if (*s == *t && !strcmp(s, t))
-			goto duplicated_name;
-		if (op == ENUM && sym->u.i == p->sym->u.i)
-			goto duplicated_value;
-	}
-
-	p = xmalloc(sizeof(*p));
-	p->next = NULL;
-	p->sym = sym;
-	if (!q)
-		tp->u.fields = p;
-	else
-		q->next = p;
-
-	return;
-
-duplicated_name:
-	err = "duplicated fields '%s' and '%s'";
-	goto error;
-duplicated_value:
-	err = "duplicated enumeration fields '%s' and '%s'";
-error:
-	error(err, s, t);
-}
-
-static void
-fielddcl(Type *base, uint8_t ns)
-{
-	Type *tp;
-	Symbol *sym;
-	char *err;
-
-	switch (yytoken) {
-	case SCLASS:
-		goto bad_storage;
-	case IDEN: case TYPE: case TQUALIFIER:
-		tp = specifier(NULL);
-	case ';':
-		break;
-	default:
-		goto dcl_expected;
-	}
-
-	if (yytoken != ';') {
-		do {
-			sym = declarator(tp, ns, ID_EXPECTED);
-			newfield(tp, sym);
-		} while (accept(','));
-	}
-
-	expect(';');
-	return;
-
-bad_storage:
-	err = "storage class '%s' in struct/union field";
-	goto error;
-dcl_expected:
-	err = "declaration expected";
-error:
-	error(err, yytext);
-}
-
-static Type *
-newtag(uint8_t tag)
-{
-	register Symbol *sym;
-	Type *tp;
-	extern uint8_t namespace;
-
-	if (yytoken == IDEN) {
-		sym = lookup(yytext, NS_TAG);
-		if (sym) {
-			if (sym->type->op != tag)
-				goto bad_tag;
-		} else {
-			sym = install(yytext, NS_TAG);
-		}
-		next();
-	} else {
-		sym = install("", NS_TAG);
-	}
-	tp = sym->type = mktype(NULL, tag, NULL, 0);
-	sym->u.ns = ++namespace;
-	tp->sym = sym;
-	return tp;
-
-bad_tag:
-	error("'%s' defined as wrong kind of tag", yytext);
-}
-
-static Type *
-structdcl(void)
-{
-	Type *tp;
-	uint8_t ns, tag;
-
-	tag = yylval.token;
-	next();
-	tp = newtag(tag);
-	tp->u.fields = NULL;
-	ns = tp->sym->u.ns;
-	if (accept('{')) {
-		if (tp->defined)
-			goto redefined;
-		tp->defined = 1;
-		while (!accept('}'))
-			 fielddcl(tp, ns);
-	}
-
-	return tp;
-
-redefined:
-	error("redefinition of struct/union '%s'", yytext);
-}
-
-static Type *
-enumdcl(void)
-{
-	register Type *tp;
-	Symbol *sym;
-	int val = 0;
-	char *err;
-
-	next();
-	tp = newtag(ENUM);
-	if (yytoken != ';') {
-		expect('{');
-		if (tp->defined)
-			goto redefined;
-		tp->defined = 1;
-		while (yytoken != '}') {
-			if (yytoken != IDEN)
-				goto iden_expected;
-			sym = newiden(NS_IDEN);
-			sym->type = inttype;
-			if (accept('='))
-				initializer(inttype);
-			sym->u.i = val++;
-			newfield(tp, sym);
-			if (!accept(','))
-				break;
-		}
-		expect('}');
-	}
-
-	return tp;
-
-redefined:
-	err = "redefinition of enumeration '%s'";
-	goto error;
-iden_expected:
-	err = "identifier expected";
-error:
-	error(err, yytext);
-}
-
-void
-decl(void)
-{
-	Type *tp;
-	Symbol *sym;
-	int8_t sclass;
-
-	tp = specifier(&sclass);
-	if (yytoken != ';') {
-		do {
-			 sym = declarator(tp, NS_IDEN, ID_EXPECTED);
-			switch (sclass) {
-			case REGISTER: sym->s.isregister = 1; break;
-			case STATIC: sym->s.isstatic = 1; break;
-			case EXTERN: /* TODO: */; break;
-			case TYPEDEF: /* TODO: */;break;
-			case AUTO: default: sym->s.isauto = 1;
-			}
-			if (accept('='))
-				initializer(sym->type); /* TODO: emit initializer */
-			emitdcl(sym);
-		} while (accept(','));
-	}
-	expect(';');
-}
-
-Type *
-typename(void)
-{
-	uint8_t sclass;
-	Type *tp;
-	Symbol *sym;
-
-	tp = specifier(&sclass);
-	if (sclass)
-		error("class storage in type name");
-	sym = declarator(tp, NS_IDEN, 0);
-	return  sym->type;
-}
-
-void
-extdecl(void)
-{
-	Type *base;
-	int8_t sclass;
-	Symbol *sym;
-	char *err;
-
-	forbid_eof = 0; /* TODO: Fix when find EOF */
-
-	switch (yytoken) {
-	case IDEN: case TYPE: case SCLASS: case TQUALIFIER:
-		base = specifier(&sclass);
-		if (sclass == REGISTER || sclass == AUTO)
-			goto bad_storage;
-	case ';':
-		break;
-	case '@':
-		next();
-		emitprint(expr());
-		goto semicolon;
-	default:
-		goto dcl_expected;
-	}
-
-	if (yytoken != ';') {
-		do {
-			Type *tp;
-
-			sym = declarator(base, NS_IDEN, ID_EXPECTED);
-			tp = sym->type;
-
-			if (!(sclass & STATIC))
-				sym->s.isglobal = 1;
-			if (BTYPE(tp) == FTN) {
-				if (yytoken == '{') {
-					extern Symbol *curfun;
-
-					curfun = sym;
-					emitfun(sym);
-					emitsframe(sym);
-					context(compound, NULL, NULL, NULL);
-					emiteframe(sym); /* FIX: sym is not used */
-					freesyms(NS_LABEL);
-					return;
-				}
-			} else {
-				sym->s.isstatic = 1;
-				if (sclass & EXTERN)
-					; /* TODO: handle extern */
-				else if (accept('='))
-					initializer(tp);
-				emitdcl(sym);
-
-			}
-		} while (accept(','));
-	}
-
-semicolon:
-	expect(';');
-	return;
-
-bad_storage:
-	err = "incorrect storage class for file-scope declaration";
-	goto error;
-dcl_expected:
-	err = "declaration expected";
-error:
-	error(err);
-}
--- a/error.c
+++ /dev/null
@@ -1,52 +1,0 @@
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "cc1.h"
-
-extern unsigned linenum;
-extern unsigned columnum;
-extern const char *filename;
-
-static void
-warn_helper(signed char flag, const char *fmt, va_list va)
-{
-	if (!flag)
-		return;
-	fprintf(stderr, "%s:%s:%u: ",
-		(!flag) ? "warning" : "error", filename, linenum);
-	vfprintf(stderr, fmt, va);
-	putc('\n', stderr);
-	if (flag < 0)
-		exit(EXIT_FAILURE); /* TODO: uhmmmm */
-}
-
-void
-warn(signed char flag, const char *fmt, ...)
-{
-	va_list va;
-	va_start(va, fmt);
-	warn_helper(flag, fmt, va);
-	va_end(va);
-}
-
-void
-error(const char *fmt, ...)
-{
-	va_list va;
-	va_start(va, fmt);
-	warn_helper(-1, fmt, va);
-	va_end(va);
-}
-
-void
-die(const char *fmt, ...)
-{
-	va_list va;
-	va_start(va, fmt);
-	fprintf(stderr, fmt, va);
-	va_end(va);
-	exit(EXIT_FAILURE);
-}
--- a/expr.c
+++ /dev/null
@@ -1,758 +1,0 @@
-#include <stdint.h>
-#include <stdio.h>
-
-#include "cc1.h"
-
-static Symbol *zero, *one;
-
-Node *expr(void);
-
-void
-init_expr(void)
-{
-	static Symbol dummy0, dummy1;
-
-	dummy0.type = dummy1.type = inttype;
-	dummy0.u.i = 0;
-	dummy1.u.i = 1;
-	zero = &dummy0;
-	one = &dummy1;
-}
-
-static Node *
-promote(Node *np)
-{
-	Type *tp;
-	uint8_t r;
-
-	if (options.npromote)
-		return np;
-	tp = np->utype;
-	r = tp->u.rank;
-	if  (r > RANK_UINT || tp == inttype || tp == uinttype)
-		return np;
-	return castcode(np, (r == RANK_UINT) ? uinttype : inttype);
-}
-
-static void
-typeconv(Node **p1, Node **p2)
-{
-	Type *tp1, *tp2;
-	Node *np1, *np2;
-	int8_t n;
-
-	np1 = promote(*p1);
-	np2 = promote(*p2);
-
-	tp1 = np1->utype;
-	tp2 = np2->utype;
-	if (tp1 != tp2) {
-		if ((n = tp1->u.rank - tp2->u.rank) > 0)
-			np2 = castcode(np2, tp1);
-		else if (n < 0)
-			np1 = castcode(np1, tp2);
-	}
-	*p1 = np1;
-	*p2 = np2;
-}
-
-Node *
-eval(Node *np)
-{
-	if (!ISNODECMP(np))
-		return np;
-	return ternarycode(np, symcode(one), symcode(zero));
-}
-
-static Node *
-integerop(char op, Node *np1, Node *np2)
-{
-	np1 = eval(np1);
-	np2 = eval(np2);
-	if (np1->typeop != INT || np2->typeop != INT)
-		error("operator requires integer operands");
-	typeconv(&np1, &np2);
-	return bincode(op, np1->type, np1, np2);
-}
-
-static Node *
-integeruop(char op, Node *np)
-{
-	np = eval(np);
-	if (np->typeop != INT)
-		error("unary operator requires integer operand");
-	return unarycode(op, np->type, np);
-}
-
-static Node *
-addr2ptr(Node *np)
-{
-	Type *tp;
-
-	tp = mktype(np->utype->type, PTR, NULL, 0);
-	return unarycode(OADDR, tp, np);
-}
-
-/*
- * Convert a Node to a type
- */
-Node *
-convert(Node *np, Type *tp, char iscast)
-{
-	Type *utp;
-	uint8_t t;
-
-	if (np->type == tp)
-		return np;
-
-	utp = UNQUAL(tp);
-	t = utp->op;
-
-	switch (np->typeop) {
-	case ENUM: case INT: case FLOAT:
-		switch (t) {
-		case PTR:
-			if (!iscast || np->typeop == FLOAT)
-				return NULL;
-		case INT: case FLOAT: case ENUM: case VOID:
-			break;
-		default:
-			return NULL;
-		}
-		break;
-	case PTR:
-		switch (t) {
-		case ENUM: case INT: case VOID: /* TODO: allow p = 0 */
-			if (!iscast)
-				return NULL;;
-			break;
-		case ARY: case FTN:
-			np = addr2ptr(np);
-		case PTR:
-			if (iscast ||
-			    utp == pvoidtype ||
-			    np->utype == pvoidtype) {
-				/* TODO:
-				 * we assume conversion between pointers
-				 * do not need any operation, but due to
-				 * alignment problems that may be false
-				 */
-				np->type = tp;
-				np->utype = utp;
-				return np;
-			}
-		default:
-			return NULL;
-		}
-	default:
-			return NULL;
-	}
-	return castcode(np, tp);
-}
-
-static Node *
-parithmetic(char op, Node *np1, Node *np2)
-{
-	Type *tp;
-	Node *size;
-	char *err;
-
-	tp = np1->utype;
-	size = sizeofcode(tp->type);
-	if (np2->typeop == ARY)
-		np2 = addr2ptr(np2);
-
-	if (op == OSUB && np2->typeop == PTR) {
-		if (tp != np2->utype)
-			goto incorrect;
-		np1 = bincode(OSUB, inttype, np1, np2);
-		return bincode(ODIV, inttype, np1, size);
-	}
-	if (np2->typeop != INT)
-		goto incorrect;
-	np2 = castcode(promote(np2), tp);
-	np2 = bincode(OMUL, tp, np2, size);
-	return bincode(op, tp, np1, np2);
-
-incorrect:
-	error("incorrect arithmetic operands");
-}
-
-static Node *
-arithmetic(char op, Node *np1, Node *np2)
-{
-	np1 = eval(np1);
-	np2 = eval(np2);
-	switch (np1->typeop) {
-	case INT: case FLOAT:
-		switch (np2->typeop) {
-		case INT: case FLOAT:
-			typeconv(&np1, &np2);
-			break;
-		case ARY:
-			np2 = addr2ptr(np2);
-		case PTR:
-			if (op == OADD || op == OSUB)
-				return parithmetic(op, np2, np1);
-		default:
-			goto incorrect;
-		}
-		break;
-	case ARY:
-		np1 = addr2ptr(np1);
-	case PTR:
-		return parithmetic(op, np1, np2);
-	default:
-	incorrect:
-		error("incorrect arithmetic operands");
-	}
-
-	return bincode(op, np1->type, np1, np2);
-}
-
-/*
- * FIXME:
- * Pointers to the same basic type after removing type qualifiers
- * can be compared. It means that utype pointer must be a field
- * of the type, not of the Node, because in other case is
- * hard doing this check
- */
-static Node *
-pcompare(char op, Node *np1, Node *np2)
-{
-	if (np2->typeop == INT && np2->b.symbol && np2->u.sym->u.i == 0) {
-		np2 = castcode(np2, pvoidtype);
-	} else if (np2->typeop != PTR) {
-		error("incompatibles type in comparision");
-	} else {
-		warn(options.pcompare,
-		     "comparision between different pointer types");
-	}
-
-	return bincode(op, np1->type, np1, np2);
-}
-
-static Node *
-compare(char op, Node *np1, Node *np2)
-{
-	np1 = eval(np1);
-	np2 = eval(np2);
-	switch (np1->typeop) {
-	case INT: case FLOAT:
-		switch (np1->typeop) {
-		case INT: case FLOAT:
-			typeconv(&np1, &np2);
-			break;
-		case ARY: case FTN:
-			np2 = addr2ptr(np2);
-		case PTR:
-			return pcompare(op, np2, np1);
-		default:
-			goto nocompat;
-		}
-		break;
-	case ARY: case FTN:
-		np1 = addr2ptr(np1);
-	case PTR:
-		return pcompare(op, np1, np2);
-	default:
-	nocompat:
-		error("incompatibles type in comparision");
-	}
-
-	return bincode(op, inttype, np1, np2);
-}
-
-static Node *
-exp2cond(Node *np, char neg)
-{
-	if (ISNODECMP(np)) {
-		NEGATE(np, neg);
-		return np;
-	}
-
-	return compare(ONE ^ neg, np, symcode(zero));
-}
-
-static Node *
-logic(char op, Node *np1, Node *np2)
-{
-	np1 = exp2cond(np1, 0);
-	np2 = exp2cond(np2, 0);
-	return bincode(op, inttype, np1, np2);
-}
-
-static Node *
-array(Node *np1, Node *np2)
-{
-	Type *tp;
-	char *err;
-
-	if (np1->typeop != INT && np2->typeop != INT)
-		goto bad_subs;
-	np1 = arithmetic(OADD, np1, np2);
-	tp = np1->type;
-	if (tp->op != PTR)
-		goto bad_vector;
-	np1 =  unarycode(OARY, tp->type , np1);
-	np1->b.lvalue = 1;
-	return 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);
-}
-
-Node *
-iszero(Node *np)
-{
-	if (ISNODECMP(np))
-		return np;
-	return compare(ONE, np, symcode(zero));
-}
-
-static Node *
-assignop(char op, Node *np1, Node *np2)
-{
-	if ((np2 = convert(np2, np1->type, 0)) == NULL)
-		error("incompatible types when assigning");
-	return bincode(op, np1->type, np1, np2);
-}
-
-static Node *
-incdec(Node *np, char op)
-{
-	char *err;
-	Type *tp = np->utype;
-
-	if (!np->b.lvalue)
-		goto nolvalue;
-	if (np->utype == voidtype)
-		goto voidassign;
-	if (isconst(tp->op))
-		goto const_mod;
-
-	switch (np->typeop) {
-	case PTR:
-		if (!tp->defined)
-			goto nocomplete;
-	case INT: case FLOAT:
-		return arithmetic(op, np, symcode(one));
-	default:
-		goto bad_type;
-	}
-
-voidassign:
-	err = "invalid use of void expression";
-	goto error;
-nolvalue:
-	err = "lvalue required in operation";
-	goto error;
-nocomplete:
-	err = "invalid use of indefined type";
-	goto error;
-bad_type:
-	err = "incorrect type in arithmetic operation";
-	goto error;
-const_mod:
-	err = "const value modified";
-error:
-	error(err);
-}
-
-static Node *
-address(char op, Node *np)
-{
-	char *err;
-
-	if (!np->b.lvalue)
-		goto no_lvalue;
-	if (np->b.symbol && np->u.sym->s.isregister)
-		goto reg_address;
-	return unarycode(op, mktype(np->type, PTR, NULL, 0), np);
-
-no_lvalue:
-	err = "lvalue required in unary expression";
-	goto error;
-reg_address:
-	err = "address of register variable '%s' requested";
-error:
-	error(err);
-}
-
-static Node *
-content(char op, Node *np)
-{
-	switch (np->typeop) {
-	case ARY: case FTN:
-		np = addr2ptr(np);
-	case PTR:
-		np = unarycode(op, np->utype->type, np);
-		np->b.lvalue = 1;
-		return np;
-	default:
-		error("invalid argument of unary '*'");
-	}
-}
-
-static Node *
-negation(char op, Node *np)
-{
-	switch (np->typeop) {
-	case FTN: case ARY:
-		np = addr2ptr(np);
-	case INT: case FLOAT: case PTR:
-		return exp2cond(np, 1);
-	default:
-		error("invalid argument of unary '!'");
-	}
-}
-
-/*************************************************************
- * grammar functions                                         *
- *************************************************************/
-static Node *
-primary(void)
-{
-	Node *np;
-	Symbol *sym;
-
-	switch (yytoken) {
-	case STRING: case CONSTANT: case IDEN:
-		if ((sym = yylval.sym) == NULL)
-			error("'%s' undeclared", yytext);
-		np = symcode(yylval.sym);
-		if (yytoken == IDEN) {
-			np->b.lvalue = 1;
-			np->b.constant = 0;
-		}
-		next();
-		break;
-	case '(':
-		next();
-		np = expr();
-		expect(')');
-		break;
-	default:
-		error("unexpected '%s'", yytext);
-	}
-	return np;
-}
-
-static Node *
-postfix(void)
-{
-	register Node *np1, *np2;
-
-	np1 = primary();
-	for (;;) {
-		switch (yytoken) {
-		case '[':
-			next();
-			np2 = expr();
-			np1 = array(np1, np2);
-			expect(']');
-			break;
-		case DEC: case INC:
-			np1 = incdec(np1,  (yytoken == INC) ? OINC : ODEC);
-			next();
-			break;
-		/* TODO: case '.': */
-		/* TODO: case INDIR: */
-		/* TODO: case '(' */
-		default:
-			return np1;
-		}
-	}
-}
-
-static Node *cast(void);
-
-static Node *
-unary(void)
-{
-	register Node *(*fun)(char, Node *);
-	register char op;
-	Type *tp;
-	char *err;
-
-	switch (yytoken) {
-	case SIZEOF:
-		next();
-		if (yytoken == '(' && ahead() == TYPE) {
-			next();
-			tp = typename();
-			expect(')');
-		} else {
-			tp = unary()->type;
-			/* TODO: Free memory */
-		}
-		return sizeofcode(tp);
-	case INC: case DEC:
-		op = (yytoken == INC) ? OA_ADD : OA_SUB;
-		next();
-		return incdec(unary(), op);
-	case '!': op = 0; fun = negation; break;
-	case '+': op = OADD; fun = integeruop; break;
-	case '-': op = OSUB; fun = integeruop; break;
-	case '~': op = ONEG; fun = integeruop; break;
-	case '&': op = OADDR; fun = address; break;
-	case '*': op = OPTR; fun = content; break;
-	default: return postfix();
-	}
-
-	next();
-	return (*fun)(op, cast());
-}
-
-static Node *
-cast(void)
-{
-	Type *tp;
-	register Node *np1, *np2;
-
-	if (yytoken == '(') {
-		switch(ahead()) {
-		case TQUALIFIER: case TYPE:
-			next();
-			tp = typename();
-			expect(')');
-			np1 = eval(cast());
-			if ((np2 = convert(np1,  tp, 1)) == NULL)
-				error("bad type convertion requested");
-			np2->b.lvalue = np1->b.lvalue;
-			return np2;
-		default:
-			break;
-		}
-	}
-
-	return unary();
-}
-
-static Node *
-mul(void)
-{
-	register Node *np, *(*fun)(char, Node *, Node *);
-	register char op;
-
-	np = cast();
-	for (;;) {
-		switch (yytoken) {
-		case '*': op = OMUL; fun = arithmetic; break;
-		case '/': op = ODIV; fun = arithmetic; break;
-		case '%': op = OMOD; fun = integerop;   break;
-		default: return np;
-		}
-		next();
-		np = (*fun)(op, np, cast());
-	}
-}
-
-static Node *
-add(void)
-{
-	register char op;
-	register Node *np;
-
-	np = mul();
-	for (;;) {
-		switch (yytoken) {
-		case '+': op = OADD; break;
-		case '-': op = OSUB; break;
-		default:  return np;
-		}
-		next();
-		np = arithmetic(op, np, mul());
-	}
-}
-
-static Node *
-shift(void)
-{
-	register char op;
-	register Node *np;
-
-	np = add();
-	for (;;) {
-		switch (yytoken) {
-		case SHL: op = OSHL; break;
-		case SHR: op = OSHR; break;
-		default:  return np;
-		}
-		next();
-		np = integerop(op, np, add());
-	}
-}
-
-static Node *
-relational(void)
-{
-	register char op;
-	register Node *np;
-
-	np = shift();
-	for (;;) {
-		switch (yytoken) {
-		case '<': op = OLT; break;
-		case '>': op = OGT; break;
-		case GE:  op = OGE; break;
-		case LE:  op = OLE; break;
-		default:  return np;
-		}
-		next();
-		np = compare(op, np, shift());
-	}
-}
-
-static Node *
-eq(void)
-{
-	register char op;
-	register Node *np;
-
-	np = relational();
-	for (;;) {
-		switch (yytoken) {
-		case EQ: op = OEQ; break;
-		case NE: op = ONE; break;
-		default: return np;
-		}
-		next();
-		np = compare(op, np, relational());
-	}
-}
-
-static Node *
-bit_and(void)
-{
-	register Node *np;
-
-	np = eq();
-	while (accept('&'))
-		np = integerop(OBAND, np, eq());
-	return np;
-}
-
-static Node *
-bit_xor(void)
-{
-	register Node *np;
-
-	np = bit_and();
-	while (accept('^'))
-		np = integerop(OBXOR,  np, bit_and());
-	return np;
-}
-
-static Node *
-bit_or(void)
-{
-	register Node *np;
-
-	np = bit_xor();
-	while (accept('|'))
-		np = integerop(OBOR, np, bit_xor());
-	return np;
-}
-
-static Node *
-and(void)
-{
-	register Node *np;
-
-	np = bit_or();
-	while (accept(AND))
-		np = logic(OAND, np, bit_or());
-	return np;
-}
-
-static Node *
-or(void)
-{
-	register Node *np;
-
-	np = and();
-	while (accept(OR))
-		np = logic(OOR, np, and());
-	return np;
-}
-
-static Node *
-ternary(void)
-{
-	Node *np, *ifyes, *ifno;
-
-	np = or();
-	while (accept('?')) {
-		ifyes = promote(expr());
-		expect(':');
-		ifno = promote(ternary());
-		typeconv(&ifyes, &ifno);
-		np = ternarycode(iszero(np), ifyes, ifno);
-	}
-	return np;
-}
-
-static Node *
-assign(void)
-{
-	register Node *np, *(*fun)(char , Node *, Node *);
-	register char op;
-	char *err;
-
-	np = ternary();
-	for (;;) {
-		switch (yytoken) {
-		case '=':    op = OASSIGN; fun = assignop;   break;
-		case MUL_EQ: op = OA_MUL;  fun = arithmetic; break;
-		case DIV_EQ: op = OA_DIV;  fun = arithmetic; break;
-		case MOD_EQ: op = OA_MOD;  fun = integerop;  break;
-		case ADD_EQ: op = OA_ADD;  fun = arithmetic; break;
-		case SUB_EQ: op = OA_SUB;  fun = arithmetic; break;
-		case SHL_EQ: op = OA_SHL;  fun = integerop;  break;
-		case SHR_EQ: op = OA_SHR;  fun = integerop;  break;
-		case AND_EQ: op = OA_AND;  fun = integerop;  break;
-		case XOR_EQ: op = OA_XOR;  fun = integerop;  break;
-		case OR_EQ:  op = OA_OR;   fun = integerop;  break;
-		default: return np;
-		}
-		if (!np->b.lvalue)
-			goto nolvalue;
-		if (np->utype == voidtype)
-			goto voidassign;
-		if (isconst(np->type->op))
-			goto const_mod;
-		next();
-		np = (fun)(op, np, eval(assign()));
-	}
-voidassign:
-	err = "invalid use of void expression";
-	goto error;
-const_mod:
-	err = "const value modified";
-	goto error;
-nolvalue:
-	err = "lvalue required as left operand of assignment";
-	goto error;
-error:
-	error(err);
-}
-
-Node *
-expr(void)
-{
-	register Node *np1, *np2;
-
-	np1 = assign();
-	while (accept(',')) {
-		np2 = assign();
-		np1 = bincode(OCOMMA, np2->type, np1, np2);
-	}
-
-	return np1;
-}
--- a/lex.c
+++ /dev/null
@@ -1,438 +1,0 @@
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "cc1.h"
-#include "sizes.h"
-
-static FILE *yyin;
-const char *filename;
-unsigned linenum;
-
-uint8_t yytoken, yyntoken;;
-union yystype yylval;
-char yytext[IDENTSIZ + 1];
-
-static union yystype yynlval;
-static char yybuf[IDENTSIZ + 1];
-
-static uint8_t
-integer(char *s, char base)
-{
-	static Type *tp;
-	static Symbol *sym;
-	static char ch, size, sign;
-	static long v;
-
-	size = sign = 0;
-type:
-	switch (ch = toupper(getc(yyin))) {
-	case 'L':
-		if (size == LONG + LONG)
-			goto wrong_type;
-		size += LONG;
-		goto type;
-	case 'U':
-		if (sign == UNSIGNED)
-			goto wrong_type;
-		goto type;
-	default:
-		ungetc(ch, yyin);
-		tp = ctype(INT, sign, size);
-		break;
-	wrong_type:
-		error("invalid suffix in integer constant");
-	}
-
-	sym = install("", NS_IDEN);
-	sym->type = tp;
-	v = strtol(yybuf, NULL, base);
-	if (tp == inttype)
-		sym->u.i = v;
-	yynlval.sym = sym;
-	return CONSTANT;
-}
-
-static uint8_t
-number(void)
-{
-	register char ch, *bp;
-	static char base;
-
-	if ((ch = getc(yyin)) == '0') {
-		if (toupper(ch = getc(yyin)) == 'X') {
-			base = 16;
-		} else {
-			base = 8;
-			ungetc(ch, yyin);
-		}
-	} else {
-		base = 10;
-		ungetc(ch, yyin);
-	}
-
-	for (bp = yybuf ; bp < &yybuf[IDENTSIZ]; *bp++ = ch) {
-		ch = getc(yyin);
-		switch (base) {
-		case 8:
-			if (ch >= '7')
-				goto end;
-			/* passthru */
-		case 10:
-			if (!isdigit(ch))
-				goto end;
-			break;
-		case 16:
-			if (!isxdigit(ch))
-				goto end;
-			break;
-		}
-	}
-
-end:
-	if (bp == &yybuf[IDENTSIZ])
-		error("identifier too long %s", yybuf);
-	*bp = '\0';
-	ungetc(ch, yyin);
-	return integer(yybuf, base);
-}
-
-static char *
-escape(char *s)
-{
-	char c;
-
-repeat:
-	switch (getc(yyin)) {
-	case '\\': c = '\''; break;
-	case 'a': c = '\a'; break;
-	case 'f': c = '\f'; break;
-	case 'n': c = '\n'; break;
-	case 'r': c = '\r'; break;
-	case 't': c = '\t'; break;
-	case 'v': c = '\v'; break;
-	case '\'': c = '\\'; break;
-	case '"': c ='"'; break;
-	case '?': c = '?'; break;
-	case 'x': /* TODO: */
-	case '0': /* TODO: */
-	case 'u': /* TODO: */
-	case '\n':
-		 ++linenum;
-		if ((c = getc(yyin)) == '\\')
-			goto repeat;
-		break;
-	default:
-		warn(1, "unknown escape sequence");
-		return s;
-	}
-
-	*s = c;
-	return ++s;
-}
-
-static uint8_t
-character(void)
-{
-	static char c;
-	register Symbol *sym;
-
-	getc(yyin);   /* discard the initial ' */
-	c = getc(yyin);
-	if (c == '\\')
-		escape(&c);
-	if (getc(yyin) != '\'')
-		error("invalid character constant");
-	sym = install("", NS_IDEN);
-	sym->u.i = c;
-	sym->type = inttype;
-	yynlval.sym = sym;
-	return CONSTANT;
-}
-
-static uint8_t
-string(void)
-{
-	static char buf[STRINGSIZ+1];
-	register char *bp;
-	register int c;
-	static Symbol *sym;
-
-	getc(yyin); /* discard the initial " */
-
-	for (bp = buf; bp < &buf[STRINGSIZ]; ) {
-		switch (c = getc(yyin)) {
-		case EOF:
-			error("found EOF while parsing");
-		case '"':
-			goto end_string;
-		case '\\':
-			bp = escape(bp);
-			break;
-		default:
-			*bp++ = c;
-		}
-	}
-
-end_string:
-	if (bp == &buf[IDENTSIZ])
-		error("string too long");
-	*bp = '\0';
-	sym = install("", NS_IDEN);
-	sym->u.s = xstrdup(buf);
-	sym->type = mktype(chartype, PTR, NULL, 0);
-	yynlval.sym = sym;
-	return STRING;
-}
-
-void
-init_keywords(void)
-{
-	static struct {
-		char *str;
-		uint8_t token, value;
-	} *bp, buff[] = {
-		{"auto", SCLASS, AUTO},
-		{"break", BREAK, BREAK},
-		{"_Bool", TYPE, BOOL},
-		{"case", CASE, CASE},
-		{"char", TYPE, CHAR},
-		{"const", TQUALIFIER, CONST},
-		{"continue", CONTINUE, CONTINUE},
-		{"default", DEFAULT, DEFAULT},
-		{"do", DO, DO},
-		{"double", TYPE, DOUBLE},
-		{"else", ELSE, ELSE},
-		{"enum", TYPE, ENUM},
-		{"extern", SCLASS, EXTERN},
-		{"float", TYPE, FLOAT},
-		{"for", FOR, FOR},
-		{"goto", GOTO, GOTO},
-		{"if", IF, IF},
-		{"int", TYPE, INT},
-		{"long", TYPE, LONG},
-		{"register", SCLASS, REGISTER},
-		{"restrict", TQUALIFIER, RESTRICT},
-		{"return", RETURN, RETURN},
-		{"short", TYPE, SHORT},
-		{"signed", TYPE, SIGNED},
-		{"sizeof", SIZEOF, SIZEOF},
-		{"static", SCLASS, STATIC},
-		{"struct", TYPE, STRUCT},
-		{"switch", SWITCH, SWITCH},
-		{"typedef", SCLASS, TYPEDEF},
-		{"union", TYPE, UNION},
-		{"unsigned", TYPE, UNSIGNED},
-		{"void", TYPE, VOID},
-		{"volatile", TQUALIFIER, VOLATILE},
-		{"while", WHILE, WHILE},
-		{NULL, 0, 0},
-	};
-	register Symbol *sym;
-	extern short symid;
-
-	for (bp = buff; bp->str; ++bp) {
-		sym = install(bp->str, NS_IDEN);
-		sym->token = bp->token;
-		sym->u.token = bp->value;
-	}
-	symid = 0;
-}
-
-static uint8_t
-iden(void)
-{
-	register char *bp;
-	register int c;
-	Symbol *sym;
-
-	for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = c) {
-		if (!isalnum(c = getc(yyin)) && c != '_')
-			break;
-	}
-	if (bp == &yybuf[IDENTSIZ])
-		error("identifier too long %s", yybuf);
-	*bp = '\0';
-	ungetc(c, yyin);
-
-	sym = lookup(yybuf, NS_IDEN);
-	if (!sym || sym->token == IDEN) {
-		yynlval.sym = sym;
-		return IDEN;
-	}
-	yynlval.token = sym->u.token;
-	return sym->token;
-}
-
-static uint8_t
-follow(int expect, int ifyes, int ifno)
-{
-	register int c = getc(yyin);
-
-	if (c == expect) {
-		yybuf[1] = c;
-		yybuf[2] = 0;
-		return ifyes;
-	}
-	ungetc(c, yyin);
-	return ifno;
-}
-
-static uint8_t
-minus(void)
-{
-	register int c = getc(yyin);
-
-	yybuf[1] = c;
-	yybuf[2] = '\0';
-	switch (c) {
-	case '-': return DEC;
-	case '>': return INDIR;
-	case '=': return SUB_EQ;
-	default:
-		yybuf[1] = '\0';
-		ungetc(c, yyin);
-		return '-';
-	}
-}
-
-static uint8_t
-plus(void)
-{
-	register int c = getc(yyin);
-
-	yybuf[1] = c;
-	yybuf[2] = '\0';
-	switch (c) {
-	case '+': return INC;
-	case '=': return ADD_EQ;
-	default:
-		yybuf[1] = '\0';
-		ungetc(c, yyin);
-		return '+';
-	}
-}
-
-static uint8_t
-relational(uint8_t op, uint8_t equal, uint8_t shift, uint8_t assig)
-{
-	register int c = getc(yyin);
-
-	yybuf[1] = c;
-	yybuf[2] = '\0';
-
-	if (c == '=')
-		return equal;
-	if (c == op)
-		return follow('=', assig, shift);
-	ungetc(c, yyin);
-	yybuf[1] = '\0';
-	return op;
-}
-
-static uint8_t
-logic(uint8_t op, uint8_t equal, uint8_t logic)
-{
-	register int c = getc(yyin);
-
-	yybuf[1] = c;
-	yybuf[2] = '\0';
-
-	if (c == '=')
-		return equal;
-	if (c == op)
-		return logic;
-	ungetc(c, yyin);
-	yybuf[1] = '\0';
-	return op;
-}
-
-static uint8_t
-operator(void)
-{
-	register uint8_t c = getc(yyin);
-
-	yybuf[0] = c;
-	yybuf[1] = '\0';
-	switch (c) {
-	case '<': return relational('<', LE, SHL, SHL_EQ);
-	case '>': return relational('>', GE, SHR, SHR_EQ);
-	case '&': return logic('&', AND_EQ, AND);
-	case '|': return logic('|', OR_EQ, OR);
-	case '=': return follow('=', EQ, '=');
-	case '^': return follow('=', XOR_EQ, '^');
-	case '*': return follow('=', MUL_EQ, '*');
-	case '/': return follow('=', DIV_EQ, '/');
-	case '!': return follow('=', NE, '!');
-	case '-': return minus();
-	case '+': return plus();
-	default: return c;
-	}
-}
-
-uint8_t
-next(void)
-{
-	static int c;
-	extern int8_t forbid_eof;
-
-	strcpy(yytext, yybuf);
-	yylval = yynlval;
-	if ((yytoken = yyntoken) == EOFTOK) {
-		if (forbid_eof)
-			error("Find EOF while parsing");
-		goto ret;
-	}
-
-	while (isspace(c = getc(yyin))) {
-		if (c == '\n')
-			++linenum;
-	}
-
-	if (c == EOF) {
-		yyntoken = EOFTOK;
-		goto ret;
-	}
-
-	ungetc(c, yyin);
-	if (isalpha(c) || c == '_')
-		yyntoken = iden();
-	else if (isdigit(c))
-		yyntoken = number();
-	else if (c == '"')
-		yyntoken = string();
-	else if (c == '\'')
-		yyntoken = character();
-	else
-		yyntoken = operator();
-
-ret:	return yytoken;
-}
-
-void
-expect(register uint8_t tok)
-{
-	if (yytoken != tok)
-		error("unexpected %s", yytext);
-	next();
-}
-
-void
-open_file(register const char *file)
-{
-	if (yyin != NULL)
-		fclose(yyin);
-	if (file == NULL) {
-		yyin = stdin;
-		filename = "(stdin)";
-	} else {
-		if ((yyin = fopen(file, "r")) == NULL)
-			die("file '%s' not found", file);
-		filename = file;
-	}
-	linenum = 1;
-	next();      /* prefetch first token */
-}
--- a/main.c
+++ /dev/null
@@ -1,25 +1,0 @@
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "cc1.h"
-
-extern void init_keywords(void),
-	open_file(const char *file),  init_expr(void);
-
-struct user_opt options;
-
-int
-main(int argc, char *argv[])
-{
-	setvbuf(stdin, NULL, _IONBF, 0);
-	setvbuf(stdout, NULL, _IONBF, 0);
-	init_keywords();
-	init_expr();
-	open_file(NULL);
-	for (next(); yytoken != EOFTOK; extdecl());
-		/* nothing */;
-
-	return 0;
-}
--- a/opcode.txt
+++ /dev/null
@@ -1,133 +1,0 @@
-Ax -> automatic variable number x
-Tx -> static variable number x
-Gx -> global variable with name x
-Xx -> global function with name x
-Yx -> static function with name x
-Lx -> label number x
-Px -> parameter number x
-Mx -> member number x
-
-@  -> content of variable
-#x -> size of type x (R, I, C, W, N, Z, Q, H, Sx, Ux)
-#x -> integer constant of value x
-##x -> float constant of value x
-#%x -> long constant of value x
-" -> begin of string, each element is coded in decimal and comma (better in hexa!!)
-a  -> take address
-:x -> assign of type x
-+x -> sum of type x
--x -> substraction of type x
-*x -> multiplication of type x
-/x -> division of type x
-;  -> used in post operators (A2++ -> A2 #1 ;+I)
-:  -> used in pre operators  (++A2 -> A2 #1 :+I)
-.  -> struct field
-_x -> sign negation of type x
-~x -> logic negation of type x
-%x -> modulo of type x
-lx -> left shift of type x
-rx -> right shift of type x
->x -> greater than of type x
-<x -> less than of type x
-[x -> less or equal of type x
-]x -> greater or equal of type x
-=x -> equal of type x
-!x -> not equal of type x
-&x -> logical and of type x
-|x -> logical or of type x
-^x -> logical exor of type x
-m  -> and (last two stack values)
-s  -> or (last two stack values)
-`  -> index array (*(val1 + val2))
-:yx -> operation y and assign of type x
-:x -> assign of type x
-?x -> ternary of type x (cond val1 val2)
-cx -> call to function of type x
-px -> pass parameter to function of type x
-Fx -> x number of parameters passed in a function call
-,  -> comma operator (last two stack values)
-d  -> begin of loop
-b  -> end of loop
-j  -> jump (next stack value is the label)
-yx -> return of type x
-ex -> switch of type x
-w  -> case (next stack value is label and next is value)
-n  -> no operation (it is used in ! and in for conditions)
-E  -> no operation (it is used to mark end of function declaration)
-
-Conversions:
-----------
-Sx -> struct number x
-Ux -> union number x
-Vx -> vector number x
-R -> pointer
-I -> integer
-C -> char
-W -> long
-N -> unsigned
-Z -> unsigned long
-Q -> float
-H -> double
-F -> function
-
-
-xy -> conversion from y to x
-
-
-Examples:
----------
-
-int
-main()
-{
-	int i;
-	float v = 3.0;
-
-	i = i != v;
-}
-
-->
-
-Xmain	I	F	E
-{
-A1	I
-A2	I
-A3	Q
-	A3	##4130000	QH	:Q
-	A1	A1	QI	A3	!Q	#1	#0	?I	:I
-}
-
--------------------------------------------
-
-struct pepe {
-	int i, j;
-	struct p2 {
-		int k;
-	} k;
-};
-
-int
-main()
-{
-	int i;
-	struct pepe p;
-
-	i += p.i + p.k.k;
-}
-
-->
-
-S4	(
-M5	I
-)
-S1	(
-M2	I
-M3	I
-M6	S4
-)
-Xmain	I	F	E
-{
-A7	I
-A8	S1
-	A7	A8	M2	.	A8	M6	.	M5	.	+I	:+I
-}
--- a/sizes.h
+++ /dev/null
@@ -1,88 +1,0 @@
-#ifndef SIZES_H
-#define SIZES_H
-
-/*
- * 15 nesting levels of compound statements, iteration control
- * structures, and selection control structures
- */
-#define NR_BLOCK       15
-/*
- * 8 nesting levels of conditional inclusion
- */
-#define NR_COND   8
-/*
- * number of defined structs/unions in one translation unit
- */
-#define NR_MAXSTRUCTS 127
-/*
- * 12 pointer, array, and function declarators (in any combinations)
- *  modifying an arithmetic, a structure, a union, or an incomplete type
- *  in a declaration
- */
-#define NR_DECLARATORS  12
-/*
- * 31 declarators nested by parentheses within a full declarator.
- */
-#define NR_SUBTYPE     31
-/*
- * 32 expressions nested by parentheses within a full expression
- */
-#define NR_SUBEXPR     32
-/*
- * 31 significant initial characters in an internal identifier or a
- * macro name
- */
-#define IDENTSIZ       31
-/*
- * 511 external identifiers in one translation unit
- */
-#define NR_EXT_IDENT   511
-/*
- * 127 identifiers with block scope declared in one block
- */
-#define NR_INT_IDENT   127
-/*
- * 31 parameters in one function definition * 6 significant initial
- * characters in an external identifier.
- */
-#define NR_FUNPARAM    31
-/*
- * 31 parameters in one macro definition
- */
-#define NR_MACROARG    31
-/*
- * 509 characters in a logical source line.
- */
-#define LINESIZ     509
-/*
- * 509 characters in a character string literal or wide string literal
- * (after concatenation)
- */
-#define STRINGSIZ   509
-/*
- * 8 nesting levels for #include'd files
- */
-#define NR_INCLUDE   9
-/*
- * 257 case labels for a switch statement (excluding those for any
- * nested switch statements)
- */
-#define NR_SWITCH  257
-/*
- * 127 members in a single structure or union
- */
-#define NR_FIELDS  127
-/*
- * 127 enumeration constants in a single enumeration
- */
-#define NR_ENUM_CTES 127
-/*
- * 15 levels of nested structure or union definitions in a single
- *  struct-declaration-list
- */
-#define NR_STRUCT_LEVEL 15
-/*
- * 32767 bytes in an object (in a hosted environment only)
- */
-#define OBJECTSIZ  32767
-#endif
--- a/stmt.c
+++ /dev/null
@@ -1,329 +1,0 @@
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "cc1.h"
-
-struct scase {
-	Symbol *label;
-	Node *expr;
-	struct scase *next;
-};
-
-struct caselist {
-	short nr;
-	Symbol *deflabel;
-	struct scase *head;
-};
-
-Symbol *curfun;
-
-extern Node *convert(Node *np, Type *tp1, char iscast);
-extern Node *iszero(Node *np), *eval(Node *np);
-static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
-
-static Symbol *
-label(char *s, char define)
-{
-	Symbol *sym;
-
-	if (s) {
-		if ((sym = lookup(s, NS_LABEL)) != NULL) {
-			if (define && sym->s.isdefined)
-				error("label '%s' already defined", s);
-			else
-				sym->s.isdefined = 1;
-			return sym;
-		}
-	} else {
-		s = "";
-	}
-
-	sym = install(s, NS_LABEL);
-	sym->s.isdefined = define;
-	return sym;
-}
-
-static void
-stmtexp(void)
-{
-	if (accept(';'))
-		return;
-	emitexp(expr());
-	expect(';');
-}
-
-static Node *
-condition(void)
-{
-	Node *np;
-
-	expect('(');
-	np = iszero(expr());
-	expect(')');
-	return np;
-}
-
-static void
-While(Caselist *lswitch)
-{
-	Symbol *begin, *cond, *end;
-	Node *np;
-
-	begin = label(NULL, 1);
-	end = label(NULL, 1);
-	cond = label(NULL, 1);
-
-	expect(WHILE);
-	np = condition();
-	emitjump(cond, NULL);
-	emitbloop();
-	emitlabel(begin);
-	stmt(end, begin, lswitch);
-	emitlabel(cond);
-	emitjump(begin, np);
-	emiteloop();
-	emitlabel(end);
-}
-
-static void
-For(Caselist *lswitch)
-{
-	Symbol *begin, *cond, *end;
-	Node *econd = NULL, *einc = NULL;
-
-	begin = label(NULL, 1);
-	end = label(NULL, 1);
-	cond = label(NULL, 1);
-
-	expect(FOR);
-	expect('(');
-	stmtexp();
-
-	if (yytoken != ';')
-		econd = expr();
-	expect(';');
-	if (yytoken != ')')
-		einc = expr();
-	expect(')');
-
-	emitjump(cond, NULL);
-	emitbloop();
-	emitlabel(begin);
-	stmt(end, begin, lswitch);
-	if (einc)
-		emitexp(einc);
-	emitlabel(cond);
-	emitjump(begin, econd);
-	emiteloop();
-	emitlabel(end);
-}
-
-static void
-Dowhile(Caselist *lswitch)
-{
-	Symbol *begin= label(NULL, 1), *end = label(NULL, 1);
-
-
-	expect(DO);
-	emitbloop();
-	emitlabel(begin);
-	stmt(end, begin, lswitch);
-	expect(WHILE);
-	emitjump(begin, condition());
-	emiteloop();
-	emitlabel(end);
-}
-
-static void
-Return(void)
-{
-	Node *np;
-	Type *tp = curfun->type->type;
-
-	expect(RETURN);
-	np  =  (yytoken == ';') ? NULL : eval(expr());
-	expect(';');
-	if (!np) {
-		if (tp != voidtype)
-			warn(1, "function returning non void returns no value");
-		tp = voidtype;
-	} else if (np->type != tp) {
-		if (tp == voidtype)
-			warn(1, "function returning void returns a value");
-		else if ((np = convert(np, tp, 0)) == NULL)
-			error("incorrect type in return");
-	}
-	emitret(tp);
-	emitexp(np);
-}
-
-static void
-Break(Symbol *lbreak)
-{
-	expect(BREAK);
-	if (!lbreak)
-		error("break statement not within loop or switch");
-	emitjump(lbreak, NULL);
-	expect(';');
-}
-
-static void
-Label(void)
-{
-	emitlabel(label(yytext, 1));
-
-	expect(IDEN);
-	expect(':');
-}
-
-static void
-Continue(Symbol *lcont)
-{
-	expect(CONTINUE);
-	if (!lcont)
-		error("continue statement not within loop");
-	emitjump(lcont, NULL);
-	expect(';');
-}
-
-static void
-Goto(void)
-{
-	expect(GOTO);
-
-	if (yytoken != IDEN)
-		error("unexpected '%s'", yytext);
-	emitjump(label(yytext, 0), NULL);
-	next();
-	expect(';');
-}
-
-static void
-Switch(Symbol *lcont)
-{
-	Caselist lcase = {.nr = 0, .head = NULL, .deflabel = NULL};
-	struct scase *p;
-	Symbol *lbreak = label(NULL, 1), *lcond = label(NULL, 1);
-	Node *cond;
-
-	expect(SWITCH);
-	expect ('(');
-	cond = eval(expr());
-	expect (')');
-	/* TODO: check integer type */
-	emitjump(lcond, NULL);
-	stmt(lbreak, lcont, &lcase);
-	emitlabel(lcond);
-	emitswitch(lcase.nr, cond);
-	for (p = lcase.head; p; p = p->next)
-		emitcase(p->label, p->expr);
-	if (lcase.deflabel)
-		emitdefault(lcase.deflabel);
-	emitlabel(lbreak);
-	/* TODO: free memory */
-}
-
-static void
-Case(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-	Node *np;
-	Symbol *lcase = label(NULL, 1);
-	struct scase *pcase;
-
-	if (!lswitch)
-		error("case label not within a switch statement");
-	expect(CASE);
-	if (yytoken == ':')
-		error("expected expression before ':'");
-	np = eval(expr());
-	/* TODO: check integer type */
-	expect(':');
-	emitlabel(lcase);
-	pcase = xmalloc(sizeof(*pcase));
-	pcase->expr = np;
-	pcase->label = lcase;
-	pcase->next = lswitch->head;
-	lswitch->head = pcase;
-	++lswitch->nr;
-}
-
-static void
-Default(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-	Symbol *ldefault = label(NULL, 1);
-
-	expect(DEFAULT);
-	expect(':');
-	emitlabel(ldefault);
-	lswitch->deflabel = ldefault;
-}
-
-static void
-If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-	Symbol *end, *lelse = label(NULL, 1);
-	Node *np;
-
-	expect(IF);
-	np = condition();
-	NEGATE(np, 1);
-	emitjump(lelse, np);
-	stmt(lbreak, lcont, lswitch);
-	if (accept(ELSE)) {
-		end = label(NULL, 1);
-		emitjump(end, NULL);
-		emitlabel(lelse);
-		stmt(lbreak, lcont, lswitch);
-		emitlabel(end);
-	} else {
-		emitlabel(lelse);
-	}
-}
-
-void
-compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-	expect('{');
-	for (;;) {
-		switch (yytoken) {
-		case '}':
-			next();
-			return;
-		case TYPE: case SCLASS: case TQUALIFIER:
-			decl();
-			break;
-		default:
-			stmt(lbreak, lcont, lswitch);
-		}
-	}
-}
-
-static void
-stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-
-repeat:
-	switch (yytoken) {
-	case '{':      compound(lbreak, lcont, lswitch); break;
-	case RETURN:   Return(); break;
-	case WHILE:    While(lswitch); break;
-	case FOR:      For(lswitch); break;
-	case DO:       Dowhile(lswitch); break;
-	case IF:       If(lbreak, lcont, lswitch); break;
-	case BREAK:    Break(lbreak); break;
-	case CONTINUE: Continue(lcont); break;
-	case GOTO:     Goto(); break;
-	case SWITCH:   Switch(lcont); break;
-	case CASE:     Case(lbreak, lcont, lswitch); break;
-	case DEFAULT:  Default(lbreak, lcont, lswitch); break;
-	case IDEN:
-		if (ahead() == ':') {
-			Label();
-			goto repeat;
-		}
-	default:       stmtexp(); break;
-	}
-}
-
--- a/symbol.c
+++ /dev/null
@@ -1,103 +1,0 @@
-
-#include <stdint.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cc1.h"
-
-#define NR_SYM_HASH 32
-
-uint8_t curctx;
-uint8_t namespace = NS_FREE + 1;
-short symid;
-
-static struct symtab {
-	Symbol *head;
-	Symbol *htab[NR_SYM_HASH];
-} symtab [NR_NAMESPACES];
-
-static inline uint8_t
-hash(register const char *s)
-{
-	register uint8_t h, ch;
-
-	for (h = 0; ch = *s++; h += ch)
-		/* nothing */;
-	return h & NR_SYM_HASH - 1;
-}
-
-void
-freesyms(uint8_t ns)
-{
-	static struct symtab *tbl;
-	register Symbol *sym, *next;
-
-	tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
-	for (sym = tbl->head; sym; sym = next) {
-		if (sym->ctx <= curctx)
-			break;
-		if (ns == NS_LABEL && !sym->s.isdefined)
-			error("label '%s' is not defined", sym->name);
-		tbl->htab[hash(sym->name)] = sym->hash;
-		next = tbl->head = sym->next;
-		free(sym->name);
-		free(sym);
-	}
-}
-
-void
-context(Ctxfun *fun, Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-	uint8_t ns;
-
-	ns = namespace;
-	++curctx;
-	(*fun)(lbreak, lcont, lswitch);
-	--curctx;
-	namespace = ns;
-
-	freesyms(NS_IDEN);
-	freesyms(NS_TAG);
-}
-
-Symbol *
-lookup(register char *s, uint8_t ns)
-{
-	extern union yystype yylval;
-	static struct symtab *tbl;
-	register Symbol *sym;
-
-	tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
-	for (sym = tbl->htab[hash(s)]; sym; sym = sym->hash) {
-		register char *t = sym->name;
-		if (sym->ns == ns && t && *t == *s && !strcmp(t, s))
-			return sym;
-	}
-
-	return NULL;
-}
-
-Symbol *
-install(char *s, uint8_t ns)
-{
-	register Symbol *sym, **t;
-	struct symtab *tbl;
-
-	sym = xcalloc(1, sizeof(*sym));
-	sym->name = xstrdup(s);
-	sym->ctx = curctx;
-	sym->token = IDEN;
-	sym->ns = ns;
-	sym->id = symid++;
-	tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
-	sym->next = tbl->head;
-	tbl->head = sym;
-
-
-	t = &tbl->htab[hash(s)];
-	sym->hash = *t;
-	*t = sym;
-
-	return sym;
-}
--- a/types.c
+++ /dev/null
@@ -1,198 +1,0 @@
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sizes.h"
-#include "cc1.h"
-
-#define NR_TYPE_HASH 16
-
-Type
-	*voidtype = &(Type) {
-		.op = VOID,
-		.letter = 'W'
-	},
-	*pvoidtype = &(Type) {
-		.op = PTR,
-		.letter = 'R'
-	},
-	*booltype = &(Type) {
-		.op = INT,
-		.letter = 'B',
-		.defined = 1,
-		.u.rank = RANK_BOOL
-	},
-	*schartype = &(Type) {
-		.op = INT,
-		.letter = 'C',
-		.defined = 1,
-		.u.rank = RANK_SCHAR
-	},
-	*uchartype = &(Type) {
-		.op = INT,
-		.letter = 'M',
-		.sign = 1,
-		.defined = 1,
-		.u.rank = RANK_UCHAR
-	},
-	*chartype = &(Type) {
-		.op = INT,
-		.letter = 'M',
-		.sign = 1,
-		.defined = 1,
-		.u.rank = RANK_UCHAR
-	},
-	*ushortype = &(Type) {
-		.op = INT,
-		.letter = 'E',
-		.defined = 1,
-		.u.rank = RANK_USHORT
-	},
-	*shortype = &(Type) {
-		.op = INT,
-		.letter = 'K',
-		.defined = 1,
-		.u.rank = RANK_SHORT
-	},
-	*uinttype = &(Type) {
-		.op = INT,
-		.letter = 'U',
-		.sign = 1,
-		.defined = 1,
-		.u.rank = RANK_UINT
-	},
-	*inttype = &(Type) {
-		.op = INT,
-		.letter = 'I',
-		.defined = 1,
-		.u.rank = RANK_INT
-	},
-	*longtype = &(Type) {
-		.op = INT,
-		.letter = 'L',
-		.defined = 1,
-		.u.rank = RANK_LONG
-	},
-	*ulongtype = &(Type) {
-		.op = INT,
-		.letter = 'Z',
-		.sign = 1,
-		.defined = 1,
-		.u.rank = RANK_ULONG
-	},
-	*ullongtype = &(Type) {
-		.op = INT,
-		.letter = 'O',
-		.sign = 1,
-		.defined = 1,
-		.u.rank = RANK_ULLONG
-	},
-	*llongtype = &(Type) {
-		.op = INT,
-		.letter = 'J',
-		.defined = 1,
-		.u.rank = RANK_LLONG
-	},
-	*floattype = &(Type) {
-		.op = FLOAT,
-		.letter = 'F',
-		.defined = 1,
-		.u.rank = RANK_FLOAT
-	},
-	*doubletype = &(Type) {
-		.op = FLOAT,
-		.letter = 'D',
-		.defined = 1,
-		.u.rank = RANK_DOUBLE
-	},
-	*ldoubletype = &(Type) {
-		.op = FLOAT,
-		.letter = 'H',
-		.defined = 1,
-		.u.rank = RANK_LDOUBLE
-	};
-
-Type *
-ctype(int8_t type, int8_t sign, int8_t size)
-{
-	if (type == DOUBLE)
-		type = FLOAT, size += LONG;
-
-	switch (type) {
-	case CHAR: if (sign == 0)
-					return chartype;
-				return (sign == UNSIGNED) ?  uchartype : schartype;
-	case VOID:            return voidtype;
-	case BOOL:            return booltype;
-	case INT: switch (size) {
-		case 0:          return (sign == UNSIGNED) ? uinttype   : inttype;
-		case SHORT:      return (sign == UNSIGNED) ? ushortype  : shortype;
-		case LONG:       return (sign == UNSIGNED) ? ulongtype  : longtype;
-		case LONG+LONG:  return (sign == UNSIGNED) ? ullongtype : llongtype;
-		}
-	case FLOAT: switch (size) {
-		case 0:          return floattype;
-		case LONG:       return doubletype;
-		case LONG+LONG:  return ldoubletype;
-		}
-	}
-}
-
-Type *
-mktype(Type *tp, uint8_t op,
-       Symbol *sym, uint16_t nelem)
-{
-	static Type *typetab[NR_TYPE_HASH], **tbl;
-	static uint8_t t;
-	register Type *bp;
-	char letter;
-
-	if (op == PTR && tp == voidtype)
-		return pvoidtype;
-	t = (op  ^  (uint8_t) ((unsigned short) tp >> 3))
-	         & NR_TYPE_HASH-1;
-	tbl = &typetab[t];
-	if (op != FTN || op != STRUCT || op != UNION || op != ENUM) {
-		for (bp = *tbl; bp; bp = bp->next) {
-			if (bp->type == tp && bp->op == op &&
-			    bp->sym == sym && bp->u.nelem == nelem) {
-				return bp;
-			}
-		}
-	}
-
-	switch (op) {
-	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: letter = tp->letter;
-	}
-	bp = xmalloc(sizeof(*bp));
-	bp->next = *tbl;
-	bp->type = tp;
-	bp->op = op;
-	bp->u.nelem = nelem;
-	bp->sym = sym;
-	bp->letter = letter;
-	return *tbl = bp;
-}
-
-Type *
-qualifier(Type *tp, uint8_t qlf)
-{
-	uint8_t q = tp->op;
-
-	if (!qlf)
-		return tp;
-	if (q & TQUALIFIER) {
-		if (q == qlf)
-			return tp;
-		tp = tp->type;
-		qlf |= q;
-	}
-	return mktype(tp, qlf|TQUALIFIER, NULL, 0);
-}
-
--- a/wrapper.c
+++ /dev/null
@@ -1,53 +1,0 @@
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <stdint.h>
-
-#include "cc1.h"
-
-
-static void
-out_of_memory(void)
-{
-	/* TODO: deal with out of memory errors */
-	error("out of memory");
-}
-
-void *
-xmalloc(size_t size)
-{
-	register void *p = malloc(size);
-
-	if (!p)
-		out_of_memory();
-	return p;
-}
-
-void *
-xcalloc(size_t nmemb, size_t size)
-{
-	register size_t nbytes = nmemb * size;
-	register void *p = xmalloc(nbytes);
-
-	return memset(p, nbytes, 0);
-}
-
-char *
-xstrdup(const char *s)
-{
-	register size_t len = strlen(s) + 1;
-	register char *p = xmalloc(len);
-
-	return memcpy(p, s, len);
-}
-
-void *
-xrealloc(void *buff, register size_t size)
-{
-	register void *p = realloc(buff, size);
-
-	if (!p)
-		out_of_memory();
-	return p;
-}