Mercurial > hg-old > index.cgi
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 } |