Class: Nydp::InterpretedFunction

Inherits:
Object
  • Object
show all
Extended by:
Helper
Includes:
Helper
Defined in:
lib/nydp/interpreted_function.rb

Constant Summary collapse

NIL =
Nydp::NIL

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helper

cons, list, literal?, pair?, sig, sym, sym?

Methods included from Converter

#n2r, #r2n

Instance Attribute Details

#arg_namesObject

Returns the value of attribute arg_names.



17
18
19
# File 'lib/nydp/interpreted_function.rb', line 17

def arg_names
  @arg_names
end

#bodyObject

Returns the value of attribute body.



17
18
19
# File 'lib/nydp/interpreted_function.rb', line 17

def body
  @body
end

#context_builderObject

Returns the value of attribute context_builder.



17
18
19
# File 'lib/nydp/interpreted_function.rb', line 17

def context_builder
  @context_builder
end

Class Method Details

.build(arg_list, body, bindings) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/nydp/interpreted_function.rb', line 23

def self.build arg_list, body, bindings
  my_params = { }
  index_parameters arg_list, my_params
  body = compile_body body, cons(my_params, bindings), []
  reach = body.map { |b| b.lexical_reach(-1)  }.max

  ifn_klass     = reach >= 0 ? InterpretedFunctionWithClosure : InterpretedFunctionWithoutClosure
  ifn           = ifn_klass.new
  ifn.arg_names = arg_list
  ifn.body      = body

  ifn.extend Nydp::LexicalContextBuilder.select arg_list
  ifn
end

.compile_body(body_forms, bindings, instructions) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/nydp/interpreted_function.rb', line 38

def self.compile_body body_forms, bindings, instructions
  instructions << Nydp::Compiler.compile(body_forms.car, bindings)

  rest = body_forms.cdr
  if Nydp::NIL.is? rest
    return Pair.from_list(instructions)
  else
    # PopArg is necessary because each expression pushes an arg onto the arg stack.
    # we only need to keep the arg pushed by the last expression in a function
    # so we need the following line in order to remove unwanted args from the stack.
    # Each expression at some executes vm.push_arg(thing)
    # TODO find a more intelligent way to do this, eg change the meaning of vm or of push_arg in the expression vm.push_arg(thing)
    instructions << PopArg
    compile_body rest, bindings, instructions
  end
end

.index_parameters(arg_list, hsh) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/nydp/interpreted_function.rb', line 55

def self.index_parameters arg_list, hsh
  if pair? arg_list
    index_parameters arg_list.car, hsh
    index_parameters arg_list.cdr, hsh
  elsif NIL != arg_list
    hsh[arg_list] = hsh.size
  end
end

Instance Method Details

#inspectObject



65
# File 'lib/nydp/interpreted_function.rb', line 65

def inspect   ; to_s ; end

#lexical_reach(n) ⇒ Object



19
20
21
# File 'lib/nydp/interpreted_function.rb', line 19

def lexical_reach n
  body.map { |b| b.lexical_reach(n - 1)  }.max
end

#nydp_typeObject



64
# File 'lib/nydp/interpreted_function.rb', line 64

def nydp_type ; "fn" ; end

#to_sObject



66
67
68
# File 'lib/nydp/interpreted_function.rb', line 66

def to_s
  "(fn #{arg_names.inspect} #{body.map { |b| b.inspect}.join(' ')})"
end