summaryrefslogtreecommitdiff
path: root/tests/programs.py
blob: 78c52c74f2fc70e5c040afc2b0489a85a4a11402 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from hypothesis.strategies import integers, decimals, booleans, text, tuples
from hypothesis.strategies import one_of, composite, deferred

from actinide.types import *
from actinide.environment import *
from actinide.symbol_table import *

symbol_table = SymbolTable()

def literals():
    return one_of(
        booleans(),
        integers(),
        decimals(allow_nan=False, allow_infinity=False),
        text(),
    ).map(lambda value: (value, (value,), []))

def symbols():
    return text().map(lambda symb: symbol_table[symb])

def values():
    return literals()

@composite
def ifs(draw, conds, trues, falses):
    cond, (cond_result,), cond_bindings = draw(conds)
    true, true_result, true_bindings = draw(trues)
    false, false_result, false_bindings = draw(falses)

    expr = list(symbol_table['if'], cond, true, false)
    result = true_result if cond_result else false_result
    bindings = cond_bindings + (true_bindings if cond_result else false_bindings)

    return expr, result, bindings

def if_exprs():
    return ifs(exprs(), exprs(), exprs())

def if_progs():
    return ifs(exprs(), programs(), programs())

@composite
def defines(draw):
    symbol = draw(symbols())
    value, (value_result,), value_bindings = draw(values())
    return (
        list(symbol_table['define'], symbol, value),
        (),
        value_bindings + [(symbol, value_result)],
    )

def exprs():
    return deferred(lambda: one_of(literals(), if_exprs()))

def programs():
    return deferred(lambda: one_of(literals(), defines(), if_progs()))