lib/flea/interpreter.rb in flea-0.1.0 vs lib/flea/interpreter.rb in flea-0.1.1

- old
+ new

@@ -1,67 +1,67 @@ +# frozen_string_literal: true + module Flea class Interpreter - - attr_accessor :base_environment, - :current_environment, - :parser - - def initialize(options = {}) - options = { - :base_environment => Environment.new, - :load_standard_library => true - }.merge(options) - - @base_environment = @current_environment = options[:base_environment] - @parser = Sexpistol.new - @parser.ruby_keyword_literals = false - @parser.scheme_compatability = true - - load_standard_library unless options[:load_standard_library] == false + attr_accessor :base_environment, :current_environment + + def initialize(environment: Environment.new, standard_library: true) + @base_environment = @current_environment = environment + + load_standard_library if standard_library end - + def run(program) - expressions = parse(program) + program = parse(program) result = nil - expressions.each do |expression| - result = evaluate(expression) - end - return result + + + if program.is_a?(Sexpistol::SExpressionArray) + program.each do |expression| + result = evaluate(expression) + end + + else + result = evaluate(program) + end + + result end - - def parse(string) - return @parser.parse_string(string) - end - + def evaluate(expression) return @current_environment.find(expression) if expression.is_a? Symbol return expression unless expression.is_a? Array - - if expression[0] == :define - return @current_environment.define expression[1], evaluate(expression[2]) - - elsif expression[0] == :native_function - return eval expression[1] - - else # function call + + 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 RuntimeError, "\n#{@parser.to_sexp(expression)}\n ^\n\n#{expression[0]} is not a function" unless function.is_a? Proc + 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) - return function.call(arguments, self) + function.call(arguments, self) end end - - private - + + def parse(string) + Sexpistol.parse(string, parse_ruby_keyword_literals: true) + end + + def to_sexp(expression) + Sexpistol.to_sexp(expression, scheme_compatability: true) + end + + private + 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 - end -end \ No newline at end of file +end