atomy 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +30 -0
- data/README.md +1 -0
- data/bin/atomy +134 -0
- data/kernel/block.ay +30 -0
- data/kernel/boot.ay +10 -0
- data/kernel/comparison.ay +61 -0
- data/kernel/concurrency.ay +84 -0
- data/kernel/condition.ay +277 -0
- data/kernel/control-flow.ay +222 -0
- data/kernel/cosmetics.ay +3 -0
- data/kernel/data-delta.ay +105 -0
- data/kernel/data.ay +56 -0
- data/kernel/define.ay +93 -0
- data/kernel/doc.ay +453 -0
- data/kernel/documentation.ay +135 -0
- data/kernel/dynamic.ay +42 -0
- data/kernel/errors.ay +6 -0
- data/kernel/format.ay +13 -0
- data/kernel/format/data.ay +89 -0
- data/kernel/format/formatter.ay +345 -0
- data/kernel/format/parser.ay +13 -0
- data/kernel/hashes.ay +39 -0
- data/kernel/io.ay +244 -0
- data/kernel/namespaces.ay +63 -0
- data/kernel/node.ay +48 -0
- data/kernel/operators.ay +28 -0
- data/kernel/particles.ay +53 -0
- data/kernel/patterns.ay +256 -0
- data/kernel/precision.ay +148 -0
- data/kernel/pretty.ay +283 -0
- data/kernel/repl.ay +140 -0
- data/kernel/therie.ay +204 -0
- data/lib/ast/binary_send.rb +44 -0
- data/lib/ast/block.rb +268 -0
- data/lib/ast/constant.rb +88 -0
- data/lib/ast/internal/assign.rb +19 -0
- data/lib/ast/internal/block_pass.rb +21 -0
- data/lib/ast/internal/catch.rb +247 -0
- data/lib/ast/internal/class.rb +30 -0
- data/lib/ast/internal/class_variable.rb +23 -0
- data/lib/ast/internal/define.rb +174 -0
- data/lib/ast/internal/ensure.rb +135 -0
- data/lib/ast/internal/file.rb +14 -0
- data/lib/ast/internal/global_variable.rb +20 -0
- data/lib/ast/internal/if_then_else.rb +24 -0
- data/lib/ast/internal/instance_variable.rb +17 -0
- data/lib/ast/internal/let_macro.rb +35 -0
- data/lib/ast/internal/macro_quote.rb +23 -0
- data/lib/ast/internal/match.rb +53 -0
- data/lib/ast/internal/module.rb +30 -0
- data/lib/ast/internal/pattern.rb +17 -0
- data/lib/ast/internal/return.rb +29 -0
- data/lib/ast/internal/set.rb +19 -0
- data/lib/ast/internal/singleton_class.rb +18 -0
- data/lib/ast/internal/splat.rb +14 -0
- data/lib/ast/internal/when.rb +24 -0
- data/lib/ast/list.rb +25 -0
- data/lib/ast/macro.rb +37 -0
- data/lib/ast/node.rb +599 -0
- data/lib/ast/operator.rb +21 -0
- data/lib/ast/particle.rb +13 -0
- data/lib/ast/primitive.rb +20 -0
- data/lib/ast/quasi_quote.rb +20 -0
- data/lib/ast/quote.rb +13 -0
- data/lib/ast/send.rb +104 -0
- data/lib/ast/splice.rb +32 -0
- data/lib/ast/string.rb +23 -0
- data/lib/ast/unary.rb +44 -0
- data/lib/ast/unquote.rb +45 -0
- data/lib/ast/variable.rb +64 -0
- data/lib/atomy.kpeg.rb +3995 -0
- data/lib/code_loader.rb +137 -0
- data/lib/compiler/compiler.rb +155 -0
- data/lib/compiler/stages.rb +81 -0
- data/lib/formatter.kpeg.rb +1394 -0
- data/lib/macros.rb +317 -0
- data/lib/method.rb +261 -0
- data/lib/namespace.rb +236 -0
- data/lib/parser.rb +28 -0
- data/lib/patterns.rb +276 -0
- data/lib/patterns/any.rb +21 -0
- data/lib/patterns/attribute.rb +59 -0
- data/lib/patterns/block_pass.rb +54 -0
- data/lib/patterns/constant.rb +33 -0
- data/lib/patterns/default.rb +44 -0
- data/lib/patterns/head_tail.rb +63 -0
- data/lib/patterns/list.rb +77 -0
- data/lib/patterns/match.rb +45 -0
- data/lib/patterns/named.rb +55 -0
- data/lib/patterns/named_class.rb +46 -0
- data/lib/patterns/named_global.rb +46 -0
- data/lib/patterns/named_instance.rb +46 -0
- data/lib/patterns/particle.rb +29 -0
- data/lib/patterns/quasi_quote.rb +184 -0
- data/lib/patterns/quote.rb +33 -0
- data/lib/patterns/singleton_class.rb +31 -0
- data/lib/patterns/splat.rb +57 -0
- data/lib/util.rb +37 -0
- metadata +164 -0
data/lib/namespace.rb
ADDED
@@ -0,0 +1,236 @@
|
|
1
|
+
module Atomy
|
2
|
+
NAMESPACES = {}
|
3
|
+
NAMESPACE_DELIM = "_ns_"
|
4
|
+
|
5
|
+
def self.namespaced(ns, name)
|
6
|
+
return name.to_s if !ns or ns == "_"
|
7
|
+
ns.to_s + NAMESPACE_DELIM + name.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.from_namespaced(resolved)
|
11
|
+
split = resolved.to_s.split(NAMESPACE_DELIM)
|
12
|
+
meth_name = split.pop
|
13
|
+
ns_name = !split.empty? && split.join(NAMESPACE_DELIM)
|
14
|
+
[ns_name, meth_name]
|
15
|
+
end
|
16
|
+
|
17
|
+
class Namespace
|
18
|
+
attr_reader :name, :using, :symbols
|
19
|
+
|
20
|
+
def initialize(name, using = [])
|
21
|
+
using = [:atomy] + using unless name == :atomy
|
22
|
+
|
23
|
+
@name = name
|
24
|
+
@using = using
|
25
|
+
@symbols = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def register(sym)
|
29
|
+
@symbols << sym unless contains?(sym)
|
30
|
+
end
|
31
|
+
|
32
|
+
def contains?(sym)
|
33
|
+
@symbols.include?(sym)
|
34
|
+
end
|
35
|
+
|
36
|
+
def use(sym)
|
37
|
+
raise "namespace `#{sym}` tried to use itself" if sym == @name
|
38
|
+
raise "unknown namespace `#{sym}'" unless ns = Namespace.get(sym)
|
39
|
+
raise "circular namespaces: `#{@name}' <=> `#{sym}'" if ns.uses?(@name)
|
40
|
+
@using << sym unless @using.include?(sym)
|
41
|
+
end
|
42
|
+
|
43
|
+
def uses?(ns)
|
44
|
+
return true if @using.include?(ns)
|
45
|
+
|
46
|
+
@using.each do |u|
|
47
|
+
return true if Namespace.get(u).uses?(ns)
|
48
|
+
end
|
49
|
+
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolve(sym)
|
54
|
+
return @name if contains?(sym)
|
55
|
+
|
56
|
+
@using.each do |ns|
|
57
|
+
unless used = Namespace.get(ns)
|
58
|
+
raise "unknown namespace: #{ns.inspect}"
|
59
|
+
end
|
60
|
+
|
61
|
+
return ns if used.contains?(sym)
|
62
|
+
end
|
63
|
+
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def top_down(&blk)
|
68
|
+
yield @name
|
69
|
+
@using.each do |u|
|
70
|
+
Atomy::Namespace.get(u).top_down(&blk)
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.define_target
|
76
|
+
Thread.current.atomy_get_local(:atomy_define_in) ||
|
77
|
+
get && get.name.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.ensure(name, using = [])
|
81
|
+
Thread.current.atomy_set_local(
|
82
|
+
:atomy_namespace,
|
83
|
+
create(name, using)
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.create(name, using = [])
|
88
|
+
NAMESPACES[name.to_sym] ||=
|
89
|
+
new(name, using)
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.get(name = nil)
|
93
|
+
return NAMESPACES[name.to_sym] if name
|
94
|
+
Thread.current.atomy_get_local(:atomy_namespace)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.set(x)
|
98
|
+
Thread.current.atomy_set_local(:atomy_namespace, x)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.register(sym, name = nil)
|
102
|
+
ns = get(name)
|
103
|
+
return unless ns
|
104
|
+
ns.register(sym)
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.name
|
108
|
+
ns = get
|
109
|
+
return unless ns
|
110
|
+
ns.name
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.try_methods(name)
|
114
|
+
ns_name, meth_name = Atomy.from_namespaced(name)
|
115
|
+
|
116
|
+
if ns_name != "_" and \
|
117
|
+
ns = Atomy::Namespace.get(ns_name && ns_name.to_sym)
|
118
|
+
ns.top_down do |name|
|
119
|
+
yield Atomy.namespaced(name, meth_name).to_sym
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
meth_name.to_sym
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class Thread
|
129
|
+
def atomy_get_local(n)
|
130
|
+
@locals[n]
|
131
|
+
end
|
132
|
+
|
133
|
+
def atomy_set_local(n, v)
|
134
|
+
@locals[n] = v
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# NOTE: this is currently not used
|
139
|
+
# TODO: allow_private stuff
|
140
|
+
=begin
|
141
|
+
def Rubinius.bind_call(recv, nmeth, *args, &blk)
|
142
|
+
ns_name, meth_name = Atomy.from_namespaced(nmeth)
|
143
|
+
|
144
|
+
if ns_name == "_"
|
145
|
+
ns = nil
|
146
|
+
else
|
147
|
+
ns = Atomy::Namespace.get(!ns_name ? nil : ns_name.to_sym)
|
148
|
+
end
|
149
|
+
|
150
|
+
meth = meth_name.to_sym
|
151
|
+
|
152
|
+
res = Rubinius::CallUnit.send_as(meth)
|
153
|
+
|
154
|
+
if ns
|
155
|
+
nss = [ns]
|
156
|
+
scan = proc do |u|
|
157
|
+
unless un = Atomy::Namespace.get(u) and \
|
158
|
+
!nss.include?(un)
|
159
|
+
next
|
160
|
+
end
|
161
|
+
|
162
|
+
nss << un
|
163
|
+
un.using.each(&scan)
|
164
|
+
end
|
165
|
+
|
166
|
+
ns.using.each(&scan)
|
167
|
+
|
168
|
+
nss.reverse_each do |n|
|
169
|
+
next unless n.contains?(meth)
|
170
|
+
m = Atomy.namespaced(n.name, meth).to_sym
|
171
|
+
res = Rubinius::CallUnit.test(
|
172
|
+
Rubinius::CallUnit.test_respond_to(m),
|
173
|
+
Rubinius::CallUnit.send_as(m),
|
174
|
+
res
|
175
|
+
)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
res
|
180
|
+
end
|
181
|
+
=end
|
182
|
+
|
183
|
+
class Object
|
184
|
+
alias :respond_to_atomy_old? :respond_to?
|
185
|
+
|
186
|
+
def respond_to?(nmeth, include_private = false)
|
187
|
+
return true if respond_to_atomy_old?(nmeth, include_private)
|
188
|
+
|
189
|
+
Atomy::Namespace.try_methods(nmeth) do |m|
|
190
|
+
return true if respond_to_atomy_old?(m, include_private)
|
191
|
+
end
|
192
|
+
|
193
|
+
false
|
194
|
+
end
|
195
|
+
|
196
|
+
def send(nmeth, *as, &blk)
|
197
|
+
if respond_to_atomy_old?(nmeth, true)
|
198
|
+
return __send__(nmeth, *as, &blk)
|
199
|
+
end
|
200
|
+
|
201
|
+
name = Atomy::Namespace.try_methods(nmeth) do |m|
|
202
|
+
if respond_to_atomy_old?(m, true)
|
203
|
+
return __send__(m, *as, &blk)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
__send__(name, *as, &blk)
|
208
|
+
end
|
209
|
+
|
210
|
+
alias_method :atomy_send, :send
|
211
|
+
|
212
|
+
alias :method_atomy_old :method
|
213
|
+
|
214
|
+
def method(nmeth)
|
215
|
+
sym = Rubinius::Type.coerce_to_symbol nmeth
|
216
|
+
cm = Rubinius.find_method(self, sym)
|
217
|
+
|
218
|
+
return Method.new(self, cm[1], cm[0], sym) if cm
|
219
|
+
|
220
|
+
name = Atomy::Namespace.try_methods(nmeth) do |m|
|
221
|
+
cm = Rubinius.find_method(self, m)
|
222
|
+
return Method.new(self, cm[1], cm[0], m) if cm
|
223
|
+
end
|
224
|
+
|
225
|
+
method_atomy_old(name)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class Module
|
230
|
+
# TODO: alias_method, instance_method, module_function, private,
|
231
|
+
# private_class_method, protected, public, public_class_method
|
232
|
+
#
|
233
|
+
# TODO?: define_method, method_defined?, private_method_defined?,
|
234
|
+
# protected_method_defined?, public_method_defined?, remove_method,
|
235
|
+
# undef_method
|
236
|
+
end
|
data/lib/parser.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
base = File.expand_path "../", __FILE__
|
2
|
+
|
3
|
+
require base + "/atomy.kpeg.rb"
|
4
|
+
|
5
|
+
module Atomy
|
6
|
+
class Parser
|
7
|
+
def self.parse_string(source)
|
8
|
+
p = new(source)
|
9
|
+
p.raise_error unless p.parse
|
10
|
+
AST::Tree.new(p.result)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_file(name)
|
14
|
+
p = new(File.open(name, "rb").read)
|
15
|
+
p.raise_error unless p.parse
|
16
|
+
AST::Tree.new(p.result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
path = File.expand_path("../ast", __FILE__)
|
21
|
+
|
22
|
+
require path + "/node"
|
23
|
+
|
24
|
+
Dir["#{path}/**/*.rb"].sort.each do |f|
|
25
|
+
require f
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
data/lib/patterns.rb
ADDED
@@ -0,0 +1,276 @@
|
|
1
|
+
class PatternMismatch < RuntimeError
|
2
|
+
def initialize(p)
|
3
|
+
@pattern = p
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
module Atomy::Patterns
|
8
|
+
class Pattern
|
9
|
+
attr_accessor :variable
|
10
|
+
|
11
|
+
# push the target class for this pattern in a defition
|
12
|
+
def target(g)
|
13
|
+
raise Rubinius::CompileError, "no #target for #{self}"
|
14
|
+
end
|
15
|
+
|
16
|
+
# test if the pattern mtaches the value at the top of the stack
|
17
|
+
# effect on the stack: top value removed, boolean pushed
|
18
|
+
def matches?(g)
|
19
|
+
raise Rubinius::CompileError, "no #matches? for #{self}"
|
20
|
+
end
|
21
|
+
|
22
|
+
# match the pattern on the value at the top of the stack
|
23
|
+
# effect on the stack: top value removed
|
24
|
+
def deconstruct(g, locals = {})
|
25
|
+
g.pop
|
26
|
+
end
|
27
|
+
|
28
|
+
# helper for pushing the current class const onto the stack
|
29
|
+
def get(g)
|
30
|
+
g.push_cpath_top
|
31
|
+
self.class.name.split("::").each do |n|
|
32
|
+
g.find_const n.to_sym
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# create the pattern on the stack
|
37
|
+
def construct(g)
|
38
|
+
raise Rubinius::CompileError, "no #construct for #{self}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def assign(g, expr, set = false)
|
42
|
+
locals = {}
|
43
|
+
local_names.each do |n|
|
44
|
+
locals[n] = Atomy.assign_local(g, n, set)
|
45
|
+
end
|
46
|
+
|
47
|
+
expr.compile(g)
|
48
|
+
g.dup
|
49
|
+
match(g, set, locals)
|
50
|
+
end
|
51
|
+
|
52
|
+
# try pattern-matching, erroring on failure
|
53
|
+
# effect on the stack: top value removed
|
54
|
+
def match(g, set = false, locals = {})
|
55
|
+
error = g.new_label
|
56
|
+
done = g.new_label
|
57
|
+
|
58
|
+
local_names.each do |n|
|
59
|
+
locals[n] ||= Atomy.assign_local(g, n, set)
|
60
|
+
end
|
61
|
+
|
62
|
+
g.dup
|
63
|
+
matches?(g)
|
64
|
+
g.gif error
|
65
|
+
deconstruct(g, locals)
|
66
|
+
g.goto done
|
67
|
+
|
68
|
+
error.set!
|
69
|
+
g.pop
|
70
|
+
g.push_self
|
71
|
+
g.push_const :PatternMismatch
|
72
|
+
construct(g)
|
73
|
+
g.send :new, 1
|
74
|
+
g.allow_private
|
75
|
+
g.send :raise, 1
|
76
|
+
g.pop
|
77
|
+
|
78
|
+
done.set!
|
79
|
+
end
|
80
|
+
|
81
|
+
# local names bound by this pattern
|
82
|
+
def local_names
|
83
|
+
[]
|
84
|
+
end
|
85
|
+
|
86
|
+
# number of locals
|
87
|
+
def locals
|
88
|
+
local_names.size
|
89
|
+
end
|
90
|
+
|
91
|
+
# number of bindings
|
92
|
+
def bindings
|
93
|
+
locals
|
94
|
+
end
|
95
|
+
|
96
|
+
# test if a pattern matches a value
|
97
|
+
def ===(v)
|
98
|
+
singleton_class.dynamic_method(:===) do |g|
|
99
|
+
g.total_args = g.required_args = g.local_count = 1
|
100
|
+
g.push_local(0)
|
101
|
+
matches?(g)
|
102
|
+
g.ret
|
103
|
+
end
|
104
|
+
|
105
|
+
__send__ :===, v
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_node
|
109
|
+
Atomy::AST::Pattern.new(0, self)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# include all pattern classes
|
114
|
+
path = File.expand_path("../patterns", __FILE__)
|
115
|
+
|
116
|
+
Dir["#{path}/*.rb"].sort.each do |f|
|
117
|
+
require path + "/#{File.basename f}"
|
118
|
+
end
|
119
|
+
|
120
|
+
class Atomy::AST::Node
|
121
|
+
def pattern
|
122
|
+
raise "unknown pattern: #{inspect}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class Atomy::AST::Variable
|
127
|
+
def pattern
|
128
|
+
if @name == "_"
|
129
|
+
Any.new
|
130
|
+
else
|
131
|
+
Named.new(@name, Any.new)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class Atomy::AST::Primitive
|
137
|
+
def pattern
|
138
|
+
Match.new(@value)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class Atomy::AST::List
|
143
|
+
def pattern
|
144
|
+
List.new(@elements.collect(&:to_pattern))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class Atomy::AST::Constant
|
149
|
+
def pattern
|
150
|
+
Constant.new(self)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class Atomy::AST::ScopedConstant
|
155
|
+
def pattern
|
156
|
+
Constant.new(self)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class Atomy::AST::ToplevelConstant
|
161
|
+
def pattern
|
162
|
+
Constant.new(self)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Atomy::AST::BinarySend
|
167
|
+
def pattern
|
168
|
+
case @operator
|
169
|
+
when "."
|
170
|
+
HeadTail.new(@lhs.to_pattern, @rhs.to_pattern)
|
171
|
+
when "="
|
172
|
+
Default.new(@lhs.to_pattern, @rhs)
|
173
|
+
when "?"
|
174
|
+
Predicate.new(@private ? Any.new : @lhs.to_pattern, @rhs)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class Atomy::AST::Assign
|
180
|
+
def pattern
|
181
|
+
Default.new(@lhs.to_pattern, @rhs)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class Atomy::AST::BlockPass
|
186
|
+
def pattern
|
187
|
+
BlockPass.new(@body.to_pattern)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
class Atomy::AST::Quote
|
192
|
+
def pattern
|
193
|
+
Quote.new(@expression)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class Atomy::AST::Block
|
198
|
+
def pattern
|
199
|
+
SingletonClass.new(self)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class Atomy::AST::GlobalVariable
|
204
|
+
def pattern
|
205
|
+
NamedGlobal.new(@identifier)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class Atomy::AST::InstanceVariable
|
210
|
+
def pattern
|
211
|
+
NamedInstance.new(@identifier)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
class Atomy::AST::ClassVariable
|
216
|
+
def pattern
|
217
|
+
NamedClass.new(@identifier)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class Atomy::AST::Unary
|
222
|
+
def pattern
|
223
|
+
case @operator
|
224
|
+
when "$"
|
225
|
+
NamedGlobal.new(@receiver.name)
|
226
|
+
when "@"
|
227
|
+
case @receiver
|
228
|
+
when Atomy::AST::Unary
|
229
|
+
NamedClass.new(@receiver.receiver.name)
|
230
|
+
else
|
231
|
+
NamedInstance.new(@receiver.name)
|
232
|
+
end
|
233
|
+
when "%"
|
234
|
+
RuntimeClass.new(@receiver, nil)
|
235
|
+
when "&"
|
236
|
+
BlockPass.new(@receiver.to_pattern)
|
237
|
+
when "*"
|
238
|
+
Splat.new(@receiver.to_pattern)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
class Atomy::AST::Splat
|
244
|
+
def pattern
|
245
|
+
Splat.new(@value.to_pattern)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
class Atomy::AST::String
|
250
|
+
def pattern
|
251
|
+
Match.new(@value)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
class Atomy::AST::Particle
|
256
|
+
def pattern
|
257
|
+
Particle.new(@name.to_sym) # TODO: other forms
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
class Atomy::AST::Send
|
262
|
+
def pattern
|
263
|
+
if @block
|
264
|
+
Named.new(@method_name, @block.contents[0].to_pattern)
|
265
|
+
else
|
266
|
+
Attribute.new(@receiver, @method_name, @arguments)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class Atomy::AST::QuasiQuote
|
272
|
+
def pattern
|
273
|
+
QuasiQuote.new(self)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|