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.
Files changed (99) hide show
  1. data/COPYING +30 -0
  2. data/README.md +1 -0
  3. data/bin/atomy +134 -0
  4. data/kernel/block.ay +30 -0
  5. data/kernel/boot.ay +10 -0
  6. data/kernel/comparison.ay +61 -0
  7. data/kernel/concurrency.ay +84 -0
  8. data/kernel/condition.ay +277 -0
  9. data/kernel/control-flow.ay +222 -0
  10. data/kernel/cosmetics.ay +3 -0
  11. data/kernel/data-delta.ay +105 -0
  12. data/kernel/data.ay +56 -0
  13. data/kernel/define.ay +93 -0
  14. data/kernel/doc.ay +453 -0
  15. data/kernel/documentation.ay +135 -0
  16. data/kernel/dynamic.ay +42 -0
  17. data/kernel/errors.ay +6 -0
  18. data/kernel/format.ay +13 -0
  19. data/kernel/format/data.ay +89 -0
  20. data/kernel/format/formatter.ay +345 -0
  21. data/kernel/format/parser.ay +13 -0
  22. data/kernel/hashes.ay +39 -0
  23. data/kernel/io.ay +244 -0
  24. data/kernel/namespaces.ay +63 -0
  25. data/kernel/node.ay +48 -0
  26. data/kernel/operators.ay +28 -0
  27. data/kernel/particles.ay +53 -0
  28. data/kernel/patterns.ay +256 -0
  29. data/kernel/precision.ay +148 -0
  30. data/kernel/pretty.ay +283 -0
  31. data/kernel/repl.ay +140 -0
  32. data/kernel/therie.ay +204 -0
  33. data/lib/ast/binary_send.rb +44 -0
  34. data/lib/ast/block.rb +268 -0
  35. data/lib/ast/constant.rb +88 -0
  36. data/lib/ast/internal/assign.rb +19 -0
  37. data/lib/ast/internal/block_pass.rb +21 -0
  38. data/lib/ast/internal/catch.rb +247 -0
  39. data/lib/ast/internal/class.rb +30 -0
  40. data/lib/ast/internal/class_variable.rb +23 -0
  41. data/lib/ast/internal/define.rb +174 -0
  42. data/lib/ast/internal/ensure.rb +135 -0
  43. data/lib/ast/internal/file.rb +14 -0
  44. data/lib/ast/internal/global_variable.rb +20 -0
  45. data/lib/ast/internal/if_then_else.rb +24 -0
  46. data/lib/ast/internal/instance_variable.rb +17 -0
  47. data/lib/ast/internal/let_macro.rb +35 -0
  48. data/lib/ast/internal/macro_quote.rb +23 -0
  49. data/lib/ast/internal/match.rb +53 -0
  50. data/lib/ast/internal/module.rb +30 -0
  51. data/lib/ast/internal/pattern.rb +17 -0
  52. data/lib/ast/internal/return.rb +29 -0
  53. data/lib/ast/internal/set.rb +19 -0
  54. data/lib/ast/internal/singleton_class.rb +18 -0
  55. data/lib/ast/internal/splat.rb +14 -0
  56. data/lib/ast/internal/when.rb +24 -0
  57. data/lib/ast/list.rb +25 -0
  58. data/lib/ast/macro.rb +37 -0
  59. data/lib/ast/node.rb +599 -0
  60. data/lib/ast/operator.rb +21 -0
  61. data/lib/ast/particle.rb +13 -0
  62. data/lib/ast/primitive.rb +20 -0
  63. data/lib/ast/quasi_quote.rb +20 -0
  64. data/lib/ast/quote.rb +13 -0
  65. data/lib/ast/send.rb +104 -0
  66. data/lib/ast/splice.rb +32 -0
  67. data/lib/ast/string.rb +23 -0
  68. data/lib/ast/unary.rb +44 -0
  69. data/lib/ast/unquote.rb +45 -0
  70. data/lib/ast/variable.rb +64 -0
  71. data/lib/atomy.kpeg.rb +3995 -0
  72. data/lib/code_loader.rb +137 -0
  73. data/lib/compiler/compiler.rb +155 -0
  74. data/lib/compiler/stages.rb +81 -0
  75. data/lib/formatter.kpeg.rb +1394 -0
  76. data/lib/macros.rb +317 -0
  77. data/lib/method.rb +261 -0
  78. data/lib/namespace.rb +236 -0
  79. data/lib/parser.rb +28 -0
  80. data/lib/patterns.rb +276 -0
  81. data/lib/patterns/any.rb +21 -0
  82. data/lib/patterns/attribute.rb +59 -0
  83. data/lib/patterns/block_pass.rb +54 -0
  84. data/lib/patterns/constant.rb +33 -0
  85. data/lib/patterns/default.rb +44 -0
  86. data/lib/patterns/head_tail.rb +63 -0
  87. data/lib/patterns/list.rb +77 -0
  88. data/lib/patterns/match.rb +45 -0
  89. data/lib/patterns/named.rb +55 -0
  90. data/lib/patterns/named_class.rb +46 -0
  91. data/lib/patterns/named_global.rb +46 -0
  92. data/lib/patterns/named_instance.rb +46 -0
  93. data/lib/patterns/particle.rb +29 -0
  94. data/lib/patterns/quasi_quote.rb +184 -0
  95. data/lib/patterns/quote.rb +33 -0
  96. data/lib/patterns/singleton_class.rb +31 -0
  97. data/lib/patterns/splat.rb +57 -0
  98. data/lib/util.rb +37 -0
  99. metadata +164 -0
@@ -0,0 +1,88 @@
1
+ module Atomy
2
+ module AST
3
+ class Constant < Node
4
+ attributes :identifier
5
+ generate
6
+
7
+ def name
8
+ @identifier.to_sym
9
+ end
10
+
11
+ def bytecode(g)
12
+ pos(g)
13
+ g.push_const name
14
+ end
15
+
16
+ def assign(g, v)
17
+ g.push_scope
18
+ g.push_literal name
19
+ v.compile(g)
20
+ g.send :const_set, 2
21
+ end
22
+
23
+ def as_message(send)
24
+ send.dup.tap do |s|
25
+ s.method_name = @identifier
26
+ end
27
+ end
28
+ end
29
+
30
+ class ToplevelConstant < Node
31
+ attributes :identifier
32
+ generate
33
+
34
+ def name
35
+ @identifier.to_sym
36
+ end
37
+
38
+ def bytecode(g)
39
+ pos(g)
40
+ g.push_cpath_top
41
+ g.find_const name
42
+ end
43
+
44
+ def assign(g, v)
45
+ g.push_cpath_top
46
+ g.push_literal name
47
+ v.compile(g)
48
+ g.send :const_set, 2
49
+ end
50
+
51
+ def as_message(send)
52
+ send.dup.tap do |s|
53
+ s.method_name = @identifier
54
+ end
55
+ end
56
+ end
57
+
58
+ class ScopedConstant < Node
59
+ children :parent
60
+ attributes :identifier
61
+ generate
62
+
63
+ def name
64
+ @identifier.to_sym
65
+ end
66
+
67
+ def bytecode(g)
68
+ pos(g)
69
+ @parent.compile(g)
70
+ g.find_const name
71
+ end
72
+
73
+ def assign(g, v)
74
+ @parent.compile(g)
75
+ g.push_literal name
76
+ v.compile(g)
77
+ g.send :const_set, 2
78
+ end
79
+
80
+ def as_message(send)
81
+ send.dup.tap do |s|
82
+ s.method_name = @identifier
83
+ s.receiver = @parent
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,19 @@
1
+ module Atomy
2
+ module AST
3
+ class Assign < Node
4
+ children :lhs, :rhs
5
+ generate
6
+
7
+ def bytecode(g)
8
+ pos(g)
9
+
10
+ if @lhs.respond_to?(:assign)
11
+ @lhs.assign(g, @rhs)
12
+ return
13
+ end
14
+
15
+ @lhs.to_pattern.assign(g, @rhs)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Atomy::AST
2
+ class BlockPass < Node
3
+ children :body
4
+ generate
5
+ def bytecode(g)
6
+ @body.compile(g)
7
+ nil_block = g.new_label
8
+ g.dup
9
+ g.is_nil
10
+ g.git nil_block
11
+
12
+ g.push_cpath_top
13
+ g.find_const :Proc
14
+
15
+ g.swap
16
+ g.send :__from_block__, 1
17
+
18
+ nil_block.set!
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,247 @@
1
+ module Atomy
2
+ module AST
3
+ class Catch < Node
4
+ children :body, [:handlers], :else?
5
+ generate
6
+
7
+ # via Rubinius::AST::Rescue
8
+ def bytecode(g)
9
+ pos(g)
10
+
11
+ g.push_modifiers
12
+ if @body.nil?
13
+ if @else.nil?
14
+ # Stupid. No body and no else.
15
+ g.push :nil
16
+ else
17
+ # Only an else, run it.
18
+ @else.compile(g)
19
+ end
20
+ else
21
+ outer_retry = g.retry
22
+
23
+ this_retry = g.new_label
24
+ reraise = g.new_label
25
+ els = g.new_label
26
+ done = g.new_label
27
+
28
+ # Save the current exception into a stack local
29
+ g.push_exception_state
30
+ outer_exc_state = g.new_stack_local
31
+ g.set_stack_local outer_exc_state
32
+ g.pop
33
+
34
+ this_retry.set!
35
+ ex = g.new_label
36
+ g.setup_unwind ex, Rubinius::AST::RescueType
37
+
38
+ # TODO: ?
39
+ g.new_label.set!
40
+
41
+ if current_break = g.break
42
+ # Make a break available to use, which we'll use to
43
+ # lazily generate a cleanup area
44
+ g.break = g.new_label
45
+ end
46
+
47
+ # Setup a lazy cleanup area for next'ing out of the handler
48
+ current_next = g.next
49
+ g.next = g.new_label
50
+
51
+ # Use a lazy label to patch up prematuraly leaving a begin
52
+ # body via retry.
53
+ if outer_retry
54
+ g.retry = g.new_label
55
+ end
56
+
57
+ # Also handle redo unwinding through the rescue
58
+ if current_redo = g.redo
59
+ g.redo = g.new_label
60
+ end
61
+
62
+ @body.compile(g)
63
+ g.pop_unwind
64
+ g.goto els
65
+
66
+ if current_break
67
+ if g.break.used?
68
+ g.break.set!
69
+ g.pop_unwind
70
+
71
+ # Reset the outer exception
72
+ g.push_stack_local outer_exc_state
73
+ g.restore_exception_state
74
+
75
+ g.goto current_break
76
+ end
77
+
78
+ g.break = current_break
79
+ end
80
+
81
+ if g.next.used?
82
+ g.next.set!
83
+ g.pop_unwind
84
+
85
+ # Reset the outer exception
86
+ g.push_stack_local outer_exc_state
87
+ g.restore_exception_state
88
+
89
+ if current_next
90
+ g.goto current_next
91
+ else
92
+ g.ret
93
+ end
94
+ end
95
+
96
+ g.next = current_next
97
+
98
+ if current_redo
99
+ if g.redo.used?
100
+ g.redo.set!
101
+ g.pop_unwind
102
+
103
+ # Reset the outer exception
104
+ g.push_stack_local outer_exc_state
105
+ g.restore_exception_state
106
+
107
+ g.goto current_redo
108
+ end
109
+
110
+ g.redo = current_redo
111
+ end
112
+
113
+ if outer_retry
114
+ if g.retry.used?
115
+ g.retry.set!
116
+ g.pop_unwind
117
+
118
+ # Reset the outer exception
119
+ g.push_stack_local outer_exc_state
120
+ g.restore_exception_state
121
+
122
+ g.goto outer_retry
123
+ end
124
+
125
+ g.retry = outer_retry
126
+ end
127
+
128
+ # We jump here if an exception has occured in the body
129
+ ex.set!
130
+
131
+ # Expose the retry label here only, not before this.
132
+ g.retry = this_retry
133
+
134
+ # Save exception state to use in reraise
135
+ g.push_exception_state
136
+
137
+ raised_exc_state = g.new_stack_local
138
+ g.set_stack_local raised_exc_state
139
+ g.pop
140
+
141
+ # Save the current exception, so that calling #=== can't trample
142
+ # it.
143
+ g.push_current_exception
144
+
145
+ @handlers.each_with_index do |p, i|
146
+ last = i + 1 == @handlers.size
147
+ n = last ? nil : g.new_label
148
+ handler_bytecode(g, p.lhs.to_pattern, p.rhs, reraise, done, outer_exc_state, n)
149
+ n.set! unless last
150
+ end
151
+
152
+ reraise.set!
153
+
154
+ # Restore the exception state we saved and the reraise. The act
155
+ # of checking if an exception matches can run any code, which
156
+ # can easily trample on the current exception.
157
+ #
158
+ # Remove the direct exception so we can get to the state
159
+ g.pop
160
+
161
+ # Restore the state and reraise
162
+ g.push_stack_local raised_exc_state
163
+ g.restore_exception_state
164
+ g.reraise
165
+
166
+ els.set!
167
+ if @else
168
+ g.pop
169
+ @else.compile(g)
170
+ end
171
+
172
+ done.set!
173
+
174
+ g.push_stack_local outer_exc_state
175
+ g.restore_exception_state
176
+ end
177
+ g.pop_modifiers
178
+ end
179
+
180
+ def handler_bytecode(g, pattern, expression, reraise, done, outer_exc_state, next_handler = nil)
181
+ body = g.new_label
182
+
183
+ g.dup
184
+ pattern.matches?(g)
185
+ g.git body
186
+
187
+ if next_handler
188
+ g.goto next_handler
189
+ else
190
+ g.goto reraise
191
+ end
192
+
193
+ body.set!
194
+
195
+ pattern.deconstruct(g)
196
+
197
+ current_break = g.break
198
+ g.break = g.new_label
199
+
200
+ current_next = g.next
201
+ g.next = g.new_label
202
+
203
+ g.state.push_rescue(outer_exc_state)
204
+ expression.compile(g)
205
+ g.state.pop_rescue
206
+
207
+ g.clear_exception
208
+ g.goto done
209
+
210
+ if g.break.used?
211
+ g.break.set!
212
+ g.clear_exception
213
+
214
+ # Reset the outer exception
215
+ g.push_stack_local outer_exc_state
216
+ g.restore_exception_state
217
+
218
+ if current_break
219
+ g.goto current_break
220
+ else
221
+ g.raise_break
222
+ end
223
+ end
224
+
225
+ g.break = current_break
226
+
227
+ if g.next.used?
228
+ g.next.set!
229
+
230
+ g.clear_exception
231
+
232
+ # Reset the outer exception
233
+ g.push_stack_local outer_exc_state
234
+ g.restore_exception_state
235
+
236
+ if current_next
237
+ g.goto current_next
238
+ else
239
+ g.ret
240
+ end
241
+ end
242
+
243
+ g.next = current_next
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,30 @@
1
+ module Atomy
2
+ module AST
3
+ class Class < Node
4
+ children :name, :body, [:superclass, "Primitive.new(0, :nil)"]
5
+ generate
6
+
7
+ def class_name
8
+ case @name
9
+ when Constant
10
+ Rubinius::AST::ClassName.new @line, @name.name, @superclass
11
+ when ToplevelConstant
12
+ Rubinius::AST::ToplevelModuleName.new @line, @name, @superclass
13
+ when ScopedConstant
14
+ Rubinius::AST::ScopedClassName.new @line, @name, @superclass
15
+ else
16
+ @name
17
+ end
18
+ end
19
+
20
+ def class_body
21
+ Rubinius::AST::ClassScope.new @line, class_name, @body
22
+ end
23
+
24
+ def bytecode(g)
25
+ class_name.bytecode(g)
26
+ class_body.bytecode(g)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ module Atomy
2
+ module AST
3
+ class ClassVariable < Node
4
+ attributes :identifier
5
+ generate
6
+
7
+ def name
8
+ ("@@" + @identifier).to_sym
9
+ end
10
+
11
+ def bytecode(g)
12
+ pos(g)
13
+ if g.state.scope.module?
14
+ g.push :self
15
+ else
16
+ g.push_scope
17
+ end
18
+ g.push_literal name
19
+ g.send :class_variable_get, 1
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,174 @@
1
+ module Atomy
2
+ module AST
3
+ class Define < Node
4
+ children :pattern, :body
5
+ slots :namespace?
6
+ generate
7
+
8
+ def arguments
9
+ return @arguments if @arguments
10
+
11
+ case pattern
12
+ when BinarySend
13
+ args = [pattern.rhs]
14
+ when Variable, Unary
15
+ args = []
16
+ else
17
+ args = pattern.arguments
18
+ end
19
+
20
+ @arguments = args.collect(&:to_pattern)
21
+ end
22
+
23
+ def receiver
24
+ return @receiver if @receiver
25
+
26
+ case pattern
27
+ when BinarySend
28
+ recv = pattern.lhs
29
+ when Variable
30
+ recv = Primitive.new(pattern.line, :self)
31
+ else
32
+ recv = pattern.receiver
33
+ end
34
+
35
+ @receiver = recv.to_pattern
36
+ end
37
+
38
+ def method_name
39
+ case pattern
40
+ when Variable
41
+ pattern.name
42
+ else
43
+ pattern.method_name
44
+ end
45
+ end
46
+
47
+ def ns_method_name(g)
48
+ if method_name == "initialize"
49
+ g.push_literal :initialize
50
+ return
51
+ end
52
+
53
+ if @namespace
54
+ g.push_literal(
55
+ Atomy.namespaced(@namespace, method_name).to_sym
56
+ )
57
+ return
58
+ end
59
+
60
+ no_ns = g.new_label
61
+ done = g.new_label
62
+
63
+ g.push_cpath_top
64
+ g.find_const :Atomy
65
+ g.push_cpath_top
66
+ g.find_const :Atomy
67
+ g.find_const :Namespace
68
+ g.send :get, 0
69
+ g.dup
70
+ g.gif no_ns
71
+
72
+ g.send :name, 0
73
+ g.send :to_s, 0
74
+ g.push_literal method_name
75
+ g.send :namespaced, 2
76
+ g.goto done
77
+
78
+ no_ns.set!
79
+ g.pop
80
+ g.pop
81
+ g.push_literal method_name
82
+
83
+ done.set!
84
+ end
85
+
86
+ def bytecode(g)
87
+ pos(g)
88
+
89
+ defn = receiver.kind_of?(Patterns::Match) && receiver.value == :self
90
+
91
+ if defn
92
+ g.push_rubinius
93
+ ns_method_name(g)
94
+ g.send :to_sym, 0
95
+ g.dup
96
+ g.push_cpath_top
97
+ g.find_const :Atomy
98
+ g.swap
99
+ else
100
+ g.push_cpath_top
101
+ g.find_const :Atomy
102
+ receiver.target(g)
103
+ ns_method_name(g)
104
+ g.send :to_sym, 0
105
+ end
106
+
107
+ create = g.new_label
108
+ added = g.new_label
109
+ receiver.construct(g)
110
+ arguments.each do |p|
111
+ p.construct(g)
112
+ end
113
+ g.make_array arguments.size
114
+ g.make_array 2
115
+ @body.construct(g, nil)
116
+ g.make_array 2
117
+
118
+ receiver.target(g)
119
+ g.push_literal "@atomy::"
120
+ ns_method_name(g)
121
+ g.string_build 2
122
+ g.send :to_sym, 0
123
+ g.send :instance_variable_get, 1
124
+ g.dup
125
+ g.gif create
126
+
127
+ g.push_cpath_top
128
+ g.find_const :Atomy
129
+ g.move_down 2
130
+ g.send :insert_method, 2
131
+ g.goto added
132
+
133
+ create.set!
134
+ g.pop
135
+ g.make_array 1
136
+ receiver.target(g)
137
+ g.swap
138
+ g.push_literal "@atomy::"
139
+ ns_method_name(g)
140
+ g.string_build 2
141
+ g.send :to_sym, 0
142
+ g.swap
143
+ g.send :instance_variable_set, 2
144
+
145
+ added.set!
146
+
147
+ if defn
148
+ g.push_false
149
+ g.push_scope
150
+ g.send :active_path, 0
151
+ g.push_int @line
152
+ g.send :build_method, 5
153
+ g.push_scope
154
+ g.push_variables
155
+ g.send :method_visibility, 0
156
+ g.send :add_defn_method, 4
157
+ else
158
+ g.push_scope
159
+ g.send :add_method, 4
160
+ end
161
+ end
162
+
163
+ def local_count
164
+ local_names.size
165
+ end
166
+
167
+ def local_names
168
+ arguments.inject(receiver.local_names) do |acc, a|
169
+ acc + a.local_names
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end