comparison src/symtab.c @ 0:57495da01900

Initial checking of LWASM
author lost
date Fri, 03 Oct 2008 02:44:20 +0000
parents
children 34568fab6058
comparison
equal deleted inserted replaced
-1:000000000000 0:57495da01900
1 /*
2 * symtab.c
3 *
4 * main code for lwasm
5 */
6
7 #include <ctype.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #define __symtab_c_seen__
13 #include "lwasm.h"
14
15 void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags)
16 {
17 symtab_t *st;
18 symtab_t *prev;
19 int cv = -2;
20
21 for (prev = NULL, st = as -> symbol_table; st; st = st -> next)
22 {
23 cv = strcasecmp(st -> symbol, symstr);
24 if (cv == 0)
25 {
26 cv = strcmp(st -> symbol, symstr);
27 }
28 if (cv >= 0)
29 break;
30 prev = st;
31 }
32 // cv is 0 if we found the symbol, > 0 if we didn't and found one
33 // later in order, or -2 if we never did a comparison
34 // if st is NULL, the value of cv is irrelevant as it means
35 // we fell off the end of the list
36 // if st is NULL and prev is not, then prev is the tail of the list
37 // if both are NULL, the list is empty
38
39 // handle adding the symbol if needed
40 if (!st || cv != 0)
41 {
42 symtab_t *st2;
43 // register the symbol
44 st2 = malloc(sizeof(symtab_t));
45 st2 -> symbol = strdup(symstr);
46 st2 -> addr = val;
47 st2 -> flags = 0;
48 if (flags & SYMFLAG_SET)
49 st2 -> flags |= SYMFLAG_SET;
50
51 if (prev)
52 prev -> next = st2;
53 else
54 as -> symbol_table = st2;
55
56 st2 -> next = st;
57 return;
58 }
59
60 // st is NOT NULL here and cv IS 0
61 if ((flags & SYMFLAG_SET) && ((st -> flags) & SYMFLAG_SET))
62 {
63 // symbol already exists but it is a "SET" symbol so reset the value
64 st -> addr = val;
65 return;
66 }
67 if (st && as -> passnum == 1)
68 {
69 // duplicate symbol, flag error
70 errorp1(ERR_DUPSYM);
71 }
72 if (st -> addr != val)
73 errorp2(ERR_PHASE);
74 }
75
76 int lookup_symbol(asmstate_t *as, char *symstr)
77 {
78 symtab_t *st;
79
80 for (st = as -> symbol_table; st; st = st -> next)
81 {
82 if (!strcmp(symstr, st -> symbol))
83 break;
84 }
85 if (st)
86 return st -> addr;
87 return -1;
88 }
89
90 void list_symbols(asmstate_t *as, FILE *f)
91 {
92 symtab_t *st;
93 for (st = as -> symbol_table; st; st = st -> next)
94 {
95 fprintf(f, "%04X %s%s\n", st -> addr, st -> symbol, (st -> flags & SYMFLAG_SET) ? "(S)" : "");
96 }
97 }