Mercurial > hg-old > index.cgi
diff lwasm/symbol.c @ 363:d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
author | lost@starbug |
---|---|
date | Tue, 06 Apr 2010 21:03:19 -0600 |
parents | 7d91ab7ac7d6 |
children | 6b33faa21a0a |
line wrap: on
line diff
--- a/lwasm/symbol.c Thu Apr 01 20:56:19 2010 -0600 +++ b/lwasm/symbol.c Tue Apr 06 21:03:19 2010 -0600 @@ -65,7 +65,7 @@ } if (islocal) - context = as -> context; + context = cl -> context; // first, look up symbol to see if it is already defined for (se = as -> symtab.head; se; se = se -> next) @@ -95,6 +95,10 @@ version++; } + // symplify the symbol expression - replaces "SET" symbols with + // symbol table entries + lwasm_reduce_expr(as, val); + se = lw_alloc(sizeof(struct symtabe)); se -> next = as -> symtab.head; as -> symtab.head = se; @@ -105,7 +109,53 @@ return se; } -struct symtabe * lookup_symbol(asmstate_t *as, line_t *cl, char *sym, int context, int version) +// for "SET" symbols, always returns the LAST definition of the +// symbol. This works because the lwasm_reduce_expr() call in +// register_symbol will ensure there are no lingering "var" references +// to the set symbol anywhere in the symbol table; they will all be +// converted to direct references +// NOTE: this means that for a forward reference to a SET symbol, +// the LAST definition will be the one used. +// This arrangement also ensures that any reference to the symbol +// itself inside a "set" definition will refer to the previous version +// of the symbol. +struct symtabe * lookup_symbol(asmstate_t *as, line_t *cl, char *sym) { - return NULL; + int local = 0; + struct symtabe *s, *s2; + + // check if this is a local symbol + if (strchr(sym, '@') || strchr(sym, '?')) + local = 1; + + if (cl && !CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) + local = 1; + if (!cl && !(as -> pragmas & PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) + local = 1; + + // cannot look up local symbol in global context!!!!! + if (!cl && local) + return NULL; + + for (s = as -> symtab.head, s2 = NULL; s; s = s -> next) + { + if (!strcmp(sym, s -> symbol)) + { + if (local && s -> context != cl -> context) + continue; + + if (s -> flags & symbol_flag_set) + { + // look for highest version of symbol + if (s -> version > s2 -> version) + s2 = s; + continue; + } + break; + } + } + if (!s && s2) + s = s2; + + return s; }