Class: C::Block

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#temp_localsObject (readonly)

Returns the value of attribute temp_locals.



435
436
437
# File 'lib/csquare.rb', line 435

def temp_locals
  @temp_locals
end

#temp_statementsObject (readonly)

Returns the value of attribute temp_statements.



435
436
437
# File 'lib/csquare.rb', line 435

def temp_statements
  @temp_statements
end

Instance Method Details

#has_local?(var, blueprint = nil) ⇒ Boolean

Does some local exist at the base scope?

Returns:

  • (Boolean)


531
532
533
534
535
536
537
538
# File 'lib/csquare.rb', line 531

def has_local? var, blueprint=nil
  return true if defined?(@temp_locals) && temp_locals.has_key?(var)
  return true if locals.has_key?(var)
  return true if self.parent_function_def.params.has_key?(var)
  return true if self.parent_function_def.has_local?(var)
  return true if !blueprint.nil? && (blueprint.externs.has_key?(var) || blueprint.generator.externs.has_key?(var))
  false
end

#locals(as = nil) ⇒ Object

Return a hash of function local variables => types. You may pass :string as the sole argument if you want

Note: only returns local variables at root scope in the function.



522
523
524
525
526
527
528
# File 'lib/csquare.rb', line 522

def locals(as=nil)
  h = {}
  self.stmts.each do |statement|
    h.merge!(statement.to_h(as)) if statement.Declaration?
  end
  h
end

#new_temp_local(type) ⇒ Object

Create a new temporary variable

Raises:

  • (ArgumentError)


486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'lib/csquare.rb', line 486

def new_temp_local type
  raise(ArgumentError, "type needs to be a string: #{type.inspect}") unless type.is_a?(String)

  @temp_count ||= 0
  @temp_locals ||= {}

  name = "temp#{@temp_count}"
  @temp_count += 1

  parent_fd = parent_function_def

  while parent_fd.has_local?(name) #|| has_local_below?(name) # check for conflicts just in case the programmer put in temp0 or something
    name = "temp#{@temp_count}"
    @temp_count += 1
  end

  @temp_locals[name] = C::CustomType.new(type).clone

  name
end

#new_temp_statement(statement, before_statement) ⇒ Object

Queue a statement for addition before some existing statement.



508
509
510
511
512
513
514
515
516
517
# File 'lib/csquare.rb', line 508

def new_temp_statement statement, before_statement
  @temp_statements ||= []
  begin
    @temp_statements << [C::Statement.parse("#{statement};"), before_statement]
  rescue C::ParseError => e
    STDERR.puts "Exception in new_temp_statement: #{e.inspect}"
    STDERR.puts "statement = #{statement.inspect}"
    raise e
  end
end

#recombine_recursive!(function, blueprint, type_symbol, outside_return_type) ⇒ Object



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/csquare.rb', line 437

def recombine_recursive! function, blueprint, type_symbol, outside_return_type
  result = self.stmts.map do |n|
    replacement, return_type = n.recombine! function, blueprint, type_symbol, outside_return_type
    n.replace_with(replacement) unless replacement.nil? || replacement == n
    return_type # return an array of return types
  end

  before_offset = Hash.new { |h,k| h[k] = 0 }

  # Add temp statements to the beginning of the block
  if defined?(@temp_statements)
    @temp_statements.reverse.each do |statement, before|

      # Figure out the index of the statement that we want to insert before
      before_index = self.stmts.index(before)

      # Account for statements already inserted
      self.stmts.insert(before_index - before_offset[before], statement)
      before_offset[before] += 1 # increment every time a statement is added before some 'before' statement.
    end
  end

  # Add the declarations to the beginning of the block, before the statements
  temp_local_declarations.each do |dec|
    self.stmts.unshift dec
  end

  result
end

#replace_types!(typenames_and_types) ⇒ Object



541
542
543
544
545
546
547
548
549
# File 'lib/csquare.rb', line 541

def replace_types! typenames_and_types
  super typenames_and_types

  self.stmts.each_with_index do |stmt, i|
    next unless stmt.Declaration?
    next unless typenames_and_types.has_key?(stmt.type.underlying_typename)
    stmt.type.underlying_typename = typenames_and_types[stmt.type.underlying_typename]
  end
end

#temp_local_declarationsObject

Create declarations for locals



468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/csquare.rb', line 468

def temp_local_declarations
  by_type = {}

  return [] unless defined?(@temp_locals)

  @temp_locals.each_pair do |name, type|
    by_type[type] ||= C::NodeArray.new
    by_type[type] << C::Declarator.new(:name => name)
  end

  ary = []
  by_type.each_pair do |type, declarators|
    ary << C::Declaration.new(:type => type, :declarators => declarators)
  end
  ary
end