2 # Common base class for code generators
3 class CommonCodeGenerator
5 @sections = { 'code' => '' }
7 @top_level = Environment.initial_environment
8 @environment = @top_level
14 # add_code [:call, :exit, 0]
17 actions.each do |action|
18 keyword, args = action[0], action[1..-1]
25 send :tail_call, *args
26 when :call, :goto, :let, :set
29 raise "Invalid action: #{action[0]}"
35 # Add a label at the current address in the code section.
36 def add_code_label name
37 raise NoSuchMethodError, 'TODO'
42 # add_data [:word, 42]
46 keyword, args = defn[0], defn[1..-1]
53 raise "Invalid directive in data section: #{defn[0]}"
59 # Add a label at the current address in the data section.
60 def add_data_label name
61 raise NoSuchMethodError, 'TODO'
66 # add_data [:word, 42]
67 def add_function formals, *code
69 begin_function formals
75 # Add a label at the address where the next function will be generated.
76 def add_function_label name
77 raise NoSuchMethodError, 'TODO'
80 # Set the current section
83 unless @sections.has_key? section
84 @sections[section] = ''
88 def section name = nil
89 section = name if name
93 def in_section name, &block
103 attr_reader :args, :locals, :symbols
105 def initialize parent = nil
106 ## Parent environment
108 ## Symbol lookup table
109 @symbols = parent ? parent.symbols.dup : {}
110 ## Number of arguments
111 @args = parent ? parent.args : 0
112 ## Number of local variables
113 @locals = parent ? parent.locals : 0
117 @symbols[symbol] = [:arg, @args]
122 symbols.each { |sym| add_arg sym }
126 @symbols[symbol] = [:local, @locals]
127 @locals = @locals + 1
130 def add_locals symbols
131 symbols.each { |sym| add_local sym }
135 @@gensym_counter = @@gensym_counter + 1
136 ".G#{@@gensym_counter}"
143 def self.initial_environment