myco 0.1.0.dev
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +2 -0
- data/bin/myco +7 -0
- data/lib/myco/backtrace.rb +56 -0
- data/lib/myco/bootstrap/component.rb +142 -0
- data/lib/myco/bootstrap/empty_object.rb +4 -0
- data/lib/myco/bootstrap/file_toplevel.rb +5 -0
- data/lib/myco/bootstrap/find_constant.rb +86 -0
- data/lib/myco/bootstrap/instance.rb +52 -0
- data/lib/myco/bootstrap/meme.rb +160 -0
- data/lib/myco/bootstrap/void.rb +40 -0
- data/lib/myco/bootstrap.my +15 -0
- data/lib/myco/bootstrap.rb +10 -0
- data/lib/myco/command.my +33 -0
- data/lib/myco/core/BasicObject.my +46 -0
- data/lib/myco/core/Category.my +5 -0
- data/lib/myco/core/Decorator.my +18 -0
- data/lib/myco/core/FileToplevel.my +23 -0
- data/lib/myco/core/Object.my +24 -0
- data/lib/myco/core/Switch.my +31 -0
- data/lib/myco/eval.rb +63 -0
- data/lib/myco/parser/ast/constant_access.rb +29 -0
- data/lib/myco/parser/ast/constant_define.rb +40 -0
- data/lib/myco/parser/ast/constant_reopen.rb +47 -0
- data/lib/myco/parser/ast/declare_category.rb +51 -0
- data/lib/myco/parser/ast/declare_decorator.rb +35 -0
- data/lib/myco/parser/ast/declare_file.rb +54 -0
- data/lib/myco/parser/ast/declare_meme.rb +44 -0
- data/lib/myco/parser/ast/declare_object.rb +75 -0
- data/lib/myco/parser/ast/declare_string.rb +37 -0
- data/lib/myco/parser/ast/invoke.rb +66 -0
- data/lib/myco/parser/ast/local_variable_access_ambiguous.rb +38 -0
- data/lib/myco/parser/ast/misc.rb +61 -0
- data/lib/myco/parser/ast/myco_module_scope.rb +58 -0
- data/lib/myco/parser/ast/quest.rb +82 -0
- data/lib/myco/parser/ast.rb +15 -0
- data/lib/myco/parser/builder.output +3995 -0
- data/lib/myco/parser/builder.racc +585 -0
- data/lib/myco/parser/builder.rb +1592 -0
- data/lib/myco/parser/lexer.rb +2306 -0
- data/lib/myco/parser/lexer.rl +393 -0
- data/lib/myco/parser/lexer_char_classes.rl +56 -0
- data/lib/myco/parser/lexer_common.rb +95 -0
- data/lib/myco/parser/lexer_skeleton.rl +154 -0
- data/lib/myco/parser/peg_parser.kpeg +759 -0
- data/lib/myco/parser/peg_parser.rb +7094 -0
- data/lib/myco/parser.rb +40 -0
- data/lib/myco/tools/OptionParser.my +38 -0
- data/lib/myco/tools/mycompile.my +51 -0
- data/lib/myco/toolset.rb +16 -0
- data/lib/myco/version.rb +22 -0
- data/lib/myco.rb +15 -0
- metadata +247 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
::Myco::Decorator < ::Myco::BasicObject {
|
3
|
+
# Implement the apply meme to mutate the incoming meme in more custom ways.
|
4
|
+
# This is run after transforms.apply has already mutated the meme.
|
5
|
+
apply: |meme, *args| { }
|
6
|
+
|
7
|
+
[transforms]
|
8
|
+
# Implement one of the recognized transform memes to
|
9
|
+
# set the corresponding property of the incoming meme.
|
10
|
+
apply: |meme, *args| {
|
11
|
+
# TODO: make order-agnostic by waiting to assign until all have run
|
12
|
+
self .? target(meme) .tap |x| { meme.target = x }
|
13
|
+
self .? name(meme) .tap |x| { meme.name = x }
|
14
|
+
self .? body(meme) .tap |x| { meme.body = x }
|
15
|
+
self .? cache(meme) .tap |x| { meme.cache = x }
|
16
|
+
self .? expose(meme) .tap |x| { meme.expose = x }
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
::Myco::FileToplevel < ::Myco::Object {
|
3
|
+
# TODO: don't use instance_variable_get
|
4
|
+
dirname: component.instance_variable_get("@dirname")
|
5
|
+
basename: component.instance_variable_get("@basename")
|
6
|
+
filename: component.instance_variable_get("@filename")
|
7
|
+
|
8
|
+
[decorators]
|
9
|
+
|
10
|
+
# Run the code in the given file, ignoring the return value but
|
11
|
+
# importing the constants defined therein into the current namespace.
|
12
|
+
import: Decorator {
|
13
|
+
apply: |meme, *args| {
|
14
|
+
# TODO: shouldn't have to use meme.target here;
|
15
|
+
# should be able to use 'parent' to reach the outer objects
|
16
|
+
# while still referring to distinct instances rather than the originals.
|
17
|
+
load_paths = [meme.target.instance.dirname]
|
18
|
+
scope = meme.target.constant_scope
|
19
|
+
component = Myco.eval_file(meme.name.to_s, load_paths, false, scope)
|
20
|
+
meme.target.include(component)
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
::Myco::Object < ::Myco::BasicObject {
|
3
|
+
# Send the named signal to all handlers for this object
|
4
|
+
__signal__: |name, *args, &block| {
|
5
|
+
component.ancestors.reverse.each |other| {
|
6
|
+
inst = (component == other) && self || other.instance
|
7
|
+
inst.?decorators.?on.?signal_handlers(name).each |meme| {
|
8
|
+
meme.result_for(self, *args, &block)
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
[decorators]
|
14
|
+
|
15
|
+
# Register a named signal handler
|
16
|
+
var on: Decorator {
|
17
|
+
storage signal_handlers: Array.new
|
18
|
+
|
19
|
+
apply: |meme| signal_handlers(meme.name).push(meme)
|
20
|
+
|
21
|
+
[transforms]
|
22
|
+
expose: false
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
::Myco::Switch < ::Myco::Object {
|
3
|
+
var input: void
|
4
|
+
var output: void
|
5
|
+
var matched: false
|
6
|
+
var comparator: :"=="
|
7
|
+
|
8
|
+
when: |expected, &blk| {
|
9
|
+
matched || (input.send(comparator, expected) &&
|
10
|
+
((matched() = true) && (output() = blk.call(input))))
|
11
|
+
self
|
12
|
+
}
|
13
|
+
|
14
|
+
when_true: |&blk| {
|
15
|
+
matched || (input &&
|
16
|
+
((matched() = true) && (output() = blk.call(input))))
|
17
|
+
self
|
18
|
+
}
|
19
|
+
|
20
|
+
when_false: |&blk| {
|
21
|
+
matched || (input ||
|
22
|
+
((matched() = true) && (output() = blk.call(input))))
|
23
|
+
self
|
24
|
+
}
|
25
|
+
|
26
|
+
else: |&blk| {
|
27
|
+
matched ||
|
28
|
+
((matched() = true) && (output() = blk.call(input)))
|
29
|
+
self
|
30
|
+
}
|
31
|
+
}
|
data/lib/myco/eval.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
module Myco
|
3
|
+
|
4
|
+
# Most of method is stolen from Rubinius implementation of Kernel#eval
|
5
|
+
def self.eval(string, scope=nil, filename=nil, lineno=nil)
|
6
|
+
string = StringValue(string)
|
7
|
+
filename = StringValue(filename) if filename
|
8
|
+
lineno = Rubinius::Type.coerce_to lineno, Fixnum, :to_i if lineno
|
9
|
+
lineno = 1 if filename && !lineno
|
10
|
+
|
11
|
+
binding = ::Binding.setup(Rubinius::VariableScope.of_sender,
|
12
|
+
Rubinius::CompiledCode.of_sender,
|
13
|
+
(scope||Rubinius::ConstantScope.of_sender),
|
14
|
+
self)
|
15
|
+
|
16
|
+
filename ||= "(eval)"
|
17
|
+
|
18
|
+
lineno ||= binding.line_number
|
19
|
+
|
20
|
+
existing_scope = binding.constant_scope
|
21
|
+
binding.constant_scope = existing_scope.dup
|
22
|
+
|
23
|
+
c = Myco::ToolSet::Compiler
|
24
|
+
be = c.construct_block string, binding, filename, lineno
|
25
|
+
|
26
|
+
result = be.call_on_instance(binding.self)
|
27
|
+
binding.constant_scope = existing_scope
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: replace with proper import set of functions
|
32
|
+
def self.eval_file path, load_paths=nil, get_last=true, scope=nil
|
33
|
+
load_paths ||= [File.dirname(Rubinius::VM.backtrace(1).first.file)]
|
34
|
+
|
35
|
+
tmp_path = File.expand_path(path)
|
36
|
+
use_path = File.file?(tmp_path) && tmp_path
|
37
|
+
load_paths.each do |load_path|
|
38
|
+
break if use_path
|
39
|
+
tmp_path = File.expand_path(path, load_path)
|
40
|
+
use_path = File.file?(tmp_path) && tmp_path
|
41
|
+
end
|
42
|
+
|
43
|
+
raise ArgumentError, "Couldn't resolve file: #{path.inspect} \n" \
|
44
|
+
"in load_paths: #{load_paths.inspect}" \
|
45
|
+
unless use_path
|
46
|
+
|
47
|
+
file_toplevel = Myco.eval File.read(use_path), scope, use_path, 1
|
48
|
+
get_last ? file_toplevel.component.__last__ : file_toplevel.component
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.rescue
|
52
|
+
begin
|
53
|
+
yield
|
54
|
+
rescue Exception=>e
|
55
|
+
unless e.is_a? SystemExit
|
56
|
+
puts e.awesome_backtrace.show
|
57
|
+
puts e.awesome_backtrace.first_color + e.message + "\033[0m"
|
58
|
+
puts
|
59
|
+
exit(1)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
# Monkey patch original to use methods of ::Myco to lookup constants
|
5
|
+
class ConstantAccess
|
6
|
+
def bytecode(g)
|
7
|
+
pos(g)
|
8
|
+
|
9
|
+
if g.state.op_asgn? # TODO: is this branch unnecessary with Myco AST?
|
10
|
+
g.push_cpath_top
|
11
|
+
g.find_const :Myco
|
12
|
+
g.push_literal @name
|
13
|
+
g.push_scope
|
14
|
+
g.send :find_constant_for_op_asign_or, 2
|
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
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_cdefn line, name, object
|
6
|
+
ConstantDefine.new line, name, object
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ConstantDefine < Node
|
11
|
+
attr_accessor :name, :object
|
12
|
+
|
13
|
+
def initialize line, name, object
|
14
|
+
@line = line
|
15
|
+
@name = name
|
16
|
+
@object = object
|
17
|
+
@object.create = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_sexp
|
21
|
+
[:cdefn, @name.name, @object.to_sexp]
|
22
|
+
end
|
23
|
+
|
24
|
+
def implementation
|
25
|
+
ConstantAssignment.new @line, @name, @object
|
26
|
+
end
|
27
|
+
|
28
|
+
def bytecode g
|
29
|
+
pos(g)
|
30
|
+
|
31
|
+
implementation.bytecode g
|
32
|
+
|
33
|
+
g.dup_top
|
34
|
+
g.push_literal @name.name
|
35
|
+
g.send :__name__=, 1
|
36
|
+
g.pop
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_copen line, name, body
|
6
|
+
ConstantReopen.new line, name, body
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ConstantReopenScope < ModuleScope
|
11
|
+
def initialize(line, body)
|
12
|
+
@line = line
|
13
|
+
@name = :ConstantReopenScope # TODO: remove/fix
|
14
|
+
@body = body
|
15
|
+
end
|
16
|
+
|
17
|
+
def bytecode(g)
|
18
|
+
pos(g)
|
19
|
+
|
20
|
+
attach_and_call g, :__component_init__, true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class ConstantReopen < Node
|
25
|
+
attr_accessor :name, :body
|
26
|
+
|
27
|
+
def initialize line, name, body
|
28
|
+
@line = line
|
29
|
+
@name = name
|
30
|
+
@body = body
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_sexp
|
34
|
+
[:copen, @name.name, @body.to_sexp]
|
35
|
+
end
|
36
|
+
|
37
|
+
def bytecode g
|
38
|
+
pos(g)
|
39
|
+
|
40
|
+
scope = ConstantReopenScope.new @line, @body
|
41
|
+
|
42
|
+
@name.bytecode g
|
43
|
+
scope.bytecode g
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
require_relative 'myco_module_scope'
|
3
|
+
|
4
|
+
|
5
|
+
module CodeTools::AST
|
6
|
+
|
7
|
+
module ProcessorMethods
|
8
|
+
def process_category line, name, body
|
9
|
+
DeclareCategory.new line, name, body
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class DeclareCategoryScope < MycoModuleScope
|
14
|
+
def body_bytecode g
|
15
|
+
g.push_scope
|
16
|
+
g.send :set_myco_category, 0
|
17
|
+
g.pop
|
18
|
+
|
19
|
+
@body.bytecode g
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class DeclareCategory < Node
|
24
|
+
attr_accessor :name, :body
|
25
|
+
|
26
|
+
def initialize line, name, body
|
27
|
+
@line = line
|
28
|
+
@name = name
|
29
|
+
@body = body
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_sexp
|
33
|
+
[:category, @name.value, @body.to_sexp]
|
34
|
+
end
|
35
|
+
|
36
|
+
def bytecode g
|
37
|
+
pos(g)
|
38
|
+
|
39
|
+
scope = DeclareCategoryScope.new @line, @body
|
40
|
+
|
41
|
+
##
|
42
|
+
# category = self.__category__ @name
|
43
|
+
g.push_self
|
44
|
+
g.push_literal @name.value
|
45
|
+
g.send :__category__, 1
|
46
|
+
|
47
|
+
scope.bytecode g
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_deco line, name, arguments
|
6
|
+
DeclareDecorator.new line, name, arguments
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class DeclareDecorator < Node
|
11
|
+
attr_accessor :line, :name, :arguments
|
12
|
+
|
13
|
+
def initialize line, name, arguments
|
14
|
+
@line = line
|
15
|
+
@name = name
|
16
|
+
@arguments = arguments || ArrayLiteral.new(@line, [])
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_sexp
|
20
|
+
args_sexp = @arguments.to_sexp
|
21
|
+
args_sexp[0] = :arglist
|
22
|
+
sexp = [:deco, @name.value]
|
23
|
+
sexp.push args_sexp unless @arguments.body.empty?
|
24
|
+
sexp
|
25
|
+
end
|
26
|
+
|
27
|
+
def bytecode g
|
28
|
+
pos(g)
|
29
|
+
|
30
|
+
ary = ArrayLiteral.new @line, [@name, @arguments]
|
31
|
+
ary.bytecode g
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_declfile line, body
|
6
|
+
DeclareFile.new line, body
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class DeclareFileScope < MycoModuleScope
|
11
|
+
def body_bytecode g
|
12
|
+
g.push_scope
|
13
|
+
g.send :set_myco_file, 0
|
14
|
+
g.pop
|
15
|
+
|
16
|
+
@body.bytecode g
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class DeclareFile < Node
|
21
|
+
attr_accessor :body
|
22
|
+
|
23
|
+
# Use minimal inspect to avoid huge inspect output for inner AST nodes
|
24
|
+
# that store a reference to a DeclareFile in an instance variable.
|
25
|
+
def inspect
|
26
|
+
to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize line, body
|
30
|
+
@line = line
|
31
|
+
@body = body
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_sexp
|
35
|
+
[:declfile, @body.to_sexp]
|
36
|
+
end
|
37
|
+
|
38
|
+
def implementation
|
39
|
+
myco = ToplevelConstant.new @line, :Myco
|
40
|
+
type = ScopedConstant.new @line, myco, :FileToplevel
|
41
|
+
types = ArrayLiteral.new @line, [type]
|
42
|
+
decl = DeclareObject.new @line, types, @body
|
43
|
+
decl.scope_type = DeclareFileScope
|
44
|
+
decl
|
45
|
+
end
|
46
|
+
|
47
|
+
def bytecode g
|
48
|
+
pos(g)
|
49
|
+
|
50
|
+
implementation.bytecode g
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_meme line, name, decorations, arguments, body
|
6
|
+
DeclareMeme.new line, name, decorations, arguments, body
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class DeclareMeme < Define
|
11
|
+
attr_accessor :name, :decorations, :arguments, :body
|
12
|
+
|
13
|
+
def initialize line, name, decorations, arguments, body
|
14
|
+
@line = line
|
15
|
+
@name = name.value
|
16
|
+
@decorations = decorations || ArrayLiteral.new(line, [])
|
17
|
+
@arguments = arguments || Parameters.new(line, [], nil, false, nil, nil, nil, nil)
|
18
|
+
@body = body || NilLiteral.new(line)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_sexp
|
22
|
+
[:meme, @name, @decorations.to_sexp, @arguments.to_sexp, @body.to_sexp]
|
23
|
+
end
|
24
|
+
|
25
|
+
def bytecode(g)
|
26
|
+
pos(g)
|
27
|
+
|
28
|
+
##
|
29
|
+
# module = scope.for_method_definition
|
30
|
+
# module.send :declare_meme, @name, @decorations,
|
31
|
+
# CompiledCode(@body), const_scope, var_scope
|
32
|
+
#
|
33
|
+
g.push_scope
|
34
|
+
g.send :for_method_definition, 0
|
35
|
+
g.push_literal @name
|
36
|
+
@decorations.bytecode g
|
37
|
+
g.push_generator compile_body(g)
|
38
|
+
g.push_scope
|
39
|
+
g.push_variables
|
40
|
+
g.send :declare_meme, 5
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
require_relative 'myco_module_scope'
|
3
|
+
|
4
|
+
|
5
|
+
module CodeTools::AST
|
6
|
+
|
7
|
+
module ProcessorMethods
|
8
|
+
def process_declobj line, types, body
|
9
|
+
DeclareObject.new line, types, body
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class DeclareObjectScope < MycoModuleScope
|
14
|
+
def body_bytecode g
|
15
|
+
g.push_scope
|
16
|
+
g.send :set_myco_component, 0
|
17
|
+
g.pop
|
18
|
+
|
19
|
+
@body.bytecode g
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class DeclareObject < Node
|
24
|
+
attr_accessor :types, :body
|
25
|
+
attr_accessor :create
|
26
|
+
|
27
|
+
attr_accessor :scope_type
|
28
|
+
|
29
|
+
def initialize line, types, body
|
30
|
+
@line = line
|
31
|
+
@types = types
|
32
|
+
@body = body
|
33
|
+
|
34
|
+
@create = true
|
35
|
+
@scope_type = DeclareObjectScope
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_sexp
|
39
|
+
[:declobj, @types.to_sexp, @body.to_sexp]
|
40
|
+
end
|
41
|
+
|
42
|
+
def bytecode g
|
43
|
+
pos(g)
|
44
|
+
|
45
|
+
scope = @scope_type.new @line, @body
|
46
|
+
|
47
|
+
# ::Myco::Component.new types, parent, filename
|
48
|
+
g.push_cpath_top
|
49
|
+
g.find_const :Myco
|
50
|
+
g.find_const :Component
|
51
|
+
@types.bytecode g
|
52
|
+
g.push_scope; g.send :for_method_definition, 0
|
53
|
+
g.push_scope; g.send :active_path, 0; g.meta_to_s
|
54
|
+
g.push_literal @line
|
55
|
+
g.send :new, 4
|
56
|
+
|
57
|
+
# The return value of Component.new at the top of the stack
|
58
|
+
# will be consumed by @scope.bytecode, so save two copies of it.
|
59
|
+
g.dup_top # One for sending :__last__= to
|
60
|
+
g.dup_top # One for sending :instance to (or returning, if !@create)
|
61
|
+
|
62
|
+
# Compile the inner scope,
|
63
|
+
# leaving the last object in the scope at the top of the stack.
|
64
|
+
scope.bytecode g
|
65
|
+
|
66
|
+
# component.__last__ = (value left on stack from @scope.bytecode)
|
67
|
+
g.send :__last__=, 1
|
68
|
+
g.pop
|
69
|
+
|
70
|
+
# return (@create ? component.instance : component)
|
71
|
+
g.send :instance, 0 if @create
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_declstr line, types, string
|
6
|
+
DeclareString.new line, types, string
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class DeclareString < Node
|
11
|
+
attr_accessor :types, :string
|
12
|
+
|
13
|
+
def initialize line, types, string
|
14
|
+
@line = line
|
15
|
+
@types = types
|
16
|
+
@string = string
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_sexp
|
20
|
+
[:declstr, @types.to_sexp, @string.to_sexp]
|
21
|
+
end
|
22
|
+
|
23
|
+
def implementation
|
24
|
+
blk = NilLiteral.new @line
|
25
|
+
obj = DeclareObject.new @line, @types, blk
|
26
|
+
args = ArrayLiteral.new @string.line, [@string]
|
27
|
+
SendWithArguments.new @string.line, obj, :from_string, args
|
28
|
+
end
|
29
|
+
|
30
|
+
def bytecode g
|
31
|
+
pos(g)
|
32
|
+
|
33
|
+
implementation.bytecode g
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_invoke line, receiver, name, arguments, *rest
|
6
|
+
Invoke.new line, receiver, name, arguments, *rest
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Invoke < Node
|
11
|
+
attr_accessor :receiver, :name, :arguments, :block_params, :block
|
12
|
+
|
13
|
+
def initialize line, receiver, name, arguments, block_params=nil, block=nil
|
14
|
+
block_arg = nil
|
15
|
+
if arguments.is_a? BlockPass
|
16
|
+
block_arg = arguments
|
17
|
+
arguments = block_arg.arguments
|
18
|
+
block_arg.arguments = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
@line = line
|
22
|
+
@receiver = receiver
|
23
|
+
@name = name
|
24
|
+
@arguments = arguments
|
25
|
+
@block_params = block_params
|
26
|
+
@block = block
|
27
|
+
@block_arg = block_arg
|
28
|
+
end
|
29
|
+
|
30
|
+
def bytecode g
|
31
|
+
pos(g)
|
32
|
+
|
33
|
+
implementation.bytecode(g)
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_sexp
|
37
|
+
implementation.to_sexp
|
38
|
+
end
|
39
|
+
|
40
|
+
def implementation
|
41
|
+
if @block.nil? && @block_arg.nil?
|
42
|
+
if @arguments.nil?
|
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
|
53
|
+
else
|
54
|
+
rcvr = @receiver || Self.new(@line)
|
55
|
+
send = SendWithArguments.new @line, rcvr, @name, @arguments
|
56
|
+
if @block
|
57
|
+
send.block = Iter.new @line, @block_params, @block
|
58
|
+
elsif @block_arg
|
59
|
+
send.block = @block_arg
|
60
|
+
end
|
61
|
+
send
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
module CodeTools::AST
|
3
|
+
|
4
|
+
module ProcessorMethods
|
5
|
+
def process_lambig line, name
|
6
|
+
LocalVariableAccessAmbiguous.new line, name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class LocalVariableAccessAmbiguous < Node
|
11
|
+
attr_accessor :name
|
12
|
+
|
13
|
+
def initialize line, name
|
14
|
+
@line = line
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def bytecode g
|
19
|
+
pos(g)
|
20
|
+
|
21
|
+
implementation(g).bytecode(g)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_sexp
|
25
|
+
[:lambig, @name]
|
26
|
+
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
|
+
end
|
37
|
+
|
38
|
+
end
|