class Risp::Interpreter
Constants
- SPECIAL_FORMS
Attributes
binding[R]
lexer[R]
macros[R]
parser[R]
Public Class Methods
assign_args(symbols, values)
click to toggle source
# File lib/risp/interpreter.rb, line 133 def self.assign_args(symbols, values) symbols.each_with_index.reduce({}) do |a, (s, i)| v = values[i] if s.is_a?(Hamster::Vector) && v.is_a?(Enumerable) a.merge(assign_args(s, v)) elsif s.is_a?(Risp::Splat) a[s.name] = values.drop(i) a else a[s.name] = v a end end end
eval(expr, binding, locals, macros)
click to toggle source
# File lib/risp/interpreter.rb, line 73 def self.eval(expr, binding, locals, macros) case expr when Hamster::List first = expr.first if special = first.is_a?(Risp::Symbol) && SPECIAL_FORMS[first.name] special.call(expr.drop(1), binding, locals, macros) elsif macro = first.is_a?(Risp::Symbol) && macros[first.name] _, *args = expr eval(macro.call(*args), binding, locals, macros) elsif first.is_a?(Risp::Method) receiver, *args = expr.drop(1).map { |x| eval(x, binding, locals, macros) } if args.last.is_a?(Proc) && receiver.method(first.name).arity < args.size *args, block = args receiver.send(first.name, *args, &block) else receiver.send(first.name, *args) end else fn, *args = expr.map { |x| eval(x, binding, locals, macros) } fn.call(*args) end when Risp::Symbol symbol = expr.name resolve(symbol, binding, locals, macros) when Enumerable expr.map { |x| eval(x, binding, locals, macros) } else expr end end
new()
click to toggle source
# File lib/risp/interpreter.rb, line 60 def initialize() @binding = {} @macros = {} @lexer = Risp::Lexer.new @parser = Risp::Parser.new corelib = File.read(File.expand_path('core.risp', File.dirname(__FILE__))) eval(corelib) end
resolve(symbol, binding, locals, macros)
click to toggle source
# File lib/risp/interpreter.rb, line 117 def self.resolve(symbol, binding, locals, macros) if locals.has_key?(symbol) locals[symbol] elsif binding.has_key?(symbol) binding[symbol] else begin symbol.to_s.split('/').reduce(Object) do |c, p| c.const_get(p) end rescue NameError => e raise "cannot resolve #{symbol}" end end end
unquote(expr, binding, locals, macros)
click to toggle source
# File lib/risp/interpreter.rb, line 104 def self.unquote(expr, binding, locals, macros) if expr.is_a?(Enumerable) && !expr.is_a?(Risp::Symbol) first, second = expr if first.is_a?(Risp::Symbol) && first.name == :unquote eval(second, binding, locals, macros) else expr.map { |x| unquote(x, binding, locals, macros) } end else expr end end
Public Instance Methods
eval(code)
click to toggle source
# File lib/risp/interpreter.rb, line 69 def eval(code) parser.parse(lexer.lex(code)).map { |x| self.class.eval(x, binding, {}, macros) }.last end