ref: eb99e511ae17e585239954aa02821a05be94eb08
parent: 087c633307b818c0bd30579ba0a805e48e530cd3
author: Roberto E. Vargas Caballero <[email protected]>
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