Bladeren bron

Fixed model compiler: find modelling errors and report them

Yentl Van Tendeloo 8 jaren geleden
bovenliggende
commit
687f2d27c6
2 gewijzigde bestanden met toevoegingen van 23 en 1 verwijderingen
  1. 8 0
      bootstrap/modelling.alc
  2. 15 1
      interface/HUTN/hutn_compiler/model_visitor.py

+ 8 - 0
bootstrap/modelling.alc

@@ -347,6 +347,14 @@ String function instantiate_link(model : Element, type : String, name : String,
 			log("   options: " + set_to_string(options))
 			return ""!
 
+	if (bool_not(dict_in(model["model"], source))):
+		log("ERROR: source of link undefined: " + source)
+		return ""!
+
+	if (bool_not(dict_in(model["model"], destination))):
+		log("ERROR: destination of link undefined: " + destination)
+		return ""!
+
 	if (bool_not(dict_in(model["metamodel"]["model"], type))):
 		log("ERROR: (instantiate_link) no such type in metamodel: " + type)
 		log("    for " + name)

+ 15 - 1
interface/HUTN/hutn_compiler/model_visitor.py

@@ -10,7 +10,7 @@ class ModelVisitor(Visitor):
         Visitor.__init__(self, args)
         self.constructors = []
         self.free_id = 0
-        self.name_maps = {}
+        self.names = set()
         self.current_model = None
         self.current_element = []
         self.includes = []
@@ -59,14 +59,23 @@ class ModelVisitor(Visitor):
             element_name = "__%s" % self.free_id
             self.free_id += 1
 
+        if element_name in self.names:
+            raise Exception("Redefinition of element %s" % element_name)
+
         if len(children) > 2:
             # So we have a source and target; but aren't sure which is which, because the name is optional!
             source_name = children[-2].get_text()
             target_name = children[-1].get_text()
+            if source_name not in self.names:
+                raise Exception("Source of link %s unknown: %s" % (element_name, source_name))
+            if target_name not in self.names:
+                raise Exception("Target of link %s unknown: %s" % (element_name, target_name))
+
             self.constructors.extend(["instantiate_link", self.current_model, element_type, element_name, source_name, target_name])
         else:
             self.constructors.extend(["instantiate_node", self.current_model, element_type, element_name])
 
+        self.names.add(element_name)
         self.current_element.append(element_name)
 
         if tree.get_children("inheritance"):
@@ -82,7 +91,11 @@ class ModelVisitor(Visitor):
     def visit_inheritance(self, tree):
         for token in tree.get_children("MODEL_ID"):
             superclass = token.get_text()
+            if superclass not in self.names:
+                raise Exception("Superclass %s is undefined" % superclass)
+
             self.constructors.extend(["instantiate_link", self.current_model, "Inheritance", "%s_inherits_from_%s" % (self.current_element[-1], superclass), self.current_element[-1], superclass])
+            self.names.add("%s_inherits_from_%s" % (self.current_element[-1], superclass))
 
     def visit_model_attribute(self, tree):
         children = tree.get_children("MODEL_ID")
@@ -114,6 +127,7 @@ class ModelVisitor(Visitor):
                 contains_link = ""
             entry = self.visit(tree.get_children("model_element")[0])
             self.constructors.extend(["instantiate_link", self.current_model, contains_link, "__%s" % self.free_id, self.current_element[-1], entry])
+            self.names.add("__%s" % self.free_id)
             self.free_id += 1
 
     def visit_model_attr_instance(self, tree):