Class: Conflisp::Evaluator

Inherits:
Object
  • Object
show all
Defined in:
lib/conflisp/evaluator.rb

Overview

Evaluator takes s-expressions and resolves them into Ruby values

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(registry:, globals:) ⇒ Evaluator

Returns a new instance of Evaluator.



11
12
13
14
# File 'lib/conflisp/evaluator.rb', line 11

def initialize(registry:, globals:)
  @registry = registry
  @globals = globals
end

Instance Attribute Details

#globalsObject (readonly)

Returns the value of attribute globals.



9
10
11
# File 'lib/conflisp/evaluator.rb', line 9

def globals
  @globals
end

#registryObject (readonly)

Returns the value of attribute registry.



9
10
11
# File 'lib/conflisp/evaluator.rb', line 9

def registry
  @registry
end

Instance Method Details

#apply(fn_name, *args) ⇒ Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/conflisp/evaluator.rb', line 40

def apply(fn_name, *args)
  method = registry[fn_name]
  raise Conflisp::MethodMissing, fn_name unless method

  begin
    instance_exec(*args, &method)
  rescue StandardError => e
    raise Conflisp::RuntimeError.new(e, [fn_name, *args])
  end
end

#resolve(expression) ⇒ Object

rubocop:disable Metrics/MethodLength



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/conflisp/evaluator.rb', line 16

def resolve(expression) # rubocop:disable Metrics/MethodLength
  case expression
  when Array
    # In Lisp, Arrays are function calls
    fn_name, *raw_args = expression
    fn_name = fn_name.to_s
    args = raw_args.map { |arg| resolve(arg) }
    if fn_name == 'global'
      globals.dig(*args)
    else
      apply(fn_name, *args)
    end
  when Hash
    expression.transform_values do |value|
      resolve(value)
    end
  else
    expression
  end
rescue Conflisp::ConflispError => e
  e.conflisp_stack << expression
  raise e
end