ref: eb99e511ae17e585239954aa02821a05be94eb08
parent: 087c633307b818c0bd30579ba0a805e48e530cd3
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Jun 4 17:07:53 EDT 2012
Added support for function declaration
--- a/cc.h
+++ b/cc.h
@@ -8,6 +8,7 @@
struct {unsigned implicit_int : 1;
unsigned c99 : 1;
+ unsigned useless_typename : 1;
} user_opt;
--- a/decl.c
+++ b/decl.c
@@ -5,8 +5,8 @@
#include "cc.h"
#include "tokens.h"
#include "types.h"
+#include "syntax.h"
-
char parser_out_home;
#include <stdio.h> /* TODO: remove this */
@@ -233,31 +233,52 @@
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()
{}
+
--- 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 @@
void stmt(void)
{ puts("stmt");- unsigned char tok;
switch (yytoken) { case '{':@@ -130,7 +131,9 @@
{ puts("compound"); if (accept('{')) {- decl_list();
+ ++nested_level;
+ while (decl())
+ /* nothing */;
while (!accept('}'))stmt();
}
--- a/main.c
+++ b/main.c
@@ -1,19 +1,22 @@
#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();
+
+
int main(int argc, char *argv[])
{init_lex();
open_file(NULL);
- next();
- compound();
+ for (next(); yytoken != EOFTOK; decl())
+ /* nothing */;
return 0;
}
--- 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
--- a/types.c
+++ b/types.c
@@ -135,3 +135,9 @@
}
#endif
+
+
+unsigned char isfunction(struct type *t)
+{+ return t->op == FTN;
+}
--- a/types.h
+++ b/types.h
@@ -65,4 +65,6 @@
#endif
+extern unsigned char isfunction(struct type *t);
+
#endif
--
⑨