AL_to_py.alc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. include "primitives.alh"
  2. include "modelling.alh"
  3. include "object_operations.alh"
  4. // def print_instruction(self, inst, indent=0):
  5. // intrinsics = {"integer_addition": (lambda x, y: "(%s + %s)" % (x, y)),
  6. // #"string_join": (lambda x, y: "(str(%s) + str(%s))" % (x, y)),
  7. // #"dict_read": (lambda x, y: "(%s[%s])" % (x, y)),
  8. // #"dict_overwrite": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)),
  9. // #"dict_add_fast": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)),
  10. // #"dict_add_fast": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)),
  11. // }
  12. //
  13. // inst_type, = yield [("RV", [inst])]
  14. // instruction = "(no_printer_for_%s)" % inst_type["value"]
  15. //
  16. // if inst_type["value"] == "if":
  17. // cond, true, false = yield [("RD", [inst, "cond"]),
  18. // ("RD", [inst, "then"]),
  19. // ("RD", [inst, "else"])]
  20. // cond, = yield [("CALL_ARGS", [self.print_instruction, (cond, 0)])]
  21. // true, = yield [("CALL_ARGS", [self.print_instruction, (true, indent+1)])]
  22. // if false:
  23. // false, = yield [("CALL_ARGS", [self.print_instruction, (false, indent+1)])]
  24. // false = (" " * indent + "else:\n%s\n") % false
  25. // else:
  26. // false = ""
  27. //
  28. // instruction = " " * indent + "if (" + cond + "):\n" + true + "\n" + false
  29. // #TODO fix for inline calls
  30. // elif inst_type["value"] == "constant":
  31. // node, = yield [("RD", [inst, "node"])]
  32. // node, = yield [("RV", [node])]
  33. // if isinstance(node, str):
  34. // instruction = " " * indent + '"%s"' % node
  35. // else:
  36. // instruction = " " * indent + str(node)
  37. // elif inst_type["value"] == "return":
  38. // value, = yield [("RD", [inst, "value"])]
  39. // if value:
  40. // value, = yield [("CALL_ARGS", [self.print_instruction, (value, 0)])]
  41. // instruction = " " * indent + "return %s\n" % value
  42. // else:
  43. // instruction = " " * indent + "return\n"
  44. // #TODO fix for inline calls
  45. // elif inst_type["value"] == "declare":
  46. // instruction = ""
  47. // elif inst_type["value"] == "resolve":
  48. // value, = yield [("RD", [inst, "var"])]
  49. // str_value, = yield [("RV", [value])]
  50. // if str_value:
  51. // instruction = str_value
  52. // else:
  53. // instruction = "var_%s" % value
  54. // elif inst_type["value"] == "assign":
  55. // var, val = yield [("RD", [inst, "var"]),
  56. // ("RD", [inst, "value"])]
  57. // var, val = yield [("CALL_ARGS", [self.print_instruction, (var, 0)]),
  58. // ("CALL_ARGS", [self.print_instruction, (val, 0)])]
  59. // instruction = " " * indent + var + " = " + val + "\n"
  60. // #TODO fix for inline calls
  61. // elif inst_type["value"] == "call":
  62. // func_name, = yield [("RD", [inst, "func"])]
  63. // func_name, = yield [("CALL_ARGS", [self.print_instruction, (func_name, 0)])]
  64. // param_list = []
  65. //
  66. // param, = yield [("RD", [inst, "params"])]
  67. // while param:
  68. // value, = yield [("RD", [param, "value"])]
  69. // res, param = yield [("CALL_ARGS", [self.print_instruction, (value, 0)]),
  70. // ("RD", [param, "next_param"])]
  71. // param_list.append(res)
  72. //
  73. // if func_name in intrinsics:
  74. // instruction = " " * indent + intrinsics[func_name](*param_list)
  75. // else:
  76. // instruction = " " * indent + func_name + "(" + ", ".join(param_list) + ")"
  77. // """
  78. // if indent == 0:
  79. // #TODO fix for inline calls
  80. // instruction = 'result, = yield [("CALL_ARGS", (%s, (' % func_name + ",".join(param_list) + ',)))]'
  81. // else:
  82. // instruction = " " * indent + 'yield [("CALL_ARGS", (%s, (' % func_name + ",".join(param_list) + ',)))]'
  83. // """
  84. // if indent:
  85. // instruction += "\n"
  86. // elif inst_type["value"] == "access":
  87. // value, = yield [("RD", [inst, "var"])]
  88. // instruction, = yield [("CALL_ARGS", [self.print_instruction, (value, 0)])]
  89. // elif inst_type["value"] == "while":
  90. // cond, body = yield [("RD", [inst, "cond"]),
  91. // ("RD", [inst, "body"])]
  92. // cond, body = yield [("CALL_ARGS", [self.print_instruction, (cond, 0)]),
  93. // ("CALL_ARGS", [self.print_instruction, (body, indent+1)])]
  94. // instruction = " " * indent + "while (%s):\n" % cond + body
  95. // #TODO fix for inline calls
  96. //
  97. // next_inst, = yield [("RD", [inst, "next"])]
  98. // if next_inst:
  99. // next_inst, = yield [("CALL_ARGS", [self.print_instruction, (next_inst, indent)])]
  100. // else:
  101. // next_inst = ""
  102. //
  103. // raise primitive_functions.PrimitiveFinished(instruction + next_inst)
  104. String function get_indent(indentation : Integer):
  105. String code
  106. code = ""
  107. while (indentation > 0):
  108. code = code + " "
  109. indentation = indentation - 1
  110. return code!
  111. String function code_print(node : Element, indentation : Integer):
  112. String code
  113. String inst_type
  114. inst_type = cast_value(node)
  115. code = "(no_printer_for_" + inst_type + ")"
  116. if (inst_type == "if"):
  117. String cond_code
  118. String true_code
  119. String false_code
  120. cond_code = code_print(node["cond"], 0)
  121. true_code = code_print(node["then"], indentation + 1)
  122. if (dict_in(node, "else")):
  123. false_code = get_indent(indentation) + "else:\n"
  124. false_code = code_print(node["else"], indentation + 1)
  125. else:
  126. false_code = ""
  127. code = get_indent(indentation) + "if(" + cond_code + "):\n" + true_code + false_code
  128. elif (inst_type == "constant"):
  129. String value
  130. value = cast_value(node["node"])
  131. if (value == "true"):
  132. value = "True"
  133. elif (value == "false"):
  134. value = "False"
  135. code = get_indent(indentation) + value
  136. elif (inst_type == "return"):
  137. if (dict_in(node, "value")):
  138. code = get_indent(indentation) + "return " + code_print(node["value"], 0) + "\n"
  139. else:
  140. code = get_indent(indentation) + "return\n"
  141. elif (inst_type == "declare"):
  142. code = ""
  143. elif (inst_type == "resolve"):
  144. if (is_physical_string(node["var"])):
  145. code = cast_string(node["var"])
  146. else:
  147. code = "var_" + cast_id(node["var"])
  148. elif (inst_type == "assign"):
  149. code = get_indent(indentation) + code_print(node["var"], 0) + " = " + code_print(node["value"], 0) + "\n"
  150. elif (inst_type == "access"):
  151. code = code_print(node["var"], indentation)
  152. elif (inst_type == "while"):
  153. code = get_indent(indentation) + "while (" + code_print(node["cond"], 0) + "):\n" + code_print(node["body"], indentation + 1)
  154. elif (inst_type == "call"):
  155. String func_name
  156. String params
  157. params = ""
  158. func_name = code_print(node["func"], 0)
  159. Element param
  160. param = node["params"]
  161. Boolean continue
  162. continue = True
  163. while (continue):
  164. if (params == ""):
  165. params = code_print(param["value"], 0)
  166. else:
  167. params = params + ", " + code_print(param["value"], 0)
  168. if (bool_not(dict_in(param, "next_param"))):
  169. continue = False
  170. param = param["next_param"]
  171. code = func_name + "(" + params + ")"
  172. if (indentation > 0):
  173. code = get_indent(indentation) + code + "\n"
  174. if (dict_in(node, "next")):
  175. code = code + code_print(node["next"], indentation)
  176. return code!
  177. Boolean function main(model : Element):
  178. // Read out the main function
  179. log("Start up MAIN function")
  180. String al_node
  181. Element function_element
  182. String code
  183. Element funcdefs
  184. String function
  185. funcdefs = allInstances(model, "AL/funcdef")
  186. while (set_len(funcdefs) > 0):
  187. // Iterate over all functions
  188. function = set_pop(funcdefs)
  189. log("Starting at function " + function)
  190. log("Got keys: " + set_to_string(dict_keys(model["model"][function])))
  191. log("Parameters:")
  192. Element params
  193. String param
  194. params = dict_keys(model["model"][function]["params"])
  195. code = "def func_" + cast_id(model["model"][function]) + "("
  196. while (set_len(params) > 0):
  197. param = set_pop(params)
  198. log(" " + param + " --> " + cast_id(model["model"][function]["params"][param]))
  199. code = code + "var_" + cast_id(model["model"][function]["params"][param])
  200. if (set_len(params) > 0):
  201. code = code + ", "
  202. code = code + "):\n"
  203. function_element = model["model"][function]["body"]
  204. al_node = cast_value(function_element)
  205. while (cast_value(function_element) == "global"):
  206. log("Assigning to " + cast_value(function_element["next"]["var"]["var"]))
  207. log(" the element: " + cast_id(function_element["next"]["value"]["node"]))
  208. log(" keys: " + set_to_string(dict_keys(function_element["next"]["value"]["node"])))
  209. log("Function is element: " + cast_id(function_element["next"]["value"]["node"]))
  210. function_element = function_element["next"]["next"]
  211. log("Started execution at " + cast_value(function_element))
  212. log("Started REAL execution at " + cast_value(function_element))
  213. code = code + code_print(function_element, 1)
  214. log("Finding initial function...")
  215. function = set_pop(allInstances(model, "AL/Initial"))
  216. function = set_pop(allAssociationDestinations(model, function, "AL/initial_funcdef"))
  217. log("Initial function: " + cast_id(model["model"][function]))
  218. code = code + "main = func_" + cast_id(model["model"][function]) + "\n"
  219. // Found the main function, though we only have the name of the function to assign...
  220. // What we can do is reassign main to that function!
  221. log("Generated code:")
  222. log(code)
  223. log("Function block can now be invoked by calling the 'main' function!")
  224. return True!