cast 0.3.0 → 0.4.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.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/CHANGELOG +12 -0
- data/Rakefile +2 -0
- data/ext/cast.h +1 -0
- data/ext/parser.c +2 -0
- data/ext/yylex.c +4346 -5767
- data/ext/yylex.re +3 -0
- data/lib/cast/c.tab.rb +2070 -1415
- data/lib/cast/c.y +12 -3
- data/lib/cast/node.rb +0 -14
- data/lib/cast/node_list.rb +0 -33
- data/lib/cast/preprocessor.rb +4 -2
- data/lib/cast/version.rb +1 -1
- data/lib/cast.rb +1 -0
- data/test/c_nodes_test.rb +2 -2
- data/test/node_list_test.rb +1 -1
- data/test/parse_test.rb +3 -1
- data/test/parser_test.rb +60 -0
- data/test/preprocessor_test.rb +2 -2
- data/test/test_helper.rb +0 -6
- metadata +7 -8
data/lib/cast/c.y
CHANGED
@@ -12,8 +12,11 @@ translation_unit
|
|
12
12
|
|
13
13
|
# Returns Declaration|FunctionDef
|
14
14
|
external_declaration
|
15
|
-
: function_definition
|
16
|
-
| declaration
|
15
|
+
: function_definition {result = val[0]}
|
16
|
+
| declaration {result = val[0]}
|
17
|
+
# GCC EXTENSION: __extension__ can go before any external declaration
|
18
|
+
# this has no effect aside from suppressing certain warnings
|
19
|
+
| EXTENSION external_declaration {result = val[1]}
|
17
20
|
|
18
21
|
# Returns FunctionDef
|
19
22
|
function_definition
|
@@ -172,7 +175,11 @@ struct_declaration_list
|
|
172
175
|
|
173
176
|
# Returns Declaration
|
174
177
|
struct_declaration
|
175
|
-
: specifier_qualifier_list struct_declarator_list SEMICOLON
|
178
|
+
: specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
|
179
|
+
| specifier_qualifier_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
|
180
|
+
# GCC EXTENSION: __extension__ can go before any struct_declaration
|
181
|
+
| EXTENSION specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[1][0], val[1][1], val[2])}
|
182
|
+
| EXTENSION specifier_qualifier_list SEMICOLON {result = make_declaration(val[1][0], val[1][1], NodeArray[])}
|
176
183
|
|
177
184
|
# Returns {Pos, [Symbol]}
|
178
185
|
specifier_qualifier_list
|
@@ -381,6 +388,8 @@ unary_expression
|
|
381
388
|
| unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
|
382
389
|
| SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
|
383
390
|
| SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
|
391
|
+
# GCC extension: __extension__
|
392
|
+
| EXTENSION cast_expression {result = val[1]}
|
384
393
|
|
385
394
|
# Returns [Class, Pos]
|
386
395
|
unary_operator
|
data/lib/cast/node.rb
CHANGED
@@ -9,20 +9,6 @@ module C
|
|
9
9
|
# Abstract base class for all AST nodes.
|
10
10
|
#
|
11
11
|
class Node
|
12
|
-
#
|
13
|
-
# Called by the test suite to ensure all invariants are true.
|
14
|
-
#
|
15
|
-
def assert_invariants(testcase)
|
16
|
-
fields.each do |field|
|
17
|
-
if val = send(field.reader)
|
18
|
-
assert_same(self, node.parent, "field.reader is #{field.reader}")
|
19
|
-
if field.child?
|
20
|
-
assert_same(field, val.instance_variable_get(:@parent_field), "field.reader is #{field.reader}")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
12
|
#
|
27
13
|
# Like self.new, but the first argument is taken as the position
|
28
14
|
# of the Node.
|
data/lib/cast/node_list.rb
CHANGED
@@ -148,14 +148,6 @@ module C
|
|
148
148
|
end
|
149
149
|
|
150
150
|
class NodeArray
|
151
|
-
def assert_invariants(testcase)
|
152
|
-
super
|
153
|
-
testcase.assert_same(::Array, @array)
|
154
|
-
@array.each_with_index do |node, i|
|
155
|
-
assert_same(i, node.instance_variable_get(:@parent_index))
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
151
|
def initialize
|
160
152
|
super
|
161
153
|
@array = []
|
@@ -177,31 +169,6 @@ module C
|
|
177
169
|
end
|
178
170
|
|
179
171
|
class NodeChain
|
180
|
-
def assert_invariants(testcase)
|
181
|
-
super
|
182
|
-
assert_same(@length.zero?, @first.nil?)
|
183
|
-
assert_same(@length.zero?, @last.nil?)
|
184
|
-
unless @length.zero?
|
185
|
-
assert_same(@first, self[0])
|
186
|
-
assert_same(@last, self[@length-1])
|
187
|
-
(0...@length.times).each do |i|
|
188
|
-
nodeprev = self[i].instance_variable_get(:@prev)
|
189
|
-
nodenext = self[i].instance_variable_get(:@next)
|
190
|
-
if i == 0
|
191
|
-
assert_nil(nodeprev)
|
192
|
-
else
|
193
|
-
assert_same(self[i-1], nodeprev)
|
194
|
-
end
|
195
|
-
|
196
|
-
if i == @length-1
|
197
|
-
assert_nil(nodenext)
|
198
|
-
else
|
199
|
-
assert_same(self[i+1], nodenext)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
172
|
def initialize
|
206
173
|
super
|
207
174
|
@first = nil
|
data/lib/cast/preprocessor.rb
CHANGED
@@ -29,11 +29,13 @@ module C
|
|
29
29
|
end
|
30
30
|
def preprocess(text)
|
31
31
|
filename = nil
|
32
|
-
|
32
|
+
output = nil
|
33
|
+
Tempfile.open(['cast-preprocessor-input.', '.c']) do |file|
|
33
34
|
filename = file.path
|
34
35
|
file.puts text
|
36
|
+
file.flush
|
37
|
+
output = `#{full_command(filename)} #{'2> /dev/null' if @quiet}`
|
35
38
|
end
|
36
|
-
output = `#{full_command(filename)} #{'2> /dev/null' if @quiet}`
|
37
39
|
if $? == 0
|
38
40
|
return output
|
39
41
|
else
|
data/lib/cast/version.rb
CHANGED
data/lib/cast.rb
CHANGED
data/test/c_nodes_test.rb
CHANGED
@@ -194,7 +194,7 @@ EOS
|
|
194
194
|
|
195
195
|
c.wide = false
|
196
196
|
assert(!c.wide?)
|
197
|
-
|
197
|
+
assert_nil(c.prefix)
|
198
198
|
end
|
199
199
|
def test_string_literal_wide
|
200
200
|
s = C::StringLiteral.new('abc', 'L')
|
@@ -219,6 +219,6 @@ EOS
|
|
219
219
|
|
220
220
|
s.wide = false
|
221
221
|
assert(!s.wide?)
|
222
|
-
|
222
|
+
assert_nil(s.prefix)
|
223
223
|
end
|
224
224
|
end
|
data/test/node_list_test.rb
CHANGED
@@ -1298,7 +1298,7 @@ module NodeListArrayQueryTests
|
|
1298
1298
|
assert_equal(0, list.index(a))
|
1299
1299
|
assert_equal(1, list.index(l1))
|
1300
1300
|
assert_equal(1, list.index(_List[C::Int.new(2)]))
|
1301
|
-
|
1301
|
+
assert_nil(list.index([b]))
|
1302
1302
|
assert_nil(list.index([a]))
|
1303
1303
|
assert_nil(list.index(C::Int.new))
|
1304
1304
|
assert_nil(list.index(nil))
|
data/test/parse_test.rb
CHANGED
@@ -1761,10 +1761,12 @@ Struct
|
|
1761
1761
|
name: "s"
|
1762
1762
|
EOS
|
1763
1763
|
check C::Struct, <<EOS
|
1764
|
-
const struct {int i, j : 4;}
|
1764
|
+
const struct {float; int i, j : 4;}
|
1765
1765
|
----
|
1766
1766
|
Struct (const)
|
1767
1767
|
members:
|
1768
|
+
- Declaration
|
1769
|
+
type: Float
|
1768
1770
|
- Declaration
|
1769
1771
|
type: Int
|
1770
1772
|
declarators:
|
data/test/parser_test.rb
CHANGED
@@ -118,6 +118,66 @@ TranslationUnit
|
|
118
118
|
EOS
|
119
119
|
end
|
120
120
|
|
121
|
+
def test_external_declaration_with_extension_kw
|
122
|
+
check <<EOS
|
123
|
+
__extension__ typedef int blah;
|
124
|
+
----
|
125
|
+
TranslationUnit
|
126
|
+
entities:
|
127
|
+
- Declaration
|
128
|
+
storage: typedef
|
129
|
+
type: Int
|
130
|
+
declarators:
|
131
|
+
- Declarator
|
132
|
+
name: "blah"
|
133
|
+
EOS
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_struct_member_declaration_with_extension_kw
|
137
|
+
check <<EOS
|
138
|
+
struct { __extension__ int; __extension__ int i; int j; } blah;
|
139
|
+
----
|
140
|
+
TranslationUnit
|
141
|
+
entities:
|
142
|
+
- Declaration
|
143
|
+
type: Struct
|
144
|
+
members:
|
145
|
+
- Declaration
|
146
|
+
type: Int
|
147
|
+
- Declaration
|
148
|
+
type: Int
|
149
|
+
declarators:
|
150
|
+
- Declarator
|
151
|
+
name: "i"
|
152
|
+
- Declaration
|
153
|
+
type: Int
|
154
|
+
declarators:
|
155
|
+
- Declarator
|
156
|
+
name: "j"
|
157
|
+
declarators:
|
158
|
+
- Declarator
|
159
|
+
name: "blah"
|
160
|
+
EOS
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_unary_extension_kw
|
164
|
+
check <<EOS
|
165
|
+
void f() { __extension__ 0; }
|
166
|
+
----
|
167
|
+
TranslationUnit
|
168
|
+
entities:
|
169
|
+
- FunctionDef
|
170
|
+
type: Function
|
171
|
+
type: Void
|
172
|
+
name: "f"
|
173
|
+
def: Block
|
174
|
+
stmts:
|
175
|
+
- ExpressionStatement
|
176
|
+
expr: IntLiteral
|
177
|
+
val: 0
|
178
|
+
EOS
|
179
|
+
end
|
180
|
+
|
121
181
|
def test_function_def
|
122
182
|
check <<EOS
|
123
183
|
int main(int, char **) {}
|
data/test/preprocessor_test.rb
CHANGED
@@ -14,7 +14,7 @@ class PreprocessorTest < Minitest::Test
|
|
14
14
|
attr_accessor :cpp
|
15
15
|
def setup
|
16
16
|
@cpp = C::Preprocessor.new(quiet: true)
|
17
|
-
@cpp.include_path <<
|
17
|
+
@cpp.include_path << TEST_DIR << 'dir 2'
|
18
18
|
@cpp.macros['V'] = nil
|
19
19
|
@cpp.macros['I'] = 5
|
20
20
|
@cpp.macros['S'] = '"blah"'
|
@@ -30,7 +30,7 @@ class PreprocessorTest < Minitest::Test
|
|
30
30
|
C::Preprocessor.command = 'COMMAND'
|
31
31
|
assert_equal([
|
32
32
|
'COMMAND',
|
33
|
-
|
33
|
+
"-I#{TEST_DIR}", '-Idir 2',
|
34
34
|
'-DI=5', '-DS="blah"', '-DSWAP(a,b)=a ^= b ^= a ^= b', '-DV',
|
35
35
|
'a file.c',
|
36
36
|
], cpp.full_command('a file.c').shellsplit)
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- George Ogata
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description:
|
14
14
|
email:
|
15
15
|
- george.ogata@gmail.com
|
16
16
|
executables: []
|
@@ -56,7 +56,7 @@ homepage: http://github.com/oggy/cast
|
|
56
56
|
licenses:
|
57
57
|
- MIT
|
58
58
|
metadata: {}
|
59
|
-
post_install_message:
|
59
|
+
post_install_message:
|
60
60
|
rdoc_options: []
|
61
61
|
require_paths:
|
62
62
|
- lib
|
@@ -71,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '0'
|
73
73
|
requirements: []
|
74
|
-
|
75
|
-
|
76
|
-
signing_key:
|
74
|
+
rubygems_version: 3.5.9
|
75
|
+
signing_key:
|
77
76
|
specification_version: 4
|
78
77
|
summary: C parser and AST constructor.
|
79
78
|
test_files:
|