constructors.alc 12 KB

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