浏览代码

Initial version of the JSON serialize/deserialize service

Yentl Van Tendeloo 7 年之前
父节点
当前提交
b19ec36af8

+ 115 - 0
bootstrap/json.alc

@@ -0,0 +1,115 @@
+include "primitives.alh"
+include "services.alh"
+include "constructors.alh"
+include "modelling.alh"
+
+String function json_connect():
+	String port
+	port = ""
+	while (port == ""):
+		port = comm_connect("JSON")
+	return port!
+
+Void function json_send_data(port : String, data : Element):
+	// Send the current value to the service
+	// First determine what it is!
+
+	if (has_value(data)):
+		// Primitive value, so send as-is
+		comm_set(port, "P")
+		comm_set(port, data)
+
+	else:
+		// Is a dict or list
+		// Problem is that we don't know which it is, as everything is a dictionary in the Modelverse...
+		// We will do a simple check: if it is a dictionary with keys the contiguous range of integers from 0 to length - 1, it is a list!
+		Element keys
+		Element expected
+		Element copy
+		Element entry
+		String key
+
+		keys = dict_keys(data)
+		expected = list_to_set(range(dict_len(data)))
+		if (set_equality(keys, expected)):
+			// Equal, so we are (most likely...) dealing with a list
+			comm_set(port, "L")
+			
+			copy = list_copy(data)
+			while (list_len(copy) > 0):
+				entry = list_pop(copy, 0)
+				json_send_data(port, entry)
+		else:
+			// Not equal, so we are surely dealing with a dict
+			comm_set(port, "D")
+
+			while (set_len(keys) > 0):
+				key = set_pop(keys)
+				comm_set(port, key)
+				json_send_data(port, data[key])
+	return!
+
+Element function process_JSON_data(port : String):
+	String type
+	Element result
+	type = comm_get(port)
+
+	if (type == "P"):
+		// Primitive data type, so just return as-is
+		result = comm_get(port)
+	elif (type == "L"):
+		// List, so fetch elements in turn
+		Integer length
+
+		length = comm_get(port)
+		result = list_create()
+		while (length > 0):
+			list_append(result, process_JSON_data(port))
+			length = length - 1
+	elif (type == "D"):
+		// Dict, so fetch elements in turn
+		Integer length
+
+		length = comm_get(port)
+		result = dict_create()
+		while (length > 0):
+			dict_add(result, comm_get(port), process_JSON_data(port))
+			length = length - 1
+	return result!
+
+String function json_serialize(data : Element):
+	String port
+	String response
+	port = json_connect()
+	comm_set(port, "encode")
+	response = comm_get(port)
+
+	if (response == "OK"):
+		// Send data to the service...
+		json_send_data(port, data)
+		response = comm_get(port)
+		comm_close(port)
+		return response!
+	else:
+		log("Error: " + response)
+		comm_close(port)
+		return ""!
+
+Element function json_deserialize(str : String):
+	String port
+	String response
+	Element rval
+	port = json_connect()
+	comm_set(port, "decode")
+
+	response = comm_get(port)
+
+	if (response == "OK"):
+		comm_set(port, str)
+		rval = process_JSON_data(port)
+		comm_close(port)
+		return rval!
+	else:
+		log("Error: " + response)
+		comm_close(port)
+		return read_root()!

+ 37 - 0
bootstrap/semi_primitives.alc

@@ -314,6 +314,19 @@ Element function dict_copy(d : Element):
 
 	return result!
 
+Element function list_copy(lst : Element):
+	Integer counter
+	Element result
+
+	result = list_create()
+	counter = 0
+
+	while (counter < list_len(lst)):
+		list_append(result, lst[counter])
+		counter = counter + 1
+
+	return result!
+
 Element function set_to_list(s : Element):
 	Element result
 	Element tmp
@@ -325,6 +338,18 @@ Element function set_to_list(s : Element):
 
 	return result!
 
+Element function list_to_set(s : Element):
+	Element result
+	Integer i
+
+	i = 0
+	result = set_create()
+	while (i < list_len(s)):
+		set_add(result, s[i])
+		i = i + 1
+
+	return result!
+
 Void function dict_overwrite(d : Element, key : Element, value : Element):
 	if (dict_in(d, key)):
 		dict_delete(d, key)
@@ -441,3 +466,15 @@ Element function set_difference(sa : Element, sb : Element):
 			set_remove(result, elem)
 
 	return result!
+
+Element function range(max : Integer):
+	Element result
+	Integer counter
+	result = list_create()
+	counter = 0
+
+	while (counter < max):
+		list_append(result, counter)
+		counter = counter + 1
+
+	return result!

+ 2 - 0
interface/HUTN/includes/json.alh

@@ -0,0 +1,2 @@
+String function json_serialize(data : Element)
+Element function json_deserialize(str : String)

+ 3 - 0
interface/HUTN/includes/primitives.alh

@@ -113,6 +113,8 @@ Element function set_equality(sa : Element, sb : Element)
 Element function dict_eq(da : Element, db : Element)
 Element function dict_copy(dict : Element)
 Element function set_to_list(s : Element)
+Element function list_to_set(s : Element)
+Element function list_copy(list : Element)
 Element function create_tuple(a : Element, b : Element)
 Void function dict_overwrite(a : Element, b : Element, c : Element)
 Void function set_merge(sa : Element, sb : Element)
@@ -124,3 +126,4 @@ String function reverseKeyLookup(a: Element, b: Element)
 Element function reverseKeyLookupMulti(a: Element, b: Element)
 Element function dict_values(dict : Element)
 Boolean function is_error(a : Element)
+Element function range(max : Integer)

+ 5 - 0
scripts/run_local_modelverse.py

@@ -11,6 +11,7 @@ else:
 # Start up the HUTN compilation service already
 try:
     hutn = subprocess.Popen([sys.executable, "scripts/HUTN_service.py", "127.0.0.1:%s" % port])
+    json = subprocess.Popen([sys.executable, "scripts/JSON_service.py", "127.0.0.1:%s" % port])
 
     os.chdir("hybrid_server")
     subprocess.check_call([sys.executable, "-m", "sccd.compiler.sccdc", "-p", "threads", "server.xml"])
@@ -33,3 +34,7 @@ finally:
         hutn.terminate()
     except:
         pass
+    try:
+        json.terminate()
+    except:
+        pass