voodoo 0.6.2 → 0.6.3

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.
@@ -163,6 +163,11 @@ module Voodoo
163
163
  [:div, :mod, :sub].member?(op)
164
164
  end
165
165
 
166
+ # Test if a value is an at-expression
167
+ def at_expr? value
168
+ value.respond_to?(:[]) && value[0] == :'@'
169
+ end
170
+
166
171
  # Emit function prologue and declare _formals_ as function arguments
167
172
  def begin_function formals, nlocals
168
173
  if @environment != @top_level
@@ -530,6 +535,13 @@ module Voodoo
530
535
  end
531
536
  end
532
537
 
538
+ # Load the value at the given address.
539
+ def load_at address, register = @TEMPORARY
540
+ load_value_into_register address, register
541
+ emit "lw #{register}, 0(#{register})\n"
542
+ register
543
+ end
544
+
533
545
  # Load a value into a register.
534
546
  # Returns the name of the register.
535
547
  # If the value was already in a register, the name of that
@@ -573,6 +585,8 @@ module Voodoo
573
585
  emit "addiu #{register}, %lo(#{x})\n"
574
586
  return register
575
587
  end
588
+ elsif at_expr? x
589
+ load_at x[1], register
576
590
  else
577
591
  raise "Don't know how to load #{x.inspect}"
578
592
  end
@@ -728,7 +742,9 @@ module Voodoo
728
742
  def string value
729
743
  code = ''
730
744
  value.each_byte do |b|
731
- if b >= 32 && b < 128
745
+ if b == 92
746
+ code << "\\\\"
747
+ elsif b >= 32 && b < 127 && b != 34
732
748
  code << b.chr
733
749
  else
734
750
  code << sprintf("\\%03o", b)
@@ -31,29 +31,38 @@ module Voodoo
31
31
  end
32
32
 
33
33
  Tempfile.open(base + '.asm') do |nasmfile|
34
- Tempfile.open(base + '.o') do |elffile|
35
- elffile.close
36
- # Write NASM code to nsamfile
37
- @nasmgenerator.write nasmfile
38
- nasmfile.close
39
- # Find out the name of the nasm executable
40
- if ENV.has_key? 'NASM'
41
- nasm = ENV['NASM']
42
- elsif ENV.has_key? 'YASM'
43
- nasm = ENV['YASM']
44
- else
45
- nasm = Voodoo::Config.nasm_command
34
+ begin
35
+ Tempfile.open(base + '.o') do |elffile|
36
+ begin
37
+ elffile.close
38
+ # Write NASM code to nsamfile
39
+ @nasmgenerator.write nasmfile
40
+ nasmfile.close
41
+ # Find out the name of the nasm executable
42
+ if ENV.has_key? 'NASM'
43
+ nasm = ENV['NASM']
44
+ elsif ENV.has_key? 'YASM'
45
+ nasm = ENV['YASM']
46
+ else
47
+ nasm = Voodoo::Config.nasm_command
48
+ end
49
+ # Invoke nasm on nasmfile
50
+ command = "#{nasm} #{@nasm_extra_args}" +
51
+ " -o #{shell_encode elffile.path}" +
52
+ " #{shell_encode nasmfile.path}"
53
+ if system(command)
54
+ write_file_to_io elffile.path, io
55
+ else
56
+ raise "Command (#{command}) failed " +
57
+ " with status #{$?.exitstatus}"
58
+ end
59
+ ensure
60
+ elffile.unlink
61
+ end
46
62
  end
47
- # Invoke nasm on nasmfile
48
- command = "#{nasm} #{@nasm_extra_args}" +
49
- " -o #{shell_encode elffile.path}" +
50
- " #{shell_encode nasmfile.path}"
51
- if system(command)
52
- write_file_to_io elffile.path, io
53
- end
54
- elffile.unlink
63
+ ensure
64
+ nasmfile.unlink
55
65
  end
56
- nasmfile.unlink
57
66
  end
58
67
  end
59
68
  end
@@ -88,7 +88,7 @@ module Voodoo
88
88
  code = ''
89
89
  in_quote = false
90
90
  value.each_byte do |b|
91
- if b >= 32 && b < 128
91
+ if b >= 32 && b < 127 && b != 39
92
92
  if in_quote
93
93
  code << b.chr
94
94
  else
@@ -185,6 +185,11 @@ module Voodoo
185
185
  # == Value Classification
186
186
  #
187
187
 
188
+ # Test if a value is an at-expression
189
+ def at_expr? value
190
+ value.respond_to?(:[]) && value[0] == :'@'
191
+ end
192
+
188
193
  # Test if op is a binary operation
189
194
  def binop? op
190
195
  [:div, :mod, :sub].member?(op) || symmetric_operation?(op)
@@ -271,6 +276,17 @@ module Voodoo
271
276
  end
272
277
  end
273
278
 
279
+ # Load the value at the given address.
280
+ # Invoking this code may clobber @BX.
281
+ def load_at address, reg = @SCRATCH_REG
282
+ if integer?(address) || global?(address)
283
+ "[#{address}]"
284
+ else
285
+ load_value_into_register address, @BX
286
+ "[#{@BX}]"
287
+ end
288
+ end
289
+
274
290
  # Load the value associated with the given symbol.
275
291
  # Returns a string that can be used to refer to the loaded value.
276
292
  def load_symbol symbol, reg = @SCRATCH_REG
@@ -298,6 +314,20 @@ module Voodoo
298
314
  value
299
315
  elsif symbol? value
300
316
  load_symbol value, reg
317
+ elsif at_expr? value
318
+ load_at value[1], reg
319
+ else
320
+ raise "Don't know how to load #{value.inspect}"
321
+ end
322
+ end
323
+
324
+ # Load a value into a register.
325
+ def load_value_into_register value, register
326
+ load_code = load_value(value), register
327
+ if load_code == register.to_s
328
+ load_code
329
+ else
330
+ "mov #{register}, #{load_code}\n"
301
331
  end
302
332
  end
303
333
 
data/lib/voodoo/parser.rb CHANGED
@@ -108,8 +108,23 @@ module Voodoo
108
108
  when /\s/
109
109
  # Skip whitespace
110
110
  consume
111
+ when '@'
112
+ # Parse at-expression.
113
+ # '@' must be followed by a number or symbol.
114
+ consume
115
+ case lookahead
116
+ when /\d|-/
117
+ expr = parse_number
118
+ when /\w|\\/
119
+ expr = parse_symbol
120
+ else
121
+ raise "Invalid character (#{@lookahead.chr.inspect})" +
122
+ " at #{@line}:#{@char}; expecting number or symbol"
123
+ end
124
+ words << [:'@', expr]
111
125
  else
112
- raise "Invalid character (#{@lookahead}) at #{@line}:#{@char}"
126
+ raise "Invalid character (#{@lookahead.chr.inspect})" +
127
+ " at #{@line}:#{@char}"
113
128
  end
114
129
  end
115
130
 
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ hash: 1
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 3
10
+ version: 0.6.3
5
11
  platform: ruby
6
12
  authors:
7
13
  - Robbert Haarman
@@ -9,7 +15,7 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-05-05 00:00:00 +02:00
18
+ date: 2010-11-21 00:00:00 +01:00
13
19
  default_executable:
14
20
  dependencies: []
15
21
 
@@ -29,7 +35,6 @@ extensions: []
29
35
  extra_rdoc_files: []
30
36
 
31
37
  files:
32
- - bin/ast.rb
33
38
  - bin/voodooc
34
39
  - lib/voodoo.rb
35
40
  - lib/voodoo/parser.rb
@@ -61,21 +66,27 @@ rdoc_options:
61
66
  require_paths:
62
67
  - lib
63
68
  required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
64
70
  requirements:
65
71
  - - ">="
66
72
  - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
67
76
  version: "0"
68
- version:
69
77
  required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
70
79
  requirements:
71
80
  - - ">="
72
81
  - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
73
85
  version: "0"
74
- version:
75
86
  requirements: []
76
87
 
77
88
  rubyforge_project: voodoo
78
- rubygems_version: 1.3.5
89
+ rubygems_version: 1.3.7
79
90
  signing_key:
80
91
  specification_version: 3
81
92
  summary: Compiler for the Voodoo programming language
data/bin/ast.rb DELETED
@@ -1,47 +0,0 @@
1
- module Ast
2
- # A program consists of zero or more elements,
3
- # each one of which can be a label, an action,
4
- # a function definition, or a comment
5
- class Program
6
- def initialize elements
7
- @elements = elements
8
- end
9
- attr_accessor :elements
10
- end
11
-
12
- # A comment contains text
13
- class Comment
14
- def initialize text
15
- @text = text
16
- end
17
- attr_accessor :text
18
- end
19
-
20
- # A label contains text
21
- class Label
22
- def initialize text
23
- @text = text
24
- end
25
- attr_accessor :text
26
- end
27
-
28
- # A function definition has an argument list and contains
29
- # a number of actions and/or comments
30
- class Function
31
- def initialize args, actions
32
- @args = args
33
- @statements = actions
34
- end
35
- attr_accessor :args, :actions
36
- end
37
-
38
- # An action contains an operation and zero or more
39
- # arguments
40
- class Action
41
- def initialize op, args
42
- @op = op
43
- @args = args
44
- end
45
- attr_accessor :op, :args
46
- end
47
- end