bootstrap.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. ### Configuration for creating the bootstrap model using conformance_bottom.
  2. import glob
  3. import hashlib
  4. import tempfile
  5. import gzip
  6. def bootstrap():
  7. root = ["__hierarchy"]
  8. bootstrap_files = glob.glob("bootstrap/*.alc")
  9. user_data = [ "input",
  10. "output",
  11. "globals",
  12. "frame",
  13. ]
  14. user_frame = [ "evalstack",
  15. "symbols",
  16. "returnvalue",
  17. ]
  18. primitives = { "integer_addition": ["Integer", "Integer", "Integer"],
  19. "integer_subtraction": ["Integer", "Integer", "Integer"],
  20. "integer_multiplication": ["Integer", "Integer", "Integer"],
  21. "integer_division": ["Integer", "Integer", "Integer"],
  22. "integer_gt": ["Boolean", "Integer", "Integer"],
  23. "integer_lt": ["Boolean", "Integer", "Integer"],
  24. "integer_neg": ["Integer", "Integer"],
  25. "float_addition": ["Float", "Float", "Float"],
  26. "float_subtraction": ["Float", "Float", "Float"],
  27. "float_multiplication": ["Float", "Float", "Float"],
  28. "float_division": ["Float", "Float", "Float"],
  29. "float_gt": ["Boolean", "Float", "Float"],
  30. "float_lt": ["Boolean", "Float", "Float"],
  31. "float_neg": ["Float", "Float"],
  32. "bool_and": ["Boolean", "Boolean", "Boolean"],
  33. "bool_or": ["Boolean", "Boolean", "Boolean"],
  34. "bool_not": ["Boolean", "Boolean"],
  35. "string_join": ["String", "String", "String"],
  36. "string_get": ["String", "String", "Integer"],
  37. "string_len": ["Integer", "String"],
  38. "string_split": ["Element", "String", "String"],
  39. "value_eq": ["Boolean", "Element", "Element"],
  40. "value_neq": ["Boolean", "Element", "Element"],
  41. "cast_i2f": ["Float", "Integer"],
  42. "cast_i2s": ["String", "Integer"],
  43. "cast_i2b": ["Boolean", "Integer"],
  44. "cast_f2i": ["Integer", "Float"],
  45. "cast_f2b": ["Boolean", "Float"],
  46. "cast_f2s": ["String", "Float"],
  47. "cast_s2i": ["Integer", "String"],
  48. "cast_s2f": ["Float", "String"],
  49. "cast_s2b": ["Boolean", "String"],
  50. "cast_b2i": ["Integer", "Boolean"],
  51. "cast_b2f": ["Float", "Boolean"],
  52. "cast_b2s": ["String", "Boolean"],
  53. "cast_e2s": ["String", "Element"],
  54. "cast_a2s": ["String", "Action"],
  55. "cast_v2s": ["String", "Element"],
  56. "cast_id2s": ["String", "Element"],
  57. "list_read": ["Element", "Element", "Integer"],
  58. "list_append": ["Element", "Element", "Element"],
  59. "list_insert": ["Element", "Element", "Integer", "Element"],
  60. "list_delete": ["Element", "Element", "Integer"],
  61. "list_len": ["Integer", "Element"],
  62. "dict_add": ["Element", "Element", "Element", "Element"],
  63. "dict_delete": ["Element", "Element", "Element"],
  64. "dict_delete_node": ["Element", "Element", "Element"],
  65. "dict_read": ["Element", "Element", "Element"],
  66. "dict_read_edge": ["Element", "Element", "Element"],
  67. "dict_read_node": ["Element", "Element", "Element"],
  68. "dict_len": ["Integer", "Element"],
  69. "dict_in": ["Boolean", "Element", "Element"],
  70. "dict_in_node": ["Boolean", "Element", "Element"],
  71. "dict_keys": ["Element", "Element"],
  72. "set_add": ["Element", "Element", "Element"],
  73. "set_pop": ["Element", "Element"],
  74. "set_remove": ["Element", "Element", "Element"],
  75. "set_remove_node": ["Element", "Element", "Element"],
  76. "set_in": ["Boolean", "Element", "Element"],
  77. "set_in_node": ["Boolean", "Element", "Element"],
  78. "is_physical_int": ["Boolean", "Element"],
  79. "is_physical_boolean": ["Boolean", "Element"],
  80. "is_physical_string": ["Boolean", "Element"],
  81. "is_physical_action": ["Boolean", "Element"],
  82. "is_physical_float": ["Boolean", "Element"],
  83. "create_node": ["Element"],
  84. "create_edge": ["Element", "Element", "Element"],
  85. "create_value": ["Element", "Element"],
  86. "is_edge": ["Boolean", "Element"],
  87. "read_nr_out": ["Integer", "Element"],
  88. "read_out": ["Element", "Element", "Integer"],
  89. "read_nr_in": ["Integer", "Element"],
  90. "read_in": ["Element", "Element", "Integer"],
  91. "read_edge_src": ["Element", "Element"],
  92. "read_edge_dst": ["Element", "Element"],
  93. "delete_element": ["Element", "Element"],
  94. "element_eq": ["Boolean", "Element", "Element"],
  95. "element_neq": ["Boolean", "Element", "Element"],
  96. "read_root": ["Element"],
  97. "read_userroot": ["Element"],
  98. "deserialize": ["Element", "String"],
  99. "log": ["String", "String"],
  100. "time": ["Float"],
  101. }
  102. initial_user = "user_manager"
  103. initial_user_code = \
  104. '''
  105. include "bootstrap/primitives.alc"
  106. include "user_manager.alh"
  107. Void function __main():
  108. \tElement root
  109. \troot = read_root()
  110. \troot = root["__hierarchy"]["objects"]
  111. \texec(root["bootstrap/user_manager.alc"]["initializers"])
  112. \tuser_management()
  113. '''
  114. code_new_users = \
  115. '''
  116. include "bootstrap/primitives.alc"
  117. include "user_interface.alh"
  118. Void function __main():
  119. \tElement root
  120. \troot = read_root()
  121. \troot = root["__hierarchy"]["objects"]
  122. \texec(root["bootstrap/compilation_manager.alc"]["initializers"])
  123. \texec(root["bootstrap/constructors.alc"]["initializers"])
  124. \texec(root["bootstrap/library.alc"]["initializers"])
  125. \texec(root["bootstrap/object_operations.alc"]["initializers"])
  126. \texec(root["bootstrap/conformance_scd.alc"]["initializers"])
  127. \texec(root["bootstrap/metamodels.alc"]["initializers"])
  128. \texec(root["bootstrap/modelling.alc"]["initializers"])
  129. \texec(root["bootstrap/user_interface.alc"]["initializers"])
  130. \tnew_user()
  131. '''
  132. ### Actual script to generate the file
  133. import os
  134. import sys
  135. class Writer(object):
  136. def __init__(self, file_a, file_b):
  137. self.file_a = file_a
  138. self.file_b = file_b
  139. def write(self, text, both=True):
  140. self.file_a.write(text)
  141. if both:
  142. self.file_b.write(text)
  143. try:
  144. with gzip.GzipFile("bootstrap/bootstrap.m.gz", "wb", mtime=0) as fa:
  145. with gzip.GzipFile("bootstrap/minimal.m.gz", "wb", mtime=0) as fb:
  146. f = Writer(fa, fb)
  147. # Create the root first
  148. f.write("Node root()\n")
  149. # Create all children of the root
  150. for node in root:
  151. f.write("Node %s()\n" % node)
  152. f.write("Edge _%s(root, %s)\n" % (node, node))
  153. f.write('Node __%s("%s")\n' % (node, node))
  154. f.write("Edge ___%s(_%s, __%s)\n" % (node, node, node))
  155. f.write("Node primitives()\n")
  156. f.write("Edge _primitives(__hierarchy, primitives)\n")
  157. f.write('Node __primitives("primitives")\n')
  158. f.write("Edge ___primitives(_primitives, __primitives)\n")
  159. # Define all primitive functions
  160. for function, parameters in primitives.iteritems():
  161. f.write("Node _func_signature_%s()\n" % function)
  162. f.write("Node _func_params_%s()\n" % function)
  163. f.write("Node _func_body_%s()\n" % function)
  164. f.write("Edge _primitives_%s(primitives, _func_signature_%s)\n" % (function, function))
  165. f.write('Node _name_%s("%s")\n' % (function, function))
  166. f.write("Edge _primitives_name_%s(_primitives_%s, _name_%s)\n" % (function, function, function))
  167. f.write('Node _body_%s("body")\n' % function)
  168. f.write("Edge _signature_body_%s(_func_signature_%s, _func_body_%s)\n" % (function, function, function))
  169. f.write("Edge _signature_body_str_%s(_signature_body_%s, _body_%s)\n" % (function, function, function))
  170. f.write('Node _params_%s("params")\n' % function)
  171. f.write("Edge _signature_params_%s(_func_signature_%s, _func_params_%s)\n" % (function, function, function))
  172. f.write("Edge _signature_params_str_%s(_signature_params_%s, _params_%s)\n" % (function, function, function))
  173. parameter_names = "abcdefghijklmnopqrstuvwxyz"
  174. for number, param in enumerate(parameters[1:]):
  175. param_encoding = "%s_%s" % (function, parameter_names[number])
  176. f.write("Node _func_params_%s()\n" % (param_encoding))
  177. f.write('Node _name_%s("%s")\n' % (param_encoding, parameter_names[number]))
  178. f.write("Edge _param_link_%s(_func_params_%s, _func_params_%s)\n" % (param_encoding, function, param_encoding))
  179. f.write("Edge _param_link_str_%s(_param_link_%s, _name_%s)\n" % (param_encoding, param_encoding, param_encoding))
  180. f.write('Node _name_str_%s("name")\n' % param_encoding)
  181. f.write("Edge _param_name_%s(_func_params_%s, _name_%s)\n" % (param_encoding, param_encoding, param_encoding))
  182. f.write("Edge _param_name_str_%s(_param_name_%s, _name_str_%s)\n" % (param_encoding, param_encoding, param_encoding))
  183. # Create the initial user
  184. f.write("Node user_root()\n")
  185. for data in user_data:
  186. f.write("Node user_%s()\n" % data)
  187. f.write('Node ___user_%s("%s")\n' % (data, data))
  188. f.write("Edge _user_%s(user_root, user_%s)\n" % (data, data))
  189. f.write("Edge __user_%s(_user_%s, ___user_%s)\n" % (data, data, data))
  190. for data in user_frame:
  191. f.write("Node user_%s()\n" % data)
  192. f.write('Node ___user_%s("%s")\n' % (data, data))
  193. f.write("Edge _user_%s(user_frame, user_%s)\n" % (data, data))
  194. f.write("Edge __user_%s(_user_%s, ___user_%s)\n" % (data, data, data))
  195. # Add last_input and last_output links
  196. for data in ["input", "output"]:
  197. f.write('Node ___user_last_%s("last_%s")\n' % (data, data))
  198. f.write("Edge _user_last_%s(user_root, user_%s)\n" % (data, data))
  199. f.write("Edge __user_last_%s(_user_last_%s, ___user_last_%s)\n" % (data, data, data))
  200. # Bind user to the root
  201. f.write('Node ___new_user("%s")\n' % initial_user)
  202. f.write("Edge _new_user(root, user_root)\n")
  203. f.write("Edge __new_user(_new_user, ___new_user)\n")
  204. def compile_code_AL(code, target, prepend="", is_file=False, main=False, symbols=None):
  205. import sys
  206. sys.path.append("interface/HUTN/")
  207. from hutn_compiler.compiler import main as compile_code
  208. if not is_file:
  209. f = tempfile.NamedTemporaryFile()
  210. f.write(code)
  211. f.flush()
  212. filename = f.name
  213. else:
  214. filename = code
  215. code = compile_code(filename, "interface/HUTN/grammars/actionlanguage.g", "BS", ["--debug", "--prepend:%s" % prepend, "--main" if main else "--not-main"], symbols=symbols)
  216. if not is_file:
  217. f.close()
  218. return code.replace("auto_initial_IP", target)
  219. # Create all library code
  220. # But first create the structure to hold compiled data
  221. f.write("Node __objects()\n", both=False)
  222. f.write('Node __objects_name("objects")\n', both=False)
  223. f.write("Edge __obj_link(__hierarchy, __objects)\n", both=False)
  224. f.write("Edge _name_obj_link(__obj_link, __objects_name)\n", both=False)
  225. # Compile all files and add to structure manually
  226. for bootstrap_file in bootstrap_files:
  227. # Compile the subfile
  228. print("[COMP] %s" % bootstrap_file)
  229. symbols = {}
  230. result = compile_code_AL(bootstrap_file, "initial_IP", prepend=bootstrap_file, is_file=True, symbols=symbols)
  231. f.write(result, both=False)
  232. # Now link the code with the compilation manager structure
  233. f.write("Node elem()\n", both=False)
  234. f.write('Node initializers("initializers")\n', both=False)
  235. f.write('Node hash("hash_md5")\n', both=False)
  236. f.write("Edge _(__objects, elem)\n", both=False)
  237. f.write('Node filename("%s")\n' % bootstrap_file, both=False)
  238. f.write("Edge _(_, filename)\n", both=False)
  239. f.write("Edge _(elem, %s_initial_IP)\n" % bootstrap_file, both=False)
  240. f.write("Edge _(_, initializers)\n", both=False)
  241. md5 = hashlib.md5()
  242. md5.update(open(bootstrap_file, 'r').read())
  243. f.write('Node hash_value("%s")\n' % md5.hexdigest(), both=False)
  244. f.write("Edge _(elem, hash_value)\n", both=False)
  245. f.write("Edge _(_, hash)\n", both=False)
  246. f.write('Node symbols("symbols")\n', both=False)
  247. f.write('Node __symbols()\n', both=False)
  248. f.write('Edge _(elem, __symbols)\n', both=False)
  249. f.write('Edge _(_, symbols)\n', both=False)
  250. for k, v in symbols.items():
  251. f.write('Node v(%s)\n' % v, both=False)
  252. f.write('Node k("%s")\n' % k, both=False)
  253. f.write('Edge _(__symbols, v)\n', both=False)
  254. f.write('Edge _(_, k)\n', both=False)
  255. # Create code for initial user
  256. print("[BOOT] initial_user")
  257. f.write(compile_code_AL(initial_user_code, "initial_IP", prepend="user_manager", main=True), both=False)
  258. f.write('Node _IP_str("IP")\n', both=False)
  259. f.write("Edge _user_frame(user_frame, user_manager_initial_IP)\n", both=False)
  260. f.write("Edge __user_frame(_user_frame, _IP_str)\n", both=False)
  261. f.write('Node __phase("init")\n', both=False)
  262. f.write('Node __phase_str("phase")\n', both=False)
  263. f.write("Edge _user_phase(user_frame, __phase)\n", both=False)
  264. f.write("Edge __user_phase(_user_phase, __phase_str)\n", both=False)
  265. # Create code for new users to start at
  266. print("[BOOT] new_user")
  267. f.write(compile_code_AL(code_new_users, "initial_IP", prepend="new_user", main=True), both=False)
  268. f.write('Node __IP_str("__IP")\n', both=False)
  269. f.write("Edge _user_IP(__hierarchy, new_user_initial_IP)\n", both=False)
  270. f.write("Edge __user_IP(_user_IP, __IP_str)\n", both=False)
  271. except:
  272. os.remove("bootstrap/bootstrap.m.gz")
  273. os.remove("bootstrap/minimal.m.gz")
  274. raise