Skip to content

Commit

Permalink
Get new x() and prototype chain lookup working
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed Aug 25, 2011
1 parent bac1fbb commit 475e2eb
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 4 deletions.
28 changes: 26 additions & 2 deletions lib/sparta/compilers/compiler.rb
Expand Up @@ -59,14 +59,18 @@ def visit_FunctionExprNode(o)
block.generator.for_block = true
block.generator.total_args = o.arguments.size
block.generator.cast_for_multi_block_arg unless o.arguments.empty?
block.generator.set_line o.line if o.line

# Visit arguments and then the block
o.arguments.each { |x| x.accept(block) }
block.accept(body)

g.push_const :Function

# Invoke the create block instruction
# with the generator of the block compiler
g.create_block block.finalize
g.send :new, 1
end

def visit_ParameterNode(o)
Expand Down Expand Up @@ -156,9 +160,22 @@ def visit_StringNode(o)
end

def visit_OpEqualNode(o)
o.value.accept(self)
set_line(o)
s.set_variable o.left.value

if o.left.is_a?(RKelly::Nodes::ResolveNode)
o.value.accept(self)
s.set_variable o.left.value
elsif o.left.is_a?(RKelly::Nodes::DotAccessorNode)
o.left.value.accept(self)
g.push_literal o.left.accessor.to_sym
o.value.accept(self)
g.send :internal_Put, 2
end
end

def visit_ThisNode(o)
set_line(o)
g.push_self
end

def visit_ResolveNode(o)
Expand Down Expand Up @@ -187,6 +204,13 @@ def visit_PropertyNode(o)
g.send :internal_LiteralPut, 2
end

def visit_NewExprNode(o)
set_line(o)
g.push_const :Object
super
g.send :with_constructor, 1
end

protected

def set_line(o)
Expand Down
3 changes: 2 additions & 1 deletion lib/sparta/compilers/eval_compiler.rb
Expand Up @@ -4,9 +4,10 @@
module Sparta
module Compilers
class EvalCompiler < Compiler
def initialize
def initialize(static_scope = nil)
@generator = Rubinius::Generator.new
@scope = Sparta::Scopes::GlobalScope.new(@generator)
@static_scope = static_scope
end

# Automatically return the last expression unless
Expand Down
36 changes: 35 additions & 1 deletion lib/sparta/runtime/object.rb
Expand Up @@ -7,11 +7,31 @@ def self.runtime_binding
class Object < Rubinius::LookupTable
attr_accessor :spec_Prototype, :spec_Class

def self.with_constructor(constructor)
object = new
object.spec_Prototype = constructor.spec_Get(:prototype)
constructor.call_with(object)
object
end

def to_hash
Hash[*keys.zip(values).flatten]
end

def inspect
"#<#{object_id.to_s(16)} #{to_hash.inspect}>"
end

def spec_Get(name)
self[name]
if value = self[name]
value
elsif prototype = spec_Prototype
prototype.spec_Get(name)
end
end

def spec_Put(name, object, throw=false)
self[name] = object
end

def internal_Put(name, object)
Expand Down Expand Up @@ -66,6 +86,20 @@ def self.empty_object
class Window < Object
end

class Function < Object
def initialize(block)
@block = block
end

def call(*args)
@block.call(*args)
end

def call_with(this, *args)
@block.call_under(this, @block.static_scope)
end
end

class LiteralObject < Object
thunk_method :spec_Prototype, OBJECT_PROTOTYPE
thunk_method :spec_Class, "Object"
Expand Down
6 changes: 6 additions & 0 deletions spec/object_spec.rb
Expand Up @@ -5,4 +5,10 @@
e("x = { a: 1 }; x.a").should == 1
e("x = { a: { b: 2 }, c: 5 }; x.a.b + x.c").should == 7
end

it "creates a new object with the new operator" do
e("x = function() {}; y = new x; y.a = 1; y.a").should == 1
e("x = function() {}; x.prototype = { a: 1 }; y = new x; y.b = 2; y.a + y.b").should == 3
e("x = function() { this.c = 5; }; x.prototype = { a: 1 }; y = new x; y.b = 2; y.a + y.b + y.c").should == 8
end
end

0 comments on commit 475e2eb

Please sign in to comment.