Browse Source

Update symbols to dictionaries as well

Yentl Van Tendeloo 5 years ago
parent
commit
ff901f9756

+ 15 - 15
interface/HUTN/hutn_compiler/constructors_visitor.py

@@ -44,12 +44,12 @@ class ConstructorsVisitor(Visitor):
             self.add_constructors(False)
 
     def declare(self, symbol):
-        if symbol.is_global:
-            symbol.node = symbol.name
-            self.add_constructors("global", symbol.node)
+        if symbol['is_global']:
+            symbol['node'] = symbol['name']
+            self.add_constructors("global", symbol['node'])
         else:
-            symbol.node = str(self.free_id)
-            self.add_constructors("declare", symbol.node)
+            symbol['node'] = str(self.free_id)
+            self.add_constructors("declare", symbol['node'])
             self.free_id += 1
 
     def visit_assignment(self, tree):
@@ -120,9 +120,9 @@ class ConstructorsVisitor(Visitor):
     def visit_lvalue(self, tree):
         symbol = self.get_symbol(tree)
         # TODO: split visit_funcdecl in pre_visit_funcdecl and visit_funcdecl
-        if symbol.node is None:
-            raise Exception("Undefined variable: %s" % (symbol.name))
-        self.add_constructors("resolve", symbol.node)
+        if symbol['node'] is None:
+            raise Exception("Undefined variable: %s" % (symbol['name']))
+        self.add_constructors("resolve", symbol['node'])
 
     def visit_func_call(self, tree):
         symbol = self.get_symbol(Tree.get_tail(tree)[0])
@@ -209,21 +209,21 @@ class ConstructorsVisitor(Visitor):
     def pre_visit_funcdecl(self, tree):
         func_body = Tree.get_child(tree, "func_body")
         symbol = self.get_symbol(tree)
-        symbol.node = symbol.name
+        symbol['node'] = symbol['name']
         return False
 
     def visit_funcdecl(self, tree):
         func_body = Tree.get_child(tree, "func_body")
         symbol = self.get_symbol(tree)
         if func_body:
-            if symbol.name in ["input", "output"]:
+            if symbol['name'] in ["input", "output"]:
                 return False
             if Tree.get_children(tree, "MUTABLE"):
                 self.add_constructors("mutable_funcdef")
             else:
                 self.add_constructors("funcdef")
-            self.add_constructors(symbol.node,
-                                  len(symbol.params))
+            self.add_constructors(symbol['node'],
+                                  len(symbol['params']))
             for p in Tree.get_children(tree, "parameter"):
                 self.visit(p)
             self.visit(func_body)
@@ -235,7 +235,7 @@ class ConstructorsVisitor(Visitor):
             # pathmv is needed in visit_func_call(self, tree)
             symbol.pathmv = Tree.get_text(Tree.get_child(tree, "ANYTHING"))
 
-            self.add_constructors("global", symbol.node, "deref", symbol.pathmv)
+            self.add_constructors("global", symbol['node'], "deref", symbol.pathmv)
 
             # reason: "X function f(Y) = Z" adds no constructors
             return True
@@ -245,8 +245,8 @@ class ConstructorsVisitor(Visitor):
 
     def visit_parameter(self, tree):
         symbol = self.get_symbol(tree)
-        symbol.node = str(self.free_id)
-        self.add_constructors(symbol.node)
+        symbol['node'] = str(self.free_id)
+        self.add_constructors(symbol['node'])
         self.free_id += 1
 
     def visit_continue(self, tree):

+ 1 - 1
interface/HUTN/hutn_compiler/declare_functions_visitor.py

@@ -30,7 +30,7 @@ class DeclareFunctionsVisitor(Visitor):
 
         #TODO should check type compatibility if declared multiple times
         try:
-            s = st.Symbol(func_name, func_type, is_global=True, params=parameter_types)
+            s = {"name": func_name, "type": func_type, "is_global": True, "node": None, "params": parameter_types}
             self.symbol_table.add(s)
         except Exception:
             if "COLON" in Tree.get_tail(tree) or "ASSIGN" in Tree.get_tail(tree):

+ 1 - 1
interface/HUTN/hutn_compiler/model_visitor.py

@@ -145,7 +145,7 @@ class ModelVisitor(Visitor):
                 attr_value = False
             elif attr_value['head'] == "DEC_NUMBER":
                 attr_value = int(Tree.get_text(attr_value))
-            elif attr_value.head == "FLOAT_NUMBER":
+            elif attr_value['head'] == "FLOAT_NUMBER":
                 attr_value = float(Tree.get_text(attr_value))
             else:
                 raise Exception(attr_value['head'])

+ 14 - 14
interface/HUTN/hutn_compiler/primitives_visitor.py

@@ -200,11 +200,11 @@ class PrimitivesVisitor(Visitor):
 
     def visit_lvalue(self, tree):
         symbol = self.get_symbol(tree)
-        if symbol.name in ["__input", "__output"]:
+        if symbol['name'] in ["__input", "__output"]:
             return
         r = self.value(Action("resolve"))
         # print symbol.name, symbol.is_func(), symbol.node
-        self.dict(r, "var", symbol.node)
+        self.dict(r, "var", symbol['node'])
         self.debug(r, tree)
         self.set_primitive(tree, r)
 
@@ -328,7 +328,7 @@ class PrimitivesVisitor(Visitor):
 
     def pre_visit_funcdecl(self, tree):
         symbol = self.get_symbol(tree)
-        if symbol.name in ["__input", "__output"]:
+        if symbol['name'] in ["__input", "__output"]:
             return
 
         # TODO: fix funcdecl special case: "X function f(...) = ..."
@@ -338,10 +338,10 @@ class PrimitivesVisitor(Visitor):
             return
 
         new_value = self.node()
-        self.function_values[symbol.name] = new_value
+        self.function_values[symbol['name']] = new_value
 
-        root = self.value(symbol.name)
-        symbol.node = root
+        root = self.value(symbol['name'])
+        symbol['node'] = root
         declare = self.value(Action("global"))
         self.dict(declare, "var", root)
 
@@ -359,13 +359,13 @@ class PrimitivesVisitor(Visitor):
 
     def visit_funcdecl(self, tree):
         symbol = self.get_symbol(tree)
-        if symbol.name in ["__input", "__output"]:
+        if symbol['name'] in ["__input", "__output"]:
             return
 
         func_body = Tree.get_child(tree, "func_body")
         if func_body:
             self.visit_children(tree)
-            vf = self.function_values[symbol.name]
+            vf = self.function_values[symbol['name']]
             parameters = Tree.get_children(tree, "parameter")
             if parameters:
                 ps = self.node()
@@ -386,8 +386,8 @@ class PrimitivesVisitor(Visitor):
             # TODO: fix funcdecl special case: "X function f(...) = ..."
             # Note: replicates "Element x; x = ?primiteves/a" behavior
             # Dangerous: SemanticsVisitor handles it as a function
-            root = self.value(symbol.name)
-            symbol.node = root
+            root = self.value(symbol['name'])
+            symbol['node'] = root
 
             if Tree.get_child(tree, "ASSIGN"):
                 new_value = "?" + Tree.get_text(Tree.get_child(tree, "ANYTHING"))
@@ -415,9 +415,9 @@ class PrimitivesVisitor(Visitor):
     def visit_definition(self, tree):
         symbol = self.get_symbol(tree)
 
-        if symbol.is_global:
+        if symbol['is_global']:
             declare = self.value(Action("global"))
-            root = self.value(symbol.name)
+            root = self.value(symbol['name'])
         else:
             declare = self.value(Action("declare"))
             root = self.node()
@@ -425,7 +425,7 @@ class PrimitivesVisitor(Visitor):
         self.dict(declare, "var", root)
         self.debug(declare, tree)
 
-        symbol.node = root
+        symbol['node'] = root
 
         if Tree.get_children(tree, "ASSIGN"):
             resolve = self.value(Action("resolve"))
@@ -455,7 +455,7 @@ class PrimitivesVisitor(Visitor):
         n = self.node()
 
         symbol = self.get_symbol(tree)
-        symbol.node = n
+        symbol['node'] = n
 
         self.set_primitive(tree, n)
 

+ 12 - 13
interface/HUTN/hutn_compiler/semantics_visitor.py

@@ -6,7 +6,6 @@ from hutn_compiler.declare_functions_visitor import DeclareFunctionsVisitor
 from hutn_compiler.hutnparser import Tree
 from hutn_compiler.visitor import Visitor
 
-
 class SemanticsVisitor(Visitor):
     def __init__(self, args):
         Visitor.__init__(self, args)
@@ -360,7 +359,7 @@ class SemanticsVisitor(Visitor):
         var_type = types_mv.string_to_type(Tree.get_text(type_spec))
         var_name = Tree.get_text(var_id)
 
-        symbol = st.Symbol(var_name, var_type, is_global=self.current_funcdecl is None)
+        symbol = {"name": var_name, "type": var_type, "is_global": self.current_funcdecl is None, "node": None, "params": None}
 
         try:
             self.symbol_table.add(symbol)
@@ -512,7 +511,7 @@ class SemanticsVisitor(Visitor):
             raise RuntimeError("{}:{}:{}: error: '{}' is not declared".format(
                 self.inputfiles[0], tree['startpos']['line'],
                 tree['startpos']['column'], name))
-        self.set_type(tree, symbol.type)
+        self.set_type(tree, symbol['type'])
         self.set_symbol(tree, symbol)
 
     def visit_rvalue(self, tree):
@@ -539,10 +538,10 @@ class SemanticsVisitor(Visitor):
         self.visit_children(tree)
 
         symbol = self.get_symbol(Tree.get_tail(tree)[0])
-        self.set_type(tree, symbol.type)
+        self.set_type(tree, symbol['type'])
 
-        if not symbol.is_func():
-            if isinstance(symbol.type, types_mv.Element):
+        if not st.Symbol.is_func(symbol):
+            if isinstance(symbol['type'], types_mv.Element):
                 #sys.stderr.write("{}:{}:{}: warning: calling a variable of type "
                 #                 "'Element'\n".format(self.inputfiles[0],
                 #                                      tree.startpos['line'],
@@ -554,17 +553,17 @@ class SemanticsVisitor(Visitor):
                 "function".format(self.inputfiles[0],
                                   tree['startpos']['line'],
                                   tree['startpos']['column'],
-                                  symbol.name,
-                                  symbol.type))
+                                  symbol['name'],
+                                  symbol['type']))
 
         expressions = Tree.get_children(tree, "expression")
-        if len(expressions) != len(symbol.params):
+        if len(expressions) != len(symbol['params']):
             raise RuntimeError(
                 "{}:{}:{}: error: wrong number of arguments to "
                 "function '{}'".format(self.inputfiles[0],
                                        tree['startpos']['line'],
                                        tree['startpos']['column'],
-                                       symbol.signature()))
+                                       st.Symbol.signature(symbol)))
 
         """
         for i in range(len(expressions)):
@@ -586,9 +585,9 @@ class SemanticsVisitor(Visitor):
                                            param_type)
         """
 
-        if symbol.name == "__input":
+        if symbol['name'] == "__input":
             tree['head'] = "input"
-        elif symbol.name == "__output":
+        elif symbol['name'] == "__output":
             tree['head'] = "output"
 
     def visit_input(self, tree):
@@ -646,7 +645,7 @@ class SemanticsVisitor(Visitor):
         param_type = types_mv.string_to_type(Tree.get_text(type_spec))
         param_name = Tree.get_text(param_id)
 
-        symbol = st.Symbol(param_name, param_type, is_global=False)
+        symbol = {"name": param_name, "type": param_type, "is_global": False, "node": None, "params": None}
 
         try:
             self.symbol_table.add(symbol)

+ 13 - 11
interface/HUTN/hutn_compiler/symbol_table.py

@@ -9,16 +9,18 @@ class Symbol(object):
         self.node = node
         self.params = params
 
-    def is_func(self):
-        return self.params is not None
-
-    def signature(self):
-        if self.is_func():
-            params = ", ".join([str(t) for t in self.params])
-            return "{} function {}({})".format(str(self.type),
-                                               self.name, params)
+    @staticmethod
+    def is_func(symb):
+        return symb['params'] is not None
+
+    @staticmethod
+    def signature(symb):
+        if Symbol.is_func(symb):
+            params = ", ".join([str(t) for t in symb['params']])
+            return "{} function {}({})".format(str(symb['type']),
+                                               symb['name'], params)
         else:
-            return self.name
+            return symb['name']
 
 class SymbolTable(object):
     def __init__(self):
@@ -31,10 +33,10 @@ class SymbolTable(object):
         self.stacks.pop()
 
     def add(self, symbol):
-        if symbol.name in self.stacks[-1]:
+        if symbol['name'] in self.stacks[-1]:
             raise Exception("Redefinition of symbol " + str(symbol))
         else:
-            self.stacks[-1][symbol.name] = symbol
+            self.stacks[-1][symbol['name']] = symbol
 
     def get(self, name):
         for frame in reversed(self.stacks):