myco 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/lib/myco/bootstrap/component.rb +6 -7
  3. data/lib/myco/bootstrap/instance.rb +14 -9
  4. data/lib/myco/bootstrap/meme.rb +34 -3
  5. data/lib/myco/code_loader.rb +17 -34
  6. data/lib/myco/code_tools/AST/ArgumentAssembly.my +60 -0
  7. data/lib/myco/code_tools/AST/ArgumentAssembly.my.rb +55 -0
  8. data/lib/myco/code_tools/AST/ArrayAssembly.my +43 -0
  9. data/lib/myco/code_tools/AST/ArrayAssembly.my.rb +37 -0
  10. data/lib/myco/code_tools/AST/BlockArgument.my +25 -0
  11. data/lib/myco/code_tools/AST/BlockArgument.my.rb +26 -0
  12. data/lib/myco/code_tools/AST/BlockLiteral.my +104 -0
  13. data/lib/myco/code_tools/AST/BlockLiteral.my.rb +126 -0
  14. data/lib/myco/code_tools/AST/BlockParameter.my +25 -0
  15. data/lib/myco/code_tools/AST/BlockParameter.my.rb +24 -0
  16. data/lib/myco/code_tools/AST/Body.my +18 -0
  17. data/lib/myco/code_tools/AST/Body.my.rb +20 -0
  18. data/lib/myco/code_tools/AST/BranchOperator.my +59 -0
  19. data/lib/myco/code_tools/AST/BranchOperator.my.rb +87 -0
  20. data/lib/myco/code_tools/AST/ConstantAccess.my +30 -0
  21. data/lib/myco/code_tools/AST/ConstantAccess.my.rb +32 -0
  22. data/lib/myco/code_tools/AST/ConstantAssignment.my +40 -0
  23. data/lib/myco/code_tools/AST/ConstantAssignment.my.rb +45 -0
  24. data/lib/myco/code_tools/AST/ConstantDefine.my +30 -0
  25. data/lib/myco/code_tools/AST/ConstantDefine.my.rb +36 -0
  26. data/lib/myco/code_tools/AST/ConstantReopen.my +29 -0
  27. data/lib/myco/code_tools/AST/ConstantReopen.my.rb +35 -0
  28. data/lib/myco/code_tools/AST/DeclareCategory.my +35 -0
  29. data/lib/myco/code_tools/AST/DeclareCategory.my.rb +40 -0
  30. data/lib/myco/code_tools/AST/DeclareDecorator.my +20 -0
  31. data/lib/myco/code_tools/AST/DeclareDecorator.my.rb +28 -0
  32. data/lib/myco/code_tools/AST/DeclareFile.my +38 -0
  33. data/lib/myco/code_tools/AST/DeclareFile.my.rb +53 -0
  34. data/lib/myco/code_tools/AST/DeclareMeme.my +79 -0
  35. data/lib/myco/code_tools/AST/DeclareMeme.my.rb +90 -0
  36. data/lib/myco/code_tools/AST/DeclareObject.my +58 -0
  37. data/lib/myco/code_tools/AST/DeclareObject.my.rb +67 -0
  38. data/lib/myco/code_tools/AST/DeclareString.my +26 -0
  39. data/lib/myco/code_tools/AST/DeclareString.my.rb +30 -0
  40. data/lib/myco/code_tools/AST/DynamicString.my +21 -0
  41. data/lib/myco/code_tools/AST/DynamicString.my.rb +22 -0
  42. data/lib/myco/code_tools/AST/DynamicSymbol.my +22 -0
  43. data/lib/myco/code_tools/AST/DynamicSymbol.my.rb +26 -0
  44. data/lib/myco/code_tools/AST/Invoke.my +37 -0
  45. data/lib/myco/code_tools/AST/Invoke.my.rb +58 -0
  46. data/lib/myco/code_tools/AST/InvokeMethod.my +19 -0
  47. data/lib/myco/code_tools/AST/InvokeMethod.my.rb +25 -0
  48. data/lib/myco/code_tools/AST/KeywordAssembly.my +30 -0
  49. data/lib/myco/code_tools/AST/KeywordAssembly.my.rb +36 -0
  50. data/lib/myco/code_tools/AST/LocalVariableAccessAmbiguous.my +22 -0
  51. data/lib/myco/code_tools/AST/LocalVariableAccessAmbiguous.my.rb +22 -0
  52. data/lib/myco/code_tools/AST/LocalVariableAssignment.my +20 -0
  53. data/lib/myco/code_tools/AST/LocalVariableAssignment.my.rb +20 -0
  54. data/lib/myco/{parser/ast/myco_module_scope.rb → code_tools/AST/MycoModuleScope.my} +32 -39
  55. data/lib/myco/code_tools/AST/MycoModuleScope.my.rb +82 -0
  56. data/lib/myco/code_tools/AST/Node.my +67 -0
  57. data/lib/myco/code_tools/AST/Node.my.rb +84 -0
  58. data/lib/myco/code_tools/AST/ParameterAssembly.my +248 -0
  59. data/lib/myco/code_tools/AST/ParameterAssembly.my.rb +314 -0
  60. data/lib/myco/code_tools/AST/Quest.my +61 -0
  61. data/lib/myco/code_tools/AST/Quest.my.rb +51 -0
  62. data/lib/myco/code_tools/AST/Script.my +27 -0
  63. data/lib/myco/code_tools/AST/Script.my.rb +33 -0
  64. data/lib/myco/code_tools/AST/SplatValue.my +23 -0
  65. data/lib/myco/code_tools/AST/SplatValue.my.rb +25 -0
  66. data/lib/myco/code_tools/AST/StringLiteral.my +17 -0
  67. data/lib/myco/code_tools/AST/StringLiteral.my.rb +16 -0
  68. data/lib/myco/code_tools/AST/SymbolLiteral.my +16 -0
  69. data/lib/myco/code_tools/AST/SymbolLiteral.my.rb +15 -0
  70. data/lib/myco/{parser/ast → code_tools/AST}/ToRuby.my +89 -90
  71. data/lib/myco/{parser/ast → code_tools/AST}/ToRuby.my.rb +89 -101
  72. data/lib/myco/code_tools/AST/misc.my +57 -0
  73. data/lib/myco/code_tools/AST/misc.my.rb +81 -0
  74. data/lib/myco/code_tools/AST.my +52 -0
  75. data/lib/myco/code_tools/AST.my.rb +40 -0
  76. data/lib/myco/{parser → code_tools/parser}/peg_parser.rb +107 -199
  77. data/lib/myco/{parser.rb → code_tools/parser.rb} +0 -17
  78. data/lib/myco/code_tools.rb +5 -0
  79. data/lib/myco/core/BasicDecorators.my +47 -0
  80. data/lib/myco/core/BasicDecorators.my.rb +66 -0
  81. data/lib/myco/core/FileToplevel.my +14 -3
  82. data/lib/myco/core/FileToplevel.my.rb +27 -12
  83. data/lib/myco/eval.rb +7 -37
  84. data/lib/myco/version.rb +1 -4
  85. data/lib/myco.rb +20 -22
  86. metadata +74 -66
  87. data/lib/myco/parser/ast/argument_assembly.rb +0 -76
  88. data/lib/myco/parser/ast/array_assembly.rb +0 -57
  89. data/lib/myco/parser/ast/branch_operator.rb +0 -73
  90. data/lib/myco/parser/ast/constant_access.rb +0 -15
  91. data/lib/myco/parser/ast/constant_define.rb +0 -40
  92. data/lib/myco/parser/ast/constant_reopen.rb +0 -46
  93. data/lib/myco/parser/ast/declare_category.rb +0 -53
  94. data/lib/myco/parser/ast/declare_decorator.rb +0 -35
  95. data/lib/myco/parser/ast/declare_file.rb +0 -54
  96. data/lib/myco/parser/ast/declare_meme.rb +0 -86
  97. data/lib/myco/parser/ast/declare_object.rb +0 -77
  98. data/lib/myco/parser/ast/declare_string.rb +0 -37
  99. data/lib/myco/parser/ast/invoke.rb +0 -48
  100. data/lib/myco/parser/ast/invoke_method.rb +0 -28
  101. data/lib/myco/parser/ast/local_variable_access_ambiguous.rb +0 -34
  102. data/lib/myco/parser/ast/misc.rb +0 -156
  103. data/lib/myco/parser/ast/quest.rb +0 -82
  104. data/lib/myco/parser/ast.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df9a55b04c78564fb8a8f10e94d72c7136fc2bde
4
- data.tar.gz: 6073c4691d0c8d869435b52fc9ccee1f78093bd7
3
+ metadata.gz: c497fbe2e87f23f8cea7374510cbac8a7aefdd6a
4
+ data.tar.gz: 519dc6fbe9d381ee9478ca46fa71fefecd5318b8
5
5
  SHA512:
6
- metadata.gz: 2276b5f604d73476740c3a8357e3ac7a759bbaa71606da9d778a11274550233c59e8cb92a1d47ed362565e56e73a0daffafb053f3ad3320dd5a8b24c095989dc
7
- data.tar.gz: 5c68645cf8199d1f6eb86d9f861ed6fb2812caafaceb1b8b3469cdefb3c91c7205c58eafb3d661a9049cf252034e2bf591e901a602d54b84e0e9977df029441f
6
+ metadata.gz: 6e7dc8c64ae6d9a26b421ba7a45dc5a0ec44f969519e128ebe680701c39d68dd70b6dde54743e99c2c5fb0b2267696c4e119095cead9c41254b1de50d28556a4
7
+ data.tar.gz: 05cf18931bdf1d8632dcf9d7d88e09cc014b8af1e6a86d70f8a2b74395c8210c36d999cb25f4fc0096380618132e09887d4af23aa0130a73724055e0b7029b3d
@@ -18,7 +18,7 @@ module Myco
18
18
  elsif @__name__
19
19
  @__name__.to_s
20
20
  else
21
- "#{@super_components.map(&:to_s).join(',')}" \
21
+ "#{(@super_components || []).map(&:to_s).join(',')}" \
22
22
  "(#{@basename}:#{@line.to_s} 0x#{object_id.to_s 16})"
23
23
  end
24
24
  end
@@ -64,13 +64,12 @@ module Myco
64
64
  all_categories = Hash.new { |h,k| h[k] = Array.new }
65
65
 
66
66
  super_components.each do |other|
67
- raise TypeError, "Got non-Component in supers for new Component: "\
68
- "#{super_components.inspect}" \
69
- unless other.is_a? Component
70
-
71
67
  this.include other
72
- other.categories.each do |name, cat|
73
- all_categories[name] << cat
68
+
69
+ if other.is_a? Component
70
+ other.categories.each do |name, cat|
71
+ all_categories[name] << cat
72
+ end
74
73
  end
75
74
  end
76
75
 
@@ -3,20 +3,16 @@ module Myco
3
3
  module InstanceMethods
4
4
  include ::Kernel
5
5
 
6
- # TODO: clean this up
7
- prepend (::Module.new {
8
- def method_missing name, *args
9
- msg = "#{to_s} has no method called '#{name}'"
10
- ::Kernel.raise ::NoMethodError.new(msg, name, args)
11
- end
12
- })
13
-
14
6
  def to_s
15
7
  "#<#{@component.to_s}>"
16
8
  end
17
9
 
18
10
  def inspect
19
- to_s
11
+ vars = (instance_variables - [:@component]).map { |var|
12
+ [var.to_s[1..-1], instance_variable_get(var).inspect].join(": ")
13
+ }
14
+ vars = vars.any? ? (" " + vars.join(", ")) : ""
15
+ "#<#{@component.to_s}#{vars}>"
20
16
  end
21
17
 
22
18
  # TODO: remove (for now it makes debugging easier with RSpec)
@@ -41,5 +37,14 @@ module Myco
41
37
 
42
38
  class Instance < ::BasicObject
43
39
  include InstanceMethods
40
+
41
+ # # TODO: clean this up
42
+ # prepend (::Module.new {
43
+ def method_missing name, *args
44
+ msg = "#{to_s} has no method called '#{name}'"
45
+ ::Kernel.raise ::NoMethodError.new(msg, name, args)
46
+ end
47
+ # })
48
+
44
49
  end
45
50
  end
@@ -47,6 +47,8 @@ module Myco
47
47
  attr_accessor :cache
48
48
  attr_accessor :var
49
49
  attr_accessor :expose
50
+ attr_accessor :setter
51
+ attr_accessor :getter
50
52
 
51
53
  attr_reader :metadata
52
54
 
@@ -133,6 +135,12 @@ module Myco
133
135
  bind_var_getter
134
136
  bind_var_setter
135
137
  @effective_body = @target.instance_method(@name).executable
138
+ elsif @getter
139
+ bind_var_getter
140
+ @effective_body = @target.instance_method(@name).executable
141
+ elsif @setter
142
+ bind_var_setter
143
+ @effective_body = @target.instance_method(@name).executable
136
144
  elsif @cache
137
145
  bind_cache_method
138
146
  @effective_body = @target.instance_method(@name).executable
@@ -272,7 +280,7 @@ module Myco
272
280
  g.make_array 0
273
281
  g.push_nil
274
282
  g.send :invoke, 5
275
- g.set_ivar(@name)
283
+ g.set_ivar(:"@#{@name}")
276
284
 
277
285
  g.push_true
278
286
  g.set_ivar(:"__#{@name}_defined__")
@@ -280,14 +288,27 @@ module Myco
280
288
  g.goto(ret)
281
289
 
282
290
  get.set!
283
- g.push_ivar(@name)
291
+ g.push_ivar(:"@#{@name}")
284
292
 
285
293
  ret.set!
294
+
295
+ # If this meme has a getter defined, use it
296
+ if self.getter
297
+ g.push_self
298
+ g.push_local(1) # meme
299
+ g.send(:getter, 0)
300
+ g.rotate(3)
301
+ g.send(:call_on_object, 2)
302
+ end
303
+
286
304
  g.ret
287
305
  end
288
306
  end
289
307
 
290
308
  def bind_var_setter
309
+ # TODO: move this bytecode generation to a helper method
310
+ meme = self
311
+
291
312
  # TODO: move this bytecode generation to a helper method
292
313
  target.dynamic_method :"#{@name}=", '(myco_internal)' do |g|
293
314
  g.total_args = 1
@@ -298,7 +319,17 @@ module Myco
298
319
  g.pop
299
320
 
300
321
  g.push_local 0 # value
301
- g.set_ivar @name
322
+
323
+ # If this meme has a setter defined, use it
324
+ if meme.setter
325
+ g.push_self
326
+ g.push_literal(meme)
327
+ g.send(:setter, 0)
328
+ g.rotate(3)
329
+ g.send(:call_on_object, 2)
330
+ end
331
+
332
+ g.set_ivar(:"@#{@name}")
302
333
 
303
334
  g.ret
304
335
  end
@@ -16,12 +16,6 @@ module Myco
16
16
  # Use generated ruby files only when Myco files cannot be found or loaded.
17
17
  self.precedence = [:rbc, :myco, :rb]
18
18
 
19
- # TODO: a more elegant solution than env vars
20
- # Emit ruby if env var indicates
21
- # Load from ruby exclusively if env var indicates
22
- self.emit_rb = true if ENV['MYCO_TO_RUBY'] == 'PRE'
23
- self.precedence = [:myco] if ENV['MYCO_TO_RUBY'] == 'PRE'
24
-
25
19
  # Try to resolve the given file path
26
20
  # in the current working directory or in the given load paths.
27
21
  def self.resolve_file path, load_paths=[]
@@ -136,10 +130,10 @@ module Myco
136
130
  def make_ast
137
131
  @string || make_string
138
132
 
139
- parser = parser_type.new(@filename, @line, [])
133
+ parser = new_parser
140
134
  ast = parser.parse_string(@string)
141
135
 
142
- ast = ast_root_type.new(ast) if ast_root_type
136
+ ast = ast_root_for(ast)
143
137
  ast.file = filename.to_sym
144
138
  ast.variable_scope = @variable_scope
145
139
 
@@ -149,7 +143,7 @@ module Myco
149
143
  def make_generator
150
144
  @ast || make_ast
151
145
 
152
- g = generator_type.new
146
+ g = new_generator
153
147
  @ast.bytecode(g)
154
148
 
155
149
  g.close
@@ -206,7 +200,7 @@ module Myco
206
200
  return nil unless filename
207
201
 
208
202
  compiled_file_type.dump(
209
- @compiled_code, filename, Rubinius::Signature, 0
203
+ @compiled_code, filename, Rubinius::Signature, Rubinius::RUBY_LIB_VERSION
210
204
  )
211
205
  end
212
206
 
@@ -249,22 +243,16 @@ module Myco
249
243
  end
250
244
 
251
245
  class MycoLoader < AbstractLoader
252
- def initialize *args
253
- # TODO: a more elegant solution than env vars
254
- raise NotImplementedError if ENV['MYCO_TO_RUBY'] == 'POST'
255
- super
256
- end
257
-
258
- def ast_root_type
259
- Myco::ToolSet::AST::EvalExpression
246
+ def ast_root_for(body)
247
+ Myco::ToolSet::AST::Script.new(body: body)
260
248
  end
261
249
 
262
- def parser_type
263
- Myco::ToolSet::Parser
250
+ def new_parser
251
+ Myco::ToolSet::Parser.new
264
252
  end
265
253
 
266
- def generator_type
267
- Myco::ToolSet::Generator
254
+ def new_generator
255
+ Myco::ToolSet::Generator.new
268
256
  end
269
257
 
270
258
  def compiled_file_type
@@ -281,16 +269,16 @@ module Myco
281
269
  super *args
282
270
  end
283
271
 
284
- def ast_root_type
285
- Rubinius::ToolSets::Runtime::AST::EvalExpression
272
+ def ast_root_for(body)
273
+ Rubinius::ToolSets::Runtime::AST::EvalExpression.new(body)
286
274
  end
287
275
 
288
- def parser_type
289
- Rubinius::ToolSets::Runtime::Melbourne
276
+ def new_parser
277
+ Rubinius::ToolSets::Runtime::Melbourne.new(@filename, @line, [])
290
278
  end
291
279
 
292
- def generator_type
293
- Rubinius::ToolSets::Runtime::Generator
280
+ def new_generator
281
+ Rubinius::ToolSets::Runtime::Generator.new
294
282
  end
295
283
 
296
284
  def compiled_file_type
@@ -304,17 +292,12 @@ module Myco
304
292
  def emit_rb!; nil end
305
293
  def emit_rbc!; nil end
306
294
 
307
- def initialize *args
308
- # TODO: a more elegant solution than env vars
309
- raise NotImplementedError if ENV['MYCO_TO_RUBY'] == 'POST'
310
- super
311
- end
312
-
313
295
  def make_compiled_code
314
296
  begin
315
297
  @compiled_code = primitive_load_file \
316
298
  @filename, Rubinius::Signature, Rubinius::RUBY_LIB_VERSION
317
299
  rescue Rubinius::InvalidRBC => e
300
+ warn e.message
318
301
  File.delete @filename
319
302
  raise e
320
303
  end
@@ -0,0 +1,60 @@
1
+
2
+ CodeTools::AST << {
3
+
4
+ ArgumentAssembly < Node {
5
+ var body, var block
6
+
7
+ Form: [:argass, :body]
8
+
9
+ setter body: |given_body| {
10
+ given_body.last.is_a?(BlockArgument) && (self.block = given_body.pop)
11
+ given_body
12
+ }
13
+
14
+ # All items before the first SplatValue
15
+ pre_group:
16
+ self.body.take_while |item| { !item.is_a?(SplatValue) }
17
+
18
+ # All items after and including the first SplatValue
19
+ post_group:
20
+ self.body.drop_while |item| { !item.is_a?(SplatValue) }
21
+
22
+ # Symbol of bytecode operation to use for send
23
+ send_op: {
24
+ self.body.detect |item| { item.is_a?(SplatValue) } &? (
25
+ :send_with_splat
26
+ ) ?? (self.block &? ( # TODO: better elsif construction
27
+ :send_with_block
28
+ ) ?? (
29
+ :send
30
+ ))
31
+ }
32
+
33
+ # Number of arguments to use for send operation
34
+ send_count:
35
+ pre_group.size
36
+
37
+ splat_bytecode: |g| ArrayAssembly.new(
38
+ line: self.line
39
+ body: post_group
40
+ ).bytecode(g)
41
+
42
+ block_bytecode: |g|
43
+ self.block &? self.block.bytecode(g) ?? g.push_null
44
+
45
+ bytecode: |g| {
46
+ pos(g)
47
+
48
+ pre_group.each |item| { item.bytecode(g) }
49
+
50
+ send_op == :send_with_splat && (
51
+ splat_bytecode(g)
52
+ block_bytecode(g)
53
+ )
54
+ send_op == :send_with_block && (
55
+ block_bytecode(g)
56
+ )
57
+ }
58
+ }
59
+
60
+ }
@@ -0,0 +1,55 @@
1
+
2
+ ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.find_constant(:CodeTools)::AST.component_eval {(::Myco.cscope.for_method_definition.const_set(:ArgumentAssembly, ::Myco::Component.new([::Myco.find_constant(:Node)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
+ declare_meme(:body, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
6
+ declare_meme(:block, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
7
+ ::Myco.cscope.for_method_definition.const_set(:Form, ([
8
+ :argass,
9
+ :body
10
+ ]))
11
+ declare_meme(:body, [[:setter, []]], nil, ::Myco.cscope.dup) { |given_body| (
12
+ ::Myco.branch_op(:"&&", given_body.last.__send__(
13
+ :is_a?,
14
+ ::Myco.find_constant(:BlockArgument)
15
+ )) {self.__send__(
16
+ :block=,
17
+ given_body.pop
18
+ )}
19
+ given_body
20
+ )}
21
+ declare_meme(:pre_group, [], nil, ::Myco.cscope.dup) { |*| (self.body.take_while { |item| (item.__send__(
22
+ :is_a?,
23
+ ::Myco.find_constant(:SplatValue)
24
+ ).__send__(:!))})}
25
+ declare_meme(:post_group, [], nil, ::Myco.cscope.dup) { |*| (self.body.drop_while { |item| (item.__send__(
26
+ :is_a?,
27
+ ::Myco.find_constant(:SplatValue)
28
+ ).__send__(:!))})}
29
+ declare_meme(:send_op, [], nil, ::Myco.cscope.dup) { |*| (::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", self.body.detect { |item| (item.__send__(
30
+ :is_a?,
31
+ ::Myco.find_constant(:SplatValue)
32
+ ))}) {:send_with_splat}) {::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", self.block) {:send_with_block}) {:send}})}
33
+ declare_meme(:send_count, [], nil, ::Myco.cscope.dup) { |*| (self.pre_group.size)}
34
+ declare_meme(:splat_bytecode, [], nil, ::Myco.cscope.dup) { |g| (::Myco.find_constant(:ArrayAssembly).new({
35
+ :line => self.line,
36
+ :body => self.post_group
37
+ }).bytecode(g))}
38
+ declare_meme(:block_bytecode, [], nil, ::Myco.cscope.dup) { |g| (::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", self.block) {self.block.bytecode(g)}) {g.push_null})}
39
+ declare_meme(:bytecode, [], nil, ::Myco.cscope.dup) { |g| (
40
+ self.pos(g)
41
+ self.pre_group.each { |item| (item.bytecode(g))}
42
+ ::Myco.branch_op(:"&&", self.send_op.__send__(
43
+ :==,
44
+ :send_with_splat
45
+ )) {(
46
+ self.splat_bytecode(g)
47
+ self.block_bytecode(g)
48
+ )}
49
+ ::Myco.branch_op(:"&&", self.send_op.__send__(
50
+ :==,
51
+ :send_with_block
52
+ )) {self.block_bytecode(g)}
53
+ )}
54
+ )}})
55
+ .tap { |__c__| __c__.__name__ = :ArgumentAssembly })})}}.instance
@@ -0,0 +1,43 @@
1
+
2
+ CodeTools::AST << {
3
+
4
+ ArrayAssembly < Node {
5
+ var body
6
+
7
+ Form: [:arrass, :body]
8
+
9
+ bytecode: |g| {
10
+ pos(g)
11
+
12
+ self.body.empty? &? (
13
+ g.make_array(0)
14
+ ) ?? (
15
+ # Group the self.body into chunks of splats and non-splats
16
+ chunked = self.body.chunk |item| { item.is_a?(SplatValue) }
17
+
18
+ # Each SplatValue outputs the bytecode of a single array
19
+ # Non-SplatValues are grouped to output the bytecode of
20
+ # a single array for each contiguous group. Along the way, the
21
+ # arrays are concatenated to form one final array on the stack.
22
+ first_bytecode = true
23
+ chunked.each |is_splat_group, group| {
24
+ is_splat_group &? (
25
+ group.each |item| {
26
+ item.bytecode(g)
27
+ first_bytecode || g.send(:concat, 1)
28
+ first_bytecode = false
29
+ }
30
+ ) ?? (
31
+ group.each |item| {
32
+ item.bytecode(g)
33
+ }
34
+ g.make_array(group.size)
35
+ first_bytecode || g.send(:concat, 1)
36
+ first_bytecode = false
37
+ )
38
+ }
39
+ )
40
+ }
41
+ }
42
+
43
+ }
@@ -0,0 +1,37 @@
1
+
2
+ ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.find_constant(:CodeTools)::AST.component_eval {(::Myco.cscope.for_method_definition.const_set(:ArrayAssembly, ::Myco::Component.new([::Myco.find_constant(:Node)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
+ declare_meme(:body, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
6
+ ::Myco.cscope.for_method_definition.const_set(:Form, ([
7
+ :arrass,
8
+ :body
9
+ ]))
10
+ declare_meme(:bytecode, [], nil, ::Myco.cscope.dup) { |g| (
11
+ self.pos(g)
12
+ ::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", self.body.__send__(:empty?)) {g.make_array(0)}) {(
13
+ chunked = self.body.chunk { |item| (item.__send__(
14
+ :is_a?,
15
+ ::Myco.find_constant(:SplatValue)
16
+ ))}
17
+ first_bytecode = true
18
+ chunked.each { |is_splat_group, group| (::Myco.branch_op(:"??", ::Myco.branch_op(:"&?", is_splat_group) {group.each { |item| (
19
+ item.bytecode(g)
20
+ ::Myco.branch_op(:"||", first_bytecode) {g.send(
21
+ :concat,
22
+ 1
23
+ )}
24
+ first_bytecode = false
25
+ )}}) {(
26
+ group.each { |item| (item.bytecode(g))}
27
+ g.make_array(group.size)
28
+ ::Myco.branch_op(:"||", first_bytecode) {g.send(
29
+ :concat,
30
+ 1
31
+ )}
32
+ first_bytecode = false
33
+ )})}
34
+ )}
35
+ )}
36
+ )}})
37
+ .tap { |__c__| __c__.__name__ = :ArrayAssembly })})}}.instance
@@ -0,0 +1,25 @@
1
+
2
+ CodeTools::AST << {
3
+
4
+ BlockArgument < Node {
5
+ var body
6
+
7
+ Form: [:blkarg, :body]
8
+
9
+ bytecode: |g| {
10
+ self.body.bytecode(g)
11
+
12
+ done_label = g.new_label
13
+ g.dup
14
+ g.is_nil
15
+ g.goto_if_true(done_label)
16
+
17
+ g.push_cpath_top; g.find_const(:"Proc")
18
+ g.swap
19
+ g.send(:"__from_block__", 1)
20
+
21
+ done_label.set!
22
+ }
23
+ }
24
+
25
+ }
@@ -0,0 +1,26 @@
1
+
2
+ ::Myco::Component.new([::Myco::FileToplevel], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
3
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(::Myco.find_constant(:CodeTools)::AST.component_eval {(::Myco.cscope.for_method_definition.const_set(:BlockArgument, ::Myco::Component.new([::Myco.find_constant(:Node)], ::Myco.cscope.for_method_definition, __FILE__, __LINE__)
4
+ .tap { |__c__| __c__.__last__ = __c__.component_eval {(
5
+ declare_meme(:body, [[:var, []]], nil, ::Myco.cscope.dup) { |*| nil}
6
+ ::Myco.cscope.for_method_definition.const_set(:Form, ([
7
+ :blkarg,
8
+ :body
9
+ ]))
10
+ declare_meme(:bytecode, [], nil, ::Myco.cscope.dup) { |g| (
11
+ self.body.bytecode(g)
12
+ done_label = g.new_label
13
+ g.dup
14
+ g.is_nil
15
+ g.goto_if_true(done_label)
16
+ g.push_cpath_top
17
+ g.find_const(:Proc)
18
+ g.swap
19
+ g.send(
20
+ :__from_block__,
21
+ 1
22
+ )
23
+ done_label.__send__(:set!)
24
+ )}
25
+ )}})
26
+ .tap { |__c__| __c__.__name__ = :BlockArgument })})}}.instance
@@ -0,0 +1,104 @@
1
+
2
+ CodeTools::AST << {
3
+
4
+ BlockLiteral < CodeTools::Compiler::LocalVariables, Node {
5
+ var parameters, var body
6
+ var parent # TODO: investigate removing
7
+
8
+ Form: [:blklit, :parameters, :body]
9
+
10
+ CompilerClass: CodeTools::Compiler # TODO: remove this
11
+
12
+ setter parameters: |given| given || ParameterAssembly.new(line:self.line)
13
+ setter body: |given| given || NullLiteral.new(line:self.line)
14
+
15
+ locals: self.body.?locals.?body.map(&:value) ?? null
16
+
17
+ block_local?: |name|
18
+ locals.?include?(name) ?? false
19
+
20
+ module?: false
21
+
22
+ nest_scope: |scope| scope.parent = self
23
+
24
+ # Look up a local variable in this block's scope.
25
+ search_local: |name| {
26
+ (variable = self.variables[name]) &? (
27
+ variable.nested_reference
28
+ ) ?? (self.block_local?(name) &? (
29
+ self.new_local(name)
30
+ ) ?? ((reference = self.parent.search_local(name)) &? (
31
+ reference.depth = reference.depth + 1
32
+ reference
33
+ ) ?? (
34
+ null
35
+ )))
36
+ }
37
+
38
+ # Assign a slot number to a local variable access node.
39
+ # TODO: remove this method in favor of using search_local in all cases instead.
40
+ assign_local_reference: |var| {
41
+ var.variable = (variable = self.variables[var.name]) &? (
42
+ variable.reference
43
+ ) ?? (self.block_local?(var.name) &? (
44
+ variable = self.new_local(var.name)
45
+ variable.reference
46
+ ) ?? ((reference = self.parent.search_local(var.name)) &? (
47
+ reference.depth = reference.depth + 1
48
+ reference
49
+ ) ?? (
50
+ variable = self.new_local(var.name)
51
+ variable.reference
52
+ )))
53
+ }
54
+
55
+ new_local: |name| {
56
+ self.variables[name] = \
57
+ self.variables[name] || CompilerClass::LocalVariable.new(allocate_slot)
58
+ }
59
+
60
+ new_nested_local: |name| new_local(name).nested_reference
61
+
62
+ bytecode: |g| {
63
+ pos(g)
64
+
65
+ state = g.state
66
+ state.scope.nest_scope(self)
67
+
68
+ blk = new_block_generator(g, self.parameters)
69
+
70
+ blk.push_state(self)
71
+ blk.definition_line(self.line)
72
+ blk.state.push_super(state.super)
73
+ blk.state.push_eval(state.eval)
74
+
75
+ blk.state.push_name(blk.name)
76
+
77
+ # Push line info down.
78
+ pos(blk)
79
+
80
+ self.parameters.bytecode(blk)
81
+
82
+ blk.state.push_block
83
+ blk.push_modifiers
84
+ blk.break = null
85
+ blk.next = null
86
+ blk.redo = blk.new_label
87
+ blk.redo.set!
88
+
89
+ self.body.bytecode(blk)
90
+
91
+ blk.pop_modifiers
92
+ blk.state.pop_block
93
+ blk.ret
94
+ blk.close
95
+ blk.pop_state
96
+
97
+ blk.local_count = local_count
98
+ blk.local_names = local_names
99
+
100
+ g.create_block(blk)
101
+ }
102
+ }
103
+
104
+ }