atomy 0.1.1 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +13 -0
  3. data/LICENSE.md +201 -0
  4. data/bin/atomy +16 -133
  5. data/kernel/array.ay +6 -0
  6. data/kernel/atomy.ay +18 -0
  7. data/kernel/condition.ay +171 -271
  8. data/kernel/control-flow.ay +197 -192
  9. data/kernel/core.ay +120 -0
  10. data/kernel/data.ay +83 -39
  11. data/kernel/define.ay +84 -93
  12. data/kernel/doc.ay +282 -449
  13. data/kernel/dynamic.ay +25 -29
  14. data/kernel/file.ay +9 -0
  15. data/kernel/grammar.ay +267 -0
  16. data/kernel/hash.ay +17 -0
  17. data/kernel/interpolation.ay +59 -0
  18. data/kernel/io.ay +70 -244
  19. data/kernel/let-macro.ay +24 -0
  20. data/kernel/let-pattern.ay +24 -0
  21. data/kernel/loop.ay +80 -0
  22. data/kernel/mutation.ay +53 -0
  23. data/kernel/particles.ay +176 -39
  24. data/kernel/patterns.ay +527 -191
  25. data/kernel/pretty.ay +311 -277
  26. data/kernel/quotes.ay +29 -0
  27. data/kernel/range.ay +4 -0
  28. data/kernel/regexp.ay +23 -0
  29. data/kernel/repl.ay +83 -109
  30. data/kernel/stack-local.ay +21 -0
  31. data/lib/atomy.rb +37 -0
  32. data/lib/atomy/bootstrap.rb +256 -0
  33. data/lib/atomy/code/assign.rb +64 -0
  34. data/lib/atomy/code/block.rb +98 -0
  35. data/lib/atomy/code/class_variable.rb +17 -0
  36. data/lib/atomy/code/constant.rb +21 -0
  37. data/lib/atomy/code/define.rb +242 -0
  38. data/lib/atomy/code/define_function.rb +51 -0
  39. data/lib/atomy/code/define_method.rb +20 -0
  40. data/lib/atomy/code/false.rb +9 -0
  41. data/lib/atomy/code/instance_variable.rb +15 -0
  42. data/lib/atomy/code/integer.rb +13 -0
  43. data/lib/atomy/code/list.rb +17 -0
  44. data/lib/atomy/code/nil.rb +9 -0
  45. data/lib/atomy/code/pattern.rb +23 -0
  46. data/lib/atomy/code/pattern/and.rb +61 -0
  47. data/lib/atomy/code/pattern/quasi_quote.rb +185 -0
  48. data/lib/atomy/code/pattern/splat.rb +29 -0
  49. data/lib/atomy/code/pattern/wildcard.rb +37 -0
  50. data/lib/atomy/code/quasi_quote.rb +118 -0
  51. data/lib/atomy/code/quote.rb +13 -0
  52. data/lib/atomy/code/self.rb +9 -0
  53. data/lib/atomy/code/send.rb +110 -0
  54. data/lib/atomy/code/sequence.rb +23 -0
  55. data/lib/atomy/code/string_literal.rb +53 -0
  56. data/lib/atomy/code/symbol.rb +13 -0
  57. data/lib/atomy/code/true.rb +9 -0
  58. data/lib/atomy/code/undefined.rb +9 -0
  59. data/lib/atomy/code/variable.rb +17 -0
  60. data/lib/atomy/codeloader.rb +218 -0
  61. data/lib/atomy/compiler.rb +57 -0
  62. data/lib/atomy/errors.rb +54 -0
  63. data/lib/atomy/grammar.rb +2278 -0
  64. data/lib/atomy/locals.rb +75 -0
  65. data/lib/atomy/message_structure.rb +277 -0
  66. data/lib/atomy/method.rb +343 -0
  67. data/lib/atomy/module.rb +144 -0
  68. data/lib/atomy/node/constructable.rb +169 -0
  69. data/lib/atomy/node/equality.rb +113 -0
  70. data/lib/atomy/node/meta.rb +206 -0
  71. data/lib/atomy/node/pretty.rb +108 -0
  72. data/lib/atomy/parser.rb +21 -0
  73. data/lib/atomy/pattern.rb +26 -0
  74. data/lib/atomy/pattern/and.rb +59 -0
  75. data/lib/atomy/pattern/attribute.rb +16 -0
  76. data/lib/atomy/pattern/class_variable.rb +15 -0
  77. data/lib/atomy/pattern/equality.rb +42 -0
  78. data/lib/atomy/pattern/instance_variable.rb +15 -0
  79. data/lib/atomy/pattern/kind_of.rb +20 -0
  80. data/lib/atomy/pattern/or.rb +48 -0
  81. data/lib/atomy/pattern/quasi_quote.rb +164 -0
  82. data/lib/atomy/pattern/splat.rb +15 -0
  83. data/lib/atomy/pattern/wildcard.rb +18 -0
  84. data/lib/atomy/rubygems.rb +48 -0
  85. data/lib/atomy/version.rb +3 -0
  86. metadata +169 -134
  87. data/COPYING +0 -30
  88. data/README.md +0 -1
  89. data/kernel/block.ay +0 -30
  90. data/kernel/boot.ay +0 -10
  91. data/kernel/comparison.ay +0 -61
  92. data/kernel/concurrency.ay +0 -84
  93. data/kernel/cosmetics.ay +0 -3
  94. data/kernel/data-delta.ay +0 -105
  95. data/kernel/documentation.ay +0 -135
  96. data/kernel/errors.ay +0 -6
  97. data/kernel/format.ay +0 -13
  98. data/kernel/format/data.ay +0 -89
  99. data/kernel/format/formatter.ay +0 -345
  100. data/kernel/format/parser.ay +0 -13
  101. data/kernel/hashes.ay +0 -39
  102. data/kernel/namespaces.ay +0 -63
  103. data/kernel/node.ay +0 -48
  104. data/kernel/operators.ay +0 -28
  105. data/kernel/precision.ay +0 -148
  106. data/kernel/therie.ay +0 -204
  107. data/lib/ast/binary_send.rb +0 -44
  108. data/lib/ast/block.rb +0 -268
  109. data/lib/ast/constant.rb +0 -88
  110. data/lib/ast/internal/assign.rb +0 -19
  111. data/lib/ast/internal/block_pass.rb +0 -21
  112. data/lib/ast/internal/catch.rb +0 -247
  113. data/lib/ast/internal/class.rb +0 -30
  114. data/lib/ast/internal/class_variable.rb +0 -23
  115. data/lib/ast/internal/define.rb +0 -174
  116. data/lib/ast/internal/ensure.rb +0 -135
  117. data/lib/ast/internal/file.rb +0 -14
  118. data/lib/ast/internal/global_variable.rb +0 -20
  119. data/lib/ast/internal/if_then_else.rb +0 -24
  120. data/lib/ast/internal/instance_variable.rb +0 -17
  121. data/lib/ast/internal/let_macro.rb +0 -35
  122. data/lib/ast/internal/macro_quote.rb +0 -23
  123. data/lib/ast/internal/match.rb +0 -53
  124. data/lib/ast/internal/module.rb +0 -30
  125. data/lib/ast/internal/pattern.rb +0 -17
  126. data/lib/ast/internal/return.rb +0 -29
  127. data/lib/ast/internal/set.rb +0 -19
  128. data/lib/ast/internal/singleton_class.rb +0 -18
  129. data/lib/ast/internal/splat.rb +0 -14
  130. data/lib/ast/internal/when.rb +0 -24
  131. data/lib/ast/list.rb +0 -25
  132. data/lib/ast/macro.rb +0 -37
  133. data/lib/ast/node.rb +0 -599
  134. data/lib/ast/operator.rb +0 -21
  135. data/lib/ast/particle.rb +0 -13
  136. data/lib/ast/primitive.rb +0 -20
  137. data/lib/ast/quasi_quote.rb +0 -20
  138. data/lib/ast/quote.rb +0 -13
  139. data/lib/ast/send.rb +0 -104
  140. data/lib/ast/splice.rb +0 -32
  141. data/lib/ast/string.rb +0 -23
  142. data/lib/ast/unary.rb +0 -44
  143. data/lib/ast/unquote.rb +0 -45
  144. data/lib/ast/variable.rb +0 -64
  145. data/lib/atomy.kpeg.rb +0 -3995
  146. data/lib/code_loader.rb +0 -137
  147. data/lib/compiler/compiler.rb +0 -155
  148. data/lib/compiler/stages.rb +0 -81
  149. data/lib/formatter.kpeg.rb +0 -1394
  150. data/lib/macros.rb +0 -317
  151. data/lib/method.rb +0 -261
  152. data/lib/namespace.rb +0 -236
  153. data/lib/parser.rb +0 -28
  154. data/lib/patterns.rb +0 -276
  155. data/lib/patterns/any.rb +0 -21
  156. data/lib/patterns/attribute.rb +0 -59
  157. data/lib/patterns/block_pass.rb +0 -54
  158. data/lib/patterns/constant.rb +0 -33
  159. data/lib/patterns/default.rb +0 -44
  160. data/lib/patterns/head_tail.rb +0 -63
  161. data/lib/patterns/list.rb +0 -77
  162. data/lib/patterns/match.rb +0 -45
  163. data/lib/patterns/named.rb +0 -55
  164. data/lib/patterns/named_class.rb +0 -46
  165. data/lib/patterns/named_global.rb +0 -46
  166. data/lib/patterns/named_instance.rb +0 -46
  167. data/lib/patterns/particle.rb +0 -29
  168. data/lib/patterns/quasi_quote.rb +0 -184
  169. data/lib/patterns/quote.rb +0 -33
  170. data/lib/patterns/singleton_class.rb +0 -31
  171. data/lib/patterns/splat.rb +0 -57
  172. data/lib/util.rb +0 -37
data/lib/macros.rb DELETED
@@ -1,317 +0,0 @@
1
- class MethodFail < ArgumentError
2
- def initialize(mn)
3
- @method_name = mn
4
- end
5
-
6
- def message
7
- "method #{@method_name.to_s} did not understand " +
8
- "its arguments (non-exhaustive patterns)"
9
- end
10
- end
11
-
12
- module Atomy
13
- OPERATORS = {}
14
- STATE = {}
15
-
16
- module Macro
17
- def self.set_op_info(ops, assoc, prec)
18
- ops.each do |o|
19
- info = OPERATORS[o] ||= {}
20
- info[:assoc] = assoc
21
- info[:prec] = prec
22
- end
23
- end
24
-
25
- class Environment
26
- @@salt = 0
27
- @@macros = {}
28
- @@let = Hash.new { |h, k| h[k] = [] }
29
- @@quoters = {}
30
- @@line = 0
31
-
32
- class << self
33
- attr_accessor :quoters
34
-
35
- def macros
36
- @@macros
37
- end
38
-
39
- def let
40
- @@let
41
- end
42
-
43
- def line
44
- @@line
45
- end
46
-
47
- def line=(x)
48
- @@line = x
49
- end
50
-
51
- def quoter(name, &blk)
52
- @@quoters[name] = blk
53
- end
54
-
55
- def quote(name, contents, flags)
56
- if a = @@quoters[name.to_sym]
57
- a.call(contents, flags)
58
- else
59
- raise "unknown quoter #{name.inspect}"
60
- end
61
- end
62
-
63
- def names(num = 0, &block)
64
- num = block.arity if block
65
-
66
- as = []
67
- num.times do
68
- as << Atomy::AST::Variable.new(0, "s:" + @@salt.to_s)
69
- @@salt += 1
70
- end
71
-
72
- if block
73
- block.call(*as)
74
- else
75
- as
76
- end
77
- end
78
- end
79
- end
80
-
81
- def self.register(name, args, body, let = false)
82
- ns = Atomy::Namespace.get(Thread.current[:atomy_define_in])
83
- meth = ns ? Atomy.namespaced(ns.name, name) : name
84
- meth = (intern meth).to_sym
85
-
86
- if let && Environment.respond_to?(meth)
87
- Environment.let[name] << Environment.method(meth)
88
- end
89
-
90
- methods = Environment.macros
91
- method = [[Patterns::Any.new, args], body.resolve]
92
- if ms = methods[meth]
93
- Atomy.insert_method(method, ms)
94
- else
95
- methods[meth] = [method]
96
- end
97
-
98
- Atomy.add_method(
99
- Environment.singleton_class,
100
- meth,
101
- methods[meth],
102
- nil,
103
- :public,
104
- true
105
- )
106
-
107
- meth
108
- end
109
-
110
- def self.intern(name)
111
- "atomy-macro:" + name
112
- end
113
-
114
- # take a node and return its expansion
115
- def self.expand(node)
116
- name = node.method_name
117
-
118
- return node unless name
119
-
120
- methods = []
121
- if name && ns = Atomy::Namespace.get
122
- ([ns.name] + ns.using).each do |n|
123
- methods << intern(Atomy.namespaced(n, name)).to_sym
124
- end
125
- end
126
-
127
- methods << intern(name).to_sym
128
-
129
- expanded = nil
130
- methods.each do |meth|
131
- next unless Environment.respond_to?(meth)
132
-
133
- expanded = expand_node(node, meth)
134
- break if expanded
135
- end
136
-
137
- expanded || node
138
- end
139
-
140
- def self.expand_node(node, meth)
141
- Environment.line ||= node.line
142
-
143
- begin
144
- case node
145
- when AST::BinarySend
146
- expand_res Environment.send(
147
- meth,
148
- nil,
149
- node.lhs,
150
- node.rhs
151
- )
152
- when AST::Send
153
- if node.arguments.last.kind_of?(AST::Unary) && \
154
- node.arguments.last.operator == "&"
155
- block = AST::BlockPass.new(node.line, node.arguments.pop.receiver)
156
- else
157
- block = node.block
158
- end
159
-
160
- expand_res Environment.send(
161
- meth,
162
- block,
163
- node.receiver,
164
- *node.arguments
165
- )
166
- when AST::Unary
167
- expand_res Environment.send(
168
- meth,
169
- nil,
170
- node.receiver
171
- )
172
- when AST::Variable
173
- expand_res Environment.send(
174
- meth
175
- )
176
- else
177
- # just stopping
178
- nil
179
- end
180
- rescue MethodFail, ArgumentError => e
181
- # expand normally if the macro doesn't seem to be a match
182
- raise unless e.instance_variable_get("@method_name") == meth
183
- nil
184
- ensure
185
- Environment.line = nil
186
- end
187
- end
188
-
189
- # helper method for #expand
190
- def self.expand_res(node)
191
- expand(node.to_node)
192
- end
193
-
194
- # @!x
195
- # to:
196
- # @`(!~x)
197
- #
198
- # @!?x
199
- # to:
200
- # @(`!?~x)
201
- def self.unary_chain(n)
202
- d = n.dup
203
- x = d
204
- while x.kind_of?(Atomy::AST::Unary)
205
- if x.receiver.kind_of?(Atomy::AST::Unary)
206
- y = x.receiver.dup
207
- x.receiver = y
208
- x = y
209
- else
210
- unless x.receiver.kind_of?(Atomy::AST::Primitive)
211
- x.receiver = Atomy::AST::Unquote.new(
212
- x.receiver.line,
213
- x.receiver
214
- )
215
- end
216
- break
217
- end
218
- end
219
-
220
- Atomy::AST::QuasiQuote.new(d.line, d)
221
- end
222
-
223
- # x(a) y(b)
224
- # to:
225
- # `(x(~a)) y(b)
226
- #
227
- # x(a) y(b) z(c)
228
- # to:
229
- # `(x(~a) y(~b)) z(c)
230
- #
231
- # x(&a) b(c) should bind the proc-arg
232
- def self.send_chain(n)
233
- return n if n.block
234
-
235
- d = n.dup
236
- x = d
237
- while x.kind_of?(Atomy::AST::Send)
238
- as = []
239
- x.arguments.each do |a|
240
- if a.kind_of?(Atomy::AST::Unary) && a.operator == "&"
241
- x.block = Atomy::AST::Unquote.new(
242
- a.line,
243
- a.receiver
244
- )
245
- else
246
- as << Atomy::AST::Unquote.new(
247
- a.line,
248
- a
249
- )
250
- end
251
- end
252
-
253
- x.arguments = as
254
-
255
- if x.receiver.kind_of?(Atomy::AST::Send) && !x.receiver.block
256
- y = x.receiver.dup
257
- x.receiver = y
258
- x = y
259
- else
260
- unless x.receiver.kind_of?(Atomy::AST::Primitive)
261
- x.receiver = Atomy::AST::Unquote.new(
262
- x.receiver.line,
263
- x.receiver
264
- )
265
- end
266
- break
267
- end
268
- end
269
-
270
- Atomy::AST::QuasiQuote.new(d.line, d)
271
- end
272
-
273
- def self.macro_pattern(n)
274
- if n.kind_of?(Atomy::AST::Send) && !n.block
275
- n = send_chain(n)
276
- end
277
-
278
- if n.kind_of?(Atomy::AST::Unary) && n.operator != "&" && n.operator != "*"
279
- n = unary_chain(n)
280
- end
281
-
282
- # TODO: this is too powerful. `foo = 'Object` pattern breaks.
283
- n = n.recursively do |sub|
284
- case sub
285
- when Atomy::AST::Constant
286
- Atomy::AST::ScopedConstant.new(
287
- sub.line,
288
- Atomy::AST::ScopedConstant.new(
289
- sub.line,
290
- Atomy::AST::Constant.new(
291
- sub.line,
292
- "Atomy"
293
- ),
294
- "AST"
295
- ),
296
- sub.identifier
297
- )
298
- else
299
- sub
300
- end
301
- end
302
-
303
- case n
304
- when Atomy::AST::Primitive
305
- if n.value == :self
306
- Atomy::Patterns::Quote.new(
307
- Atomy::AST::Primitive.new(n.line, :self)
308
- )
309
- else
310
- n.to_pattern
311
- end
312
- else
313
- n.to_pattern
314
- end
315
- end
316
- end
317
- end
data/lib/method.rb DELETED
@@ -1,261 +0,0 @@
1
- module Atomy
2
- def self.segments(args)
3
- req = []
4
- dfs = []
5
- spl = nil
6
- blk = nil
7
- args.each do |a|
8
- case a
9
- when Patterns::BlockPass
10
- blk = a
11
- when Patterns::Splat
12
- spl = a
13
- when Patterns::Default
14
- dfs << a
15
- else
16
- req << a
17
- end
18
- end
19
- [req, dfs, spl, blk]
20
- end
21
-
22
- def self.match_self?(pat)
23
- case pat
24
- when Patterns::Match
25
- pat.value != :self
26
- when Patterns::Constant
27
- false
28
- when Patterns::Named
29
- match_self?(pat.pattern)
30
- else
31
- true
32
- end
33
- end
34
-
35
- def self.build_method(name, branches, is_macro = false, file = :dynamic, line = 1)
36
- g = Rubinius::Generator.new
37
- g.name = name.to_sym
38
- g.file = file.to_sym
39
- g.set_line Integer(line)
40
-
41
- done = g.new_label
42
- mismatch = g.new_label
43
-
44
- g.push_state Rubinius::AST::ClosedScope.new(line)
45
-
46
- g.state.push_name name
47
-
48
- block_offset = is_macro ? 1 : 0
49
-
50
- total = 0
51
- min_reqs = nil
52
- reqs = 0
53
- defs = 0
54
- names = []
55
- splatted = false
56
-
57
- resolved = branches.collect do |pats, meth|
58
- segs = segments(pats[1])
59
-
60
- min_reqs ||= segs[0].size
61
- min_reqs = [min_reqs, segs[0].size].min
62
- reqs = [reqs, segs[0].size].max
63
- defs = [defs, segs[1].size].max
64
- total = [reqs + defs, total].max
65
-
66
- names += pats[0].local_names
67
- pats[1].each do |p|
68
- names += p.local_names
69
- end
70
-
71
- splatted = true if segs[2]
72
-
73
- [pats[0], segs, meth]
74
- end
75
-
76
- names.uniq!
77
-
78
- if splatted
79
- g.splat_index = block_offset + reqs + defs
80
- end
81
-
82
- total += block_offset
83
-
84
- total.times do |n|
85
- names.unshift("arg:" + n.to_s)
86
- end
87
-
88
- locals = {}
89
- names.each do |n|
90
- locals[n] = g.state.scope.new_local(n).reference
91
- end
92
-
93
- g.local_names = names
94
- g.total_args = total
95
- g.required_args = min_reqs
96
- g.local_count = total + g.local_names.size
97
-
98
- g.push_self
99
- resolved.each do |recv, (reqs, defs, splat, block), meth|
100
- skip = g.new_label
101
- argmis = g.new_label
102
-
103
- if reqs.size > min_reqs
104
- g.passed_arg((reqs.size + block_offset) - 1)
105
- g.gif skip
106
- end
107
-
108
- if match_self?(recv)
109
- g.dup
110
- recv.matches?(g)
111
- g.gif skip
112
- end
113
-
114
- if splat
115
- g.push_local(g.splat_index)
116
- splat.pattern.deconstruct(g)
117
- end
118
-
119
- if recv.bindings > 0
120
- g.dup
121
- recv.deconstruct(g, locals)
122
- end
123
-
124
- if block
125
- if is_macro
126
- g.push_local(0)
127
- block.pattern.deconstruct(g, locals)
128
- else
129
- g.push_block_arg
130
- block.deconstruct(g, locals)
131
- end
132
- end
133
-
134
- reqs.each_with_index do |a, i|
135
- g.push_local(i + block_offset)
136
-
137
- if a.bindings > 0
138
- g.dup
139
- a.matches?(g)
140
- g.gif argmis
141
- a.deconstruct(g, locals)
142
- else
143
- a.matches?(g)
144
- g.gif skip
145
- end
146
- end
147
-
148
- defs.each_with_index do |d, i|
149
- passed = g.new_label
150
- decons = g.new_label
151
-
152
- num = reqs.size + i + block_offset
153
- g.passed_arg num
154
- g.git passed
155
-
156
- d.default.compile(g)
157
- g.set_local num
158
- g.goto decons
159
-
160
- passed.set!
161
- g.push_local num
162
-
163
- decons.set!
164
- d.deconstruct(g)
165
- end
166
-
167
- meth.compile(g)
168
- g.goto done
169
-
170
- argmis.set!
171
- g.pop
172
-
173
- skip.set!
174
- end
175
-
176
- g.invoke_primitive :vm_check_super_callable, 0
177
- g.gif mismatch
178
-
179
- g.push_block
180
- if g.state.super?
181
- g.zsuper g.state.super.name
182
- else
183
- g.zsuper nil
184
- end
185
- g.goto done
186
-
187
- mismatch.set!
188
- g.push_self
189
- g.push_cpath_top
190
- g.find_const :MethodFail
191
- g.push_literal name
192
- g.send :new, 1
193
- g.allow_private
194
- g.send :raise, 1
195
-
196
- done.set!
197
- g.state.pop_name
198
- g.ret
199
- g.close
200
- g.pop_state
201
- g.use_detected
202
- g.encode
203
-
204
- g.package Rubinius::CompiledMethod
205
- end
206
-
207
- def self.add_method(target, name, branches, static_scope, visibility = :public, is_macro = false)
208
- cm = build_method(name, branches, is_macro)
209
-
210
- unless static_scope
211
- static_scope = Rubinius::StaticScope.new(
212
- self,
213
- Rubinius::StaticScope.new(Object)
214
- )
215
- end
216
-
217
- cm.scope = static_scope
218
-
219
- Rubinius.add_method name, cm, target, visibility
220
- end
221
-
222
- def self.compare_heads(xs, ys)
223
- return 1 if xs.size > ys.size
224
- return -1 if xs.size < ys.size
225
-
226
- xs.zip(ys) do |x, y|
227
- cmp = x <=> y
228
- return cmp unless cmp == 0
229
- end
230
-
231
- 0
232
- end
233
-
234
- def self.equivalent?(xs, ys)
235
- xs.zip(ys) do |x, y|
236
- return false unless x =~ y
237
- end
238
-
239
- true
240
- end
241
-
242
- def self.insert_method(new, branches)
243
- (nr, na), nb = new
244
- if nr.respond_to?(:<=>)
245
- branches.each_with_index do |branch, i|
246
- (r, a), b = branch
247
- case compare_heads([nr] + na, [r] + a)
248
- when 1
249
- return branches.insert(i, new)
250
- when 0
251
- if equivalent?([nr] + na, [r] + a)
252
- branches[i] = new
253
- return branches
254
- end
255
- end
256
- end
257
- end
258
-
259
- branches << new
260
- end
261
- end