shithub: scc

Download patch

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