浏览代码

Various fixes

Yentl Van Tendeloo 8 年之前
父节点
当前提交
cfbd73cc22
共有 5 个文件被更改,包括 132 次插入58 次删除
  1. 4 0
      bootstrap/conformance_scd.alc
  2. 14 14
      bootstrap/modelling.alc
  3. 103 42
      integration/test_constructors_models.py
  4. 9 0
      integration/utils.py
  5. 2 2
      scripts/run_local_modelverse.py

+ 4 - 0
bootstrap/conformance_scd.alc

@@ -210,6 +210,10 @@ String function conformance_scd(model : Element):
 			constraint_function = read_attribute(metamodel, typing[model_name], "constraint")
 			if (element_neq(constraint_function, read_root())):
 				String result
+				// constraint_function is a complex attribute, so read it out with import_node
+				log("Got constraint_function: " + cast_e2s(constraint_function))
+				constraint_function = import_node(constraint_function)
+				constraint_function = constraint_function["model"]["main"]
 				result = constraint_function(model, model_name)
 				if (result != "OK"):
 					return result!

+ 14 - 14
bootstrap/modelling.alc

@@ -221,6 +221,7 @@ Void function instantiate_attribute(model : Element, element : String, attribute
 	if (attr_type == ""):
 		log("Could not find attribute " + cast_v2s(attribute_name))
 		log("For element " + element)
+		log("Type: " + read_type(model, element))
 		return!
 
 	if (has_value(value)):
@@ -248,6 +249,14 @@ Void function instantiate_attribute_ref(model : Element, element : String, attri
 
 	return!
 
+Void function add_code_model(model : Element, export_name : String, code : Element):
+	Element code_model
+	code_model = instantiate_model(model)
+	add_AL(code_model, code)
+	export_node(export_name, code_model)
+
+	return !
+
 Void function instantiate_attribute_code(model : Element, element : String, attribute_name : String, code : Element):
 	String ref
 	ref = add_AL(model, code)
@@ -378,7 +387,6 @@ Void function unset_attribute(model : Element, element : String, attribute : Str
 
 Void function add_AL_links(model : Element, list : Element, element : Element, type: String, linkname : String, expected_type : String):
 	if (bool_not(dict_in(element, linkname))):
-		log("FINISH")
 		return!
 
 	Element link
@@ -390,8 +398,6 @@ Void function add_AL_links(model : Element, list : Element, element : Element, t
 	// The link
 	dict_add(model["model"], link_name, link)
 	dict_add(model["type_mapping"], link_name, (type + "_") + linkname)
-	log("Added " + link_name)
-	log((("  as " + type) + "_") + linkname)
 
 	// The name link
 	link = read_out(link, 0)
@@ -400,21 +406,13 @@ Void function add_AL_links(model : Element, list : Element, element : Element, t
 	dict_add(model["model"], link_name, link)
 	dict_add(model["type_mapping"], link_name, ((type + "_") + linkname) + "_name")
 	
-	log("Add name " + link_name)
-	log(((("  As " + type) + "_") + linkname) + "_name")
-
 	// The name node
 	link = read_edge_dst(link)
 	link_name = "__" + cast_id2s(link)
 
 	if (bool_not(set_in_node(model["model"], link))):
-		log("TRUE")
 		dict_add(model["model"], link_name, link)
 		dict_add(model["type_mapping"], link_name, "String")
-		log("Added string " + link_name)
-		log("  with value " + cast_e2s(link))
-	else:
-		log("FALSE")
 
 	// Now add the destination to the worker list
 	set_add(list, create_tuple(element[linkname], expected_type))
@@ -558,6 +556,8 @@ Void function construct_model():
 				log("Error: import not found for " + command)
 			else:
 				dict_add(global_models, input(), m)
+		elif (command == "add_code_model"):
+			add_code_model(global_models[input()], input(), construct_function())
 		else:
 			log("Modelling error: did not understand command " + command)
 
@@ -593,9 +593,6 @@ Element function construct_model_raw(metamodel : Element):
 		elif (command == "instantiate_attribute_ref"):
 			input()
 			instantiate_attribute_ref(model, input(), input(), input())
-		elif (command == "instantiate_attribute_code"):
-			input()
-			instantiate_attribute_code(model, input(), input(), construct_function())
 		elif (command == "instantiate_link"):
 			input()
 			instantiate_link(model, input(), input(), input(), input())
@@ -608,5 +605,8 @@ Element function construct_model_raw(metamodel : Element):
 		elif (command == "instantiate_model"):
 			input()
 			input()
+		elif (command == "add_code_model"):
+			input()
+			add_code_model(model, input(), construct_function())
 		else:
 			log("Modelling error: did not understand command " + command)

+ 103 - 42
integration/test_constructors_models.py

@@ -2,7 +2,7 @@ import unittest
 import sys
 import os
 
-from utils import execute, kill, run_file, run_barebone
+from utils import execute, kill, run_file, run_barebone, get_constructor
 
 bottom = [
         "model",
@@ -65,9 +65,18 @@ bottom = [
         "exit",
     ]
 
+bottom_link_al = [
+        "model",
+        "instantiate_node", "1", "ComplexAttribute", "ActionLanguage",
+        "instantiate_attribute", "1", "ActionLanguage", "type", "/models/ActionLanguage",
+
+        "model_define_attribute", "1", "Element", "constraint", True, "ActionLanguage",
+        "exit",
+    ]
+
 action_language = [
         "model",
-        "instantiate_model", "2", "1",
+        "instantiate_model", "1", "2",
         "instantiate_node", "2", "Class", "Element",
         "instantiate_node", "2", "Class", "Action",
         "instantiate_node", "2", "Class", "Statement",
@@ -88,10 +97,9 @@ action_language = [
         "instantiate_node", "2", "Class", "input",
         "instantiate_node", "2", "Class", "resolve",
         "instantiate_node", "2", "Class", "call",
-
-        "instantiate_node", "2", "SimpleAttribute", "Natural",
-        "instantiate_node", "2", "SimpleAttribute", "String",
-        "instantiate_node", "2", "SimpleAttribute", "Boolean",
+        "instantiate_node", "2", "Class", "Natural",
+        "instantiate_node", "2", "Class", "String",
+        "instantiate_node", "2", "Class", "Boolean",
 
         "instantiate_link", "2", "Inheritance", "", "Action", "Element",
         "instantiate_link", "2", "Inheritance", "", "funcdef", "Action",
@@ -116,7 +124,7 @@ action_language = [
         "instantiate_link", "2", "Inheritance", "", "String", "Element",
         "instantiate_link", "2", "Inheritance", "", "Boolean", "Element",
 
-        "instantiate_link", "2", "Association", "dict_link", "Any", "Any",
+        "instantiate_link", "2", "Association", "dict_link", "Action", "Element",
         "model_define_attribute", "2", "dict_link", "name", False, "String",
         "instantiate_attribute", "2", "dict_link", "target_upper_cardinality", 1,
 
@@ -175,43 +183,18 @@ action_language = [
         "instantiate_attribute", "2", "call_params", "target_lower_cardinality", 1,
         "instantiate_attribute", "2", "call_last_param", "target_lower_cardinality", 1,
 
-        "model_define_attribute", "2", "Element", "constraint", True, "funcdef",
-        "model_define_attribute", "2", "AttributeValue", "to_string", True, "funcdef",
+        "export_node", "2", "models/ActionLanguage",
         "exit",
     ]
 
-def add_constraints(model):
+def add_constraint(model, element, code):
+    location = "constraints/%s_%s" % (model, element)
+    print(locals())
     return [
             "model",
-            "instantiate_attribute_code", str(model), "Natural", "constraint",
-                "funcdef",
-                "constraint",
-                2, str(model*100), str(model*100+1),
-                    "if",
-                        "call",
-                            "access", "resolve", "is_physical_int",
-                            1,
-                            "call",
-                                "access", "resolve", "dict_read",
-                                2,
-                                "call",
-                                    "access", "resolve", "dict_read",
-                                    2,
-                                    "access", "resolve", str(model*100),
-                                    "const", "model",
-                                    False,
-                                "access", "resolve", str(model*100+1),
-                                False,
-                            False,
-                        "return",
-                            True,
-                                "const", "OK",
-                        True,
-                        "return",
-                            True,
-                                "const", "Natural instance is not an integer.",
-                        False,
-                    False,
+            "add_code_model", "AL", location,
+           ] + get_constructor(code) + [
+            "instantiate_attribute", model, element, "constraint", location,
             "exit",
         ]
 
@@ -313,21 +296,99 @@ def conformance_check(node):
                 True,
             ]
 
+code_natural = \
+    """
+        include "primitives.alh"
+        String function constraint(model : Element, name : String):
+            Element self
+            self = model["model"][name]
+            if (is_physical_int(self)):
+                if (integer_gte(self, 0)):
+                    return "OK"!
+                else:
+                    return "Natural number not larger than or equal to zero"!
+            else:
+                return "Natural number not larger than or equal to zero"!
+    """
+
+code_string = \
+    """
+        include "primitives.alh"
+        Element function constraint(model : Element, name : String):
+            if (is_physical_string(model["model"][name])):
+                return "OK"!
+            else:
+                return "String has non-string instance"!
+    """
+
+code_boolean = \
+    """
+        include "primitives.alh"
+        Element function constraint(model : Element, name : String):
+            if (is_physical_boolean(model["model"][name])):
+                return "OK"!
+            else:
+                return "Boolean has non-boolean instance"!
+    """
+
+code_location = \
+    """
+        include "primitives.alh"
+        include "library.alh"
+        Element function constraint(model : Element, name : String):
+            if (is_physical_string(model["model"][name])):
+                if (element_neq(import_node(model["model"][name]), read_root())):
+                    return "OK"!
+                else:
+                    return "Location references non-existing element!"!
+            else:
+                return "Location has non-string instance"!
+    """
+
+code_complex_attribute = \
+    """
+        include "primitives.alh"
+        include "library.alh"
+        Element function constraint(model : Element, name : String):
+            if (is_physical_string(model["model"][name])):
+                if (element_neq(import_node(model["model"][name]), read_root())):
+                    return "OK"!
+                else:
+                    return "Complex Attribute references non-existing element!"!
+            else:
+                return "Complex Attribute has non-string value"!
+    """
+
 class TestConstructorsModels(unittest.TestCase):
     def test_constructors_instantiate_bottom(self):
         commands = bottom + conformance_check("models/SimpleClassDiagrams_new") + ["return", False]
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_action_language(self):
-        commands = bottom + action_language + conformance_check("models/SimpleClassDiagrams_new") + ["return", False]
+        commands = bottom + action_language + bottom_link_al + conformance_check("models/SimpleClassDiagrams_new") + ["return", False]
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_constraints_scd(self):
-        commands = bottom + action_language + add_constraints(1) + conformance_check("models/SimpleClassDiagrams_new") + ["return", False]
+        commands = bottom + action_language + bottom_link_al + \
+                    add_constraint("1", "Natural", code_natural) + \
+                    add_constraint("1", "String", code_string) + \
+                    add_constraint("1", "Location", code_location) + \
+                    add_constraint("1", "Boolean", code_boolean) + \
+                    add_constraint("1", "ComplexAttribute", code_complex_attribute) + \
+                    conformance_check("models/SimpleClassDiagrams_new") + ["return", False]
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_constraints_pn(self):
-        commands = bottom + action_language + add_constraints(1) + instantiate_scd + add_constraints(2) + instantiate_pn + conformance_check("models/PN_instance") + ["return", False]
+        commands = bottom + action_language + bottom_link_al + \
+                    add_constraint("1", "Natural", code_natural) + \
+                    add_constraint("1", "String", code_string) + \
+                    add_constraint("1", "Location", code_location) + \
+                    add_constraint("1", "Boolean", code_boolean) + \
+                    add_constraint("1", "ComplexAttribute", code_complex_attribute) + \
+                    instantiate_scd + \
+                    instantiate_pn + \
+                    add_constraint("3", "Natural", code_natural) + \
+                    conformance_check("models/PN_instance") + ["return", False]
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_instantiate_scd(self):

+ 9 - 0
integration/utils.py

@@ -284,6 +284,14 @@ def run_barebone(parameters, expected, interface="0", timeout=False, wait=False,
         kill(proc)
 
 def get_constructor(code):
+    code_fragments = code.split("\n")
+    code_fragments = [i for i in code_fragments if i.strip() != ""]
+    code_fragments = [i.replace("    ", "\t") for i in code_fragments]
+    initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
+    code_fragments = [i[initial_tabs:] for i in code_fragments]
+    code_fragments.append("")
+    code = "\n".join(code_fragments)
+
     with open("__constraint.alc", "w") as f:
         f.write(code)
         f.flush()
@@ -299,6 +307,7 @@ def get_model_constructor(code):
     code_fragments = [i.replace("    ", "\t") for i in code_fragments]
     initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
     code_fragments = [i[initial_tabs:] for i in code_fragments]
+    code_fragments.append("")
     code = "\n".join(code_fragments)
 
     with open("__model.mvc", "w") as f:

+ 2 - 2
scripts/run_local_modelverse.py

@@ -7,5 +7,5 @@ if len(sys.argv) < 2:
     sys.stderr.write("    %s port\n" % sys.argv[0])
 else:
     subprocess.check_call([sys.executable, "-m", "sccd.compiler.sccdc", "-p", "threads", "server.xml"], cwd="hybrid_server")
-    subprocess.call([sys.executable, "run_mvk_server.py"] + sys.argv[1:] + ["--kernel=baseline-jit"], cwd="hybrid_server")
-    #subprocess.call([sys.executable, "run_mvk_server.py"] + sys.argv[1:] + ["--kernel=legacy-interpreter"], cwd="hybrid_server")
+    #subprocess.call([sys.executable, "run_mvk_server.py"] + sys.argv[1:] + ["--kernel=baseline-jit"], cwd="hybrid_server")
+    subprocess.call([sys.executable, "run_mvk_server.py"] + sys.argv[1:] + ["--kernel=legacy-interpreter"], cwd="hybrid_server")