include "primitives.alh" include "modelling.alh" include "object_operations.alh" // def print_instruction(self, inst, indent=0): // intrinsics = {"integer_addition": (lambda x, y: "(%s + %s)" % (x, y)), // #"string_join": (lambda x, y: "(str(%s) + str(%s))" % (x, y)), // #"dict_read": (lambda x, y: "(%s[%s])" % (x, y)), // #"dict_overwrite": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)), // #"dict_add_fast": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)), // #"dict_add_fast": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)), // } // // inst_type, = yield [("RV", [inst])] // instruction = "(no_printer_for_%s)" % inst_type["value"] // // if inst_type["value"] == "if": // cond, true, false = yield [("RD", [inst, "cond"]), // ("RD", [inst, "then"]), // ("RD", [inst, "else"])] // cond, = yield [("CALL_ARGS", [self.print_instruction, (cond, 0)])] // true, = yield [("CALL_ARGS", [self.print_instruction, (true, indent+1)])] // if false: // false, = yield [("CALL_ARGS", [self.print_instruction, (false, indent+1)])] // false = (" " * indent + "else:\n%s\n") % false // else: // false = "" // // instruction = " " * indent + "if (" + cond + "):\n" + true + "\n" + false // #TODO fix for inline calls // elif inst_type["value"] == "constant": // node, = yield [("RD", [inst, "node"])] // node, = yield [("RV", [node])] // if isinstance(node, str): // instruction = " " * indent + '"%s"' % node // else: // instruction = " " * indent + str(node) // elif inst_type["value"] == "return": // value, = yield [("RD", [inst, "value"])] // if value: // value, = yield [("CALL_ARGS", [self.print_instruction, (value, 0)])] // instruction = " " * indent + "return %s\n" % value // else: // instruction = " " * indent + "return\n" // #TODO fix for inline calls // elif inst_type["value"] == "declare": // instruction = "" // elif inst_type["value"] == "resolve": // value, = yield [("RD", [inst, "var"])] // str_value, = yield [("RV", [value])] // if str_value: // instruction = str_value // else: // instruction = "var_%s" % value // elif inst_type["value"] == "assign": // var, val = yield [("RD", [inst, "var"]), // ("RD", [inst, "value"])] // var, val = yield [("CALL_ARGS", [self.print_instruction, (var, 0)]), // ("CALL_ARGS", [self.print_instruction, (val, 0)])] // instruction = " " * indent + var + " = " + val + "\n" // #TODO fix for inline calls // elif inst_type["value"] == "call": // func_name, = yield [("RD", [inst, "func"])] // func_name, = yield [("CALL_ARGS", [self.print_instruction, (func_name, 0)])] // param_list = [] // // param, = yield [("RD", [inst, "params"])] // while param: // value, = yield [("RD", [param, "value"])] // res, param = yield [("CALL_ARGS", [self.print_instruction, (value, 0)]), // ("RD", [param, "next_param"])] // param_list.append(res) // // if func_name in intrinsics: // instruction = " " * indent + intrinsics[func_name](*param_list) // else: // instruction = " " * indent + func_name + "(" + ", ".join(param_list) + ")" // """ // if indent == 0: // #TODO fix for inline calls // instruction = 'result, = yield [("CALL_ARGS", (%s, (' % func_name + ",".join(param_list) + ',)))]' // else: // instruction = " " * indent + 'yield [("CALL_ARGS", (%s, (' % func_name + ",".join(param_list) + ',)))]' // """ // if indent: // instruction += "\n" // elif inst_type["value"] == "access": // value, = yield [("RD", [inst, "var"])] // instruction, = yield [("CALL_ARGS", [self.print_instruction, (value, 0)])] // elif inst_type["value"] == "while": // cond, body = yield [("RD", [inst, "cond"]), // ("RD", [inst, "body"])] // cond, body = yield [("CALL_ARGS", [self.print_instruction, (cond, 0)]), // ("CALL_ARGS", [self.print_instruction, (body, indent+1)])] // instruction = " " * indent + "while (%s):\n" % cond + body // #TODO fix for inline calls // // next_inst, = yield [("RD", [inst, "next"])] // if next_inst: // next_inst, = yield [("CALL_ARGS", [self.print_instruction, (next_inst, indent)])] // else: // next_inst = "" // // raise primitive_functions.PrimitiveFinished(instruction + next_inst) String function get_indent(indentation : Integer): String code code = "" while (indentation > 0): code = code + " " indentation = indentation - 1 return code! String function code_print(node : Element, indentation : Integer): String code String inst_type inst_type = cast_value(node) code = "(no_printer_for_" + inst_type + ")" if (inst_type == "if"): String cond_code String true_code String false_code cond_code = code_print(node["cond"], 0) true_code = code_print(node["then"], indentation + 1) if (dict_in(node, "else")): false_code = get_indent(indentation) + "else:\n" false_code = code_print(node["else"], indentation + 1) else: false_code = "" code = get_indent(indentation) + "if(" + cond_code + "):\n" + true_code + false_code elif (inst_type == "constant"): String value value = cast_value(node["node"]) if (value == "true"): value = "True" elif (value == "false"): value = "False" code = get_indent(indentation) + value elif (inst_type == "return"): if (dict_in(node, "value")): code = get_indent(indentation) + "return " + code_print(node["value"], 0) + "\n" else: code = get_indent(indentation) + "return\n" elif (inst_type == "declare"): code = "" elif (inst_type == "resolve"): if (is_physical_string(node["var"])): code = cast_string(node["var"]) else: code = "var_" + cast_id(node["var"]) elif (inst_type == "assign"): code = get_indent(indentation) + code_print(node["var"], 0) + " = " + code_print(node["value"], 0) + "\n" elif (inst_type == "access"): code = code_print(node["var"], indentation) elif (inst_type == "while"): code = get_indent(indentation) + "while (" + code_print(node["cond"], 0) + "):\n" + code_print(node["body"], indentation + 1) elif (inst_type == "call"): String func_name String params params = "" func_name = code_print(node["func"], 0) Element param param = node["params"] Boolean continue continue = True while (continue): if (params == ""): params = code_print(param["value"], 0) else: params = params + ", " + code_print(param["value"], 0) if (bool_not(dict_in(param, "next_param"))): continue = False param = param["next_param"] code = func_name + "(" + params + ")" if (indentation > 0): code = get_indent(indentation) + code + "\n" if (dict_in(node, "next")): code = code + code_print(node["next"], indentation) return code! Boolean function main(model : Element): // Read out the main function log("Start up MAIN function") String al_node Element function_element String code Element funcdefs String function funcdefs = allInstances(model, "AL/funcdef") while (set_len(funcdefs) > 0): // Iterate over all functions function = set_pop(funcdefs) log("Starting at function " + function) log("Got keys: " + set_to_string(dict_keys(model["model"][function]))) log("Parameters:") Element params String param params = dict_keys(model["model"][function]["params"]) code = "def func_" + cast_id(model["model"][function]) + "(" while (set_len(params) > 0): param = set_pop(params) log(" " + param + " --> " + cast_id(model["model"][function]["params"][param])) code = code + "var_" + cast_id(model["model"][function]["params"][param]) if (set_len(params) > 0): code = code + ", " code = code + "):\n" function_element = model["model"][function]["body"] al_node = cast_value(function_element) while (cast_value(function_element) == "global"): log("Assigning to " + cast_value(function_element["next"]["var"]["var"])) log(" the element: " + cast_id(function_element["next"]["value"]["node"])) log(" keys: " + set_to_string(dict_keys(function_element["next"]["value"]["node"]))) log("Function is element: " + cast_id(function_element["next"]["value"]["node"])) function_element = function_element["next"]["next"] log("Started execution at " + cast_value(function_element)) log("Started REAL execution at " + cast_value(function_element)) code = code + code_print(function_element, 1) log("Finding initial function...") function = set_pop(allInstances(model, "AL/Initial")) function = set_pop(allAssociationDestinations(model, function, "AL/initial_funcdef")) log("Initial function: " + cast_id(model["model"][function])) code = code + "main = func_" + cast_id(model["model"][function]) + "\n" // Found the main function, though we only have the name of the function to assign... // What we can do is reassign main to that function! log("Generated code:") log(code) log("Function block can now be invoked by calling the 'main' function!") return True!