voodoo 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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