Mercurial > hg-old > index.cgi
view 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 source
/* 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; }