constructors.alc 12 KB

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