Esempio n. 1
0
    def from_ast(cls, filename: str, ast: AstNode, **extras):
        declarator = next(c for c in ast.children
                          if c.type == AstType.direct_declarator)
        fn_name = next(c for c in declarator
                       if c.type == AstType.IDENTIFIER).text
        assert fn_name is not None
        assert ast.type == AstType.function_definition
        ret_type = ast[0].text
        assert ret_type is not None
        env = Environment.empty()
        if ret_type != "void":
            env["ret"] = AtomicType(ret_type)
        params = declarator[2]
        if params.type == AstType.parameter_list:
            for p in params.children:
                if p.type == AstType.parameter_declaration:
                    ty = p[0].text
                    assert ty is not None and ty in (
                        "int",
                        "float",
                        "bool",
                    )
                    ty = AtomicType(ty)
                    name = None
                    if p[1].type == AstType.IDENTIFIER:
                        name = p[1].text
                    elif (p[1].type == AstType.direct_declarator
                          and p[1][0].type == AstType.IDENTIFIER
                          and p[1][1].text == "["):
                        name = p[1][0].text
                        ty = ArrayType(ty)
                    else:
                        assert False
                    assert name is not None
                    env[name] = ty
        params = env.get_vars()

        requires = None
        for s in ast[-1][1].children:
            if (s.type == AstType.expression_statement
                    and s[0].type == AstType.postfix_expression
                    and s[0][1].type == AstType.paren_left
                    and s[0][0].type == AstType.IDENTIFIER
                    and s[0][0].text == "requires"):
                requires = Expr.from_ast(s[0][2], env)

        cfg = create_cfg(ast, requires, env)
        vars = env.get_vars()
        for p in params:
            del vars[p]
        vars = [Variable(v, t) for v, t in vars.items()]
        params = [Variable(v, t) for v, t in params.items()]
        return cls(filename,
                   cfg=cfg,
                   name=fn_name,
                   vars=vars,
                   params=params,
                   **extras)
Esempio n. 2
0
 def setUp(self):
     data = {'person': {'age': array([20, 10, 35, 55]),
                        'dead': array([False, True, False, True])}}
     self.eval_ctx = EvaluationContext(entity_name='person',
                                       entities_data=data)
     self.parse_ctx = {
         'person': {'age': Variable('age'), 'dead': Variable('dead')},
         '__entity__': 'person'
     }
Esempio n. 3
0
    def store_result(self, result, context):
        if isinstance(result, np.ndarray):
            res_type = result.dtype.type
        else:
            res_type = type(result)

        if self.temporary:
            target = self.entity.temp_variables
        else:
            # we cannot store/cache self.entity.array[self.name] because the
            # array object can change (eg when enlarging it due to births)
            target = self.entity.array

            # TODO: assert type for temporary variables too
            target_type_idx = type_to_idx[target[self.name].dtype.type]
            res_type_idx = type_to_idx[res_type]
            if res_type_idx > target_type_idx:
                raise Exception(
                    "trying to store %s value into '%s' field which is of "
                    "type %s" % (idx_to_type[res_type_idx].__name__, self.name,
                                 idx_to_type[target_type_idx].__name__))

        # the whole column is updated
        target[self.name] = result

        # invalidate cache
        period = context.period
        if isinstance(period, np.ndarray):
            assert np.isscalar(period) or not period.shape
            period = int(period)
        expr_cache.invalidate(period, context.entity_name,
                              Variable(self.entity, self.name))
Esempio n. 4
0
def make_standard_game(player1_const, player2_const):
    pl1_token = make_random_token()
    pl2_token = make_random_token()

    pl1 = player1_const(pl1_token, 10, 0)
    pl2 = player2_const(pl2_token, 10, 0)

    Identity = lambda: Abstraction("x", Variable("x"))

    async def pure(x, *, game, player_idx):
        return x

    action_pure = MonadIOAction("pure", ['x'], pure)

    async def give_mana(*, game, player_idx):
        tok = game.players[player_idx].sec_token
        logging.info(f"Player {tok} gained 10 mana!")
        game.players[player_idx].mana += 10
        return Identity()

    action_give_mana = MonadIOAction("give_10_mana", [], give_mana)

    async def do_damage(x, *, game, player_idx):
        tok = game.players[player_idx].sec_token
        otok = game.players[~player_idx].sec_token
        logging.info(f"Player {tok} dealt {x.name} damage to {otok}!")
        if type(x.name) == int:
            game.players[~player_idx].health -= x.name
        else:
            logging.info(f"Invalid type!")
            # await self.players[player_idx].tell_msg(f"do_damage needs an int, you gave {type(x.name)}")

        return Identity()

    action_do_damage = MonadIOAction("do_damage", ['x'], do_damage)

    async def get_opponent_health(*, game, player_idx):
        tok = game.players[player_idx].sec_token
        logging.info(f"Player {tok} gets opponents health!")
        return Symbol(game.players[~player_idx].health)

    action_goh = MonadIOAction("get_opponent_health", [], get_opponent_health)

    layout = MonadIOLayout([action_pure, action_give_mana, action_do_damage, action_goh])

    game = Game(
        make_random_token(),
        [pl1, pl2],
        layout,
    )

    game.add_combinator(1, "pure", game.layout.constructor_for_idx(0))
    game.add_combinator(5, "+10 mana", game.layout.constructor_for_idx(1))
    game.add_combinator(10, "λx. do x damage", game.layout.constructor_for_idx(2))
    game.add_combinator(10, "get opponent's health", game.layout.constructor_for_idx(3))
    game.add_combinator(1, "bind", game.layout.constructor_for_idx(4))
    game.add_combinator(2, "the number 2", Symbol(2))
    game.add_combinator(7, "the number 7", Symbol(7))

    return game, pl1_token, pl2_token
Esempio n. 5
0
    def variables(self):
        if self._variables is None:
            if self.process_strings:
                processes = self.process_strings.items()
            else:
                processes = []

            # names of all processes (hybrid or not) of the entity
            process_names = set(k for k, v in processes if k is not None)

            # names of all entity variables (temporary or not) which are set
            # globally
            all_predictors = set(self.collect_predictors(processes))

            field_names = set(self.fields.names)

            # normal fields (non-callable/no hybrid variable-function for them)
            variables = dict((name, Variable(self, name, type_))
                             for name, type_ in self.fields.name_types
                             if name in field_names - process_names)

            # callable fields (fields with a process of the same name)
            variables.update((name, VariableMethodHybrid(self, name, type_))
                             for name, type_ in self.fields.name_types
                             if name in field_names & process_names)
            # global temporaries (they are all callable).
            variables.update((name, VariableMethodHybrid(self, name))
                             for name in all_predictors - field_names)
            variables.update(self.links)
            self._variables = variables
        return self._variables
Esempio n. 6
0
    def compute(self, context, a, size=None, replace=True, p=None):
        if isinstance(p,
                      (list, np.ndarray)) and len(p) and not np.isscalar(p[0]):
            assert len(p) == len(a)
            assert all(len(px) == size for px in p)
            assert len(a) >= 2

            # I have not found a way to do this without an explicit loop as
            # np.digitize only supports a 1d array for bins. What we do is
            # worse than a linear "search" since we always evaluate all
            # possibilities (there is no shortcut when the value is found).
            # It might be faster to rewrite this using numba + np.digitize
            # for each individual (assuming it has a low setup overhead).
            # if isinstance(p, list) and any(isinstance(px, la.LArray) for px in p):
            #     p = [np.asarray(px) for px in p]
            ap = np.asarray(p)
            cdf = ap.cumsum(axis=0)

            # copied & adapted from numpy/random/mtrand/mtrand.pyx
            atol = np.sqrt(np.finfo(np.float64).eps)
            if np.issubdtype(ap.dtype, np.floating):
                atol = max(atol, np.sqrt(np.finfo(ap.dtype).eps))

            if np.any(np.abs(cdf[-1] - 1.) > atol):
                raise ValueError("probabilities do not sum to 1")

            cdf /= cdf[-1]

            # the goal is to build something like:
            # if(u < proba1, outcome1,
            #    if(u < proba2, outcome2,
            #       outcome3))

            data = {'u': np.random.uniform(size=size)}
            expr = a[-1]
            # iterate in reverse and skip last
            pairs = zip(cdf[-2::-1], a[-2::-1])
            for i, (proba_x, outcome_x) in enumerate(pairs):
                data['p%d' % i] = proba_x
                expr = Where(
                    ComparisonOp('<', Variable(None, 'u'),
                                 Variable(None, 'p%d' % i)), outcome_x, expr)
            local_ctx = context.clone(fresh_data=True, entity_data=data)
            return expr.evaluate(local_ctx)
        else:
            return NumpyRandom.compute(self, context, a, size, replace, p)
Esempio n. 7
0
 def build_regression_expr(self, expr, mult=0.0, error_var=None):
     if error_var is not None:
         # expr += error_var
         expr = BinaryOp('+', expr, Variable(None, error_var))
     if mult:
         # expr += normal(0, 1) * mult
         expr = BinaryOp('+', expr, BinaryOp('*', Normal(0, 1), mult))
     return expr
Esempio n. 8
0
 def get_group_context(context, varnames):
     ent_name = context['__entity__']
     entity = context['__entities__'][ent_name]
     group_context = context.copy()
     entity_context = group_context[ent_name].copy()
     entity_context.update(
         (name, Variable(entity, name)) for name in varnames)
     group_context[ent_name] = entity_context
     return group_context
Esempio n. 9
0
    def constructor_for_idx(self, i):
        # λa0 ... an. c0 ... cm. ci a0 ... an

        action = self.actions[i]
        print("Constructor for", action.symb)

        result = Variable(action.symb.name)
        for arg in action.arg_names:
            result = Application(result, Variable(arg))

        for other_action in self.actions[::-1]:
            result = Abstraction(other_action.symb.name, result)

        for arg in action.arg_names[::-1]:
            result = Abstraction(arg, result)

        result = Opaque(action.symb.name, result)

        return result
Esempio n. 10
0
 def test_expr_str(self):
     n = NumberLit(11)
     m = NumberLit(22)
     self.assertEqual(str(n), "11")
     self.assertEqual(str(m), "22")
     x = Variable("x")
     self.assertEqual(str(x), "x")
     e1 = BinaryOp(n, Op.Plus, m)
     self.assertEqual(str(e1), "(11 + 22)")
     e2 = BinaryOp(n, Op.Mult, m)
     self.assertEqual(str(e2), "(11 * 22)")
     e3 = BinaryOp(e1, Op.Mult, e1)
     self.assertEqual(str(e3), "((11 + 22) * (11 + 22))")
     y = Variable("y")
     self.assertEqual(str(y), "y")
     e4 = BinaryOp(x, Op.Plus, y)
     self.assertEqual(str(e4), "(x + y)")
     e5 = LetIn("x", n, x)
     self.assertEqual(str(e5), "(let x := 11 in x)")
     e6 = LetIn("x", n, BinaryOp(x, Op.Plus, x))
     self.assertEqual(str(e6), "(let x := 11 in (x + x))")
Esempio n. 11
0
    def _eval_need(self,
                   context,
                   need,
                   expressions,
                   possible_values,
                   expressions_context=None):
        assert isinstance(need, np.ndarray)
        if expressions_context is None:
            expressions_context = context
        # When given a 0d array, we convert it to 1d. This can happen e.g. for
        # >>> b = True; x = ne.evaluate('where(b, 0.1, 0.2)')
        # >>> isinstance(x, np.ndarray)
        # True
        # >>> x.shape
        # ()
        if not need.shape:
            need = np.array([need])

        if isinstance(need, LabeledArray):
            if not expressions:
                expressions = [
                    Variable(expressions_context.entity, name)
                    for name in need.dim_names
                ]
            if not possible_values:
                possible_values = need.pvalues

        assert isinstance(need, np.ndarray)

        if len(expressions) != len(possible_values):
            raise Exception("align() expressions and possible_values "
                            "have different length: %d vs %d" %
                            (len(expressions), len(possible_values)))

        if 'period' in [str(e) for e in expressions]:
            period = context.period
            expressions, possible_values, need = \
                kill_axis('period', period, expressions, possible_values, need)

        # kill any axis where the value is constant for all individuals
        # satisfying the filter


#        tokill = [(expr, column[0])
#                  for expr, column in zip(expressions, columns)
#                  if isconstant(column, filter_value)]
#        for expr, value in tokill:
#            expressions, possible_values, need = \
#                kill_axis(str(expr), value, expressions, possible_values,
#                          need)

        return need, expressions, possible_values
Esempio n. 12
0
 def build_expr(self, context):
     res = None
     for name, coef in zip(self.names, self.coefs):
         # XXX: parse expressions instead of only simple Variable?
         if name != 'constant':
             # cond_dims = self.cond_dims
             # cond_exprs = [Variable(context.entity, d) for d in cond_dims]
             # coef = GlobalArray('__xyz')[name, *cond_exprs]
             term = _mul(Variable(context.entity, name), coef)
         else:
             term = coef
         if res is None:
             res = term
         else:
             res = _plus(res, term)
     return res
Esempio n. 13
0
 def primary(self):
     if self.match(TokenType.FALSE):
         return Literal(False)
     elif self.match(TokenType.TRUE):
         return Literal(True)
     elif self.match(TokenType.NIL):
         return Literal(None)
     elif self.match(TokenType.NUMBER, TokenType.STRING):
         return Literal(self.previous().literal)
     elif self.match(TokenType.IDENTIFIER):
         return Variable(self.previous())
     elif self.match(TokenType.LEFT_PAREN):
         expr = self.expression()
         self.consume(TokenType.RIGHT_PAREN, "Expected ')' after expression.")
         return Grouping(expr)
     
     raise self.error(self.peek(), "Expected a primary literal or a grouping.")
Esempio n. 14
0
    def execute(self, s):
        entity = self.entity
        if entity is None:
            raise Exception(entity_required)

        period = self.period
        if period is None:
            raise Exception(period_required)

        entity_name = self.entity.name
        parse_ctx = self.parse_ctx.copy()
        local_parse_ctx = parse_ctx[entity_name].copy()

        # add all currently defined temp_variables because otherwise
        # local variables (defined within a function) wouldn't be available
        local_parse_ctx.update((name, Variable(entity, name))
                               for name in entity.temp_variables.keys())
        parse_ctx[entity_name] = local_parse_ctx
        expr = parse(s, parse_ctx, interactive=True)
        result = expr_eval(expr, self.eval_ctx)
        if result is None:
            print("done.")
        return result
Esempio n. 15
0
    def primary(self):
        if self.match(TT.LEFT_PAREN):
            expr = self.expression()
            self.consume(TT.RIGHT_PAREN, "Expect ')' after expression.")
            return Grouping(expr)

        if self.match(TT.FALSE):
            return Literal(False)
        if self.match(TT.TRUE):
            return Literal(True)
        if self.match(TT.NONE):
            return Literal(None)

        if self.match(TT.INT, TT.FLOAT, TT.STRING):
            return Literal(self.previous().literal)

        if self.match(TT.IDENTIFIER):
            return Variable(self.previous())

        if self.match(TT.LAMBDA):
            return self.lambda_declaration()

        raise self.error(self.peek(), "Expected expression.")
Esempio n. 16
0
    def create_cfg(self, ast: AstNode) -> CfgNode:
        if ast.type == AstType.labeled_statement:
            if ast[0].type == AstType.DEFAULT:
                statement = self.create_cfg(ast[2])
                self.labels.append((None, statement))
                return statement
            else:
                assert ast[0].type == AstType.CASE
                value = Expr.from_ast(ast[1], self.env)
                statement = self.create_cfg(ast[3])
                self.labels.append((value, statement))
                return statement
        elif ast.type == AstType.semicolon:
            return self.next_node
        elif ast.type == AstType.selection_statement:
            if ast[0].type == AstType.IF:
                return CondNode(
                    code_location=ast[2].range,
                    condition=Expr.from_ast(ast[2], self.env),
                    true_br=self.create_cfg(ast[4]),
                    false_br=self.create_cfg(ast[6])
                    if len(ast.children) == 7 else self.next_node,
                )
            elif ast[0].type == AstType.SWITCH:
                switch_value = Expr.from_ast(ast[2], self.env)
                statement_env = self.enter_switch(self.next_node)
                statement = statement_env.create_cfg(ast[4])
                conds: list[CondNode] = []
                default = self.next_node
                for case_value, statement in statement_env.labels:
                    if case_value is None:
                        default = statement
                        continue
                    dummy = DummyNode(None)
                    conds.append(
                        CondNode(
                            None,
                            RelExpr("==", switch_value, case_value),
                            statement,
                            dummy,
                        ))
                for cond, next_ in zip(
                        conds,
                        cast("list[CfgNode]", conds[1:]) + [default]):
                    cond.false_br = next_
                return conds[0] if conds else default
            else:
                assert False
        elif ast.type == AstType.compound_statement:
            self.open_scope()
            statements: list[CfgNode] = []
            dummies: list[DummyNode] = []
            for s in ast[1].children:
                dummy = DummyNode(None)
                statement = self.with_next(dummy).create_cfg(s)
                if statement is not dummy:
                    dummies.append(dummy)
                    statements.append(statement)
            statements.append(self.next_node)
            for s, s_next, d in zip(statements, statements[1:], dummies):
                s.replace(d, s_next, set())
            self.close_scope()
            return statements[0]
        elif ast.type == AstType.jump_statement:
            # TODO? handle goto
            if ast[0].type == AstType.BREAK:
                assert self.loop_end is not None
                return self.loop_end
            elif ast[0].type == AstType.CONTINUE:
                assert self.loop_start is not None
                return self.loop_start
            elif ast[0].type == AstType.RETURN:
                if len(ast.children) == 3:
                    return AssignmentNode(
                        ast.range,
                        expression=Expr.from_ast(ast[1], self.env),
                        var=Variable("ret", self.env["ret"]),
                        next_node=self.end_node,
                    )
                else:
                    return self.end_node
            else:
                assert False
        elif ast.type == AstType.declaration:
            # TODO: what about "int x, y;"
            type_ = ast[0].text
            assert type_ is not None

            if (ast[1].type == AstType.direct_declarator
                    and ast[1][1].type == AstType.bracket_left):
                var = ast[1][0].text
                assert var is not None
                self.env[var] = ArrayType(AtomicType(type_))
                return self.next_node

            type_ = AtomicType(type_)
            if ast[1].type == AstType.IDENTIFIER:
                var = ast[1].text
                assert var is not None
                self.env[var] = type_
                return self.next_node

            var = ast[1][0].text
            assert var is not None
            value = Expr.from_ast(ast[1][2], self.env)
            self.env[var] = type_
            return AssignmentNode(
                ast.range,
                expression=value,
                var=Variable(self.env.rename(var), type_),
                next_node=self.next_node,
            )
        elif ast.type == AstType.expression_statement:
            if (ast[0].type == AstType.postfix_expression
                    and ast[0][1].type == AstType.paren_left
                    and ast[0][0].type == AstType.IDENTIFIER):
                fn = ast[0][0].text
                if fn == "assert":
                    assertion = Expr.from_ast(ast[0][2], self.env)
                    remembers = tuple(chain.from_iterable(self.remembers))
                    assertion = (And(remembers + (assertion, ))
                                 if remembers else assertion)
                    return AssertNode(
                        ast.range,
                        assertion=assertion,
                        next_node=self.next_node,
                    )
                elif fn == "ensures":
                    assert self.end_node.assertion is None
                    self.end_node.assertion = Expr.from_ast(
                        ast[0][2], self.env)
                    self.end_node.code_location = ast.range
                    return self.next_node
                elif fn == "requires":
                    assert self.start_node.requires is None
                    self.start_node.requires = Expr.from_ast(
                        ast[0][2], self.env)
                    self.start_node.code_location = ast.range
                    return self.next_node
                elif fn == "freeze":
                    args = ast[0][2]
                    right = Expr.from_ast(args[2], self.env)
                    assert args[0].type == AstType.IDENTIFIER
                    assert args[0].text is not None
                    self.env[args[0].text] = right.get_type()
                    var = Expr.from_ast(args[0], self.env)
                    assert isinstance(var, Variable)
                    return AssignmentNode(ast.range, right, var,
                                          self.next_node)
                elif fn == "remember":
                    self.remembers[-1].append(
                        Expr.from_ast(ast[0][2], self.env))
                    return self.next_node
                elif fn == "assume":
                    return AssumeNode(ast.range,
                                      Expr.from_ast(ast[0][2], self.env),
                                      self.next_node)
                else:
                    assert False, f"unknown function {fn}"

            if ast[0].type == AstType.postfix_expression and ast[0][1].type in (
                    AstType.INC_OP,
                    AstType.DEC_OP,
            ):
                left = Expr.from_ast(ast[0][0], self.env)
                operator = "+=" if ast[0][1].type == AstType.INC_OP else "-="
                value = IntValue(1)
            elif ast[0].type == AstType.unary_expression and ast[0][0].type in (
                    AstType.INC_OP,
                    AstType.DEC_OP,
            ):
                left = Expr.from_ast(ast[0][1], self.env)
                operator = "+=" if ast[0][0].type == AstType.INC_OP else "-="
                value = IntValue(1)
            elif ast[0].type != AstType.assignment_expression:
                # FIXME
                return self.next_node
            else:
                value = Expr.from_ast(ast[0][2], self.env)
                operator = ast[0][1].text
                assert operator is not None
                left = Expr.from_ast(ast[0][0], self.env)

            # TODO? handle chained assignments?

            # handle other assignment operators: *= /= %= += -= >>= <<= &= |= ^=
            if operator != "=":
                operator = operator[:-1]
                value = BinaryExpr(operator=operator, lhs=left, rhs=value)

            if isinstance(left, Variable):
                return AssignmentNode(ast.range,
                                      expression=value,
                                      var=left,
                                      next_node=self.next_node)
            elif isinstance(left, ArraySelect):
                # TODO? what about 2d+ arrays?
                assert isinstance(left.array, Variable)
                return AssignmentNode(
                    ast.range,
                    var=left.array,
                    expression=ArrayStore(
                        array=left.array,
                        index=left.index,
                        value=value,
                    ),
                    next_node=self.next_node,
                )
            else:
                assert False
        elif ast.type == AstType.iteration_statement:
            if ast[0].type == AstType.WHILE:
                self.open_scope()
                while_node = CondNode(
                    ast[2].range,
                    Expr.from_ast(ast[2], self.env),
                    DummyNode(None),
                    self.next_node,
                )
                while_node.true_br = (self.enter_loop(
                    start=while_node,
                    end=self.next_node).with_next(while_node).create_cfg(
                        ast[4]))
                self.close_scope()
                return while_node
            elif ast[0].type == AstType.DO:
                self.open_scope()
                cond = CondNode(
                    ast[4].range,
                    Expr.from_ast(ast[4], self.env),
                    DummyNode(None),
                    self.next_node,
                )
                cond.true_br = (self.enter_loop(
                    start=cond,
                    end=self.next_node).with_next(cond).create_cfg(ast[1]))
                self.close_scope()
                return cond.true_br
            elif ast[0].type == AstType.FOR:
                self.open_scope()
                if ast[2].type == AstType.declaration:
                    decl = self.with_next(DummyNode(None)).create_cfg(ast[2])
                    assert isinstance(decl, AssignmentNode)
                else:
                    assert ast[2].type == AstType.semicolon
                    decl = None
                if ast[3].type == AstType.expression_statement:
                    cond = CondNode(
                        ast[3].range,
                        Expr.from_ast(ast[3][0], self.env),
                        DummyNode(None),
                        self.next_node,
                    )
                else:
                    assert ast[3].type == AstType.semicolon
                    cond = CondNode(
                        ast[3].range,
                        BoolValue(True),
                        DummyNode(None),
                        self.next_node,
                    )
                if decl is not None:
                    decl.next_node = cond
                if ast[4].type == AstType.paren_right:
                    inc = None
                else:
                    inc = self.with_next(cond).create_cfg(
                        AstNode(None, AstType.expression_statement,
                                ast[4].range, [ast[4]]))
                cond.true_br = (self.enter_loop(
                    start=cond, end=self.next_node).with_next(
                        inc
                        or cond).create_cfg(ast[5] if inc is None else ast[6]))
                self.close_scope()
                return decl or cond
            else:
                assert False
        else:
            assert False
Esempio n. 17
0
    def test_parser(self):
        v1 = "x"
        self.assertEqual(parse(v1), Variable("x"))

        v2 = "(x)"
        self.assertEqual(parse(v2), Variable("x"))

        v3 = "thisisalongvariable"
        self.assertEqual(parse(v3), Variable(v3))

        e1 = "1"
        self.assertEqual(parse(e1), NumberLit(1))

        e2 = "(1)"
        self.assertEqual(parse(e2), NumberLit(1))

        e3 = "((1))"
        self.assertEqual(parse(e3), NumberLit(1))

        e4 = "(1 + 2)"
        r4 = BinaryOp(
                NumberLit(1),
                Op.Plus,
                NumberLit(2))
        self.assertEqual(parse(e4), r4)

        e5 = "1 + 2"
        self.assertEqual(parse(e5), r4)

        e6 = "(1 * 2)"
        r6 = BinaryOp(
                NumberLit(1),
                Op.Mult,
                NumberLit(2))
        self.assertEqual(parse(e6), r6)

        e7 = "1 * 2"
        self.assertEqual(parse(e7), r6)

        e8 = "1 + 2 * 3"
        r8 = BinaryOp(
                NumberLit(1),
                Op.Plus,
                BinaryOp(
                    NumberLit(2),
                    Op.Mult,
                    NumberLit(3)
                ))
        self.assertEqual(parse(e8), r8)

        e9 = "let x := 1 in x end"
        r9 = LetIn(
                "x",
                NumberLit(1),
                Variable("x")
                )
        self.assertEqual(parse(e9), r9)

        e10 = "2 + let x := 1 in x end"
        r10 = BinaryOp(
                NumberLit(2),
                Op.Plus,
                LetIn(
                    "x",
                    NumberLit(1),
                    Variable("x")
                ))
        self.assertEqual(parse(e10), r10)

        e11 = "let x := 1 in x + 2 end"
        r11 = LetIn(
                "x",
                NumberLit(1),
                BinaryOp(
                    Variable("x"),
                    Op.Plus,
                    NumberLit(2)
                ))
        self.assertEqual(parse(e11), r11)

        e12 = "let x := 1 in x end + 2"
        r12 = BinaryOp(
                    LetIn(
                        "x",
                        NumberLit(1),
                        Variable("x")),
                    Op.Plus,
                    NumberLit(2)
                )
        self.assertEqual(parse(e12), r12)
Esempio n. 18
0
    async def run(self, game, player_idx):
        player = game.players[player_idx]

        player.deck.append(Variable(self.var_name))
Esempio n. 19
0
    def compute(self, context, *args, **kwargs):
        filter_value = kwargs.pop('filter', None)
        missing = kwargs.pop('missing', None)
        # periods = kwargs.pop('periods', None)
        header = kwargs.pop('header', True)
        limit = kwargs.pop('limit', None)
        entity = context.entity

        if args:
            expressions = list(args)
        else:
            # extra=False because we don't want globals nor "system" variables
            # (nan, period, __xxx__)
            # FIXME: we should also somehow "traverse" expressions in this case
            # too (args is ()) => all keys in the current context
            expressions = [
                Variable(entity, name) for name in context.keys(extra=False)
            ]

        str_expressions = [str(e) for e in expressions]
        if 'id' not in str_expressions:
            str_expressions.insert(0, 'id')
            expressions.insert(0, Variable(entity, 'id'))
            id_pos = 0
        else:
            id_pos = str_expressions.index('id')

        #        if (self.periods is not None and len(self.periods) and
        #            'period' not in str_expressions):
        #            str_expressions.insert(0, 'period')
        #            expressions.insert(0, Variable('period'))
        #            id_pos += 1

        columns = []
        for expr in expressions:
            if filter_value is False:
                # dtype does not matter much
                expr_value = np.empty(0)
            else:
                expr_value = expr_eval(expr, context)
                if (filter_value is not None
                        and isinstance(expr_value, np.ndarray)
                        and expr_value.shape):
                    expr_value = expr_value[filter_value]
            columns.append(expr_value)

        ids = columns[id_pos]
        if isinstance(ids, np.ndarray) and ids.shape:
            numrows = len(ids)
        else:
            # FIXME: we need a test for this case (no idea how this can happen)
            numrows = 1

        # expand scalar columns to full columns in memory
        # TODO: handle or explicitly reject columns wh ndim > 1
        for idx, col in enumerate(columns):
            dtype = None
            if not isinstance(col, np.ndarray):
                dtype = type(col)
            elif not col.shape:
                dtype = col.dtype.type
            if dtype is not None:
                # TODO: try using itertools.repeat instead as it seems to be a
                # bit faster and would consume less memory (however, it might
                # not play very well with Pandas.to_csv)
                newcol = np.full(numrows, col, dtype=dtype)
                columns[idx] = newcol

        if limit is not None:
            assert isinstance(limit, (int, long))
            columns = [col[:limit] for col in columns]

        data = izip(*columns)
        table = chain([str_expressions], data) if header else data
        return PrettyTable(table, missing)
Esempio n. 20
0
    c_pure, c_print, c_read, c_xyz, c_bind = [
        CONSOLE_IO.constructor_for_idx(i) for i in range(5)
    ]

    print(c_xyz)

    program = C(
        c_bind, c_read,
        λ(
            "a",
            C(
                c_bind, c_read,
                λ(
                    "b",
                    C(
                        c_bind, c_read,
                        λ(
                            "c",
                            C(
                                c_xyz,
                                Variable("a"),
                                Variable("b"),
                                Variable("c"),
                            )))))))

    print(program)
    print(CONSOLE_EIO(program))

    print(CONSOLE_IO.constructor_for_idx(3))
Esempio n. 21
0
 def mprint(x):
     print("Monadic print:", x)
     return Abstraction("x", Variable("x"))
Esempio n. 22
0
 def mxyz(x, y, z):
     print(f"x = {x}, y = {y}, z = {z}")
     return Abstraction("x", Variable("x"))