Lines Matching refs:g

9 static void generate(struct generator * g, struct node * p);
10 static void w(struct generator * g, const char * s);
11 static void writef(struct generator * g, const char * s, struct node * p);
13 static int new_label(struct generator * g) { in new_label() argument
14 return g->next_label++; in new_label()
17 static struct str * vars_newname(struct generator * g) { in vars_newname() argument
20 g->var_number++; in vars_newname()
23 str_append_int(output, g->var_number); in vars_newname()
30 static void write_varname(struct generator * g, struct name * p) { in write_varname() argument
34 write_char(g, ch); in write_varname()
35 write_char(g, '_'); in write_varname()
37 write_b(g, p->b); in write_varname()
40 static void write_varref(struct generator * g, struct name * p) { in write_varref() argument
41 write_varname(g, p); in write_varref()
44 static void write_hexdigit(struct generator * g, int n) { in write_hexdigit() argument
46 write_char(g, n < 10 ? n + '0' : n - 10 + 'A'); in write_hexdigit()
49 static void write_hex(struct generator * g, int ch) { in write_hex() argument
51 write_string(g, "\\u"); in write_hex()
54 for (i = 12; i >= 0; i -= 4) write_hexdigit(g, ch >> i & 0xf); in write_hex()
58 static void write_literal_string(struct generator * g, symbol * p) { in write_literal_string() argument
61 write_string(g, "\""); in write_literal_string()
65 if (ch == '\"' || ch == '\\') write_string(g, "\\"); in write_literal_string()
66 write_char(g, ch); in write_literal_string()
68 write_hex(g, ch); in write_literal_string()
71 write_string(g, "\""); in write_literal_string()
74 static void write_margin(struct generator * g) { in write_margin() argument
77 for (i = 0; i < g->margin; i++) write_string(g, " "); in write_margin()
80 static void write_comment(struct generator * g, struct node * p) { in write_comment() argument
81 if (!g->options->comments) return; in write_comment()
82 write_margin(g); in write_comment()
83 write_string(g, "// "); in write_comment()
84 write_comment_content(g, p); in write_comment()
85 write_newline(g); in write_comment()
88 static void write_block_start(struct generator * g) { in write_block_start() argument
90 w(g, "~M{~+~N"); in write_block_start()
93 static void write_block_end(struct generator * g) /* block end */ { in write_block_end() argument
95 w(g, "~-~M}~N"); in write_block_end()
98 static void write_savecursor(struct generator * g, struct node * p, in write_savecursor() argument
101 g->B[0] = str_data(savevar); in write_savecursor()
102 g->S[1] = ""; in write_savecursor()
103 if (p->mode != m_forward) g->S[1] = "base.limit - "; in write_savecursor()
104 writef(g, "~Mvar /** number */ ~B0 = ~S1base.cursor;~N", p); in write_savecursor()
116 static void write_restorecursor(struct generator * g, struct node * p, in write_restorecursor() argument
120 write_margin(g); in write_restorecursor()
122 write_str(g, temp); in write_restorecursor()
123 write_newline(g); in write_restorecursor()
127 static void write_inc_cursor(struct generator * g, struct node * p) { in write_inc_cursor() argument
129 write_margin(g); in write_inc_cursor()
130 write_string(g, p->mode == m_forward ? "base.cursor++;" : "base.cursor--;"); in write_inc_cursor()
131 write_newline(g); in write_inc_cursor()
134 static void wsetlab_begin(struct generator * g, int n) { in wsetlab_begin() argument
135 g->I[0] = n; in wsetlab_begin()
136 w(g, "~Mlab~I0: {~N~+"); in wsetlab_begin()
139 static void wsetlab_end(struct generator * g) { in wsetlab_end() argument
141 w(g, "~-~M}~N"); in wsetlab_end()
144 static void wgotol(struct generator * g, int n) { in wgotol() argument
146 write_margin(g); in wgotol()
147 write_string(g, "break lab"); in wgotol()
148 write_int(g, n); in wgotol()
149 write_string(g, ";"); in wgotol()
150 write_newline(g); in wgotol()
153 static void write_failure(struct generator * g) { in write_failure() argument
155 if (str_len(g->failure_str) != 0) { in write_failure()
156 write_margin(g); in write_failure()
157 write_str(g, g->failure_str); in write_failure()
158 write_newline(g); in write_failure()
160 write_margin(g); in write_failure()
161 switch (g->failure_label) { in write_failure()
163 write_string(g, "return false;"); in write_failure()
164 g->unreachable = true; in write_failure()
167 write_string(g, "break lab"); in write_failure()
168 write_int(g, g->failure_label); in write_failure()
169 write_string(g, ";"); in write_failure()
170 g->unreachable = true; in write_failure()
172 write_newline(g); in write_failure()
175 static void write_failure_if(struct generator * g, char * s, struct node * p) { in write_failure_if() argument
177 writef(g, "~Mif (", p); in write_failure_if()
178 writef(g, s, p); in write_failure_if()
179 writef(g, ")~N", p); in write_failure_if()
180 write_block_start(g); in write_failure_if()
181 write_failure(g); in write_failure_if()
182 write_block_end(g); in write_failure_if()
183 g->unreachable = false; in write_failure_if()
187 static void write_check_limit(struct generator * g, struct node * p) { in write_check_limit() argument
190 write_failure_if(g, "base.cursor >= base.limit", p); in write_check_limit()
192 write_failure_if(g, "base.cursor <= base.limit_backward", p); in write_check_limit()
197 static void writef(struct generator * g, const char * input, struct node * p) { in writef() argument
204 write_char(g, ch); in writef()
208 default: write_char(g, input[i - 1]); continue; in writef()
209 case 'C': write_comment(g, p); continue; in writef()
210 case 'f': write_block_start(g); in writef()
211 write_failure(g); in writef()
212 g->unreachable = false; in writef()
213 write_block_end(g); in writef()
215 case 'M': write_margin(g); continue; in writef()
216 case 'N': write_newline(g); continue; in writef()
217 case '{': write_block_start(g); continue; in writef()
218 case '}': write_block_end(g); continue; in writef()
219 case 'S': write_string(g, g->S[input[i++] - '0']); continue; in writef()
220 case 'B': write_b(g, g->B[input[i++] - '0']); continue; in writef()
221 case 'I': write_int(g, g->I[input[i++] - '0']); continue; in writef()
222 case 'V': write_varref(g, g->V[input[i++] - '0']); continue; in writef()
223 case 'W': write_varname(g, g->V[input[i++] - '0']); continue; in writef()
224 case 'L': write_literal_string(g, g->L[input[i++] - '0']); continue; in writef()
225 case '+': g->margin++; continue; in writef()
226 case '-': g->margin--; continue; in writef()
227 case 'n': write_string(g, g->options->name); continue; in writef()
228 case 'P': write_string(g, g->options->parent_class_name); continue; in writef()
233 static void w(struct generator * g, const char * s) { in w() argument
234 writef(g, s, 0); in w()
237 static void generate_AE(struct generator * g, struct node * p) { in generate_AE() argument
241 write_varref(g, p->name); break; in generate_AE()
243 write_int(g, p->number); break; in generate_AE()
245 write_string(g, "(-1>>>1)"); break; in generate_AE()
247 write_string(g, "(~(-1>>>1))"); break; in generate_AE()
249 write_char(g, '-'); generate_AE(g, p->right); break; in generate_AE()
257 write_char(g, '('); generate_AE(g, p->left); in generate_AE()
258 write_string(g, s); generate_AE(g, p->right); write_char(g, ')'); break; in generate_AE()
263 write_string(g, "Math.trunc("); in generate_AE()
264 generate_AE(g, p->left); in generate_AE()
265 write_string(g, " / "); in generate_AE()
266 generate_AE(g, p->right); in generate_AE()
267 write_char(g, ')'); in generate_AE()
270 w(g, "base.cursor"); break; in generate_AE()
272 w(g, p->mode == m_forward ? "base.limit" : "base.limit_backward"); break; in generate_AE()
275 g->V[0] = p->name; in generate_AE()
276 w(g, "~V0.length"); in generate_AE()
280 w(g, "base.current.length"); in generate_AE()
285 static void generate_bra(struct generator * g, struct node * p) { in generate_bra() argument
287 write_comment(g, p); in generate_bra()
290 generate(g, p); in generate_bra()
295 static void generate_and(struct generator * g, struct node * p) { in generate_and() argument
297 struct str * savevar = vars_newname(g); in generate_and()
298 int keep_c = K_needed(g, p->left); in generate_and()
300 write_comment(g, p); in generate_and()
302 if (keep_c) write_savecursor(g, p, savevar); in generate_and()
306 generate(g, p); in generate_and()
307 if (g->unreachable) break; in generate_and()
308 if (keep_c && p->right != 0) write_restorecursor(g, p, savevar); in generate_and()
314 static void generate_or(struct generator * g, struct node * p) { in generate_or() argument
316 struct str * savevar = vars_newname(g); in generate_or()
317 int keep_c = K_needed(g, p->left); in generate_or()
319 int a0 = g->failure_label; in generate_or()
320 struct str * a1 = str_copy(g->failure_str); in generate_or()
322 int out_lab = new_label(g); in generate_or()
325 write_comment(g, p); in generate_or()
326 wsetlab_begin(g, out_lab); in generate_or()
328 if (keep_c) write_savecursor(g, p, savevar); in generate_or()
331 str_clear(g->failure_str); in generate_or()
340 g->failure_label = new_label(g); in generate_or()
341 wsetlab_begin(g, g->failure_label); in generate_or()
342 generate(g, p); in generate_or()
343 if (!g->unreachable) { in generate_or()
344 wgotol(g, out_lab); in generate_or()
347 wsetlab_end(g); in generate_or()
348 g->unreachable = false; in generate_or()
349 if (keep_c) write_restorecursor(g, p, savevar); in generate_or()
353 g->failure_label = a0; in generate_or()
354 str_delete(g->failure_str); in generate_or()
355 g->failure_str = a1; in generate_or()
357 generate(g, p); in generate_or()
358 wsetlab_end(g); in generate_or()
360 g->unreachable = false; in generate_or()
365 static void generate_backwards(struct generator * g, struct node * p) { in generate_backwards() argument
367 write_comment(g, p); in generate_backwards()
368 writef(g, "~Mbase.limit_backward = base.cursor; base.cursor = base.limit;~N", p); in generate_backwards()
369 generate(g, p->left); in generate_backwards()
370 w(g, "~Mbase.cursor = base.limit_backward;~N"); in generate_backwards()
374 static void generate_not(struct generator * g, struct node * p) { in generate_not() argument
376 struct str * savevar = vars_newname(g); in generate_not()
377 int keep_c = K_needed(g, p->left); in generate_not()
379 int a0 = g->failure_label; in generate_not()
380 struct str * a1 = str_copy(g->failure_str); in generate_not()
382 write_comment(g, p); in generate_not()
384 write_block_start(g); in generate_not()
385 write_savecursor(g, p, savevar); in generate_not()
388 g->failure_label = new_label(g); in generate_not()
389 str_clear(g->failure_str); in generate_not()
391 wsetlab_begin(g, g->failure_label); in generate_not()
393 generate(g, p->left); in generate_not()
395 g->failure_label = a0; in generate_not()
396 str_delete(g->failure_str); in generate_not()
397 g->failure_str = a1; in generate_not()
399 if (!g->unreachable) write_failure(g); in generate_not()
401 wsetlab_end(g); in generate_not()
402 g->unreachable = false; in generate_not()
404 if (keep_c) write_restorecursor(g, p, savevar); in generate_not()
405 if (keep_c) write_block_end(g); in generate_not()
410 static void generate_try(struct generator * g, struct node * p) { in generate_try() argument
412 struct str * savevar = vars_newname(g); in generate_try()
413 int keep_c = K_needed(g, p->left); in generate_try()
415 write_comment(g, p); in generate_try()
416 if (keep_c) write_savecursor(g, p, savevar); in generate_try()
418 g->failure_label = new_label(g); in generate_try()
419 str_clear(g->failure_str); in generate_try()
420 if (keep_c) restore_string(p, g->failure_str, savevar); in generate_try()
422 wsetlab_begin(g, g->failure_label); in generate_try()
423 generate(g, p->left); in generate_try()
424 wsetlab_end(g); in generate_try()
425 g->unreachable = false; in generate_try()
430 static void generate_set(struct generator * g, struct node * p) { in generate_set() argument
432 write_comment(g, p); in generate_set()
433 g->V[0] = p->name; in generate_set()
434 writef(g, "~M~V0 = true;~N", p); in generate_set()
437 static void generate_unset(struct generator * g, struct node * p) { in generate_unset() argument
439 write_comment(g, p); in generate_unset()
440 g->V[0] = p->name; in generate_unset()
441 writef(g, "~M~V0 = false;~N", p); in generate_unset()
444 static void generate_fail(struct generator * g, struct node * p) { in generate_fail() argument
446 write_comment(g, p); in generate_fail()
447 generate(g, p->left); in generate_fail()
448 if (!g->unreachable) write_failure(g); in generate_fail()
453 static void generate_test(struct generator * g, struct node * p) { in generate_test() argument
455 struct str * savevar = vars_newname(g); in generate_test()
456 int keep_c = K_needed(g, p->left); in generate_test()
458 write_comment(g, p); in generate_test()
461 write_savecursor(g, p, savevar); in generate_test()
464 generate(g, p->left); in generate_test()
466 if (!g->unreachable) { in generate_test()
468 write_restorecursor(g, p, savevar); in generate_test()
474 static void generate_do(struct generator * g, struct node * p) { in generate_do() argument
476 struct str * savevar = vars_newname(g); in generate_do()
477 int keep_c = K_needed(g, p->left); in generate_do()
478 write_comment(g, p); in generate_do()
479 if (keep_c) write_savecursor(g, p, savevar); in generate_do()
483 write_comment(g, p->left); in generate_do()
484 g->V[0] = p->left->name; in generate_do()
485 w(g, "~M~V0();~N"); in generate_do()
487 g->failure_label = new_label(g); in generate_do()
488 str_clear(g->failure_str); in generate_do()
490 wsetlab_begin(g, g->failure_label); in generate_do()
491 generate(g, p->left); in generate_do()
492 wsetlab_end(g); in generate_do()
493 g->unreachable = false; in generate_do()
496 if (keep_c) write_restorecursor(g, p, savevar); in generate_do()
500 static void generate_GO(struct generator * g, struct node * p, int style) { in generate_GO() argument
503 struct str * savevar = vars_newname(g); in generate_GO()
504 int keep_c = style == 1 || repeat_restore(g, p->left); in generate_GO()
506 int a0 = g->failure_label; in generate_GO()
507 struct str * a1 = str_copy(g->failure_str); in generate_GO()
509 int golab = new_label(g); in generate_GO()
510 g->I[0] = golab; in generate_GO()
511 write_comment(g, p); in generate_GO()
512 w(g, "~Mgolab~I0: while(true)~N"); in generate_GO()
513 w(g, "~{"); in generate_GO()
515 if (keep_c) write_savecursor(g, p, savevar); in generate_GO()
517 g->failure_label = new_label(g); in generate_GO()
518 str_clear(g->failure_str); in generate_GO()
519 wsetlab_begin(g, g->failure_label); in generate_GO()
520 generate(g, p->left); in generate_GO()
522 if (g->unreachable) { in generate_GO()
528 if (style == 1) write_restorecursor(g, p, savevar); in generate_GO()
529 g->I[0] = golab; in generate_GO()
530 w(g, "~Mbreak golab~I0;~N"); in generate_GO()
532 g->unreachable = false; in generate_GO()
533 wsetlab_end(g); in generate_GO()
534 if (keep_c) write_restorecursor(g, p, savevar); in generate_GO()
536 g->failure_label = a0; in generate_GO()
537 str_delete(g->failure_str); in generate_GO()
538 g->failure_str = a1; in generate_GO()
540 write_check_limit(g, p); in generate_GO()
541 write_inc_cursor(g, p); in generate_GO()
542 write_block_end(g); in generate_GO()
544 g->unreachable = end_unreachable; in generate_GO()
547 static void generate_loop(struct generator * g, struct node * p) { in generate_loop() argument
549 struct str * loopvar = vars_newname(g); in generate_loop()
550 write_comment(g, p); in generate_loop()
551 g->B[0] = str_data(loopvar); in generate_loop()
552 w(g, "~Mfor (var /** number */ ~B0 = "); in generate_loop()
553 generate_AE(g, p->AE); in generate_loop()
554 g->B[0] = str_data(loopvar); in generate_loop()
555 writef(g, "; ~B0 > 0; ~B0--)~N", p); in generate_loop()
556 writef(g, "~{", p); in generate_loop()
558 generate(g, p->left); in generate_loop()
560 w(g, "~}"); in generate_loop()
562 g->unreachable = false; in generate_loop()
565 static void generate_repeat_or_atleast(struct generator * g, struct node * p, struct str * loopvar)… in generate_repeat_or_atleast() argument
567 struct str * savevar = vars_newname(g); in generate_repeat_or_atleast()
568 int keep_c = repeat_restore(g, p->left); in generate_repeat_or_atleast()
569 writef(g, "~Mwhile(true)~N~{", p); in generate_repeat_or_atleast()
571 if (keep_c) write_savecursor(g, p, savevar); in generate_repeat_or_atleast()
573 g->failure_label = new_label(g); in generate_repeat_or_atleast()
574 str_clear(g->failure_str); in generate_repeat_or_atleast()
575 wsetlab_begin(g, g->failure_label); in generate_repeat_or_atleast()
576 generate(g, p->left); in generate_repeat_or_atleast()
578 if (!g->unreachable) { in generate_repeat_or_atleast()
580 g->B[0] = str_data(loopvar); in generate_repeat_or_atleast()
581 w(g, "~M~B0--;~N"); in generate_repeat_or_atleast()
584 w(g, "~Mcontinue;~N"); in generate_repeat_or_atleast()
587 wsetlab_end(g); in generate_repeat_or_atleast()
588 g->unreachable = false; in generate_repeat_or_atleast()
590 if (keep_c) write_restorecursor(g, p, savevar); in generate_repeat_or_atleast()
592 w(g, "~Mbreak;~N~}"); in generate_repeat_or_atleast()
596 static void generate_repeat(struct generator * g, struct node * p) { in generate_repeat() argument
597 write_comment(g, p); in generate_repeat()
598 generate_repeat_or_atleast(g, p, NULL); in generate_repeat()
601 static void generate_atleast(struct generator * g, struct node * p) { in generate_atleast() argument
603 struct str * loopvar = vars_newname(g); in generate_atleast()
604 write_comment(g, p); in generate_atleast()
605 w(g, "~{"); in generate_atleast()
606 g->B[0] = str_data(loopvar); in generate_atleast()
607 w(g, "~Mvar ~B0 = "); in generate_atleast()
608 generate_AE(g, p->AE); in generate_atleast()
609 w(g, ";~N"); in generate_atleast()
611 int a0 = g->failure_label; in generate_atleast()
612 struct str * a1 = str_copy(g->failure_str); in generate_atleast()
614 generate_repeat_or_atleast(g, p, loopvar); in generate_atleast()
616 g->failure_label = a0; in generate_atleast()
617 str_delete(g->failure_str); in generate_atleast()
618 g->failure_str = a1; in generate_atleast()
620 g->B[0] = str_data(loopvar); in generate_atleast()
621 write_failure_if(g, "~B0 > 0", p); in generate_atleast()
622 w(g, "~}"); in generate_atleast()
626 static void generate_setmark(struct generator * g, struct node * p) { in generate_setmark() argument
628 write_comment(g, p); in generate_setmark()
629 g->V[0] = p->name; in generate_setmark()
630 writef(g, "~M~V0 = base.cursor;~N", p); in generate_setmark()
633 static void generate_tomark(struct generator * g, struct node * p) { in generate_tomark() argument
635 write_comment(g, p); in generate_tomark()
636 g->S[0] = p->mode == m_forward ? ">" : "<"; in generate_tomark()
638 w(g, "~Mif (base.cursor ~S0 "); generate_AE(g, p->AE); w(g, ")~N"); in generate_tomark()
639 write_block_start(g); in generate_tomark()
640 write_failure(g); in generate_tomark()
641 write_block_end(g); in generate_tomark()
642 g->unreachable = false; in generate_tomark()
643 w(g, "~Mbase.cursor = "); generate_AE(g, p->AE); writef(g, ";~N", p); in generate_tomark()
646 static void generate_atmark(struct generator * g, struct node * p) { in generate_atmark() argument
648 write_comment(g, p); in generate_atmark()
649 w(g, "~Mif (base.cursor != "); generate_AE(g, p->AE); writef(g, ")~N", p); in generate_atmark()
650 write_block_start(g); in generate_atmark()
651 write_failure(g); in generate_atmark()
652 write_block_end(g); in generate_atmark()
653 g->unreachable = false; in generate_atmark()
656 static void generate_hop(struct generator * g, struct node * p) { in generate_hop() argument
657 int c_count = ++g->keep_count; in generate_hop()
658 write_comment(g, p); in generate_hop()
659 g->S[0] = p->mode == m_forward ? "+" : "-"; in generate_hop()
661 g->I[0] = c_count; in generate_hop()
662 w(g, "~{~Mvar /** number */ c~I0 = base.cursor ~S0 "); in generate_hop()
663 generate_AE(g, p->AE); in generate_hop()
664 w(g, ";~N"); in generate_hop()
666 g->I[0] = c_count; in generate_hop()
667 g->S[1] = p->mode == m_forward ? "> base.limit" : "< base.limit_backward"; in generate_hop()
668 g->S[2] = p->mode == m_forward ? "<" : ">"; in generate_hop()
674 write_failure_if(g, "c~I0 ~S1", p); in generate_hop()
676 write_failure_if(g, "c~I0 ~S1 || c~I0 ~S2 base.cursor", p); in generate_hop()
678 writef(g, "~Mbase.cursor = c~I0;~N", p); in generate_hop()
679 writef(g, "~}", p); in generate_hop()
682 static void generate_delete(struct generator * g, struct node * p) { in generate_delete() argument
684 write_comment(g, p); in generate_delete()
685 writef(g, "~Mif (!base.slice_del())~N" in generate_delete()
692 static void generate_next(struct generator * g, struct node * p) { in generate_next() argument
694 write_comment(g, p); in generate_next()
695 write_check_limit(g, p); in generate_next()
696 write_inc_cursor(g, p); in generate_next()
699 static void generate_tolimit(struct generator * g, struct node * p) { in generate_tolimit() argument
701 write_comment(g, p); in generate_tolimit()
703 writef(g, "~Mbase.cursor = base.limit;~N", p); in generate_tolimit()
705 writef(g, "~Mbase.cursor = base.limit_backward;~N", p); in generate_tolimit()
709 static void generate_atlimit(struct generator * g, struct node * p) { in generate_atlimit() argument
711 write_comment(g, p); in generate_atlimit()
713 write_failure_if(g, "base.cursor < base.limit", p); in generate_atlimit()
715 write_failure_if(g, "base.cursor > base.limit_backward", p); in generate_atlimit()
719 static void generate_leftslice(struct generator * g, struct node * p) { in generate_leftslice() argument
721 write_comment(g, p); in generate_leftslice()
723 writef(g, "~Mbase.bra = base.cursor;~N", p); in generate_leftslice()
725 writef(g, "~Mbase.ket = base.cursor;~N", p); in generate_leftslice()
729 static void generate_rightslice(struct generator * g, struct node * p) { in generate_rightslice() argument
731 write_comment(g, p); in generate_rightslice()
733 writef(g, "~Mbase.ket = base.cursor;~N", p); in generate_rightslice()
735 writef(g, "~Mbase.bra = base.cursor;~N", p); in generate_rightslice()
739 static void generate_assignto(struct generator * g, struct node * p) { in generate_assignto() argument
741 write_comment(g, p); in generate_assignto()
742 g->V[0] = p->name; in generate_assignto()
743 writef(g, "~M~V0 = base.assign_to();~N", p); in generate_assignto()
746 static void generate_sliceto(struct generator * g, struct node * p) { in generate_sliceto() argument
748 write_comment(g, p); in generate_sliceto()
749 g->V[0] = p->name; in generate_sliceto()
750 writef(g, "~M~V0 = base.slice_to();~N" in generate_sliceto()
757 static void generate_address(struct generator * g, struct node * p) { in generate_address() argument
761 write_literal_string(g, b); in generate_address()
763 write_varref(g, p->name); in generate_address()
767 static void generate_insert(struct generator * g, struct node * p, int style) { in generate_insert() argument
770 write_comment(g, p); in generate_insert()
773 c_count = ++g->keep_count; in generate_insert()
774 g->I[0] = c_count; in generate_insert()
775 w(g, "~{~Mvar /** number */ c~I0 = base.cursor;~N"); in generate_insert()
777 writef(g, "~Mbase.insert(base.cursor, base.cursor, ", p); in generate_insert()
778 generate_address(g, p); in generate_insert()
779 writef(g, ");~N", p); in generate_insert()
781 g->I[0] = c_count; in generate_insert()
782 w(g, "~Mbase.cursor = c~I0;~N~}"); in generate_insert()
786 static void generate_assignfrom(struct generator * g, struct node * p) { in generate_assignfrom() argument
790 write_comment(g, p); in generate_assignfrom()
792 c_count = ++g->keep_count; in generate_assignfrom()
793 g->I[0] = c_count; in generate_assignfrom()
794 w(g, "~{~Mvar /** number */ c~I0 = base.cursor;~N"); in generate_assignfrom()
797 writef(g, "~Mbase.insert(base.cursor, base.limit, ", p); in generate_assignfrom()
799 writef(g, "~Mbase.insert(base.limit_backward, base.cursor, ", p); in generate_assignfrom()
801 generate_address(g, p); in generate_assignfrom()
802 writef(g, ");~N", p); in generate_assignfrom()
804 g->I[0] = c_count; in generate_assignfrom()
805 w(g, "~Mbase.cursor = c~I0;~N~}"); in generate_assignfrom()
810 static void generate_slicefrom(struct generator * g, struct node * p) { in generate_slicefrom() argument
812 write_comment(g, p); in generate_slicefrom()
813 w(g, "~Mif (!base.slice_from("); in generate_slicefrom()
814 generate_address(g, p); in generate_slicefrom()
815 writef(g, "))~N" in generate_slicefrom()
821 static void generate_setlimit(struct generator * g, struct node * p) { in generate_setlimit() argument
822 struct str * savevar = vars_newname(g); in generate_setlimit()
823 struct str * varname = vars_newname(g); in generate_setlimit()
824 write_comment(g, p); in generate_setlimit()
835 g->S[0] = q->mode == m_forward ? ">" : "<"; in generate_setlimit()
836 w(g, "~Mif (base.cursor ~S0 "); generate_AE(g, q->AE); w(g, ")~N"); in generate_setlimit()
837 write_block_start(g); in generate_setlimit()
838 write_failure(g); in generate_setlimit()
839 write_block_end(g); in generate_setlimit()
840 g->unreachable = false; in generate_setlimit()
842 g->B[0] = str_data(varname); in generate_setlimit()
843 w(g, "~Mvar /** number */ ~B0 = "); in generate_setlimit()
845 w(g, "base.limit - base.cursor;~N"); in generate_setlimit()
846 w(g, "~Mbase.limit = "); in generate_setlimit()
848 w(g, "base.limit_backward;~N"); in generate_setlimit()
849 w(g, "~Mbase.limit_backward = "); in generate_setlimit()
851 generate_AE(g, q->AE); writef(g, ";~N", q); in generate_setlimit()
854 str_assign(g->failure_str, "base.limit += "); in generate_setlimit()
855 str_append(g->failure_str, varname); in generate_setlimit()
856 str_append_ch(g->failure_str, ';'); in generate_setlimit()
858 str_assign(g->failure_str, "base.limit_backward = "); in generate_setlimit()
859 str_append(g->failure_str, varname); in generate_setlimit()
860 str_append_ch(g->failure_str, ';'); in generate_setlimit()
863 write_savecursor(g, p, savevar); in generate_setlimit()
864 generate(g, p->left); in generate_setlimit()
866 if (!g->unreachable) { in generate_setlimit()
867 g->B[0] = str_data(varname); in generate_setlimit()
868 w(g, "~Mvar /** number */ ~B0 = "); in generate_setlimit()
870 w(g, "base.limit - base.cursor;~N"); in generate_setlimit()
871 w(g, "~Mbase.limit = base.cursor;~N"); in generate_setlimit()
873 w(g, "base.limit_backward;~N"); in generate_setlimit()
874 w(g, "~Mbase.limit_backward = base.cursor;~N"); in generate_setlimit()
876 write_restorecursor(g, p, savevar); in generate_setlimit()
879 str_assign(g->failure_str, "base.limit += "); in generate_setlimit()
880 str_append(g->failure_str, varname); in generate_setlimit()
881 str_append_ch(g->failure_str, ';'); in generate_setlimit()
883 str_assign(g->failure_str, "base.limit_backward = "); in generate_setlimit()
884 str_append(g->failure_str, varname); in generate_setlimit()
885 str_append_ch(g->failure_str, ';'); in generate_setlimit()
890 if (!g->unreachable) { in generate_setlimit()
891 generate(g, p->aux); in generate_setlimit()
893 if (!g->unreachable) { in generate_setlimit()
894 write_margin(g); in generate_setlimit()
895 write_str(g, g->failure_str); in generate_setlimit()
896 write_newline(g); in generate_setlimit()
905 static void generate_dollar(struct generator * g, struct node * p) { in generate_dollar() argument
907 struct str * savevar = vars_newname(g); in generate_dollar()
908 g->B[0] = str_data(savevar); in generate_dollar()
909 writef(g, "~{~C~N" in generate_dollar()
911 writef(g, "~M~B0.copy_from(base);~N", p); in generate_dollar()
913 ++g->copy_from_count; in generate_dollar()
914 str_assign(g->failure_str, "base.copy_from("); in generate_dollar()
915 str_append(g->failure_str, savevar); in generate_dollar()
916 str_append_string(g->failure_str, ");"); in generate_dollar()
917 g->V[0] = p->name; in generate_dollar()
918 writef(g, "~Mbase.current = ~V0;~N" in generate_dollar()
922 generate(g, p->left); in generate_dollar()
923 if (!g->unreachable) { in generate_dollar()
924 g->V[0] = p->name; in generate_dollar()
925 writef(g, "~M~V0 = base.current;~N", p); in generate_dollar()
926 write_margin(g); in generate_dollar()
927 write_str(g, g->failure_str); in generate_dollar()
928 write_newline(g); in generate_dollar()
930 w(g, "~}"); in generate_dollar()
934 static void generate_integer_assign(struct generator * g, struct node * p, char * s) { in generate_integer_assign() argument
936 g->V[0] = p->name; in generate_integer_assign()
937 g->S[0] = s; in generate_integer_assign()
938 w(g, "~M~V0 ~S0 "); generate_AE(g, p->AE); w(g, ";~N"); in generate_integer_assign()
941 static void generate_integer_test(struct generator * g, struct node * p, char * s) { in generate_integer_test() argument
943 w(g, "~Mif (!("); in generate_integer_test()
944 generate_AE(g, p->left); in generate_integer_test()
945 write_char(g, ' '); in generate_integer_test()
946 write_string(g, s); in generate_integer_test()
947 write_char(g, ' '); in generate_integer_test()
948 generate_AE(g, p->AE); in generate_integer_test()
949 w(g, "))~N"); in generate_integer_test()
950 write_block_start(g); in generate_integer_test()
951 write_failure(g); in generate_integer_test()
952 write_block_end(g); in generate_integer_test()
953 g->unreachable = false; in generate_integer_test()
956 static void generate_call(struct generator * g, struct node * p) { in generate_call() argument
958 write_comment(g, p); in generate_call()
959 g->V[0] = p->name; in generate_call()
960 write_failure_if(g, "!~V0()", p); in generate_call()
963 static void generate_grouping(struct generator * g, struct node * p, int complement) { in generate_grouping() argument
966 g->S[0] = p->mode == m_forward ? "" : "_b"; in generate_grouping()
967 g->S[1] = complement ? "out" : "in"; in generate_grouping()
968 g->V[0] = p->name; in generate_grouping()
969 g->I[0] = q->smallest_ch; in generate_grouping()
970 g->I[1] = q->largest_ch; in generate_grouping()
971 write_failure_if(g, "!(base.~S1_grouping~S0(~V0, ~I0, ~I1))", p); in generate_grouping()
974 static void generate_namedstring(struct generator * g, struct node * p) { in generate_namedstring() argument
976 write_comment(g, p); in generate_namedstring()
977 g->S[0] = p->mode == m_forward ? "" : "_b"; in generate_namedstring()
978 g->V[0] = p->name; in generate_namedstring()
979 write_failure_if(g, "!(base.eq_s~S0(~V0))", p); in generate_namedstring()
982 static void generate_literalstring(struct generator * g, struct node * p) { in generate_literalstring() argument
984 write_comment(g, p); in generate_literalstring()
985 g->S[0] = p->mode == m_forward ? "" : "_b"; in generate_literalstring()
986 g->L[0] = b; in generate_literalstring()
987 write_failure_if(g, "!(base.eq_s~S0(~L0))", p); in generate_literalstring()
990 static void generate_define(struct generator * g, struct node * p) { in generate_define() argument
993 struct str * saved_output = g->outbuf; in generate_define()
994 struct str * saved_declarations = g->declarations; in generate_define()
996 g->V[0] = q; in generate_define()
998 w(g, "~N~M/** @return {boolean} */~N" in generate_define()
1001 w(g, "~N~Mthis.~W0 = /** @return {boolean} */ function() {~+~N"); in generate_define()
1004 g->outbuf = str_new(); in generate_define()
1005 g->declarations = str_new(); in generate_define()
1007 g->next_label = 0; in generate_define()
1008 g->var_number = 0; in generate_define()
1011 w(g, "~Mvar /** number */ among_var;~N"); in generate_define()
1013 str_clear(g->failure_str); in generate_define()
1014 g->failure_label = x_return; in generate_define()
1015 g->unreachable = false; in generate_define()
1016 g->keep_count = 0; in generate_define()
1017 generate(g, p->left); in generate_define()
1018 if (!g->unreachable) w(g, "~Mreturn true;~N"); in generate_define()
1019 w(g, "~-~M};~N"); in generate_define()
1021 str_append(saved_output, g->declarations); in generate_define()
1022 str_append(saved_output, g->outbuf); in generate_define()
1023 str_delete(g->declarations); in generate_define()
1024 str_delete(g->outbuf); in generate_define()
1025 g->declarations = saved_declarations; in generate_define()
1026 g->outbuf = saved_output; in generate_define()
1029 static void generate_substring(struct generator * g, struct node * p) { in generate_substring() argument
1033 write_comment(g, p); in generate_substring()
1035 g->S[0] = p->mode == m_forward ? "" : "_b"; in generate_substring()
1036 g->I[0] = x->number; in generate_substring()
1039 write_failure_if(g, "base.find_among~S0(a_~I0) == 0", p); in generate_substring()
1041 writef(g, "~Mamong_var = base.find_among~S0(a_~I0);~N", p); in generate_substring()
1042 write_failure_if(g, "among_var == 0", p); in generate_substring()
1046 static void generate_among(struct generator * g, struct node * p) { in generate_among() argument
1050 if (x->substring == 0) generate_substring(g, p); in generate_among()
1052 if (x->starter != 0) generate(g, x->starter); in generate_among()
1056 generate(g, x->commands[0]); in generate_among()
1059 w(g, "~Mswitch (among_var) {~N~+"); in generate_among()
1061 g->I[0] = i; in generate_among()
1062 w(g, "~Mcase ~I0:~N~+"); in generate_among()
1063 generate(g, x->commands[i - 1]); in generate_among()
1064 if (!g->unreachable) w(g, "~Mbreak;~N"); in generate_among()
1065 w(g, "~-"); in generate_among()
1066 g->unreachable = false; in generate_among()
1068 write_block_end(g); in generate_among()
1072 static void generate_booltest(struct generator * g, struct node * p) { in generate_booltest() argument
1074 write_comment(g, p); in generate_booltest()
1075 g->V[0] = p->name; in generate_booltest()
1076 write_failure_if(g, "!~V0", p); in generate_booltest()
1079 static void generate_false(struct generator * g, struct node * p) { in generate_false() argument
1081 write_comment(g, p); in generate_false()
1082 write_failure(g); in generate_false()
1085 static void generate_debug(struct generator * g, struct node * p) { in generate_debug() argument
1087 write_comment(g, p); in generate_debug()
1088 g->I[0] = g->debug_count++; in generate_debug()
1089 g->I[1] = p->line_number; in generate_debug()
1090 writef(g, "~Mbase.debug(~I0, ~I1);~N", p); in generate_debug()
1093 static void generate(struct generator * g, struct node * p) { in generate() argument
1098 if (g->unreachable) return; in generate()
1100 a0 = g->failure_label; in generate()
1101 a1 = str_copy(g->failure_str); in generate()
1104 case c_define: generate_define(g, p); break; in generate()
1105 case c_bra: generate_bra(g, p); break; in generate()
1106 case c_and: generate_and(g, p); break; in generate()
1107 case c_or: generate_or(g, p); break; in generate()
1108 case c_backwards: generate_backwards(g, p); break; in generate()
1109 case c_not: generate_not(g, p); break; in generate()
1110 case c_set: generate_set(g, p); break; in generate()
1111 case c_unset: generate_unset(g, p); break; in generate()
1112 case c_try: generate_try(g, p); break; in generate()
1113 case c_fail: generate_fail(g, p); break; in generate()
1115 case c_test: generate_test(g, p); break; in generate()
1116 case c_do: generate_do(g, p); break; in generate()
1117 case c_goto: generate_GO(g, p, 1); break; in generate()
1118 case c_gopast: generate_GO(g, p, 0); break; in generate()
1119 case c_repeat: generate_repeat(g, p); break; in generate()
1120 case c_loop: generate_loop(g, p); break; in generate()
1121 case c_atleast: generate_atleast(g, p); break; in generate()
1122 case c_setmark: generate_setmark(g, p); break; in generate()
1123 case c_tomark: generate_tomark(g, p); break; in generate()
1124 case c_atmark: generate_atmark(g, p); break; in generate()
1125 case c_hop: generate_hop(g, p); break; in generate()
1126 case c_delete: generate_delete(g, p); break; in generate()
1127 case c_next: generate_next(g, p); break; in generate()
1128 case c_tolimit: generate_tolimit(g, p); break; in generate()
1129 case c_atlimit: generate_atlimit(g, p); break; in generate()
1130 case c_leftslice: generate_leftslice(g, p); break; in generate()
1131 case c_rightslice: generate_rightslice(g, p); break; in generate()
1132 case c_assignto: generate_assignto(g, p); break; in generate()
1133 case c_sliceto: generate_sliceto(g, p); break; in generate()
1134 case c_assign: generate_assignfrom(g, p); break; in generate()
1136 case c_attach: generate_insert(g, p, p->type); break; in generate()
1137 case c_slicefrom: generate_slicefrom(g, p); break; in generate()
1138 case c_setlimit: generate_setlimit(g, p); break; in generate()
1139 case c_dollar: generate_dollar(g, p); break; in generate()
1140 case c_mathassign: generate_integer_assign(g, p, "="); break; in generate()
1141 case c_plusassign: generate_integer_assign(g, p, "+="); break; in generate()
1142 case c_minusassign: generate_integer_assign(g, p, "-="); break; in generate()
1143 case c_multiplyassign:generate_integer_assign(g, p, "*="); break; in generate()
1148 g->V[0] = p->name; in generate()
1149 w(g, "~M~V0 = Math.trunc(~V0 / "); in generate()
1150 generate_AE(g, p->AE); in generate()
1151 w(g, ");~N"); in generate()
1153 case c_eq: generate_integer_test(g, p, "=="); break; in generate()
1154 case c_ne: generate_integer_test(g, p, "!="); break; in generate()
1155 case c_gr: generate_integer_test(g, p, ">"); break; in generate()
1156 case c_ge: generate_integer_test(g, p, ">="); break; in generate()
1157 case c_ls: generate_integer_test(g, p, "<"); break; in generate()
1158 case c_le: generate_integer_test(g, p, "<="); break; in generate()
1159 case c_call: generate_call(g, p); break; in generate()
1160 case c_grouping: generate_grouping(g, p, false); break; in generate()
1161 case c_non: generate_grouping(g, p, true); break; in generate()
1162 case c_name: generate_namedstring(g, p); break; in generate()
1163 case c_literalstring: generate_literalstring(g, p); break; in generate()
1164 case c_among: generate_among(g, p); break; in generate()
1165 case c_substring: generate_substring(g, p); break; in generate()
1166 case c_booltest: generate_booltest(g, p); break; in generate()
1167 case c_false: generate_false(g, p); break; in generate()
1169 case c_debug: generate_debug(g, p); break; in generate()
1174 g->failure_label = a0; in generate()
1175 str_delete(g->failure_str); in generate()
1176 g->failure_str = a1; in generate()
1179 static void generate_class_begin(struct generator * g) { in generate_class_begin() argument
1181 w(g, "/**@constructor*/~N"); in generate_class_begin()
1182 w(g, "~n = function() {~+~N" in generate_class_begin()
1186 static void generate_class_end(struct generator * g) { in generate_class_end() argument
1187 w(g, "~N"); in generate_class_end()
1188 w(g, "~M/**@return{string}*/~N"); in generate_class_end()
1189 w(g, "~Mthis['stemWord'] = function(/**string*/word) {~+~N"); in generate_class_end()
1190 w(g, "~Mbase.setCurrent(word);~N"); in generate_class_end()
1191 w(g, "~Mthis.stem();~N"); in generate_class_end()
1192 w(g, "~Mreturn base.getCurrent();~N"); in generate_class_end()
1193 w(g, "~-~M};~N"); in generate_class_end()
1194 w(g, "~-};~N"); in generate_class_end()
1198 static void generate_among_table(struct generator * g, struct among * x) { in generate_among_table() argument
1202 g->I[0] = x->number; in generate_among_table()
1204 w(g, "~M/** @const */ var a_~I0 = [~N~+"); in generate_among_table()
1208 g->I[0] = v->i; in generate_among_table()
1209 g->I[1] = v->result; in generate_among_table()
1210 g->L[0] = v->b; in generate_among_table()
1211 g->S[0] = i < x->literalstring_count - 1 ? "," : ""; in generate_among_table()
1213 w(g, "~M[~L0, ~I0, ~I1"); in generate_among_table()
1215 w(g, ", "); in generate_among_table()
1216 write_varname(g, v->function); in generate_among_table()
1218 w(g, "]~S0~N"); in generate_among_table()
1222 w(g, "~-~M];~N~N"); in generate_among_table()
1225 static void generate_amongs(struct generator * g) { in generate_amongs() argument
1227 for (x = g->analyser->amongs; x; x = x->next) { in generate_amongs()
1228 generate_among_table(g, x); in generate_amongs()
1234 static void generate_grouping_table(struct generator * g, struct grouping * q) { in generate_grouping_table() argument
1247 g->V[0] = q->name; in generate_grouping_table()
1249 w(g, "~M/** @const */ var /** Array<int> */ ~W0 = ["); in generate_grouping_table()
1251 write_int(g, map[i]); in generate_grouping_table()
1252 if (i < size - 1) w(g, ", "); in generate_grouping_table()
1254 w(g, "];~N~N"); in generate_grouping_table()
1258 static void generate_groupings(struct generator * g) { in generate_groupings() argument
1260 for (q = g->analyser->groupings; q; q = q->next) { in generate_groupings()
1262 generate_grouping_table(g, q); in generate_groupings()
1266 static void generate_members(struct generator * g) { in generate_members() argument
1269 for (q = g->analyser->names; q; q = q->next) { in generate_members()
1270 g->V[0] = q; in generate_members()
1273 w(g, "~Mvar /** string */ ~W0 = '';~N"); in generate_members()
1276 w(g, "~Mvar /** number */ ~W0 = 0;~N"); in generate_members()
1279 w(g, "~Mvar /** boolean */ ~W0 = false;~N"); in generate_members()
1283 w(g, "~N"); in generate_members()
1286 static void generate_methods(struct generator * g) { in generate_methods() argument
1288 struct node * p = g->analyser->program; in generate_methods()
1290 generate(g, p); in generate_methods()
1291 g->unreachable = false; in generate_methods()
1296 extern void generate_program_js(struct generator * g) { in generate_program_js() argument
1298 g->outbuf = str_new(); in generate_program_js()
1299 g->failure_str = str_new(); in generate_program_js()
1301 write_start_comment(g, "// ", NULL); in generate_program_js()
1303 generate_class_begin(g); in generate_program_js()
1305 generate_amongs(g); in generate_program_js()
1306 generate_groupings(g); in generate_program_js()
1308 generate_members(g); in generate_program_js()
1309 generate_methods(g); in generate_program_js()
1311 generate_class_end(g); in generate_program_js()
1313 output_str(g->options->output_src, g->outbuf); in generate_program_js()
1314 str_delete(g->failure_str); in generate_program_js()
1315 str_delete(g->outbuf); in generate_program_js()