myco 0.1.0.dev → 0.1.0
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.
- 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
data/lib/myco/misc.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
module Myco
|
|
3
|
+
|
|
4
|
+
# Logical branching operator with lazy evaluation of right hand
|
|
5
|
+
def self.branch_op type, left
|
|
6
|
+
case type
|
|
7
|
+
when :"&&"; return left if left.false?
|
|
8
|
+
when :"||"; return left unless left.false?
|
|
9
|
+
when :"??"; return left unless left.void?
|
|
10
|
+
when :"&?"; return ::Myco::Void if left.false?
|
|
11
|
+
when :"|?"; return ::Myco::Void unless left.false?
|
|
12
|
+
end
|
|
13
|
+
return yield # evaluate and return right hand
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
|
|
2
|
+
module CodeTools::AST
|
|
3
|
+
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def argass loc, body
|
|
6
|
+
ArgumentAssembly.new loc.line, body
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class ArgumentAssembly < Node
|
|
11
|
+
attr_accessor :body, :block
|
|
12
|
+
|
|
13
|
+
def initialize(line, body, block=nil)
|
|
14
|
+
@line = line
|
|
15
|
+
@body = body
|
|
16
|
+
|
|
17
|
+
# TODO: error for multiple block arguments
|
|
18
|
+
@block = body.pop if body.last.is_a?(BlockPass)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# All items before the first SplatValue
|
|
22
|
+
def pre_group
|
|
23
|
+
@body.take_while { |item| !item.is_a?(SplatValue) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# All items after and including the first SplatValue
|
|
27
|
+
def post_group
|
|
28
|
+
@body.drop_while { |item| !item.is_a?(SplatValue) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Symbol of bytecode operation to use for send
|
|
32
|
+
def send_op
|
|
33
|
+
if @body.detect { |item| item.is_a?(SplatValue) }
|
|
34
|
+
:send_with_splat
|
|
35
|
+
elsif @block
|
|
36
|
+
:send_with_block
|
|
37
|
+
else
|
|
38
|
+
:send
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Number of arguments to use for send operation
|
|
43
|
+
def send_count
|
|
44
|
+
pre_group.size
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def splat_bytecode(g)
|
|
48
|
+
ArrayAssembly.new(@line, post_group).bytecode(g)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def block_bytecode(g)
|
|
52
|
+
@block ? @block.bytecode(g) : g.push_nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def bytecode(g)
|
|
56
|
+
pos(g)
|
|
57
|
+
|
|
58
|
+
pre_group.each { |item| item.bytecode(g) }
|
|
59
|
+
|
|
60
|
+
case send_op
|
|
61
|
+
when :send_with_splat
|
|
62
|
+
splat_bytecode(g)
|
|
63
|
+
block_bytecode(g)
|
|
64
|
+
when :send_with_block
|
|
65
|
+
block_bytecode(g)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def to_sexp
|
|
70
|
+
sexp = [:arglist] + @body.map(&:to_sexp)
|
|
71
|
+
sexp.push(@block.to_sexp) if @block
|
|
72
|
+
sexp
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
module CodeTools::AST
|
|
3
|
+
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def arrass loc, body
|
|
6
|
+
ArrayAssembly.new loc.line, body
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class ArrayAssembly < Node
|
|
11
|
+
attr_accessor :body
|
|
12
|
+
|
|
13
|
+
def initialize(line, body)
|
|
14
|
+
@line = line
|
|
15
|
+
@body = body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def bytecode(g)
|
|
19
|
+
pos(g)
|
|
20
|
+
|
|
21
|
+
if @body.empty?
|
|
22
|
+
g.make_array(0)
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Group the @body into chunks of splats and non-splats
|
|
27
|
+
chunked = @body.chunk { |item| item.is_a?(SplatValue) }
|
|
28
|
+
|
|
29
|
+
# Each SplatValue outputs the bytecode of a single array
|
|
30
|
+
# Non-SplatValues are grouped to output the bytecode of
|
|
31
|
+
# a single array for each contiguous group. Along the way, the
|
|
32
|
+
# arrays are concatenated to form one final array on the stack.
|
|
33
|
+
first_bytecode = true
|
|
34
|
+
chunked.each do |is_splat_group, group|
|
|
35
|
+
if is_splat_group
|
|
36
|
+
group.each { |item|
|
|
37
|
+
item.bytecode(g)
|
|
38
|
+
g.send(:concat, 1) unless first_bytecode
|
|
39
|
+
first_bytecode = false
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
group.each { |item|
|
|
43
|
+
item.bytecode(g)
|
|
44
|
+
}
|
|
45
|
+
g.make_array(group.size)
|
|
46
|
+
g.send(:concat, 1) unless first_bytecode
|
|
47
|
+
first_bytecode = false
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_sexp
|
|
53
|
+
[:array] + @body.map(&:to_sexp)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
module CodeTools::AST
|
|
3
|
+
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def branch_op loc, type, left, right
|
|
6
|
+
BranchOperator.new loc.line, type, left, right
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class BranchOperator < Node
|
|
11
|
+
attr_accessor :type
|
|
12
|
+
attr_accessor :left
|
|
13
|
+
attr_accessor :right
|
|
14
|
+
|
|
15
|
+
def initialize line, type, left, right
|
|
16
|
+
@line = line
|
|
17
|
+
@type = type
|
|
18
|
+
@left = left
|
|
19
|
+
@right = right
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def bytecode g
|
|
23
|
+
pos(g)
|
|
24
|
+
|
|
25
|
+
done_label = g.new_label
|
|
26
|
+
right_label = g.new_label
|
|
27
|
+
can_push_void = false
|
|
28
|
+
|
|
29
|
+
@left.bytecode(g)
|
|
30
|
+
|
|
31
|
+
case type
|
|
32
|
+
when :"&&"
|
|
33
|
+
g.dup_top
|
|
34
|
+
g.send :false?, 0
|
|
35
|
+
g.goto_if_true done_label
|
|
36
|
+
g.pop
|
|
37
|
+
when :"||"
|
|
38
|
+
g.dup_top
|
|
39
|
+
g.send :false?, 0
|
|
40
|
+
g.goto_if_false done_label
|
|
41
|
+
g.pop
|
|
42
|
+
when :"??"
|
|
43
|
+
g.dup_top
|
|
44
|
+
g.send :void?, 0
|
|
45
|
+
g.goto_if_false done_label
|
|
46
|
+
g.pop
|
|
47
|
+
when :"&?"
|
|
48
|
+
g.send :false?, 0
|
|
49
|
+
g.goto_if_false right_label
|
|
50
|
+
otherwise_push_void = true
|
|
51
|
+
when :"|?"
|
|
52
|
+
g.send :false?, 0
|
|
53
|
+
g.goto_if_true right_label
|
|
54
|
+
otherwise_push_void = true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
if otherwise_push_void
|
|
58
|
+
g.push_void
|
|
59
|
+
g.goto done_label
|
|
60
|
+
|
|
61
|
+
right_label.set!
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
@right.bytecode(g)
|
|
65
|
+
done_label.set!
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_sexp
|
|
69
|
+
[:branch_op, @type, @left.to_sexp, @right.to_sexp]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
module CodeTools::AST
|
|
3
|
-
|
|
4
|
-
# Monkey patch original to use methods of ::Myco to lookup constants
|
|
3
|
+
# Monkey patch original to use ::Myco to look up constants
|
|
5
4
|
class ConstantAccess
|
|
6
5
|
def bytecode(g)
|
|
7
6
|
pos(g)
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
g.find_const :Myco
|
|
8
|
+
g.push_cpath_top
|
|
9
|
+
g.find_const :Myco
|
|
12
10
|
g.push_literal @name
|
|
13
11
|
g.push_scope
|
|
14
|
-
|
|
15
|
-
else
|
|
16
|
-
if @top_level
|
|
17
|
-
g.push_cpath_top
|
|
18
|
-
g.find_const @name
|
|
19
|
-
else
|
|
20
|
-
g.push_cpath_top
|
|
21
|
-
g.find_const :Myco
|
|
22
|
-
g.push_literal @name
|
|
23
|
-
g.push_scope
|
|
24
|
-
g.send :find_constant, 2
|
|
25
|
-
end
|
|
26
|
-
end
|
|
12
|
+
g.send :find_constant, 2
|
|
27
13
|
end
|
|
28
14
|
end
|
|
29
15
|
end
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
|
|
2
|
+
require_relative 'myco_module_scope'
|
|
3
|
+
|
|
4
|
+
|
|
2
5
|
module CodeTools::AST
|
|
3
6
|
|
|
4
|
-
module
|
|
5
|
-
def
|
|
6
|
-
ConstantReopen.new line, name, body
|
|
7
|
+
module BuilderMethods
|
|
8
|
+
def copen loc, name, body
|
|
9
|
+
ConstantReopen.new loc.line, name, body
|
|
7
10
|
end
|
|
8
11
|
end
|
|
9
12
|
|
|
10
|
-
class ConstantReopenScope <
|
|
11
|
-
def
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def bytecode(g)
|
|
18
|
-
pos(g)
|
|
13
|
+
class ConstantReopenScope < MycoModuleScope
|
|
14
|
+
def body_bytecode g
|
|
15
|
+
g.push_scope
|
|
16
|
+
g.send :set_myco_component, 0
|
|
17
|
+
g.pop
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
@body.bytecode g
|
|
21
20
|
end
|
|
22
21
|
end
|
|
23
22
|
|
|
@@ -4,9 +4,9 @@ require_relative 'myco_module_scope'
|
|
|
4
4
|
|
|
5
5
|
module CodeTools::AST
|
|
6
6
|
|
|
7
|
-
module
|
|
8
|
-
def
|
|
9
|
-
DeclareCategory.new line, name, body
|
|
7
|
+
module BuilderMethods
|
|
8
|
+
def category loc, name, body
|
|
9
|
+
DeclareCategory.new loc.line, name, body
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -33,18 +33,20 @@ module CodeTools::AST
|
|
|
33
33
|
[:category, @name.value, @body.to_sexp]
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
def scope_implementation
|
|
37
|
+
DeclareCategoryScope.new @line, @body
|
|
38
|
+
end
|
|
39
|
+
|
|
36
40
|
def bytecode g
|
|
37
41
|
pos(g)
|
|
38
42
|
|
|
39
|
-
scope = DeclareCategoryScope.new @line, @body
|
|
40
|
-
|
|
41
43
|
##
|
|
42
44
|
# category = self.__category__ @name
|
|
43
45
|
g.push_self
|
|
44
46
|
g.push_literal @name.value
|
|
45
47
|
g.send :__category__, 1
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
scope_implementation.bytecode g
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
module CodeTools::AST
|
|
3
3
|
|
|
4
|
-
module
|
|
5
|
-
def
|
|
6
|
-
DeclareDecorator.new line, name, arguments
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def deco loc, name, arguments
|
|
6
|
+
DeclareDecorator.new loc.line, name, arguments
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ module CodeTools::AST
|
|
|
13
13
|
def initialize line, name, arguments
|
|
14
14
|
@line = line
|
|
15
15
|
@name = name
|
|
16
|
-
@arguments = arguments ||
|
|
16
|
+
@arguments = arguments || ArrayAssembly.new(@line, [])
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def to_sexp
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
module CodeTools::AST
|
|
3
3
|
|
|
4
|
-
module
|
|
5
|
-
def
|
|
6
|
-
DeclareFile.new line, body
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def declfile loc, body
|
|
6
|
+
DeclareFile.new loc.line, body
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -38,7 +38,7 @@ module CodeTools::AST
|
|
|
38
38
|
def implementation
|
|
39
39
|
myco = ToplevelConstant.new @line, :Myco
|
|
40
40
|
type = ScopedConstant.new @line, myco, :FileToplevel
|
|
41
|
-
types =
|
|
41
|
+
types = ArrayAssembly.new @line, [type]
|
|
42
42
|
decl = DeclareObject.new @line, types, @body
|
|
43
43
|
decl.scope_type = DeclareFileScope
|
|
44
44
|
decl
|
|
@@ -1,20 +1,58 @@
|
|
|
1
1
|
|
|
2
2
|
module CodeTools::AST
|
|
3
3
|
|
|
4
|
-
module
|
|
5
|
-
def
|
|
6
|
-
DeclareMeme.new line, name, decorations, arguments, body
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def meme loc, name, decorations, arguments, body
|
|
6
|
+
DeclareMeme.new loc.line, name, decorations, arguments, body
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
class
|
|
10
|
+
class DeclareMemeBody < Iter
|
|
11
|
+
attr_accessor :name
|
|
12
|
+
|
|
13
|
+
def bytecode(g)
|
|
14
|
+
pos(g)
|
|
15
|
+
|
|
16
|
+
g.state.scope.nest_scope self
|
|
17
|
+
|
|
18
|
+
meth = new_generator g, @name, @arguments
|
|
19
|
+
|
|
20
|
+
meth.push_state self
|
|
21
|
+
meth.state.push_super self
|
|
22
|
+
meth.definition_line @line
|
|
23
|
+
|
|
24
|
+
meth.state.push_name @name
|
|
25
|
+
|
|
26
|
+
@arguments.bytecode meth
|
|
27
|
+
@body.bytecode meth
|
|
28
|
+
|
|
29
|
+
meth.state.pop_name
|
|
30
|
+
|
|
31
|
+
meth.local_count = local_count
|
|
32
|
+
meth.local_names = local_names
|
|
33
|
+
meth.splat_index = @arguments.splat_index
|
|
34
|
+
|
|
35
|
+
meth.ret
|
|
36
|
+
meth.close
|
|
37
|
+
meth.pop_state
|
|
38
|
+
|
|
39
|
+
g.push_scope
|
|
40
|
+
g.send :for_method_definition, 0
|
|
41
|
+
g.add_scope
|
|
42
|
+
|
|
43
|
+
# Create the BlockEnvironment from the meth Generator
|
|
44
|
+
g.create_block meth
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class DeclareMeme < Node
|
|
11
49
|
attr_accessor :name, :decorations, :arguments, :body
|
|
12
50
|
|
|
13
51
|
def initialize line, name, decorations, arguments, body
|
|
14
52
|
@line = line
|
|
15
53
|
@name = name.value
|
|
16
|
-
@decorations = decorations ||
|
|
17
|
-
@arguments = arguments || Parameters.new(line, [], nil,
|
|
54
|
+
@decorations = decorations || ArrayAssembly.new(line, [])
|
|
55
|
+
@arguments = arguments || Parameters.new(line, [], nil, true, nil, nil, nil, nil)
|
|
18
56
|
@body = body || NilLiteral.new(line)
|
|
19
57
|
end
|
|
20
58
|
|
|
@@ -22,22 +60,26 @@ module CodeTools::AST
|
|
|
22
60
|
[:meme, @name, @decorations.to_sexp, @arguments.to_sexp, @body.to_sexp]
|
|
23
61
|
end
|
|
24
62
|
|
|
63
|
+
def body_implementation
|
|
64
|
+
meme_body = DeclareMemeBody.new(@line, @arguments, @body)
|
|
65
|
+
meme_body.name = @name
|
|
66
|
+
meme_body
|
|
67
|
+
end
|
|
68
|
+
|
|
25
69
|
def bytecode(g)
|
|
26
70
|
pos(g)
|
|
27
71
|
|
|
28
72
|
##
|
|
29
73
|
# module = scope.for_method_definition
|
|
30
74
|
# module.send :declare_meme, @name, @decorations,
|
|
31
|
-
#
|
|
75
|
+
# BlockEnvironment(body_implementation)
|
|
32
76
|
#
|
|
33
77
|
g.push_scope
|
|
34
78
|
g.send :for_method_definition, 0
|
|
35
79
|
g.push_literal @name
|
|
36
80
|
@decorations.bytecode g
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
g.push_variables
|
|
40
|
-
g.send :declare_meme, 5
|
|
81
|
+
body_implementation.bytecode(g)
|
|
82
|
+
g.send :declare_meme, 3
|
|
41
83
|
end
|
|
42
84
|
end
|
|
43
85
|
|
|
@@ -4,9 +4,9 @@ require_relative 'myco_module_scope'
|
|
|
4
4
|
|
|
5
5
|
module CodeTools::AST
|
|
6
6
|
|
|
7
|
-
module
|
|
8
|
-
def
|
|
9
|
-
DeclareObject.new line, types, body
|
|
7
|
+
module BuilderMethods
|
|
8
|
+
def declobj loc, types, body
|
|
9
|
+
DeclareObject.new loc.line, types, body
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -39,11 +39,13 @@ module CodeTools::AST
|
|
|
39
39
|
[:declobj, @types.to_sexp, @body.to_sexp]
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def scope_implementation
|
|
43
|
+
@scope_type.new @line, @body
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
def bytecode g
|
|
43
47
|
pos(g)
|
|
44
48
|
|
|
45
|
-
scope = @scope_type.new @line, @body
|
|
46
|
-
|
|
47
49
|
# ::Myco::Component.new types, parent, filename
|
|
48
50
|
g.push_cpath_top
|
|
49
51
|
g.find_const :Myco
|
|
@@ -51,7 +53,7 @@ module CodeTools::AST
|
|
|
51
53
|
@types.bytecode g
|
|
52
54
|
g.push_scope; g.send :for_method_definition, 0
|
|
53
55
|
g.push_scope; g.send :active_path, 0; g.meta_to_s
|
|
54
|
-
g.
|
|
56
|
+
g.push_int @line
|
|
55
57
|
g.send :new, 4
|
|
56
58
|
|
|
57
59
|
# The return value of Component.new at the top of the stack
|
|
@@ -61,7 +63,7 @@ module CodeTools::AST
|
|
|
61
63
|
|
|
62
64
|
# Compile the inner scope,
|
|
63
65
|
# leaving the last object in the scope at the top of the stack.
|
|
64
|
-
|
|
66
|
+
scope_implementation.bytecode g
|
|
65
67
|
|
|
66
68
|
# component.__last__ = (value left on stack from @scope.bytecode)
|
|
67
69
|
g.send :__last__=, 1
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
module CodeTools::AST
|
|
3
3
|
|
|
4
|
-
module
|
|
5
|
-
def
|
|
6
|
-
DeclareString.new line, types, string
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def declstr loc, types, string
|
|
6
|
+
DeclareString.new loc.line, types, string
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -23,8 +23,8 @@ module CodeTools::AST
|
|
|
23
23
|
def implementation
|
|
24
24
|
blk = NilLiteral.new @line
|
|
25
25
|
obj = DeclareObject.new @line, @types, blk
|
|
26
|
-
args =
|
|
27
|
-
|
|
26
|
+
args = ArgumentAssembly.new @string.line, [@string]
|
|
27
|
+
InvokeMethod.new @string.line, obj, :from_string, args
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def bytecode g
|
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
|
|
2
2
|
module CodeTools::AST
|
|
3
3
|
|
|
4
|
-
module
|
|
5
|
-
def
|
|
6
|
-
Invoke.new line, receiver, name, arguments, *rest
|
|
4
|
+
module BuilderMethods
|
|
5
|
+
def invoke loc, receiver, name, arguments, *rest
|
|
6
|
+
Invoke.new loc.line, receiver, name, arguments, *rest
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
class Invoke < Node
|
|
11
|
-
attr_accessor :receiver, :name, :arguments
|
|
11
|
+
attr_accessor :receiver, :name, :arguments
|
|
12
12
|
|
|
13
13
|
def initialize line, receiver, name, arguments, block_params=nil, block=nil
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
block_arg.arguments = nil
|
|
19
|
-
end
|
|
14
|
+
@line = line
|
|
15
|
+
@receiver = receiver
|
|
16
|
+
@name = name
|
|
17
|
+
@arguments = arguments
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@block_arg = block_arg
|
|
19
|
+
if block
|
|
20
|
+
# TODO: error if passing both block argument and block literal
|
|
21
|
+
# Currently, this fails silently and ignores the block argument
|
|
22
|
+
@arguments ||= ArgumentAssembly.new(line, [])
|
|
23
|
+
@arguments.block = Iter.new(line, block_params, block)
|
|
24
|
+
end
|
|
28
25
|
end
|
|
29
26
|
|
|
30
27
|
def bytecode g
|
|
@@ -38,27 +35,12 @@ module CodeTools::AST
|
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
def implementation
|
|
41
|
-
if @
|
|
42
|
-
|
|
43
|
-
if @receiver.nil?
|
|
44
|
-
LocalVariableAccessAmbiguous.new @line, @name
|
|
45
|
-
else
|
|
46
|
-
Send.new @line, @receiver, @name
|
|
47
|
-
end
|
|
48
|
-
else
|
|
49
|
-
rcvr = @receiver || Self.new(@line)
|
|
50
|
-
send = SendWithArguments.new @line, rcvr, @name, @arguments
|
|
51
|
-
send
|
|
52
|
-
end
|
|
38
|
+
if @receiver.nil? && @arguments.nil?
|
|
39
|
+
LocalVariableAccessAmbiguous.new(@line, @name)
|
|
53
40
|
else
|
|
54
41
|
rcvr = @receiver || Self.new(@line)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
send.block = Iter.new @line, @block_params, @block
|
|
58
|
-
elsif @block_arg
|
|
59
|
-
send.block = @block_arg
|
|
60
|
-
end
|
|
61
|
-
send
|
|
42
|
+
args = @arguments || ArgumentAssembly.new(line, [])
|
|
43
|
+
InvokeMethod.new @line, rcvr, @name, args
|
|
62
44
|
end
|
|
63
45
|
end
|
|
64
46
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
module CodeTools::AST
|
|
3
|
+
|
|
4
|
+
class InvokeMethod < Node
|
|
5
|
+
attr_accessor :line, :receiver, :name, :arguments
|
|
6
|
+
|
|
7
|
+
def initialize line, receiver, name, arguments
|
|
8
|
+
@line = line
|
|
9
|
+
@receiver = receiver
|
|
10
|
+
@name = name
|
|
11
|
+
@arguments = arguments
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def bytecode(g)
|
|
15
|
+
@receiver.bytecode(g)
|
|
16
|
+
@arguments.bytecode(g)
|
|
17
|
+
|
|
18
|
+
pos(g)
|
|
19
|
+
|
|
20
|
+
g.__send__(@arguments.send_op, @name, @arguments.send_count)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_sexp
|
|
24
|
+
[:call, @receiver.to_sexp, @name, @arguments.to_sexp]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|