class Nydp::InterpretedFunction
Constants
- NIL
Attributes
arg_names[RW]
body[RW]
context_builder[RW]
Public Class Methods
build(arg_list, body, bindings, ns)
click to toggle source
# File lib/nydp/interpreted_function.rb, line 99 def self.build arg_list, body, bindings, ns my_params = { } index_parameters arg_list, my_params body = compile_body body, cons(my_params, bindings), [], ns 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, ns)
click to toggle source
# File lib/nydp/interpreted_function.rb, line 114 def self.compile_body body_forms, bindings, instructions, ns instructions << Nydp::Compiler.compile(body_forms.car, bindings, ns) rest = body_forms.cdr if !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, ns end end
index_parameters(arg_list, hsh)
click to toggle source
# File lib/nydp/interpreted_function.rb, line 131 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
Public Instance Methods
can_do?()
click to toggle source
# File lib/nydp/interpreted_function.rb, line 46 def can_do? arg_names == nil end
compile_do_expr_to_ruby(indent, srcs)
click to toggle source
# File lib/nydp/interpreted_function.rb, line 50 def compile_do_expr_to_ruby indent, srcs body. map { |expr| expr.compile_to_ruby(" ", srcs, cando: true) }. to_a. join("\n"). split(/\n/). # need join-split to separate out embedded newlines (TODO worry about newlines within literal strings?) map { |e| "#{indent} #{e}" }. join("\n") end
compile_to_ruby(indent, srcs, opts={})
click to toggle source
# File lib/nydp/interpreted_function.rb, line 60 def compile_to_ruby indent, srcs, opts={} an = arg_names rubyargs = [] src_index = srcs.length srcs << to_s while (pair? an) rubyargs << "_arg_#{an.car.to_s._nydp_name_to_rb_name}=nil" an = an.cdr end if an rest_arg = "_arg_#{an.to_s._nydp_name_to_rb_name}" rubyargs << "*#{rest_arg}" end if rubyargs == [] rubyargs = "" else rubyargs = "|#{rubyargs.join ","}|" # rubyargs = "(#{rubyargs.join ","})" end # code = "#{indent}(Nydp::Fn.new(@@src_#{src_index}) {#{rubyargs}\n" code = "#{indent}##> (fn #{arg_names._nydp_inspect} #{body.to_a.map(&:_nydp_inspect).join(" ").gsub(/\n/, '\n')})\n" code << "#{indent}(Nydp::Fn.new {#{rubyargs}\n" # code << "#{indent}(Proc.new {#{rubyargs}\n" # code = "(->#{rubyargs} {\n" if rest_arg code << "#{indent} #{rest_arg} = #{rest_arg}._nydp_wrapper\n" end bodycode = body.map { |expr| expr.compile_to_ruby(" ", srcs, cando: true) }.to_a bodycode.push "#{bodycode.pop}._nydp_wrapper" code << bodycode.join("\n").split(/\n/).map { |e| "#{indent} #{e}" }.join("\n") code << "\n#{indent}})" end
inspect()
click to toggle source
# File lib/nydp/interpreted_function.rb, line 141 def inspect ; to_s ; end
lexical_reach(n)
click to toggle source
# File lib/nydp/interpreted_function.rb, line 42 def lexical_reach n body.map { |b| b.lexical_reach(n - 1) }.max end
nydp_type()
click to toggle source
# File lib/nydp/interpreted_function.rb, line 140 def nydp_type ; "fn" ; end
run_body(vm)
click to toggle source
# File lib/nydp/interpreted_function.rb, line 146 def run_body vm res = nil self.body.each { |x| res = x.execute(vm) } res end
to_s()
click to toggle source
# File lib/nydp/interpreted_function.rb, line 142 def to_s "(fn #{arg_names._nydp_inspect} #{body.map { |b| b._nydp_inspect}.join('\n')})" end