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, ty): if param == "negation" or param == "subtraction": return "-" elif param == "addition" or param == "noop": return "+" elif param == "multiplication": return "*" elif param == "division" and ty != GAZ_INT_KEY: return "/" elif param == "division" and ty == GAZ_INT_KEY: return "//" elif param == "modulo": 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 ">=" elif param == "xor": return "!=" else: warnings.warn("Warning, unknown operator: " + param) return param class PythonUnparser(GeneralUnparser): def __init__(self, ast: ET.Element, debug=False): super().__init__(ast, debug, endline='\n', outstream_begin_delimiter="print(", outstream_end_delimiter=", end='')", function_return_type_indicator_predicate="->", loop_start_delimiter="while ", loop_end_delimiter=":", conditional_case_delimiter="elif ", conditional_start_delimiter="if ", conditional_else_delimiter="else:", conditional_end_delimiter=":", block_start_delimiter="", block_end_delimiter="", strip_conditionals=True) def format_variable(self, mut, ty, name, declaration: bool = False): if declaration: return "{}: {}".format(name, ty) else: return "{}".format(name) def translate_value(self, val): return str(val) def translate_op(self, param, ty=None): return to_python_op(param, ty) def translate_type(self, ty): return to_python_type(ty) def function_declaration(self, xml_tag, args, name, return_type): return "def {}{} {}:".format( name, args, return_type, ) def format_single_arg(self, ty, name): return "{}: {}".format(name, ty) def unparse_block(self, node): # super().unparse_block(node) self.source += f"{self.block_delimiters[0]}\n" self.indentation += 4 for child in node: self.unparse_node(child) self.source += self.indentation_character * self.indentation + "pass\n" self.indentation -= 4 if node.get(GAZ_TY_KEY) is None: self.source += f"{self.block_delimiters[1]}\n\n" elif node.get(GAZ_TY_KEY) in [GAZ_TRUE_BLOCK_TAG, GAZ_FALSE_BLOCK_TAG]: self.source += f"{self.block_delimiters[1]}" def unparse(self): super().unparse() self.source += "\nif __name__ == '__main__':\n main()"