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
|
#include "rc.h"
Var *globals[1021] = { 0 };
struct Keyword {
ushort type;
char *name;
struct Keyword *link;
} *keywords[41];
// -----------------------------------------------------------------------
// utility
static
int
hash(char *s, int n)
{
int i = 1, h = 0;
while (*s)
h += *s++*i++;
h %= n;
return (h<0)?h+n:h;
}
// -----------------------------------------------------------------------
// keywords
static
void
putkw(int type, char *name)
{
struct Keyword *kw;
int h = hash(name, arrlen(keywords));
alloc(kw);
kw->type = type;
kw->name = name;
kw->link = keywords[h];
keywords[h] = kw;
}
void
initkw(void)
{
putkw(Tfor, "for");
putkw(Tin, "in");
putkw(Twhile, "while");
putkw(Tif, "if");
putkw(Telse, "else");
putkw(Tswitch, "switch");
putkw(Tcase, "case");
putkw(Tfunc, "func");
}
int
kwlookup(char *name)
{
int t;
struct Keyword *it;
for(t=-1,it = keywords[hash(name, arrlen(keywords))];it;it = it->link)
if(!strcmp(it->name, name))
t = it->type;
return t;
}
// -----------------------------------------------------------------------
// variables
Var *
newvar(char *name, Var *link)
{
Var *v;
alloc(v);
v->name = name;
v->val = 0;
v->func = nil;
v->funcnew = 0;
v->new = 0;
v->update = nil;
v->link = link;
return v;
}
/* only global lookup */
Var *
gvlookup(char *name)
{
Var *v;
int h = hash(name, arrlen(globals));
for (v = globals[h]; v; v = v->link)
if (!strcmp(v->name, name))
return v;
return globals[h] = newvar(strdup(name), globals[h]);
}
/* local + global lookup */
Var *
vlookup(char *name)
{
Var *v;
if (shell)
for (v = shell->local; v; v = v->link)
if (!strcmp(v->name, name))
return v;
return gvlookup(name);
}
static
void
set(char *name, Word *val, int call)
{
Var *v = vlookup(name);
freelist(v->val);
v->val = val;
v->new = 1;
if (call && v->update)
v->update(v);
}
void
setvar(char *name, Word *val)
{
set(name, val, 1);
}
|