constructors.alc 12 KB

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