Updated to new Voodoo code generation API.
[antimony.git] / lib / ruby / antimony / generators / common_code_generator.rb
blob402c496b2bc4f449ca9478e98146af09fb5145a1
1 require 'thread'
3 module Antimony
4   # Common base class for code generators.
5   #
6   # Code generators are expected to implement the following methods:
7   #
8   # - #new
9   # - #add
10   # - #add_function
11   # - #gensym
12   # - #output_file_name
13   # - #wordsize
14   # - #write
15   #
16   class CommonCodeGenerator
17     @@gensym_counter = 0
18     @@gensym_mutex = Mutex.new
20     # Initializes the code generator.
21     # _params_ shall be a hash containing parameters to the code generator,
22     # and shall at least contain the keys <tt>:architecture</tt> and
23     # <tt>:format</tt>, specifying the target architecture and output
24     # format, respectively.
25     def initialize params = {}
26       @architecture = params[:architecture] || Config.default_architecture
27       @format = params[:format] || Config.default_format
28       @sections = { :code => '' }
29       @section = :code
30       @temporaries = []
31       @unused_temporaries = []
32       @in_function = false
33     end
35     # Declare that a temporary variable is no longer in use
36     def free_temporary name
37       @unused_temporaries.unshift name
38     end
40     # Generate a new, unused symbol
41     def gensym
42       @@gensym_mutex.synchronize do
43         @@gensym_counter = @@gensym_counter + 1
44         "_G#{@@gensym_counter}".to_sym
45       end
46     end
48     # Get a temporary variable name
49     def get_temporary 
50       if @unused_temporaries.empty?
51         # Generate new name
52         name = gensym
53       else
54         # Reuse a temporary that wasn't in use anymore
55         name = @unused_temporaries.pop
56       end
57       @temporaries.push name
58       name
59     end
61     # Given an input file name, returns the canonical output file name
62     # for this code generator.
63     def output_file_name input_name
64       input_name.sub(/\.sb$/, '') + '.o'
65     end
67   end
68 end