Mercurial > hg-old > index.cgi
diff src/symbol.c @ 37:538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
author | lost |
---|---|
date | Sat, 03 Jan 2009 04:20:49 +0000 |
parents | |
children | d2cee0c335e7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/symbol.c Sat Jan 03 04:20:49 2009 +0000 @@ -0,0 +1,120 @@ +/* +symbol.c +Copyright © 2009 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* +for handling the symbol table +*/ + +#define __symbol_c_seen__ + +#include <string.h> + +#include "lwasm.h" +#include "util.h" + +int lwasm_register_symbol(asmstate_t *as, lwasm_line_t *l, char *sym, int val) +{ + lwasm_symbol_ent_t *se, *se2; + char *p; + + int scontext = -1; + + // first check if the symbol is valid + // the following characters are allowed in a symbol: + // [a-zA-Z0-9._$?@] and any byte value larger than 0x7F + // although symbols should be restricted to the 7 bit range + // symbols must start with [a-zA-Z._] + if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._@?", *sym)) + { + register_error(as, l, 1, "Bad symbol: %s", sym); + return -1; + } + + for (p = sym; *p; p++) + { + if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._$?@0123456789", *sym) && (unsigned char)*sym < 0x80) + { + register_error(as, l, 1, "Bad symbol: %s", sym); + return -1; + } + // flag local symbols while we're at it... + if (*p == '?' || *p == '@') + scontext = as -> context; + } + + // now look it for to see if it is a duplicate + se = lwasm_find_symbol(as, sym, scontext); + if (se) + { + register_error(as, l, 1, "Mulitply defined symbol: %s", sym); + return -1; + } + + // if not a duplicate, register it with the value + se = lwasm_alloc(sizeof(lwasm_symbol_ent_t)); + if (as -> symhead) + { + se -> prev = NULL; + se -> next = as -> symhead; + as -> symhead -> prev = se; + as -> symhead = se; + } + else + { + se -> next = NULL; + se -> prev = NULL; + as -> symhead = se; + as -> symtail = se; + } + se -> value = val; + se -> sym = lwasm_strdup(sym); + se -> context = scontext; + + return 0; +} + +lwasm_symbol_ent_t *lwasm_find_symbol(asmstate_t *as, char *sym, int scontext) +{ + lwasm_symbol_ent_t *se; + + for (se = as -> symhead; se; se = se -> next) + { + if (scontext == se -> context && !strcmp(sym, se -> sym)) + { + return se; + } + } + return NULL; +} + +// reset the value of a symbol - should not be used normally +// it is intended for use by such operations as EQU +// returns -1 if the symbol is not registered +int lwasm_set_symbol(asmstate_t *as, char *sym, int scontext, int val) +{ + lwasm_symbol_ent_t *se; + + se = lwasm_find_symbol(as, sym, scontext); + if (!se) + return -1; + + se -> value = val; + return 0; +}