-
Notifications
You must be signed in to change notification settings - Fork 0
/
UwUpp_symtab.py
83 lines (62 loc) · 2.7 KB
/
UwUpp_symtab.py
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
#########################################################################
# symbol table for UwU++
#
# it is a scoped symbol table with a dictionary at each scope level
#
#########################################################################
CURR_SCOPE = 0
class SymTab:
def __init__(self):
# global scope dictionary must always be present
self.scoped_symtab = [{}]
def get_config(self):
# we make a shallow copy of the symbol table
return list(self.scoped_symtab)
def set_config(self, c):
self.scoped_symtab = c
def push_scope(self):
# push a new dictionary onto the stack - stack grows to the left
self.scoped_symtab.insert(CURR_SCOPE,{})
def pop_scope(self):
# pop the left most dictionary off the stack
if len(self.scoped_symtab) == 1:
raise ValueError("cannot pop the global scope")
else:
self.scoped_symtab.pop(CURR_SCOPE)
def declare_scalar(self, sym, init):
# declare the scalar in the current scope: dict @ position 0
# first we need to check whether the symbol was already declared
# at this scope
if sym in self.scoped_symtab[CURR_SCOPE]:
raise ValueError("symbol {} already declared".format(sym))
# enter the symbol in the current scope
self.scoped_symtab[CURR_SCOPE].update({sym:('scalar', init)})
def declare_fun(self, sym, init):
# declare a function in the current scope: dict @ position 0
# first we need to check whether the symbol was already declared
# at this scope
if sym in self.scoped_symtab[CURR_SCOPE]:
raise ValueError("symbol {} already declared".format(sym))
# enter the function in the current scope
self.scoped_symtab[CURR_SCOPE].update({sym:('function', init)})
def lookup_sym(self, sym):
# find the first occurence of sym in the symtab stack
# and return the associated value
n_scopes = len(self.scoped_symtab)
for scope in range(n_scopes):
if sym in self.scoped_symtab[scope]:
val = self.scoped_symtab[scope].get(sym)
return val
# not found
raise ValueError("{} was not declared".format(sym))
def update_sym(self, sym, val):
# find the first occurence of sym in the symtab stack
# and update the associated value
n_scopes = len(self.scoped_symtab)
for scope in range(n_scopes):
if sym in self.scoped_symtab[scope]:
scope_dict = self.scoped_symtab[scope]
scope_dict[sym] = val
return
# not found
raise ValueError("{} was not declared".format(sym))