def _get_type(self, entity, functions): entity_type = function_type.make_type([]) if entity.name == "IDENTIFIER": if entity.value in functions: entity_type = functions[entity.value] else: self._errors.append( error.Error("unknown function {}".format(string_utilities.quote(entity.value)), entity.offset) ) entity_type = None elif entity.name == "call": entity_type = function_type.make_type(entity.children[0].children[1].children[0]) return entity_type
def handler(*args): for i, argument in enumerate(function_node.children[0].children[1].children): entity_type = function_type.make_type(argument.children[1]) entity_type.set_handler(args[i] if entity_type.arity > 0 else lambda value=args[i]: value) functions[argument.children[0].value] = entity_type return evaluate(function_node.children[1], functions)
def _transform_function(self, entity, functions): name, entity_type = utilities.extract_function(entity) if name != "": functions[name] = entity_type new_functions = functions.copy() for argument in entity.children[0].children[1].children: new_functions[argument.children[0].value] = function_type.make_type(argument.children[1]) entity.children[1].children = self._make_calls(entity.children[1].children, new_functions)
result_node = ast_node.AstNode("result", children=[type_node]) inner_function_node = ast_node.AstNode("inner_function", children=[inner_call_node, result_node]) parameters_node = ast_node.AstNode("parameter_list", children=parameters) call_node = ast_node.AstNode("call", children=[inner_function_node, parameters_node]) call_node.set_offset(entity.offset) return call_node if __name__ == "__main__": import read_code import lexer import preparser FUNCTIONS = { "@": function_type.make_type([]), "~": function_type.make_type([1]), "+": function_type.make_type([2]), "rand": function_type.make_type([1, 1, 1]), "range": function_type.make_type([0, 2]), } code = read_code.read_code() specific_lexer = lexer.Lexer() specific_preparser = preparser.Preparser(specific_lexer) preast = specific_preparser.preparse(code) parser = Parser() ast = parser.parse(preast, FUNCTIONS) print(ast) for some_error in specific_lexer.get_errors() + specific_preparser.get_errors() + parser.get_errors():
def extract_function(function_node): name = function_node.children[0].children[0].value arity = len(function_node.children[0].children[1].children) result_type = function_type.make_type(function_node.children[0].children[2].children[0]) return name, function_type.FunctionType(arity, result_type)
def _evaluate_call(call, functions): inner_function = _evaluate_entity(call.children[0].children[0].children[0], functions) parameters = [_evaluate_entity(parameter, functions) for parameter in call.children[1].children] return trampoline.closure_trampoline(inner_function(*parameters)) if __name__ == "__main__": import read_code import lexer import preparser import parser FUNCTIONS = { "ans": function_type.make_type([], handler=lambda: 42), "~": function_type.make_type([1], handler=trampoline.make_closure_trampoline_wrapper(lambda x: -x)), "+": function_type.make_type([2], handler=trampoline.make_closure_trampoline_wrapper(lambda x, y: x + y)), "-": function_type.make_type([2], handler=trampoline.make_closure_trampoline_wrapper(lambda x, y: x - y)), "*": function_type.make_type([2], handler=trampoline.make_closure_trampoline_wrapper(lambda x, y: x * y)), "/": function_type.make_type([2], handler=trampoline.make_closure_trampoline_wrapper(lambda x, y: x / y)), "%": function_type.make_type([2], handler=trampoline.make_closure_trampoline_wrapper(lambda x, y: x % y)), } code = read_code.read_code() specific_lexer = lexer.Lexer() specific_preparser = preparser.Preparser(specific_lexer) preast = specific_preparser.preparse(code) specific_parser = parser.Parser() ast = specific_parser.parse(preast, FUNCTIONS) print(ast)