Prechádzať zdrojové kódy

Made add_AL pre-compiled

Yentl Van Tendeloo 9 rokov pred
rodič
commit
68a3a5bf32
2 zmenil súbory, kde vykonal 117 pridanie a 2 odobranie
  1. 3 2
      bootstrap/modelling.alc
  2. 114 0
      kernel/modelverse_kernel/compiled.py

+ 3 - 2
bootstrap/modelling.alc

@@ -244,11 +244,12 @@ Void function unset_attribute(model : Element, element : String, attribute : Str
 	return
 
 Void function add_AL_links(model : Element, list : Element, element : Element, type: String, linkname : String, expected_type : String):
-	Element link
-	link = dict_read_edge(element, linkname)
 	if (bool_not(dict_in(element, linkname))):
 		return
 
+	Element link
+	link = dict_read_edge(element, linkname)
+
 	// The link
 	dict_add(model["model"], "__" + cast_id2s(link), link)
 	dict_add(model["type_mapping"], link, model["metamodel"]["model"][(type + "_") + linkname])

+ 114 - 0
kernel/modelverse_kernel/compiled.py

@@ -179,3 +179,117 @@ def allInstances(a, b, **remainder):
     v =         yield [("RV", [i]) for i in final]
     _ =    yield [("CE", [result, i]) for i in final]
     raise PrimitiveFinished(result)
+
+def add_AL(a, b, **remainder):
+    worklist = [(b, "funcdef")]
+    added = set()
+    type_cache = {}
+
+    model_dict = yield [("RD", [a, "model"])]
+    metamodel = yield [("RD", [a, "metamodel"])]
+    metamodel_dict = yield [("RD", [metamodel, "model"])]
+    type_map = yield [("RD", [a, "type_mapping"])]
+    outgoing = yield [("RO", [model_dict])]
+    edges = yield [("RE", [i]) for i in outgoing]
+    added |= set([i[1] for i in edges])
+
+    result = yield [("CNV", ["__%s" % b])]
+
+    # All the action language elements and their expected output links
+    type_links = {
+            "if":       [("cond", ""), ("then", ""), ("else", ""), ("next", "")],
+            "while":    [("cond", ""), ("body", ""), ("next", "")],
+            "assign":   [("var", ""), ("value", ""), ("next", "")],
+            "break":    [("while", "while")],
+            "continue": [("while", "while")],
+            "return":   [("value", "")],
+            "resolve":  [("var", "")],
+            "access":   [("var", "")],
+            "constant": [("node", "")],
+            "output":   [("node", ""), ("next", "")],
+            "global":   [("var", "String"), ("next", "")],
+            "param":    [("name", "String"), ("value", ""), ("next_param", "param")],
+            "funcdef":  [("body", ""), ("next", "")],
+            "call":     [("func", ""), ("params", "param"), ("last_param", "param"), ("next", "")],
+        }
+
+    # Already add some often used types to the type cache, so we don't have to check for their presence
+    to_str, string = yield [("RD", [metamodel_dict, "to_str"]),
+                            ("RD", [metamodel_dict, "String"])]
+
+    type_cache = {"to_str": to_str,
+                  "String": string}
+
+    while worklist:
+        # Fetch the element and see if we need to add it
+        worknode, expected_type = worklist.pop(0)
+        if worknode in added:
+            continue
+
+        # Determine type of element
+        if expected_type == "":
+            value = yield [("RV", [worknode])]
+            if (isinstance(value, dict)) and ("value" in value):
+                v = value["value"]
+                if v in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]:
+                    expected_type = v
+                else:
+                    expected_type = "Any"
+            else:
+                expected_type = "Any"
+
+        # Fill the cache
+        if expected_type not in type_cache:
+            type_cache[expected_type] = yield [("RD", [metamodel_dict, expected_type])]
+
+        # Need to add it now
+        yield [("CD", [model_dict, "__%s" % worknode, worknode])]
+        added.add(worknode)
+        # NOTE can't just use CD here, as the key is a node and not a value
+        t1 = yield [("CE", [type_map, type_cache[expected_type]])]
+        t2 = yield [("CE", [t1, worknode])]
+        if t1 is None or t2 is None:
+            raise Exception("ERROR")
+
+        # Now add all its outgoing links, depending on the type we actually saw
+        links = type_links.get(expected_type, [])
+        for link in links:
+            link_name, destination_type = link
+
+            # Check if the link actually exists
+            destination = yield [("RD", [worknode, link_name])]
+            if destination is not None:
+                # If so, we add it and continue
+                edge = yield [("RDE", [worknode, link_name])]
+                edge_outlinks = yield [("RO", [edge])]
+                edge_outlink = edge_outlinks[0]
+                edge_name = yield [("RE", [edge_outlink])]
+                edge_name = edge_name[1]
+                # Now add: edge, edge_outlink, edge_name
+
+                # Add 'edge'
+                yield [("CD", [model_dict, "__%s" % edge, edge])]
+                added.add(edge)
+                link_type = "%s_%s" % (expected_type, link_name)
+                if link_type not in type_cache:
+                    type_cache[link_type] = yield [("RD", [metamodel_dict, link_type])]
+                t = yield [("CE", [type_map, type_cache[link_type]])]
+                yield [("CE", [t, edge])]
+
+                # Add 'edge_outlink'
+                yield [("CD", [model_dict, "__%s" % edge_outlink, edge_outlink])]
+                added.add(edge_outlink)
+                t = yield [("CE", [type_map, type_cache["to_str"]])]
+                yield [("CE", [t, edge_outlink])]
+
+                # Add 'edge_name' (if not present)
+                if edge_name not in added:
+                    yield [("CD", [model_dict, "__%s" % edge_name, edge_name])]
+                    t = yield [("CE", [type_map, type_cache["String"]])]
+                    yield [("CE", [t, edge_name])]
+                    added.add(edge_name)
+
+                # Add the destination to the worklist
+                worklist.append((destination, destination_type))
+
+    raise PrimitiveFinished(result)