constructors.alc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. include "primitives.alh"
  2. include "conformance_scd.alh"
  3. include "library.alh"
  4. include "io.alh"
  5. include "modelling.alh"
  6. include "utils.alh"
  7. include "object_operations.alh"
  8. Element while_stack = ?
  9. Element variable_map = ?
  10. Element function construct_function_list(list : Element):
  11. String command
  12. Element result
  13. String main_function
  14. Boolean continue
  15. String prev_element
  16. String first_element
  17. Element model
  18. model = instantiate_model(import_node("models/ActionLanguage"))
  19. list = list_reverse(list)
  20. // Initialize variables
  21. prev_element = read_root()
  22. main_function = read_root()
  23. // Clear global variables
  24. while_stack = list_create()
  25. variable_map = dict_create()
  26. continue = True
  27. while (continue):
  28. command = list_pop_final(list)
  29. if (command == "global"):
  30. result = construct_global(model, list)
  31. elif (command == "funcdef"):
  32. result = construct_funcdef(model, list, False)
  33. elif (command == "mutable_funcdef"):
  34. result = construct_funcdef(model, list, True)
  35. else:
  36. log("ERROR (1): did not understand command " + cast_value(command))
  37. output("ERROR: compiled code not understood: " + cast_value(command))
  38. return read_root()!
  39. continue = list_pop_final(list)
  40. if (element_neq(prev_element, read_root())):
  41. dict_add_fast(prev_element, "next", result["start"])
  42. else:
  43. first_element = result["start"]
  44. if (bool_and(element_eq(main_function, read_root()), command != "global")):
  45. // In case no main function is defined, it is the first defined function
  46. // This is mostly there to ensure backwards compatibility
  47. main_function = result["instruction"]
  48. prev_element = result["end"]
  49. if (value_eq(result["name"], "main")):
  50. // It was the function that we want to call
  51. main_function = result["instruction"]
  52. if (element_eq(main_function, read_root())):
  53. log("ERROR (2): no main function found")
  54. output("ERROR: no main function found")
  55. return read_root()!
  56. // Overwrite the main function with our declaration function
  57. prev_element = set_pop(allAssociationDestinations(model, main_function, "funcdef_body"))
  58. log("Got main function: " + main_function)
  59. log("Got main function: " + set_to_string(dict_keys(model["model"][main_function])))
  60. log("Parameters stored in " + cast_string(reverseKeyLookup(model["model"], model["model"][main_function]["params"])))
  61. log("Got parameters for main function: " + set_to_string(dict_keys(model["model"][main_function]["params"])))
  62. model_delete_element(model, set_pop(allOutgoingAssociationInstances(model, main_function, "funcdef_body")))
  63. create_al_link(model, "funcdef_body", main_function, first_element, "body")
  64. create_al_link(model, "Statement_next", result["end"], prev_element, "next")
  65. instantiate_link(model, "initial_funcdef", "", instantiate_node(model, "Initial", ""), main_function)
  66. log("Created model!")
  67. return model!
  68. Void function create_al_link(model : Element, linktype : String, source : String, target : String, dictname : String):
  69. instantiate_attribute(model, instantiate_link(model, linktype, "", source, target), "name", dictname)
  70. return!
  71. String function construct_global(model : Element, list : Element):
  72. String this_element
  73. String declared_element
  74. String op
  75. this_element = instantiate_value(model, "global", "", create_value(!global))
  76. declared_element = instantiate_value(model, "String", "", create_value(list_pop_final(list)))
  77. create_al_link(model, "global_var", this_element, instantiate_value(model, "String", "", declared_element), "var")
  78. op = list_pop_final(list)
  79. if (op != "none"):
  80. // Defines
  81. String assign
  82. String resolve
  83. String value
  84. assign = instantiate_value(model, "assign", "", create_value(!assign))
  85. create_al_link(model, "Statement_next", this_element, assign, "next")
  86. resolve = instantiate_value(model, "resolve", "", create_value(!resolve))
  87. create_al_link(model, "assign_var", assign, resolve, "var")
  88. create_al_link(model, "resolve_var", resolve, declared_element, "var")
  89. if (op == "deref"):
  90. value = instantiate_value(model, "constant", "", create_value(!constant))
  91. create_al_link(model, "constant_node", this_element, value, "node")
  92. elif (op == "empty"):
  93. value = instantiate_value(model, "call", "", create_value(!call))
  94. String res
  95. String acc
  96. res = instantiate_value(model, "resolve", "", create_value(!resolve))
  97. acc = instantiate_value(model, "access", "", create_value(!access))
  98. create_al_link(model, "call_func", value, acc, "func")
  99. create_al_link(model, "access_var", acc, res, "var")
  100. create_al_link(model, "resolve_var", res, instantiate_value(model, "String", "", "create_node"), "var")
  101. elif (op == "const"):
  102. value = instantiate_value(model, "constant", "", create_value(!constant))
  103. create_al_link(model, "constant_node", value, list_pop_final(list), "node")
  104. create_al_link(model, "assign_value", assign, value, "value")
  105. Element result
  106. result = dict_create()
  107. dict_add_fast(result, "name", "")
  108. dict_add_fast(result, "instruction", this_element)
  109. dict_add_fast(result, "start", this_element)
  110. dict_add_fast(result, "end", assign)
  111. return result!
  112. else:
  113. Element result
  114. result = dict_create()
  115. dict_add_fast(result, "name", "")
  116. dict_add_fast(result, "instruction", this_element)
  117. dict_add_fast(result, "start", this_element)
  118. dict_add_fast(result, "end", this_element)
  119. return result!
  120. String function construct_funcdef(model : Element, list : Element, mutable : Boolean):
  121. String assign
  122. String resolve
  123. String constant
  124. String formal
  125. String func
  126. String params
  127. String declare
  128. String name
  129. declare = instantiate_value(model, "global", "", create_value(!global))
  130. assign = instantiate_value(model, "assign", "", create_value(!assign))
  131. resolve = instantiate_value(model, "resolve", "", create_value(!resolve))
  132. constant = instantiate_value(model, "constant", "", create_value(!constant))
  133. name = list_pop_final(list)
  134. if (dict_in(variable_map, name)):
  135. formal = dict_read(variable_map, name)
  136. else:
  137. formal = instantiate_value(model, "String", "", name)
  138. formal = instantiate_value(model, "String", "", formal)
  139. func = instantiate_node(model, "funcdef", "")
  140. params = instantiate_node(model, "param_dict", "")
  141. create_al_link(model, "declare_var", declare, formal, "var")
  142. create_al_link(model, "Statement_next", declare, assign, "next")
  143. create_al_link(model, "assign_var", assign, resolve, "var")
  144. create_al_link(model, "assign_value", assign, constant, "value")
  145. create_al_link(model, "resolve_var", resolve, formal, "var")
  146. create_al_link(model, "constant_node", constant, func, "node")
  147. create_al_link(model, "funcdef_params", func, params, "params")
  148. if (mutable):
  149. create_al_link(model, "funcdef_mutable", func, instantiate_node(model, "Element", ""), "mutable")
  150. Integer nrParams
  151. nrParams = list_pop_final(list)
  152. Integer counter
  153. counter = 0
  154. Element param
  155. String arg_names_decl
  156. arg_names_decl = "abcdefghijklmnopqrstuvwxyz"
  157. while (counter < nrParams):
  158. param = instantiate_node(model, "Element", "")
  159. log("Adding parameter: " + string_get(arg_names_decl, counter))
  160. log(" func " + func)
  161. log(" params " + params)
  162. create_al_link(model, "param_dict_link", params, param, string_get(arg_names_decl, counter))
  163. log("After append: " + set_to_string(dict_keys(model["model"][params])))
  164. dict_add_fast(variable_map, list_pop_final(list), param)
  165. // Output each parameter in turn
  166. counter = counter + 1
  167. // Now add the body
  168. create_al_link(model, "funcdef_body", func, construct_unknown(model, list), "body")
  169. Element result
  170. result = dict_create()
  171. dict_add_fast(result, "name", name)
  172. dict_add_fast(result, "instruction", func)
  173. dict_add_fast(result, "start", declare)
  174. dict_add_fast(result, "end", assign)
  175. return result!
  176. Element function construct_unknown(model : Element, list : Element):
  177. String elem
  178. Element new_model
  179. Element new_model_model
  180. elem = list_pop_final(list)
  181. if (elem == "if"):
  182. return construct_if(model, list)!
  183. elif (elem == "while"):
  184. return construct_while(model, list)!
  185. elif (elem == "access"):
  186. return construct_access(model, list)!
  187. elif (elem == "resolve"):
  188. return construct_resolve(model, list)!
  189. elif (elem == "assign"):
  190. return construct_assign(model, list)!
  191. elif (elem == "call"):
  192. return construct_call(model, list)!
  193. elif (elem == "return"):
  194. return construct_return(model, list)!
  195. elif (elem == "const"):
  196. return construct_const(model, list)!
  197. elif (elem == "declare"):
  198. return construct_declare(model, list)!
  199. elif (elem == "output"):
  200. return construct_output(model, list)!
  201. elif (elem == "input"):
  202. return construct_input(model, list)!
  203. elif (elem == "deref"):
  204. return construct_deref(model, list)!
  205. elif (elem == "break"):
  206. return construct_break(model, list)!
  207. elif (elem == "continue"):
  208. return construct_continue(model, list)!
  209. else:
  210. log("ERROR (2): did not understand command " + cast_value(elem))
  211. output("ERROR: compiled code not understood: " + cast_value(elem))
  212. return read_root()!
  213. String function construct_if(model : Element, list : Element):
  214. String this_element
  215. this_element = instantiate_value(model, "if", "", create_value(!if))
  216. create_al_link(model, "if_cond", this_element, construct_unknown(model, list), "cond")
  217. create_al_link(model, "if_then", this_element, construct_unknown(model, list), "then")
  218. if (list_pop_final(list)):
  219. create_al_link(model, "if_else", this_element, construct_unknown(model, list), "else")
  220. if (list_pop_final(list)):
  221. create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
  222. return this_element!
  223. String function construct_while(model : Element, list : Element):
  224. String this_element
  225. this_element = instantiate_value(model, "while", "", create_value(!while))
  226. create_al_link(model, "while_cond", this_element, construct_unknown(model, list), "cond")
  227. list_append(while_stack, this_element)
  228. create_al_link(model, "while_body", this_element, construct_unknown(model, list), "body")
  229. list_delete(while_stack, list_len(while_stack) - 1)
  230. if (list_pop_final(list)):
  231. create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
  232. return this_element!
  233. String function construct_access(model : Element, list : Element):
  234. String this_element
  235. this_element = instantiate_value(model, "access", "", create_value(!access))
  236. create_al_link(model, "access_var", this_element, construct_unknown(model, list), "var")
  237. return this_element!
  238. String function construct_resolve(model : Element, list : Element):
  239. String this_element
  240. Element linked_element
  241. String name
  242. this_element = instantiate_value(model, "resolve", "", create_value(!resolve))
  243. name = list_pop_final(list)
  244. // TODO might have to check if this is to be added
  245. if dict_in(variable_map, name):
  246. linked_element = variable_map[name]
  247. else:
  248. linked_element = instantiate_value(model, "String", "", name)
  249. create_al_link(model, "resolve_var", this_element, linked_element, "var")
  250. return this_element!
  251. String function construct_assign(model : Element, list : Element):
  252. String this_element
  253. this_element = instantiate_value(model, "assign", "", create_value(!assign))
  254. create_al_link(model, "assign_var", this_element, construct_unknown(model, list), "var")
  255. create_al_link(model, "assign_value", this_element, construct_unknown(model, list), "value")
  256. if (list_pop_final(list)):
  257. create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
  258. return this_element!
  259. String function construct_call(model : Element, list : Element):
  260. String this_element
  261. this_element = instantiate_value(model, "call", "", create_value(!call))
  262. create_al_link(model, "call_func", this_element, construct_unknown(model, list), "func")
  263. Integer nrParams
  264. nrParams = list_pop_final(list)
  265. Integer counter
  266. counter = 0
  267. Element param
  268. Element prev_param
  269. String arg_names_call
  270. arg_names_call = "abcdefghijklmnopqrstuvwxyz"
  271. while (counter < nrParams):
  272. param = instantiate_node(model, "param", "")
  273. create_al_link(model, "param_name", param, instantiate_value(model, "String", "", string_get(arg_names_call, counter)), "name")
  274. create_al_link(model, "param_value", param, construct_unknown(model, list), "value")
  275. if (counter == 0):
  276. create_al_link(model, "call_params", this_element, param, "params")
  277. else:
  278. create_al_link(model, "param_next_param", prev_param, param, "next_param")
  279. prev_param = param
  280. counter = counter + 1
  281. if (nrParams > 0):
  282. create_al_link(model, "call_last_param", this_element, prev_param, "last_param")
  283. if (list_pop_final(list)):
  284. create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
  285. return this_element!
  286. String function construct_return(model : Element, list : Element):
  287. if (list_pop_final(list)):
  288. String this_element
  289. this_element = instantiate_value(model, "return", "", create_value(!return))
  290. create_al_link(model, "return_value", this_element, construct_unknown(model, list), "value")
  291. return this_element!
  292. else:
  293. return instantiate_value(model, "return", "", create_value(!return))!
  294. String function construct_const(model : Element, list : Element):
  295. String this_element
  296. this_element = instantiate_value(model, "constant", "", create_value(!constant))
  297. create_al_link(model, "constant_node", this_element, instantiate_value(model, "Element", "", list_pop_final(list)), "node")
  298. return this_element!
  299. String function construct_declare(model : Element, list : Element):
  300. String this_element
  301. Element declared_element
  302. String name
  303. this_element = instantiate_value(model, "declare", "", create_value(!declare))
  304. declared_element = instantiate_node(model, "Element", "")
  305. create_al_link(model, "declare_var", this_element, declared_element, "var")
  306. name = list_pop_final(list)
  307. dict_add_fast(variable_map, name, declared_element)
  308. // Assign value
  309. String op
  310. op = list_pop_final(list)
  311. if (op != "none"):
  312. String assign
  313. String resolve
  314. String value
  315. assign = instantiate_value(model, "assign", "", create_value(!assign))
  316. create_al_link(model, "Statement_next", this_element, assign, "next")
  317. resolve = instantiate_value(model, "resolve", "", create_value(!resolve))
  318. create_al_link(model, "assign_var", assign, resolve, "var")
  319. create_al_link(model, "resolve_var", resolve, declared_element, "var")
  320. if (op == "deref"):
  321. value = instantiate_value(model, "constant", "", create_value(!constant))
  322. create_al_link(model, "constant_node", value, reuse_element(model, "Element", "", import_node(list_pop_final(list))), "node")
  323. elif (op == "empty"):
  324. value = instantiate_value(model, "call", "", create_value(!call))
  325. Element res
  326. Element acc
  327. res = instantiate_value(model, "resolve", "", create_value(!resolve))
  328. acc = instantiate_value(model, "access", "", create_value(!access))
  329. create_al_link(model, "call_func", value, acc, "func")
  330. create_al_link(model, "access_var", acc, res, "var")
  331. dict_add_fast(res, "var", "create_node")
  332. create_al_link(model, "resolve_var", res, instantiate_value(model, "String", "", "create_node"), "var")
  333. elif (op == "const"):
  334. value = instantiate_value(model, "constant", "", create_value(!constant))
  335. create_al_link(model, "constant_node", value, instantiate_value(model, "Element", "", list_pop_final(list)), "node")
  336. create_al_link(model, "assign_value", assign, value, "value")
  337. if (list_pop_final(list)):
  338. create_al_link(model, "Statement_next", assign, construct_unknown(model, list), "next")
  339. else:
  340. if (list_pop_final(list)):
  341. create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
  342. return this_element!
  343. String function construct_input(model : Element, list : Element):
  344. return instantiate_value(model, "input", "", create_value(!input))!
  345. String function construct_output(model : Element, list : Element):
  346. String this_element
  347. this_element = instantiate_value(model, "output", "", create_value(!output))
  348. create_al_link(model, "output_value", this_element, construct_unknown(model, list), "value")
  349. if (list_pop_final(list)):
  350. create_al_link(model, "Statement_next", this_element, construct_unknown(model, list), "next")
  351. return this_element!
  352. String function construct_deref(model : Element, list : Element):
  353. String this_element
  354. this_element = instantiate_value(model, "constant", "", create_value(!constant))
  355. create_al_link(model, "constant_node", this_element, reuse_element(model, "Element", "", import_node(list_pop_final(list))), "node")
  356. return this_element!
  357. String function construct_break(model : Element, list : Element):
  358. String this_element
  359. this_element = instantiate_value(model, "break", "", create_value(!break))
  360. create_al_link(model, "break_while", this_element, while_stack[list_len(while_stack) - 1], "while")
  361. return this_element!
  362. String function construct_continue(model : Element, list : Element):
  363. String this_element
  364. this_element = instantiate_value(model, "continue", "", create_value(!continue))
  365. create_al_link(model, "continue_while", this_element, while_stack[list_len(while_stack) - 1], "while")
  366. return this_element!