Преглед изворни кода

Merge branch 'yentl' of msdl.uantwerpen.be:yentl/modelverse into yentl

Yentl Van Tendeloo пре 9 година
родитељ
комит
fac92697a3

+ 18 - 14
bootstrap/compilation_manager.alc

@@ -1,6 +1,23 @@
 include "primitives.alh"
 include "constructors.alh"
 
+Element function read_symbols(root : Element, object_name : String):
+	Element keys
+	Element node
+	String rv
+	String key
+
+	node = root[object_name]["symbols"]
+	keys = dict_keys(node)
+	rv = ""
+	while (0 < read_nr_out(keys)):
+		key = set_pop(keys)
+		if (node[key]):
+			rv = (rv + key) + ":1\n"
+		else:
+			rv = (rv + key) + ":0\n"
+	return rv
+
 Element function compilation_manager():
 	String operation
 	String object_name
@@ -33,20 +50,7 @@ Element function compilation_manager():
 		while (input()):
 			dict_add(symbols, input(), input())
 	elif (operation == "read_symbols"):
-		Element keys
-		object_name = input()
-		node = root[object_name]["symbols"]
-		keys = dict_keys(node)
-		String rv
-		rv = ""
-		String key
-		while (0 < read_nr_out(keys)):
-			key = set_pop(keys)
-			if (node[key]):
-				rv = (rv + key) + ":1\n"
-			else:
-				rv = (rv + key) + ":0\n"
-		output(rv)
+		output(read_symbols(root, input()))
 	elif (operation == "read_initializers"):
 		node = root[input()]["initializers"]
 		output(node)

+ 1 - 1
integration/test_binary2decimal.py

@@ -12,6 +12,6 @@ class TestBinary2Decimal(unittest.TestCase):
 
     def binary2decimal(self, mode):
         self.assertTrue(run_file(["binary_to_decimal.alc", "primitives.alc"],
-            ["1", "10", "11", "100", "001", "1100111101"],
+            ['"1"', '"10"', '"11"', '"100"', '"001"', '"1100111101"'],
             ["1", "2", "3", "4", "1", "829"],
             mode))

+ 1 - 1
integration/test_factorial.py

@@ -12,6 +12,6 @@ class TestFactorial(unittest.TestCase):
 
     def factorial(self, mode):
         self.assertTrue(run_file(["factorial.alc", "primitives.alc"],
-            [1, 2, 3, 4],
+            ['1', '2', '3', '4'],
             ["1", "2", "6", "24"],
             mode))

+ 1 - 1
integration/test_fibonacci.py

@@ -12,6 +12,6 @@ class TestFibonacci(unittest.TestCase):
 
     def fibonacci(self, mode):
         self.assertTrue(run_file(["fibonacci.alc", "primitives.alc"],
-            [1, 2, 3, 4],
+            ['1', '2', '3', '4'],
             ["1", "1", "2", "3"],
             mode))

+ 1 - 1
integration/test_fibonacci_smart.py

@@ -12,6 +12,6 @@ class TestFibonacciSmart(unittest.TestCase):
 
     def fibonacci_smart(self, mode):
         self.assertTrue(run_file(["fibonacci_smart.alc", "primitives.alc"],
-            [1, 2, 3, 4, 5, 6, 7, 8],
+            ['1', '2', '3', '4', '5', '6', '7', '8'],
             ["1", "1", "2", "3", "5", "8", "13", "21"],
             mode))

+ 2 - 2
integration/test_if_elif.py

@@ -12,7 +12,7 @@ class TestIfElif(unittest.TestCase):
 
     def if_elif_else(self, mode):
         self.assertTrue(run_file(["if_elif_else.alc", "primitives.alc"],
-            [-1,   10,  11,  0,   1,   0,   -100],
+            ['-1', '10', '11', '0', '1', '0', '-100'],
             ["-1", "1", "1", "0", "1", "0", "-1"],
             mode))
 
@@ -24,6 +24,6 @@ class TestIfElif(unittest.TestCase):
 
     def if_elif(self, mode):
         self.assertTrue(run_file(["if_elif.alc", "primitives.alc"],
-                                 [-1, 10, 11, 0, 1, 0, -100],
+                                 ['-1', '10', '11', '0', '1', '0', '-100'],
                                  ["-1", "1", "1", "0", "1", "0", "-1"],
                                  mode))

+ 1 - 1
integration/test_leap_year.py

@@ -12,6 +12,6 @@ class TestLeapYear(unittest.TestCase):
 
     def leap_year(self, mode):
         self.assertTrue(run_file(["leap_year.alc", "primitives.alc"],
-            [  2016,    2015,    2014,    2013,   2012,    2001,    2000,    1999],
+            ['2016', '2015', '2014', '2013', '2012', '2001', '2000', '1999'],
             ["True", "False", "False", "False", "True", "False", "False", "False"],
             mode))

+ 126 - 96
integration/test_pn_interface.py

@@ -1,14 +1,18 @@
 import unittest
+import sys
+sys.path.append("interface/HUTN")
+
+from hutn_compiler.compiler import main as do_compile
 
 from utils import run_file
 
 do_instantiate_simple = [
-            "new", "PetriNets", "abc",
-            "instantiate", "Transition", "t1",
-            "instantiate", "Place", "p1", "attr_add", "p1", "tokens", 5,
-            "instantiate", "Place", "p2", "attr_add", "p2", "tokens", 0,
-            "instantiate", "P2T", "p2t", "p1", "t1", "attr_add", "p2t", "weight", 2,
-            "instantiate", "T2P", "t2p", "t1", "p2", "attr_add", "t2p", "weight", 1]
+            '"new"', '"PetriNets"', '"abc"',
+            '"instantiate"', '"Transition"', '"t1"',
+            '"instantiate"', '"Place"', '"p1"', '"attr_add"', '"p1"', '"tokens"', '5',
+            '"instantiate"', '"Place"', '"p2"', '"attr_add"', '"p2"', '"tokens"', '0',
+            '"instantiate"', '"P2T"', '"p2t"', '"p1"', '"t1"', '"attr_add"', '"p2t"', '"weight"', '2',
+            '"instantiate"', '"T2P"', '"t2p"', '"t1"', '"p2"', '"attr_add"', '"t2p"', '"weight"', '1']
 
 instantiate_node = ["Type to instantiate?",
                     "Name of new element?",
@@ -26,7 +30,8 @@ all_files = [   "pn_interface.alc",
                 "conformance_scd.alc",
                 "library.alc",
                 "metamodels.alc",
-                "--fast",
+                "constructors.alc",
+                "modelling.alc",
             ]
 
 greeting =          ["Welcome to the Model Management Interface, running live on the Modelverse!",
@@ -147,17 +152,17 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_manage(self, mode):
         self.assertTrue(run_file(all_files,
-            ["list",
-             "new", "PetriNets", "abc", "exit",
-             "list",
-             "new", "PetriNets", "def", "exit",
-             "list",
-             "delete", "def",
-             "list",
-             "rename", "abc", "a",
-             "list",
-             "delete", "a",
-             "list",
+            ['"list"',
+             '"new"', '"PetriNets"', '"abc"', '"exit"',
+             '"list"',
+             '"new"', '"PetriNets"', '"def"', '"exit"',
+             '"list"',
+             '"delete"', '"def"',
+             '"list"',
+             '"rename"', '"abc"', '"a"',
+             '"list"',
+             '"delete"', '"a"',
+             '"list"',
              ],
             init + \
                 list_menu([]) + prompt + \
@@ -176,7 +181,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_new_reload(self, mode):
         self.assertTrue(run_file(all_files,
-            ["new", "PetriNets", "abc", "exit", "load", "abc"],
+            ['"new"', '"PetriNets"', '"abc"', '"exit"', '"load"', '"abc"'],
             init + new + loaded + prompt + load + loaded,
             mode))
 
@@ -188,14 +193,14 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_instantiate_place(self, mode):
         self.assertTrue(run_file(all_files,
-            ["new", "PetriNets", "abc",
-            "instantiate", "Place", "p1",
-            "attr_add", "p1", "tokens", 5,
-            "list",
-            "read", "p1",
-            "instantiate", "Transition", "t1",
-            "list",
-            "read", "t1"],
+            ['"new"', '"PetriNets"', '"abc"',
+            '"instantiate"', '"Place"', '"p1"',
+            '"attr_add"', '"p1"', '"tokens"', '5',
+            '"list"',
+            '"read"', '"p1"',
+            '"instantiate"', '"Transition"', '"t1"',
+            '"list"',
+            '"read"', '"t1"'],
             init + new + loaded + \
                 instantiate_node + prompt + \
                 attr_add + prompt + \
@@ -215,11 +220,11 @@ class TestPetrinetInterface(unittest.TestCase):
     def pn_interface_instantiate_arcs(self, mode):
         self.assertTrue(run_file(all_files,
             do_instantiate_simple + [
-                    "read", "p1",
-                    "read", "p2",
-                    "read", "t1",
-                    "read", "p2t",
-                    "read", "t2p",
+                    '"read"', '"p1"',
+                    '"read"', '"p2"',
+                    '"read"', '"t1"',
+                    '"read"', '"p2t"',
+                    '"read"', '"t2p"',
                 ],
             did_instantiate_simple + \
                 read_node("p1", "Place", [], [("tokens", "Natural", 5)]) + prompt + \
@@ -237,7 +242,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_enabled(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["enabled"],
+            do_instantiate_simple + ['"enabled"'],
             did_instantiate_simple + enabled(["t1"]) + prompt,
             mode))
 
@@ -249,7 +254,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_fire(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["fire", "t1"],
+            do_instantiate_simple + ['"fire"', '"t1"'],
             did_instantiate_simple + fire([("p1", 3), ("p2", 1)]) + prompt,
             mode))
 
@@ -261,7 +266,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_OK(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["verify"],
+            do_instantiate_simple + ['"verify"'],
             did_instantiate_simple + ["OK"], mode))
 
     def test_po_pn_interface_verify_fail_tokens(self):
@@ -272,7 +277,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_fail_tokens(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["modify", "p1", "tokens", -5, "verify"],
+            do_instantiate_simple + ['"modify"', '"p1"', '"tokens"', '-5', '"verify"'],
             did_instantiate_simple + modify + prompt + verify_fail_tokens + prompt, mode))
 
     def test_po_pn_interface_verify_fail_weight(self):
@@ -283,7 +288,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_fail_weight(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["modify", "p2t", "weight", -2, "verify"],
+            do_instantiate_simple + ['"modify"', '"p2t"', '"weight"', '-2', '"verify"'],
             did_instantiate_simple + modify + prompt + verify_fail_weight + prompt, mode))
 
     def test_po_pn_interface_verify_fail_structure(self):
@@ -294,10 +299,10 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_fail_structure(self, mode):
         self.assertTrue(run_file(all_files,
-            ["new", "PetriNets", "abc",
-            "instantiate", "Transition", "t1",
-            "instantiate", "Place", "p1", "attr_add", "p1", "tokens", 5,
-            "instantiate", "P2T", "p2t", "t1", "p1", "attr_add", "p2t", "weight", 2, "verify"],
+            ['"new"', '"PetriNets"', '"abc"',
+            '"instantiate"', '"Transition"', '"t1"',
+            '"instantiate"', '"Place"', '"p1"', '"attr_add"', '"p1"', '"tokens"', '5',
+            '"instantiate"', '"P2T"', '"p2t"', '"t1"', '"p1"', '"attr_add"', '"p2t"', '"weight"', '2', '"verify"'],
             init + new + loaded + \
                 instantiate_node + prompt + \
                 instantiate_node + prompt + attr_add + prompt + \
@@ -313,7 +318,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_types(self, mode):
         self.assertTrue(run_file(all_files,
-            ["new", "PetriNets", "abc", "types"],
+            ['"new"', '"PetriNets"', '"abc"', '"types"'],
             init + new + loaded + list_types([("Place", "Class"), ("Transition", "Class"), ("P2T", "Association"), ("T2P", "Association"), ("Natural", "Class")]),
             mode))
 
@@ -325,10 +330,10 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_modify_place(self, mode):
         self.assertTrue(run_file(all_files,
-            ["new", "PetriNets", "abc",
-                "instantiate", "Place", "p1", "attr_add", "p1", "tokens", 5,
-                "read", "p1",
-                "modify", "p1", "tokens", 1, "read", "p1"],
+            ['"new"', '"PetriNets"', '"abc"',
+                '"instantiate"', '"Place"', '"p1"', '"attr_add"', '"p1"', '"tokens"', '5',
+                '"read"', '"p1"',
+                '"modify"', '"p1"', '"tokens"', '1', '"read"', '"p1"'],
             init + new + loaded + \
                 instantiate_node + prompt + attr_add + prompt + \
                 read_node("p1", "Place", [], [("tokens", "Natural", 5)]) + prompt + \
@@ -344,7 +349,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_fail_attr_lower_cardinality(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["instantiate", "Place", "p999", "verify"],
+            do_instantiate_simple + ['"instantiate"', '"Place"', '"p999"', '"verify"'],
             did_instantiate_simple + instantiate_node + prompt + ["Lower cardinality violation for outgoing edge at p999"] + prompt,
             mode))
 
@@ -356,7 +361,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_fail_attr_upper_cardinality(self, mode):
         self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ["attr_add", "p1", "tokens", 5, "verify"],
+            do_instantiate_simple + ['"attr_add"', '"p1"', '"tokens"', '5', '"verify"'],
             did_instantiate_simple + attr_add + prompt + ["Upper cardinality violation for outgoing edge at p1"] + prompt,
             mode))
 
@@ -368,12 +373,12 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_natural(self, mode):
         self.assertTrue(run_file(all_files,
-            ["new", "PetriNets", "abc",
-            "instantiate", "Place", "p1",
-            "attr_add", "p1", "tokens", -5,
-            "attr_del", "p1", "tokens",
-            "attr_add", "p1", "tokens", 4,
-            "verify"],
+            ['"new"', '"PetriNets"', '"abc"',
+            '"instantiate"', '"Place"', '"p1"',
+            '"attr_add"', '"p1"', '"tokens"', '-5',
+            '"attr_del"', '"p1"', '"tokens"',
+            '"attr_add"', '"p1"', '"tokens"', '4',
+            '"verify"'],
             init + new + loaded + \
             instantiate_node + prompt + \
             attr_add + prompt + \
@@ -390,7 +395,7 @@ class TestPetrinetInterface(unittest.TestCase):
 
     def pn_interface_verify_PN_OK(self, mode):
         self.assertTrue(run_file(all_files,
-            ["load", "PetriNets", "verify"],
+            ['"load"', '"PetriNets"', '"verify"'],
             init + load + loaded + ["OK"], mode))
 
     def test_po_rpgame(self):
@@ -400,48 +405,73 @@ class TestPetrinetInterface(unittest.TestCase):
         self.rpgame("CO")
 
     def rpgame(self, mode):
+
+        constraint_code = \
+            """
+            include "primitives.alh"
+            include "object_operations.alh"
+
+            Element function constraint(model : Element, name : String):
+                Element associations
+                Element back_associations
+                Element association
+
+                associations = allOutgoingAssociationInstances(model, name, "tile_left")
+                while (0 < list_len(associations)):
+                    association = set_pop(associations)
+                    destination = reverseKeyLookup(model["model"], read_edge_dst(association))
+                    back_associations = allOutgoingAssociationInstances(model, destination, "tile_right")
+                    if (list_len(back_associations) < 1):
+                        return "Left link does not have a right link back"
+                    else:
+                        association = list_get(back_associations, 0)
+                        destination = reverseKeyLookup(model["model"], read_edge_dst(association))
+                        if (destination != name):
+                            return "Left link does not have a right link back to the same node"
+            """
+
         self.assertTrue(run_file(all_files,
-            ["new", "SimpleClassDiagrams", "RPGame",
-                "instantiate", "Class", "Scene",
-                "instantiate", "Class", "Tile",
-                "instantiate", "Class", "Item",
-                "instantiate", "Class", "Goal",
-                "instantiate", "Class", "Character",
-                "instantiate", "Class", "Hero",
-                "instantiate", "Class", "String",
-                "instantiate", "Association", "scene_name", "Scene", "String",
-                "instantiate", "Association", "scene_has_tiles", "Scene", "Tile",
-                "instantiate", "Association", "tile_left", "Tile", "Tile",
-                "instantiate", "Association", "tile_right", "Tile", "Tile",
-                "instantiate", "Association", "tile_top", "Tile", "Tile",
-                "instantiate", "Association", "tile_bottom", "Tile", "Tile",
-                "instantiate", "Association", "character_on", "Character", "Tile",
-                "instantiate", "Association", "item_on", "Item", "Tile",
-                "instantiate", "Inheritance", "hero_is_character", "Hero", "Character",
-                "instantiate", "Inheritance", "goal_is_item", "Goal", "Item",
-                "attr_add", "Scene", "lower_cardinality", 1,
-                "attr_add", "Scene", "upper_cardinality", 1,
-                "attr_add", "Goal", "lower_cardinality", 1,
-                "attr_add", "scene_has_tiles", "source_lower_cardinality", 1,
-                "attr_add", "scene_has_tiles", "source_upper_cardinality", 1,
-                "attr_add", "scene_has_tiles", "target_lower_cardinality", 1,
-                "attr_add", "scene_name", "target_lower_cardinality", 1,
-                "attr_add", "scene_name", "target_upper_cardinality", 1,
-                "attr_add", "item_on", "target_lower_cardinality", 1,
-                "attr_add", "item_on", "target_upper_cardinality", 1,
-                "attr_add", "item_on", "source_upper_cardinality", 1,
-                "attr_add", "character_on", "target_lower_cardinality", 1,
-                "attr_add", "character_on", "target_upper_cardinality", 1,
-                "attr_add", "character_on", "source_upper_cardinality", 1,
-                "attr_add", "tile_left", "source_upper_cardinality", 1,
-                "attr_add", "tile_left", "target_upper_cardinality", 1,
-                "attr_add", "tile_right", "source_upper_cardinality", 1,
-                "attr_add", "tile_right", "target_upper_cardinality", 1,
-                "attr_add", "tile_top", "source_upper_cardinality", 1,
-                "attr_add", "tile_top", "target_upper_cardinality", 1,
-                "attr_add", "tile_bottom", "source_upper_cardinality", 1,
-                "attr_add", "tile_bottom", "target_upper_cardinality", 1,
-                "verify",
+            ['"new"', '"SimpleClassDiagrams"', '"RPGame"',
+                '"instantiate"', '"Class"', '"Scene"',
+                '"instantiate"', '"Class"', '"Tile"',
+                '"instantiate"', '"Class"', '"Item"',
+                '"instantiate"', '"Class"', '"Goal"',
+                '"instantiate"', '"Class"', '"Character"',
+                '"instantiate"', '"Class"', '"Hero"',
+                '"instantiate"', '"Class"', '"String"',
+                '"instantiate"', '"Association"', '"scene_name"', '"Scene"', '"String"',
+                '"instantiate"', '"Association"', '"scene_has_tiles"', '"Scene"', '"Tile"',
+                '"instantiate"', '"Association"', '"tile_left"', '"Tile"', '"Tile"',
+                '"instantiate"', '"Association"', '"tile_right"', '"Tile"', '"Tile"',
+                '"instantiate"', '"Association"', '"tile_top"', '"Tile"', '"Tile"',
+                '"instantiate"', '"Association"', '"tile_bottom"', '"Tile"', '"Tile"',
+                '"instantiate"', '"Association"', '"character_on"', '"Character"', '"Tile"',
+                '"instantiate"', '"Association"', '"item_on"', '"Item"', '"Tile"',
+                '"instantiate"', '"Inheritance"', '"hero_is_character"', '"Hero"', '"Character"',
+                '"instantiate"', '"Inheritance"', '"goal_is_item"', '"Goal"', '"Item"',
+                '"attr_add"', '"Scene"', '"lower_cardinality"', '1',
+                '"attr_add"', '"Scene"', '"upper_cardinality"', '1',
+                '"attr_add"', '"Goal"', '"lower_cardinality"', '1',
+                '"attr_add"', '"scene_has_tiles"', '"source_lower_cardinality"', '1',
+                '"attr_add"', '"scene_has_tiles"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"scene_has_tiles"', '"target_lower_cardinality"', '1',
+                '"attr_add"', '"scene_name"', '"target_lower_cardinality"', '1',
+                '"attr_add"', '"scene_name"', '"target_upper_cardinality"', '1',
+                '"attr_add"', '"item_on"', '"target_lower_cardinality"', '1',
+                '"attr_add"', '"item_on"', '"target_upper_cardinality"', '1',
+                '"attr_add"', '"item_on"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"character_on"', '"target_lower_cardinality"', '1',
+                '"attr_add"', '"character_on"', '"target_upper_cardinality"', '1',
+                '"attr_add"', '"character_on"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"tile_left"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"tile_left"', '"target_upper_cardinality"', '1',
+                '"attr_add"', '"tile_right"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"tile_right"', '"target_upper_cardinality"', '1',
+                '"attr_add"', '"tile_top"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"tile_top"', '"target_upper_cardinality"', '1',
+                '"attr_add"', '"tile_bottom"', '"source_upper_cardinality"', '1',
+                '"attr_add"', '"tile_bottom"', '"target_upper_cardinality"', '1',
+                '"verify"',
             ],
             init + new + loaded + (instantiate_node + prompt) * 7 + (instantiate_edge + prompt) * 10 + (attr_add + prompt) * 22 + ["OK"] + prompt,
             mode))

+ 1 - 1
integration/test_power.py

@@ -12,5 +12,5 @@ class TestPower(unittest.TestCase):
 
     def power(self, mode):
         self.assertTrue(run_file(["power.alc", "primitives.alc"],
-            [(1, 0), (2, 1), (5, 0), (2, 2), (3, 2), (10, 2), (10, 10)],
+            [('1', '0'), ('2', '1'), ('5', '0'), ('2', '2'), ('3', '2'), ('10', '2'), ('10', '10')],
             ["1", "2", "1", "4", "9", "100", "10000000000"], mode))

+ 1 - 1
integration/test_remainder.py

@@ -12,5 +12,5 @@ class TestRemainder(unittest.TestCase):
 
     def remainder(self, mode):
         self.assertTrue(run_file(["remainder.alc", "primitives.alc"],
-            [(1, 2), (20, 2), (99, 100), (17, 3)],
+            [('1', '2'), ('20', '2'), ('99', '100'), ('17', '3')],
             ["1", "0", "99", "2"], mode))

+ 1 - 1
integration/test_revert.py

@@ -12,6 +12,6 @@ class TestRevert(unittest.TestCase):
 
     def revert(self, mode):
         self.assertTrue(run_file(["revert.alc", "primitives.alc"],
-            ["abc", "defghi", "This is a very simple test case!", "abccba"],
+            ['"abc"', '"defghi"', '"This is a very simple test case!"', '"abccba"'],
             ["cba", "ihgfed", "!esac tset elpmis yrev a si sihT", "abccba"],
             mode))

+ 21 - 12
integration/utils.py

@@ -35,12 +35,6 @@ def getFreePort():
             # Didn't find a duplicate
             return port
 
-def serialize(value):
-    if isinstance(value, str):
-        return '"%s"' % value
-    else:
-        return str(value)
-
 def execute(scriptname, parameters=[], wait=False):
     if os.name not in ["nt", "posix"]:
         # Stop now, as we would have no clue on how to kill its subtree
@@ -114,8 +108,6 @@ def run_file(files, parameters, expected, mode):
 
         threads = []
         for filename in files:
-            if filename == "--fast":
-                continue
             if os.path.isfile("integration/code/%s" % filename):
                 mod_filename = "integration/code/%s" % filename
             elif os.path.isfile("bootstrap/%s" % filename):
@@ -145,13 +137,30 @@ def run_file(files, parameters, expected, mode):
                 raise Exception("Linking error")
 
         # Send in the actual request and wait for replies
+        var_list = {}
         data = []
         for p in parameters:
-            if isinstance(p, tuple):
-                for v in p:
-                    data.append(["V", serialize(v)])
+            if isinstance(p, int):
+                if p not in var_list:
+                    data = flush_data(address, data)
+                    
+                    proc.poll()
+                    if proc.returncode is not None:
+                        # Modelverse has already terminated, which isn't a good sign!
+                        return False
+
+                    val = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username})), timeout=10).read()
+                    val = val.split("=", 2)[1].split("&", 1)[0]
+                    var_list[p] = val
+                    continue
+                else:
+                    val = var_list[p]
+                    t = "R"
             else:
-                data.append(["V", serialize(p)])
+                val = p
+                t = "V"
+            data.append([t, val])
+        data = flush_data(address, data)
         flush_data(address, data)
         
         for e in expected:

+ 33 - 39
interface/HUTN/hutn_compiler/linker.py

@@ -8,44 +8,43 @@ def flush_data(address, data, username):
         urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": username})), timeout=10).read()
     return []
 
-def link(address, username, objects, fast):
+def link(address, username, objects):
     # Read out all symbol tables that are to be linked
     definers = {}
     users = {}
     data = []
 
-    if not fast:
-        definers["main"] = None
-        for obj in objects:
-            data.append(("V", '3'))
-            data.append(("V", '"read_symbols"'))
-            data.append(("V", '"%s"' % obj))
-
-        data = flush_data(address, data, username)
-
-        for obj in objects:
-            print("[SYMB] %s" % (obj))
-            v = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
-            lst = v.rsplit("=", 1)[1]
-            lst = lst.split("\n")
-            for e in lst:
-                if len(e) > 1:
-                    name, defined = e.rsplit(":", 1)
-                    if defined == "1":
-                        if definers.get(name, None):
-                            raise Exception("Double definition for symbol %s\nDefined in %s\nDefined in %s" % (name, definers[name], obj))
-                        definers[name] = obj
-                    else:
-                        users.setdefault(name, []).append(obj)
-                        if name not in definers:
-                            definers[name] = None
-
-        # Check for undefined symbols with this linking set
-        for symbol in definers:
-            if definers[symbol] is None:
-                if symbol not in ["input", "output"]:
-                    # Some symbols are built-ins which only look like functions
-                    raise Exception("Undefined symbol %s.\nUsed by modules:\n\t%s" % (symbol, "\n\t".join(users[symbol])))
+    definers["main"] = None
+    for obj in objects:
+        data.append(("V", '3'))
+        data.append(("V", '"read_symbols"'))
+        data.append(("V", '"%s"' % obj))
+
+    data = flush_data(address, data, username)
+
+    for obj in objects:
+        print("[SYMB] %s" % (obj))
+        v = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
+        lst = v.rsplit("=", 1)[1]
+        lst = lst.split("\n")
+        for e in lst:
+            if len(e) > 1:
+                name, defined = e.rsplit(":", 1)
+                if defined == "1":
+                    if definers.get(name, None):
+                        raise Exception("Double definition for symbol %s\nDefined in %s\nDefined in %s" % (name, definers[name], obj))
+                    definers[name] = obj
+                else:
+                    users.setdefault(name, []).append(obj)
+                    if name not in definers:
+                        definers[name] = None
+
+    # Check for undefined symbols with this linking set
+    for symbol in definers:
+        if definers[symbol] is None:
+            if symbol not in ["input", "output"]:
+                # Some symbols are built-ins which only look like functions
+                raise Exception("Undefined symbol %s.\nUsed by modules:\n\t%s" % (symbol, "\n\t".join(users[symbol])))
 
     # Ok, we know that all symbols can be defined with this set of files, now link their initializers together
     initializers = []
@@ -106,13 +105,8 @@ if __name__ == "__main__":
         address = sys.argv[1]
         username = sys.argv[2]
         objects = set(sys.argv[3:])
-        if "--fast" in objects:
-            objects.remove("--fast")
-            fast = True
-        else:
-            fast = False
 
         if objects:
-            link(address, username, objects, fast)
+            link(address, username, objects)
         else:
             print("No files to link defined")

+ 13 - 11
interface/HUTN/hutn_compiler/primitives_object_visitor.py

@@ -3,6 +3,7 @@ from primitives_visitor import PrimitivesVisitor
 
 import urllib
 import urllib2
+import json
 
 class PrimitivesObjectVisitor(PrimitivesVisitor):
     def __init__(self, args):
@@ -48,32 +49,33 @@ class PrimitivesObjectVisitor(PrimitivesVisitor):
                 print("[CACHED] %s" % simple_filename)
 
     def dump(self):
+        print("DUMP")
         v = PrimitivesVisitor.dump(self)
+        data = []
 
-        import json
         # Set up interface
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
+        data.append(["V", "3"])
 
         # Start uploading the code
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"upload"', "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.hash_file, "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": 'false', "username": self.username}))).read() # Use old interface
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": json.dumps(v), "username": self.username}))).read()
+        data.append(["V", '"upload"'])
+        data.append(["V", '"%s"' % (self.obj_file)])
+        data.append(["V", '"%s"' % (self.hash_file)])
+        data.append(["V", 'false'])
+        data.append(["V", json.dumps(v)])
 
         # Upload symbol table
-        data = []
         for e, v in self.object_symbols.iteritems():
             data.append(["V", "true"])
             data.append(["V", '"%s"' % e])
             data.append(["V", "true" if v else "false"])
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": self.username}))).read()
 
         # Finish the symbol table
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": 'false', "username": self.username}))).read()
+        data.append(["V", 'false'])
 
         # Wait for kernel to signal that it finished
-        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '2', "username": self.username}))).read()
+        data.append(["V", '2'])
+
+        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": self.username}))).read()
         v = urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "get_output", "username": self.username}))).read()
         v = v.split("=", 2)[2]
         if v == "DONE":

+ 17 - 0
kernel/modelverse_kernel/compiled.py

@@ -398,3 +398,20 @@ def selectPossibleOutgoing(a, b, c, **remainder):
             yield [("CE", [result, limit_set_names[i]])]
 
     raise PrimitiveFinished(result)
+
+def read_symbols(a, b, **remainder):
+    b_v =       yield [("RV", [b])]
+    obj =       yield [("RD", [a, b_v])]
+    node =      yield [("RD", [obj, "symbols"])]
+    keys =      yield [("RDK", [node])]
+    keys_v =    yield [("RV", [i]) for i in keys]
+    keys_v = [keys_v] if not isinstance(keys_v, list) else keys_v
+    is_in =     yield [("RD", [node, i]) for i in keys_v]
+    is_in = [is_in] if not isinstance(is_in, list) else is_in
+    is_in_v =   yield [("RV", [i]) for i in is_in]
+    is_in_v = [is_in_v] if not isinstance(is_in_v, list) else is_in_v
+
+    result_v = ["%s:%s\n" % (key, "1" if value else "0") for key, value in zip(keys_v, is_in_v)]
+    result_v = "".join(result_v)
+    result =    yield [("CNV", [result_v])]
+    raise PrimitiveFinished(result)

+ 4 - 5
scripts/link_and_load.py

@@ -1,12 +1,12 @@
 import sys
 import urllib2
 
-def link_and_load(address, username, objs, fast):
+def link_and_load(address, username, objs):
     urllib2.urlopen(urllib2.Request(address, 'op=set_input&username=user_manager&element_type=V&value="%s"' % username)).read()
 
     sys.path.append("interface/HUTN")
     from hutn_compiler.linker import link
-    link(address, username, objs, fast)
+    link(address, username, objs)
 
 if __name__ == "__main__":
     if len(sys.argv) < 4:
@@ -15,7 +15,6 @@ if __name__ == "__main__":
     else:
         address = sys.argv[1]
         username = sys.argv[2]
-        objs = [arg for arg in sys.argv[3:] if arg != "--fast"]
-        fast = "--fast" in sys.argv[3:]
+        objs = sys.argv[3:]
 
-        link_and_load(address, username, objs, fast)
+        link_and_load(address, username, objs)

+ 2 - 2
scripts/make_parallel.py

@@ -19,7 +19,7 @@ def do_compile_wrapper(filename):
     do_compile(address, filename, str(random.random()), filename, "PO", ["--debug"])
 
 if __name__ == "__main__":
-    p = multiprocessing.Pool(multiprocessing.cpu_count())
+    p = multiprocessing.Pool(multiprocessing.cpu_count() * 2)
     p.map(do_compile_wrapper, files)
 
-    link_and_load(address, username, files, True)
+    link_and_load(address, username, files, False)