def _parse_actions(self, actions): """ Analyze the given list of actions and extract pre/post actions, i.e. actions executed before and after handling children. :rtype: (list[EnvAction], list[EnvAction]) """ actions = list(actions) # If present, allow Do actions to come before SetInitialEnv self.pre_initial_env_actions = [] if any(isinstance(a, SetInitialEnv) for a in actions): while actions and isinstance(actions[0], Do): self.pre_initial_env_actions.append(actions.pop(0)) # After that, allow one call to SetInitialEnv self.initial_env = None if actions and isinstance(actions[0], SetInitialEnv): self.initial_env = actions.pop(0) pre, post = split_by(lambda a: not isinstance(a, HandleChildren), actions) # Get rid of the HandleChildren delimiter action post = post and post[1:] self.pre_actions = pre self.post_actions = post self.actions = self.pre_actions + self.post_actions
def check_spec(self, context): """ ASTNode pass which checks that properties generated by the env spec are conforming. This relies on type information and property attributes (privacy, implicit envs), so it must run only after these can be computed. :param langkit.compile_context.CompileCtx context: Current context. """ has_add_env = False with self.diagnostic_context: for action in self.actions: action.check() if isinstance(action, AddEnv): check_source_language(not has_add_env, 'There can be only one add_env' ' action per EnvSpec') has_add_env = True pre_addenv, post_addenv = split_by( lambda a: not isinstance(a, AddEnv), self.pre_actions ) if post_addenv: check_source_language( all(a.dest_env for a in post_addenv if isinstance(a, AddToEnv)), "add_to_env actions happening after add_env must have an" " explicit destination env" )
def __init__(self, lines, text): super(Failure, self).__init__(lines, text) self.exception = None if "exception" in self.text: self.exception = [l for l in lines if l.startswith('>')][0] self.traceback = split_by(lambda l: l != "Traceback:", lines)[1]
def construct(self): exprs = [construct(e) for e in self.exprs] prop_types = [self.pred_property.struct] + [ a.type for a in self.pred_property.explicit_arguments ] # Separate logic variable expressions from extra argument expressions logic_var_exprs, closure_exprs = funcy.split_by( lambda e: e.type == LogicVarType, exprs ) check_source_language( len(logic_var_exprs) > 0, "Predicate instantiation should have at " "least one logic variable expression" ) check_source_language( all(e.type != LogicVarType for e in closure_exprs), "Logic " "variable expressions should be grouped at the beginning, and " "should not appear after non logic variable expressions" ) for i, (expr, arg_type) in enumerate(zip(exprs, prop_types)): if expr.type == LogicVarType: check_source_language( arg_type.matches(T.root_node), "Argument #{} of predicate " "is a logic variable, the corresponding property formal " "has type {}, but should be a descendent of {}".format( i, arg_type.name().camel, T.root_node.name().camel ) ) else: check_source_language( expr.type.matches(arg_type), "Argument #{} of predicate " "has type {}, should be {}".format( i, expr.type.name().camel, arg_type.name().camel ) ) pred_id = self.pred_property.do_generate_logic_predicate(*[ e.type for e in closure_exprs ]) closure_exprs.append(construct(Env)) logic_var_exprs.append( BasicExpr("{}_Predicate_Caller'({})".format( pred_id, ", ".join( ["{}" for _ in range(len(closure_exprs) - 1)] + ["Env => {}"] ) ), type=None, sub_exprs=closure_exprs) ) return BuiltinCallExpr( "{}_Pred.Create".format(pred_id), EquationType, logic_var_exprs, result_var_name="Pred" )
def __init__(self, *actions): """ :param list[EnvAction] actions: A list of environment actions to execute. """ self.location = extract_library_location() self.ast_node = None """ ASTNodeType subclass associated to this environment specification. Initialized when creating ASTNodeType subclasses. :type: langkit.compiled_types.ASTNodeType """ actions = list(actions) self.env_hook = None if isinstance(actions and actions[0], CallEnvHook): self.env_hook = actions.pop(0) ":type: SetInitialEnv" self.initial_env = None if isinstance(actions and actions[0], SetInitialEnv): self.initial_env = actions.pop(0) ":type: SetInitialEnv" pre, post = split_by( lambda a: not isinstance(a, HandleChildren), actions ) # Get rid of the HandleChildren delimiter action post = post and post[1:] self.pre_actions = pre self.post_actions = post self.actions = self.pre_actions + self.post_actions # These are the property attributes self.initial_env_prop = None ":type: PropertyDef" self.env_hook_arg = None ":type: PropertyDef" self.adds_env = any(isinstance(a, AddEnv) for a in self.pre_actions)
def __init__(self, *actions): """ :param list[EnvAction] actions: A list of environment actions to execute. """ self.location = extract_library_location() self.ast_node = None """ ASTNodeType subclass associated to this environment specification. Initialized when creating ASTNodeType subclasses. :type: langkit.compiled_types.ASTNodeType """ actions = list(actions) # If present, allow Do actions to come before SetInitialEnv self.pre_initial_env_actions = [] if any(isinstance(a, SetInitialEnv) for a in actions): while actions and isinstance(actions[0], Do): self.pre_initial_env_actions.append(actions.pop(0)) # After that, allow one call to SetInitialEnv self.initial_env = None if actions and isinstance(actions[0], SetInitialEnv): self.initial_env = actions.pop(0) pre, post = split_by( lambda a: not isinstance(a, HandleChildren), actions ) # Get rid of the HandleChildren delimiter action post = post and post[1:] self.pre_actions = pre self.post_actions = post self.actions = self.pre_actions + self.post_actions # These are the property attributes self.initial_env_prop = None ":type: PropertyDef" self.adds_env = any(isinstance(a, AddEnv) for a in self.pre_actions)
def tracesplit(self, c, r, o, limit, match): return split_by(lambda e: e not in match, self.trace(c, r, o, limit))
def construct(self): check_multiple([ (isinstance(self.pred_property, PropertyDef), "Needs a property reference, got {}".format(self.pred_property)), (self.pred_property.type.matches(BoolType), "The property passed to predicate must return a boolean, " "got {}".format(self.pred_property.type.name().camel)), (self.pred_property.struct.matches(T.root_node), "The property passed to bind must belong to a subtype " "of {}".format(T.root_node.name().camel)) ]) exprs = [construct(e) for e in self.exprs] prop_types = [self.pred_property.struct] + [ a.type for a in self.pred_property.explicit_arguments ] # Separate logic variable expressions from extra argument expressions logic_var_exprs, closure_exprs = funcy.split_by( lambda e: e.type == LogicVarType, exprs ) check_source_language( len(logic_var_exprs) > 0, "Predicate instantiation should have at " "least one logic variable expression" ) check_source_language( all(e.type != LogicVarType for e in closure_exprs), "Logic " "variable expressions should be grouped at the beginning, and " "should not appear after non logic variable expressions" ) for i, (expr, arg_type) in enumerate(zip(exprs, prop_types)): if expr.type == LogicVarType: check_source_language( arg_type.matches(T.root_node), "Argument #{} of predicate " "is a logic variable, the corresponding property formal " "has type {}, but should be a descendent of {}".format( i, arg_type.name().camel, T.root_node.name().camel ) ) else: check_source_language( expr.type.matches(arg_type), "Argument #{} of predicate " "has type {}, should be {}".format( i, expr.type.name().camel, arg_type.name().camel ) ) pred_id = self.pred_property.do_generate_logic_predicate(*[ e.type for e in closure_exprs ]) closure_exprs.append(construct(Env)) # Append the debug image for the predicate closure_exprs.append(LiteralExpr('"{}.{}"'.format( self.pred_property.name.camel_with_underscores, self.pred_property.struct.name().camel_with_underscores ), type=None)) logic_var_exprs.append( BasicExpr("{}_Predicate_Caller'({})".format( pred_id, ", ".join( ["{}" for _ in range(len(closure_exprs) - 2)] + ["Env => {}, " "Dbg_Img => (if Debug then new String'({})" " else null)"] ) ), type=None, operands=closure_exprs) ) return BuiltinCallExpr( "{}_Pred.Create".format(pred_id), EquationType, logic_var_exprs, result_var_name="Pred" )
def construct(self): check_multiple([ (self.pred_property.type.matches(T.BoolType), 'Predicate property must return a boolean, got {}'.format( self.pred_property.type.dsl_name)), (self.pred_property.struct.matches(T.root_node), 'Predicate property must belong to a subtype of {}'.format( T.root_node.dsl_name)), ]) # Separate logic variable expressions from extra argument expressions exprs = [construct(e) for e in self.exprs] logic_var_exprs, closure_exprs = funcy.split_by( lambda e: e.type == T.LogicVarType, exprs) check_source_language( len(logic_var_exprs) > 0, "Predicate instantiation should have at " "least one logic variable expression") check_source_language( all(e.type != T.LogicVarType for e in closure_exprs), 'Logic variable expressions should be grouped at the beginning,' ' and should not appear after non logic variable expressions') # Make sure this predicate will work on clean logic variables logic_var_exprs = [ResetLogicVar(expr) for expr in logic_var_exprs] # Compute the list of arguments to pass to the property (Self # included). args = ( [Argument(names.Name('Self'), self.pred_property.struct.entity)] + self.pred_property.natural_arguments) # Then check that 1) all extra passed actuals match what the property # arguments expect and that 2) arguments left without an actual have a # default value. default_passed_args = 0 for i, (expr, arg) in enumerate(izip_longest(exprs, args)): if expr is None: check_source_language( arg.default_value is not None, 'Missing an actual for argument #{} ({})'.format( i, arg.name.lower)) default_passed_args += 1 continue check_source_language( arg is not None, 'Too many actuals: at most {} expected, got {}'.format( len(args), len(exprs))) if expr.type == T.LogicVarType: check_source_language( arg.type.matches(T.root_node.entity), "Argument #{} of predicate " "is a logic variable, the corresponding property formal " "has type {}, but should be a descendent of {}".format( i, arg.type.dsl_name, T.root_node.entity.dsl_name)) else: check_source_language( expr.type.matches(arg.type), "Argument #{} of predicate " "has type {}, should be {}".format(i, expr.type.dsl_name, arg.type.dsl_name)) DynamicVariable.check_call_bindings(self.pred_property, 'In predicate property {prop}') # Append dynamic variables to embed their values in the closure closure_exprs.extend( construct(dynvar) for dynvar in self.pred_property.dynamic_vars) pred_id = self.pred_property.do_generate_logic_predicate( tuple(e.type for e in closure_exprs), default_passed_args) # Append the debug image for the predicate closure_exprs.append( untyped_literal_expr('"{}.{}"'.format( self.pred_property.struct.name.camel_with_underscores, self.pred_property.name.camel_with_underscores))) logic_var_exprs.append( untyped_literal_expr("Create ({})".format( ", ".join(["{}" for _ in range(len(closure_exprs) - 1)] + [ "Dbg_Img => (if Debug then new String'({})" " else null)" ])), operands=closure_exprs)) return Predicate.Expr(self.pred_property, pred_id, logic_var_exprs, abstract_expr=self)