def compile_Init(self, node): env = self.env env.push_cvar_env() new_marking = cyast.Assign( targets=[cyast.Name(node.marking_var.name)], value=self.env.marking_type.new_marking_expr(self.env)) return_stmt = cyast.E("return {}".format(node.marking_var.name)) stmts = [new_marking] stmts.extend(self.compile(node.body)) stmts.append(return_stmt) decl = CVarSet() decl.extend([ cyast.CVar(node.marking_var.name, self.env.type2str(node.marking_var.type)) ]) additionnal_decls = self.env.pop_cvar_env() decl.extend(additionnal_decls) f1 = cyast.Builder.FunctionDef(name=node.function_name, body=stmts, returns=cyast.Name("Marking"), decl=decl) f2 = cyast.Builder.FunctionCDef(name="neco_init", body=stmts, returns=cyast.Name("Marking"), decl=decl) return [f1, f2]
def gen_different(self, indices): base = None current = None first_index = indices.pop() for index in indices: check = cyast.If(test=cyast.Compare( left=cyast.Name(first_index.name), ops=[cyast.NotEq()], comparators=[cyast.Name(index.name)]), body=[], orelse=[]) if not base: base = check current = check else: current.body.append(check) current = check inner = current if len(indices) > 1: _, inner = self.gen_different(indices) current.body.append(base) return base, inner
def gen_main_check_function(checker_env, id_prop_map): function_name = "neco_check" builder = cyast.Builder() variable_provider = VariableProvider() checker_env.push_cvar_env() checker_env.push_variable_provider(variable_provider) marking_var = variable_provider.new_variable( variable_type=checker_env.marking_type.type) atom_var = variable_provider.new_variable( variable_type=TypeInfo.get('Int')) builder.begin_FunctionCDef( name=function_name, args=(cyast.A(marking_var.name, type=checker_env.type2str(marking_var.type)).param( atom_var.name, type=checker_env.type2str(TypeInfo.get('Int')))), returns=cyast.Name("int"), decl=[], public=True, api=True) for (i, (ident, _)) in enumerate(id_prop_map.iteritems()): if i == 0: builder.begin_If( test=cyast.Compare(left=cyast.Name(atom_var.name), ops=[cyast.Eq()], comparators=[cyast.Num(ident)])) else: builder.begin_Elif( test=cyast.Compare(left=cyast.Name(atom_var.name), ops=[cyast.Eq()], comparators=[cyast.Num(ident)])) builder.emit_Return( checker_env.get_check_function("check_{}".format(ident)).call( [cyast.Name(marking_var.name)])) for _ in id_prop_map: builder.end_If() builder.emit( cyast.Print(dest=cyast.E('sys.stderr'), values=[ cyast.Str(s='!W! invalid proposition identifier'), cyast.Name(atom_var.name) ], nl=True)) builder.emit_Return(cyast.Num(n=0)) builder.end_FunctionDef() tree = cyast.to_ast(builder) checker_env.register_check_function(function_name, FunctionWrapper(function_name, tree)) return tree
def compile_Succs(self, node): body = [] body.extend(self.compile(node.body)) body.append(cyast.E("return " + node.arg_marking_acc_var.name)) f1 = cyast.Builder.FunctionCpDef( name=node.function_name, args=self.main_succ_function_args(node), body=body, lang=cyast.CpDef(public=True), returns=cyast.Name("set"), decl=[ cyast.CVar(name=node.arg_marking_acc_var.name, type=self.env.type2str( node.arg_marking_acc_var.type), init=self.env.marking_set_type.new_marking_set_expr( self.env)) ]) body = [cyast.E("l = ctypes_ext.neco_list_new()")] body.append( cyast.For( target=cyast.to_ast(cyast.E("e")), iter=cyast.to_ast(cyast.E("succs(m, ctx)")), body=[ cyast.to_ast( cyast.stmt(cyast.E("ctypes_ext.__Pyx_INCREF(e)"))), cyast.Expr( cyast.Call( func=cyast.to_ast( cyast.E("ctypes_ext.neco_list_push_front")), args=[cyast.to_ast(cyast.E("l")), cyast.Name("e")], keywords=[], starargs=None, kwargs=None)) ])) body.append(cyast.E("return l")) f2 = cyast.Builder.FunctionCDef( name="neco_succs", args=(cyast.A( "m", type=self.env.type2str(node.arg_marking_var.type)).param( "ctx", type=self.env.type2str(node.arg_ctx_var.type))), body=body, returns=cyast.Name("ctypes_ext.neco_list_t*"), decl=[ cyast.CVar(name="l", type="ctypes_ext.neco_list_t*"), cyast.CVar(name="e", type="Marking") ]) return [f1]
def gen_All_function(checker_env, function_name, place_name, arg_function_name): marking_type = checker_env.marking_type variable_provider = VariableProvider() checker_env.push_cvar_env() checker_env.push_variable_provider(variable_provider) builder = cyast.Builder() marking_var = variable_provider.new_variable( variable_type=marking_type.type) place_type = marking_type.get_place_type_by_name(place_name) token_var = variable_provider.new_variable( variable_type=place_type.token_type) # check_var = variable_provider.new_variable(variable_type=TypeInfo.Int) builder.begin_FunctionCDef(name=function_name, args=(cyast.A(marking_var.name, type=checker_env.type2str( marking_var.type))), returns=cyast.Name("int"), decl=[], public=False, api=False) main_body = [] loop_var = variable_provider.new_variable( variable_type=place_type.token_type) inner_body = cyast.If( cyast.UnaryOp( cyast.Not(), cyast.Name(arg_function_name + '(' + loop_var.name + ')')), [cyast.Return(cyast.Num(0))]) node = place_type.enumerate_tokens(checker_env, loop_var, marking_var, body=inner_body) main_body.append(node) main_body.append(cyast.Return(value=cyast.Num(1))) for stmt in main_body: builder.emit(stmt) builder.end_FunctionDef() return cyast.to_ast(builder)
def gen_check_function(checker_env, identifier, atom): marking_type = checker_env.marking_type variable_provider = VariableProvider() checker_env.push_cvar_env() checker_env.push_variable_provider(variable_provider) builder = cyast.Builder() marking_var = variable_provider.new_variable( variable_type=marking_type.type) function_name = "check_{}".format(identifier) builder.begin_FunctionCDef(name=function_name, args=cyast.A(marking_var.name, type=checker_env.type2str( marking_var.type)), returns=cyast.Name("int"), decl=[], public=False, api=False) formula = atom.formula builder.emit( cyast.Return(gen_check_expression(checker_env, marking_var, formula))) builder.end_FunctionDef() tree = cyast.to_ast(builder) tree = flatten_ast(tree) checker_env.register_check_function(function_name, FunctionWrapper(function_name, tree)) return tree
def compile_IsFireable(self, node): self.env.push_cvar_env() self.env.push_variable_provider(node.variable_provider) self.var_helper = node.transition_info.variable_helper stmts = [self.compile(node.body)] decl = netir.CVarSet() input_arcs = node.transition_info.input_arcs for input_arc in input_arcs: decl.extend(self.try_gen_type_decl(input_arc)) inter_vars = node.transition_info.intermediary_variables for var in inter_vars: if (not var.type.is_UserType) or self.env.is_cython_type(var.type): decl.add( cyast.CVar(name=var.name, type=self.env.type2str(var.type))) additionnal_decls = self.env.pop_cvar_env() for var in additionnal_decls: decl.add(var) result = cyast.to_ast( cyast.Builder.FunctionDef(name=node.function_name, args=(cyast.A( node.arg_marking_var.name, type=self.env.type2str( node.arg_marking_var.type))), body=stmts, lang=cyast.CDef(public=False), returns=cyast.Name("int"), decl=decl)) return result
def compile_FlushIn(self, node): destination_place = self.env.marking_type.get_place_type_by_name( node.place_name) return [ cyast.Assign(targets=[cyast.Name(node.token_var.name)], value=destination_place.attribute_expr( self.env, node.marking_var)) ]
def compile_CheckType(self, node): type_info = node.type if type_info.is_AnyType: return self.compile(node.body) test = cyast.Call(func=cyast.Name('isinstance'), args=[ cyast.E(node.variable.name), cyast.E(self.env.type2str(type_info)) ]) return cyast.Builder.If(test=test, body=self.compile(node.body))
def gen_tuple(self, tuple_info): elts = [] for info in tuple_info: if info.is_Value: elts.append(cyast.E(repr(info.raw))) elif info.is_Variable: elts.append(cyast.Name(id=info.name)) elif info.is_Tuple: elts.append(self.gen_tuple(info)) elif info.is_Expression: elts.append(cyast.E(info.raw)) else: raise NotImplementedError, info.component.__class__ return cyast.Builder.Tuple(elts=elts)
def generate_pxd(self, env): cls = cyast.Builder.PublicClassCDef(name="Marking", bases=[cyast.E("object")], spec=cyast.type_name_spec( o="Marking", t="MarkingType")) ################################################################################ # attributes ################################################################################ if self.chunk_manager.packed_bits() > 0: (attr_name, attr_type, count) = self.chunk_manager.packed_attribute() cls.add_decl( cyast.CVar(attr_name + '[' + str(count) + ']', type=env.type2str(attr_type))) for chunk in self.chunk_manager.normal_chunks: attr_name = chunk.get_attribute_name() attr_type = chunk.get_cython_type() cls.add_decl( cyast.CVar(name=attr_name, type=env.type2str(attr_type))) # place = chunk_place_map[attr_name] cls.add_decl(cyast.Comment("{}".format(chunk.hint))) cls.add_method( cyast.FunctionDecl(name='copy', args=cyast.to_ast( cyast.A("self", cyast.Name(env.type2str( self.type)))), returns=cyast.Name(env.type2str(self.type)), lang=cyast.CDef())) return cyast.to_ast(cls)
def is_all_expression(self, marking_var, place_name, arg_function_name): try: function = self.all_functions[(place_name, arg_function_name)] except KeyError: # function does not exist place_id = self.place_id_provider.get(place_name) function_id = self.function_id_provider.get(arg_function_name) function_name = "isAll_p{}_f{}".format(place_id, function_id) function_ast = gen_All_function(self, function_name, place_name, arg_function_name) function = FunctionWrapper(function_name, function_ast) self.all_functions[(place_name, arg_function_name)] = function return function.call([cyast.Name(marking_var.name)])
def compile_TokenEnumeration(self, node): marking_type = self.env.marking_type place_type = marking_type.get_place_type_by_name(node.place_name) if hasattr(place_type, 'enumerate'): return place_type.enumerate(self.env, node.marking_var, node.token_var, self.compile(node.body)) arc = node.arc if place_type.provides_by_index_access: index_var = arc.data['index'] size_var = self.env.variable_provider.new_variable() self.env.try_declare_cvar(index_var.name, TypeInfo.get('Int')) self.env.try_declare_cvar(node.token_var.name, node.token_var.type) self.env.try_declare_cvar(size_var.name, TypeInfo.get('Int')) place_size = place_type.get_size_expr(env=self.env, marking_var=node.marking_var) get_token = place_type.get_token_expr(env=self.env, index_expr=index_var, marking_var=node.marking_var, compiled_index=cyast.Name( index_var.name)) return [ cyast.Assign(targets=[cyast.Name(size_var.name)], value=place_size), cyast.Builder.CFor( start=cyast.Num(0), start_op=cyast.LtE(), target=cyast.Name(index_var.name), stop_op=cyast.Lt(), stop=cyast.Name(size_var.name), body=[ cyast.Assign(targets=[cyast.Name(node.token_var.name)], value=get_token), self.compile(node.body) ], orelse=[]) ] else: self.env.try_declare_cvar(node.token_var.name, node.token_var.type) place_type = marking_type.get_place_type_by_name(node.place_name) return cyast.Builder.For(target=cyast.Name(node.token_var.name), iter=place_type.iterable_expr( env=self.env, marking_var=node.marking_var), body=[self.compile(node.body)])
def is_fireable_expression(self, marking_var, transition_name): try: function = self._is_fireable_functions[transition_name] except KeyError: # function does not exist transition = self.net_info.transition_by_name(transition_name) transition_id = self.transition_id_provider.get(transition) function_name = "isfireable_t{}".format(transition_id) generator = IsFireableGenerator(self, transition, function_name) function_ir = generator() visitor = CheckerCompileVisitor(self) function_ast = visitor.compile(function_ir) function = FunctionWrapper(function_name, function_ast) self._is_fireable_functions[transition_name] = function return function.call([cyast.Name(marking_var.name)])
def compile_Match(self, node): tuple_info = node.tuple_info seq = [] component_names = [ token_info.data['local_variable'].name for token_info in tuple_info ] seq.append( cyast.Assign(targets=[ cyast.Tuple([cyast.E(name) for name in component_names]) ], value=cyast.Name( tuple_info.data['local_variable'].name))) cur = None for component in tuple_info.components: if component.is_Value: # self.try_declare_cvar(component.data['local_variable'].name, component.type) n = cyast.Builder.If( test=cyast.Builder.Compare( left=cyast.E(component.data['local_variable'].name), ops=[cyast.Eq()], comparators=[cyast.E(repr(component.raw)) ]), # TO DO unify value & pickle orelse=[]) if cur == None: cur = n seq.append(n) else: cur.body = [n] cur = n elif component.is_Variable: self.env.try_declare_cvar( component.data['local_variable'].name, component.type) if cur != None: cur.body = [self.compile(node.body)] else: seq.append(self.compile(node.body)) return seq
def new_marking_expr(self, env): return cyast.Call(func=cyast.Name(env.type2str(self.type)), args=[cyast.Name('alloc')], keywords=[cyast.Name('True')])
def new_marking_set_expr(self, env): return cyast.Call(func=cyast.Name("set"))
def add_marking_stmt(self, env, markingset_var, marking_var): return cyast.Call(func=cyast.Attribute(value=cyast.Name( markingset_var.name), attr=self.add_attribute_name), args=[cyast.E(marking_var.name)])
def compile_Assign(self, node): self.env.try_declare_cvar(node.variable.name, node.variable.type) return cyast.Assign(targets=[cyast.Name(node.variable.name)], value=self.compile(node.expr))
def call(self, args): self._function_name return cyast.Call(func=cyast.Name(self._function_name), args=args)
def compile_MultiTokenEnumeration(self, node): place_type = self.env.marking_type.get_place_type_by_name( node.place_name) base = None current = None if place_type.provides_by_index_access: for sub_arc in node.multiarc.sub_arcs: variable = sub_arc.data['local_variable'] index_var = sub_arc.data['index'] self.env.try_declare_cvar(index_var.name, TypeInfo.get('Int')) self.env.try_declare_cvar(variable.name, place_type.token_type) assign = cyast.Assign(targets=[cyast.Name(variable.name)], value=place_type.get_token_expr( self.env, index_expr=index_var, marking_var=node.marking_var, compiled_index=cyast.Name( index_var.name))) enumeration = cyast.For(target=cyast.Name(index_var.name), iter=cyast.Call( func=cyast.Name('range'), args=[ cyast.Num(0), place_type.get_size_expr( self.env, node.marking_var) ]), body=[assign]) if base == None: current = enumeration base = enumeration else: current.body.append(enumeration) current = enumeration else: # no index access for sub_arc in node.multiarc.sub_arcs: variable = sub_arc.data['local_variable'] index_var = sub_arc.data['index'] init = cyast.Assign(targets=[cyast.Name(index_var.name)], value=cyast.Num(0)) self.env.try_declare_cvar(index_var.name, TypeInfo.get('Int')) self.env.try_declare_cvar(variable.name, place_type.token_type) enumeration = cyast.For(target=cyast.Name(variable.name), iter=place_type.iterable_expr( env=self.env, marking_var=node.marking_var), body=[ cyast.AugAssign(target=cyast.Name( index_var.name), op=cyast.Add(), value=cyast.Num(1)) ]) if base == None: current = [init, enumeration] base = [init, enumeration] else: current[1].body.append([init, enumeration]) current = [init, enumeration] indices = [sub_arc.data['index'] for sub_arc in node.multiarc.sub_arcs] inner_base, inner = self.gen_different(indices) if isinstance(current, list): current[1].body.append(inner_base) else: current.body.append(inner_base) current = inner current.body.extend([self.compile(node.body)]) return base
def compile_ProcedureCall(self, node): return cyast.stmt( cyast.Call(func=cyast.Name(node.function_name), args=[self.compile(arg) for arg in node.arguments]))