From: Alan Cox Date: Fri, 24 Jun 2016 20:52:32 +0000 (+0100) Subject: scc: sort of add support for void types and the rest of functions X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=dc7bdad35ec516e731373aef98a49b23f822933f;p=FUZIX.git scc: sort of add support for void types and the rest of functions 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. --- diff --git a/Applications/SmallC/function.c b/Applications/SmallC/function.c index 26098afd..57ea3c60 100644 --- a/Applications/SmallC/function.c +++ b/Applications/SmallC/function.c @@ -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) { diff --git a/Applications/SmallC/lex.c b/Applications/SmallC/lex.c index 0f14b06b..51e7083a 100644 --- a/Applications/SmallC/lex.c +++ b/Applications/SmallC/lex.c @@ -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; } diff --git a/Applications/SmallC/main.c b/Applications/SmallC/main.c index fbefff9d..801e4a1d 100644 --- a/Applications/SmallC/main.c +++ b/Applications/SmallC/main.c @@ -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); diff --git a/Applications/SmallC/prototype.h b/Applications/SmallC/prototype.h index 36d42d63..3659188d 100644 --- a/Applications/SmallC/prototype.h +++ b/Applications/SmallC/prototype.h @@ -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); diff --git a/Applications/SmallC/stmt.c b/Applications/SmallC/stmt.c index c263556c..771409b1 100644 --- a/Applications/SmallC/stmt.c +++ b/Applications/SmallC/stmt.c @@ -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); diff --git a/Applications/SmallC/sym.c b/Applications/SmallC/sym.c index bafbc790..ae349c32 100644 --- a/Applications/SmallC/sym.c +++ b/Applications/SmallC/sym.c @@ -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"); +}