-
Notifications
You must be signed in to change notification settings - Fork 5
/
patterns_helper.rb
132 lines (112 loc) · 2.29 KB
/
patterns_helper.rb
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def match(pat, val)
Atomy::Compiler.eval(
Atomy::AST::Set.new(
0,
Atomy::AST::Pattern.new(
0,
pat),
Atomy::AST::Literal.new(0, val)),
Binding.setup(
Rubinius::VariableScope.of_sender,
Rubinius::CompiledMethod.of_sender,
Rubinius::StaticScope.of_sender))
end
def expr(str)
Atomy::Parser.parse_node(str)
end
def pat(str)
expr(str).to_pattern
end
PATTERN_TYPES = []
Atomy::Patterns.constants.each do |c|
val = Atomy::Patterns.const_get(c)
PATTERN_TYPES << val if val.is_a?(Atomy::Patterns::SentientPattern)
end
def random_symbol
sprintf("s_%04x", rand(16 ** 4)).to_sym
end
module Atomy::Patterns
class Pattern
def self.arbitrary
args = []
children[:required].each do
args << random_pattern
end
children[:many].each do
val = []
rand(5).times do
val << random_pattern
end
args << val
end
attributes[:required].each do
args << random_symbol
end
attributes[:many].each do
val = []
rand(5).times do
val << random_symbol
end
args << val
end
children[:optional].each do
if rand(2) == 0
args << nil
else
args << random_pattern
end
end
attributes[:optional].each do
if rand(2) == 0
args << nil
else
args << random_symbol
end
end
new(*args)
end
end
class Any
def self.arbitrary
new
end
end
class Attribute
def self.arbitrary
new(random_symbol.to_node,
random_symbol.to_node,
rand(5).times.collect { random_symbol.to_node })
end
end
class Match
def self.arbitrary
new([:nil, :false, :true, :self, rand(100)].sample)
end
end
class QuasiQuote
def self.arbitrary
new(Atomy::AST::QuasiQuote.new(0, random_symbol.to_node))
end
end
class Quote
def self.arbitrary
new(random_symbol.to_node)
end
end
end
def random_pattern
PATTERN_TYPES.sample.arbitrary
end
def for_every_pattern
10.times do
PATTERN_TYPES.each do |cls|
x = cls.arbitrary
begin
yield x
rescue Exception
puts "failed with #{x.inspect}"
raise
end
end
end
end