Skip to content

Commit

Permalink
Find self from the scope
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Brown committed Jun 24, 2010
1 parent 8339c94 commit 1c30e68
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 7 deletions.
21 changes: 21 additions & 0 deletions lib/duby/jvm/base.rb
Expand Up @@ -11,6 +11,7 @@ def initialize(filename)
@jump_scope = []
@bindings = Hash.new {|h, type| h[type] = type.define(@file)}
@captured_locals = Hash.new {|h, binding| h[binding] = {}}
@self_scope = nil
end

def compile(ast, expression = false)
Expand Down Expand Up @@ -151,13 +152,25 @@ def declare_argument(name, type)
end

def body(body, expression)
saved_self = @self_scope
if body.kind_of?(Duby::AST::ScopedBody)
scope = body.static_scope
if scope != @self_scope
@self_scope = scope
if scope.self_node
local_assign(
scope, 'self', scope.self_type, false, scope.self_node)
end
end
end
# all except the last element in a body of code is treated as a statement
i, last = 0, body.children.size - 1
while i < last
body.children[i].compile(self, false)
i += 1
end
yield body.children[last] if last >= 0
@current_self = saved_self
end

def scoped_body(scope, expression)
Expand All @@ -180,6 +193,14 @@ def fixnum(type, value)
end
alias float fixnum

def compile_self
if @self_scope && @self_scope.self_node
local(@self_scope, 'self', @self_scope.self_type)
else
real_self
end
end

def get_binding(type)
@bindings[type]
end
Expand Down
6 changes: 3 additions & 3 deletions lib/duby/jvm/compiler.rb
Expand Up @@ -337,8 +337,8 @@ def call(call, expression)

def self_call(fcall, expression)
return cast(fcall, expression) if fcall.cast?
type = @type
type = type.meta if @static
type = @self_scope ? @self_scope.self_type : @type
type = type.meta if (@static && type == @type)
fcall.target = ImplicitSelf.new(type)

params = fcall.parameters.map do |param|
Expand Down Expand Up @@ -688,7 +688,7 @@ def binding_reference
@method.aload(@method.local('$binding'))
end

def compile_self
def real_self
method.aload(0)
end

Expand Down
8 changes: 6 additions & 2 deletions lib/duby/jvm/source_compiler.rb
Expand Up @@ -194,7 +194,11 @@ def field(name, type, annotations)
end

def this
@static ? @class.class_name : 'this'
if @self_scope && @self_scope.self_node
scoped_local_name('self', @self_scope)
else
@static ? @class.class_name : 'this'
end
end

def local_assign(scope, name, type, expression, value)
Expand Down Expand Up @@ -659,7 +663,7 @@ def binding_reference
@method.print '$binding'
end

def compile_self
def real_self
@method.print 'this'
end

Expand Down
2 changes: 1 addition & 1 deletion lib/duby/jvm/source_generator/precompile.rb
Expand Up @@ -86,7 +86,7 @@ class FunctionalCall
def method(compiler)
@method ||= begin
arg_types = parameters.map {|p| p.inferred_type}
compiler.self_type.get_method(name, arg_types)
@self_type.get_method(name, arg_types)
end
end

Expand Down
15 changes: 14 additions & 1 deletion lib/duby/jvm/types/intrinsics.rb
Expand Up @@ -59,7 +59,20 @@ def add_macro(name, *args, &block)
def add_compiled_macro(klass, name, arg_types)
add_macro(name, *arg_types) do |duby, call|
expander = klass.constructors[0].newInstance(duby, call)
expander.expand
ast = expander.expand
if ast
if call.target
body = Duby::AST::ScopedBody.new(call.parent, call.position)
body.static_scope.self_type = call.target.inferred_type!
body.static_scope.self_node = call.target
body << ast
body
else
ast
end
else
Duby::AST::Noop.new(call.parent, call.position)
end
end
end

Expand Down

0 comments on commit 1c30e68

Please sign in to comment.