From 235cc69fb9d3cb07b5270ee7096aa12a6178fa2f Mon Sep 17 00:00:00 2001 From: inglorion Date: Sat, 26 Sep 2009 11:18:24 +0200 Subject: [PATCH] Added functions to select code generator based on architecture and format. --- lib/ruby/voodoo/code_generator.rb | 48 ++++++++++++++++++++-- .../voodoo/generators/common_code_generator.rb | 4 +- lib/ruby/voodoo/generators/i386_nasm_generator.rb | 9 +++- src/voodooc | 10 ++--- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/lib/ruby/voodoo/code_generator.rb b/lib/ruby/voodoo/code_generator.rb index 4b9b505..c613c73 100644 --- a/lib/ruby/voodoo/code_generator.rb +++ b/lib/ruby/voodoo/code_generator.rb @@ -1,7 +1,49 @@ +module Voodoo + # Module for selecting code generators. + module CodeGenerator + # Hash using target architectures as keys. + # Each entry is a hash mapping output format to generator class. + @@generators = {} + + module_function + + # Register a code generator. + # Example: + # Voodoo::CodeGenerator.register_generator I386NasmGenerator, + # :architecture => :i386, + # :format => :nasm + def register_generator klass, params + if params.has_key?(:architecture) && params.has_key?(:format) + arch = params[:architecture].to_sym + format = params[:format].to_sym + format_hash = @@generators[arch] || {} + format_hash[format] = klass + @@generators[arch] = format_hash + else + raise ArgumentError, "Need to specify :architecture and :format" + end + end + + # Gets a code generator for the specified parameters + def get_generator params + if params.has_key?(:architecture) && params.has_key?(:format) + arch = params[:architecture].to_sym + format = params[:format].to_sym + format_hash = @@generators[arch] + klass = format_hash ? format_hash[format] : nil + if klass + return klass.new params + else + raise NotImplementedError, "No code generator for architecture #{arch} and format #{format}" + end + else + raise ArgumentError, "Need to specify :architecture and :format" + end + end + end +end + # Load generators Dir.glob(File.join(File.dirname(__FILE__), 'generators', '*.rb')).each { |file| require file } - -module Voodoo -end diff --git a/lib/ruby/voodoo/generators/common_code_generator.rb b/lib/ruby/voodoo/generators/common_code_generator.rb index f523a76..9ac9dd5 100644 --- a/lib/ruby/voodoo/generators/common_code_generator.rb +++ b/lib/ruby/voodoo/generators/common_code_generator.rb @@ -1,7 +1,9 @@ module Voodoo # Common base class for code generators class CommonCodeGenerator - def initialize + def initialize params + @architecture = params[:architecture] + @format = params[:format] @sections = { 'code' => '' } @section = "code" @top_level = Environment.initial_environment diff --git a/lib/ruby/voodoo/generators/i386_nasm_generator.rb b/lib/ruby/voodoo/generators/i386_nasm_generator.rb index 9d9cd7a..eeb27ea 100644 --- a/lib/ruby/voodoo/generators/i386_nasm_generator.rb +++ b/lib/ruby/voodoo/generators/i386_nasm_generator.rb @@ -17,8 +17,8 @@ module Voodoo class I386NasmGenerator < CommonCodeGenerator WORDSIZE = 4 - def initialize - super + def initialize params + super params @if_labels = [] end @@ -698,4 +698,9 @@ module Voodoo end end end + + # Register class + Voodoo::CodeGenerator.register_generator I386NasmGenerator, + :architecture => :i386, + :format => :nasm end diff --git a/src/voodooc b/src/voodooc index cd6263b..fc022cb 100755 --- a/src/voodooc +++ b/src/voodooc @@ -23,6 +23,7 @@ EOT input_file = nil output_file = nil +architecture = :i386 output_format = :elf # @@ -62,13 +63,8 @@ else end # Select code generator based on output format -case output_format -when :nasm - generator = Voodoo::I386NasmGenerator.new -else - $stderr.puts "Unknown output format: #{output_format}" - $stderr.puts "Supported formats are:\nnasm" -end +generator = Voodoo::CodeGenerator.get_generator :architecture => architecture, + :format => output_format # Set output_file if not already set output_file = generator.output_file_name input_file unless output_file -- 2.11.4.GIT