Mercurial > hg-old > index.cgi
view src/lwasm.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 | 9bd0fbfe7405 |
children | 9bd584bb6296 |
line wrap: on
line source
/* lwasm.c Copyright © 2008 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/>. Contains random functions used by the assembler */ #define __lwasm_c_seen__ #include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include "lwasm.h" #include "util.h" #include "expr.h" int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...) { lwasm_error_t *e; va_list args; char errbuff[1024]; int r; if (as -> passnum != pass) return; va_start(args, fmt); e = lwasm_alloc(sizeof(lwasm_error_t)); e -> next = l -> err; l -> err = e; as -> errorcount++; r = vsnprintf(errbuff, 1024, fmt, args); e -> mess = lwasm_strdup(errbuff); va_end(args); return r; } void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b) { as -> addr += 1; if (as -> passnum == 1) return; fprintf(stderr, "FIXME: trying to emit code in pass 2 but not implemented.\n"); } void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o) { if (o >= 0x100) lwasm_emit(as, l, o >> 8); lwasm_emit(as, l, o & 0xff); } int lwasm_lookupreg2(const char *reglist, char **str) { int rval = 0; while (*reglist) { if (toupper(**str) == *reglist) { // first char matches if (reglist[1] == ' ' && !isalpha(*(*str + 1))) break; if (toupper(*(*str + 1)) == reglist[1]) break; } reglist += 2; rval++; } if (!*reglist) return -1; if (reglist[1] == ' ') (*str)++; else (*str) += 2; return rval; } int lwasm_lookupreg3(const char *rlist, const char **str) { int rval = 0; int f = 0; const char *reglist = rlist; while (*reglist) { if (toupper(**str) == *reglist) { // first char matches if (reglist[1] == ' ') { f = 1; break; } if (toupper(*(*str + 1)) == reglist[1]) { // second char matches if (reglist[2] == ' ') { f = 1; break; } if (toupper(*(*str + 2)) == reglist[2]) { f = 1; break; } } } reglist += 3; rval++; } if (f == 0) return -1; reglist = rval * 3 + rlist; if (reglist[1] == ' ') (*str) += 1; else if (reglist[2] == ' ') (*str) += 2; else (*str)+=3; return rval; } struct symstateinfo { asmstate_t *as; lwasm_line_t *l; }; int lwasm_expr_lookup_symbol(char *sym, void *state, int *val) { lwasm_symbol_ent_t *se; struct symstateinfo *st; st = state; // look for local symbol first then global symbol se = lwasm_find_symbol(st -> as, sym, st -> as -> context); if (!se) se = lwasm_find_symbol(st -> as, sym, -1); if (!se) return -1; *val = se -> value; return 0; } lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp) { struct symstateinfo st; st.as = as; st.l = l; return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); }