commit eb99e511ae17e585239954aa02821a05be94eb08
parent 087c633307b818c0bd30579ba0a805e48e530cd3
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 4 Jun 2012 21:07:53 +0200
Added support for function declaration
Diffstat:
7 files changed, 64 insertions(+), 27 deletions(-)
diff --git a/cc.h b/cc.h
@@ -8,6 +8,7 @@ extern const char *filename;
struct {
unsigned implicit_int : 1;
unsigned c99 : 1;
+ unsigned useless_typename : 1;
} user_opt;
diff --git a/decl.c b/decl.c
@@ -5,7 +5,7 @@
#include "cc.h"
#include "tokens.h"
#include "types.h"
-
+#include "syntax.h"
char parser_out_home;
@@ -233,31 +233,52 @@ duplicated:
error("duplicated '%s'", yytext);
}
-char decl(void)
+unsigned char decl(void)
{
- struct type *t, *spec;
+ auto struct type *tp, *tbase;
+ auto unsigned char nd = 0;
puts("decl");
- if (!(spec = specifier()))
- return 0;
- do {
- declarator();
- t = decl_type(spec);
- } while (accept(','));
- expect(';'); /* TODO: initialisation */
+ tbase = specifier();
+
+ if (!tbase) {
+ if (nested_level != 0) {
+ puts("leaving decl");
+ return 0;
+ }
+ if (yytoken == IDENTIFIER) {
+ warning_error(user_opt.implicit_int,
+ "type defaults to 'int' "
+ "in declaration of '%s'", yytext);
+ tbase = T_INT;
+ } else {
+ error("declaration expected");
+ }
+ }
+ if (yytoken != ';') {
+ do {
+ declarator();
+ tp = decl_type(tbase);
+ if (isfunction(tp) && yytoken == '{') {
+ compound();
+ puts("leaving decl");
+ return 1;
+ }
+ ++nd;
+ } while (accept(','));
+ }
+
+ expect(';');
+ if (nd == 0) {
+ warning_error(user_opt.useless_typename,
+ "useless type name in empty declaration");
+ }
puts("leaving decl");
return 1;
}
-char decl_list(void)
-{
- puts("decl_list");
- while (decl())
- /* nothing */;
- puts("leaving decl_list");
-}
-
void type_name()
{
}
+
diff --git a/flow.c b/flow.c
@@ -1,10 +1,12 @@
-#include <stddef.h>
+#include <stdio.h>
#include "tokens.h"
#include "syntax.h"
+unsigned char nested_level;
+
void stmt(void);
static void do_goto(void)
@@ -84,7 +86,6 @@ static void do_switch(void)
void stmt(void)
{
puts("stmt");
- unsigned char tok;
switch (yytoken) {
case '{':
@@ -130,7 +131,9 @@ void compound(void)
{
puts("compound");
if (accept('{')) {
- decl_list();
+ ++nested_level;
+ while (decl())
+ /* nothing */;
while (!accept('}'))
stmt();
}
diff --git a/main.c b/main.c
@@ -1,10 +1,13 @@
#include <stddef.h>
+#include "tokens.h"
+#include "syntax.h"
+
extern void open_file(const char *file);
extern void init_lex();
-extern void next();
-extern void stmt();
+
+
@@ -12,8 +15,8 @@ int main(int argc, char *argv[])
{
init_lex();
open_file(NULL);
- next();
- compound();
+ for (next(); yytoken != EOFTOK; decl())
+ /* nothing */;
return 0;
}
diff --git a/syntax.h b/syntax.h
@@ -1,8 +1,9 @@
#ifndef SYNTAX_H
#define SYNTAX_H
-extern char decl(void);
+extern unsigned char nested_level;
+
extern void compound(void);
extern void expr(void);
-extern char decl_list(void);
+unsigned char decl(void);
#endif
diff --git a/types.c b/types.c
@@ -135,3 +135,9 @@ void ptype(register struct type *t)
}
#endif
+
+
+unsigned char isfunction(struct type *t)
+{
+ return t->op == FTN;
+}
diff --git a/types.h b/types.h
@@ -65,4 +65,6 @@ extern void ptype(register struct type *t);
#endif
+extern unsigned char isfunction(struct type *t);
+
#endif