# HG changeset patch # User lost@l-w.ca # Date 1296795647 25200 # Node ID 49d608aecc4d1b41bfa9f051ba1f03c2dbd3e284 # Parent 574931d87abde44b7e6abeb101d1bb1bc5e607bd Framework for handling local stack frame and/or variables diff -r 574931d87abd -r 49d608aecc4d lwbasic/emit.c --- a/lwbasic/emit.c Thu Feb 03 21:28:24 2011 -0700 +++ b/lwbasic/emit.c Thu Feb 03 22:00:47 2011 -0700 @@ -28,24 +28,24 @@ #define __emit_c_seen__ #include "lwbasic.h" -void emit_prolog(cstate *state, int vis, int framesize) +void emit_prolog(cstate *state, int vis) { if (vis) { printf("\texport _%s\n", state -> currentsub); } printf("_%s\n", state -> currentsub); - if (framesize > 0) + if (state -> framesize > 0) { - printf("\tleas %d,s\n", -framesize); + printf("\tleas %d,s\n", -(state -> framesize)); } } -void emit_epilog(cstate *state, int framesize) +void emit_epilog(cstate *state) { - if (framesize > 0) + if (state -> framesize > 0) { - printf("\tleas %d,s\n", framesize); + printf("\tleas %d,s\n", state -> framesize); } printf("\trts\n"); } diff -r 574931d87abd -r 49d608aecc4d lwbasic/lwbasic.h --- a/lwbasic/lwbasic.h Thu Feb 03 21:28:24 2011 -0700 +++ b/lwbasic/lwbasic.h Thu Feb 03 22:00:47 2011 -0700 @@ -28,6 +28,8 @@ #include +#include "symtab.h" + /* note: integer and uinteger will be the same for positive values from 0 through 0x7FFFFFFF; the unsigned type should be used for doing ascii conversions and then if a negative value was discovered, it should be @@ -57,6 +59,10 @@ void *input_state; char *currentsub; + symtab_t *global_syms; + symtab_t *local_syms; + int returntype; + int framesize; } cstate; /* parser states */ @@ -87,6 +93,15 @@ token_eof /* end of file */ }; +/* symbol types */ +enum +{ + symtype_sub, /* "sub" (void function) */ + symtype_func, /* function (nonvoid) */ + symtype_param, /* function parameter */ + symtype_var /* variable */ +}; + #ifndef __input_c_seen__ extern int input_getchar(cstate *state); #endif @@ -101,8 +116,8 @@ #endif #ifndef __emit_c_seen__ -extern void emit_prolog(cstate *state, int vis, int framesize); -extern void emit_epilog(cstate *state, int framesize); +extern void emit_prolog(cstate *state, int vis); +extern void emit_epilog(cstate *state); #endif diff -r 574931d87abd -r 49d608aecc4d lwbasic/parser.c --- a/lwbasic/parser.c Thu Feb 03 21:28:24 2011 -0700 +++ b/lwbasic/parser.c Thu Feb 03 22:00:47 2011 -0700 @@ -29,6 +29,15 @@ #include #include "lwbasic.h" +#include "symtab.h" + + +/* size of a type */ +static int sizeof_type(int type) +{ + /* everything is an "int" right now; 2 bytes */ + return 2; +} /* parse a type; the next token will be acquired as a result */ /* the token advancement is to provide consistency */ @@ -50,14 +59,30 @@ return pt; } +static void parse_decls(cstate *state) +{ + /* declarations */ + switch (state -> lexer_token) + { + default: + return; + } +} + /* issub means RETURNS is not allowed; !issub means RETURNS is required */ + static void parse_subfunc(cstate *state, int issub) { - int pt; - char *subname; + int pt, rt; + char *subname, *pn; int vis = 0; - + symtab_entry_t *se; + int paramsize = 0; + + state -> local_syms = symtab_init(); + state -> framesize = 0; + lexer(state); if (state -> lexer_token != token_identifier) { @@ -86,7 +111,7 @@ { lwb_error("Parameter name expected, got %s\n", lexer_return_token(state)); } - printf("Got = %s\n", state -> lexer_token_string); + pn = lw_strdup(state -> lexer_token_string); lexer(state); if (state -> lexer_token != token_kw_as) @@ -94,7 +119,15 @@ lexer(state); pt = parse_type(state); - printf("Got = %d\n", pt); + + se = symtab_find(state -> local_syms, pn); + if (se) + { + lwb_error("Duplicate parameter name %s\n", pn); + } + symtab_register(state -> local_syms, pn, paramsize, symtype_param, NULL); + paramsize += sizeof_type(pt); + lw_free(pn); if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') { @@ -102,26 +135,26 @@ goto paramagain; } -noparms: +noparms: + rt = -1; if (!issub) { - int rt; - if (state -> lexer_token != token_kw_returns) { lwb_error("FUNCTION must have RETURNS\n"); } lexer(state); - if (state -> lexer_token == token_identifier) +/* if (state -> lexer_token == token_identifier) { printf("Return value named: %s\n", state -> lexer_token_string); + lexer(state); if (state -> lexer_token != token_kw_as) lwb_error("Execting AS after RETURNS"); lexer(state); } +*/ rt = parse_type(state); - printf("Return type: %d\n", rt); } else { @@ -138,21 +171,27 @@ } - printf("Sub/Func %s, vis %s\n", subname, vis ? "public" : "private"); + se = symtab_find(state -> global_syms, subname); + if (se) + { + lwb_error("Multiply defined symbol %s\n", subname); + } + + symtab_register(state -> global_syms, subname, -1, issub ? symtype_sub : symtype_func, NULL); state -> currentsub = subname; - + state -> returntype = rt; /* consume EOL */ lexer(state); /* variable declarations */ - /* parse_decls(state); */ + parse_decls(state); /* output function/sub prolog */ - emit_prolog(state, vis, 0); + emit_prolog(state, vis); /* parse statement block */ - /* parse_statemetns(state); */ + /* parse_statements(state); */ if (issub) { @@ -169,17 +208,19 @@ } } /* output function/sub epilog */ - emit_epilog(state, 0); + emit_epilog(state); lw_free(state -> currentsub); state -> currentsub = NULL; - + symtab_destroy(state -> local_syms); + state -> local_syms = NULL; } void parser(cstate *state) { state -> lexer_curchar = -1; - + state -> global_syms = symtab_init(); + /* now look for a global declaration */ for (;;) { diff -r 574931d87abd -r 49d608aecc4d lwbasic/symtab.c --- a/lwbasic/symtab.c Thu Feb 03 21:28:24 2011 -0700 +++ b/lwbasic/symtab.c Thu Feb 03 22:00:47 2011 -0700 @@ -50,6 +50,7 @@ se = st -> head; st -> head = se -> next; lw_free(se -> name); + lw_free(se -> privdata); lw_free(se); } lw_free(st); @@ -67,7 +68,7 @@ return NULL; } -void symtab_register(symtab_t *st, char *name, int addr, int symtype) +void symtab_register(symtab_t *st, char *name, int addr, int symtype, void *privdata) { symtab_entry_t *se; @@ -75,6 +76,7 @@ se -> name = lw_strdup(name); se -> addr = addr; se -> symtype = symtype; + se -> privdata = privdata; se -> next = st -> head; st -> head = se; } diff -r 574931d87abd -r 49d608aecc4d lwbasic/symtab.h --- a/lwbasic/symtab.h Thu Feb 03 21:28:24 2011 -0700 +++ b/lwbasic/symtab.h Thu Feb 03 22:00:47 2011 -0700 @@ -42,7 +42,7 @@ char *name; /* name of the symbol */ int addr; /* address of symbol */ int symtype; /* type of symbol */ - + void *privdata; /* random data associated with symbol */ symtab_entry_t *next; /* next in the list */ }; @@ -54,7 +54,7 @@ __E symtab_t *symtab_init(void); __E void symtab_destroy(symtab_t *st); __E symtab_entry_t *symtab_find(symtab_t *st, char *name); -__E void symtab_register(symtab_t *st, char *name, int addr, int symtype); +__E void symtab_register(symtab_t *st, char *name, int addr, int symtype, void *data); #undef __E