Browse Source

Major rewrite to bootstrap generation:
- make use of seperate files
- individual files can be pre-parsed to speed things up
- make all bootstrap files directly available in compilation manager

Yentl Van Tendeloo 8 years ago
parent
commit
8abdad9a25

File diff suppressed because it is too large
+ 284986 - 134367
bootstrap/bootstrap.m


+ 61 - 76
bootstrap/bootstrap.py

@@ -1,8 +1,11 @@
 ### Configuration for creating the bootstrap model using conformance_bottom.
+import glob
 
 def bootstrap():
     root = ["__hierarchy"]
 
+    bootstrap_files = glob.glob("bootstrap/*.alc")
+
     user_data = [   "input",
                     "output",
                     "globals",
@@ -100,82 +103,39 @@ def bootstrap():
     initial_user = "user_manager"
     initial_user_code = \
     '''
-    Element function read_root() = ?primitives/read_root
-    Element function dict_read(a: Element, b: Element) = ?primitives/dict_read
-    Element function create_node() = ?primitives/create_node
-    Element function create_value(a: Element) = ?primitives/create_value
-    Element function dict_add(a: Element, b: Element, c: Element) = ?primitives/dict_add
-    Boolean function value_eq(a: String, b: String) = ?primitives/value_eq
-    Boolean function delete_element(a: Element) = ?primitives/delete_element
-    Boolean function bool_not(a: Boolean) = ?primitives/bool_not
-    Boolean function dict_in(a: Element, b: Element) = ?primitives/dict_in
-
-    Element function input()
+    include "primitives.alc"
+    include "user_manager.alh"
 
     Void function __main():
-    \tString username
-    \tElement user_root
-    \tElement user_frame
-    \tElement output_value
-    \tElement input_value
-    \t
-    \twhile (True):
-    \t\tusername = input()
-    \t\tif (value_eq(username, "__delete")):
-    \t\t\tuser_root = dict_read(read_root(), input())
-    \t\t\tdelete_element(user_root)
-    \t\telse:
-    \t\t\tif (bool_not(dict_in(read_root(), username))):
-    \t\t\t\tuser_root = create_node()
-    \t\t\t\tuser_frame = create_node()
-    \t\t\t\toutput_value = create_node()
-    \t\t\t\tinput_value = create_node()
-    \t\t\t\tdict_add(user_root, "frame", user_frame)
-    \t\t\t\tdict_add(user_root, "globals", create_node())
-    \t\t\t\tdict_add(user_root, "output", output_value)
-    \t\t\t\tdict_add(user_root, "last_output", output_value)
-    \t\t\t\tdict_add(user_root, "input", input_value)
-    \t\t\t\tdict_add(user_root, "last_input", input_value)
-    \t\t\t\tdict_add(user_frame, "evalstack", create_node())
-    \t\t\t\tdict_add(user_frame, "returnvalue", create_node())
-    \t\t\t\tdict_add(user_frame, "phase", "init")
-    \t\t\t\tdict_add(user_frame, "IP", dict_read(dict_read(read_root(), "__hierarchy"), "__IP"))
-    \t\t\t\tdict_add(user_frame, "symbols", create_node())
-    \t\t\t\t//Add this only at the end, as otherwise the user will already be detected
-    \t\t\t\tdict_add(read_root(), username, user_root)
+    \tlog("In __main")
+    \tElement root
+    \troot = read_root()
+    \troot = root["__hierarchy"]["objects"]
+    \tlog("Call exec")
+    \texec(root["bootstrap/user_manager.alc"])
+    \tlog("Called exec")
+    \tuser_management()
     '''
 
     code_new_users = \
     '''
-    Element main
-
-    // Do this only in the bootstrapper
-    include "io.alh"
     include "primitives.alc"
-    include "compilation_manager.alc"
-    include "constructors.alc"
-    include "library.alc"
-    include "object_operations.alc"
-    include "conformance_scd.alc"
-    include "modelling.alc"
-    include "metamodels.alc"
+    include "user_interface.alh"
 
     Void function __main():
-    \tInteger interface
-    \twhile (True):
-    \t\tinterface = input()
-    \t\tif (interface == 0):
-    \t\t\texec(deserialize(input()))
-    \t\telif (interface == 1):
-    \t\t\texec(construct_unknown())
-    \t\telif (interface == 2):
-    \t\t\toutput("DONE")
-    \t\telif (interface == 3):
-    \t\t\tcompilation_manager()
-    \t\telif (interface == 4):
-    \t\t\tconstruct_model()
-    \t\telse:
-    \t\t\tlog("Unsupported interface!")
+    \tElement root
+    \troot = read_root()
+    \troot = root["__hierarchy"]["objects"]
+    \texec(root["bootstrap/primitives.alc"])
+    \texec(root["bootstrap/compilation_manager.alc"])
+    \texec(root["bootstrap/constructors.alc"])
+    \texec(root["bootstrap/library.alc"])
+    \texec(root["bootstrap/object_operations.alc"])
+    \texec(root["bootstrap/conformance_scd.alc"])
+    \texec(root["bootstrap/metamodels.alc"])
+    \texec(root["bootstrap/modelling.alc"])
+    \texec(root["bootstrap/user_interface.alc"])
+    \tnew_user()
     '''
 
     ### Actual script to generate the file
@@ -265,21 +225,45 @@ def bootstrap():
                 f.write("Edge _new_user(root, user_root)\n")
                 f.write("Edge __new_user(_new_user, ___new_user)\n")
 
-                def compile_code_AL(code, target):
+                def compile_code_AL(code, target, prepend="", is_file=False, main=False):
                     import sys
                     sys.path.append("interface/HUTN/")
                     from hutn_compiler.compiler import main as compile_code
 
-                    with open("bootstrap/bootstrap.al", "w") as f:
-                        f.write(code)
-                    code = compile_code("bootstrap/bootstrap.al", "interface/HUTN/grammars/actionlanguage.g", "BS", ["--debug"])
-                    os.remove("bootstrap/bootstrap.al")
+                    if not is_file:
+                        with open("bootstrap/bootstrap.al", "w") as f:
+                            f.write(code)
+                        filename = "bootstrap/bootstrap.al"
+                    else:
+                        filename = code
+                    code = compile_code(filename, "interface/HUTN/grammars/actionlanguage.g", "BS", ["--debug", "--prepend:%s" % prepend, "--main" if main else "--not-main"])
+                    if not is_file:
+                        os.remove("bootstrap/bootstrap.al")
                     return code.replace("auto_initial_IP", target)
 
+                # Create all library code
+                # But first create the structure to hold compiled data
+                f.write("Node __objects()\n", both=False)
+                f.write('Node __objects_name("objects")\n', both=False)
+                f.write("Edge __obj_link(__hierarchy, __objects)\n", both=False)
+                f.write("Edge _name_obj_link(__obj_link, __objects_name)\n", both=False)
+
+                # Compile all files and add to structure manually
+                for bootstrap_file in bootstrap_files:
+                    # Compile the subfile
+                    print("[COMP] %s" % bootstrap_file)
+                    result = compile_code_AL(bootstrap_file, "initial_IP", prepend=bootstrap_file, is_file=True)
+                    f.write(result, both=False)
+                    # Now link the code with the compilation manager structure
+                    f.write('Node filename("%s")\n' % bootstrap_file, both=False)
+                    f.write("Edge _(__objects, %s_initial_IP)\n" % bootstrap_file, both=False)
+                    f.write("Edge _(_, filename)\n", both=False)
+
                 # Create code for initial user
-                f.write(compile_code_AL(initial_user_code, "IP_initial"), both=False)
+                print("[BOOT] initial_user")
+                f.write(compile_code_AL(initial_user_code, "initial_IP", prepend="user_manager", main=True), both=False)
                 f.write('Node _IP_str("IP")\n', both=False)
-                f.write("Edge _user_frame(user_frame, IP_initial)\n", both=False)
+                f.write("Edge _user_frame(user_frame, user_manager_initial_IP)\n", both=False)
                 f.write("Edge __user_frame(_user_frame, _IP_str)\n", both=False)
 
                 f.write('Node __phase("init")\n', both=False)
@@ -288,9 +272,10 @@ def bootstrap():
                 f.write("Edge __user_phase(_user_phase, __phase_str)\n", both=False)
 
                 # Create code for new users to start at
-                f.write(compile_code_AL(code_new_users, "IP_new"), both=False)
+                print("[BOOT] new_user")
+                f.write(compile_code_AL(code_new_users, "initial_IP", prepend="new_user", main=True), both=False)
                 f.write('Node __IP_str("__IP")\n', both=False)
-                f.write("Edge _user_IP(__hierarchy, IP_new)\n", both=False)
+                f.write("Edge _user_IP(__hierarchy, new_user_initial_IP)\n", both=False)
                 f.write("Edge __user_IP(_user_IP, __IP_str)\n", both=False)
     except:
         os.remove("bootstrap/bootstrap.m")

+ 1 - 6
bootstrap/compilation_manager.alc

@@ -10,12 +10,7 @@ Void function compilation_manager():
 	Element node
 
 	mv_root = read_root()
-
-	if (dict_in(mv_root["__hierarchy"], "objects")):
-		root = mv_root["__hierarchy"]["objects"]
-	else:
-		root = create_node()
-		dict_add(mv_root["__hierarchy"], "objects", root)
+	root = mv_root["__hierarchy"]["objects"]
 
 	operation = input()
 	if (operation == "upload"):

+ 4 - 1
bootstrap/primitives.alc

@@ -102,7 +102,10 @@ Element function exec(first_instr : Element):
 	dict_add(n, "body", exec_if)
 	dict_add(exec_if, "next", exec_return)
 
-	return n()!
+	log("Set instruction to " + cast_e2s(first_instr))
+	n()
+	log("DONE")
+	return n!
 
 Boolean function string_startswith(a: String, b: String):
 	Integer i

+ 25 - 18
interface/HUTN/hutn_compiler/bootstrap_visitor.py

@@ -4,6 +4,7 @@ from primitives_visitor import PrimitivesVisitor, Action
 class BootstrapVisitor(PrimitivesVisitor):
     def __init__(self, args):
         PrimitivesVisitor.__init__(self, args)
+        self.main = "--main" in args
 
         for f in args:
             if "--prepend:" in f:
@@ -12,17 +13,24 @@ class BootstrapVisitor(PrimitivesVisitor):
         else:
             self.prepend_name = "auto"
 
+    def rename(self, name):
+        if name == "initial_IP":
+            return "%s_%s" % (self.prepend_name, name)
+        else:
+            return "%s_%s" % (self.prepend_name, name) if isinstance(name, int) else name
 
     def dump(self):
         link_id = 0
-        call = self.value(Action("call"))
-        access = self.value(Action("access"))
-        resolve = self.value(Action("resolve"))
-        main = self.value("__main")
-        self.dict(resolve, "var", main)
-        self.dict(access, "var", resolve)
-        self.dict(call, "func", access)
-        self.dict(self.last_instruction, "next", call)
+
+        if self.main:
+            call = self.value(Action("call"))
+            access = self.value(Action("access"))
+            resolve = self.value(Action("resolve"))
+            main = self.value("__main")
+            self.dict(resolve, "var", main)
+            self.dict(access, "var", resolve)
+            self.dict(call, "func", access)
+            self.dict(self.last_instruction, "next", call)
 
         output = []
         for t, data in self.output:
@@ -34,12 +42,11 @@ class BootstrapVisitor(PrimitivesVisitor):
                 output.append("Node %s_%s(%s)\n" % (self.prepend_name, name, value))
             elif t == "D":
                 source, value, target = data
-                source = source if self.first != source else "auto_initial_IP"
-                target = target if self.first != target else "auto_initial_IP"
+                source = source if self.first != source else "initial_IP"
+                target = target if self.first != target else "initial_IP"
 
-                source = "%s_%s" % (self.prepend_name, source if isinstance(source, int) else source)
-                target = "%s_%s" % (self.prepend_name, target if isinstance(target, int) else target)
-                # output.append("D %s,%s,%s\n" % (source, value, target))
+                source = self.rename(source)
+                target = self.rename(target)
                 linkname = "%s_%s_%s" % (source, link_id, target)
                 link_id += 1
                 output.append("Edge _%s_0(%s, %s)\n" % (linkname, source, target))
@@ -47,10 +54,10 @@ class BootstrapVisitor(PrimitivesVisitor):
                 output.append("Edge _%s_1(_%s_0, _%s_2)\n" % (linkname, linkname, linkname))
             elif t == "E":
                 name, source, target = data
-                source = source if self.first != source else "auto_initial_IP"
-                target = target if self.first != target else "auto_initial_IP"
-                name = "%s_%s" % (self.prepend_name, name if isinstance(name, int) else name)
-                source = "%s_%s" % (self.prepend_name, source if isinstance(source, int) else source)
-                target = "%s_%s" % (self.prepend_name, target if isinstance(target, int) else target)
+                source = source if self.first != source else "initial_IP"
+                target = target if self.first != target else "initial_IP"
+                name = self.rename(name)
+                source = self.rename(source)
+                target = self.rename(target)
                 output.append("Edge _%s(_%s, _%s)\n" % (name, source, target))
         return ''.join(output)

+ 2 - 0
kernel/modelverse_kernel/main.py

@@ -966,6 +966,8 @@ class ModelverseKernel(object):
         value, =        yield [("RV", [new_var])]
         exists, =       yield [("RD", [global_symbols, value])]
 
+        print("Define global " + str(value))
+
         if exists is None:
             yield [("CD", [global_symbols, value, empty_node])]
 

+ 4 - 0
state/modelverse_state/main.py

@@ -98,6 +98,8 @@ class ModelverseState(object):
                             else:
                                 value = eval(value)
                             symbols[name], status = self.create_nodevalue(value)
+                            if name.endswith("initial_IP"):
+                                print("%s -- %s" % (name, symbols[name]))
                     elif element_type == "Edge":
                         values = [v.split()[0] for v in values.split(",")]
                         symbols[name], status = self.create_edge(resolve(values[0]), resolve(values[1]))
@@ -400,3 +402,5 @@ class ModelverseState(object):
                 v = values.pop()
                 if v in self.nodes:
                     self.delete_node(v)
+
+        print("Remaining nodes: " + str(len(self.nodes)))