Class: C::Block
- Inherits:
-
Object
- Object
- C::Block
- Defined in:
- lib/csquare.rb
Instance Attribute Summary collapse
-
#temp_locals ⇒ Object
readonly
Returns the value of attribute temp_locals.
-
#temp_statements ⇒ Object
readonly
Returns the value of attribute temp_statements.
Instance Method Summary collapse
-
#has_local?(var, blueprint = nil) ⇒ Boolean
Does some local exist at the base scope?.
-
#locals(as = nil) ⇒ Object
Return a hash of function local variables => types.
-
#new_temp_local(type) ⇒ Object
Create a new temporary variable.
-
#new_temp_statement(statement, before_statement) ⇒ Object
Queue a statement for addition before some existing statement.
- #recombine_recursive!(function, blueprint, type_symbol, outside_return_type) ⇒ Object
- #replace_types!(typenames_and_types) ⇒ Object
-
#temp_local_declarations ⇒ Object
Create declarations for locals.
Instance Attribute Details
#temp_locals ⇒ Object (readonly)
Returns the value of attribute temp_locals.
435 436 437 |
# File 'lib/csquare.rb', line 435 def temp_locals @temp_locals end |
#temp_statements ⇒ Object (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?
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
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.) stmt.type. = typenames_and_types[stmt.type.] end end |
#temp_local_declarations ⇒ Object
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 |