scc: sort of add support for void types and the rest of functions
authorAlan Cox <alan@linux.intel.com>
Fri, 24 Jun 2016 20:52:32 +0000 (21:52 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 24 Jun 2016 20:52:32 +0000 (21:52 +0100)
we now handle static functions, extern definitions of functions and function
declarations more nicely. We also understand void including the use of (void)

No typechecking other other magic is done at all.

Applications/SmallC/function.c
Applications/SmallC/lex.c
Applications/SmallC/main.c
Applications/SmallC/prototype.h
Applications/SmallC/stmt.c
Applications/SmallC/sym.c

index 26098af..57ea3c6 100644 (file)
@@ -31,25 +31,32 @@ void newfunc(void) {
 void newfunc_typed(int storage, char *n, int type)
 {
     int idx;
-    /* TODO: external storage */
-    if (storage == EXTERN)
-        error("not yet supported");
+    SYMBOL *symbol;
     if ((idx = find_global(n)) > -1) {
-        if (symbol_table[idx].identity != FUNCTION)
+        symbol = &symbol_table[idx];
+        if (symbol->identity != FUNCTION) {
+            printf("L3 %d %d\n", idx, symbol->identity);
             multidef(n);
-        else if (symbol_table[idx].offset == FUNCTION)
-            multidef(n);
-        else
-            symbol_table[idx].offset = FUNCTION;
-    } else
-        add_global(n, FUNCTION, CINT, FUNCTION, storage);
-    output_string(n);
-    output_label_terminator();
-    newline();
+        }
+    } else {
+        /* extern implies global scope */
+        idx = add_global(n, FUNCTION, CINT, 0, storage == EXTERN ? PUBLIC : storage);
+        printf("L1 %d\n", idx);
+        symbol = &symbol_table[idx];
+        printf("L1 %d %d\n", idx, symbol->offset);
+    }
     local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
     argstk = 0;
     // ANSI style argument declaration
-    if (doAnsiArguments() == 0) {
+    if (doAnsiArguments()) {
+        if (storage == EXTERN) {
+            need_semicolon();
+            return;
+        }
+        /* No body .. just a definition */
+        if (match(";"))
+            return;
+    } else {
         // K&R style argument declaration
         while (!match(")")) {
             if (symname(n)) {
@@ -71,10 +78,18 @@ void newfunc_typed(int storage, char *n, int type)
             if (endst())
                 break;
         }
+        if (storage == EXTERN) {
+            need_semicolon();
+            return;
+        }
+        /* No body .. just a definition */
+        if (match(";"))
+            return;
         stkp = 0;
         argtop = argstk;
         while (argstk) {
-            if ((type = get_type()) != 0) {
+            if ((type = get_type()) != -1) {
+                notvoid(type);
                 getarg(type);
                 need_semicolon();
             } else {
@@ -83,6 +98,14 @@ void newfunc_typed(int storage, char *n, int type)
             }
         }
     }
+    if (symbol->offset == FUNCTION) {
+            printf("L2 %d %d\n", idx, symbol->offset);
+            multidef(n);
+    }
+    symbol->offset = FUNCTION;
+    output_string(n);
+    output_label_terminator();
+    newline();
     gen_prologue();
     statement(YES);
     print_label(fexitlab);
@@ -143,14 +166,15 @@ void getarg(int t) {
 int doAnsiArguments(void) {
     int type;
     type = get_type();
-    if (type == 0) {
+    if (type == -1) {
         return 0; // no type detected, revert back to K&R style
     }
     argtop = argstk;
     argstk = 0;
     FOREVER
     {
-        if (type) {
+        /* We don't need to pull a variable for void */
+        if (type != -1) {
             doLocalAnsiArgument(type);
         } else {
             error("wrong number args");
@@ -175,6 +199,8 @@ void doLocalAnsiArgument(int type) {
         identity = POINTER;
     } else {
         identity = VARIABLE;
+        if (type == VOID)
+            return;
     }
     if (symname(symbol_name)) {
         if (find_locale(symbol_name) > -1) {
index 0f14b06..51e7083 100644 (file)
@@ -196,7 +196,7 @@ void blanks(void) {
 
 /**
  * returns declaration type
- * @return CCHAR, CINT, UCHAR, UINT
+ * @return VOID, CCHAR, CINT, UCHAR, UINT
  *
  * FIXME: wants rewriting to collect property bits and base type right
  */
@@ -228,6 +228,6 @@ int get_type(void) {
     } else if (amatch ("int", 3)) {
         return CINT;
     }
-    return 0;
+    return -1;
 }
 
index fbefff9..801e4a1 100644 (file)
@@ -188,7 +188,7 @@ int do_declarations(int stclass, TAG_SYMBOL *mtag, int is_struct) {
             otag = define_struct(sname, stclass, sflag);
         }
         declare_global(STRUCT, stclass, mtag, otag, is_struct);
-    } else if ((type = get_type()) != 0) {
+    } else if ((type = get_type()) != 1) {
         ns = declare_global(type, stclass, mtag, 0, is_struct);
     } else if (stclass == PUBLIC) {
         return (0);
index 36d42d6..3659188 100644 (file)
@@ -214,6 +214,7 @@ extern int add_local (char *sname, int identity, int type, int offset, int stora
 extern int symname(char *sname);
 extern void illname(void);
 extern void multidef(char *symbol_name);
+extern void notvoid(int type);
 extern void addwhile(WHILE *ptr);
 extern void delwhile(void);
 extern WHILE *readwhile(void);
index c263556..771409b 100644 (file)
@@ -68,7 +68,7 @@ int do_local_declares(int stclass) {
             otag = define_struct(sname, stclass, sflag);
         }
         declare_local(STRUCT, stclass, otag);
-    } else if ((type = get_type()) != 0) {
+    } else if ((type = get_type()) != -1) {
         declare_local(type, stclass, -1);
     } else if (stclass == LSTATIC || stclass == DEFAUTO) {
         declare_local(CINT, stclass, -1);
index bafbc79..ae349c3 100644 (file)
@@ -31,8 +31,6 @@ int declare_global(int type, int storage, TAG_SYMBOL *mtag, int otag, int is_str
             }
             if (!symname (sname))
                 illname ();
-            if (find_global (sname) > -1)
-                multidef (sname);
             if (match ("(")) {
                 /* FIXME: We need to deal with pointer types properly here */
                 if (identity == POINTER)
@@ -41,8 +39,11 @@ int declare_global(int type, int storage, TAG_SYMBOL *mtag, int otag, int is_str
                 /* Can't int foo(x){blah),a=4; */
                 return 1;
             }
-            if (identity == VARIABLE && type == VOID)
-                error("cannot have void variables");
+            /* FIXME: we need to deal with extern properly here */
+            if (find_global (sname) > -1)
+                multidef (sname);
+            if (identity == VARIABLE)
+                notvoid(type);
             if (match ("[")) {
                 dim = needsub ();
                 //if (dim || storage == EXTERN) {
@@ -430,3 +431,9 @@ void multidef(char *symbol_name) {
     newline ();
 }
 
+
+void notvoid(int type)
+{
+    if (type == VOID)
+        error("cannot be void type");
+}