From d996f1e3e9c53f4c689cb086dc4b4d27fbfcd898 Mon Sep 17 00:00:00 2001
From: Xun Yang <x299yang@uwaterloo.ca>
Date: Mon, 24 Feb 2020 23:33:00 -0500
Subject: [PATCH] add more lower level nodes

---
 AST.py         | 16 --------------
 MemberNodes.py | 27 ++++++++++-------------
 UnitNodes.py   | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 31 deletions(-)

diff --git a/AST.py b/AST.py
index 88e71d0..3e89f96 100644
--- a/AST.py
+++ b/AST.py
@@ -73,19 +73,3 @@ def getParseTreeNodes(names, tree, terminateList = []):
         else:
             result.extend(getParseTreeNodes(names, n))
     return result
-
-
-# input: a parse tree node with its name == 'type'
-# output: (isPrimitiveType: Bool, typeName: String) of a type
-def getTypeName(node):
-    isPrimType = False
-    typeName = ''
-    nameNodes = getParseTreeNodes(['BOOLEAN', 'BYTE', 'CHAR', 'INT', 'SHORT'], node)
-    if nameNodes:
-        isPrimType = True
-    else:
-        # get refType
-        nameNodes = getParseTreeNodes(['ID', 'COMPID'], node)
-    for n in nameNodes:
-        typeName = n.lex
-    return (isPrimType, typeName)
diff --git a/MemberNodes.py b/MemberNodes.py
index 6a212d7..13e0270 100644
--- a/MemberNodes.py
+++ b/MemberNodes.py
@@ -1,6 +1,6 @@
-from AST import ASTNode, getParseTreeNodes, getTypeName
+from AST import ASTNode, getParseTreeNodes
 from LineNodes import BlockNode
-from WordNodes import makeNodeFromExpr
+from ExprPrimaryNodes import makeNodeFromExpr, TypeNode
 from Environment import Env
 from collections import OrderedDict
 
@@ -13,7 +13,6 @@ class FieldNode(ASTNode):
         self.fieldType = ''
         self.fieldInit = None
         self.mods = []
-        self.isPrimType = False # easy boolean flag, can be optimize later
         self.env = None
         self.children = []
 
@@ -24,7 +23,7 @@ class FieldNode(ASTNode):
                     self.mods.append(m.lex)
 
             elif node.name == 'type':
-                self.isPrimType, self.fieldType = getTypeName(node)
+                self.fieldType = TypeNode(node)
 
             elif node.name == 'variableDcl':
                 nameNodes = getParseTreeNodes(['ID', 'COMPID'], node, ['variableInit'])
@@ -46,11 +45,10 @@ class MethodNode(ASTNode):
         self.parseTree = parseTree
         self.name = ''
         self.methodType = ''
-        self.params = OrderedDict() # a dictionary {paramName -> (isPrimType, typeName)}, after type linking: {paramName -> typeNode}
+        self.params = [] # a list of tuples (paramName, typeNode)
         self.mods = []
         self.body = None
-        self.isPrimType = False # easy boolean flag, can be optimize later
-        self.paramTypes = '' # a string of param types for easy type checking against arguments
+        self.paramTypes = '' # a string of param types (signature) for easy type checking against arguments
         self.env = None
         self.children = []
 
@@ -66,19 +64,18 @@ class MethodNode(ASTNode):
             paramType = ''
             for c in n.children:
                 if c.name == 'type':
-                    paramType = getTypeName(c)
+                    paramType = TypeNode(c)
                 elif c.name == 'ID':
                     paramName = c.lex
-            self.params[paramName] = paramType
-            self.paramTypes += paramType[1] + ","
+            self.params.append(paramName, paramType)
+            self.paramTypes += paramType.name + ","
 
         nameNodes = getParseTreeNodes(['type', 'VOID'], parseTree, ['methodBody', 'params'])
         for n in nameNodes:
             if n.name == 'VOID':
-                self.isPrimType = True
-                self.methodType = n.lex
+                self.methodType = TypeNode('VOID')
             else:
-                self.isPrimType, self.methodType = getTypeName(n)
+                self.methodType = TypeNode(n)
 
         for node in parseTree.children:
             if node.name == 'methodMod':
@@ -96,8 +93,8 @@ class MethodNode(ASTNode):
     def buildEnv(self, parentEnv):
         env = Env(parentEnv)
         i = 0
-        for k, v in self.params:
-            key = (k, 'expr')
+        for p in self.params:
+            key = (p[0], 'expr')
             if key in env.map:
                 raise Exception('ERROR: Declaration of {} is already in current Environment'.format(node.name))
             env.map[key] = (True, i)
diff --git a/UnitNodes.py b/UnitNodes.py
index 8b13789..2514144 100644
--- a/UnitNodes.py
+++ b/UnitNodes.py
@@ -1 +1,61 @@
+from AST import ASTNode, getParseTreeNodes
+from Environment import Env
 
+#   LiteralNode
+#   TypeNode
+# param
+
+
+#################################################################################
+# literals
+class LiteralNode(ASTNode):
+    toLiType = dict({
+        'LITERALBOOL': 'bool',
+        'LITERALCHAR': 'char',
+        'LITERALSTRING': 'String',
+        'NULL': 'null',
+        'NUM': 'int',
+        'ZERO': 'int'
+    })
+    # always list all fields in the init method to show the class structure
+    def __init__(self, parseTree):
+        self.parseTree = parseTree
+        self.liType = toLiType.get(parseTree.children[0].name)  # type of the literal
+        self.value = parseTree.children[0].lex # the value
+        self.env = None
+        self.children = []
+
+        if self.liType == 'int':
+            self.value = int(self.value)
+        if self.liType == 'LITERALBOOL':
+            if self.value == 'false':
+                self.value = False
+            else:
+                self.value = True
+
+
+##################################################################################
+# type: primitiveType, ArrayType, RefType
+class TypeNode(ASTNode):
+    # always list all fields in the init method to show the class structure
+    def __init__(self, parseTree):
+        self.parseTree = parseTree
+        self.name = ''
+        self.isArray = False
+        self.isPrimitive = False
+        self.env = None
+        self.children = []
+
+        if parseTree == 'VOID':
+            self.name = 'void'
+            self.isPrimitive = True
+        else:
+            nameNodes = getParseTreeNodes(['BOOLEAN', 'BYTE', 'CHAR', 'INT', 'SHORT'], parseTree)
+            if nameNodes:
+                self.isPrimType = True
+            else:
+                self.name = getParseTreeNodes(['ID', 'COMPID'], parseTree)[0].lex
+
+            nameNodes = getParseTreeNodes(['LSQRBRACK'], parseTree)
+            if nameNodes:
+                self.isArray = True
-- 
GitLab