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