فهرست منبع

Allow the "main" function to be changed to any name (to prevent possible name clashes)

Yentl Van Tendeloo 9 سال پیش
والد
کامیت
40aeab0485

+ 1 - 0
bootstrap/bootstrap.py

@@ -92,6 +92,7 @@ def bootstrap():
                     "element_eq": ["Boolean", "Element", "Element"],
                     "element_neq": ["Boolean", "Element", "Element"],
                     "read_root": ["Element"],
+                    "read_userroot": ["Element"],
                     "deserialize": ["Element", "String"],
                     "log": ["String", "String"],
                 }

+ 14 - 6
bootstrap/compilation_manager.alc

@@ -50,7 +50,7 @@ Element function compilation_manager():
 				log("ERROR: couldn't find obj " + obj)
 			obj = input()
 
-		link_and_load(root, objs)
+		link_and_load(root, input(), objs)
 	elif (operation == "is_defined"):
 		object_name = input()
 		if (dict_in(root, object_name)):
@@ -61,7 +61,7 @@ Element function compilation_manager():
 		log("Failed to understand command")
 	return operation
 
-Boolean function check_symbols(root : Element, objs : Element):
+Boolean function check_symbols(root : Element, main_function : String, objs : Element):
 	Element symbols
 	String obj
 	Element keys
@@ -70,7 +70,7 @@ Boolean function check_symbols(root : Element, objs : Element):
 
 	// We always need a main variable
 	symbols = create_node()
-	dict_add(symbols, "main", False)
+	dict_add(symbols, main_function, False)
 
 	// Resolve all symbols
 	copy_objs = set_copy(objs)
@@ -109,17 +109,25 @@ Boolean function check_symbols(root : Element, objs : Element):
 
 	return True
 
-Void function link_and_load(root : Element, objs : Element):
+Void function link_and_load(root : Element, main_function : String, objs : Element):
 	String obj
 	Element func
+	Element main_f
 
-	if (check_symbols(root, objs)):
+	if (check_symbols(root, main_function, objs)):
+		// Symbols verified OK, start execution
 		output(True)
+
+		// Call all initializers in turn
 		while (0 < list_len(objs)):
 			obj = set_pop(objs)
 			func = root[obj]["initializers"]
 			exec(func)
-		main()
+
+		// Resolve the main function, which should now be in (global) scope, and execute it
+		main_f = resolve(main_function)
+		main_f()
 	else:
+		// Symbol verification failed, so don't execute
 		output(False)
 	return

+ 8 - 0
bootstrap/primitives.alc

@@ -73,6 +73,7 @@ Integer function string_len(a: String) = ?primitives/string_len
 Element function deserialize(a: String) = ?primitives/deserialize
 Element function log(a: String) = ?primitives/log
 Element function read_root() = ?primitives/read_root
+Element function read_userroot() = ?primitives/read_userroot
 Boolean function is_physical_int(a: Element) = ?primitives/is_physical_int
 Boolean function is_physical_float(a: Element) = ?primitives/is_physical_float
 Boolean function is_physical_string(a: Element) = ?primitives/is_physical_string
@@ -155,3 +156,10 @@ String function string_substr(a: String, b: Integer, c: Integer):
 			return result
 	return result
 	
+Element function resolve(name : String):
+	// Could directly access it through introspection
+	// But seems safer to create some code and execute it...
+	Element user_root
+	user_root = read_userroot()
+	user_root = user_root["globals"][name]["value"]
+	return user_root

+ 3 - 0
interface/HUTN/hutn_compiler/linker.py

@@ -20,6 +20,9 @@ def link(address, username, objects):
         data.append(("V", '"%s"' % obj))
     data.append(("V", '""'))
 
+    # Call the main function
+    data.append(("V", '"main"'))
+
     data = flush_data(address, data, username)
     v = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
     if "False" in v:

+ 1 - 0
interface/HUTN/includes/primitives.alh

@@ -79,6 +79,7 @@ Boolean function string_startswith(a: String, b: String)
 Element function deserialize(a: String) 
 String function log(a: String)
 Element function read_root()
+Element function read_userroot()
 Element function input()
 Element function output(a : Element)
 Boolean function is_physical_int(a : Element)

+ 5 - 3
kernel/modelverse_kernel/main.py

@@ -60,11 +60,11 @@ class ModelverseKernel(object):
         elif isinstance(phase_v, string_types):
             if phase_v == "init" and inst in self.compiled:
                 #print("%-30s(%s)" % ("COMPILED " + str(self.primitives[inst]), phase_v))
-                gen = self.execute_primitive(user_root, inst)
+                gen = self.execute_primitive(user_root, inst, username)
             elif inst_v is None:
                 raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
             else:
-                print("%-30s(%s)" % (inst_v["value"], phase_v))
+                #print("%-30s(%s)" % (inst_v["value"], phase_v))
                 gen = getattr(self, "%s_%s" % (inst_v["value"], phase_v))(user_root)
         elif inst_v is None:
             raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info, inst_v, phase_v))
@@ -96,7 +96,7 @@ class ModelverseKernel(object):
             self.primitives[bodies[i]] = getattr(primitive_functions, function_names[i])
         self.compiled.update(self.primitives)
 
-    def execute_primitive(self, user_root, inst):
+    def execute_primitive(self, user_root, inst, username):
         # execute_primitive
         user_frame =    yield [("RD", [user_root, "frame"])]
         symbols =       yield [("RD", [user_frame, "symbols"])]
@@ -121,6 +121,8 @@ class ModelverseKernel(object):
             parameters = dict(zip(dict_keys, dict_values))
 
         parameters["root"] = self.root
+        parameters["user_root"] = user_root
+        parameters["username"] = username
 
         # prim is a generator itself!
         try:

+ 3 - 0
kernel/modelverse_kernel/primitives.py

@@ -526,3 +526,6 @@ def log(a, **remainder):
     a_value = yield [("RV", [a])]
     print("== LOG == " + str(a_value))
     raise PrimitiveFinished(a)
+
+def read_userroot(user_root, **remainder):
+    raise PrimitiveFinished(user_root)