voodoo 0.7.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/voodooc CHANGED
@@ -24,17 +24,31 @@ Valid options are:
24
24
  Select output format. Use -a <architecture> -f help to get a list of
25
25
  supported output formats for architecture.
26
26
 
27
+ --features
28
+ Lists the features supported by this implementation. The features
29
+ are listed in the format <feature name><tab><version>, ordered
30
+ by feature name. The program exits after printing the list of
31
+ features; no compilation is performed.
32
+
33
+ -h
34
+ --help
35
+ Display usage information and exit. No compilation will be performed.
36
+
27
37
  -o <output file>
28
38
  --output <output file>
29
39
  --output-file <output file>
30
40
  Set output file name. The special name '-' causes voodooc to write
31
41
  to standard output.
42
+
43
+ --version
44
+ Display version information and exit. No compilation will be performed.
32
45
  EOT
33
46
 
34
47
  input_file = nil
35
48
  output_file = nil
36
49
  architecture = Voodoo::Config.default_architecture
37
50
  output_format = Voodoo::Config.default_format
51
+ show_features = false
38
52
 
39
53
  #
40
54
  # Process command line
@@ -43,8 +57,10 @@ output_format = Voodoo::Config.default_format
43
57
  opts = GetoptLong.new(
44
58
  ['--help', '-h', GetoptLong::NO_ARGUMENT ],
45
59
  ['--arch', '--architecture', '-a', GetoptLong::REQUIRED_ARGUMENT ],
60
+ ['--features', GetoptLong::NO_ARGUMENT],
46
61
  ['--output-file', '--output', '-o', GetoptLong::REQUIRED_ARGUMENT ],
47
- ['--output-format', '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ]
62
+ ['--output-format', '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
63
+ ['--version', GetoptLong::NO_ARGUMENT]
48
64
  )
49
65
 
50
66
  # Process options
@@ -56,10 +72,16 @@ opts.each do |opt, arg|
56
72
  exit
57
73
  when '--arch'
58
74
  architecture = arg.to_sym
75
+ when '--features'
76
+ show_features = true
59
77
  when '--output-file'
60
78
  output_file = arg
61
79
  when '--output-format'
62
80
  output_format = arg.to_sym
81
+ when '--version'
82
+ puts "#{Voodoo::Config::IMPLEMENTATION_NAME} version " +
83
+ Voodoo::Config::IMPLEMENTATION_VERSION
84
+ exit
63
85
  end
64
86
  end
65
87
 
@@ -77,19 +99,6 @@ if output_format == :help
77
99
  exit
78
100
  end
79
101
 
80
- # Get input file name
81
- if ARGV.length == 1
82
- input_file = ARGV[0]
83
- else
84
- if ARGV.length < 1
85
- $stderr.puts "no input files"
86
- else
87
- $stderr.puts "Too many arguments"
88
- end
89
- $stderr.puts usage
90
- exit 0x80
91
- end
92
-
93
102
  # Select code generator based on output format
94
103
  begin
95
104
  generator = Voodoo::CodeGenerator.get_generator :architecture => architecture,
@@ -107,6 +116,28 @@ rescue NotImplementedError
107
116
  exit 1
108
117
  end
109
118
 
119
+ # If requested, show features and exit
120
+ if show_features
121
+ generator.features.to_a.sort{|x,y| x[0].to_s <=> y[0].to_s}.each do |feature|
122
+ puts "#{feature[0]}\t#{feature[1]}"
123
+ end
124
+ exit
125
+ end
126
+
127
+ # Get input file name
128
+ if ARGV.length == 1
129
+ input_file = ARGV[0]
130
+ else
131
+ if ARGV.length < 1
132
+ $stderr.puts "no input files"
133
+ else
134
+ $stderr.puts "Too many arguments"
135
+ end
136
+ $stderr.puts usage
137
+ exit 0x80
138
+ end
139
+
140
+
110
141
 
111
142
  #
112
143
  # Compile
@@ -135,11 +166,35 @@ begin
135
166
  compiler = Voodoo::Compiler.new parser, generator, outfile
136
167
 
137
168
  compiler.compile
138
- rescue
169
+ rescue => e
139
170
  if output_file != '-'
140
171
  File::unlink(output_file) if File::exists?(output_file)
141
172
  end
142
- raise
173
+
174
+ # If e is a compiler error, iterate over all child errors and
175
+ # print user-friendly messages. Else, re-raise so that the default
176
+ # handling is performed.
177
+ if e.kind_of? Voodoo::Compiler::Error
178
+ e.errors.each do |error|
179
+ message = ''
180
+ if error.start_line != nil
181
+ message << "#{error.start_line}: "
182
+ if error.input_name != nil
183
+ message = "#{error.input_name}:#{message}"
184
+ else
185
+ message = "line #{message}"
186
+ end
187
+ end
188
+ message << error.message
189
+ $stderr.puts message
190
+ if error.text != nil
191
+ $stderr.print "\n #{error.text.gsub("\n", "\n ")}\n"
192
+ end
193
+ end
194
+ exit 1
195
+ else
196
+ raise
197
+ end
143
198
  ensure
144
199
  outfile.close
145
200
  infile.close
@@ -1,3 +1,5 @@
1
+ require 'voodoo/parser'
2
+
1
3
  module Voodoo
2
4
  # Voodoo compiler driver.
3
5
  # The compiler driver reads input from a parser (see
@@ -7,6 +9,20 @@ module Voodoo
7
9
  # An example of its usage can be found on the main page for the
8
10
  # Voodoo module.
9
11
  class Compiler
12
+ class Error < StandardError
13
+ def initialize errors
14
+ @errors = errors
15
+ end
16
+
17
+ attr_reader :errors
18
+
19
+ def message
20
+ msg = ""
21
+ @errors.each {|e| msg << e.message << "\n"}
22
+ msg
23
+ end
24
+ end
25
+
10
26
  # Initialize a compiler.
11
27
  #
12
28
  # Parameters:
@@ -23,23 +39,35 @@ module Voodoo
23
39
  # Perform the compilation.
24
40
  def compile
25
41
  section = :code
42
+ errors = []
26
43
  while true
27
- statement = @parser.parse_top_level
28
-
29
- break if statement == nil
30
- next if statement.empty?
31
-
32
- case statement[0]
33
- when :section
34
- section = statement[1]
35
- when :function
36
- @generator.add section, [:function, statement[1]] + statement[2]
37
- else
38
- @generator.add section, statement
44
+ begin
45
+ statement = @parser.parse_top_level
46
+
47
+ break if statement == nil
48
+ next if statement.empty?
49
+
50
+ case statement[0]
51
+ when :section
52
+ section = statement[1]
53
+ else
54
+ @generator.add section, statement
55
+ end
56
+
57
+ rescue Parser::ParseError => e
58
+ errors << e
59
+ if errors.length >= 100
60
+ raise Error.new(errors)
61
+ end
39
62
  end
63
+
40
64
  end
41
65
 
42
- @generator.write @output
66
+ if errors.empty?
67
+ @generator.write @output
68
+ else
69
+ raise Error.new(errors)
70
+ end
43
71
  end
44
72
  end
45
73
  end
data/lib/voodoo/config.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  module Voodoo
2
2
  # Methods to get and set configuration parameters
3
3
  module Config
4
+ IMPLEMENTATION_NAME = 'Voodoo Compiler'
5
+ IMPLEMENTATION_VERSION = '1.0.0'
6
+
4
7
  # Class that holds configuration parameters
5
8
  class Configuration
6
9
  def initialize
@@ -35,6 +38,8 @@ module Voodoo
35
38
  case arch
36
39
  when 'x86_64', 'amd64'
37
40
  :amd64
41
+ when 'arm'
42
+ :arm
38
43
  when 'i386', 'i686'
39
44
  :i386
40
45
  when 'mips'
@@ -81,6 +81,10 @@ module Voodoo
81
81
  # Stack pointer
82
82
  @SP = 'rsp'
83
83
  super params
84
+ @features.merge! \
85
+ :'bits-per-word' => '64',
86
+ :'byte-order' => 'little-endian',
87
+ :'bytes-per-word' => '8'
84
88
  end
85
89
 
86
90
  #
@@ -0,0 +1,33 @@
1
+ require 'delegate'
2
+ require 'tempfile'
3
+ require 'voodoo/generators/arm_gas_generator'
4
+ require 'voodoo/generators/gas_elf_generator'
5
+
6
+ module Voodoo
7
+ # Generator that produces ELF objects for arm
8
+ class ARMELFGenerator < DelegateClass(ARMGasGenerator)
9
+ def initialize params = {}
10
+ @asmgenerator = ARMGasGenerator.new params
11
+ super(@asmgenerator)
12
+ @elfgenerator = GasELFGenerator.new @asmgenerator
13
+ end
14
+
15
+ def output_file_name input_name
16
+ @elfgenerator.output_file_name input_name
17
+ end
18
+
19
+ def output_file_suffix
20
+ @elfgenerator.output_file_suffix
21
+ end
22
+
23
+ def write io
24
+ @elfgenerator.write io
25
+ end
26
+ end
27
+
28
+ # Register class for arm
29
+ Voodoo::CodeGenerator.register_generator ARMELFGenerator,
30
+ :architecture => :arm,
31
+ :format => :elf
32
+
33
+ end