def veval_ast_if(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): assert (isinstance(astc.nast, gast.gast.If)) lineprop = utils.LineProperty(astc.lineno) # if condition test = veval_ast(astc.c(astc.nast.test), local_field, graph) test_value = try_get_value(test, 'if', lineprop) id_str = str(utils.get_guid()) if_id = 'if_' + id_str true_id = 'true_' + id_str false_id = 'false_' + id_str # True values.push_history(true_id) true_graph = Graph() true_graph.root_graph = graph.root_graph true_graph.name = 'True' body = veval_ast(astc.c(astc.nast.body), local_field, true_graph) true_value_inputs = values.get_inputs() true_value_outputs = values.get_outputs() values.pop_history() # False values.push_history(false_id) false_graph = Graph() false_graph.root_graph = graph.root_graph false_graph.name = 'False' body = veval_ast(astc.c(astc.nast.orelse), local_field, false_graph) false_value_inputs = values.get_inputs() false_value_outputs = values.get_outputs() values.pop_history() # generate pairs value_pairs = {} for v in true_value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['true_input_value'] = v.input_value value_pairs[key]['true_input_body_value'] = v.value for v in true_value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['true_output_body_value'] = v.value for v in false_value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['false_input_value'] = v.input_value value_pairs[key]['false_input_body_value'] = v.value for v in false_value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['false_output_body_value'] = v.value inputs = [] outputs = [] for k, v in value_pairs.items(): name = v['name'] field = v['field'] input_value = None true_input_body_value = None false_input_body_value = None if 'true_input_value' in v: input_value = v['true_input_value'] elif 'false_input_value' in v: input_value = v['false_input_value'] if input_value is not None: if 'true_input_body_value' in v: true_input_body_value = v['true_input_body_value'] else: true_input_body_value = functions.generate_value_with_same_type( input_value) if 'false_input_body_value' in v: false_input_body_value = v['false_input_body_value'] else: false_input_body_value = functions.generate_value_with_same_type( input_value) true_output_body_value = None false_output_body_value = None output_value = None if 'true_output_body_value' in v: true_output_body_value = v['true_output_body_value'] else: true_output_body_value = true_input_body_value if 'false_output_body_value' in v: false_output_body_value = v['false_output_body_value'] else: false_output_body_value = false_input_body_value # TODO check types between true and false if true_output_body_value is not None or false_output_body_value is not None: output_value = functions.generate_value_with_same_type( true_output_body_value) if input_value is not None: inputs.append(input_value) true_graph.add_input_value(true_input_body_value) false_graph.add_input_value(false_input_body_value) if output_value is not None: outputs.append(output_value) true_graph.add_output_value(true_output_body_value) false_graph.add_output_value(false_output_body_value) if field.get_attribute(name).has_obj(): field.get_attribute(name).get_ref().revise(output_value) else: field.get_attribute(name).revise(values.ValueRef(output_value)) node = nodes.NodeIf(test_value, inputs, true_graph, false_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) return None
def veval_ast_if(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): assert (isinstance(astc.nast, gast.gast.If)) lineprop = utils.LineProperty(astc.lineno) # if condition test = veval_ast(astc.c(astc.nast.test), local_field, graph) test_value = try_get_value(test, 'if', lineprop) id_str = str(utils.get_guid()) if_id = 'if_' + id_str true_id = 'true_' + id_str false_id = 'false_' + id_str values.commit(if_id) # True condition values.checkout(if_id) true_graph = Graph() true_graph.name = 'True' body = veval_ast(astc.c(astc.nast.body), local_field, true_graph) values.commit(true_id) true_input_attributes = get_input_attritubtes(local_field, if_id, true_id) true_output_attributes = get_output_attritubtes(local_field, if_id, true_id) true_output_objs = get_output_objs(local_field, if_id, true_id) #TODO(durswd): improve true_input_attributes = filter_attributes(true_input_attributes) true_output_attributes = filter_attributes(true_output_attributes) true_output_attributes_2_values = {} for attribute in true_output_attributes: true_output_attributes_2_values[attribute] = attribute.get_obj( ).get_value() # False condition values.checkout(if_id) false_graph = Graph() false_graph.name = 'False' orelse = veval_ast(astc.c(astc.nast.orelse), local_field, false_graph) values.commit(false_id) false_input_attributes = get_input_attritubtes(local_field, if_id, false_id) false_output_attributes = get_output_attritubtes(local_field, if_id, false_id) false_output_objs = get_output_objs(local_field, if_id, false_id) #TODO(durswd): improve false_input_attributes = filter_attributes(false_input_attributes) false_output_attributes = filter_attributes(false_output_attributes) false_output_attributes_2_values = {} for attribute in false_output_attributes: false_output_attributes_2_values[attribute] = attribute.get_obj( ).get_value() # Merge values.checkout(if_id) # Input input_attributes = set(true_input_attributes) | set(false_input_attributes) # remove unexisting values input_attributes = [v for v in input_attributes if v.has_obj()] input_values = [i.get_obj().get_value() for i in input_attributes] # Output name2output_attributes = {} # generate attribute pairs for attribute in true_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2output_attributes.keys(): name2output_attributes[key][0] = attribute else: name2output_attributes[key] = [attribute, None] for attribute in false_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2output_attributes.keys(): name2output_attributes[key][1] = attribute else: name2output_attributes[key] = [None, attribute] obj2output_values = {} for obj in true_output_objs: if obj.get_value() == None: continue key = obj value = obj.get_value_log(true_id) if key in obj2output_values.keys(): obj2output_values[key][0] = value else: obj2output_values[key] = [value, None] for obj in false_output_objs: if obj.get_value() == None: continue key = obj value = obj.get_value_log(false_id) if key in obj2output_values.keys(): obj2output_values[key][1] = value else: obj2output_values[key] = [None, value] output_attributes = set(true_output_attributes) | set( false_output_attributes) output_values = [] non_volatiles = [] for attribute_pair in name2output_attributes.values(): true_attribute, false_attribute = attribute_pair name = '' parent = None # type: values.Field if true_attribute is not None: name = true_attribute.name parent = true_attribute.parent if false_attribute is not None: name = false_attribute.name parent = false_attribute.parent if true_attribute is not None: true_value = true_output_attributes_2_values[true_attribute] else: if parent.has_attribute(name): true_value = parent.get_attribute(name).get_obj().get_value() if not true_value in input_values: input_values.append(true_value) else: # TODO : it should be better # case # if xxx: # y = 10 # print(y) true_value = false_output_attributes_2_values[false_attribute] if false_attribute is not None: false_value = false_output_attributes_2_values[false_attribute] else: if parent.has_attribute(name): false_value = parent.get_attribute(name).get_obj().get_value() if not false_value in input_values: input_values.append(false_value) else: # TODO : it should be better # case # if xxx: # y = 10 # print(y) false_value = true_output_attributes_2_values[true_attribute] true_graph.add_output_value(true_value) false_graph.add_output_value(false_value) if true_attribute is not None and false_attribute is not None and true_attribute != false_attribute: # dynamic value = functions.generate_value_with_same_type(true_value) output_values.append(value) parent.get_attribute(name).revise(values.Object(value)) elif true_attribute is not None and false_attribute is not None: # change both value = functions.generate_value_with_same_type(true_value) output_values.append(value) if parent.get_attribute(name).is_non_volatile: non_volatiles.append( (parent.get_attribute(name).initial_obj.get_value(), value)) parent.get_attribute(name).revise(values.Object(value)) elif true_attribute in input_attributes: value = functions.generate_value_with_same_type(true_value) if parent.get_attribute(name).is_non_volatile: non_volatiles.append( (parent.get_attribute(name).initial_obj.get_value(), value)) output_values.append(value) parent.get_attribute(name).revise(values.Object(value)) else: value = functions.generate_value_with_same_type(false_value) if parent.get_attribute(name).is_non_volatile: non_volatiles.append( (parent.get_attribute(name).initial_obj.get_value(), value)) output_values.append(value) parent.get_attribute(name).revise(values.Object(value)) for input_value in input_values: true_graph.add_input_value(input_value) false_graph.add_input_value(input_value) for obj, values_pairs in obj2output_values.items(): if not obj.get_value() in input_values: input_values.append(obj.get_value()) value = None true_value = None false_value = None if values_pairs[0] is not None: value = values_pairs[0] true_value = values_pairs[0] if values_pairs[1] is not None: value = values_pairs[1] false_value = values_pairs[1] if true_value is None: true_value = obj.get_value() if false_value is None: false_value = obj.get_value() value = functions.generate_value_with_same_type(value) obj.revise(value) output_values.append(value) true_graph.add_output_value(true_value) false_graph.add_output_value(false_value) node = nodes.NodeIf(test_value, input_values, true_graph, false_graph, astc.lineno) node.set_outputs(output_values) graph.add_node(node) # add non-volatiles for tv, v in non_volatiles: node_nv = nodes.NodeNonVolatileAssign(tv, v) graph.add_node(node_nv) return None