import warnings from xml.etree import ElementTree as ET from ast_parser.gaz_unparser import GazUnparser from ast_parser.general_unparser import GeneralUnparser from constants import * def to_python_type(ty): if ty == GAZ_INT_KEY: return "int" elif ty == GAZ_BOOL_KEY: return "bool" elif ty == GAZ_FLOAT_KEY: return "float" elif ty == GAZ_CHAR_KEY: return "str" elif ty == GAZ_STRING_KEY: return "str" else: raise Exception("Unknown type: " + ty) def to_python_op(param): if param == "negation" or param == "subtraction": return "-" elif param == "addition": return "+" elif param == "multiplication": return "*" elif param == "division": return "/" elif param == "modulus": return "%" elif param == "power": return "**" elif param == "equality": return "==" elif param == "inequality": return "!=" elif param == "less-than": return "<" elif param == "less-than-or-equal": return "<=" elif param == "greater-than": return ">" elif param == "greater-than-or-equal": return ">=" else: warnings.warn("Warning, unknown operator: " + param) return param class PythonUnparser(GazUnparser): def __init__(self, ast: ET.Element, debug=False): super().__init__(ast, debug) def unparse_top_block(self, element_in: ET.Element): pass def unparse_block(self, node: ET.Element): self.source += "\n" self.indentation += 4 for child in node: self.unparse_node(child) self.indentation -= 4 if node.get(GAZ_TY_KEY) is None: self.source += "\n\n" elif node.get(GAZ_TY_KEY) in [GAZ_TRUE_BLOCK_TAG, GAZ_FALSE_BLOCK_TAG]: self.source += "" def unparse_routine(self, element_in: ET.Element): pass def unparse_argument(self, element_in: ET.Element): pass def unparse_statement(self, element_in: ET.Element): pass def unparse_expression(self, element_in: ET.Element): pass def unparse_declaration(self, element_in: ET.Element): variable = element_in.find(GAZ_VAR_TAG) rhs = element_in.find(GAZ_RHS_TAG) self.unparse_variable(variable, True) self.source += " = " self.unparse_node(rhs) self.source += "\n" def unparse_operator(self, element_in: ET.Element): self.unparse_xhs(element_in.find(GAZ_LHS_TAG)) self.source += " {} ".format(to_python_op(element_in.get("op"))) self.unparse_xhs(element_in.find(GAZ_RHS_TAG)) def unparse_instream(self, node): for child in node: self.unparse_node(child) self.source += "input()\n".format(GAZ_IN_STREAM) def unparse_outstream(self, node): self.source += "print(" for child in node: self.unparse_node(child) self.source += ", end='')\n".format(GAZ_OUT_STREAM) def unparse_unary(self, element_in: ET.Element): pass def unparse_assignment(self, element_in: ET.Element): pass def unparse_conditional(self, element_in: ET.Element): pass def unparse_loop(self, element_in: ET.Element): pass def unparse_routine_call(self, element_in: ET.Element): pass def unparse_return(self, element_in: ET.Element): self.source += "return " for child in element_in: self.unparse_node(child) self.source += "\n" def unparse_variable(self, element_in: ET.Element, is_declaration=False): if is_declaration: ty = to_python_type(element_in.get(GAZ_TY_KEY)) name = element_in.get(GAZ_NAME_KEY) self.source += f"{name}: {ty}" else: super().unparse_variable(element_in)