mirror of https://github.com/captn3m0/nand2tetris
Initial work on a Symbol Table abstraction
parent
66efa72230
commit
3b541898e2
@ -0,0 +1,48 @@
|
||||
from constants import SymbolType
|
||||
|
||||
class SymbolTable:
|
||||
def __init__(self):
|
||||
self.subroutineTable = {}
|
||||
self.classTable = {}
|
||||
self.subroutineIndex = 0
|
||||
self.classIndex = 0
|
||||
|
||||
def startSubroutine(self):
|
||||
self.subroutineTable = {}
|
||||
|
||||
def define(self, name, var_type, kind):
|
||||
if (kind in [SymbolType.STATIC, SymbolType.FIELD]):
|
||||
self.classTable[name] = (var_type, kind, self.classIndex)
|
||||
self.classIndex += 1
|
||||
elif (kind in [SymbolType.ARG, SymbolType.VAR]):
|
||||
self.subroutineTable[name] = (var_type, kind, self.subroutineIndex)
|
||||
self.subroutineIndex += 1
|
||||
else:
|
||||
raise Exception("Invalid SymbolType")
|
||||
|
||||
def varCount(self, kind):
|
||||
t = None
|
||||
if (kind in [SymbolType.STATIC, SymbolType.FIELD]):
|
||||
t = self.classTable
|
||||
elif (kind in [SymbolType.ARG, SymbolType.VAR]):
|
||||
t = self.subroutineTable
|
||||
else:
|
||||
raise Exception("Invalid SymbolType")
|
||||
return len([i for i in t.values() if i[1] == kind])
|
||||
|
||||
def _lookup(self, name, index):
|
||||
if name in self.classTable:
|
||||
return self.classTable[name][index]
|
||||
elif name in self.subroutineTable:
|
||||
return self.subroutineTable[name][index]
|
||||
else:
|
||||
raise Exception("Invalid variable name")
|
||||
|
||||
def TypeOf(self, name):
|
||||
return self._lookup(name, 0)
|
||||
|
||||
def KindOf(self, name):
|
||||
return self._lookup(name, 1)
|
||||
|
||||
def IndexOf(self, name):
|
||||
return self._lookup(name, 2)
|
@ -0,0 +1,53 @@
|
||||
from symboltable import SymbolTable
|
||||
from constants import SymbolType
|
||||
def test_st_init():
|
||||
st = SymbolTable()
|
||||
assert(st.subroutineTable == {})
|
||||
assert(st.classTable == {})
|
||||
|
||||
def test_st_define():
|
||||
st = SymbolTable()
|
||||
st.define("first", "int", SymbolType.STATIC)
|
||||
st.define("second", "SomeClass", SymbolType.FIELD)
|
||||
st.define("third", "String", SymbolType.ARG)
|
||||
st.define("fourth", "bool", SymbolType.VAR)
|
||||
|
||||
assert(st.classTable == {
|
||||
"first": ("int", SymbolType.STATIC, 0),
|
||||
"second": ("SomeClass", SymbolType.FIELD, 1),
|
||||
})
|
||||
|
||||
assert(st.subroutineTable == {
|
||||
"third": ("String", SymbolType.ARG, 0),
|
||||
"fourth": ("bool", SymbolType.VAR, 1),
|
||||
})
|
||||
|
||||
def test_subroutine():
|
||||
st = SymbolTable()
|
||||
st.define("first", "int", SymbolType.ARG)
|
||||
st.startSubroutine()
|
||||
assert(st.subroutineTable == {})
|
||||
|
||||
def test_var_count():
|
||||
st = SymbolTable()
|
||||
st.define("first", "int", SymbolType.STATIC)
|
||||
st.define("second", "SomeClass", SymbolType.FIELD)
|
||||
st.define("third", "String", SymbolType.ARG)
|
||||
st.define("fourth", "bool", SymbolType.VAR)
|
||||
|
||||
assert(st.varCount(SymbolType.STATIC) == 1)
|
||||
assert(st.varCount(SymbolType.FIELD) == 1)
|
||||
assert(st.varCount(SymbolType.ARG) == 1)
|
||||
assert(st.varCount(SymbolType.VAR) == 1)
|
||||
|
||||
def test_lookups():
|
||||
st = SymbolTable()
|
||||
st.define("first", "int", SymbolType.STATIC)
|
||||
st.define("second", "SomeClass", SymbolType.FIELD)
|
||||
st.define("third", "String", SymbolType.ARG)
|
||||
st.define("fourth", "bool", SymbolType.VAR)
|
||||
|
||||
assert(st.KindOf("first") == SymbolType.STATIC)
|
||||
assert(st.TypeOf("second") == "SomeClass")
|
||||
assert(st.IndexOf("third") == 0)
|
||||
assert(st.IndexOf("fourth") == 1)
|
Loading…
Reference in New Issue