Class: BusScheme::Lambda

Inherits:
Cons show all
Defined in:
lib/lambda.rb

Overview

Lambdas are closures.

Direct Known Subclasses

Primitive

Instance Attribute Summary collapse

Attributes inherited from Cons

#car, #cdr

Instance Method Summary collapse

Methods inherited from Cons

#==, #each, #empty?, #inspect, #last, #length, #map, #to_a, #to_list

Constructor Details

#initialize(formals, body) ⇒ Lambda

create new Lambda object


8
9
10
11
12
13
14
# File 'lib/lambda.rb', line 8

def initialize(formals, body)
  @special_form = false
  @formals, @body, @enclosing_scope = [formals, body, BusScheme.current_scope]
  @car = :lambda.sym
  @cdr = Cons.new(@formals.sexp, @body.sexp)
  @called_as = nil # avoid warnings
end

Instance Attribute Details

#scopeObject (readonly)

Returns the value of attribute scope


4
5
6
# File 'lib/lambda.rb', line 4

def scope
  @scope
end

#special_formObject

Returns the value of attribute special_form


5
6
7
# File 'lib/lambda.rb', line 5

def special_form
  @special_form
end

Instance Method Details

#call(*args) ⇒ Object

execute body with args bound to formals


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/lambda.rb', line 17

def call(*args)
  locals = if @formals.is_a? Sym # rest args
             { @formals => args.to_list }
           else # regular arg list
             raise BusScheme::ArgumentError, "Wrong number of args:
  expected #{@formals.size}, got #{args.size}
  #{BusScheme.stacktrace.join("\n")}" if @formals.length != args.length
             @formals.to_a.zip(args).to_hash
           end

  @frame = StackFrame.new(locals, @enclosing_scope, @called_as)
  
  BusScheme.stack.push @frame
  begin
    val = @body.map{ |form| BusScheme.eval(form) }.last
  rescue => e
    raise e
    BusScheme.stack.pop
  end
  BusScheme.stack.pop
  return val
end

#call_as(called_as, *args) ⇒ Object


40
41
42
43
# File 'lib/lambda.rb', line 40

def call_as(called_as, *args)
  @called_as = called_as
  call(*args)
end