cast 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -401,13 +401,6 @@ module C
401
401
  initializer :cond, :then, :else
402
402
  end
403
403
  ###
404
- ### Sizeof
405
- ###
406
- class Sizeof
407
- child :expr
408
- initializer :expr
409
- end
410
- ###
411
404
  ### Variable
412
405
  ###
413
406
  class Variable
@@ -444,6 +437,13 @@ module C
444
437
  initializer :expr
445
438
  end
446
439
  ###
440
+ ### Sizeof
441
+ ###
442
+ class Sizeof
443
+ child :expr
444
+ initializer :expr
445
+ end
446
+ ###
447
447
  ### Positive
448
448
  ###
449
449
  class Positive
@@ -849,6 +849,7 @@ module C
849
849
  ###
850
850
  class StringLiteral
851
851
  field :val
852
+ field :wide?
852
853
  initializer :val
853
854
  end
854
855
  ###
@@ -856,6 +857,7 @@ module C
856
857
  ###
857
858
  class CharLiteral
858
859
  field :val
860
+ field :wide?
859
861
  initializer :val
860
862
  end
861
863
  ###
@@ -872,6 +874,7 @@ module C
872
874
  class IntLiteral
873
875
  field :val
874
876
  field :format, :dec
877
+ field :suffix
875
878
  initializer :val
876
879
  def dec?
877
880
  format.equal? :dec
@@ -888,6 +891,8 @@ module C
888
891
  ###
889
892
  class FloatLiteral
890
893
  field :val
894
+ field :format, :dec
895
+ field :suffix
891
896
  initializer :val
892
897
  end
893
898
 
@@ -1,33 +1,33 @@
1
1
  ###
2
2
  ### ##################################################################
3
3
  ###
4
- ### Node#to_debug.
4
+ ### Node#inspect.
5
5
  ###
6
6
  ### ##################################################################
7
7
  ###
8
8
 
9
9
  module C
10
10
  class Node
11
- TO_DEBUG_TAB = ' '
12
- def to_debug
13
- return Node.to_debug1(self)
11
+ INSPECT_TAB = ' '
12
+ def inspect
13
+ return Node.inspect1(self)
14
14
  end
15
15
 
16
- def Node.to_debug1 x, prefix='', indent=0, is_child=true
16
+ def Node.inspect1 x, prefix='', indent=0, is_child=true
17
17
  case x
18
18
  when NodeList
19
19
  if x.empty?
20
- return "#{TO_DEBUG_TAB*indent}#{prefix}[]\n"
20
+ return "#{INSPECT_TAB*indent}#{prefix}[]\n"
21
21
  else
22
- str = "#{TO_DEBUG_TAB*indent}#{prefix}\n"
22
+ str = "#{INSPECT_TAB*indent}#{prefix}\n"
23
23
  x.each do |el|
24
- str << to_debug1(el, "- ", indent+1)
24
+ str << inspect1(el, "- ", indent+1)
25
25
  end
26
26
  return str
27
27
  end
28
28
  when Node
29
29
  classname = x.class.name.gsub(/^C::/, '')
30
- str = "#{TO_DEBUG_TAB*indent}#{prefix}#{classname}"
30
+ str = "#{INSPECT_TAB*indent}#{prefix}#{classname}"
31
31
 
32
32
  fields = x.fields
33
33
  bools, others = fields.partition{|field| field.reader.to_s[-1] == ??}
@@ -45,13 +45,13 @@ module C
45
45
  ## don't bother with non-child Nodes, since they may cause
46
46
  ## loops in the tree
47
47
  (val.is_a?(Node) && !field.child?)
48
- str << to_debug1(val, "#{field.reader}: ", indent+1, field.child?)
48
+ str << inspect1(val, "#{field.reader}: ", indent+1, field.child?)
49
49
  end
50
50
  return str
51
51
  when Symbol
52
- return "#{TO_DEBUG_TAB*indent}#{prefix}#{x}\n"
52
+ return "#{INSPECT_TAB*indent}#{prefix}#{x}\n"
53
53
  else
54
- return "#{TO_DEBUG_TAB*indent}#{prefix}#{x.inspect}\n"
54
+ return "#{INSPECT_TAB*indent}#{prefix}#{x.inspect}\n"
55
55
  end
56
56
  return s.string
57
57
  end
File without changes
@@ -451,7 +451,11 @@ module C
451
451
  removed_(ret)
452
452
  return ret
453
453
  else
454
- ret = @array.pop(*args)
454
+ args.length == 1 or
455
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 0..1)"
456
+ arg = args[0]
457
+ arg = @array.length if @array.length < arg
458
+ ret = @array.slice!(-arg, arg)
455
459
  removed_ *ret
456
460
  return ret
457
461
  end
@@ -461,7 +465,11 @@ module C
461
465
  ret = @array.shift
462
466
  removed_ ret
463
467
  else
464
- ret = @array.shift(*args)
468
+ args.length == 1 or
469
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 0..1)"
470
+ arg = args[0]
471
+ arg = @array.length if @array.length < arg
472
+ ret = @array.slice!(0, arg)
465
473
  removed_ *ret
466
474
  end
467
475
  adjust_indices_(0)
File without changes
@@ -301,7 +301,12 @@ module C
301
301
  else
302
302
  rvalstr = "#{rval}"
303
303
  end
304
- "#{lval} #{op}= #{rvalstr}"
304
+ if lval.to_s_precedence < self.to_s_precedence
305
+ lvalstr = "(#{lval})"
306
+ else
307
+ lvalstr = "#{lval}"
308
+ end
309
+ "#{lvalstr} #{op}= #{rvalstr}"
305
310
  end
306
311
  end
307
312
  ## Other Expressions
@@ -470,7 +475,11 @@ module C
470
475
  class Parameter
471
476
  def to_s
472
477
  str = register? ? 'register ' : ''
473
- str << type.to_s(name)
478
+ if type
479
+ str << type.to_s(name)
480
+ else
481
+ str << name.to_s
482
+ end
474
483
  end
475
484
  end
476
485
 
@@ -490,7 +499,7 @@ module C
490
499
  str = ''
491
500
  type and
492
501
  str << "(#{type}) "
493
- str << "{\n" << indent(inits.join(",\n")) << "\n}"
502
+ str << "{\n" << indent(member_inits.join(",\n")) << "\n}"
494
503
  end
495
504
  end
496
505
  class MemberInit
@@ -1,5 +1,207 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- Dir.new(Dir.pwd).grep(/^test_/) do |filename|
4
- require "#{Dir.pwd}/#{filename}"
3
+ require 'test/unit'
4
+ require 'stringio'
5
+
6
+ # require cast
7
+ CAST_ROOT = File.expand_path('..', File.dirname(__FILE__))
8
+ ENV['CAST_EXTDIR'] = "#{CAST_ROOT}/ext"
9
+ ENV['CAST_LIBDIR'] = "#{CAST_ROOT}/lib/cast"
10
+ require "#{CAST_ROOT}/lib/cast.rb"
11
+
12
+ ###
13
+ ### ------------------------------------------------------------------
14
+ ### Helpers for testing
15
+ ### ------------------------------------------------------------------
16
+ ###
17
+
18
+ class Array
19
+ def same_list? other
20
+ self.length == other.length or
21
+ return false
22
+ self.zip(other).all? do |mine, yours|
23
+ mine.equal? yours or
24
+ return false
25
+ end
26
+ end
27
+ end
28
+
29
+ class Integer
30
+ ###
31
+ ### Return a `self'-element array containing the result of the given
32
+ ### block.
33
+ ###
34
+ def of &blk
35
+ Array.new(self, &blk)
36
+ end
37
+ end
38
+
39
+ module Test::Unit::Assertions
40
+ INDENT = ' '
41
+ ###
42
+ ### Assert that the given string is parsed as expected. The given
43
+ ### string is of the format:
44
+ ###
45
+ ### <program>
46
+ ### ----
47
+ ### <expected inspect string>
48
+ ###
49
+ ### The <program> part is yielded to obtain the AST.
50
+ ###
51
+ def check_ast test_data
52
+ inp, exp = test_data.split(/^----+\n/)
53
+ ast = yield(inp)
54
+ assert_tree(ast)
55
+ assert(ast.is_a?(C::Node))
56
+ assert_equal_inspect_strs(exp, ast.inspect)
57
+ end
58
+ ###
59
+ ### Assert that the given Node#inspect strings are equal.
60
+ ###
61
+ def assert_equal_inspect_strs exp, out
62
+ ## remove EOL space
63
+ out = out.gsub(/ *$/, '')
64
+ exp = exp.gsub(/ *$/, '')
65
+
66
+ ## normalize BOL space
67
+ exp.gsub!(%r'^#{INDENT}*') do |s|
68
+ levels = s.length / INDENT.length
69
+ C::Node::INSPECT_TAB*levels
70
+ end
71
+
72
+ ## compare
73
+ msg = "Debug strings unequal:\n#{juxtapose('Expected', exp, 'Output', out)}"
74
+ assert_block(msg){out == exp}
75
+ end
76
+ ###
77
+ ### Return a string of `s1' and `s2' side by side with a dividing
78
+ ### line in between indicating differences. `h1' and `h2' are the
79
+ ### column headings.
80
+ ###
81
+ def juxtapose h1, s1, h2, s2
82
+ s1 = s1.map{|line| line.chomp}
83
+ s2 = s2.map{|line| line.chomp}
84
+ rows = [s1.length, s2.length].max
85
+ wl = s1.map{|line| line.length}.max
86
+ wr = s2.map{|line| line.length}.max
87
+ ret = ''
88
+ ret << "#{('-'*wl)}----#{'-'*wr}\n"
89
+ ret << "#{h1.ljust(wl)} || #{h2}\n"
90
+ ret << "#{('-'*wl)}-++-#{'-'*wr}\n"
91
+ (0...rows).each do |i|
92
+ if i >= s1.length
93
+ ret << "#{' '*wl} > #{s2[i]}\n"
94
+ elsif i >= s2.length
95
+ ret << "#{s1[i].ljust(wl)} <\n"
96
+ elsif s1[i] == s2[i]
97
+ ret << "#{s1[i].ljust(wl)} || #{s2[i]}\n"
98
+ else
99
+ ret << "#{s1[i].ljust(wl)} <> #{s2[i]}\n"
100
+ end
101
+ end
102
+ ret << "#{('-'*wl)}----#{'-'*wr}\n"
103
+ return ret
104
+ end
105
+ ###
106
+ ### Assert that an exception of the given class is raised, and that
107
+ ### the message matches the given regex.
108
+ ###
109
+ def assert_error klass, re
110
+ ex = nil
111
+ assert_raise(klass) do
112
+ begin
113
+ yield
114
+ rescue Exception => ex
115
+ raise
116
+ end
117
+ end
118
+ assert_match(re, ex.message)
119
+ end
120
+ ###
121
+ ### Assert that the given ast's nodes' parents are correct, and
122
+ ### there aren't non-Nodes where there shouldn't be.
123
+ ###
124
+ def assert_tree ast
125
+ meth = 'unknown method'
126
+ caller.each do |line|
127
+ if line =~ /in `(test_.*?)'/ #`
128
+ meth = $1
129
+ break
130
+ end
131
+ end
132
+ filename = "#{self.class}_#{meth}.out"
133
+ begin
134
+ assert_tree1(ast, nil)
135
+ assert(true)
136
+ rescue BadTreeError => e
137
+ require 'pp'
138
+ open("#{filename}", 'w'){|f| PP.pp(ast, f)}
139
+ flunk("#{e.message}. Output dumped to `#{filename}'.")
140
+ end
141
+ end
142
+ ###
143
+ def assert_tree1 x, parent
144
+ if x.is_a? C::Node
145
+ parent.equal? x.parent or
146
+ raise BadTreeError, "#{x.class}:0x#{(x.id << 1).to_s(16)} has #{x.parent ? 'wrong' : 'no'} parent"
147
+ x.fields.each do |field|
148
+ next if !field.child?
149
+ val = x.send(field.reader)
150
+ next if val.nil?
151
+ val.is_a? C::Node or
152
+ raise BadTreeError, "#{x.class}:0x#{(x.id << 1).to_s(16)} is a non-Node child"
153
+ assert_tree1(val, x)
154
+ end
155
+ end
156
+ end
157
+ class BadTreeError < StandardError; end
158
+ ###
159
+ ### Assert that `arg' is a C::NodeList.
160
+ ###
161
+ def assert_list arg
162
+ assert_kind_of(C::NodeList, arg)
163
+ end
164
+ ###
165
+ ### Assert that `arg' is an empty C::NodeList.
166
+ ###
167
+ def assert_empty_list arg
168
+ assert_list arg
169
+ assert(arg.empty?)
170
+ end
171
+ ###
172
+ ### Assert that the elements of exp are the same as those of out,
173
+ ### and are in the same order.
174
+ ###
175
+ def assert_same_list exp, out
176
+ assert_equal(exp.length, out.length, "Checking length")
177
+ (0...exp.length).each do |i|
178
+ assert_same(exp[i], out[i], "At index #{i} (of 0...#{exp.length})")
179
+ end
180
+ end
181
+ ###
182
+ ### Assert that out is ==, but not the same as exp (i.e., it is a
183
+ ### copy).
184
+ ###
185
+ def assert_copy exp, out
186
+ assert_not_same exp, out
187
+ assert_equal exp, out
188
+ end
189
+ ###
190
+ ### Assert the invariants of `node'.
191
+ ###
192
+ def assert_invariants node
193
+ node.assert_invariants(self)
194
+ end
195
+ end
196
+
197
+ ###
198
+ ### ------------------------------------------------------------------
199
+ ### Main
200
+ ### ------------------------------------------------------------------
201
+ ###
202
+
203
+ if $0 == __FILE__
204
+ Dir.new(Dir.pwd).grep(/^test_/) do |filename|
205
+ require "#{Dir.pwd}/#{filename}"
206
+ end
5
207
  end
@@ -1,5 +1,3 @@
1
- require 'common'
2
-
3
1
  ###
4
2
  ### ##################################################################
5
3
  ###
@@ -9,8 +7,6 @@ require 'common'
9
7
  ### ##################################################################
10
8
  ###
11
9
  class MiscTests < Test::Unit::TestCase
12
- include CheckAst
13
-
14
10
  ###
15
11
  ### ----------------------------------------------------------------
16
12
  ### Declarator#
@@ -42,22 +38,22 @@ class MiscTests < Test::Unit::TestCase
42
38
  arr = C::Array.new(C::Pointer.new, C::IntLiteral.new(10))
43
39
  decl.declarators << C::Declarator.new(arr, 'm')
44
40
 
45
- assert_equal_debug_strs(decl.declarators[0].type.to_debug, <<EOS)
41
+ assert_equal_inspect_strs(decl.declarators[0].type.inspect, <<EOS)
46
42
  Int
47
43
  EOS
48
- assert_equal_debug_strs(decl.declarators[1].type.to_debug, <<EOS)
44
+ assert_equal_inspect_strs(decl.declarators[1].type.inspect, <<EOS)
49
45
  Pointer
50
46
  type: Int
51
47
  EOS
52
- assert_equal_debug_strs(decl.declarators[2].type.to_debug, <<EOS)
48
+ assert_equal_inspect_strs(decl.declarators[2].type.inspect, <<EOS)
53
49
  Array
54
50
  type: Int
55
51
  EOS
56
- assert_equal_debug_strs(decl.declarators[3].type.to_debug, <<EOS)
52
+ assert_equal_inspect_strs(decl.declarators[3].type.inspect, <<EOS)
57
53
  Function
58
54
  type: Int
59
55
  EOS
60
- assert_equal_debug_strs(decl.declarators[4].type.to_debug, <<EOS)
56
+ assert_equal_inspect_strs(decl.declarators[4].type.inspect, <<EOS)
61
57
  Array
62
58
  type: Pointer
63
59
  type: Int
@@ -6,16 +6,6 @@
6
6
  ### ##################################################################
7
7
  ###
8
8
 
9
- require 'common'
10
- require 'stringio'
11
-
12
- require 'pp'
13
- class C::Node
14
- def pretty_print q
15
- q.text self.to_debug
16
- end
17
- end
18
-
19
9
  Chain = C::NodeChain
20
10
 
21
11
  ###