constructors.alc 9.7 KB

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