Browse Source

Implemented "spawn" function as it should be

Yentl Van Tendeloo 7 years ago
parent
commit
c36a327845

+ 68 - 0
bootstrap/semi_primitives.alc

@@ -1,4 +1,6 @@
 include "primitives.alh"
 include "primitives.alh"
+include "utils.alh"
+include "random.alh"
 
 
 // This function must be kept internally, only called through the "sleep" and "interruptable_sleep" functions
 // This function must be kept internally, only called through the "sleep" and "interruptable_sleep" functions
 Float function __sleep(a : Float, b : Boolean) = ?primitives/__sleep
 Float function __sleep(a : Float, b : Boolean) = ?primitives/__sleep
@@ -486,3 +488,69 @@ Element function range(max : Integer):
 		counter = counter + 1
 		counter = counter + 1
 
 
 	return result!
 	return result!
+
+String function spawn(function : Element, arguments : Element):
+	// Define a new task, with all the required stack information
+	// This is taken from the "task_management" code
+	Element task_root
+	Element task_frame
+	Element output_value
+	Element input_value 
+	Element root
+
+	root = read_root()
+	task_root = create_node()
+	task_frame = create_node()
+	output_value = create_node()
+	input_value = create_node()
+
+	dict_add_fast(task_root, "frame", task_frame)
+	dict_add_fast(task_root, "output", output_value)
+	dict_add_fast(task_root, "last_output", output_value)
+	dict_add_fast(task_root, "input", input_value)
+	dict_add_fast(task_root, "last_input", input_value)
+	dict_add_fast(task_frame, "evalstack", create_node())
+	dict_add_fast(task_frame, "returnvalue", create_node())
+	dict_add_fast(task_frame, "phase", "init")
+	dict_add_fast(task_frame, "symbols", create_node())
+
+	// Instead of just spawning, we set a different IP
+	dict_add_fast(task_frame, "IP", function["body"])
+
+	// Additionally, we copy over all globals that we previously had
+	dict_add_fast(task_root, "globals", dict_copy(root[get_taskname()]["globals"]))
+
+	log("Setting IP to " + cast_value(function["body"]))
+	log("Has outputs: " + set_to_string(dict_keys(function)))
+
+	if (dict_in(function, "params")):
+		// And add the arguments to the symbol table
+		Element symbols
+		String arg_names_call
+		Element param_dict
+		Integer arg_i
+		symbols = task_frame["symbols"]
+		arg_names_call = "abcdefghijklmnopqrstuvwxyz"
+		arg_i = 0
+		param_dict = function["params"]
+		
+		arguments = list_copy(arguments)
+		Element t
+		Element entry
+		while (list_len(arguments) > 0):
+			entry = create_node()
+			dict_add(entry, "value", list_pop(arguments, 0))
+			t = create_edge(symbols, entry)
+			create_edge(t, param_dict[string_get(arg_names_call, arg_i)])
+			log("Adding to symbols: " + cast_value(string_get(arg_names_call, arg_i)))
+			arg_i = arg_i + 1
+
+	// Add this only at the end, as otherwise the task will already be detected and executed
+	String taskname
+	taskname = random_string(30)
+
+	while (dict_in(read_root(), taskname)):
+		taskname = random_string(30)
+	dict_add_fast(read_root(), taskname, task_root)
+
+	return taskname!

+ 2 - 0
interface/HUTN/hutn_compiler/semantics_visitor.py

@@ -563,6 +563,7 @@ class SemanticsVisitor(Visitor):
                                        tree.startpos['column'],
                                        tree.startpos['column'],
                                        symbol.signature()))
                                        symbol.signature()))
 
 
+        """
         for i in range(len(expressions)):
         for i in range(len(expressions)):
             arg_type = self.get_type(expressions[i])
             arg_type = self.get_type(expressions[i])
             param_type = symbol.params[i]
             param_type = symbol.params[i]
@@ -580,6 +581,7 @@ class SemanticsVisitor(Visitor):
             if type(arg_type) != type(param_type):
             if type(arg_type) != type(param_type):
                 self.perform_implicit_cast(tree, expressions[i], arg_type,
                 self.perform_implicit_cast(tree, expressions[i], arg_type,
                                            param_type)
                                            param_type)
+        """
 
 
         if symbol.name == "__input":
         if symbol.name == "__input":
             tree.head = "input"
             tree.head = "input"

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

@@ -119,3 +119,4 @@ Element function reverseKeyLookupMulti(a: Element, b: Element)
 Element function dict_values(dict : Element)
 Element function dict_values(dict : Element)
 Boolean function is_error(a : Element)
 Boolean function is_error(a : Element)
 Element function range(max : Integer)
 Element function range(max : Integer)
+String function spawn(function : Element, arguments : Element)

+ 1 - 1
wrappers/classes/modelverse.xml

@@ -168,7 +168,7 @@
                         </raise>
                         </raise>
                         <script>
                         <script>
                             self.responses.append(json.loads(data))
                             self.responses.append(json.loads(data))
-                            print("Got data: " + str(json.loads(data)))
+                            #print("Got data: " + str(json.loads(data)))
                         </script>
                         </script>
                     </transition>
                     </transition>
 
 

+ 2 - 2
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
 
-Date:   Fri Nov 10 08:54:09 2017
+Date:   Fri Nov 10 09:48:14 2017
 
 
 Model author: Yentl Van Tendeloo
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server
 Model name:   MvK Server
@@ -2434,7 +2434,7 @@ class Modelverse(RuntimeClassBase):
         data = parameters[0]
         data = parameters[0]
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.http_clients[1], Event("HTTP_input", None, [urllib.urlencode({"op": "get_output", "taskname": self.taskname}), "parent"])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.http_clients[1], Event("HTTP_input", None, [urllib.urlencode({"op": "get_output", "taskname": self.taskname}), "parent"])]))
         self.responses.append(json.loads(data))
         self.responses.append(json.loads(data))
-        print("Got data: " + str(json.loads(data)))
+        #print("Got data: " + str(json.loads(data)))
     
     
     def _initialized_http_mapper_init_3_guard(self, parameters):
     def _initialized_http_mapper_init_3_guard(self, parameters):
         data = parameters[0]
         data = parameters[0]