class Flea::Interpreter

Attributes

base_environment[RW]
current_environment[RW]

Public Class Methods

new(environment: Environment.new, standard_library: true) click to toggle source
# File lib/flea/interpreter.rb, line 7
def initialize(environment: Environment.new, standard_library: true)
  @base_environment = @current_environment = environment

  load_standard_library if standard_library
end

Public Instance Methods

evaluate(expression) click to toggle source
# File lib/flea/interpreter.rb, line 31
def evaluate(expression)
  return @current_environment.find(expression) if expression.is_a? Symbol
  return expression unless expression.is_a? Array

  case expression[0]
  when :define then @current_environment.define(expression[1], evaluate(expression[2]))
  when :native_function then eval expression[1]
  else
    function = evaluate(expression[0])
    raise "\n#{to_sexp(expression)}\n ^\n\n#{expression[0]} is not a function\n\n#{@current_environment.table.keys}" unless function.is_a? Proc

    arguments = expression.slice(1, expression.length)
    function.call(arguments, self)
  end
end
parse(string) click to toggle source
# File lib/flea/interpreter.rb, line 47
def parse(string)
  Sexpistol.parse(string, parse_ruby_keyword_literals: true)
end
run(program) click to toggle source
# File lib/flea/interpreter.rb, line 13
def run(program)
  program = parse(program)
  result = nil
  


  if program.is_a?(Sexpistol::SExpressionArray)
    program.each do |expression|
      result = evaluate(expression)
    end
    
  else
    result = evaluate(program)
  end

  result
end
to_sexp(expression) click to toggle source
# File lib/flea/interpreter.rb, line 51
def to_sexp(expression)
  Sexpistol.to_sexp(expression, scheme_compatability: true)
end

Private Instance Methods

load_standard_library() click to toggle source
# File lib/flea/interpreter.rb, line 57
def load_standard_library
  library_pattern = File.join(File.dirname(__FILE__), 'standard_library', '*.scm')

  Dir[library_pattern].each do |item|
    File.open(item) do |file|
      run(file.read)
    end
  end
end