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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
from hypothesis.strategies import integers, decimals as hypo_decimals, booleans, characters, text, tuples, lists as hypo_lists, just, one_of
from hypothesis.strategies import deferred, recursive
from actinide.symbol_table import *
from actinide.types import *
# Generators for forms. Where these generators create a symbol, they will use
# the global symbol table defined in this module. Do not do this in your own
# code! A global symbol table is a memory leak, and only the fact that tests
# exit before they can do any substantial damage prevents this from being a
# bigger problem.
#
# Each generator produces the parsed version of a form.
symbol_table = SymbolTable()
# Generates nil.
def nils():
return just(None)
# Generates integers.
def ints():
return integers()
# Generates language decimals.
def decimals():
return hypo_decimals(allow_nan=False, allow_infinity=False)
# Generates booleans.
def bools():
return booleans()
# Generates strings.
def strings():
return text()
# Generates any character legal in a symbol, which cannot be part of some other
# kind of atom.
def symbol_characters():
return characters(blacklist_characters='01234567890#. \t\n();"')
# Generates symbols guaranteed not to conflict with other kinds of literal. This
# is a subset of the legal symbols.
def symbols():
return text(symbol_characters(), min_size=1)\
.map(lambda item: symbol_table[item])
# Generates atoms.
def atoms():
return one_of(
nils(),
ints(),
decimals(),
bools(),
strings(),
symbols(),
)
# Generates arbitrary conses, with varying depth. This may happen to generate
# lists by accident.
def conses():
return recursive(
tuples(atoms(), atoms()).map(lambda elems: cons(*elems)),
lambda children: tuples(children | atoms(), children | atoms()).map(lambda elems: cons(*elems)),
)
# Generates lists, with varying depth.
def lists():
return recursive(
hypo_lists(atoms()).map(lambda elems: list(*elems)),
lambda children: hypo_lists(children | atoms()).map(lambda elems: list(*elems)),
)
# Generates random forms.
def forms():
return one_of(nils(), ints(), bools(), strings(), symbols(), conses(), lists())
|