cast 0.0.1 → 0.1.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.
@@ -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
  ###