rubex 0.0.1 → 0.1
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 +4 -4
- data/.gitignore +4 -0
- data/.travis.yml +14 -0
- data/CONTRIBUTING.md +101 -0
- data/HISTORY.md +3 -0
- data/README.md +112 -297
- data/REFERENCE.md +753 -0
- data/Rakefile +4 -1
- data/TUTORIAL.md +234 -0
- data/bin/rubex +1 -1
- data/docs/_config.yml +1 -0
- data/docs/index.html +1 -0
- data/examples/c_struct_interface/c_struct_interface.rb +6 -0
- data/examples/c_struct_interface/c_struct_interface.rubex +47 -0
- data/examples/linked_list/linked_list.rubex +39 -0
- data/examples/linked_list/rb_linked_list.rb +8 -0
- data/examples/rcsv wrapper/rcsv/README.md +1 -0
- data/examples/rcsv wrapper/rcsv/Rakefile +7 -0
- data/examples/rcsv wrapper/rcsv/ext/rcsv/extconf.rb +3 -0
- data/examples/rcsv wrapper/rcsv/ext/rcsv/rcsv.c +302 -0
- data/examples/rcsv wrapper/rcsv/ext/rcsv/rcsv.rubex +124 -0
- data/examples/rcsv wrapper/rcsv/lib/rcsv.rb +8 -0
- data/examples/rcsv wrapper/rcsv/lib/rcsv.so +0 -0
- data/examples/rcsv wrapper/rcsv/lib/rcsv/version.rb +1 -0
- data/examples/rcsv wrapper/rcsv/rcsv.gemspec +27 -0
- data/examples/rcsv wrapper/rcsv/spec/rcsv.csv +5 -0
- data/examples/rcsv wrapper/rcsv/spec/rcsv_spec.rb +17 -0
- data/examples/rcsv wrapper/rcsv/spec/spec_helper.rb +6 -0
- data/{spec/fixtures/basic_ruby_method/Makefile → examples/rcsv wrapper/rcsv/tmp/x86_64-linux/rcsv/2.3.3/Makefile } +20 -20
- data/examples/rcsv wrapper/rcsv/tmp/x86_64-linux/rcsv/2.3.3/rcsv.o +0 -0
- data/examples/rcsv wrapper/rcsv/tmp/x86_64-linux/rcsv/2.3.3/rcsv.so +0 -0
- data/examples/rcsv wrapper/rcsv/tmp/x86_64-linux/stage/lib/rcsv.so +0 -0
- data/lib/rubex.rb +6 -50
- data/lib/rubex/ast.rb +1 -3
- data/lib/rubex/ast/expression.rb +1257 -8
- data/lib/rubex/ast/node.rb +226 -28
- data/lib/rubex/ast/statement.rb +1162 -35
- data/lib/rubex/ast/top_statement.rb +815 -0
- data/lib/rubex/code_writer.rb +103 -26
- data/lib/rubex/compiler.rb +72 -0
- data/lib/rubex/compiler_config.rb +19 -0
- data/lib/rubex/constants.rb +145 -8
- data/lib/rubex/data_type.rb +667 -4
- data/lib/rubex/error.rb +15 -0
- data/lib/rubex/helpers.rb +154 -0
- data/lib/rubex/lexer.rex +186 -22
- data/lib/rubex/lexer.rex.rb +261 -35
- data/lib/rubex/parser.racc +876 -28
- data/lib/rubex/parser.racc.rb +2845 -90
- data/lib/rubex/rake_task.rb +34 -0
- data/lib/rubex/symbol_table/entry.rb +17 -3
- data/lib/rubex/symbol_table/scope.rb +298 -25
- data/lib/rubex/version.rb +1 -1
- data/rubex.gemspec +11 -3
- data/spec/basic_ruby_method_spec.rb +15 -21
- data/spec/binding_ptr_args_spec.rb +33 -0
- data/spec/bitwise_operators_spec.rb +40 -0
- data/spec/blocks_spec.rb +35 -0
- data/spec/c_bindings_spec.rb +36 -0
- data/spec/c_constants_spec.rb +33 -0
- data/spec/c_function_ptrs_spec.rb +38 -0
- data/spec/c_functions_spec.rb +35 -0
- data/spec/c_struct_interface_spec.rb +38 -0
- data/spec/call_by_reference_spec.rb +33 -0
- data/spec/class_methods_spec.rb +33 -0
- data/spec/class_spec.rb +40 -0
- data/spec/comments_spec.rb +33 -0
- data/spec/default_args_spec.rb +37 -0
- data/spec/error_handling_spec.rb +42 -0
- data/spec/examples_spec.rb +52 -0
- data/spec/expressions_spec.rb +33 -0
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.rubex +2 -0
- data/spec/fixtures/binding_ptr_args/binding_ptr_args.rubex +30 -0
- data/spec/fixtures/bitwise_operators/bitwise_operators.rubex +40 -0
- data/spec/fixtures/blocks/blocks.rubex +11 -0
- data/spec/fixtures/c_bindings/c_bindings.rubex +58 -0
- data/spec/fixtures/c_constants/c_constants.rubex +7 -0
- data/spec/fixtures/c_function_ptrs/c_function_ptrs.rubex +52 -0
- data/spec/fixtures/c_functions/c_functions.rubex +25 -0
- data/spec/fixtures/c_struct_interface/c_struct_interface.rubex +34 -0
- data/spec/fixtures/call_by_reference/call_by_reference.rubex +30 -0
- data/spec/fixtures/class/class.rubex +20 -0
- data/spec/fixtures/class_methods/class_methods.rubex +12 -0
- data/spec/fixtures/comments/comments.rubex +9 -0
- data/spec/fixtures/default_args/default_args.rubex +11 -0
- data/spec/fixtures/error_handling/error_handling.rubex +54 -0
- data/spec/fixtures/examples/array_to_hash.rubex +14 -0
- data/spec/fixtures/examples/rcsv.csv +5 -0
- data/spec/fixtures/examples/rcsv.rubex +329 -0
- data/spec/fixtures/expressions/expressions.rubex +10 -0
- data/spec/fixtures/if_else/if_else.rubex +77 -0
- data/spec/fixtures/implicit_lib_include/implicit_lib_include.rubex +15 -0
- data/spec/fixtures/init_ruby_objects_with_literal_syntax/init_ruby_objects_with_literal_syntax.rubex +17 -0
- data/spec/fixtures/loops/loops.rubex +33 -0
- data/spec/fixtures/recursion/recursion.rubex +9 -0
- data/spec/fixtures/ruby_constant_method_calls/ruby_constant_method_calls.rubex +17 -0
- data/spec/fixtures/ruby_operators/ruby_operators.rubex +29 -0
- data/spec/fixtures/ruby_raise/ruby_raise.rubex +13 -0
- data/spec/fixtures/ruby_strings/ruby_strings.rubex +19 -0
- data/spec/fixtures/ruby_strings/string_blank_bm.rb +37 -0
- data/spec/fixtures/ruby_symbols/ruby_symbols.rubex +12 -0
- data/spec/fixtures/ruby_types/ruby_types.rubex +15 -0
- data/spec/fixtures/statement_expression/statement_expression.rubex +23 -0
- data/spec/fixtures/static_array/static_array.rubex +20 -0
- data/spec/fixtures/string_literals/string_literals.rubex +15 -0
- data/spec/fixtures/struct/struct.rubex +82 -0
- data/spec/fixtures/typecasting/typecasting.rubex +23 -0
- data/spec/fixtures/var_declarations/var_declarations.rubex +39 -0
- data/spec/if_else_spec.rb +39 -0
- data/spec/implicit_lib_include_spec.rb +33 -0
- data/spec/init_ruby_objects_with_literal_syntax_spec.rb +39 -0
- data/spec/loops_spec.rb +34 -0
- data/spec/recursion_spec.rb +35 -0
- data/spec/ruby_constant_method_calls_spec.rb +35 -0
- data/spec/ruby_operators_spec.rb +40 -0
- data/spec/ruby_raise_spec.rb +35 -0
- data/spec/ruby_strings_spec.rb +33 -0
- data/spec/ruby_symbols_spec.rb +37 -0
- data/spec/ruby_types_spec.rb +35 -0
- data/spec/spec_helper.rb +54 -1
- data/spec/statement_expression_spec.rb +34 -0
- data/spec/static_array_spec.rb +33 -0
- data/spec/string_literals_spec.rb +34 -0
- data/spec/struct_spec.rb +36 -0
- data/spec/typecasting_spec.rb +38 -0
- data/spec/var_declarions_spec.rb +35 -0
- metadata +255 -29
- data/lib/rubex/ast/argument_list.rb +0 -20
- data/lib/rubex/ast/c_base_type.rb +0 -11
- data/lib/rubex/ast/ruby_method_def.rb +0 -84
- data/spec/fixtures/basic_ruby_method/basic.rb +0 -3
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.c +0 -16
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.o +0 -0
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.so +0 -0
- data/spec/fixtures/basic_ruby_method/extconf.rb +0 -3
data/lib/rubex/parser.racc
CHANGED
@@ -1,53 +1,724 @@
|
|
1
1
|
class Rubex::Parser
|
2
|
-
token
|
3
|
-
kDEF kEND kRETURN
|
2
|
+
token
|
3
|
+
kDEF kEND kRETURN kPRINT kIF kELSIF kELSE kTHEN kSTATIC_ARRAY kFOR
|
4
|
+
kDOT_EACH kDO kTRUE kFALSE kNIL kSTRUCT kUNION kALIAS kLIB
|
5
|
+
kCFUNC kSELF kNULL kFWD kATTACH kRAISE kBREAK kBLOCK_GIVEN kYIELD
|
6
|
+
kBEGIN kRESCUE kENSURE kWHILE kCLASS kDATA_VAR
|
7
|
+
|
8
|
+
kDTYPE_UINT kDTYPE_LINT kDTYPE_LLINT kDTYPE_CHAR kDTYPE_I8 kDTYPE_I16
|
9
|
+
kDTYPE_I32 kDTYPE_I64 kDTYPE_UI8 kDTYPE_UI16 kDTYPE_UI32 kDTYPE_UI64
|
10
|
+
kDTYPE_INT kDTYPE_F32 kDTYPE_F64 kDTYPE_LF64 kDTYPE_ROBJ kDTYPE_ULINT
|
11
|
+
kDTYPE_ULLINT kDTYPE_VOID kDTYPE_SIZE_T kDTYPE_RB_STR kDTYPE_UCHAR kDTYPE_BOOL
|
12
|
+
tCUSTOM_DTYPE kDTYPE_RB_ARR kDTYPE_RB_HSH
|
13
|
+
|
14
|
+
tLPAREN tRPAREN tLSQUARE tRSQUARE tIDENTIFIER tNL tCOMMA tSQUOTE tSCOLON
|
15
|
+
EOF tDOT tQMARK tSYMBOL tLBRACE tRBRACE tCOLON
|
16
|
+
|
17
|
+
tPLUS tMINUS tSTAR tDIVIDE tEXPO tMODULUS tASSIGN tEQ tLT tLTEQ tGT
|
18
|
+
tGTEQ tANDOP tOROP tBANG tOP_ASSIGN tSTRING kSIZEOF
|
19
|
+
|
20
|
+
tBIT_AND tBIT_OR tBIT_XOR tBIT_LSHIFT tBIT_RSHIFT tBIT_NOT
|
21
|
+
|
22
|
+
tINTEGER tFLOAT tSINGLE_CHAR
|
4
23
|
|
5
24
|
prechigh
|
6
|
-
|
7
|
-
|
25
|
+
right tBANG tBIT_NOT
|
26
|
+
right ADDRESS_OF
|
27
|
+
right tEXPO
|
28
|
+
right TYPECAST
|
29
|
+
right kSIZEOF
|
30
|
+
|
31
|
+
right UMINUS
|
32
|
+
left tSTAR tDIVIDE tMODULUS
|
8
33
|
left tPLUS tMINUS
|
34
|
+
left tBIT_OR tBIT_XOR
|
35
|
+
left tBIT_AND
|
36
|
+
left tBIT_LSHIFT tBIT_RSHIFT
|
37
|
+
left tLT tLTEQ tGT tGTEQ
|
38
|
+
nonassoc tEQ tNEQ
|
39
|
+
left tANDOP
|
40
|
+
left tOROP
|
9
41
|
|
10
|
-
right
|
42
|
+
right tASSIGN tOP_ASSIGN
|
11
43
|
preclow
|
12
44
|
|
13
45
|
rule
|
14
46
|
|
15
47
|
program:
|
16
|
-
|
48
|
+
opt_terms top_compstmts opt_terms {result = Node.new(val[1])}
|
17
49
|
|
18
|
-
|
19
|
-
|
20
|
-
|
|
50
|
+
top_compstmts:
|
51
|
+
top_compstmt { result = [val[0]] }
|
52
|
+
| top_compstmts terms top_compstmt { result = [*val[0], val[2]] }
|
53
|
+
|
54
|
+
top_compstmt:
|
55
|
+
c_bindings {}
|
56
|
+
| top_stmts terms { result = val[0] }
|
57
|
+
|
58
|
+
top_stmts:
|
59
|
+
{ result = [] }
|
60
|
+
| top_stmt { result = [val[0]] }
|
61
|
+
| top_stmts terms top_stmt { result = [*val[0], val[2]] }
|
62
|
+
|
63
|
+
top_stmt:
|
64
|
+
methods {}
|
65
|
+
| klass {}
|
66
|
+
| attached_klass {}
|
67
|
+
| struct_or_union_def {}
|
68
|
+
|
69
|
+
klass:
|
70
|
+
kCLASS tIDENTIFIER opt_inheritance eol top_stmts opt_terms kEND
|
71
|
+
{
|
72
|
+
raise Rubex::SyntaxError unless val[1][0].match(/[A-Z]/)
|
73
|
+
result = TopStatement::Klass.new val[1], val[2], val[4]
|
74
|
+
}
|
75
|
+
|
76
|
+
attached_klass:
|
77
|
+
kCLASS tIDENTIFIER kATTACH dtype opt_inheritance eol top_stmts terms kEND
|
78
|
+
{
|
79
|
+
raise Rubex::SyntaxError unless val[1][0].match(/[A-Z]/)
|
80
|
+
result = TopStatement::AttachedKlass.new(val[1], val[3], val[4], val[6],
|
81
|
+
location)
|
82
|
+
}
|
83
|
+
|
84
|
+
opt_inheritance:
|
85
|
+
{ result = nil }
|
86
|
+
| tLT tIDENTIFIER { result = val[1] }
|
87
|
+
|
88
|
+
c_bindings:
|
89
|
+
kLIB tSTRING opt_compilation_cmds c_declarations terms kEND
|
90
|
+
{
|
91
|
+
result = TopStatement::CBindings.new val[1], val[2], val[3], location
|
92
|
+
}
|
93
|
+
|
94
|
+
opt_compilation_cmds:
|
95
|
+
{ result = [{}] }
|
96
|
+
| compilation_cmd { result = [val[0]] }
|
97
|
+
| opt_compilation_cmds tCOMMA compilation_cmd { result = [*val[0], val[2]] }
|
98
|
+
|
99
|
+
compilation_cmd:
|
100
|
+
tIDENTIFIER tCOLON tSTRING
|
101
|
+
{
|
102
|
+
if val[0] == 'link'
|
103
|
+
result = { link: val[2] }
|
104
|
+
end
|
105
|
+
}
|
106
|
+
|
107
|
+
c_declarations:
|
108
|
+
{}
|
109
|
+
| c_declaration { result = [val[0]] }
|
110
|
+
| c_declarations terms c_declaration { result = [*val[0], val[2]] }
|
111
|
+
|
112
|
+
c_declaration:
|
113
|
+
c_function_declaration_or_var_decl
|
114
|
+
| struct_or_union_def
|
115
|
+
| alias_stmt
|
116
|
+
|
117
|
+
c_function_declaration_or_var_decl:
|
118
|
+
dtype opt_star tIDENTIFIER opt_c_func_arg_list
|
119
|
+
{
|
120
|
+
if !val[3].empty? # function decl
|
121
|
+
val[3].pop # HACK: because declared external C functions don't have implicit self argument.
|
122
|
+
result = Statement::CFunctionDecl.new val[0], val[1], val[2], val[3]
|
123
|
+
else # var/macro decl
|
124
|
+
result = variable_decl_nodes([{
|
125
|
+
dtype: val[0],
|
126
|
+
variables: [{
|
127
|
+
ptr_level: val[1],
|
128
|
+
ident: val[2]
|
129
|
+
}]
|
130
|
+
}])[0]
|
131
|
+
end
|
132
|
+
}
|
133
|
+
|
134
|
+
c_func_args:
|
135
|
+
{ result = [] }
|
136
|
+
| c_func_normal_arg { result = [Expression::ArgDeclaration.new(val[0])] }
|
137
|
+
| c_func_args tCOMMA c_func_normal_arg
|
138
|
+
{
|
139
|
+
result = [*val[0], Expression::ArgDeclaration.new(val[2])]
|
140
|
+
}
|
141
|
+
|
142
|
+
opt_c_func_arg_list:
|
143
|
+
{ result = Statement::ArgumentList.new([]) }
|
144
|
+
| tLPAREN c_func_args tRPAREN
|
145
|
+
{
|
146
|
+
# self is a compulsory implicit argument for C methods.
|
147
|
+
val[1] << Expression::ArgDeclaration.new(
|
148
|
+
{ dtype: 'object', variables: [ {ident: 'self' }] })
|
149
|
+
result = Statement::ArgumentList.new(val[1])
|
150
|
+
}
|
151
|
+
|
152
|
+
struct_or_union_def:
|
153
|
+
kSTRUCT tIDENTIFIER eol var_decl_stmts opt_terms kEND
|
154
|
+
{
|
155
|
+
add_dtype_to_lexer val[1]
|
156
|
+
result = Statement::CStructOrUnionDef.new(val[0], val[1], val[3].flatten,
|
157
|
+
location)
|
158
|
+
}
|
159
|
+
|
160
|
+
var_decl_stmts:
|
161
|
+
{ result = [] }
|
162
|
+
| var_decl_stmt { result = [*val[0]] }
|
163
|
+
| var_decl_stmts terms var_decl_stmt { result = [*val[0], val[2]] }
|
164
|
+
|
165
|
+
var_decl_stmt:
|
166
|
+
dtype var_decls
|
167
|
+
{
|
168
|
+
result = variable_decl_nodes([{ dtype: val[0], variables: val[1] }])
|
169
|
+
}
|
170
|
+
|
171
|
+
var_decls:
|
172
|
+
var_decls tCOMMA normal_decl { result = [*val[0], val[2]] }
|
173
|
+
| normal_decl { result = [val[0]] }
|
21
174
|
|
22
|
-
|
23
|
-
|
175
|
+
alias_stmt:
|
176
|
+
kALIAS ident_or_custom_dtype tASSIGN aliased_type
|
177
|
+
{ # TODO: take hash from aliased_type and turn into nodes.
|
178
|
+
add_dtype_to_lexer val[1]
|
179
|
+
result = Statement::Alias.new val[1], val[3], location
|
180
|
+
}
|
181
|
+
|
182
|
+
ident_or_custom_dtype:
|
183
|
+
tIDENTIFIER | tCUSTOM_DTYPE {}
|
184
|
+
|
185
|
+
aliased_type:
|
186
|
+
dtype opt_star
|
24
187
|
{
|
25
|
-
result =
|
26
|
-
|
188
|
+
result = {
|
189
|
+
dtype: val[0],
|
190
|
+
variables: [
|
191
|
+
{
|
192
|
+
ptr_level: val[1],
|
193
|
+
ident: ""
|
194
|
+
}
|
195
|
+
]
|
196
|
+
}
|
197
|
+
}
|
198
|
+
| kSTRUCT tIDENTIFIER opt_star
|
199
|
+
{
|
200
|
+
result = {
|
201
|
+
dtype: "#{val[0]}#{val[1]}",
|
202
|
+
variables: [
|
203
|
+
{
|
204
|
+
ptr_level: val[2],
|
205
|
+
ident: ""
|
206
|
+
}
|
207
|
+
]
|
208
|
+
}
|
209
|
+
}
|
210
|
+
| dtype opt_star tLPAREN opt_star opt_identifier tRPAREN opt_c_func_arg_list
|
211
|
+
{
|
212
|
+
result = {
|
213
|
+
dtype: val[0],
|
214
|
+
variables: [
|
215
|
+
{
|
216
|
+
ptr_level: val[3],
|
217
|
+
ident:{
|
218
|
+
return_ptr_level: val[1],
|
219
|
+
arg_list: val[6],
|
220
|
+
name: val[4]
|
221
|
+
}
|
222
|
+
}
|
223
|
+
]
|
224
|
+
}
|
27
225
|
}
|
28
|
-
| kRETURN expr { result = Statement::Return.new val[1] }
|
29
|
-
| {}
|
30
226
|
|
31
|
-
|
32
|
-
|
227
|
+
opt_identifier:
|
228
|
+
{ result = nil }
|
229
|
+
| tIDENTIFIER {}
|
230
|
+
|
231
|
+
methods:
|
232
|
+
ruby_method { result = val[0] }
|
233
|
+
| c_function { result = val[0] }
|
234
|
+
|
235
|
+
ruby_method:
|
236
|
+
kDEF opt_singleton f_name f_opt_arglist compstmt kEND
|
237
|
+
{
|
238
|
+
result = TopStatement::RubyMethodDef.new(
|
239
|
+
val[2], val[3], val[4], singleton: val[1])
|
240
|
+
}
|
241
|
+
|
242
|
+
c_function:
|
243
|
+
kCFUNC dtype opt_star tIDENTIFIER opt_c_func_arg_list eol compstmt kEND
|
244
|
+
{
|
245
|
+
if val[4].empty? # since last arg of cfunc must be self.
|
246
|
+
val[4] = Statement::ArgumentList.new(
|
247
|
+
[
|
248
|
+
Expression::ArgDeclaration.new(
|
249
|
+
{ dtype: 'object', variables: [ { ident: 'self' }] }
|
250
|
+
)
|
251
|
+
]
|
252
|
+
)
|
253
|
+
end
|
254
|
+
result = TopStatement::CFunctionDef.new(val[1], val[2], val[3],
|
255
|
+
val[4], val[6])
|
256
|
+
}
|
257
|
+
|
258
|
+
c_func_normal_arg:
|
259
|
+
dtype opt_star
|
260
|
+
{
|
261
|
+
result = {
|
262
|
+
dtype: val[0],
|
263
|
+
variables: [
|
264
|
+
{
|
265
|
+
ptr_level: val[1],
|
266
|
+
ident: ""
|
267
|
+
}
|
268
|
+
]
|
269
|
+
}
|
270
|
+
}
|
271
|
+
| dtype normal_decl { result = { dtype: val[0] , variables: [val[1]] } }
|
272
|
+
| normal_decl { result = { dtype: 'object', variables: [val[0]] } }
|
273
|
+
|
274
|
+
opt_singleton:
|
275
|
+
{ result = false }
|
276
|
+
| kSELF tDOT { result = true }
|
277
|
+
|
278
|
+
compstmt:
|
279
|
+
stmts opt_terms { result = val[0] }
|
280
|
+
|
281
|
+
stmts:
|
282
|
+
{ result = [] }
|
283
|
+
| stmt { result = [*val[0]] }
|
284
|
+
| stmts terms stmt { result = [*val[0], *val[2]] }
|
285
|
+
|
286
|
+
|
287
|
+
stmt:
|
288
|
+
var_decl_or_init { result = variable_decl_nodes val }
|
289
|
+
| kRETURN opt_expr { result = Statement::Return.new val[1], location }
|
290
|
+
| kPRINT opt_lparen command_arg_list opt_rparen
|
291
|
+
{ result = Statement::Print.new val[2], location }
|
292
|
+
| normal_init
|
293
|
+
{
|
294
|
+
match = val[0]
|
295
|
+
result = Statement::Assign.new match[:name], match[:value], location
|
296
|
+
}
|
297
|
+
| kIF expr then compstmt if_tail kEND
|
298
|
+
{
|
299
|
+
result = Statement::IfBlock.new val[1], [*val[3]], val[4], location
|
300
|
+
}
|
301
|
+
| stmt kIF expr
|
302
|
+
{
|
303
|
+
set_location
|
304
|
+
result = Statement::IfBlock.new val[2], [*val[0]], nil, location
|
305
|
+
}
|
306
|
+
| kFOR for_expr kDO compstmt kEND
|
307
|
+
{
|
308
|
+
result = Statement::For.new *val[1], val[3], location
|
309
|
+
}
|
310
|
+
| kWHILE expr kDO compstmt kEND
|
311
|
+
{
|
312
|
+
result = Statement::While.new val[1], val[3], location
|
313
|
+
}
|
314
|
+
| op_assign {}
|
315
|
+
| struct_or_union_def
|
316
|
+
| forward_declaration
|
317
|
+
| alias_stmt
|
318
|
+
| expr { result = Statement::Expression.new(val[0], location) }
|
319
|
+
| kRAISE opt_lparen command_arg_list opt_rparen
|
320
|
+
{
|
321
|
+
result = Statement::Raise.new(Statement::ActualArgList.new(val[2]))
|
322
|
+
}
|
323
|
+
| kBREAK { result = Statement::Break.new(location) }
|
324
|
+
| kYIELD opt_lparen command_arg_list opt_rparen
|
325
|
+
{
|
326
|
+
result = Statement::Yield.new(Statement::ActualArgList.new(val[2]))
|
327
|
+
}
|
328
|
+
| begin_block
|
329
|
+
|
330
|
+
begin_block:
|
331
|
+
kBEGIN terms compstmt opt_begin_block_tails kEND
|
332
|
+
{
|
333
|
+
result = Statement::BeginBlock::Begin.new val[2], val[3], location
|
334
|
+
}
|
335
|
+
|
336
|
+
opt_begin_block_tails:
|
337
|
+
opt_rescue_blocks opt_else_block opt_ensure_block
|
338
|
+
{
|
339
|
+
tails = []
|
340
|
+
tails.concat(val[0]) if val[0]
|
341
|
+
tails << val[1] if val[1]
|
342
|
+
tails << val[2] if val[2]
|
343
|
+
|
344
|
+
result = tails
|
345
|
+
}
|
346
|
+
|
347
|
+
opt_rescue_blocks:
|
348
|
+
{ result = nil }
|
349
|
+
| rescue_block { result = [val[0]] }
|
350
|
+
| opt_rescue_blocks rescue_block { result = [*val[0], val[1]] }
|
351
|
+
|
352
|
+
rescue_block:
|
353
|
+
kRESCUE tIDENTIFIER terms compstmt
|
354
|
+
{
|
355
|
+
err = Expression::Name.new(val[1])
|
356
|
+
result = Statement::BeginBlock::Rescue.new err, nil, val[3] || [], location
|
357
|
+
}
|
358
|
+
|
359
|
+
opt_else_block:
|
360
|
+
{ result = nil }
|
361
|
+
| kELSE terms compstmt
|
362
|
+
{ result = Statement::BeginBlock::Else.new val[2] || [], location }
|
363
|
+
|
364
|
+
opt_ensure_block:
|
365
|
+
{ result = nil }
|
366
|
+
| kENSURE terms compstmt
|
367
|
+
{ result = Statement::BeginBlock::Ensure.new val[2] || [], location }
|
368
|
+
|
369
|
+
forward_declaration:
|
370
|
+
kFWD kSTRUCT tIDENTIFIER
|
371
|
+
{
|
372
|
+
val.flatten!
|
373
|
+
add_dtype_to_lexer val[2]
|
374
|
+
result = Statement::ForwardDecl.new val[1], val[2], location
|
375
|
+
}
|
376
|
+
|
377
|
+
op_assign:
|
378
|
+
atomic_value tOP_ASSIGN expr
|
379
|
+
{
|
380
|
+
# TODO: error if lvalue is a literal
|
381
|
+
result = op_assign val
|
382
|
+
}
|
383
|
+
|
384
|
+
for_expr:
|
385
|
+
tLPAREN actual_for_expr tRPAREN { result = val[1] }
|
386
|
+
| actual_for_expr
|
387
|
+
|
388
|
+
actual_for_expr:
|
389
|
+
expr_value lt_or_lteq tIDENTIFIER lt_or_lteq expr_value { result = val }
|
390
|
+
| expr_value gt_or_gteq tIDENTIFIER gt_or_gteq expr_value { result = val }
|
391
|
+
|
392
|
+
lt_or_lteq:
|
393
|
+
tLT | tLTEQ
|
394
|
+
|
395
|
+
gt_or_gteq:
|
396
|
+
tGT | tGTEQ
|
397
|
+
|
398
|
+
then:
|
399
|
+
kTHEN | eol
|
400
|
+
|
401
|
+
if_tail:
|
402
|
+
{}
|
403
|
+
| opt_else {}
|
404
|
+
| kELSIF expr then compstmt if_tail
|
405
|
+
{
|
406
|
+
result = Statement::IfBlock::Elsif.new val[1], [*val[3]], val[4], location
|
407
|
+
}
|
33
408
|
|
34
|
-
|
35
|
-
|
409
|
+
opt_else:
|
410
|
+
kELSE compstmt { result = Statement::IfBlock::Else.new val[1], location }
|
411
|
+
|
412
|
+
var_decl_or_init:
|
413
|
+
dtype decls_or_inits
|
414
|
+
{
|
415
|
+
result = {
|
416
|
+
dtype: val[0],
|
417
|
+
variables: val[1]
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
decls_or_inits:
|
422
|
+
decls_or_inits tCOMMA var_init { result = [*val[0], val[2]] }
|
423
|
+
| decls_or_inits tCOMMA normal_decl { result = [*val[0], val[2]] }
|
424
|
+
| normal_decl { result = [val[0]] }
|
425
|
+
| var_init { result = [val[0]] }
|
426
|
+
|
427
|
+
normal_decl:
|
428
|
+
# possible function pointer declaration
|
429
|
+
opt_star tLPAREN opt_star actual_normal_decl tRPAREN opt_c_func_arg_list
|
430
|
+
{
|
431
|
+
result = {}
|
432
|
+
|
433
|
+
if val[5] # function (pointer) decl
|
434
|
+
result[:ptr_level] = val[2]
|
435
|
+
result[:ident] = {
|
436
|
+
:return_ptr_level => val[0],
|
437
|
+
:name => val[3],
|
438
|
+
:arg_list => val[5]
|
439
|
+
}
|
440
|
+
else
|
441
|
+
result[:ptr_level] = val[0].join val[2]
|
442
|
+
result[:ident] = val[3]
|
443
|
+
end
|
444
|
+
}
|
445
|
+
| opt_star actual_normal_decl opt_c_func_arg_list
|
446
|
+
{
|
447
|
+
result = {}
|
448
|
+
|
449
|
+
if !val[2].empty?
|
450
|
+
result[:ptr_level] = val[0]
|
451
|
+
result[:ident] = {
|
452
|
+
:name => val[1],
|
453
|
+
:arg_list => val[2]
|
454
|
+
}
|
455
|
+
else
|
456
|
+
result[:ptr_level] = val[0]
|
457
|
+
result[:ident] = val[1]
|
458
|
+
end
|
459
|
+
}
|
460
|
+
|
461
|
+
actual_normal_decl: tIDENTIFIER | array_ref
|
462
|
+
|
463
|
+
var_init:
|
464
|
+
normal_decl tASSIGN expr
|
465
|
+
{
|
466
|
+
result = val[0]
|
467
|
+
value = val[2]
|
468
|
+
|
469
|
+
value.c_array = true if value.is_a?(Expression::Literal::ArrayLit)
|
470
|
+
result[:value] = value
|
471
|
+
}
|
472
|
+
|
473
|
+
opt_star:
|
474
|
+
{ result = nil }
|
475
|
+
| opt_star tSTAR { result = val.join }
|
476
|
+
|
477
|
+
array_list:
|
478
|
+
{ result = [] }
|
479
|
+
| expr { result = [*val[0]] }
|
480
|
+
| array_list tCOMMA expr { result = [*val[0], val[2]] }
|
481
|
+
|
482
|
+
normal_init:
|
483
|
+
tIDENTIFIER tASSIGN expr
|
484
|
+
{
|
485
|
+
result = {
|
486
|
+
name: Expression::Name.new(val[0]),
|
487
|
+
value: val[2]
|
488
|
+
}
|
489
|
+
}
|
490
|
+
| array_ref tASSIGN expr { result = { name: val[0], value: val[2] } }
|
491
|
+
| method_or_attr tASSIGN expr
|
492
|
+
{
|
493
|
+
result = {
|
494
|
+
name: Expression::CommandCall.new(val[0][0], val[0][1], []),
|
495
|
+
value: val[2]
|
496
|
+
}
|
497
|
+
}
|
498
|
+
|
499
|
+
literal:
|
500
|
+
tINTEGER { result = Expression::Literal::Int.new val[0] }
|
501
|
+
| tFLOAT { result = Expression::Literal::Double.new val[0] }
|
502
|
+
| tSINGLE_CHAR { result = Expression::Literal::Char.new val[0] }
|
503
|
+
| tSTRING { result = Expression::Literal::StringLit.new val[0] }
|
504
|
+
| kTRUE { result = Expression::Literal::True.new 'Qtrue' }
|
505
|
+
| kFALSE { result = Expression::Literal::False.new 'Qfalse' }
|
506
|
+
| kNIL { result = Expression::Literal::Nil.new 'Qnil' }
|
507
|
+
| tSYMBOL { result = Expression::Literal::RubySymbol.new val[0] }
|
508
|
+
| kNULL { result = Expression::Literal::CNull.new val[0] }
|
509
|
+
| tLSQUARE opt_eols array_list tRSQUARE
|
510
|
+
{ result = Expression::Literal::ArrayLit.new val[2] }
|
511
|
+
| tLBRACE opt_eols hash_data opt_eols tRBRACE
|
512
|
+
{ result = Expression::Literal::HashLit.new val[2] }
|
513
|
+
|
514
|
+
hash_data:
|
515
|
+
{ result = [] }
|
516
|
+
| hash_data_k_v { result = [val[0]] }
|
517
|
+
| hash_data tCOMMA opt_eols hash_data_k_v { result = [*val[0], val[3]] }
|
518
|
+
|
519
|
+
hash_data_k_v:
|
520
|
+
atomic_value rocket atomic_value { result = [val[0], val[2]] }
|
521
|
+
|
522
|
+
rocket:
|
523
|
+
tASSIGN tGT
|
524
|
+
|
525
|
+
f_name:
|
526
|
+
tIDENTIFIER tQMARK { result = "#{val[0]}#{val[1]}" }
|
527
|
+
| tIDENTIFIER tBANG { result = "#{val[0]}#{val[1]}" }
|
528
|
+
| tIDENTIFIER { result = val[0] }
|
529
|
+
| kNIL tQMARK { result = "#{val[0]}#{val[1]}" }
|
530
|
+
|
531
|
+
f_opt_arglist:
|
532
|
+
{ result = Statement::ArgumentList.new([]) }
|
533
|
+
| tLPAREN f_args tRPAREN eol { result = Statement::ArgumentList.new val[1] }
|
36
534
|
|
37
535
|
f_args:
|
38
|
-
|
536
|
+
f_normal_arg
|
39
537
|
{
|
40
|
-
result =
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
538
|
+
result = [Expression::ArgDeclaration.new(val[0])]
|
539
|
+
}
|
540
|
+
| f_args tCOMMA f_normal_arg
|
541
|
+
{
|
542
|
+
result = [*val[0], Expression::ArgDeclaration.new(val[2])]
|
543
|
+
}
|
45
544
|
|
46
545
|
f_normal_arg:
|
47
|
-
|
546
|
+
dtype tIDENTIFIER opt_default_value
|
547
|
+
{
|
548
|
+
result = {
|
549
|
+
dtype: val[0],
|
550
|
+
variables: [
|
551
|
+
{
|
552
|
+
ident: val[1],
|
553
|
+
value: val[2]
|
554
|
+
}
|
555
|
+
]
|
556
|
+
}
|
557
|
+
}
|
558
|
+
| tIDENTIFIER opt_default_value
|
559
|
+
{
|
560
|
+
result = {
|
561
|
+
dtype: 'object',
|
562
|
+
variables: [
|
563
|
+
{
|
564
|
+
ident: val[0],
|
565
|
+
value: val[1]
|
566
|
+
}
|
567
|
+
]
|
568
|
+
}
|
569
|
+
}
|
570
|
+
|
571
|
+
opt_default_value:
|
572
|
+
{ result = nil }
|
573
|
+
| tASSIGN atomic_value { result = val[1] }
|
48
574
|
|
49
575
|
expr:
|
50
|
-
|
576
|
+
actual_expr {}
|
577
|
+
| typecast actual_expr =TYPECAST
|
578
|
+
{
|
579
|
+
val[1].typecast = val[0]
|
580
|
+
result = val[1]
|
581
|
+
}
|
582
|
+
| expr tANDOP expr { result = binary_op val }
|
583
|
+
| expr tOROP expr { result = binary_op val }
|
584
|
+
|
585
|
+
typecast:
|
586
|
+
tLT dtype opt_star tGT { result = Expression::Typecast.new(val[1], val[2]) }
|
587
|
+
|
588
|
+
actual_expr:
|
589
|
+
expr_value {}
|
590
|
+
| expr_cmp {}
|
591
|
+
| tBANG expr { result = unary_op val }
|
592
|
+
| tLPAREN expr tRPAREN { result = val[1] }
|
593
|
+
|
594
|
+
expr_value:
|
595
|
+
expr_value tPLUS expr_value { result = binary_op val }
|
596
|
+
| expr_value tMINUS expr_value { result = binary_op val }
|
597
|
+
| expr_value tSTAR expr_value { result = binary_op val }
|
598
|
+
| expr_value tDIVIDE expr_value { result = binary_op val }
|
599
|
+
| expr_value tEXPO expr_value { result = binary_op val }
|
600
|
+
| expr_value tMODULUS expr_value { result = binary_op val }
|
601
|
+
| expr_value tBIT_AND expr_value { result = binary_op val }
|
602
|
+
| expr_value tBIT_OR expr_value { result = binary_op val }
|
603
|
+
| expr_value tBIT_XOR expr_value { result = binary_op val }
|
604
|
+
| expr_value tBIT_LSHIFT expr_value { result = binary_op val }
|
605
|
+
| expr_value tBIT_RSHIFT expr_value { result = binary_op val }
|
606
|
+
| tMINUS expr_value =UMINUS { result = unary_op val }
|
607
|
+
| tBIT_AND expr_value =ADDRESS_OF{ result = unary_op val }
|
608
|
+
| tBIT_NOT expr_value { result = unary_op val }
|
609
|
+
| tLPAREN expr_value tRPAREN { result = val[1] }
|
610
|
+
| atomic_value {}
|
611
|
+
|
612
|
+
expr_cmp:
|
613
|
+
expr_value tEQ expr_value { result = binary_op val }
|
614
|
+
| expr_value tNEQ expr_value { result = binary_op val }
|
615
|
+
| expr_value tLT expr_value { result = binary_op val }
|
616
|
+
| expr_value tLTEQ expr_value { result = binary_op val }
|
617
|
+
| expr_value tGT expr_value { result = binary_op val }
|
618
|
+
| expr_value tGTEQ expr_value { result = binary_op val }
|
619
|
+
| tLPAREN expr_cmp tRPAREN { result = val[1] }
|
620
|
+
|
621
|
+
atomic_value:
|
622
|
+
array_ref {}
|
623
|
+
| literal {}
|
624
|
+
| tIDENTIFIER command_opt_args
|
625
|
+
{
|
626
|
+
args = val[1]
|
627
|
+
result =
|
628
|
+
if args.empty?
|
629
|
+
Expression::Name.new val[0]
|
630
|
+
else
|
631
|
+
Expression::CommandCall.new nil, val[0], args
|
632
|
+
end
|
633
|
+
}
|
634
|
+
| command_call
|
635
|
+
| kSIZEOF tLPAREN dtype opt_star tRPAREN
|
636
|
+
{
|
637
|
+
result = Expression::SizeOf.new(val[2], val[3])
|
638
|
+
}
|
639
|
+
| kBLOCK_GIVEN { result = Expression::BlockGiven.new }
|
640
|
+
| kDATA_VAR
|
641
|
+
{
|
642
|
+
result = Expression::ElementRef.new('data',
|
643
|
+
Expression::Literal::Int.new('0'))
|
644
|
+
}
|
645
|
+
|
646
|
+
command_call:
|
647
|
+
method_or_attr command_opt_args
|
648
|
+
{
|
649
|
+
result = Expression::CommandCall.new val[0][0], val[0][1], val[1]
|
650
|
+
}
|
651
|
+
|
652
|
+
method_or_attr:
|
653
|
+
atomic_value tDOT f_name
|
654
|
+
{
|
655
|
+
result = [val[0], val[2]]
|
656
|
+
}
|
657
|
+
| atomic_value tDOT array_ref
|
658
|
+
{
|
659
|
+
result = [val[0], val[2]]
|
660
|
+
}
|
661
|
+
|
662
|
+
command_opt_args:
|
663
|
+
{ result = [] }
|
664
|
+
| tLPAREN command_arg_list tRPAREN { result = val[1] }
|
665
|
+
|
666
|
+
command_arg_list:
|
667
|
+
{ result = [] }
|
668
|
+
| expr { result = val }
|
669
|
+
| command_arg_list tCOMMA expr { result = [*val[0], val[2]] }
|
670
|
+
|
671
|
+
array_ref:
|
672
|
+
tIDENTIFIER tLSQUARE expr tRSQUARE
|
673
|
+
{
|
674
|
+
result = Expression::ElementRef.new val[0], val[2]
|
675
|
+
}
|
676
|
+
|
677
|
+
dtype:
|
678
|
+
kDTYPE_UINT | kDTYPE_LINT | kDTYPE_LLINT | kDTYPE_CHAR | kDTYPE_I8 |
|
679
|
+
kDTYPE_I16 | kDTYPE_I32 | kDTYPE_I64 | kDTYPE_UI8 | kDTYPE_UI16 |
|
680
|
+
kDTYPE_UI32 | kDTYPE_UI64 | kDTYPE_INT | kDTYPE_F32 | kDTYPE_F64 |
|
681
|
+
kDTYPE_LF64 | kDTYPE_ROBJ | kDTYPE_ULINT | kDTYPE_ULLINT | kDTYPE_VOID |
|
682
|
+
kDTYPE_SIZE_T | kDTYPE_RB_STR | kDTYPE_UCHAR | kDTYPE_BOOL | tCUSTOM_DTYPE |
|
683
|
+
kDTYPE_RB_ARR | kDTYPE_RB_HSH
|
684
|
+
{
|
685
|
+
result = val[0]
|
686
|
+
}
|
687
|
+
|
688
|
+
opt_expr:
|
689
|
+
{ result = nil }
|
690
|
+
| expr
|
691
|
+
|
692
|
+
opt_lparen:
|
693
|
+
{}
|
694
|
+
| tLPAREN
|
695
|
+
|
696
|
+
opt_rparen:
|
697
|
+
{}
|
698
|
+
| tRPAREN
|
699
|
+
|
700
|
+
opt_terms:
|
701
|
+
{}
|
702
|
+
| terms {}
|
703
|
+
|
704
|
+
terms:
|
705
|
+
term {}
|
706
|
+
| terms term {}
|
707
|
+
|
708
|
+
term:
|
709
|
+
tNL {}
|
710
|
+
| tSCOLON
|
711
|
+
|
712
|
+
opt_eols:
|
713
|
+
{}
|
714
|
+
| eols
|
715
|
+
|
716
|
+
eols:
|
717
|
+
eol
|
718
|
+
| eols eol
|
719
|
+
|
720
|
+
eol:
|
721
|
+
tNL {result = val[0]}
|
51
722
|
end
|
52
723
|
|
53
724
|
---- header
|
@@ -57,11 +728,188 @@ require_relative 'ast.rb'
|
|
57
728
|
include Rubex::AST
|
58
729
|
|
59
730
|
---- inner
|
731
|
+
|
732
|
+
attr_reader :lineno, :location, :string
|
733
|
+
|
60
734
|
def parse file_name
|
61
735
|
@lexer = Rubex::Lexer.new
|
736
|
+
@yydebug = true
|
737
|
+
@custom_dtypes = {}
|
738
|
+
@prev_token = nil
|
62
739
|
@lexer.parse_file file_name
|
63
740
|
end
|
64
741
|
|
742
|
+
def set_location
|
743
|
+
@location = @lexer.location
|
744
|
+
end
|
745
|
+
|
746
|
+
def set_string
|
747
|
+
@string = @lexer.ss.string
|
748
|
+
end
|
749
|
+
|
750
|
+
def set_lineno
|
751
|
+
@lineno = @lexer.lineno
|
752
|
+
end
|
753
|
+
|
65
754
|
def next_token
|
66
|
-
|
755
|
+
set_location
|
756
|
+
set_string
|
757
|
+
set_lineno
|
758
|
+
|
759
|
+
t = @lexer.next_token
|
760
|
+
if !t.nil?
|
761
|
+
if t[0] == :tIDENTIFIER
|
762
|
+
if @custom_dtypes.has_key?(t[1]) &&
|
763
|
+
!(@prev_token[0] == :kSTRUCT || @prev_token[0] == :tDOT)
|
764
|
+
t = [:tCUSTOM_DTYPE, t[1]]
|
765
|
+
else
|
766
|
+
t = check_for_primitive_dtype(t)
|
767
|
+
t = check_for_keyword(t)
|
768
|
+
end
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
@prev_token = t
|
773
|
+
t
|
774
|
+
end
|
775
|
+
|
776
|
+
def check_for_keyword token
|
777
|
+
match = token[1]
|
778
|
+
if match == "def"
|
779
|
+
return [:kDEF, match]
|
780
|
+
elsif match == "cfunc"
|
781
|
+
return [:kCFUNC, match]
|
782
|
+
elsif match == "self"
|
783
|
+
return [:kSELF, match]
|
784
|
+
elsif match == "do"
|
785
|
+
return [:kDO, match]
|
786
|
+
elsif match == "end"
|
787
|
+
return [:kEND, match]
|
788
|
+
elsif match == "return"
|
789
|
+
return [:kRETURN, match]
|
790
|
+
elsif match == "print"
|
791
|
+
return [:kPRINT , match]
|
792
|
+
elsif match == "if"
|
793
|
+
return [:kIF , match]
|
794
|
+
elsif match == "elsif"
|
795
|
+
return [:kELSIF , match]
|
796
|
+
elsif match == "else"
|
797
|
+
return [:kELSE , match]
|
798
|
+
elsif match == "then"
|
799
|
+
return [:kTHEN , match]
|
800
|
+
elsif match == "sizeof"
|
801
|
+
return [:kSIZEOF, match]
|
802
|
+
elsif match == "raise"
|
803
|
+
return [:kRAISE, match]
|
804
|
+
elsif match == "break"
|
805
|
+
return [:kBREAK, match]
|
806
|
+
elsif match == "begin"
|
807
|
+
return [:kBEGIN, match]
|
808
|
+
elsif match == "ensure"
|
809
|
+
return [:kENSURE, match]
|
810
|
+
elsif match == "rescue"
|
811
|
+
return [:kRESCUE, match]
|
812
|
+
end
|
813
|
+
|
814
|
+
return token
|
815
|
+
end
|
816
|
+
|
817
|
+
def check_for_primitive_dtype token
|
818
|
+
match = token[1]
|
819
|
+
if match == "char"
|
820
|
+
return [:kDTYPE_CHAR, match]
|
821
|
+
elsif match == "i8"
|
822
|
+
return [:kDTYPE_I8, match]
|
823
|
+
elsif match == "i16"
|
824
|
+
return [:kDTYPE_I16, match]
|
825
|
+
elsif match == "i32"
|
826
|
+
return [:kDTYPE_I32, match]
|
827
|
+
elsif match == "i64"
|
828
|
+
return [:kDTYPE_I64, match]
|
829
|
+
elsif match == "u8"
|
830
|
+
return [:kDTYPE_UI8, match]
|
831
|
+
elsif match == "u16"
|
832
|
+
return [:kDTYPE_UI16, match]
|
833
|
+
elsif match == "u32"
|
834
|
+
return [:kDTYPE_UI32, match]
|
835
|
+
elsif match == "u64"
|
836
|
+
return [:kDTYPE_UI64, match]
|
837
|
+
elsif match == "int"
|
838
|
+
return [:kDTYPE_INT, match]
|
839
|
+
elsif match == "long"
|
840
|
+
return [:kDTYPE_LINT, match]
|
841
|
+
elsif match == "f32"
|
842
|
+
return [:kDTYPE_F32, match]
|
843
|
+
elsif match == "float"
|
844
|
+
return [:kDTYPE_F32, match]
|
845
|
+
elsif match == "f64"
|
846
|
+
return [:kDTYPE_F64, match]
|
847
|
+
elsif match == "double"
|
848
|
+
return [:kDTYPE_F64, match]
|
849
|
+
elsif match == "object"
|
850
|
+
return[:kDTYPE_ROBJ, match]
|
851
|
+
elsif match == "void"
|
852
|
+
return[:kDTYPE_VOID, match]
|
853
|
+
elsif match == "size_t"
|
854
|
+
return [:kDTYPE_SIZE_T, match]
|
855
|
+
elsif match == "str"
|
856
|
+
return [:kDTYPE_RB_STR, match]
|
857
|
+
elsif match == "arr"
|
858
|
+
return [:kDTYPE_RB_ARR, match]
|
859
|
+
elsif match == "hsh"
|
860
|
+
return [:kDTYPE_RB_HSH, match]
|
861
|
+
elsif match == "yield"
|
862
|
+
return [:kYIELD, match]
|
863
|
+
elsif match == "bool"
|
864
|
+
return [:kDTYPE_BOOL, match]
|
865
|
+
end
|
866
|
+
|
867
|
+
token
|
868
|
+
end
|
869
|
+
|
870
|
+
def binary_op val
|
871
|
+
Expression::Binary.new val[0], val[1], val[2]
|
872
|
+
end
|
873
|
+
|
874
|
+
def unary_op val
|
875
|
+
Expression::Unary.new val[0], val[1]
|
876
|
+
end
|
877
|
+
|
878
|
+
# expr, op_assign, expr => expr = expr op expr
|
879
|
+
def op_assign val
|
880
|
+
Statement::Assign.new(val[0], binary_op([val[0], val[1][0], val[2]]), location)
|
881
|
+
end
|
882
|
+
|
883
|
+
def variable_decl_nodes val
|
884
|
+
variables = val[0]
|
885
|
+
type = variables[:dtype]
|
886
|
+
|
887
|
+
result = variables[:variables].map do |var|
|
888
|
+
ident = var[:ident]
|
889
|
+
ptr_level = var[:ptr_level]
|
890
|
+
|
891
|
+
statement =
|
892
|
+
if ident.is_a?(Hash) # only if function pointer
|
893
|
+
dtype = { dtype: type, ident: ident }
|
894
|
+
Statement::CPtrDecl.new(dtype, ident[:name], var[:value], ptr_level,
|
895
|
+
location)
|
896
|
+
else
|
897
|
+
if ptr_level
|
898
|
+
Statement::CPtrDecl.new(type, var[:ident], var[:value], ptr_level,
|
899
|
+
location)
|
900
|
+
elsif ident.is_a?(Expression::ElementRef)
|
901
|
+
Statement::CArrayDecl.new(type, var[:ident], var[:value], location)
|
902
|
+
else
|
903
|
+
Statement::VarDecl.new(type, var[:ident], var[:value], location)
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
statement
|
908
|
+
end
|
909
|
+
|
910
|
+
result
|
911
|
+
end
|
912
|
+
|
913
|
+
def add_dtype_to_lexer dtype
|
914
|
+
@custom_dtypes[dtype] = true
|
67
915
|
end
|