declare_functions_visitor.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import symbol_table as st
  2. import types_mv
  3. from visitor import Visitor
  4. # Declare the function but do not visit its body
  5. class DeclareFunctionsVisitor(Visitor):
  6. def __init__(self, symbol_table, inputfiles):
  7. self.symbol_table = symbol_table
  8. self.inputfiles = inputfiles
  9. def compute_parameter_types(self, tree):
  10. parameter_types = []
  11. for parameter in tree.get_children('parameter'):
  12. type_specifier = parameter.get_tail()[2].get_text()
  13. parameter_types.append(types_mv.string_to_type(type_specifier))
  14. return parameter_types
  15. def compute_func_type(self, tree):
  16. self.visit(tree.get_tail()[0])
  17. func_type = self.get_type(tree.get_tail()[0])
  18. return func_type
  19. def visit_funcdecl(self, tree):
  20. func_name = tree.get_tail()[2].get_text()
  21. func_type = self.compute_func_type(tree)
  22. parameter_types = self.compute_parameter_types(tree)
  23. self.set_type(tree, func_type)
  24. #TODO should check type compatibility if declared multiple times
  25. try:
  26. s = st.Symbol(func_name, func_type, is_global=True, params=parameter_types)
  27. self.symbol_table.add(s)
  28. except Exception:
  29. if "COLON" in tree.get_tail() or "ASSIGN" in tree.get_tail():
  30. raise RuntimeError(
  31. "{}:{}:{}: error: redeclaration of '{}'".format(
  32. self.inputfiles[0], tree.startpos['line'],
  33. tree.startpos['column'], func_name))
  34. self.set_symbol(tree, s)
  35. def visit_func_type(self, tree):
  36. self.set_type(tree, types_mv.string_to_type(tree.get_text()))