예제 #1
0
    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
예제 #2
0
파일: envs.py 프로젝트: briot/langkit
    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"
                )
예제 #3
0
    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]
예제 #4
0
파일: logic.py 프로젝트: AdaCore/langkit
    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"
        )
예제 #5
0
파일: envs.py 프로젝트: briot/langkit
    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)
예제 #6
0
파일: envs.py 프로젝트: nyulacska/langkit
    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)
예제 #7
0
 def tracesplit(self, c, r, o, limit, match):
     return split_by(lambda e: e not in match, self.trace(c, r, o, limit))
예제 #8
0
    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"
        )
예제 #9
0
    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)