forked from DoctorWkt/acwj
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsym.c
149 lines (125 loc) · 3.98 KB
/
sym.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "defs.h"
#include "data.h"
#include "decl.h"
// Symbol table functions
// Copyright (c) 2019 Warren Toomey, GPL3
// Determine if the symbol s is in the global symbol table.
// Return its slot position or -1 if not found.
// Skip C_PARAM entries
int findglob(char *s) {
int i;
for (i = 0; i < Globs; i++) {
if (Symtable[i].class == C_PARAM)
continue;
if (*s == *Symtable[i].name && !strcmp(s, Symtable[i].name))
return (i);
}
return (-1);
}
// Get the position of a new global symbol slot, or die
// if we've run out of positions.
static int newglob(void) {
int p;
if ((p = Globs++) >= Locls)
fatal("Too many global symbols");
return (p);
}
// Determine if the symbol s is in the local symbol table.
// Return its slot position or -1 if not found.
int findlocl(char *s) {
int i;
for (i = Locls + 1; i < NSYMBOLS; i++) {
if (*s == *Symtable[i].name && !strcmp(s, Symtable[i].name))
return (i);
}
return (-1);
}
// Get the position of a new local symbol slot, or die
// if we've run out of positions.
static int newlocl(void) {
int p;
if ((p = Locls--) <= Globs)
fatal("Too many local symbols");
return (p);
}
// Clear all the entries in the
// local symbol table
void freeloclsyms(void) {
Locls = NSYMBOLS - 1;
}
// Update a symbol at the given slot number in the symbol table. Set up its:
// + type: char, int etc.
// + structural type: var, function, array etc.
// + size: number of elements, or endlabel: end label for a function
// + posn: Position information for local symbols
static void updatesym(int slot, char *name, int type, int stype,
int class, int size, int posn) {
if (slot < 0 || slot >= NSYMBOLS)
fatal("Invalid symbol slot number in updatesym()");
Symtable[slot].name = strdup(name);
Symtable[slot].type = type;
Symtable[slot].stype = stype;
Symtable[slot].class = class;
Symtable[slot].size = size;
Symtable[slot].posn = posn;
}
// Add a global symbol to the symbol table. Set up its:
// + type: char, int etc.
// + structural type: var, function, array etc.
// + class of the symbol
// + size: number of elements, or endlabel: end label for a function
// Return the slot number in the symbol table
int addglob(char *name, int type, int stype, int class, int size) {
int slot;
// If this is already in the symbol table, return the existing slot
if ((slot = findglob(name)) != -1)
return (slot);
// Otherwise get a new slot and fill it in
slot = newglob();
updatesym(slot, name, type, stype, class, size, 0);
// Generate the assembly for the symbol if it's global
if (class == C_GLOBAL)
genglobsym(slot);
// Return the slot number
return (slot);
}
// Add a local symbol to the symbol table. Set up its:
// + type: char, int etc.
// + structural type: var, function, array etc.
// + size: number of elements
// Return the slot number in the symbol table, -1 if a duplicate entry
int addlocl(char *name, int type, int stype, int class, int size) {
int localslot;
// If this is already in the symbol table, return an error
if ((localslot = findlocl(name)) != -1)
return (-1);
// Otherwise get a new symbol slot and a position for this local.
// Update the local symbol table entry.
localslot = newlocl();
updatesym(localslot, name, type, stype, class, size, 0);
// Return the local symbol's slot
return (localslot);
}
// Given a function's slot number, copy the global parameters
// from its prototype to be local parameters
void copyfuncparams(int slot) {
int i, id = slot + 1;
for (i = 0; i < Symtable[slot].nelems; i++, id++) {
addlocl(Symtable[id].name, Symtable[id].type, Symtable[id].stype,
Symtable[id].class, Symtable[id].size);
}
}
// Determine if the symbol s is in the symbol table.
// Return its slot position or -1 if not found.
int findsymbol(char *s) {
int slot;
slot = findlocl(s);
if (slot == -1)
slot = findglob(s);
return (slot);
}
// Reset the contents of the symbol table
void clear_symtable(void) {
Globs = 0;
Locls = NSYMBOLS - 1;
}