Class: TRuby::IR::CodeGenerator

Inherits:
Visitor
  • Object
show all
Defined in:
lib/t_ruby/ir.rb

Overview

Code Generator - Converts IR to Ruby code

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Visitor

#visit, #visit_children, #visit_default

Constructor Details

#initializeCodeGenerator

Returns a new instance of CodeGenerator.



858
859
860
861
# File 'lib/t_ruby/ir.rb', line 858

def initialize
  @output = []
  @indent = 0
end

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



856
857
858
# File 'lib/t_ruby/ir.rb', line 856

def output
  @output
end

Instance Method Details

#generate(program) ⇒ Object



863
864
865
866
867
# File 'lib/t_ruby/ir.rb', line 863

def generate(program)
  @output = []
  visit(program)
  @output.join("\n")
end

#visit_assignment(node) ⇒ Object



907
908
909
# File 'lib/t_ruby/ir.rb', line 907

def visit_assignment(node)
  emit("#{node.target} = #{generate_expression(node.value)}")
end

#visit_block(node) ⇒ Object



903
904
905
# File 'lib/t_ruby/ir.rb', line 903

def visit_block(node)
  node.statements.each { |stmt| visit(stmt) }
end

#visit_conditional(node) ⇒ Object



919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
# File 'lib/t_ruby/ir.rb', line 919

def visit_conditional(node)
  keyword = node.kind == :unless ? "unless" : "if"
  emit("#{keyword} #{generate_expression(node.condition)}")
  @indent += 1
  visit(node.then_branch) if node.then_branch
  @indent -= 1

  if node.else_branch
    emit("else")
    @indent += 1
    visit(node.else_branch)
    @indent -= 1
  end

  emit("end")
end

#visit_interface(node) ⇒ Object



881
882
883
884
885
886
887
888
# File 'lib/t_ruby/ir.rb', line 881

def visit_interface(node)
  # Interfaces are erased in Ruby output
  emit_comment("interface #{node.name}")
  node.members.each do |member|
    emit_comment("  #{member.name}: #{member.type_signature.to_trb}")
  end
  emit_comment("end")
end

#visit_method_def(node) ⇒ Object



890
891
892
893
894
895
896
897
898
899
900
901
# File 'lib/t_ruby/ir.rb', line 890

def visit_method_def(node)
  params_str = node.params.map(&:name).join(", ")
  emit("def #{node.name}(#{params_str})")
  @indent += 1

  if node.body
    visit(node.body)
  end

  @indent -= 1
  emit("end")
end

#visit_program(node) ⇒ Object



869
870
871
872
873
874
# File 'lib/t_ruby/ir.rb', line 869

def visit_program(node)
  node.declarations.each do |decl|
    visit(decl)
    @output << ""
  end
end

#visit_raw_code(node) ⇒ Object



936
937
938
939
940
# File 'lib/t_ruby/ir.rb', line 936

def visit_raw_code(node)
  node.code.each_line do |line|
    emit(line.rstrip)
  end
end

#visit_return(node) ⇒ Object



911
912
913
914
915
916
917
# File 'lib/t_ruby/ir.rb', line 911

def visit_return(node)
  if node.value
    emit("return #{generate_expression(node.value)}")
  else
    emit("return")
  end
end

#visit_type_alias(node) ⇒ Object



876
877
878
879
# File 'lib/t_ruby/ir.rb', line 876

def visit_type_alias(node)
  # Type aliases are erased in Ruby output
  emit_comment("type #{node.name} = #{node.definition.to_trb}")
end