Mercurial > hg-old > index.cgi
diff src/symtab.c @ 0:57495da01900
Initial checking of LWASM
author | lost |
---|---|
date | Fri, 03 Oct 2008 02:44:20 +0000 |
parents | |
children | 34568fab6058 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/symtab.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,97 @@ +/* + * symtab.c + * + * main code for lwasm + */ + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define __symtab_c_seen__ +#include "lwasm.h" + +void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags) +{ + symtab_t *st; + symtab_t *prev; + int cv = -2; + + for (prev = NULL, st = as -> symbol_table; st; st = st -> next) + { + cv = strcasecmp(st -> symbol, symstr); + if (cv == 0) + { + cv = strcmp(st -> symbol, symstr); + } + if (cv >= 0) + break; + prev = st; + } + // cv is 0 if we found the symbol, > 0 if we didn't and found one + // later in order, or -2 if we never did a comparison + // if st is NULL, the value of cv is irrelevant as it means + // we fell off the end of the list + // if st is NULL and prev is not, then prev is the tail of the list + // if both are NULL, the list is empty + + // handle adding the symbol if needed + if (!st || cv != 0) + { + symtab_t *st2; + // register the symbol + st2 = malloc(sizeof(symtab_t)); + st2 -> symbol = strdup(symstr); + st2 -> addr = val; + st2 -> flags = 0; + if (flags & SYMFLAG_SET) + st2 -> flags |= SYMFLAG_SET; + + if (prev) + prev -> next = st2; + else + as -> symbol_table = st2; + + st2 -> next = st; + return; + } + + // st is NOT NULL here and cv IS 0 + if ((flags & SYMFLAG_SET) && ((st -> flags) & SYMFLAG_SET)) + { + // symbol already exists but it is a "SET" symbol so reset the value + st -> addr = val; + return; + } + if (st && as -> passnum == 1) + { + // duplicate symbol, flag error + errorp1(ERR_DUPSYM); + } + if (st -> addr != val) + errorp2(ERR_PHASE); +} + +int lookup_symbol(asmstate_t *as, char *symstr) +{ + symtab_t *st; + + for (st = as -> symbol_table; st; st = st -> next) + { + if (!strcmp(symstr, st -> symbol)) + break; + } + if (st) + return st -> addr; + return -1; +} + +void list_symbols(asmstate_t *as, FILE *f) +{ + symtab_t *st; + for (st = as -> symbol_table; st; st = st -> next) + { + fprintf(f, "%04X %s%s\n", st -> addr, st -> symbol, (st -> flags & SYMFLAG_SET) ? "(S)" : ""); + } +}