commit 9a720370111cf87f4a1a9c2665c5e12f5c04855c
parent 67f3a8cc5d3362bd2f4670721de588a266fbb1cc
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 25 Mar 2014 09:52:32 +0100
Emit name of identifiers in expressions
Diffstat:
7 files changed, 58 insertions(+), 52 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
- wrapper.o
+ wrapper.o code.o stmt.o
all: kcc
diff --git a/decl.c b/decl.c
@@ -443,7 +443,7 @@ error:
error(err, yytext);
}
-struct node *
+void
decl(void)
{
struct ctype *tp;
@@ -459,9 +459,6 @@ decl(void)
initializer(sym->type);
} while (accept(','));
}
-
- expect(';');
- return NULL;
}
struct node *
@@ -471,16 +468,16 @@ typename(void)
return NULL;
}
-struct node *
+void
extdecl(void)
{
struct ctype *tp;
int8_t sclass;
struct symbol *sym;
- extern struct symbol *curfun;
char *err;
+ extern void compound(void);
- forbid_eof = 1;
+ forbid_eof = 0; /* TODO: Fix when find EOF */
switch (yytoken) {
case IDEN: case TYPE: case SCLASS: case TQUALIFIER:
@@ -498,22 +495,26 @@ extdecl(void)
extern void printtype(struct ctype *tp);
sym = declarator(tp, NS_IDEN, ID_EXPECTED);
printtype(sym->type);
- /* assign storage class */
- if (isfun(sym)) {
+ if (!(sclass & STATIC))
+ sym->s.isglobal = 1;
+ if (ISFUN(sym->type)) {
if (yytoken == '{') {
- curfun = sym;
- context(function);
+ context(compound);
freesyms(NS_LABEL);
+ return;
}
- } else if (accept('=')) {
- initializer(sym->type);
+ } else {
+ sym->s.isstatic = 1;
+ if (sclass & EXTERN)
+ ; /* TODO: handle extern */
+ else if (accept('='))
+ initializer(sym->type);
}
} while (accept(','));
}
- forbid_eof = 0;
expect(';');
- return NULL;
+ return;
bad_storage:
err = "incorrect storage class for file-scope declaration";
diff --git a/expr.c b/expr.c
@@ -1,26 +1,26 @@
-#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include "cc.h"
+#include "code.h"
#include "tokens.h"
#include "symbol.h"
#include "syntax.h"
-struct node *expr(void);
+struct ctype *expr(void);
-static struct node *
+static struct ctype *
primary(void)
{
- register struct node *np;
- register struct symbol *sym;
+ register struct ctype *tp;
switch (yytoken) {
case IDEN:
if (yylval.sym == NULL)
error("'%s' undeclared", yytext);
- /* TODO: Do something */
+ emitsym(yylval.sym);
+ tp = yylval.sym->type;
next();
break;
case CONSTANT:
@@ -29,24 +29,23 @@ primary(void)
break;
case '(':
next();
- np = expr();
+ tp = expr();
expect(')');
break;
default:
- np = NULL;
- break;
+ tp = NULL;
}
- return np;
+ return tp;
}
-struct node *
+struct ctype *
expr(void)
{
- register struct node *np;
+ register struct ctype *tp;
do
- np = primary();
+ tp = primary();
while (yytoken == ',');
- return np;
+ return tp;
}
diff --git a/main.c b/main.c
@@ -12,6 +12,8 @@ struct user_opt options;
int
main(int argc, char *argv[])
{
+ extern void extdecl(void);
+
init_keywords();
open_file(NULL);
for (next(); yytoken != EOFTOK; extdecl());
diff --git a/symbol.c b/symbol.c
@@ -44,22 +44,19 @@ freesyms(uint8_t ns)
}
}
-struct node *
-context(struct node * (*fun)(void))
+void
+context(void (*fun)(void))
{
uint8_t ns;
- struct node *np;
ns = namespace;
++curctx;
- np = fun();
+ fun();
--curctx;
namespace = ns;
freesyms(NS_IDEN);
freesyms(NS_TAG);
-
- return np;
}
struct symbol *
@@ -87,17 +84,20 @@ install(char *s, uint8_t ns)
struct symtab *tbl;
static short id;
- if (ns == NS_KEYWORD)
+ if (ns == NS_KEYWORD) {
ns = NS_IDEN;
- else if (s != NULL)
- s = xstrdup(s);
+ } else {
+ ++id;
+ if (s != NULL)
+ s = xstrdup(s);
+ }
sym = xcalloc(1, sizeof(*sym));
sym->name = s;
sym->ctx = curctx;
sym->token = IDEN;
sym->ns = ns;
- sym->id = id++;
+ sym->id = id;
tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
sym->next = tbl->head;
tbl->head = sym;
diff --git a/symbol.h b/symbol.h
@@ -2,11 +2,13 @@
#ifndef SYMBOL_H
#define SYMBOL_H
+#if ! __bool_true_and_false_are_defined
+#include <stdbool.h>
+#endif
+
#define CTX_OUTER 0
#define CTX_FUNC 1
-#define isfun(t) 0
-
enum {
NS_IDEN = 0,
NS_LABEL,
@@ -61,6 +63,12 @@ struct symbol {
uint8_t ctx;
uint8_t token;
uint8_t ns;
+ struct {
+ bool isglobal : 1;
+ bool isstatic : 1;
+ bool isauto : 1;
+ bool isregister : 1;
+ } s;
union value u;
struct symbol *next;
struct symbol *hash;
@@ -77,7 +85,7 @@ extern struct symbol
*lookup(char *s, unsigned char ns),
*install(char *s, unsigned char ns);
-extern struct node *context(struct node * (*fun)(void));
+extern void context(void (*fun)(void));
extern struct ctype *voidtype,
*uchartype, *chartype,
@@ -89,4 +97,9 @@ extern struct ctype *voidtype,
*doubletype, *cdoubletype, *idoubletype,
*ldoubletype, *cldoubletype,*ildoubletype;
+#define ISQUAL(t) ((t)->op & TQUALIFIER)
+#define UNQUAL(t) (ISQUAL(t) ? (t)->type : (t))
+#define ISFUN(t) (UNQUAL(t)->op == FTN)
+
+
#endif
diff --git a/syntax.h b/syntax.h
@@ -20,14 +20,5 @@ enum opcode {
ORETURN, OCASE, ODEFAULT, OFTN, ODEF, O2EXP
};
-struct node;
-struct symbol;
-struct ctype;
-
-extern struct node *expr(void), *extdecl(void), *decl(void),
- *typename(void), *function(void);
-
-extern struct node *node(unsigned char op, struct node *l, struct node *r);
-extern bool walk(register struct node *np, bool (*fun)(struct node *));
#endif