constructors.alc 12 KB

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