Class: CSVPlusPlus::Runtime::Runtime

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/csv_plus_plus/runtime/runtime.rb

Overview

The runtime state of the compiler (the current line_number/row_index, cell being processed, etc) for parsing a given file. We take multiple runs through the input file for parsing so it’s really convenient to have a central place for these things to be managed.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_code:, position: nil, scope: nil) ⇒ Runtime

Returns a new instance of Runtime.

Parameters:

  • position (Position, nil) (defaults to: nil)

    The (optional) position to start at

  • source_code (SourceCode)

    The source code being compiled

  • scope (Runtime::Scope, nil) (defaults to: nil)

    The (optional) scope if it already exists



35
36
37
38
39
40
41
42
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 35

def initialize(source_code:, position: nil, scope: nil)
  @source_code = source_code
  @scope = ::T.let(scope || ::CSVPlusPlus::Runtime::Scope.new, ::CSVPlusPlus::Runtime::Scope)
  @position = ::T.let(
    position || ::CSVPlusPlus::Runtime::Position.new(source_code.input),
    ::CSVPlusPlus::Runtime::Position
  )
end

Instance Attribute Details

#positionRuntime::Position (readonly)

Returns the current value of position.

Returns:



13
14
15
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 13

def position
  @position
end

#scopeRuntime::Scope (readonly)

Returns the current value of scope.

Returns:



13
14
15
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 13

def scope
  @scope
end

#source_codeSourceCode (readonly)

Returns the current value of source_code.

Returns:

  • (SourceCode)

    the current value of source_code



13
14
15
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 13

def source_code
  @source_code
end

Instance Method Details

#bind_variable_in_expand(var_id, expand) ⇒ Entities::Reference

Bind var_id relative to a cell relative to an ![[expand]] modifier. The variable can only be referenced inside rows of that expand.

Parameters:

  • var_id (Symbol)

    The name of the variable to bind the cell reference to

  • expand (Expand)

    The expand where the variable is accessible (where it will be bound relative to)

Returns:



68
69
70
71
72
73
74
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 68

def bind_variable_in_expand(var_id, expand)
  ::CSVPlusPlus::Entities::Reference.new(
    a1_ref: ::CSVPlusPlus::A1Reference.new(scoped_to_expand: expand, cell_index: position.cell_index)
  ).tap do |var|
    scope.def_variable(var_id, var)
  end
end

#bind_variable_to_cell(var_id) ⇒ Entities::Reference

Bind var_id to the current cell

Parameters:

  • var_id (Symbol)

    The name of the variable to bind the cell reference to

Returns:



50
51
52
53
54
55
56
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 50

def bind_variable_to_cell(var_id)
  ::CSVPlusPlus::Entities::Reference.new(
    a1_ref: ::CSVPlusPlus::A1Reference.new(cell_index: position.cell_index, row_index: position.row_index)
  ).tap do |var|
    scope.def_variable(var_id, var)
  end
end

#parsing_csv_section?T::Boolean

Is the parser currently inside of the CSV section?

Returns:

  • (T::Boolean)


80
81
82
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 80

def parsing_csv_section?
  source_code.in_csv_section?(position.line_number)
end

#resolve_cell_value(ast) ⇒ Entity

Resolve all values in the ast of the current cell being processed

rubocop:disable Metrics/MethodLength

Parameters:

Returns:

  • (Entity)

    The AST with all references replaced



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 91

def resolve_cell_value(ast)
  last_round = nil
  ::Kernel.loop do
    refs = ::CSVPlusPlus::Runtime::References.extract(ast, position, scope)
    return ast if refs.empty?

    # TODO: throw a +CompilerError+ here instead I think - basically we did a round and didn't make progress
    return ast if last_round == refs

    ast = scope.resolve_functions(
      position,
      scope.resolve_variables(position, ast, refs.variables),
      refs.functions
    )
  end
end

#start!(&block) ⇒ Object

Each time we run a parse on the input, reset the runtime state starting at the beginning of the file rubocop:disable Naming/BlockForwarding



114
115
116
117
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 114

def start!(&block)
  position.line_number = 1
  position.start!(&block)
end

#start_at_csv!(&block) ⇒ Object

Reset the runtime state starting at the CSV section rubocop:disable Naming/BlockForwarding



125
126
127
128
# File 'lib/csv_plus_plus/runtime/runtime.rb', line 125

def start_at_csv!(&block)
  position.line_number = source_code.length_of_code_section + 1
  position.start!(&block)
end