sydparse 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/parse_override.h ADDED
@@ -0,0 +1,14 @@
1
+
2
+ #define ruby_debug_lines PARSE_VAR(debug_lines)
3
+ #define heredoc_end PARSE_VAR(heredoc_end)
4
+ #define command_start PARSE_VAR(command_start)
5
+ #define lex_strterm PARSE_VAR(lex_strterm)
6
+ #define class_nest PARSE_VAR(class_nest)
7
+ #define in_single PARSE_VAR(in_single)
8
+ #define in_def PARSE_VAR(in_def)
9
+ #define compile_for_eval PARSE_VAR(compile_for_eval)
10
+ #define cur_mid PARSE_VAR(cur_mid)
11
+
12
+ #define tokenbuf PARSE_VAR(token_buffer)
13
+ #define tokidx PARSE_VAR(tokidx)
14
+ #define toksiz PARSE_VAR(toksiz)
data/runtime.c ADDED
@@ -0,0 +1,968 @@
1
+ #include "ruby.h"
2
+ #include "node.h"
3
+ #include "runtime.h"
4
+ #include "internal.h"
5
+
6
+ rb_parse_state *alloc_parse_state() {
7
+ rb_parse_state *st = (rb_parse_state*)malloc(sizeof(rb_parse_state));
8
+ memset(st, 0, sizeof(rb_parse_state));
9
+
10
+ st->command_start = Qtrue;
11
+ st->class_nest = 0;
12
+ st->in_single = 0;
13
+ st->in_def = 0;
14
+ st->compile_for_eval = 0;
15
+ st->cur_mid = 0;
16
+ st->token_buffer = NULL;
17
+ st->tokidx = 0;
18
+ st->toksiz = 0;
19
+ st->comments = 0;
20
+
21
+ return st;
22
+ }
23
+
24
+ void *rb_pt_mark(void *vps) {
25
+ rb_parse_state *parse_state = (rb_parse_state*)vps;
26
+
27
+ // rb_gc_mark_maybe((VALUE)(parse_state->lval->node));
28
+ rb_gc_mark(parse_state->lex_lastline);
29
+ rb_gc_mark(parse_state->lex_input);
30
+ rb_gc_mark(parse_state->self);
31
+ rb_gc_mark((VALUE)parse_state->top);
32
+ return NULL;
33
+ }
34
+
35
+ VALUE rb_cSydParser;
36
+
37
+ VALUE rb_pt_create() {
38
+ VALUE obj;
39
+ rb_parse_state *st;
40
+ st = alloc_parse_state();
41
+ obj = Data_Wrap_Struct(rb_cSydParser, rb_pt_mark, NULL, st);
42
+ st->self = obj;
43
+ return obj;
44
+ }
45
+
46
+ VALUE rb_pt_wrap_node(NODE *node) {
47
+ rb_parse_state *st;
48
+ VALUE pt = rb_pt_create();
49
+ Data_Get_Struct(pt, rb_parse_state, st);
50
+ st->top = (NODE*)node;
51
+ return pt;
52
+ }
53
+
54
+ void compile_error(const char *);
55
+
56
+ VALUE rb_pt_load_string(int argc, VALUE *argv, VALUE self) {
57
+ VALUE str, get_comments;
58
+ VALUE pt, old_err, *old_vars;
59
+ ID *old_tbl;
60
+ int state;
61
+ rb_parse_state *st;
62
+
63
+ get_comments = Qfalse;
64
+ rb_scan_args(argc, argv, "11", &str, &get_comments);
65
+
66
+ pt = rb_pt_create();
67
+ Data_Get_Struct(pt, rb_parse_state, st);
68
+
69
+ if(RTEST(get_comments)) {
70
+ st->comments = rb_ary_new();
71
+ }
72
+
73
+ old_err = ruby_errinfo;
74
+ ruby_errinfo = Qnil;
75
+ // PUSH_TAG(PROT_NONE);
76
+ // ruby_in_eval++;
77
+ // RUN_TAG(state) {
78
+ syd_compile_string("(eval)", str, 1, st);
79
+ // }
80
+ // POP_TAG();
81
+ // ruby_in_eval--;
82
+ if(ruby_nerrs > 0) {
83
+ rb_exc_raise(ruby_errinfo);
84
+ }
85
+ ruby_errinfo = old_err;
86
+
87
+ return pt;
88
+ }
89
+
90
+ #define SYMBOL(sym) rb_intern(#sym)
91
+
92
+ VALUE rb_pt_load_file(int argc, VALUE *argv, VALUE self) {
93
+ VALUE pt, old_err;
94
+ int state;
95
+ rb_parse_state *st;
96
+ VALUE file, fname, get_comments;
97
+
98
+ pt = rb_pt_create();
99
+ Data_Get_Struct(pt, rb_parse_state, st);
100
+
101
+ get_comments = Qfalse;
102
+ fname = Qfalse;
103
+ rb_scan_args(argc, argv, "12", &file, &fname, &get_comments);
104
+
105
+ if(!RTEST(fname)) {
106
+ fname = rb_funcall(file, SYMBOL(path), 0);
107
+ }
108
+
109
+ if(RTEST(get_comments)) {
110
+ st->comments = rb_ary_new();
111
+ }
112
+
113
+ old_err = ruby_errinfo;
114
+ // ruby_errinfo = Qnil;
115
+ // PUSH_TAG(PROT_NONE);
116
+ // ruby_in_eval++;
117
+ // RUN_TAG(state) {
118
+ syd_compile_file_from_state(RSTRING(fname)->ptr, file, 1, st);
119
+ // }
120
+ // POP_TAG();
121
+ // ruby_in_eval--;
122
+ if(ruby_nerrs > 0) {
123
+ rb_exc_raise(ruby_errinfo);
124
+ }
125
+ ruby_errinfo = old_err;
126
+
127
+ return pt;
128
+ }
129
+
130
+ /*
131
+ VALUE eval_node(VALUE, NODE*);
132
+
133
+ void jump_tag_but_local_jump(int, VALUE);
134
+ VALUE rb_pt_eval(int argc, VALUE *argv, VALUE self) {
135
+ VALUE old_err, result, wrapper, current_wrapper;
136
+ int state;
137
+ NODE *cref;
138
+ rb_parse_state *st;
139
+
140
+ Data_Get_Struct(self, rb_parse_state, st);
141
+ if(!rb_scan_args(argc, argv, "01", &wrapper)) {
142
+ wrapper = 0;
143
+ }
144
+
145
+ result = Qnil;
146
+ old_err = ruby_errinfo;
147
+ ruby_errinfo = Qnil;
148
+ current_wrapper = ruby_wrapper;
149
+ cref = ruby_cref;
150
+ PUSH_VARS();
151
+ PUSH_CLASS(ruby_wrapper);
152
+ ruby_cref = top_cref;
153
+ if (!RTEST(wrapper)) {
154
+ rb_secure(4);
155
+ ruby_class = rb_cObject;
156
+ ruby_wrapper = 0;
157
+ }
158
+ else {
159
+ if(wrapper == Qtrue) {
160
+ ruby_class = ruby_wrapper = rb_module_new();
161
+ } else {
162
+ if(rb_obj_is_kind_of(wrapper, CPATH(Module))) {
163
+ ruby_class = ruby_wrapper = wrapper;
164
+ } else {
165
+ rb_raise(CPATH(ArgumentError), "wrapper is not a module");
166
+ }
167
+ }
168
+ self = rb_obj_clone(ruby_top_self);
169
+ rb_extend_object(self, ruby_wrapper);
170
+ PUSH_CREF(ruby_wrapper);
171
+ }
172
+ PUSH_SCOPE();
173
+ SCOPE_SET(SCOPE_PRIVATE);
174
+ PUSH_TAG(PROT_NONE);
175
+ RUN_TAG(state) {
176
+ result = eval_node(self, st->top);
177
+ }
178
+ POP_TAG();
179
+ ruby_cref = cref;
180
+ POP_SCOPE();
181
+ POP_CLASS();
182
+ POP_VARS();
183
+ ruby_wrapper = current_wrapper;
184
+
185
+ if(state) jump_tag_but_local_jump(state, Qundef);
186
+
187
+ return result;
188
+ }
189
+
190
+ */
191
+
192
+ VALUE rb_pt_loaded(VALUE self) {
193
+ rb_parse_state *st;
194
+ Data_Get_Struct(self, rb_parse_state, st);
195
+
196
+ if(st->top) {
197
+ return Qtrue;
198
+ } else {
199
+ return Qfalse;
200
+ }
201
+ }
202
+
203
+ NODE *rb_pt_top(VALUE self) {
204
+ rb_parse_state *st;
205
+ Data_Get_Struct(self, rb_parse_state, st);
206
+ return st->top;
207
+ }
208
+
209
+
210
+ /*
211
+ *
212
+ * 100% of the credit for the following node tree => sexp transform goes
213
+ * to Ryan Davis (zenspider) and Eric Hodel (drbrain).
214
+ *
215
+ * It was mearly imported into this space by Evan Webb.
216
+ */
217
+ static char node_type_string[][60] = {
218
+ /* 00 */
219
+ "method", "fbody", "cfunc", "scope", "block",
220
+ "if", "case", "when", "opt_n", "while",
221
+ /* 10 */
222
+ "until", "iter", "for", "break", "next",
223
+ "redo", "retry", "begin", "rescue", "resbody",
224
+ /* 20 */
225
+ "ensure", "and", "or", "not", "masgn",
226
+ "lasgn", "dasgn", "dasgn_curr", "gasgn", "iasgn",
227
+ /* 30 */
228
+ "cdecl", "cvasgn", "cvdecl", "op_asgn1", "op_asgn2",
229
+ "op_asgn_and", "op_asgn_or", "call", "fcall", "vcall",
230
+ /* 40 */
231
+ "super", "zsuper", "array", "zarray", "hash",
232
+ "return", "yield", "lvar", "dvar", "gvar",
233
+ /* 50 */
234
+ "ivar", "const", "cvar", "nth_ref", "back_ref",
235
+ "match", "match2", "match3", "lit", "str",
236
+ /* 60 */
237
+ "dstr", "xstr", "dxstr", "evstr", "dregx",
238
+ "dregx_once", "args", "argscat", "argspush", "splat",
239
+ /* 70 */
240
+ "to_ary", "svalue", "block_arg", "block_pass", "defn",
241
+ "defs", "alias", "valias", "undef", "class",
242
+ /* 80 */
243
+ "module", "sclass", "colon2", "colon3", "cref",
244
+ "dot2", "dot3", "flip2", "flip3", "attrset",
245
+ /* 90 */
246
+ "self", "nil", "true", "false", "defined",
247
+ /* 95 */
248
+ "newline", "postexe",
249
+ #ifdef C_ALLOCA
250
+ "alloca",
251
+ #endif
252
+ "dmethod", "bmethod",
253
+ /* 100 / 99 */
254
+ "memo", "ifunc", "dsym", "attrasgn",
255
+ /* 104 / 103 */
256
+ "last"
257
+ };
258
+
259
+ #define nd_3rd u3.node
260
+
261
+
262
+ #define ADD_LINE if(node && RTEST(line_numbers)) { rb_ary_push(current, INT2NUM(nd_line(node))); }
263
+
264
+ void add_to_parse_tree(VALUE ary,
265
+ NODE * n,
266
+ VALUE newlines,
267
+ ID * locals,
268
+ VALUE line_numbers) {
269
+ NODE * volatile node = n;
270
+ NODE * volatile contnode = NULL;
271
+ VALUE old_ary = Qnil;
272
+ VALUE current;
273
+ VALUE node_name;
274
+
275
+ if (!node) return;
276
+
277
+ again:
278
+
279
+ if (node) {
280
+ node_name = ID2SYM(rb_intern(node_type_string[nd_type(node)]));
281
+ if (RTEST(ruby_debug)) {
282
+ fprintf(stderr, "%15s: %s%s%s\n",
283
+ node_type_string[nd_type(node)],
284
+ (RNODE(node)->u1.node != NULL ? "u1 " : " "),
285
+ (RNODE(node)->u2.node != NULL ? "u2 " : " "),
286
+ (RNODE(node)->u3.node != NULL ? "u3 " : " "));
287
+ }
288
+ } else {
289
+ node_name = ID2SYM(rb_intern("ICKY"));
290
+ }
291
+
292
+ current = rb_ary_new();
293
+ rb_ary_push(ary, current);
294
+ rb_ary_push(current, node_name);
295
+
296
+ again_no_block:
297
+
298
+ switch (nd_type(node)) {
299
+
300
+ case NODE_BLOCK:
301
+ if (contnode) {
302
+ add_to_parse_tree(current, node, newlines, locals, line_numbers);
303
+ break;
304
+ }
305
+
306
+ contnode = node->nd_next;
307
+
308
+ /* NOTE: this will break the moment there is a block w/in a block */
309
+ old_ary = ary;
310
+ ary = current;
311
+ node = node->nd_head;
312
+ goto again;
313
+ break;
314
+
315
+ case NODE_FBODY:
316
+ case NODE_DEFINED:
317
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
318
+ break;
319
+
320
+ case NODE_COLON2:
321
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
322
+ rb_ary_push(current, ID2SYM(node->nd_mid));
323
+ break;
324
+
325
+ case NODE_MATCH2:
326
+ case NODE_MATCH3:
327
+ add_to_parse_tree(current, node->nd_recv, newlines, locals, line_numbers);
328
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
329
+ break;
330
+
331
+ case NODE_BEGIN:
332
+ case NODE_OPT_N:
333
+ case NODE_NOT:
334
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
335
+ break;
336
+
337
+ case NODE_IF:
338
+ add_to_parse_tree(current, node->nd_cond, newlines, locals, line_numbers);
339
+ if (node->nd_body) {
340
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
341
+ } else {
342
+ rb_ary_push(current, Qnil);
343
+ }
344
+ if (node->nd_else) {
345
+ add_to_parse_tree(current, node->nd_else, newlines, locals, line_numbers);
346
+ } else {
347
+ rb_ary_push(current, Qnil);
348
+ }
349
+ break;
350
+
351
+ case NODE_CASE:
352
+ {
353
+ VALUE tmp;
354
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers); /* expr */
355
+ node = node->nd_body;
356
+ tmp = rb_ary_new();
357
+ rb_ary_push(current, tmp);
358
+ while (node) {
359
+ add_to_parse_tree(tmp, node, newlines, locals, line_numbers);
360
+ if (nd_type(node) == NODE_WHEN) { /* when */
361
+ node = node->nd_next;
362
+ } else {
363
+ rb_ary_push(current, rb_ary_pop(tmp));
364
+ break; /* else */
365
+ }
366
+ if (! node) {
367
+ rb_ary_push(current, Qnil); /* no else */
368
+ }
369
+ }
370
+ break;
371
+ }
372
+ case NODE_WHEN:
373
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers); /* args */
374
+ if (node->nd_body) {
375
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers); /* body */
376
+ } else {
377
+ rb_ary_push(current, Qnil);
378
+ }
379
+ break;
380
+
381
+ case NODE_WHILE:
382
+ case NODE_UNTIL:
383
+ add_to_parse_tree(current, node->nd_cond, newlines, locals, line_numbers);
384
+ if(node->nd_body) {
385
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
386
+ } else {
387
+ rb_ary_push(current, Qnil);
388
+ }
389
+ rb_ary_push(current, node->nd_3rd == 0 ? Qfalse : Qtrue);
390
+ break;
391
+
392
+ case NODE_BLOCK_PASS:
393
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
394
+ add_to_parse_tree(current, node->nd_iter, newlines, locals, line_numbers);
395
+ break;
396
+
397
+ case NODE_ITER:
398
+ case NODE_FOR:
399
+ add_to_parse_tree(current, node->nd_iter, newlines, locals, line_numbers);
400
+ if (node->nd_var != (NODE *)1
401
+ && node->nd_var != (NODE *)2
402
+ && node->nd_var != NULL) {
403
+ add_to_parse_tree(current, node->nd_var, newlines, locals, line_numbers);
404
+ } else {
405
+ rb_ary_push(current, Qnil);
406
+ }
407
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
408
+ break;
409
+
410
+ case NODE_BREAK:
411
+ case NODE_NEXT:
412
+ if (node->nd_stts)
413
+ add_to_parse_tree(current, node->nd_stts, newlines, locals, line_numbers);
414
+ break;
415
+ case NODE_YIELD:
416
+ if (node->nd_stts) {
417
+ add_to_parse_tree(current, node->nd_stts, newlines, locals, line_numbers);
418
+ } else {
419
+ rb_ary_push(current, Qnil);
420
+ }
421
+ rb_ary_push(current, node->u3.value);
422
+ break;
423
+
424
+ case NODE_RESCUE:
425
+ add_to_parse_tree(current, node->nd_1st, newlines, locals, line_numbers);
426
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals, line_numbers);
427
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals, line_numbers);
428
+ break;
429
+
430
+ /* rescue body:
431
+ * begin stmt rescue exception => var; stmt; [rescue e2 => v2; s2;]* end
432
+ * stmt rescue stmt
433
+ * a = b rescue c */
434
+
435
+ case NODE_RESBODY:
436
+ if(node->nd_3rd) {
437
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals, line_numbers);
438
+ } else {
439
+ rb_ary_push(current, Qnil);
440
+ }
441
+ if(node->nd_2nd) {
442
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals, line_numbers);
443
+ } else {
444
+ rb_ary_push(current, Qnil);
445
+ }
446
+ if(node->nd_1st) {
447
+ add_to_parse_tree(current, node->nd_1st, newlines, locals, line_numbers);
448
+ } else {
449
+ rb_ary_push(current, Qnil);
450
+ }
451
+ break;
452
+
453
+ case NODE_ENSURE:
454
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
455
+ if (node->nd_ensr) {
456
+ add_to_parse_tree(current, node->nd_ensr, newlines, locals, line_numbers);
457
+ }
458
+ break;
459
+
460
+ case NODE_AND:
461
+ case NODE_OR:
462
+ add_to_parse_tree(current, node->nd_1st, newlines, locals, line_numbers);
463
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals, line_numbers);
464
+ break;
465
+
466
+ case NODE_DOT2:
467
+ case NODE_DOT3:
468
+ case NODE_FLIP2:
469
+ case NODE_FLIP3:
470
+ add_to_parse_tree(current, node->nd_beg, newlines, locals, line_numbers);
471
+ add_to_parse_tree(current, node->nd_end, newlines, locals, line_numbers);
472
+ break;
473
+
474
+ case NODE_RETURN:
475
+ if (node->nd_stts)
476
+ add_to_parse_tree(current, node->nd_stts, newlines, locals, line_numbers);
477
+ break;
478
+
479
+ case NODE_ARGSCAT:
480
+ case NODE_ARGSPUSH:
481
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
482
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
483
+ break;
484
+
485
+ case NODE_CALL:
486
+ case NODE_FCALL:
487
+ case NODE_VCALL:
488
+ if (nd_type(node) != NODE_FCALL)
489
+ add_to_parse_tree(current, node->nd_recv, newlines, locals, line_numbers);
490
+ rb_ary_push(current, ID2SYM(node->nd_mid));
491
+ if (node->nd_args || nd_type(node) != NODE_FCALL)
492
+ add_to_parse_tree(current, node->nd_args, newlines, locals, line_numbers);
493
+ break;
494
+
495
+ case NODE_SUPER:
496
+ add_to_parse_tree(current, node->nd_args, newlines, locals, line_numbers);
497
+ break;
498
+
499
+ case NODE_BMETHOD:
500
+ {
501
+ struct BLOCK *data;
502
+ Data_Get_Struct(node->nd_cval, struct BLOCK, data);
503
+ add_to_parse_tree(current, data->var, newlines, locals, line_numbers);
504
+ add_to_parse_tree(current, data->body, newlines, locals, line_numbers);
505
+ break;
506
+ }
507
+ break;
508
+
509
+ case NODE_DMETHOD:
510
+ {
511
+ struct METHOD *data;
512
+ Data_Get_Struct(node->nd_cval, struct METHOD, data);
513
+ rb_ary_push(current, ID2SYM(data->id));
514
+ add_to_parse_tree(current, data->body, newlines, locals, line_numbers);
515
+ break;
516
+ }
517
+
518
+ case NODE_METHOD:
519
+ fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
520
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals, line_numbers);
521
+ break;
522
+
523
+ case NODE_SCOPE:
524
+ {
525
+ VALUE tbl;
526
+ int i;
527
+ tbl = rb_ary_new();
528
+ // printf("=> scope %x, %d\n", node->nd_tbl, node->nd_tbl[0]);
529
+ add_to_parse_tree(current, node->nd_next, newlines, node->nd_tbl, line_numbers);
530
+ for(i = 0; i < node->nd_tbl[0]; i++) {
531
+ rb_ary_push(tbl, ID2SYM(node->nd_tbl[i + 3]));
532
+ }
533
+ rb_ary_push(current, tbl);
534
+ }
535
+ break;
536
+
537
+ case NODE_OP_ASGN1:
538
+ add_to_parse_tree(current, node->nd_recv, newlines, locals, line_numbers);
539
+ switch(node->nd_mid) {
540
+ case 0:
541
+ rb_ary_push(current, ID2SYM(rb_intern("or")));
542
+ break;
543
+ case 1:
544
+ rb_ary_push(current, ID2SYM(rb_intern("and")));
545
+ break;
546
+ default:
547
+ rb_ary_push(current, ID2SYM(node->nd_mid));
548
+ }
549
+ //add_to_parse_tree(current, node->nd_args->nd_next, newlines, locals, line_numbers);
550
+ add_to_parse_tree(current, node->nd_args, newlines, locals, line_numbers);
551
+ break;
552
+
553
+ case NODE_OP_ASGN2:
554
+ add_to_parse_tree(current, node->nd_recv, newlines, locals, line_numbers);
555
+ rb_ary_push(current, ID2SYM(node->nd_next->nd_vid));
556
+ switch(node->nd_next->nd_mid) {
557
+ case 0:
558
+ rb_ary_push(current, ID2SYM(rb_intern("or")));
559
+ break;
560
+ case 1:
561
+ rb_ary_push(current, ID2SYM(rb_intern("and")));
562
+ break;
563
+ default:
564
+ rb_ary_push(current, ID2SYM(node->nd_next->nd_mid));
565
+ }
566
+
567
+ rb_ary_push(current, ID2SYM(node->nd_next->nd_aid));
568
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
569
+ break;
570
+
571
+ case NODE_OP_ASGN_AND:
572
+ case NODE_OP_ASGN_OR:
573
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
574
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
575
+ break;
576
+
577
+ case NODE_MASGN:
578
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
579
+ if (node->nd_args) {
580
+ if(node->nd_args != (NODE *)-1) {
581
+ add_to_parse_tree(current, node->nd_args, newlines, locals, line_numbers);
582
+ } else {
583
+ rb_ary_push(current, Qtrue);
584
+ }
585
+ } else {
586
+ rb_ary_push(current, Qnil);
587
+ }
588
+ if(node->nd_value) {
589
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
590
+ } else {
591
+ rb_ary_push(current, Qnil);
592
+ }
593
+ break;
594
+
595
+ case NODE_LASGN:
596
+ rb_ary_push(current, ID2SYM(node->nd_vid));
597
+ rb_ary_push(current, INT2NUM(node->nd_cnt));
598
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
599
+ break;
600
+ case NODE_IASGN:
601
+ case NODE_DASGN:
602
+ case NODE_DASGN_CURR:
603
+ case NODE_CVASGN:
604
+ case NODE_CVDECL:
605
+ case NODE_GASGN:
606
+ rb_ary_push(current, ID2SYM(node->nd_vid));
607
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
608
+ break;
609
+
610
+ case NODE_CDECL:
611
+ if(node->nd_vid == 0) {
612
+ rb_ary_push(current, Qnil);
613
+ } else {
614
+ rb_ary_push(current, ID2SYM(node->nd_vid));
615
+ }
616
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
617
+ if(node->nd_next) {
618
+ add_to_parse_tree(current, node->nd_next, newlines, locals, line_numbers);
619
+ } else {
620
+ rb_ary_push(current, Qnil);
621
+ }
622
+ break;
623
+
624
+ case NODE_ALIAS: /* u1 u2 (alias :blah :blah2) */
625
+ case NODE_VALIAS: /* u1 u2 (alias $global $global2) */
626
+ rb_ary_push(current, ID2SYM(node->u1.id));
627
+ rb_ary_push(current, ID2SYM(node->u2.id));
628
+ break;
629
+
630
+ case NODE_COLON3: /* u2 (::OUTER_CONST) */
631
+ case NODE_UNDEF: /* u2 (undef instvar) */
632
+ rb_ary_push(current, ID2SYM(node->u2.id));
633
+ break;
634
+
635
+ case NODE_HASH:
636
+ {
637
+ NODE *list;
638
+
639
+ /* Support for sydneys flag on a Hash which indicates that it was
640
+ create implicitly from using a hash style syntax in a method call
641
+ but without using {}'s */
642
+ if(node->u2.argc) {
643
+ rb_ary_store(current, 0, ID2SYM(rb_intern("ihash")));
644
+ }
645
+
646
+ list = node->nd_head;
647
+ while (list) {
648
+ add_to_parse_tree(current, list->nd_head, newlines, locals, line_numbers);
649
+ list = list->nd_next;
650
+ if (list == 0)
651
+ rb_bug("odd number list for Hash");
652
+ add_to_parse_tree(current, list->nd_head, newlines, locals, line_numbers);
653
+ list = list->nd_next;
654
+ }
655
+ }
656
+ break;
657
+
658
+ case NODE_ARRAY:
659
+ while (node) {
660
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
661
+ node = node->nd_next;
662
+ }
663
+ break;
664
+
665
+ case NODE_DSTR:
666
+ case NODE_DXSTR:
667
+ case NODE_DREGX:
668
+ case NODE_DREGX_ONCE:
669
+ {
670
+ NODE *list = node->nd_next;
671
+ //if (nd_type(node) == NODE_DREGX || nd_type(node) == NODE_DREGX_ONCE) {
672
+ // break;
673
+ //}
674
+ if(0 && node->u2.id) {
675
+ rb_ary_pop(current);
676
+ rb_ary_push(current, ID2SYM(rb_intern("xstr_custom")));
677
+ rb_ary_push(current, ID2SYM(node->u2.id));
678
+ }
679
+ rb_ary_push(current, rb_str_new3(node->nd_lit));
680
+ while (list) {
681
+ if (list->nd_head) {
682
+ switch (nd_type(list->nd_head)) {
683
+ case NODE_STR:
684
+ add_to_parse_tree(current, list->nd_head, newlines, locals, line_numbers);
685
+ break;
686
+ case NODE_EVSTR:
687
+ add_to_parse_tree(current, list->nd_head, newlines, locals, line_numbers);
688
+ break;
689
+ default:
690
+ add_to_parse_tree(current, list->nd_head, newlines, locals, line_numbers);
691
+ break;
692
+ }
693
+ }
694
+ list = list->nd_next;
695
+ }
696
+ }
697
+ break;
698
+
699
+ case NODE_DEFN:
700
+ case NODE_DEFS:
701
+ if (node->nd_defn) {
702
+ if (nd_type(node) == NODE_DEFS)
703
+ add_to_parse_tree(current, node->nd_recv, newlines, locals, line_numbers);
704
+ rb_ary_push(current, ID2SYM(node->nd_mid));
705
+ add_to_parse_tree(current, node->nd_defn, newlines, locals, line_numbers);
706
+ }
707
+ break;
708
+
709
+ case NODE_CLASS:
710
+ case NODE_MODULE:
711
+ add_to_parse_tree(current, node->nd_cpath, newlines, locals, line_numbers);
712
+ // rb_ary_push(current, ID2SYM((ID)node->nd_cpath->nd_mid));
713
+ if (nd_type(node) == NODE_CLASS) {
714
+ if(node->nd_super) {
715
+ add_to_parse_tree(current, node->nd_super, newlines, locals, line_numbers);
716
+ } else {
717
+ rb_ary_push(current, Qnil);
718
+ }
719
+ }
720
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
721
+ break;
722
+
723
+ case NODE_SCLASS:
724
+ add_to_parse_tree(current, node->nd_recv, newlines, locals, line_numbers);
725
+ add_to_parse_tree(current, node->nd_body, newlines, locals, line_numbers);
726
+ break;
727
+
728
+ case NODE_ARGS:
729
+ if (locals &&
730
+ (node->nd_cnt || node->nd_opt || node->nd_rest != -1)) {
731
+ int i;
732
+ NODE *optnode;
733
+ VALUE tmp;
734
+ long arg_count;
735
+
736
+ if(locals[0] < node->nd_cnt) {
737
+ rb_raise(rb_eStandardError, "Corrupted args detected (count of %d, local size of %d)", node->nd_cnt, locals[0]);
738
+ }
739
+ tmp = rb_ary_new();
740
+ rb_ary_push(current, tmp);
741
+ // printf("locals: %x (%d / cnt:%d)\n", locals, locals[0], node->nd_cnt);
742
+ for (i = 0; i < node->nd_cnt; i++) {
743
+ /* regular arg names */
744
+ // printf("Pushing %d/%d %d (%s)\n", i, node->nd_cnt, locals[i + 3], rb_id2name(locals[i + 3]));
745
+ rb_ary_push(tmp, ID2SYM(locals[i + 3]));
746
+ }
747
+
748
+ tmp = rb_ary_new();
749
+ rb_ary_push(current, tmp);
750
+
751
+ optnode = node->nd_opt;
752
+ while (optnode) {
753
+ /* optional arg names */
754
+ rb_ary_push(tmp, ID2SYM(locals[i + 3]));
755
+ i++;
756
+ optnode = optnode->nd_next;
757
+ }
758
+
759
+ arg_count = node->nd_rest;
760
+ if (arg_count > 0) {
761
+ /* *arg name */
762
+ tmp = rb_ary_new();
763
+ rb_ary_push(tmp, ID2SYM(locals[arg_count+1]));
764
+ rb_ary_push(tmp, INT2FIX(arg_count));
765
+ //VALUE sym = rb_str_intern(rb_str_plus(rb_str_new2("*"),
766
+ // rb_str_new2(rb_id2name(locals[node->nd_rest + 1]))));
767
+ rb_ary_push(current, tmp);
768
+ } else if (arg_count == -1) {
769
+ rb_ary_push(current, Qnil);
770
+ /* nothing to do in this case, handled above */
771
+ } else if (arg_count == -2) {
772
+ rb_ary_push(current, Qnil);
773
+ /* nothing to do in this case, no name == no use */
774
+ } else {
775
+ printf("Unknown arg_count %d encountered while processing args.\n", arg_count);
776
+ break;
777
+ // exit(1);
778
+ }
779
+
780
+ optnode = node->nd_opt;
781
+ /* block? */
782
+ if (optnode) {
783
+ add_to_parse_tree(current, node->nd_opt, newlines, locals, line_numbers);
784
+ } else {
785
+ rb_ary_push(current, Qnil);
786
+ }
787
+ }
788
+ break;
789
+
790
+ case NODE_LVAR:
791
+ rb_ary_push(current, ID2SYM(node->nd_vid));
792
+ rb_ary_push(current, INT2NUM(node->nd_cnt));
793
+ break;
794
+
795
+ case NODE_DVAR:
796
+ case NODE_IVAR:
797
+ case NODE_CVAR:
798
+ case NODE_GVAR:
799
+ case NODE_CONST:
800
+ case NODE_ATTRSET:
801
+ rb_ary_push(current, ID2SYM(node->nd_vid));
802
+ break;
803
+
804
+ case NODE_XSTR: /* u1 (%x{ls}) */
805
+ case NODE_STR: /* u1 */
806
+ case NODE_LIT:
807
+ case NODE_MATCH:
808
+ rb_ary_push(current, node->nd_lit);
809
+ break;
810
+
811
+ case NODE_NEWLINE:
812
+ ADD_LINE;
813
+
814
+ if(RTEST(newlines)) {
815
+ rb_ary_push(current, INT2FIX(nd_line(node)));
816
+ rb_ary_push(current, rb_str_new2(node->nd_file));
817
+ add_to_parse_tree(current, node->nd_next, newlines, locals, line_numbers);
818
+ } else {
819
+ rb_ary_pop(ary);
820
+ node = node->nd_next;
821
+ goto again;
822
+ }
823
+ break;
824
+
825
+ case NODE_NTH_REF: /* u2 u3 ($1) - u3 is local_cnt('~') ignorable? */
826
+ rb_ary_push(current, INT2FIX(node->nd_nth));
827
+ break;
828
+
829
+ case NODE_BACK_REF: /* u2 u3 ($& etc) */
830
+ {
831
+ char c = node->nd_nth;
832
+ rb_ary_push(current, rb_str_intern(rb_str_new(&c, 1)));
833
+ }
834
+ break;
835
+
836
+ case NODE_BLOCK_ARG: /* u1 u3 (def x(&b) */
837
+ rb_ary_push(current, ID2SYM(node->u1.id));
838
+ rb_ary_push(current, INT2FIX(node->nd_cnt));
839
+ break;
840
+
841
+ /* these nodes are empty and do not require extra work: */
842
+ case NODE_RETRY:
843
+ case NODE_FALSE:
844
+ case NODE_NIL:
845
+ case NODE_SELF:
846
+ case NODE_TRUE:
847
+ case NODE_ZARRAY:
848
+ case NODE_ZSUPER:
849
+ case NODE_REDO:
850
+ break;
851
+
852
+ case NODE_SPLAT:
853
+ case NODE_TO_ARY:
854
+ case NODE_SVALUE: /* a = b, c */
855
+ add_to_parse_tree(current, node->nd_head, newlines, locals, line_numbers);
856
+ break;
857
+
858
+ case NODE_ATTRASGN: /* literal.meth = y u1 u2 u3 */
859
+ /* node id node */
860
+ if (node->nd_1st == RNODE(1)) {
861
+ add_to_parse_tree(current, NEW_SELF(), newlines, locals, line_numbers);
862
+ } else {
863
+ add_to_parse_tree(current, node->nd_1st, newlines, locals, line_numbers);
864
+ }
865
+ rb_ary_push(current, ID2SYM(node->u2.id));
866
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals, line_numbers);
867
+ break;
868
+
869
+ case NODE_DSYM: /* :"#{foo}" u1 u2 u3 */
870
+ add_to_parse_tree(current, node->nd_3rd, newlines, locals, line_numbers);
871
+ break;
872
+
873
+ case NODE_EVSTR:
874
+ add_to_parse_tree(current, node->nd_2nd, newlines, locals, line_numbers);
875
+ break;
876
+
877
+ case NODE_POSTEXE: /* END { ... } */
878
+ /* Nothing to do here... we are in an iter block */
879
+ break;
880
+
881
+ case NODE_CFUNC:
882
+ rb_ary_push(current, INT2FIX(node->nd_cfnc));
883
+ rb_ary_push(current, INT2FIX(node->nd_argc));
884
+ break;
885
+
886
+ /* Nodes we found but have yet to decypher
887
+ I think these are all runtime only... not positive but... */
888
+ case NODE_MEMO: /* enum.c zip */
889
+ case NODE_CREF:
890
+ case NODE_IFUNC:
891
+ /* #defines:
892
+ case NODE_LMASK:
893
+ case NODE_LSHIFT: */
894
+ default:
895
+ rb_warn("Unhandled node #%d type '%s'", nd_type(node), node_type_string[nd_type(node)]);
896
+ if (RNODE(node)->u1.node != NULL) rb_warning("unhandled u1 value");
897
+ if (RNODE(node)->u2.node != NULL) rb_warning("unhandled u2 value");
898
+ if (RNODE(node)->u3.node != NULL) rb_warning("unhandled u3 value");
899
+ if (RTEST(ruby_debug)) fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
900
+ rb_ary_push(current, INT2FIX(-99));
901
+ rb_ary_push(current, INT2FIX(nd_type(node)));
902
+ break;
903
+ }
904
+
905
+ ADD_LINE;
906
+
907
+ /* finish: */
908
+ if (contnode) {
909
+ node = contnode;
910
+ contnode = NULL;
911
+ current = ary;
912
+ ary = old_ary;
913
+ old_ary = Qnil;
914
+ goto again_no_block;
915
+ }
916
+ }
917
+
918
+ VALUE rb_pt_sexp(int argc, VALUE *argv, VALUE self) {
919
+ rb_parse_state *st;
920
+ VALUE result;
921
+ VALUE line_numbers, newlines;
922
+
923
+ line_numbers = Qfalse;
924
+ newlines = Qfalse;
925
+
926
+ rb_scan_args(argc, argv, "02", &line_numbers, &newlines);
927
+
928
+ Data_Get_Struct(self, rb_parse_state, st);
929
+ result = rb_ary_new();
930
+ if(!st->top) {
931
+ return result;
932
+ }
933
+
934
+ add_to_parse_tree(result, st->top, newlines, NULL, line_numbers);
935
+ /* Seems that the way the parser is setup now, we always get one
936
+ element in the array, so just return it. */
937
+ return RARRAY(result)->ptr[0];
938
+ }
939
+
940
+ VALUE rb_pt_comments(VALUE self) {
941
+ rb_parse_state *st;
942
+
943
+ Data_Get_Struct(self, rb_parse_state, st);
944
+
945
+ if(st->comments) {
946
+ return st->comments;
947
+ } else {
948
+ return Qnil;
949
+ }
950
+ }
951
+
952
+
953
+ void Init_sydney_parser() {
954
+ VALUE cParser;
955
+ setup_parser();
956
+
957
+ cParser = rb_define_class("SydneyParser",rb_cObject);
958
+ rb_define_singleton_method(cParser, "load_string", rb_pt_load_string, -1);
959
+ rb_define_singleton_method(cParser, "load_file", rb_pt_load_file, -1);
960
+ rb_define_singleton_method(cParser, "new", rb_pt_create, 0);
961
+ rb_define_method(cParser, "loaded?", rb_pt_loaded, 0);
962
+ // rb_define_method(cParser, "evaluate", rb_pt_eval, -1);
963
+ rb_define_method(cParser, "sexp", rb_pt_sexp, -1);
964
+ rb_define_method(cParser, "comments", rb_pt_comments, 0);
965
+ rb_cSydParser = cParser;
966
+
967
+ // Init_accelload();
968
+ }