fixed count_locals_helper so that blocks inside conditionals are considered
[voodoo-lang.git] / lib / voodoo / code_generator.rb
blobe4920913a196b8bf9ff97ee96e6b50458a91b690
1 require 'voodoo/config'
3 module Voodoo
4   # Module for selecting code generators.
5   #
6   # The code generation API is described in Voodoo::CommonCodeGenerator.
7   module CodeGenerator
8     # Hash using target architectures as keys.
9     # Each entry is a hash mapping output format to generator class.
10     @@generators = {}
12     module_function
14     # Registers a code generator.
15     # Example:
16     #   Voodoo::CodeGenerator.register_generator I386NasmGenerator,
17     #                                            :architecture => :i386,
18     #                                            :format => :nasm
19     def register_generator klass, params
20       if params.has_key?(:architecture) && params.has_key?(:format)
21         arch = params[:architecture].to_sym
22         format = params[:format].to_sym
23         format_hash = @@generators[arch] || {}
24         format_hash[format] = klass
25         @@generators[arch] = format_hash
26       else
27         raise ArgumentError, "Need to specify :architecture and :format"
28       end
29     end
31     # Gets a code generator for the specified parameters.
32     def get_generator params = {}
33       params[:architecture] = Config.default_architecture \
34         unless params[:architecture]
35       params[:format] = Config.default_format unless params[:format]
36       arch = params[:architecture].to_sym
37       format = params[:format].to_sym
38       format_hash = @@generators[arch]
39       klass = format_hash ? format_hash[format] : nil
40       if klass
41         return klass.new params
42       else
43         raise NotImplementedError, "No code generator for architecture #{arch} and format #{format}"
44       end
45     end
47     # Tests if a given architecture is supported.
48     def architecture_supported? arch
49       @@generators.has_key? arch.to_sym
50     end
52     # Gets an array of supported architectures.
53     def architectures
54       @@generators.keys
55     end
57     # Tests if a given format is supported for a given architecture.
58     def format_supported? arch, format
59       architecture_supported?(arch.to_sym) &&
60         @@generators[arch.to_sym].has_key?(format.to_sym)
61     end
63     # Gets an array of supported formats for a given architecture.
64     def formats architecture
65       @@generators[architecture.to_sym].keys
66     end
67   end
68 end
70 # Load generators
71 Dir.glob(File.join(File.dirname(__FILE__), 'generators', '*.rb')).each do |file|
72   name = file.sub(/.*(voodoo\/generators\/.*)\.rb/, "\\1")
73   require name
74 end