Class: Kalculator::Evaluator

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

Instance Method Summary collapse

Constructor Details

#initialize(data_source, custom_functions = {}) ⇒ Evaluator

Returns a new instance of Evaluator.



4
5
6
7
8
# File 'lib/kalculator/evaluator.rb', line 4

def initialize(data_source, custom_functions = {})

  @data_source = data_source
  @functions = Kalculator::BUILT_IN_FUNCTIONS.merge(custom_functions)
end

Instance Method Details

#!=(_, left, right, metadata) ⇒ Object



65
66
67
# File 'lib/kalculator/evaluator.rb', line 65

def !=(_, left, right, )
  evaluate(left) != evaluate(right)
end

#*(_, left, right, metadata) ⇒ Object



37
38
39
# File 'lib/kalculator/evaluator.rb', line 37

def *(_, left, right, )
  evaluate(left) * evaluate(right)
end

#+(_, left, right, metadata) ⇒ Object



29
30
31
# File 'lib/kalculator/evaluator.rb', line 29

def +(_, left, right, )
  evaluate(left) + evaluate(right)
end

#-(_, left, right, metadata) ⇒ Object



33
34
35
# File 'lib/kalculator/evaluator.rb', line 33

def -(_, left, right, )
  evaluate(left) - evaluate(right)
end

#/(_, left, right, metadata) ⇒ Object



41
42
43
# File 'lib/kalculator/evaluator.rb', line 41

def /(_, left, right, )
  evaluate(left) / evaluate(right)
end

#<(_, left, right, metadata) ⇒ Object



53
54
55
# File 'lib/kalculator/evaluator.rb', line 53

def <(_, left, right, )
  evaluate(left) < evaluate(right)
end

#<=(_, left, right, metadata) ⇒ Object



57
58
59
# File 'lib/kalculator/evaluator.rb', line 57

def <=(_, left, right, )
  evaluate(left) <= evaluate(right)
end

#==(_, left, right, metadata) ⇒ Object



61
62
63
# File 'lib/kalculator/evaluator.rb', line 61

def ==(_, left, right, )
  evaluate(left) == evaluate(right)
end

#>(_, left, right, metadata) ⇒ Object



45
46
47
# File 'lib/kalculator/evaluator.rb', line 45

def >(_, left, right, )
  evaluate(left) > evaluate(right)
end

#>=(_, left, right, metadata) ⇒ Object



49
50
51
# File 'lib/kalculator/evaluator.rb', line 49

def >=(_, left, right, )
  evaluate(left) >= evaluate(right)
end

#access(_, identifier, object, metadata) ⇒ Object

Raises:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/kalculator/evaluator.rb', line 15

def access(_, identifier, object, )
  a = evaluate(object)
  if(a.key?(identifier))
    b =a[identifier]
    if(b.is_a?(Kalculator::Pointer))
      b = @data_source[b.p]
    end
    if(b.is_a?(Kalculator::AnonymousPointer))
      b = b.p
    end
    return b
  end
  raise UndefinedVariableError.new(), "object #{a} doesn't have attribute #{identifier}"
end

#and(_, left, right, metadata) ⇒ Object



69
70
71
# File 'lib/kalculator/evaluator.rb', line 69

def and(_, left, right, )
  evaluate(left) && evaluate(right)
end

#boolean(_, boolean, _, metadata) ⇒ Object



77
78
79
# File 'lib/kalculator/evaluator.rb', line 77

def boolean(_, boolean,_, )
  boolean
end

#evaluate(ast) ⇒ Object



10
11
12
13
# File 'lib/kalculator/evaluator.rb', line 10

def evaluate(ast)

  send(ast.first, *ast)
end

#exists(_, variable, metadata) ⇒ Object



81
82
83
# File 'lib/kalculator/evaluator.rb', line 81

def exists(_, variable, )
  @data_source.key?(variable)
end

#fn_call(_, fn_name, expressions, metadata) ⇒ Object

Raises:



85
86
87
88
89
90
91
# File 'lib/kalculator/evaluator.rb', line 85

def fn_call(_, fn_name, expressions, )
  key = [fn_name, expressions.count]
  fn = @functions[key]
  raise UndefinedFunctionError.new(), "no such function #{fn_name}/#{expressions.count}" if fn.nil?
  args = expressions.map{|expression| evaluate(expression) }
  return fn.call(*args)
end

#if(_, condition, true_clause, false_clause, metadata) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/kalculator/evaluator.rb', line 93

def if(_, condition, true_clause, false_clause, )
  if evaluate(condition)
    evaluate(true_clause)
  else
    evaluate(false_clause)
  end
end

#list(_, expressions, metadata) ⇒ Object



101
102
103
# File 'lib/kalculator/evaluator.rb', line 101

def list(_, expressions, )
  expressions.map{|expression| evaluate(expression) }
end

#not(_, expression, metadata) ⇒ Object



105
106
107
108
# File 'lib/kalculator/evaluator.rb', line 105

def not(_, expression, )
  bool = evaluate(expression)
  !bool
end

#null(_, _, _, metadata) ⇒ Object



110
111
112
# File 'lib/kalculator/evaluator.rb', line 110

def null(_, _,_, )
  nil
end

#number(_, number, _, metadata) ⇒ Object



114
115
116
# File 'lib/kalculator/evaluator.rb', line 114

def number(_, number,_, )
  number
end

#or(_, left, right, metadata) ⇒ Object



73
74
75
# File 'lib/kalculator/evaluator.rb', line 73

def or(_, left, right, )
  evaluate(left) || evaluate(right)
end

#percent(_, percent, _, metadata) ⇒ Object



118
119
120
# File 'lib/kalculator/evaluator.rb', line 118

def percent(_, percent,_, )
  percent / 100.0
end

#string(_, string, _, metadata) ⇒ Object



122
123
124
# File 'lib/kalculator/evaluator.rb', line 122

def string(_, string,_, )
  string
end

#variable(_, name, metadata) ⇒ Object

Raises:



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/kalculator/evaluator.rb', line 126

def variable(_, name, )
  raise UndefinedVariableError.new(), "undefined variable #{name}" unless @data_source.key?(name)
  a = @data_source[name]
  if(a.is_a?(Pointer))
    a = @data_source[a.p]
  end
  if(a.is_a?(Kalculator::AnonymousPointer))
    a = a.p
  end
  return a
end