myco 0.1.0.dev → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/LICENSE +1 -1
- data/README.md +79 -0
- data/lib/myco/backtrace.rb +1 -1
- data/lib/myco/bootstrap/component.rb +78 -39
- data/lib/myco/bootstrap/find_constant.rb +12 -1
- data/lib/myco/bootstrap/instance.rb +5 -12
- data/lib/myco/bootstrap/meme.rb +176 -28
- data/lib/myco/bootstrap.my +8 -7
- data/lib/myco/code_loader.rb +332 -0
- data/lib/myco/command/inoculate.my +83 -0
- data/lib/myco/command.my +26 -26
- data/lib/myco/core/BasicDecorators.my +62 -0
- data/lib/myco/core/BasicObject.my +12 -34
- data/lib/myco/core/Decorator.my +1 -0
- data/lib/myco/core/FileToplevel.my +0 -3
- data/lib/myco/core/Myco.my +4 -0
- data/lib/myco/core/Object.my +6 -4
- data/lib/myco/eval.rb +17 -18
- data/lib/myco/misc.rb +16 -0
- data/lib/myco/parser/ast/argument_assembly.rb +76 -0
- data/lib/myco/parser/ast/array_assembly.rb +57 -0
- data/lib/myco/parser/ast/branch_operator.rb +73 -0
- data/lib/myco/parser/ast/constant_access.rb +4 -18
- data/lib/myco/parser/ast/constant_define.rb +3 -3
- data/lib/myco/parser/ast/constant_reopen.rb +12 -13
- data/lib/myco/parser/ast/declare_category.rb +8 -6
- data/lib/myco/parser/ast/declare_decorator.rb +4 -4
- data/lib/myco/parser/ast/declare_file.rb +4 -4
- data/lib/myco/parser/ast/declare_meme.rb +53 -11
- data/lib/myco/parser/ast/declare_object.rb +9 -7
- data/lib/myco/parser/ast/declare_string.rb +5 -5
- data/lib/myco/parser/ast/invoke.rb +18 -36
- data/lib/myco/parser/ast/invoke_method.rb +28 -0
- data/lib/myco/parser/ast/local_variable_access_ambiguous.rb +9 -13
- data/lib/myco/parser/ast/misc.rb +128 -33
- data/lib/myco/parser/ast/myco_module_scope.rb +26 -0
- data/lib/myco/parser/ast/quest.rb +3 -3
- data/lib/myco/parser/ast/to_ruby/array_assembly.rb +15 -0
- data/lib/myco/parser/ast/to_ruby/block.rb +14 -0
- data/lib/myco/parser/ast/to_ruby/block_pass.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/branch_operator.rb +9 -0
- data/lib/myco/parser/ast/to_ruby/constant_access.rb +10 -0
- data/lib/myco/parser/ast/to_ruby/constant_assignment.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/constant_define.rb +9 -0
- data/lib/myco/parser/ast/to_ruby/constant_reopen.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/declare_category.rb +7 -0
- data/lib/myco/parser/ast/to_ruby/declare_decorator.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/declare_file.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/declare_meme.rb +16 -0
- data/lib/myco/parser/ast/to_ruby/declare_object.rb +8 -0
- data/lib/myco/parser/ast/to_ruby/declare_string.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/dynamic_string.rb +14 -0
- data/lib/myco/parser/ast/to_ruby/dynamic_symbol.rb +7 -0
- data/lib/myco/parser/ast/to_ruby/eval_expression.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/false_literal.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/hash_literal.rb +16 -0
- data/lib/myco/parser/ast/to_ruby/invoke.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/invoke_method.rb +35 -0
- data/lib/myco/parser/ast/to_ruby/iter.rb +10 -0
- data/lib/myco/parser/ast/to_ruby/local_variable_access_ambiguous.rb +16 -0
- data/lib/myco/parser/ast/to_ruby/local_variable_assignment.rb +8 -0
- data/lib/myco/parser/ast/to_ruby/myco_module_scope.rb +8 -0
- data/lib/myco/parser/ast/to_ruby/null_literal.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/parameters.rb +60 -0
- data/lib/myco/parser/ast/to_ruby/quest.rb +13 -0
- data/lib/myco/parser/ast/to_ruby/return.rb +7 -0
- data/lib/myco/parser/ast/to_ruby/scoped_constant.rb +11 -0
- data/lib/myco/parser/ast/to_ruby/self.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/splat_value.rb +33 -0
- data/lib/myco/parser/ast/to_ruby/string_literal.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/symbol_literal.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/toplevel_constant.rb +11 -0
- data/lib/myco/parser/ast/to_ruby/true_literal.rb +6 -0
- data/lib/myco/parser/ast/to_ruby/void_literal.rb +6 -0
- data/lib/myco/parser/ast/to_ruby.rb +138 -0
- data/lib/myco/parser/ast.rb +6 -0
- data/lib/myco/parser/peg_parser.rb +361 -181
- data/lib/myco/parser.rb +27 -11
- data/lib/myco/tools/BasicCommand.my +42 -0
- data/lib/myco/tools/Generator.my +18 -0
- data/lib/myco/toolset.rb +0 -3
- data/lib/myco/version.rb +1 -4
- data/lib/myco.rb +2 -0
- metadata +230 -160
- data/lib/myco/parser/builder.output +0 -3995
- data/lib/myco/parser/builder.racc +0 -585
- data/lib/myco/parser/builder.rb +0 -1592
- data/lib/myco/parser/lexer.rb +0 -2306
- data/lib/myco/parser/lexer.rl +0 -393
- data/lib/myco/parser/lexer_char_classes.rl +0 -56
- data/lib/myco/parser/lexer_common.rb +0 -95
- data/lib/myco/parser/lexer_skeleton.rl +0 -154
- data/lib/myco/parser/peg_parser.kpeg +0 -759
- data/lib/myco/tools/OptionParser.my +0 -38
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
2
|
module CodeTools::AST
|
3
3
|
|
4
|
-
module
|
5
|
-
def
|
6
|
-
LocalVariableAccessAmbiguous.new line, name
|
4
|
+
module BuilderMethods
|
5
|
+
def lambig loc, name
|
6
|
+
LocalVariableAccessAmbiguous.new loc.line, name
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
@@ -18,21 +18,17 @@ module CodeTools::AST
|
|
18
18
|
def bytecode g
|
19
19
|
pos(g)
|
20
20
|
|
21
|
-
|
21
|
+
local = g.state.scope.search_local @name
|
22
|
+
return local.get_bytecode(g) if local
|
23
|
+
|
24
|
+
rcvr = Self.new @line
|
25
|
+
send = Send.new @line, rcvr, @name, true, true
|
26
|
+
send.bytecode(g)
|
22
27
|
end
|
23
28
|
|
24
29
|
def to_sexp
|
25
30
|
[:lambig, @name]
|
26
31
|
end
|
27
|
-
|
28
|
-
def implementation g
|
29
|
-
if g.state.scope.variables.has_key? @name
|
30
|
-
LocalVariableAccess.new @line, @name
|
31
|
-
else
|
32
|
-
rcvr = Self.new @line
|
33
|
-
Send.new @line, rcvr, @name, true, true
|
34
|
-
end
|
35
|
-
end
|
36
32
|
end
|
37
33
|
|
38
34
|
end
|
data/lib/myco/parser/ast/misc.rb
CHANGED
@@ -1,13 +1,127 @@
|
|
1
1
|
|
2
2
|
module CodeTools::AST
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# These builder methods are copied directly from rubinius-processor
|
5
|
+
# TODO: remove and Myco-ize all dependencies on rubinius-processor and rubinius-ast
|
6
|
+
module BuilderMethods
|
7
|
+
def colon2 loc, outer, name
|
8
|
+
if outer
|
9
|
+
if outer.kind_of? ConstantAccess and
|
10
|
+
outer.name == :Rubinius
|
11
|
+
case name
|
12
|
+
when :Type
|
13
|
+
TypeConstant.new loc.line
|
14
|
+
when :Mirror
|
15
|
+
MirrorConstant.new loc.line
|
16
|
+
else
|
17
|
+
ScopedConstant.new loc.line, outer, name
|
18
|
+
end
|
19
|
+
else
|
20
|
+
ScopedConstant.new loc.line, outer, name
|
21
|
+
end
|
22
|
+
else
|
23
|
+
ConstantAccess.new loc.line, name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def colon3 loc, name
|
28
|
+
ToplevelConstant.new loc.line, name
|
29
|
+
end
|
30
|
+
|
31
|
+
def const loc, name
|
32
|
+
ConstantAccess.new loc.line, name
|
33
|
+
end
|
34
|
+
|
35
|
+
def lit loc, sym
|
36
|
+
SymbolLiteral.new loc.line, sym
|
37
|
+
end
|
38
|
+
|
39
|
+
def args loc, required, optional, splat, post, kwargs, kwrest, block
|
40
|
+
Parameters.new loc.line, required, optional, splat, post, kwargs, kwrest, block
|
41
|
+
end
|
42
|
+
|
43
|
+
def self loc
|
44
|
+
Self.new loc.line
|
45
|
+
end
|
46
|
+
|
47
|
+
def block loc, array
|
48
|
+
Block.new loc.line, array
|
49
|
+
end
|
50
|
+
|
51
|
+
def str loc, str
|
52
|
+
StringLiteral.new loc.line, str
|
53
|
+
end
|
54
|
+
|
55
|
+
def splat loc, expr
|
56
|
+
SplatValue.new loc.line, expr
|
57
|
+
end
|
58
|
+
|
59
|
+
def block_pass loc, arguments, body
|
60
|
+
BlockPass19.new loc.line, arguments, body
|
61
|
+
end
|
62
|
+
|
63
|
+
def evstr loc, value
|
64
|
+
if value
|
65
|
+
ToString.new loc.line, value
|
66
|
+
else
|
67
|
+
StringLiteral.new loc.line, ""
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def dsym loc, str, array
|
72
|
+
DynamicSymbol.new loc.line, str, array
|
73
|
+
end
|
74
|
+
|
75
|
+
def dstr loc, str, array
|
76
|
+
DynamicString.new loc.line, str, array
|
7
77
|
end
|
8
78
|
|
9
|
-
def
|
10
|
-
|
79
|
+
def true loc
|
80
|
+
TrueLiteral.new loc.line
|
81
|
+
end
|
82
|
+
|
83
|
+
def false loc
|
84
|
+
FalseLiteral.new loc.line
|
85
|
+
end
|
86
|
+
|
87
|
+
def return loc, value
|
88
|
+
Return.new loc.line, value
|
89
|
+
end
|
90
|
+
|
91
|
+
def lasgn loc, name, value
|
92
|
+
LocalVariableAssignment.new loc.line, name, value
|
93
|
+
end
|
94
|
+
|
95
|
+
def hash loc, array
|
96
|
+
HashLiteral.new loc.line, array
|
97
|
+
end
|
98
|
+
|
99
|
+
def cdecl loc, expr, value
|
100
|
+
ConstantAssignment.new loc.line, expr, value
|
101
|
+
end
|
102
|
+
|
103
|
+
def op_cdecl loc, var, value, op
|
104
|
+
op_value = case op
|
105
|
+
when :and
|
106
|
+
And.new loc.line, var, value
|
107
|
+
when :or
|
108
|
+
Or.new loc.line, var, value
|
109
|
+
else
|
110
|
+
args = ArrayLiteral.new loc.line, [value]
|
111
|
+
SendWithArguments.new loc.line, var, op, args
|
112
|
+
end
|
113
|
+
ConstantAssignment.new loc.line, var, op_value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# These builder methods process the null and void literals
|
118
|
+
module BuilderMethods
|
119
|
+
def null loc
|
120
|
+
NullLiteral.new loc.line
|
121
|
+
end
|
122
|
+
|
123
|
+
def void loc
|
124
|
+
VoidLiteral.new loc.line
|
11
125
|
end
|
12
126
|
end
|
13
127
|
|
@@ -20,14 +134,18 @@ module CodeTools::AST
|
|
20
134
|
# Replace NilLiteral with NullLiteral and let original NilLiteral "disappear"
|
21
135
|
NilLiteral = NullLiteral
|
22
136
|
|
137
|
+
class ::CodeTools::Generator
|
138
|
+
def push_void
|
139
|
+
push_cpath_top
|
140
|
+
find_const :Myco
|
141
|
+
find_const :Void
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
23
145
|
class VoidLiteral < Node
|
24
146
|
def bytecode(g)
|
25
147
|
pos(g)
|
26
|
-
|
27
|
-
# TODO: create push_void helper to abstract this out (and elsewhere)
|
28
|
-
g.push_cpath_top
|
29
|
-
g.find_const :Myco
|
30
|
-
g.find_const :Void
|
148
|
+
g.push_void
|
31
149
|
end
|
32
150
|
|
33
151
|
def to_sexp
|
@@ -35,27 +153,4 @@ module CodeTools::AST
|
|
35
153
|
end
|
36
154
|
end
|
37
155
|
|
38
|
-
|
39
|
-
# Patch the And (and Or) Node bytecode to use .false? to determine falsehood
|
40
|
-
# This accomodates treating Void (or any other non-builtin) as falsey
|
41
|
-
# TODO: use new branch instruction when it gets added to Rubinius
|
42
|
-
class And
|
43
|
-
def bytecode(g, use_git=true)
|
44
|
-
@left.bytecode(g)
|
45
|
-
g.dup
|
46
|
-
lbl = g.new_label
|
47
|
-
|
48
|
-
g.send :false?, 0
|
49
|
-
if use_git
|
50
|
-
g.git lbl
|
51
|
-
else
|
52
|
-
g.gif lbl
|
53
|
-
end
|
54
|
-
|
55
|
-
g.pop
|
56
|
-
@right.bytecode(g)
|
57
|
-
lbl.set!
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
156
|
end
|
@@ -11,6 +11,11 @@ module CodeTools::AST
|
|
11
11
|
def bytecode(g)
|
12
12
|
pos(g)
|
13
13
|
|
14
|
+
# Register in the AST as a scope for local variable lookup
|
15
|
+
# Right now, this just sets @parent to g.state.scope
|
16
|
+
# (Necessary to pass local variables from above to memes below)
|
17
|
+
g.state.scope.nest_scope self
|
18
|
+
|
14
19
|
attach_and_call g, :__myco_module_init__, true
|
15
20
|
end
|
16
21
|
|
@@ -53,6 +58,27 @@ module CodeTools::AST
|
|
53
58
|
def body_bytecode g
|
54
59
|
@body.bytecode g
|
55
60
|
end
|
61
|
+
|
62
|
+
include CodeTools::Compiler::LocalVariables
|
63
|
+
|
64
|
+
# Become the AST scope parent of the given AST scope Node .
|
65
|
+
# This is only for the benefit of LocalVariableAccessAmbiguous
|
66
|
+
# being able to call search_local, and has nothing to do with
|
67
|
+
# the scope referenced by g.push_scope or g.add_scope
|
68
|
+
def nest_scope scope
|
69
|
+
scope.parent = self
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_accessor :parent
|
73
|
+
|
74
|
+
# This is an abbreviated form of Iter#search_local
|
75
|
+
# because no locals can be assigned within the MycoModuleScope
|
76
|
+
def search_local name
|
77
|
+
if reference = @parent.search_local(name)
|
78
|
+
reference.depth += 1
|
79
|
+
reference
|
80
|
+
end
|
81
|
+
end
|
56
82
|
end
|
57
83
|
|
58
84
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::ArrayAssembly
|
3
|
+
def to_ruby g
|
4
|
+
if @body.empty?
|
5
|
+
g.add("[]")
|
6
|
+
else
|
7
|
+
g.add("[")
|
8
|
+
g.push_indent
|
9
|
+
@body[0...-1].each { |item| g.line(item); g.add(",") }
|
10
|
+
@body.last.tap { |item| g.line(item) }
|
11
|
+
g.pop_indent
|
12
|
+
g.line("]")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::DeclareMeme
|
3
|
+
def to_ruby g
|
4
|
+
g.with_nested_var_scope(body_implementation) {
|
5
|
+
g.var_scope_declare_locals(@arguments.names)
|
6
|
+
|
7
|
+
g.add("declare_meme(")
|
8
|
+
g.add("#{@name.inspect}, ")
|
9
|
+
g.add(@decorations); g.add(", nil, ::Myco.cscope.dup)")
|
10
|
+
g.add(" { ");
|
11
|
+
g.add(@arguments); g.add(" ")
|
12
|
+
g.add(@body);
|
13
|
+
g.add("}")
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::DeclareObject
|
3
|
+
def to_ruby g
|
4
|
+
g.add("::Myco::Component.new("); g.add(@types); g.add(", ::Myco.cscope.for_method_definition, __FILE__, __LINE__)")
|
5
|
+
g.line(".tap { |__c__| __c__.__last__ = __c__.component_eval {"); g.add(scope_implementation); g.add("}}")
|
6
|
+
g.add(".instance") if @create
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::DynamicString
|
3
|
+
def to_ruby g
|
4
|
+
inspect_escape = Proc.new { |str| str.inspect[1...-1] }
|
5
|
+
|
6
|
+
g.add('"')
|
7
|
+
g.add(inspect_escape.call(@string))
|
8
|
+
@array.each_slice(2) { |interpolated, inner_string|
|
9
|
+
g.add('#{'); g.add(interpolated.value); g.add('}')
|
10
|
+
g.add(inspect_escape.call(inner_string.value))
|
11
|
+
}
|
12
|
+
g.add('"')
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::HashLiteral
|
3
|
+
def to_ruby g
|
4
|
+
list = @array.each_slice(2).to_a
|
5
|
+
if list.empty?
|
6
|
+
g.add("{}")
|
7
|
+
else
|
8
|
+
g.add("{")
|
9
|
+
g.push_indent
|
10
|
+
list[0...-1].each { |key, value| g.line(key); g.add(" => "); g.add(value); g.add(",") }
|
11
|
+
list.last.tap { |key, value| g.line(key); g.add(" => "); g.add(value) }
|
12
|
+
g.pop_indent
|
13
|
+
g.line("}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
class InvokeMethod
|
4
|
+
def to_ruby g
|
5
|
+
list = @arguments ? @arguments.body.dup : []
|
6
|
+
list.push(@arguments.block) if @arguments.block.is_a?(BlockPass)
|
7
|
+
|
8
|
+
g.add(@receiver)
|
9
|
+
|
10
|
+
if g.easy_ident?(@name)
|
11
|
+
g.add(".#{@name}")
|
12
|
+
else
|
13
|
+
g.add(".__send__")
|
14
|
+
list.unshift(SymbolLiteral.new(@line, @name))
|
15
|
+
end
|
16
|
+
|
17
|
+
if list.empty?
|
18
|
+
g.add("")
|
19
|
+
elsif list.size == 1
|
20
|
+
g.add("("); g.add(list.first); g.add(")")
|
21
|
+
else
|
22
|
+
g.add("(")
|
23
|
+
g.push_indent
|
24
|
+
list[0...-1].each { |item| g.line(item); g.add(",") }
|
25
|
+
list.last.tap { |item| g.line(item) }
|
26
|
+
g.pop_indent
|
27
|
+
g.line(")")
|
28
|
+
end
|
29
|
+
|
30
|
+
if @arguments.block.is_a?(Iter)
|
31
|
+
(g.add(" {"); g.add(@arguments.block); g.add("}"))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::LocalVariableAccessAmbiguous
|
3
|
+
def to_ruby g
|
4
|
+
if g.var_scope_has_local?(@name)
|
5
|
+
g.add(@name.to_s)
|
6
|
+
else
|
7
|
+
g.add("self")
|
8
|
+
|
9
|
+
if g.easy_ident?(@name)
|
10
|
+
g.add(".#{@name}")
|
11
|
+
else
|
12
|
+
g.add(".__send__(#{name.inspect})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
class Parameters
|
4
|
+
def to_ruby g
|
5
|
+
list = []
|
6
|
+
list_add = Proc.new { |&blk| list.push(Proc.new(&blk)) }
|
7
|
+
|
8
|
+
@required.each { |item| list_add.call { g.add(item.to_s) } }
|
9
|
+
|
10
|
+
if @defaults
|
11
|
+
@defaults.arguments.each { |asgn|
|
12
|
+
name = asgn.name
|
13
|
+
value = asgn.value
|
14
|
+
list_add.call {
|
15
|
+
g.add("#{name}=")
|
16
|
+
g.add(value) unless value.is_a?(SymbolLiteral) and value.value==:*
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
if @splat == :*
|
22
|
+
list_add.call { g.add("*") }
|
23
|
+
elsif @splat
|
24
|
+
list_add.call { g.add("*#{@splat}") }
|
25
|
+
end
|
26
|
+
|
27
|
+
if @keywords
|
28
|
+
@keywords.arguments.each { |asgn|
|
29
|
+
name = asgn.name
|
30
|
+
value = asgn.value
|
31
|
+
list_add.call {
|
32
|
+
g.add("#{name}:")
|
33
|
+
g.add(value) unless value.is_a?(SymbolLiteral) and value.value==:*
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
if @keywords.kwrest == true
|
38
|
+
list_add.call { g.add("**") }
|
39
|
+
elsif @keywords.kwrest
|
40
|
+
list_add.call { g.add("**#{@keywords.kwrest.name}") }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if @block_arg
|
45
|
+
list_add.call { g.add("&#{@block_arg.name}") }
|
46
|
+
end
|
47
|
+
|
48
|
+
if list.empty?
|
49
|
+
g.add("||")
|
50
|
+
else
|
51
|
+
g.add("|")
|
52
|
+
g.push_indent
|
53
|
+
list[0...-1].each { |proc| proc.call; g.add(", ") }
|
54
|
+
list.last.tap { |proc| proc.call }
|
55
|
+
g.pop_indent
|
56
|
+
g.add("|")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
class CodeTools::AST::Quest
|
3
|
+
def to_ruby g
|
4
|
+
associated_questable = @questable.dup
|
5
|
+
associated_questable.receiver = @receiver
|
6
|
+
|
7
|
+
g.add("(")
|
8
|
+
g.add(@receiver); g.add(".respond_to?(#{@questable.name.inspect}).false?")
|
9
|
+
g.add(" ? ::Myco::Void : ")
|
10
|
+
g.add(associated_questable)
|
11
|
+
g.add(")")
|
12
|
+
end
|
13
|
+
end
|