# Exception to indicate the result value of the primitive, as a return cannot be used class PrimitiveFinished(Exception): def __init__(self, value): self.result = value def integer_subtraction(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value - b_value])] raise PrimitiveFinished(result) def integer_addition(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value + b_value])] raise PrimitiveFinished(result) def integer_multiplication(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value * b_value])] raise PrimitiveFinished(result) def integer_division(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [int(a_value) / b_value])] raise PrimitiveFinished(result) def integer_gt(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value > b_value])] raise PrimitiveFinished(result) def integer_lt(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value < b_value])] raise PrimitiveFinished(result) def integer_neg(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [-a_value])] raise PrimitiveFinished(result) def bool_and(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value and b_value])] raise PrimitiveFinished(result) def bool_or(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value or b_value])] raise PrimitiveFinished(result) def bool_not(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [not a_value])] raise PrimitiveFinished(result) def float_subtraction(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value - b_value])] raise PrimitiveFinished(result) def float_addition(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value + b_value])] raise PrimitiveFinished(result) def float_multiplication(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value * b_value])] raise PrimitiveFinished(result) def float_division(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value / b_value])] raise PrimitiveFinished(result) def float_gt(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value > b_value])] raise PrimitiveFinished(result) def float_lt(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value < b_value])] raise PrimitiveFinished(result) def float_neg(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [-a_value])] raise PrimitiveFinished(result) def string_join(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [str(a_value) + str(b_value)])] raise PrimitiveFinished(result) def string_split(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = a_value.split(b_value) elems = yield [("CN", [])] + [("CNV", [v]) for v in result] new_val = elems[0] yield [("CD", [new_val, i, v]) for i, v in enumerate(elems[1:])] raise PrimitiveFinished(new_val) def string_get(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value[b_value]])] raise PrimitiveFinished(result) def string_len(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [len(a_value)])] raise PrimitiveFinished(result) def value_eq(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value == b_value])] raise PrimitiveFinished(result) def value_neq(a, b, **remainder): a_value, b_value = yield [("RV", [a]), ("RV", [b])] result = yield [("CNV", [a_value != b_value])] raise PrimitiveFinished(result) def element_eq(a, b, **remainder): result = yield [("CNV", [a == b])] raise PrimitiveFinished(result) def element_neq(a, b, **remainder): result = yield [("CNV", [a != b])] raise PrimitiveFinished(result) def cast_a2s(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [str(a_value["value"])])] raise PrimitiveFinished(result) def cast_i2f(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [float(a_value)])] raise PrimitiveFinished(result) def cast_i2s(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [str(a_value)])] raise PrimitiveFinished(result) def cast_i2b(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [bool(a_value)])] raise PrimitiveFinished(result) def cast_f2i(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [int(a_value)])] raise PrimitiveFinished(result) def cast_f2s(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [str(a_value)])] raise PrimitiveFinished(result) def cast_f2b(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [bool(a_value)])] raise PrimitiveFinished(result) def cast_s2i(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [int(a_value)])] raise PrimitiveFinished(result) def cast_s2f(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [float(a_value)])] raise PrimitiveFinished(result) def cast_s2b(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [bool(a_value)])] raise PrimitiveFinished(result) def cast_b2i(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [int(a_value)])] raise PrimitiveFinished(result) def cast_b2f(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [float(a_value)])] raise PrimitiveFinished(result) def cast_b2s(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [str(a_value)])] raise PrimitiveFinished(result) def cast_e2s(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", ["{ID: %s, value: %s}" % (a, a_value)])] raise PrimitiveFinished(result) def cast_v2s(a, **remainder): a_value = yield [("RV", [a])] if isinstance(a_value, (str, unicode)): # String should be encoded to distinguish between 3 and "3" a_value = '"%s"' % a_value elif isinstance(a_value, dict): # Action or type a_value = a_value["value"] result = yield [("CNV", ["%s" % (a_value)])] raise PrimitiveFinished(result) def cast_id2s(a, **remainder): result = yield [("CNV", ["%s" % (a)])] raise PrimitiveFinished(result) def list_append(a, b, **remainder): a_outgoing = yield [("RO", [a])] _ = yield [("CD", [a, len(a_outgoing), b])] raise PrimitiveFinished(a) def list_insert(a, b, c, **remainder): a_outgoing, c_value = yield [("RO", [a]), ("RV", [c])] links = yield [("RD", [a, i]) for i in range(c_value, len(a_outgoing))] + \ [("RDE", [a, i]) for i in range(c_value, len(a_outgoing))] values = links[:len(links)/2] edges = links[len(links)/2:] yield [("CD", [a, c_value, b])] + \ [("CD", [a, c_value + 1 + index, value]) for index, value in enumerate(values)] + \ [("DE", [i]) for i in edges] raise PrimitiveFinished(a) def list_delete(a, b, **remainder): a_outgoing, b_value = yield [("RO", [a]), ("RV", [b])] links = yield [("RD", [a, i]) for i in range(b_value, len(a_outgoing))] + \ [("RDE", [a, i]) for i in range(b_value, len(a_outgoing))] values = links[:len(links)/2] edges = links[len(links)/2:] yield [("CD", [a, b_value + index, value]) for index, value in enumerate(values[1:])] + \ [("DE", [i]) for i in edges] raise PrimitiveFinished(a) def list_read(a, b, **remainder): b_value = yield [("RV", [b])] result = yield [("RD", [a, b_value])] if result is None: raise Exception("List read out of bounds: %s" % b_value) raise PrimitiveFinished(result) def list_len(a, **remainder): outgoings = yield [("RO", [a])] result = yield [("CNV", [len(outgoings)])] raise PrimitiveFinished(result) def dict_add(a, b, c, **remainder): new_edge = yield [("CE", [a, c])] yield [("CE", [new_edge, b])] raise PrimitiveFinished(a) def dict_delete(a, b, **remainder): edge = yield [("RDNE", [a, b])] if edge is None: # This exact node isn't in this dictionary, so delete everything matching the value instead b_value = yield [("RV", [b])] edge = yield [("RDE", [a, b_value])] yield [("DE", [edge])] raise PrimitiveFinished(a) def dict_read(a, b, **remainder): b_value = yield [("RV", [b])] result = yield [("RD", [a, b_value])] raise PrimitiveFinished(result) def dict_read_edge(a, b, **remainder): b_value = yield [("RV", [b])] result = yield [("RDE", [a, b_value])] raise PrimitiveFinished(result) def dict_read_node(a, b, **remainder): result = yield [("RDN", [a, b])] raise PrimitiveFinished(result) def dict_in(a, b, **remainder): b_value = yield [("RV", [b])] value = yield [("RD", [a, b_value])] is_in = value is not None result = yield [("CNV", [is_in])] raise PrimitiveFinished(result) def dict_in_node(a, b, **remainder): value = yield [("RDN", [a, b])] result = yield [("CNV", [value is not None])] raise PrimitiveFinished(result) def dict_len(a, **remainder): outgoings = yield [("RO", [a])] result = yield [("CNV", [len(outgoings)])] raise PrimitiveFinished(result) def dict_keys(a, **remainder): keys, result = yield [("RDK", [a]), ("CN", [])] yield [("CE", [result, v]) for v in keys] raise PrimitiveFinished(result) def dict_reverse(a, b, **remainder): edges = yield [("RO", [a])] expanded_edges = yield [("RE", [i]) for i in edges] for i, edge in enumerate(expanded_edges): if b == edge[1]: # Found our edge: edges[i] outgoing = yield [("RO", [edges[i]])] result = yield [("RE", [outgoing[0]])] raise PrimitiveFinished(result[1]) result = yield [("CNV", ["(unknown: %s)" % b])] raise PrimitiveFinished(result) def is_physical_int(a, **remainder): t = yield [("RV", [a])] result = yield [("CNV", [isinstance(t, int) or isinstance(t, long)])] raise PrimitiveFinished(result) def is_physical_string(a, **remainder): t = yield [("RV", [a])] result = yield [("CNV", [isinstance(t, str) or isinstance(t, unicode)])] raise PrimitiveFinished(result) def is_physical_float(a, **remainder): t = yield [("RV", [a])] result = yield [("CNV", [isinstance(t, float)])] raise PrimitiveFinished(result) def is_physical_boolean(a, **remainder): t = yield [("RV", [a])] result = yield [("CNV", [isinstance(t, bool)])] raise PrimitiveFinished(result) def is_physical_action(a, **remainder): t = yield [("RV", [a])] result = yield [("CNV", [isinstance(t, dict) and t["value"] in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]])] raise PrimitiveFinished(result) def create_node(**remainder): result = yield [("CN", [])] raise PrimitiveFinished(result) def create_edge(a, b, **remainder): result = yield [("CE", [a, b])] raise PrimitiveFinished(result) def create_value(a, **remainder): a_value = yield [("RV", [a])] result = yield [("CNV", [a_value])] raise PrimitiveFinished(result) def read_nr_out(a, **remainder): outgoing = yield [("RO", [a])] result = yield [("CNV", [len(outgoing)])] raise PrimitiveFinished(result) def read_out(a, b, **remainder): outgoing, b_value = yield [("RO", [a]), ("RV", [b])] raise PrimitiveFinished(sorted(outgoing)[b_value]) def read_nr_in(a, **remainder): incoming = yield [("RI", [a])] result = yield [("CNV", [len(incoming)])] raise PrimitiveFinished(result) def read_in(a, b, **remainder): incoming, b_value = yield [("RI", [a]), ("RV", [b])] raise PrimitiveFinished(sorted(incoming)[b_value]) def read_edge_src(a, **remainder): result = yield [("RE", [a])] raise PrimitiveFinished(result[0]) def read_edge_dst(a, **remainder): result = yield [("RE", [a])] raise PrimitiveFinished(result[1]) def delete_element(a, **remainder): edge = yield [("RE", [a])] if edge[0] is None: # Not an edge: yield [("DN", [a])] result = yield [("CNV", [False])] raise PrimitiveFinished(result) else: yield [("DE", [a])] result = yield [("CNV", [True])] raise PrimitiveFinished(result) def read_root(root, **remainder): raise PrimitiveFinished(root) def set_add(a, b, **remainder): yield [("CE", [a, b])] raise PrimitiveFinished(a) def set_pop(a, **remainder): outgoing = yield [("RO", [a])] v, _ = yield [("RE", [outgoing[0]]), ("DE", [outgoing[0]])] raise PrimitiveFinished(v[1]) def set_remove(a, b, **remainder): outgoing, b_value = yield [("RO", [a]), ("RV", [b])] elements = yield [("RE", [i]) for i in outgoing] elements = [elements] if not isinstance(elements[0], list) else elements values = yield [("RV", [i[1]]) for i in elements] values = [values] if not isinstance(values, list) else values yield [("DE", [identifier]) for identifier, edge in zip(outgoing, values) if edge == b_value] raise PrimitiveFinished(a) def set_remove_node(a, b, **remainder): outgoing = yield [("RO", [a])] elements = yield [("RE", [i]) for i in outgoing] elements = [elements] if not isinstance(elements[0], list) else elements yield [("DE", [identifier]) for identifier, edge in zip(outgoing, elements) if edge[1] == b] raise PrimitiveFinished(a) def set_in(a, b, **remainder): outgoing, b_value = yield [("RO", [a]), ("RV", [b])] if outgoing: elements = yield [("RE", [i]) for i in outgoing] elements = [elements] if not isinstance(elements[0], list) else elements values = yield [("RV", [i[1]]) for i in elements] values = [values] if not isinstance(values, list) else values if b_value in [v for v in values]: result = yield [("CNV", [True])] else: result = yield [("CNV", [False])] else: result = yield [("CNV", [False])] raise PrimitiveFinished(result) def set_in_node(a, b, **remainder): outgoing = yield [("RO", [a])] if outgoing: elements = yield [("RE", [i]) for i in outgoing] elements = [elements] if not isinstance(elements[0], list) else elements if b in [v[1] for v in elements]: result = yield [("CNV", [True])] else: result = yield [("CNV", [False])] else: result = yield [("CNV", [False])] raise PrimitiveFinished(result) def is_edge(a, **remainder): edge = yield [("RE", [a])] result = yield [("CNV", [edge[0] is not None])] raise PrimitiveFinished(result) #TODO deprecate def deserialize(a, root, **remainder): print("DESERIALIZE") value = yield [("RV", [a])] id_mappings = {} complex_primitives = frozenset(["if", "while", "assign", "call", "break", "continue", "return","resolve","access", "constant", "input", "output", "declare", "global"]) for l in value.split("\n"): try: graph_type, constructor = l.split(None, 1) except: continue if graph_type == "N": # Node id_mappings[constructor] = yield [("CN", [])] elif graph_type == "V": # Node with Value name, temp = constructor.split("(", 1) string_value = temp[:-1] if string_value in complex_primitives: value = {"value": string_value} else: #TODO this is very dangerous! value = eval(string_value) id_mappings[name] = yield [("CNV", [value])] elif graph_type == "E": # Edge name, temp = constructor.split("(", 1) source, target = temp[:-1].split(",", 1) if target[0] == "?" and target not in id_mappings: hierarchy = target[1:].split("/") current = yield [("RD", [root, "__hierarchy"])] for i in hierarchy: current = yield [("RD", [current, i])] id_mappings[target] = current try: source = int(source) except: source = id_mappings[source] try: target = int(target) except: target = id_mappings[target] # Both nodes will normally be already present in the matching dictionary, so can just pass them along id_mappings[name] = yield [("CE", [source, target])] elif graph_type == "D": source, value, target = constructor.split(",",3) if value in complex_primitives: value = {"value": value} else: #TODO this is very dangerous! value = eval(value) if target[0] == "?" and target not in id_mappings: hierarchy = target[1:].split("/") current = yield [("RD", [root, "__hierarchy"])] for i in hierarchy: current = yield [("RD", [current, i])] id_mappings[target] = current try: source = int(source) except: source = id_mappings[source] try: target = int(target) except: target = id_mappings[target] yield [("CD", [source, value, target])] else: print("Unknown graph type: " + str(graph_type)) raise PrimitiveFinished(id_mappings["auto_initial_IP"]) def log(a, **remainder): a_value = yield [("RV", [a])] print("== LOG == " + str(a_value)) raise PrimitiveFinished(a) def read_userroot(user_root, **remainder): raise PrimitiveFinished(user_root)