Jelajahi Sumber

Explicitly model the symbol checking algorithm

Yentl Van Tendeloo 9 tahun lalu
induk
melakukan
48942603ba

+ 69 - 0
bootstrap/compilation_manager.alc

@@ -56,6 +56,23 @@ Element function compilation_manager():
 	elif (operation == "read_initializers"):
 		node = root[input()]["initializers"]
 		output(node)
+	elif (operation == "check_symbols"):
+		Element objs
+		String obj
+
+		objs = create_node()
+		obj = input()
+		log("Checking symbols")
+		while (obj != ""):
+			if (dict_in(root, obj)):
+				set_add(objs, obj)
+				log("Will check " + obj)
+			else:
+				log("ERROR: couldn't find obj " + obj)
+			obj = input()
+
+		log("Start check!")
+		output(check_symbols(root, objs))
 	elif (operation == "is_defined"):
 		object_name = input()
 		if (dict_in(root, object_name)):
@@ -65,3 +82,55 @@ Element function compilation_manager():
 	else:
 		log("Failed to understand command")
 	return operation
+
+Boolean function check_symbols(root : Element, objs : Element):
+	Element symbols
+	String obj
+	Element keys
+	String key
+	Element copy_objs
+
+	// We always need a main variable
+	symbols = create_node()
+	dict_add(symbols, "main", False)
+
+	// Resolve all symbols
+	copy_objs = set_copy(objs)
+	while (0 < list_len(copy_objs)):
+		obj = set_pop(copy_objs)
+		log("CHECK " + obj)
+		keys = dict_keys(root[obj]["symbols"])
+		while (0 < list_len(keys)):
+			key = set_pop(keys)
+
+			if (root[obj]["symbols"][key]):
+				log("  SYMB " + key)
+				// Defines
+				if (bool_not(dict_in(symbols, key))):
+					// Not yet in dictionary
+					dict_add(symbols, key, True)
+				elif (symbols[key]):
+					// Already in dictionary, and it was already defined
+					log("ERROR: multiple definition of symbol " + key)
+					return False
+				else:
+					// Already in dictionary, but only used
+					dict_delete(symbols, key)
+					dict_add(symbols, key, True)
+			else:
+				// Uses
+				if (bool_not(dict_in(symbols, key))):
+					dict_add(symbols, key, False)
+
+	// Check whether we have everything
+	keys = dict_keys(symbols)
+	while (0 < list_len(keys)):
+		key = set_pop(keys)
+		if (bool_not(symbols[key])):
+			if (bool_not(bool_or(key == "output", key == "input"))):
+				log(cast_e2s(symbols[key]))
+				log("ERROR: undefined symbol " + key)
+				return False
+
+	log("Symbol checking OK")
+	return True

+ 13 - 0
interface/HUTN/hutn_compiler/linker.py

@@ -14,6 +14,7 @@ def link(address, username, objects):
     users = {}
     data = []
 
+    """
     definers["main"] = None
     for obj in objects:
         data.append(("V", '3'))
@@ -45,6 +46,18 @@ def link(address, username, objects):
             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])))
+    """
+
+    data.append(("V", '3'))
+    data.append(("V", '"check_symbols"'))
+    for obj in objects:
+        data.append(("V", '"%s"' % obj))
+    data.append(("V", '""'))
+
+    data = flush_data(address, data, username)
+    v = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
+    if "False" in v:
+        raise Exception("Linking error")
 
     # Ok, we know that all symbols can be defined with this set of files, now link their initializers together
     initializers = []

+ 0 - 7
kernel/modelverse_kernel/primitives.py

@@ -264,7 +264,6 @@ def dict_delete(a, b, **remainder):
         b_value = yield [("RV", [b])]
         edge = yield [("RDE", [a, b_value])]
     yield [("DE", [edge])]
-    print("DELETE " + str(edge))
     raise PrimitiveFinished(a)
 
 def dict_read(a, b, **remainder):
@@ -317,12 +316,8 @@ def dict_reverse(a, b, **remainder):
     raise PrimitiveFinished(result)
 
 def is_physical_int(a, **remainder):
-    print("REQUEST PHYSICAL INT")
     t = yield [("RV", [a])]
-    print(a)
-    print(t)
     result = yield [("CNV", [isinstance(t, int) or isinstance(t, long)])]
-    print(type(t))
     raise PrimitiveFinished(result)
 
 def is_physical_string(a, **remainder):
@@ -389,12 +384,10 @@ def delete_element(a, **remainder):
     if edge[0] is None:
         # Not an edge:
         yield [("DN", [a])]
-        print("DELETE ELEMENT NODE " + str(a))
         result = yield [("CNV", [False])]
         raise PrimitiveFinished(result)
     else:
         yield [("DE", [a])]
-        print("DELETE ELEMENT EDGE " + str(a))
         result = yield [("CNV", [True])]
         raise PrimitiveFinished(result)