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 | #include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "error.h"
#include "symtab.h"
#include <utils/loc.h>
struct SymtabNode
{
const struct UStr *ident;
const struct Expr *val;
bool global;
struct SymtabNode *next;
} * symtab, *symtabLast;
static struct SymtabNode *
findSym(const struct UStr *ident)
{
for (struct SymtabNode *n = symtab; n; n = n->next) {
if (n->ident == ident) {
return n;
}
}
return 0;
}
static void
setSym(struct SymtabNode *n, const struct Expr *val)
{
assert(n);
n->val = val;
}
static struct SymtabNode *
addSym(const struct UStr *ident, const struct Expr *val)
{
struct SymtabNode *node = malloc(sizeof(*node));
if (!node) {
fprintf(stderr, "'addSym': out of memory\n");
exit(1);
}
node->ident = ident;
node->val = val;
node->global = false;
node->next = 0;
if (symtab) {
symtabLast = symtabLast->next = node;
} else {
symtab = symtabLast = node;
}
return node;
}
void
symtabSet(const struct UStr *ident, const struct Expr *val)
{
struct SymtabNode *n = findSym(ident);
if (n) {
setSym(n, val);
} else {
addSym(ident, val);
}
}
void
symtabGlobal(const struct UStr *ident)
{
struct SymtabNode *n = findSym(ident);
if (!n) {
n = addSym(ident, makeValExpr(nullLoc, UNKNOWN, 0));
}
n->global = true;
}
void
symtabGet(const struct UStr *ident, const struct UStr *recGuard,
enum ExprType *type, uint64_t *val)
{
struct SymtabNode *n = findSym(ident);
if (!n) {
n = addSym(ident, makeValExpr(nullLoc, UNKNOWN, 0));
}
*type = typeExpr(n->val);
if (ident == recGuard) {
error("symbol '%s' recursively defined\n", ident->cstr);
} else {
*val = evalExprWithRecGuard(n->val, recGuard ? recGuard : ident);
}
}
void
symtabPrint(FILE *out)
{
fprintf(out, "#SYMTAB\n");
for (struct SymtabNode *n = symtab; n; n = n->next) {
uint64_t val = evalExpr(n->val);
int type = typeExpr(n->val);
fprintf(out, "%c ", (char)(n->global ? toupper(type) : type));
fprintf(out, "%-20s ", n->ident->cstr);
fprintf(out, "0x%016" PRIX64 "\n", val);
}
}
|