Commits

Anonymous committed a54080d

Make all tests pass by (1) binding receivers to methods when methods
are obtained from objects and (2) returning MethodCalls from lots
and lots of places in the parser.

Comments (0)

Files changed (3)

     debug "eval #{self} on #{obj} with #{args}"
     val = @expr.eval obj, args
     receiver = @object.eval obj, args
-    if receiver.is_a? VeloMethod
-      receiver = receiver.run obj, []
-    end
+    debug "setting #{@field} on #{receiver}"
     receiver.set @field, val
     val
   end
     obj
   end
 
-  def find_receiver obj, args
-    obj
-  end
-
   def to_s
     "Self()"
   end
     @ident
   end
 
-  def find_receiver obj, args
-    debug "find_receiver #{self}"
-    @receiver.eval obj, args
-  end
-
   def eval obj, args
     debug "eval #{self} on #{obj} with #{args}"
     receiver = @receiver.eval obj, args
-    if receiver.is_a? VeloMethod
-      receiver = receiver.run obj, []
-    end
     receiver.lookup @ident
   end
 
     end
     method = @method_expr.eval obj, args
     debug "arguments evaluated, now calling #{@method_expr} -> #{method}"
-    receiver = @method_expr.find_receiver obj, args
     if method.is_a? VeloMethod
-      debug "running real method #{method} w/args #{args}, receiver=#{receiver}"
-      method.run receiver, new_args
+      # xxx show receiver (method's bound object) in debug
+      debug "running real method #{method} w/args #{args}"
+      method.run new_args
     else
-      debug "just returning non-method (#{method}) on call, receiver=#{receiver}"
+      debug "just returning non-method (#{method}) on call"
       method
     end
   end

src/velo/parser.rb

     end
     receiver = base  # could be Expr, StringLit, Arg
     if (['EOL', 'EOF'].include? @scanner.type or [')', ','].include? @scanner.text)
-      return receiver
+      return MethodCall.new(receiver, [])
     end
     while @scanner.consume '.'
       @scanner.consume_type 'EOL'
       debug "parsing .ident"
       ident = @scanner.text
       @scanner.scan
-      receiver = Lookup.new(receiver, ident)
+      receiver = Lookup.new(MethodCall.new(receiver, []), ident)
     end
     if @scanner.consume '='
       # this is an assignment, so we must resolve the reciever chain
       # as follows: a.b.c becomes
       # lookup(lookup(a, b), c)
       debug "not a method call"
-      return receiver
+      return MethodCall.new(receiver, [])
     else
       # this is a method call, so we must resolve the reciever chain
       # as follows: a.b.c args becomes
       raise VeloSyntaxError, "unexpected '#{@scanner.text}'"
     end
   end
-
-  # no longer used -- goofy.
-  def rest receiver, is_call
-    debug "parsing Rest (of Expr) production"
-    if @scanner.consume "."
-      debug "parsing lookup"
-      @scanner.consume_type 'EOL'
-      ident = @scanner.text
-      @scanner.scan
-      rest Lookup.new(receiver, ident), true
-    elsif (['EOL', 'EOF'].include? @scanner.type or [')', ','].include? @scanner.text)
-      if is_call
-        MethodCall.new(receiver, [])
-      else
-        receiver
-      end
-    else
-      args = []
-      e = expr
-      args.push(e) unless e.nil?
-      while @scanner.consume ","
-        @scanner.consume_type 'EOL'
-        e = expr
-        args.push(e) unless e.nil?
-      end
-      MethodCall.new(receiver, args)
-    end
-  end
 end
 
 if $0 == __FILE__

src/velo/runtime.rb

   def initialize title, fun
     @title = title
     @fun = fun
+    @obj = nil
   end
 
-  def run obj, args
-    @fun.call obj, args
+  def bind_object obj
+    @obj = obj
+  end
+
+  def run args
+    @fun.call @obj, args
   end
   
   def to_s
     if result.nil?
       raise VeloAttributeNotFound, "could not locate '#{ident}' on #{self}"
     end
+    if result.is_a? VeloMethod
+      debug "binding obtained method #{result} to object #{self}"
+      result.bind_object self
+    end
     result
   end
 
   method = nil
   choice = args[0].contents.empty? ? 2 : 1
   method = args[choice].lookup 'create'
-  method.run args[choice], [obj]
+  method.run [obj]
 })
 
 $String = VeloObject.new 'String'
 
   velo_Shimmy = VeloObject.new 'Shimmy'
   velo_Shimmy.velo_extend $String
-  (velo_Shimmy.lookup 'bar').run velo_Shimmy, [1,2,3]
+  (velo_Shimmy.lookup 'bar').run [1,2,3]
 end