Initial work on a Symbol Table abstraction
This commit is contained in:
parent
66efa72230
commit
3b541898e2
|
@ -1,4 +1,4 @@
|
||||||
from enum import IntFlag,auto
|
from enum import IntFlag,auto,Enum
|
||||||
|
|
||||||
class PrintableFlag(IntFlag):
|
class PrintableFlag(IntFlag):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -106,3 +106,9 @@ class Token(PrintableFlag):
|
||||||
STRINGCONSTANT = Atom.STRINGCONSTANT.value
|
STRINGCONSTANT = Atom.STRINGCONSTANT.value
|
||||||
SYMBOL = auto()
|
SYMBOL = auto()
|
||||||
KEYWORD = auto()
|
KEYWORD = auto()
|
||||||
|
|
||||||
|
class SymbolType(Enum):
|
||||||
|
STATIC = auto()
|
||||||
|
FIELD = auto()
|
||||||
|
ARG = auto()
|
||||||
|
VAR = auto()
|
|
@ -1,5 +1,5 @@
|
||||||
from tokenizer import JackTokenizer
|
from tokenizer import JackTokenizer
|
||||||
from keywords import *
|
from constants import *
|
||||||
from grammar import *
|
from grammar import *
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from keywords import Atom
|
from constants import Atom
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The grammar is defined by the following constructs:
|
The grammar is defined by the following constructs:
|
||||||
|
|
|
@ -2,12 +2,11 @@ from engine import Engine
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__' and len(sys.argv) > 1:
|
||||||
p = Path(sys.argv[1])
|
p = Path(sys.argv[1])
|
||||||
if p.is_dir():
|
if p.is_dir():
|
||||||
for f in p.glob("*.jack"):
|
for f in p.glob("*.jack"):
|
||||||
print("compiling %s" % f)
|
print("compiling %s" % f)
|
||||||
Engine(f.as_posix()).compileClass()
|
Engine(f.as_posix()).compileClass()
|
||||||
elif p.is_file():
|
elif p.is_file():
|
||||||
Engine(p.as_posix()).compileClass()
|
Engine(p.as_posix()).compileClass()
|
||||||
|
|
|
@ -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)
|
|
@ -1,5 +1,5 @@
|
||||||
import re
|
import re
|
||||||
from keywords import *
|
from constants import *
|
||||||
from html import escape
|
from html import escape
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
# Superclass in some sense
|
# Superclass in some sense
|
||||||
|
|
Loading…
Reference in New Issue