Class: Idl::ForLoopAst

Inherits:
AstNode show all
Includes:
Executable, Returns
Defined in:
lib/idl/ast.rb

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, init, condition, update, stmts) ⇒ ForLoopAst

Returns a new instance of ForLoopAst.



5185
5186
5187
# File 'lib/idl/ast.rb', line 5185

def initialize(input, interval, init, condition, update, stmts)
  super(input, interval, [init, condition, update] + stmts)
end

Instance Method Details

#conditionObject



5181
# File 'lib/idl/ast.rb', line 5181

def condition = @children[1]

#execute_unknown(symtab) ⇒ void Originally defined in module Executable

This method returns an undefined value.

“execute” the statement, forcing any variable assignments to an unknown state This is used down unknown conditional paths.

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Raises:

  • ValueError if some part of the statement cannot be executed at compile time

#initObject



5180
# File 'lib/idl/ast.rb', line 5180

def init = @children[0]

#return_value(symtab) ⇒ Integer, ... Also known as: execute

Evaluate the compile-time return value of this node, or, if the node does not return (e.g., because it is an IfAst but there is no return on the taken path), execute the node and update the symtab

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Returns:

  • (Integer)

    The return value, if it is integral

  • (Boolean)

    The return value, if it is boolean

  • (nil)

    if the return value is not compile-time-known

Raises:

  • ValueError if, during evaluation, a node without a compile-time value is found



5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
# File 'lib/idl/ast.rb', line 5203

def return_value(symtab)
  symtab.push(self)

  begin
    value_result = value_try do
      init.execute(symtab)

      while condition.value(symtab)
        stmts.each do |s|
          if s.is_a?(Returns)
            v = s.return_value(symtab)
            unless v.nil?
              return v
            end
          else
            s.execute(symtab)
          end
        end
        update.execute(symtab)
      end
    end
    value_else(value_result) do
      value_error ""
    end
  ensure
    symtab.pop
  end
  nil
end

#return_values(symtab) ⇒ Array<Integer>, Array<Boolean>

Evaluate all possible compile-time return values of this node, or, if the node does not return (e.g., because it is an IfAst but there is no return on a possible path), execute the node and update the symtab

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Returns:

  • (Array<Integer>)

    The possible return values. Will be an empty array if there are no return values

  • (Array<Boolean>)

    The possible return values. Will be an empty array if there are no return values

Raises:

  • ValueError if, during evaluation, a node without a compile-time value is found



5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
# File 'lib/idl/ast.rb', line 5234

def return_values(symtab)
  value_result = value_try do
    # if there is a known return value, then we are done
    return [return_value(symtab)]
  end
  value_else(value_result) do
    # see if we can collect a list
    values = []
    symtab.push(self)

    begin
      value_result = value_try do
        init.execute(symtab)

        while condition.value(symtab)
          stmts.each do |s|
            if s.is_a?(Returns)
              value_result = value_try do
                v = s.return_value(symtab)
                unless v.nil?
                  return values.push(v).uniq
                end
              end
              value_else(value_result) do
                values += s.return_values(symtab)
              end
            else
              s.execute(symtab)
            end
          end
          update.execute(symtab)
        end
        :ok
      end
    ensure
      symtab.pop
    end

    values.uniq
  end
end

#stmtsObject



5183
# File 'lib/idl/ast.rb', line 5183

def stmts = @children[3..]

#to_idlString

Return valid IDL representation of the node (and its subtree)

Returns:

  • (String)

    IDL code for the node



5280
5281
5282
5283
5284
5285
5286
5287
# File 'lib/idl/ast.rb', line 5280

def to_idl
  idl = "for (#{init.to_idl}; #{condition.to_idl}; #{update.to_idl}) {"
  stmts.each do |s|
    idl << s.to_idl
  end
  idl << "}"
  idl
end

#type_check(symtab) ⇒ void

This method returns an undefined value.

type check this node and all children

Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError

Parameters:

Raises:



5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
# File 'lib/idl/ast.rb', line 5190

def type_check(symtab)
  symtab.push(self)
  init.type_check(symtab)
  condition.type_check(symtab)
  update.type_check(symtab)

  stmts.each do |s|
    s.type_check(symtab)
  end
  symtab.pop
end

#updateObject



5182
# File 'lib/idl/ast.rb', line 5182

def update = @children[2]