class Yoda::Evaluation::Evaluator

Attributes

registry[R]

@return [Store::Registry]

scope[R]

@return [Parsing::Scopes::Base]

Public Class Methods

from_ast(registry, ast, location) click to toggle source

@param registry [Store::Registry] @param ast [Parser::AST::Node] @param location [Parsing::Location] @return [Evaluator]

# File lib/yoda/evaluation/evaluator.rb, line 14
def self.from_ast(registry, ast, location)
  from_root_scope(registry, Parsing::Scopes::Builder.new(ast).root_scope, location)
end
from_root_scope(registry, root_scope, location) click to toggle source

@param registry [Store::Registry] @param root_scope [Parsing::Scopes::Root] @param location [Parsing::Location] @return [Evaluator]

# File lib/yoda/evaluation/evaluator.rb, line 22
def self.from_root_scope(registry, root_scope, location)
  new(registry, root_scope.find_evaluation_root_scope(location) || root_scope)
end
new(registry, scope) click to toggle source

@param registry [Store::Registry] @param scope [Parsing::Scopes::Base]

# File lib/yoda/evaluation/evaluator.rb, line 28
def initialize(registry, scope)
  @registry = registry
  @scope = scope
end

Public Instance Methods

calculate_trace(code_node) click to toggle source

@param code_node [::Parser::AST::Node, nil] @return [Typing::Traces::Base, nil]

# File lib/yoda/evaluation/evaluator.rb, line 48
def calculate_trace(code_node)
  return nil unless code_node
  evaluate
  evaluator.find_trace(code_node)
end
calculate_type(code_node) click to toggle source

@param code_node [::Parser::AST::Node] @return [Model::Types::Base, nil]

# File lib/yoda/evaluation/evaluator.rb, line 35
def calculate_type(code_node)
  calculate_trace(code_node)&.type
end
calculate_values(code_node) click to toggle source

@param code_node [::Parser::AST::Node] @return [Array<Store::Objects::Base>]

# File lib/yoda/evaluation/evaluator.rb, line 41
def calculate_values(code_node)
  trace = calculate_trace(code_node)
  trace ? trace.values : []
end
scope_constant() click to toggle source

@return [Store::Objects::Base, nil]

# File lib/yoda/evaluation/evaluator.rb, line 55
def scope_constant
  @scope_constant ||= begin
    Store::Query::FindConstant.new(registry).find(scope.scope_name)
  end
end

Private Instance Methods

current_method_signature() click to toggle source

@return [Model::FunctionSignatures::Base, nil]

# File lib/yoda/evaluation/evaluator.rb, line 88
def current_method_signature
  return unless scope.kind == :method
  @current_method_signature ||= Store::Query::FindSignature.new(registry).select(scope_constant, scope.name.to_s)&.first
end
evaluate() click to toggle source
# File lib/yoda/evaluation/evaluator.rb, line 63
def evaluate
  unless @evaluated
    evaluator.process(scope.body_node)
    @evaluated = true
  end
end
evaluation_context() click to toggle source

@return [Typing::Context]

# File lib/yoda/evaluation/evaluator.rb, line 76
def evaluation_context
  @evaluation_context ||= begin
    fail RuntimeError, "The namespace #{scope.scope_name} (#{scope}) is not registered" unless scope_constant
    fail RuntimeError, "The namespace for #{scope} (#{scope.scope_name}) is not registered" unless receiver
    lexical_scope = Typing::LexicalScope.new(scope_constant, scope.ancestor_scopes)
    context = Typing::Context.new(registry: registry, caller_object: receiver, lexical_scope: lexical_scope)
    context.env.bind_method_parameters(current_method_signature) if current_method_signature
    context
  end
end
evaluator() click to toggle source

@return [Typing::Evaluator]

# File lib/yoda/evaluation/evaluator.rb, line 71
def evaluator
  @evaluator ||= Typing::Evaluator.new(evaluation_context)
end
receiver() click to toggle source

@return [Store::Objects::Base, nil]

# File lib/yoda/evaluation/evaluator.rb, line 94
def receiver
  @receiver ||= begin
    if scope.kind == :method
      Store::Query::FindConstant.new(registry).find(scope.scope_name)
    else
      Store::Query::FindMetaClass.new(registry).find(scope.scope_name)
    end
  end
end