2 # Common base class for code generators
3 class CommonCodeGenerator
5 @architecture = params[:architecture]
6 @format = params[:format]
7 @sections = { :code => '' }
9 @top_level = Environment.initial_environment
10 @environment = @top_level
16 # add_code [:call, :exit, 0]
19 actions.each do |action|
20 keyword, args = action[0], action[1..-1]
22 when :ifeq, :ifge, :ifgt, :ifle, :iflt, :ifne
25 send keyword, action[1][0], action[1][1]
27 if falsebody && !falsebody.empty?
35 send :tail_call, *args
43 # Add a label at the current address in the code section.
44 def add_code_label name
45 in_section(:code) { label name }
50 # add_data [:word, 42]
54 keyword, args = defn[0], defn[1..-1]
58 when :byte, :string, :word
61 raise "Invalid directive in data section: #{defn[0]}"
67 # Add a label at the current address in the data section.
68 def add_data_label name
69 in_section(:data) { label name }
74 # add_data [:word, 42]
75 def add_function formals, *code
76 in_section :functions do
77 begin_function *formals
83 # Add a label at the address where the next function will be generated.
84 def add_function_label name
85 in_section(:functions) { label name }
88 # Set the current section
91 unless @sections.has_key? name
96 def section name = nil
97 self.section = name if name
101 def in_section name, &block
102 oldsection = @section
108 # Given an input file name, returns the canonical output file name
109 # for this code generator.
110 def output_file_name input_name
111 input_name.sub(/\.voo$/, '') + '.o'
117 attr_reader :args, :locals, :symbols
119 def initialize parent = nil
120 ## Parent environment
122 ## Symbol lookup table
123 @symbols = parent ? parent.symbols.dup : {}
124 ## Number of arguments
125 @args = parent ? parent.args : 0
126 ## Number of local variables
127 @locals = parent ? parent.locals : 0
131 @symbols[symbol] = [:arg, @args]
136 symbols.each { |sym| add_arg sym }
140 @symbols[symbol] = [:local, @locals]
141 @locals = @locals + 1
144 def add_locals symbols
145 symbols.each { |sym| add_local sym }
149 @@gensym_counter = @@gensym_counter + 1
150 ".G#{@@gensym_counter}"
157 def self.initial_environment