atomy 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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