mittens 0.3.3 → 0.3.5

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/ext/mittens/ext.c +68 -30
  6. data/ext/mittens/extconf.rb +2 -0
  7. data/lib/mittens/version.rb +1 -1
  8. data/vendor/snowball/.github/workflows/ci.yml +43 -3
  9. data/vendor/snowball/.github/workflows/coverage.yml +8 -5
  10. data/vendor/snowball/GNUmakefile +46 -16
  11. data/vendor/snowball/NEWS +437 -13
  12. data/vendor/snowball/README.rst +4 -4
  13. data/vendor/snowball/algorithms/earlymodernenglish.sbl +301 -0
  14. data/vendor/snowball/algorithms/french.sbl +1 -1
  15. data/vendor/snowball/algorithms/ukrainian.sbl +1251 -0
  16. data/vendor/snowball/compiler/analyser.c +460 -156
  17. data/vendor/snowball/compiler/driver.c +41 -36
  18. data/vendor/snowball/compiler/generator.c +24 -1
  19. data/vendor/snowball/compiler/generator_ada.c +46 -45
  20. data/vendor/snowball/compiler/generator_c.c +1094 -187
  21. data/vendor/snowball/compiler/generator_csharp.c +34 -11
  22. data/vendor/snowball/compiler/generator_dart.c +39 -11
  23. data/vendor/snowball/compiler/generator_go.c +6 -6
  24. data/vendor/snowball/compiler/generator_java.c +29 -8
  25. data/vendor/snowball/compiler/generator_js.c +65 -38
  26. data/vendor/snowball/compiler/generator_pascal.c +69 -26
  27. data/vendor/snowball/compiler/generator_php.c +33 -12
  28. data/vendor/snowball/compiler/generator_python.c +23 -4
  29. data/vendor/snowball/compiler/generator_rust.c +37 -13
  30. data/vendor/snowball/compiler/generator_zig.c +6 -6
  31. data/vendor/snowball/compiler/header.h +85 -14
  32. data/vendor/snowball/compiler/space.c +67 -38
  33. data/vendor/snowball/compiler/tokeniser.c +28 -16
  34. data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +2 -2
  35. data/vendor/snowball/csharp/Snowball/Stemmer.cs +1 -4
  36. data/vendor/snowball/cxx/generate_algorithms.pl +5 -4
  37. data/vendor/snowball/cxx/{utilities.cxx → snowball_runtime.cxx} +1 -1
  38. data/vendor/snowball/cxx/stemmer.h +4 -0
  39. data/vendor/snowball/cxx/stemwords.cxx +36 -6
  40. data/vendor/snowball/dart/lib/src/snowball.dart +2 -2
  41. data/vendor/snowball/dart/pubspec.yaml +1 -1
  42. data/vendor/snowball/doc/libstemmer_c_README +3 -0
  43. data/vendor/snowball/doc/libstemmer_php_README +1 -1
  44. data/vendor/snowball/doc/libstemmer_python_README +8 -6
  45. data/vendor/snowball/examples/stemwords.c +4 -14
  46. data/vendor/snowball/go/env.go +16 -4
  47. data/vendor/snowball/include/libstemmer.h +0 -3
  48. data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +4 -4
  49. data/vendor/snowball/javascript/base-stemmer.js +27 -40
  50. data/vendor/snowball/javascript/stemwords.js +34 -10
  51. data/vendor/snowball/libstemmer/libstemmer_c.in +5 -5
  52. data/vendor/snowball/libstemmer/mkmodules.pl +5 -3
  53. data/vendor/snowball/libstemmer/modules.txt +4 -2
  54. data/vendor/snowball/pascal/SnowballProgram.pas +2 -2
  55. data/vendor/snowball/php/base-stemmer.php +2 -2
  56. data/vendor/snowball/python/setup.py +5 -1
  57. data/vendor/snowball/python/snowballstemmer/basestemmer.py +1 -2
  58. data/vendor/snowball/runtime/api.c +14 -3
  59. data/vendor/snowball/runtime/api.h +13 -9
  60. data/vendor/snowball/runtime/{utilities.c → snowball_runtime.c} +115 -181
  61. data/vendor/snowball/runtime/snowball_runtime.h +35 -24
  62. data/vendor/snowball/rust/src/snowball/snowball_env.rs +1 -1
  63. data/vendor/snowball/tests/compilertest +3 -3
  64. data/vendor/snowball/tests/runtime/among.sbl +96 -2
  65. data/vendor/snowball/tests/runtime/attachinsert.sbl +4 -0
  66. data/vendor/snowball/tests/runtime/debug.out +7 -0
  67. data/vendor/snowball/tests/runtime/debug.sbl +9 -0
  68. data/vendor/snowball/tests/runtime/integertests.sbl +22 -0
  69. data/vendor/snowball/tests/runtime/marklimit.sbl +30 -0
  70. data/vendor/snowball/tests/runtime/naming.sbl +20 -0
  71. data/vendor/snowball/tests/runtime/reverse.sbl +11 -0
  72. data/vendor/snowball/tests/stemtest.c +2 -5
  73. data/vendor/snowball/tests/syntax/aeslicefrom.sbl +7 -0
  74. data/vendor/snowball/tests/syntax/canon.sbl +14 -0
  75. data/vendor/snowball/tests/syntax/canon.syntax +36 -0
  76. data/vendor/snowball/tests/syntax/inline.syntax +4 -4
  77. data/vendor/snowball/tests/syntax/localvar.sbl +38 -0
  78. data/vendor/snowball/tests/syntax/localvar.stderr +3 -0
  79. data/vendor/snowball/tests/syntax/localvar.syntax +76 -0
  80. data/vendor/snowball/tests/syntax/unused.sbl +5 -1
  81. data/vendor/snowball/tests/syntax/unused.stderr +3 -1
  82. data/vendor/snowball/zig/env.zig +24 -4
  83. metadata +14 -4
@@ -42,7 +42,7 @@ static void write_varref(struct generator * g, struct name * p) {
42
42
  write_varname(g, p);
43
43
  }
44
44
 
45
- static void write_literal_string(struct generator * g, symbol * p) {
45
+ static void write_literal_string(struct generator * g, const symbol * p) {
46
46
  write_char(g, '"');
47
47
  for (int i = 0; i < SIZE(p); i++) {
48
48
  int ch = p[i];
@@ -78,7 +78,7 @@ static void write_savecursor(struct generator * g, struct node * p,
78
78
  g->B[0] = str_data(savevar);
79
79
  g->S[1] = "";
80
80
  if (p->mode != m_forward) g->S[1] = "this.limit - ";
81
- writef(g, "~Mconst /** number */ ~B0 = ~S1this.c;~N", p);
81
+ writef(g, "~Mconst /**@type {number}*/ ~B0 = ~S1this.c;~N", p);
82
82
  }
83
83
 
84
84
  static void append_restore_string(struct node * p, struct str * out, struct str * savevar) {
@@ -208,22 +208,22 @@ static void writef(struct generator * g, const char * input, struct node * p) {
208
208
  }
209
209
  case 'F': { // Among function dispatcher.
210
210
  struct among * x = p->among;
211
- if (x->function_count == 0) {
211
+ if (x->unique_function_count == 0) {
212
212
  continue;
213
213
  }
214
214
 
215
215
  w(g, ", ");
216
216
 
217
- if (x->function_count == 1) {
217
+ if (x->unique_function_count == 1) {
218
218
  // Only one different function used in this among.
219
- struct amongvec * v = x->b;
219
+ struct amongvec * v = x->v;
220
220
  for (int j = 0; j < x->literalstring_count; j++) {
221
221
  if (v[j].function) {
222
222
  write_varref(g, v[j].function);
223
223
  goto continue_outer_loop;
224
224
  }
225
225
  }
226
- fprintf(stderr, "function_count == 1 but no among functions\n");
226
+ fprintf(stderr, "unique_function_count == 1 but no among functions\n");
227
227
  exit(1);
228
228
  continue_outer_loop:
229
229
  continue;
@@ -644,7 +644,7 @@ static void generate_loop(struct generator * g, struct node * p) {
644
644
  write_comment(g, p);
645
645
  struct str * loopvar = vars_newname(g);
646
646
  g->B[0] = str_data(loopvar);
647
- w(g, "~Mfor (let /** number */ ~B0 = ");
647
+ w(g, "~Mfor (let /**@type {number}*/ ~B0 = ");
648
648
  generate_AE(g, p->AE);
649
649
  g->B[0] = str_data(loopvar);
650
650
  writef(g, "; ~B0 > 0; ~B0--)~N", p);
@@ -747,7 +747,7 @@ static void generate_hop(struct generator * g, struct node * p) {
747
747
  write_failure_if(g, "this.c ~S0 ~I0 ~S1", p);
748
748
  writef(g, "~Mthis.c ~S0= ~I0;~N", p);
749
749
  } else {
750
- w(g, "~{~Mconst /** number */ c = this.c ~S0 ");
750
+ w(g, "~{~Mconst /**@type {number}*/ c = this.c ~S0 ");
751
751
  generate_AE(g, p->AE);
752
752
  w(g, ";~N");
753
753
  write_failure_if(g, "c ~S1 || c ~S2 this.c", p);
@@ -807,7 +807,7 @@ static void generate_insert(struct generator * g, struct node * p, int style) {
807
807
  int keep_c = style == c_attach;
808
808
  if (p->mode == m_backward) keep_c = !keep_c;
809
809
  if (keep_c) {
810
- w(g, "~{~Mconst /** number */ c = this.c;~N");
810
+ w(g, "~{~Mconst /**@type {number}*/ c = this.c;~N");
811
811
  writef(g, "~Mthis.insert(c, c, ", p);
812
812
  } else {
813
813
  writef(g, "~Mthis.insert(this.c, this.c, ", p);
@@ -821,7 +821,7 @@ static void generate_stringassign(struct generator * g, struct node * p) {
821
821
  write_comment(g, p);
822
822
  int keep_c = p->mode == m_forward; /* like 'attach' */
823
823
  if (keep_c) {
824
- w(g, "~{~Mconst /** number */ c = this.c;~N");
824
+ w(g, "~{~Mconst /**@type {number}*/ c = this.c;~N");
825
825
  if (p->mode == m_forward) {
826
826
  writef(g, "~Mthis.insert(c, this.limit, ", p);
827
827
  } else {
@@ -875,13 +875,13 @@ static void generate_setlimit(struct generator * g, struct node * p) {
875
875
 
876
876
  g->B[0] = str_data(varname);
877
877
  if (p->mode == m_forward) {
878
- w(g, "~Mlet /** number */ ~B0 = this.limit;~N");
878
+ w(g, "~Mlet /**@type {number}*/ ~B0 = this.limit;~N");
879
879
  w(g, "~Mthis.limit = ");
880
880
  generate_AE(g, q->AE);
881
881
  w(g, ";~N");
882
882
  w(g, "~M~B0 -= this.limit;~N");
883
883
  } else {
884
- w(g, "~Mconst /** number */ ~B0 = this.limit_backward;~N");
884
+ w(g, "~Mconst /**@type {number}*/ ~B0 = this.limit_backward;~N");
885
885
  w(g, "~Mthis.limit_backward = ");
886
886
  generate_AE(g, q->AE);
887
887
  w(g, ";~N");
@@ -904,7 +904,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
904
904
 
905
905
  if (!g->unreachable) {
906
906
  g->B[0] = str_data(varname);
907
- w(g, "~Mconst /** number */ ~B0 = ");
907
+ w(g, "~Mconst /**@type {number}*/ ~B0 = ");
908
908
  if (p->mode == m_forward) {
909
909
  w(g, "this.limit - this.c;~N");
910
910
  w(g, "~Mthis.limit = this.c;~N");
@@ -953,7 +953,7 @@ static void generate_dollar(struct generator * g, struct node * p) {
953
953
  struct str * savevar = vars_newname(g);
954
954
  g->B[0] = str_data(savevar);
955
955
  writef(g, "~{~N"
956
- "~Mconst /** !Object */ ~B0 = new ~P();~N", p);
956
+ "~Mconst /**@type {~P}*/ ~B0 = new ~P();~N", p);
957
957
  writef(g, "~M~B0.copy_from(this);~N", p);
958
958
 
959
959
  writef(g, "~Mthis.current = ~V;~N"
@@ -962,7 +962,7 @@ static void generate_dollar(struct generator * g, struct node * p) {
962
962
  "~Mthis.limit = this.current.length;~N", p);
963
963
  if (p->left->possible_signals == -1) {
964
964
  /* Assume failure. */
965
- w(g, "~Mlet /**boolean*/ ~B0_f = true;~N");
965
+ w(g, "~Mlet /**@type {boolean}*/ ~B0_f = true;~N");
966
966
  }
967
967
 
968
968
  wsetlab_begin(g, g->failure_label);
@@ -1024,7 +1024,10 @@ static void generate_integer_test(struct generator * g, struct node * p) {
1024
1024
  w(g, "~Mreturn ");
1025
1025
  p->right = NULL;
1026
1026
  } else {
1027
- w(g, "~Mif (");
1027
+ // Generate a typescript annotation cast to boolean to suppress
1028
+ // deno check errors for constant if expressions, since a constant
1029
+ // integer test is valid Snowball code.
1030
+ w(g, "~Mif (/**@type {boolean}*/(");
1028
1031
  // We want the inverse of the snowball test here.
1029
1032
  relop ^= 1;
1030
1033
  }
@@ -1034,7 +1037,7 @@ static void generate_integer_test(struct generator * g, struct node * p) {
1034
1037
  if (optimise_to_return) {
1035
1038
  w(g, ";~N");
1036
1039
  } else {
1037
- w(g, ") ");
1040
+ w(g, ")) ");
1038
1041
  write_failure_after_if(g);
1039
1042
  g->unreachable = false;
1040
1043
  }
@@ -1114,7 +1117,7 @@ static void generate_define(struct generator * g, struct node * p) {
1114
1117
  "~M#~W() {~+~N", p);
1115
1118
 
1116
1119
  /* Save output. */
1117
- struct str * saved_output = g->outbuf;
1120
+ struct str * saved_outbuf = g->outbuf;
1118
1121
  struct str * saved_declarations = g->declarations;
1119
1122
  g->outbuf = str_new();
1120
1123
  g->declarations = str_new();
@@ -1124,11 +1127,11 @@ static void generate_define(struct generator * g, struct node * p) {
1124
1127
 
1125
1128
  struct name * q = p->name;
1126
1129
 
1127
- if (q->amongvar_needed) {
1130
+ if (amongvar_needed(p->left)) {
1128
1131
  // The "among var" (`a`) is only assigned to, but the initialisation
1129
1132
  // can be generated in a nested block so it seems hard to declare it as
1130
1133
  // const and still have it visible when we want to use it.
1131
- w(g, "~Mlet /** number */ a;~N");
1134
+ w(g, "~Mlet /**@type {number}*/ a;~N");
1132
1135
  }
1133
1136
 
1134
1137
  /* Declare localised variables. */
@@ -1136,17 +1139,17 @@ static void generate_define(struct generator * g, struct node * p) {
1136
1139
  if (name->local_to == q) {
1137
1140
  switch (name->type) {
1138
1141
  case t_string:
1139
- w(g, "~Mlet /** string */ ");
1142
+ w(g, "~Mlet /**@type {string}*/ ");
1140
1143
  write_varname(g, name);
1141
1144
  w(g, ";~N");
1142
1145
  break;
1143
1146
  case t_integer:
1144
- w(g, "~Mlet /** number */ ");
1147
+ w(g, "~Mlet /**@type {number}*/ ");
1145
1148
  write_varname(g, name);
1146
1149
  w(g, ";~N");
1147
1150
  break;
1148
1151
  case t_boolean:
1149
- w(g, "~Mlet /** boolean */ ");
1152
+ w(g, "~Mlet /**@type {boolean}*/ ");
1150
1153
  write_varname(g, name);
1151
1154
  w(g, ";~N");
1152
1155
  break;
@@ -1172,7 +1175,7 @@ static void generate_define(struct generator * g, struct node * p) {
1172
1175
  if (q->type == t_external) {
1173
1176
  w(g, "~N");
1174
1177
  w(g, "~M/**@return{string}*/~N");
1175
- writef(g, "~M~W(/**string*/input) {~+~N", p);
1178
+ writef(g, "~M~W(/**@type {string}*/input) {~+~N", p);
1176
1179
  w(g, "~Mthis.setCurrent(input);~N");
1177
1180
  writef(g, "~Mthis.#~W();~N", p);
1178
1181
  w(g, "~Mreturn this.getCurrent();~N");
@@ -1184,12 +1187,12 @@ static void generate_define(struct generator * g, struct node * p) {
1184
1187
  }
1185
1188
  }
1186
1189
 
1187
- str_append(saved_output, g->declarations);
1188
- str_append(saved_output, g->outbuf);
1190
+ str_append(saved_outbuf, g->declarations);
1191
+ str_append(saved_outbuf, g->outbuf);
1189
1192
  str_delete(g->declarations);
1190
1193
  str_delete(g->outbuf);
1191
1194
  g->declarations = saved_declarations;
1192
- g->outbuf = saved_output;
1195
+ g->outbuf = saved_outbuf;
1193
1196
  }
1194
1197
 
1195
1198
  static void generate_functionend(struct generator * g, struct node * p) {
@@ -1290,7 +1293,7 @@ static void generate_debug(struct generator * g, struct node * p) {
1290
1293
  write_comment(g, p);
1291
1294
  g->I[0] = g->debug_count++;
1292
1295
  g->I[1] = p->line_number;
1293
- writef(g, "~Mthis.debug(~I0, ~I1);~N", p);
1296
+ writef(g, "~Mthis.#debug(~I0, ~I1);~N", p);
1294
1297
  }
1295
1298
 
1296
1299
  static void generate(struct generator * g, struct node * p) {
@@ -1394,7 +1397,7 @@ static void generate_class_end(struct generator * g) {
1394
1397
  static void generate_among_table(struct generator * g, struct among * x) {
1395
1398
  write_comment(g, x->node);
1396
1399
 
1397
- struct amongvec * v = x->b;
1400
+ struct amongvec * v = x->v;
1398
1401
 
1399
1402
  g->I[0] = x->number;
1400
1403
  w(g, "~Mconst a_~I0 = [~N~+");
@@ -1420,7 +1423,7 @@ static void generate_among_table(struct generator * g, struct among * x) {
1420
1423
 
1421
1424
  if (x->same_action == c_slicefrom && x->command_count > 1) {
1422
1425
  g->I[0] = x->number;
1423
- w(g, "~Mconst /** Array<string> */ as_~I0 = [");
1426
+ w(g, "~Mconst /**@type {Array<string>}*/ as_~I0 = [");
1424
1427
  for (int i = 1; i <= x->command_count; i++) {
1425
1428
  if (i > 1) w(g, ", ");
1426
1429
  write_literal_string(g, x->commands[i - 1]->left->literalstring);
@@ -1431,14 +1434,14 @@ static void generate_among_table(struct generator * g, struct among * x) {
1431
1434
 
1432
1435
  static void generate_amongs(struct generator * g) {
1433
1436
  for (struct among * x = g->analyser->amongs; x; x = x->next) {
1434
- generate_among_table(g, x);
1437
+ if (!x->duplicate) generate_among_table(g, x);
1435
1438
  }
1436
1439
  }
1437
1440
 
1438
1441
  static void generate_among_dispatcher(struct generator * g, struct among * x) {
1439
- if (x->function_count <= 1) return;
1442
+ if (x->unique_function_count <= 1) return;
1440
1443
 
1441
- struct amongvec * v = x->b;
1444
+ struct amongvec * v = x->v;
1442
1445
 
1443
1446
  write_comment(g, x->node);
1444
1447
 
@@ -1446,7 +1449,7 @@ static void generate_among_dispatcher(struct generator * g, struct among * x) {
1446
1449
  w(g, "~N~M/** @return {boolean} */~N");
1447
1450
  w(g, "~M#af_~I0() {~N~+");
1448
1451
  w(g, "~Mswitch (this.af) {~N~+");
1449
- for (int n = 1; n <= x->function_count; n++) {
1452
+ for (int n = 1; n <= x->unique_function_count; n++) {
1450
1453
  w(g, "~Mcase ");
1451
1454
  write_int(g, n);
1452
1455
  w(g, ": return ");
@@ -1481,7 +1484,7 @@ static void generate_grouping_table(struct generator * g, struct grouping * q) {
1481
1484
 
1482
1485
  for (int i = 0; i < SIZE(b); i++) set_bit(map, b[i] - q->smallest_ch);
1483
1486
 
1484
- w(g, "~Mconst /** Array<number> */ ");
1487
+ w(g, "~Mconst /**@type {Array<number>}*/ ");
1485
1488
  write_varname(g, q->name);
1486
1489
  write_string(g, " = [");
1487
1490
  for (int i = 0; i < size; i++) {
@@ -1508,19 +1511,19 @@ static void generate_members(struct generator * g) {
1508
1511
  case t_string:
1509
1512
  w(g, "~M#");
1510
1513
  write_varname(g, q);
1511
- w(g, "/** string */ = '';~N");
1514
+ w(g, "/**@type {string}*/ = '';~N");
1512
1515
  wrote_members = true;
1513
1516
  break;
1514
1517
  case t_integer:
1515
1518
  w(g, "~M#");
1516
1519
  write_varname(g, q);
1517
- w(g, "/** number */ = 0;~N");
1520
+ w(g, "/**@type {number}*/ = 0;~N");
1518
1521
  wrote_members = true;
1519
1522
  break;
1520
1523
  case t_boolean:
1521
1524
  w(g, "~M#");
1522
1525
  write_varname(g, q);
1523
- w(g, "/** boolean */ = false;~N");
1526
+ w(g, "/**@type {boolean}*/ = false;~N");
1524
1527
  wrote_members = true;
1525
1528
  break;
1526
1529
  }
@@ -1563,6 +1566,30 @@ extern void generate_program_js(struct generator * g) {
1563
1566
 
1564
1567
  generate_members(g);
1565
1568
 
1569
+ if (g->analyser->debug_used) {
1570
+ w(g, "~N"
1571
+ "~M/**~N"
1572
+ "~M/* @param {number} n~N"
1573
+ "~M/* @param {number} line~N"
1574
+ "~M */~N"
1575
+ "~M#debug(n, line) {~N~+"
1576
+ "~Mconst len = this.current.length;~N"
1577
+ "~Mlet s = `${n<10?' ':n<100?' ':''}${n} (line ${line<10?' ':line<100?' ':line<1000?' ':''}${line}): [${len}]'`;~N"
1578
+ "~Mfor (let i = 0; i <= len; ++i) {~N~+"
1579
+ "~Mif (this.limit_backward === i) s = s + '{';~N"
1580
+ "~Mif (this.bra === i) s = s + '[';~N"
1581
+ "~Mif (this.c === i) s = s + '|';~N"
1582
+ "~Mif (this.ket === i) s = s + ']';~N"
1583
+ "~Mif (this.limit === i) s = s + '}';~N"
1584
+ "~Mif (i < len) {~N~+"
1585
+ "~Mconst ch = this.current[i];~N"
1586
+ "~Mif (ch === '\\0') s = s + '#'; else s = s + ch;~N~-"
1587
+ "~M}~N~-"
1588
+ "~M}~N"
1589
+ "~Mconsole.log(s + \"'\");~N~-"
1590
+ "~M}~N");
1591
+ }
1592
+
1566
1593
  generate_among_dispatchers(g);
1567
1594
 
1568
1595
  generate_methods(g);
@@ -59,7 +59,7 @@ static void write_varname(struct generator * g, struct name * p) {
59
59
  write_s(g, p->s);
60
60
  }
61
61
 
62
- static void write_literal_string(struct generator * g, symbol * p) {
62
+ static void write_literal_string(struct generator * g, const symbol * p) {
63
63
  if (SIZE(p) == 0) {
64
64
  write_string(g, "''");
65
65
  return;
@@ -1118,7 +1118,7 @@ static void generate_define(struct generator * g, struct node * p) {
1118
1118
  writef(g, "~MFunction T~n.~W : Boolean;~N", p);
1119
1119
 
1120
1120
  /* Save output. */
1121
- struct str * saved_output = g->outbuf;
1121
+ struct str * saved_outbuf = g->outbuf;
1122
1122
  struct str * saved_declarations = g->declarations;
1123
1123
  g->outbuf = str_new();
1124
1124
  g->declarations = str_new();
@@ -1142,61 +1142,67 @@ static void generate_define(struct generator * g, struct node * p) {
1142
1142
  }
1143
1143
  w(g, "~}");
1144
1144
 
1145
- if (q->amongvar_needed) {
1146
- str_append_string(g->declarations, " AmongVar : Integer;\n");
1145
+ struct str * temp = g->outbuf;
1146
+ g->outbuf = g->declarations;
1147
+
1148
+ g->margin++;
1149
+
1150
+ if (amongvar_needed(p->left)) {
1151
+ w(g, "~MAmongVar : Integer;~N");
1147
1152
  }
1148
1153
 
1149
1154
  if (g->temporary_used) {
1150
- str_append_string(g->declarations, " C : Integer;\n");
1155
+ w(g, "~MC : Integer;~N");
1151
1156
  }
1152
1157
 
1153
1158
  /* Declare localised variables. */
1154
- struct str * temp = g->outbuf;
1155
- g->outbuf = g->declarations;
1156
1159
  for (struct name * name = g->analyser->names; name; name = name->next) {
1157
1160
  if (name->local_to == q) {
1158
1161
  switch (name->type) {
1159
1162
  case t_string:
1160
- w(g, " ");
1163
+ write_margin(g);
1161
1164
  write_varname(g, name);
1162
- w(g, " : AnsiString;\n");
1165
+ w(g, " : AnsiString;~N");
1163
1166
  break;
1164
1167
  case t_integer:
1165
- w(g, " ");
1168
+ write_margin(g);
1166
1169
  write_varname(g, name);
1167
- w(g, " : Integer;\n");
1170
+ w(g, " : Integer;~N");
1168
1171
  break;
1169
1172
  case t_boolean:
1170
- w(g, " ");
1173
+ write_margin(g);
1171
1174
  write_varname(g, name);
1172
- w(g, " : Boolean;\n");
1175
+ w(g, " : Boolean;~N");
1173
1176
  break;
1174
1177
  }
1175
1178
  }
1176
1179
  }
1177
- g->outbuf = temp;
1180
+ g->margin--;
1181
+ g->outbuf = saved_outbuf;
1178
1182
 
1179
1183
  if (str_len(g->declarations) > 0) {
1180
- str_append_string(saved_output, "Var\n");
1181
- str_append(saved_output, g->declarations);
1184
+ w(g, "~MVar~N");
1185
+ str_append(saved_outbuf, g->declarations);
1182
1186
  }
1183
1187
 
1184
1188
  if (g->next_label) {
1185
- str_append_string(saved_output, "Label\n");
1189
+ w(g, "~MLabel~N~+");
1186
1190
 
1187
1191
  int num = g->next_label;
1188
1192
  for (int i = 0; i < num; ++i) {
1189
- str_append_string(saved_output, " lab");
1190
- str_append_int(saved_output, i);
1191
- str_append_string(saved_output, i == num - 1 ? ";\n" : ",\n");
1193
+ if (i) w(g, ",~N");
1194
+ w(g, "~Mlab");
1195
+ write_int(g, i);
1192
1196
  }
1197
+ w(g, ";~N");
1198
+
1199
+ g->margin--;
1193
1200
  }
1194
1201
 
1195
- str_append(saved_output, g->outbuf);
1202
+ str_append(saved_outbuf, temp);
1196
1203
  str_delete(g->declarations);
1197
- str_delete(g->outbuf);
1204
+ str_delete(temp);
1198
1205
  g->declarations = saved_declarations;
1199
- g->outbuf = saved_output;
1200
1206
  }
1201
1207
 
1202
1208
  static void generate_functionend(struct generator * g, struct node * p) {
@@ -1281,7 +1287,7 @@ static void generate_debug(struct generator * g, struct node * p) {
1281
1287
  write_comment(g, p);
1282
1288
  g->I[0] = g->debug_count++;
1283
1289
  g->I[1] = p->line_number;
1284
- writef(g, "~Mdebug(~I0, ~I1);~N", p);
1290
+ writef(g, "~MDebug(~I0, ~I1);~N", p);
1285
1291
  }
1286
1292
 
1287
1293
  static void generate(struct generator * g, struct node * p) {
@@ -1397,6 +1403,10 @@ static void generate_method_decls(struct generator * g) {
1397
1403
  w(g, "~Mpublic~N~+");
1398
1404
  w(g, "~MConstructor Create;~N");
1399
1405
 
1406
+ if (g->analyser->debug_used) {
1407
+ w(g, "~Mprocedure Debug(N : Integer; Line : Integer);~N");
1408
+ }
1409
+
1400
1410
  for (struct name * q = g->analyser->names; q; q = q->next) {
1401
1411
  if (q->type == t_external) {
1402
1412
  generate_method_decl(g, q);
@@ -1470,7 +1480,7 @@ static void generate_among_decls(struct generator * g) {
1470
1480
  static void generate_among_table(struct generator * g, struct among * x) {
1471
1481
  write_comment(g, x->node);
1472
1482
 
1473
- struct amongvec * v = x->b;
1483
+ struct amongvec * v = x->v;
1474
1484
 
1475
1485
  g->I[0] = x->number;
1476
1486
  g->I[1] = x->literalstring_count;
@@ -1505,7 +1515,7 @@ static void generate_among_table(struct generator * g, struct among * x) {
1505
1515
 
1506
1516
  static void generate_amongs(struct generator * g) {
1507
1517
  for (struct among * x = g->analyser->amongs; x; x = x->next) {
1508
- generate_among_table(g, x);
1518
+ if (!x->duplicate) generate_among_table(g, x);
1509
1519
  }
1510
1520
  }
1511
1521
 
@@ -1570,6 +1580,39 @@ extern void generate_program_pascal(struct generator * g) {
1570
1580
  /* generate implementation. */
1571
1581
  generate_groupings(g);
1572
1582
  generate_constructor(g);
1583
+
1584
+ if (g->analyser->debug_used) {
1585
+ w(g, "~N"
1586
+ "~Mprocedure T~n.Debug(N : Integer; Line : Integer);~N~+"
1587
+ "~MVar Len : Integer;~N"
1588
+ "~MVar Ch : Char;~N"
1589
+ "~MVar I : Integer;~N"
1590
+ "~-~MBegin~N~+"
1591
+ "~MLen := Length(FCurrent);~N"
1592
+ "~MIf N < 10 Then Write(' ');~N"
1593
+ "~MIf N < 100 Then Write(' ');~N"
1594
+ "~MWrite(N, ' (line ');~N"
1595
+ "~MIf Line < 10 Then Write(' ');~N"
1596
+ "~MIf Line < 100 Then Write(' ');~N"
1597
+ "~MIf Line < 1000 Then Write(' ');~N"
1598
+ "~MWrite(Line, '): [', Len, ']''');~N"
1599
+ "~MFor I := 0 To Len Do~N"
1600
+ "~MBegin~N~+"
1601
+ "~MIf FBkLimit = I Then Write('{');~N"
1602
+ "~MIf FBra = I Then Write('[');~N"
1603
+ "~MIf FCursor = I Then Write('|');~N"
1604
+ "~MIf FKet = I Then Write(']');~N"
1605
+ "~MIf FLimit = I Then Write('}');~N"
1606
+ "~MIf I < Len Then~N"
1607
+ "~MBegin~N~+"
1608
+ "~MCh := FCurrent[I + 1];~N"
1609
+ "~MIf Ch = #0 Then Write('#') Else Write(Ch);~N"
1610
+ "~-~MEnd;~N"
1611
+ "~-~MEnd;~N"
1612
+ "~MWriteLn('''');~N"
1613
+ "~-~MEnd;~N");
1614
+ }
1615
+
1573
1616
  generate_methods(g);
1574
1617
 
1575
1618
  generate_unit_end(g);
@@ -46,7 +46,7 @@ static void write_varref(struct generator * g, struct name * p) {
46
46
  write_varname(g, p);
47
47
  }
48
48
 
49
- static void write_literal_string(struct generator * g, symbol * p) {
49
+ static void write_literal_string(struct generator * g, const symbol * p) {
50
50
  int i = 0;
51
51
  write_char(g, '"');
52
52
  while (i < SIZE(p)) {
@@ -57,7 +57,7 @@ static void write_literal_string(struct generator * g, symbol * p) {
57
57
  write_char(g, ch);
58
58
  } else {
59
59
  write_string(g, "\\u{");
60
- write_hex4(g, ch);
60
+ write_hex(g, ch);
61
61
  write_string(g, "}");
62
62
  }
63
63
  }
@@ -71,7 +71,7 @@ static void write_literal_char(struct generator * g, symbol ch) {
71
71
  write_char(g, ch);
72
72
  } else {
73
73
  write_string(g, "\\u{");
74
- write_hex4(g, ch);
74
+ write_hex(g, ch);
75
75
  write_string(g, "}");
76
76
  }
77
77
  write_char(g, '"');
@@ -722,10 +722,10 @@ static void generate_hop(struct generator * g, struct node * p) {
722
722
  // Generate the AE to a temporary block so we can substitute it in
723
723
  // write_failure_if().
724
724
  struct str * ae = str_new();
725
- struct str * s = g->outbuf;
725
+ struct str * saved_outbuf = g->outbuf;
726
726
  g->outbuf = ae;
727
727
  generate_AE(g, p->AE);
728
- g->outbuf = s;
728
+ g->outbuf = saved_outbuf;
729
729
  g->B[0] = str_data(ae);
730
730
  g->S[0] = p->mode == m_forward ? "" : "_back";
731
731
  g->S[1] = p->AE->type == c_number ? "" : "_checked";
@@ -1095,7 +1095,7 @@ static void generate_define(struct generator * g, struct node * p) {
1095
1095
  write_block_start(g);
1096
1096
 
1097
1097
  /* Save output. */
1098
- struct str * saved_output = g->outbuf;
1098
+ struct str * saved_outbuf = g->outbuf;
1099
1099
  struct str * saved_declarations = g->declarations;
1100
1100
  g->outbuf = str_new();
1101
1101
  g->declarations = str_new();
@@ -1118,12 +1118,12 @@ static void generate_define(struct generator * g, struct node * p) {
1118
1118
  }
1119
1119
  write_block_end(g);
1120
1120
 
1121
- str_append(saved_output, g->declarations);
1122
- str_append(saved_output, g->outbuf);
1121
+ str_append(saved_outbuf, g->declarations);
1122
+ str_append(saved_outbuf, g->outbuf);
1123
1123
  str_delete(g->declarations);
1124
1124
  str_delete(g->outbuf);
1125
1125
  g->declarations = saved_declarations;
1126
- g->outbuf = saved_output;
1126
+ g->outbuf = saved_outbuf;
1127
1127
  }
1128
1128
 
1129
1129
  static void generate_functionend(struct generator * g, struct node * p) {
@@ -1224,7 +1224,7 @@ static void generate_debug(struct generator * g, struct node * p) {
1224
1224
  write_comment(g, p);
1225
1225
  g->I[0] = g->debug_count++;
1226
1226
  g->I[1] = p->line_number;
1227
- writef(g, "~M$this->debug(~I0, ~I1);~N", p);
1227
+ writef(g, "~M$this->_debug(~I0, ~I1);~N", p);
1228
1228
  }
1229
1229
 
1230
1230
  static void generate(struct generator * g, struct node * p) {
@@ -1325,7 +1325,7 @@ static void generate_class_end(struct generator * g) {
1325
1325
  static void generate_among_table(struct generator * g, struct among * x) {
1326
1326
  write_comment(g, x->node);
1327
1327
 
1328
- struct amongvec * v = x->b;
1328
+ struct amongvec * v = x->v;
1329
1329
 
1330
1330
  g->I[0] = x->number;
1331
1331
  w(g, "~Mprivate const array A_~I0 = [~N~+");
@@ -1360,7 +1360,7 @@ static void generate_among_table(struct generator * g, struct among * x) {
1360
1360
 
1361
1361
  static void generate_amongs(struct generator * g) {
1362
1362
  for (struct among * x = g->analyser->amongs; x; x = x->next) {
1363
- generate_among_table(g, x);
1363
+ if (!x->duplicate) generate_among_table(g, x);
1364
1364
  }
1365
1365
  }
1366
1366
 
@@ -1435,6 +1435,27 @@ extern void generate_program_php(struct generator * g) {
1435
1435
  generate_groupings(g);
1436
1436
 
1437
1437
  generate_members(g);
1438
+
1439
+ if (g->analyser->debug_used) {
1440
+ w(g, "~N"
1441
+ "~Mprivate function _debug(int $n, int $line): void {~N~+"
1442
+ "~M$len = strlen($this->current);~N"
1443
+ "~Mprintf(\"%3d (line %4d): [%d]'\", $n, $line, $len);~N"
1444
+ "~Mfor ($i = 0; $i <= $len; ++$i) {~N~+"
1445
+ "~Mif ($this->limit_backward === $i) echo '{';~N"
1446
+ "~Mif ($this->bra === $i) echo '[';~N"
1447
+ "~Mif ($this->cursor === $i) echo '|';~N"
1448
+ "~Mif ($this->ket === $i) echo ']';~N"
1449
+ "~Mif ($this->limit === $i) echo '}';~N"
1450
+ "~Mif ($i < $len) {~N~+"
1451
+ "~M$ch = $this->current[$i];~N"
1452
+ "~Mif ($ch === '\\0') echo '#'; else echo $ch;~N~-"
1453
+ "~M}~N~-"
1454
+ "~M}~N"
1455
+ "~Mecho \"'\\n\";~N~-"
1456
+ "~M}~N");
1457
+ }
1458
+
1438
1459
  generate_methods(g);
1439
1460
 
1440
1461
  generate_class_end(g);