mittens 0.3.1 → 0.3.2

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +1 -0
  4. data/README.md +2 -2
  5. data/Rakefile +10 -3
  6. data/lib/mittens/version.rb +1 -1
  7. data/vendor/snowball/.github/workflows/ci.yml +144 -17
  8. data/vendor/snowball/.github/workflows/coverage.yml +117 -0
  9. data/vendor/snowball/.github/workflows/runtime-tests.yml +26 -0
  10. data/vendor/snowball/.gitignore +33 -7
  11. data/vendor/snowball/CONTRIBUTING.rst +7 -0
  12. data/vendor/snowball/COPYING +1 -1
  13. data/vendor/snowball/GNUmakefile +736 -298
  14. data/vendor/snowball/NEWS +1394 -7
  15. data/vendor/snowball/README.rst +8 -8
  16. data/vendor/snowball/ada/generate/generate.adb +5 -5
  17. data/vendor/snowball/ada/src/stemmer.adb +177 -188
  18. data/vendor/snowball/ada/src/stemmer.ads +86 -89
  19. data/vendor/snowball/ada/src/stemwords.adb +21 -5
  20. data/vendor/snowball/algorithms/czech.sbl +255 -0
  21. data/vendor/snowball/algorithms/danish.sbl +22 -10
  22. data/vendor/snowball/algorithms/english.sbl +7 -4
  23. data/vendor/snowball/algorithms/esperanto.sbl +6 -7
  24. data/vendor/snowball/algorithms/estonian.sbl +9 -4
  25. data/vendor/snowball/algorithms/finnish.sbl +33 -21
  26. data/vendor/snowball/algorithms/german.sbl +5 -0
  27. data/vendor/snowball/algorithms/indonesian.sbl +115 -96
  28. data/vendor/snowball/algorithms/italian.sbl +26 -1
  29. data/vendor/snowball/algorithms/lithuanian.sbl +13 -13
  30. data/vendor/snowball/algorithms/norwegian.sbl +17 -6
  31. data/vendor/snowball/algorithms/persian.sbl +387 -0
  32. data/vendor/snowball/algorithms/polish.sbl +177 -0
  33. data/vendor/snowball/algorithms/sesotho.sbl +115 -0
  34. data/vendor/snowball/algorithms/turkish.sbl +4 -4
  35. data/vendor/snowball/compiler/analyser.c +2002 -711
  36. data/vendor/snowball/compiler/driver.c +460 -298
  37. data/vendor/snowball/compiler/generator.c +439 -1965
  38. data/vendor/snowball/compiler/generator_ada.c +605 -430
  39. data/vendor/snowball/compiler/generator_c.c +2227 -0
  40. data/vendor/snowball/compiler/generator_csharp.c +365 -274
  41. data/vendor/snowball/compiler/generator_dart.c +1476 -0
  42. data/vendor/snowball/compiler/generator_go.c +348 -270
  43. data/vendor/snowball/compiler/generator_java.c +330 -233
  44. data/vendor/snowball/compiler/generator_js.c +534 -385
  45. data/vendor/snowball/compiler/generator_pascal.c +361 -320
  46. data/vendor/snowball/compiler/generator_php.c +1445 -0
  47. data/vendor/snowball/compiler/generator_python.c +399 -299
  48. data/vendor/snowball/compiler/generator_rust.c +370 -261
  49. data/vendor/snowball/compiler/generator_zig.c +1474 -0
  50. data/vendor/snowball/compiler/header.h +153 -86
  51. data/vendor/snowball/compiler/space.c +121 -63
  52. data/vendor/snowball/compiler/tokeniser.c +286 -182
  53. data/vendor/snowball/compiler/tokens.h +71 -0
  54. data/vendor/snowball/csharp/Snowball/Among.cs +14 -26
  55. data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +3 -3
  56. data/vendor/snowball/csharp/Snowball/Stemmer.cs +41 -45
  57. data/vendor/snowball/csharp/Stemwords/Program.cs +20 -14
  58. data/vendor/snowball/cxx/.gitignore +4 -0
  59. data/vendor/snowball/cxx/generate_algorithms.pl +87 -0
  60. data/vendor/snowball/cxx/stemmer.h +12 -0
  61. data/vendor/snowball/cxx/stemwords.cxx +176 -0
  62. data/vendor/snowball/cxx/utilities.cxx +2 -0
  63. data/vendor/snowball/dart/.gitignore +4 -0
  64. data/vendor/snowball/dart/analysis_options.yaml +1 -0
  65. data/vendor/snowball/dart/example/test_app.dart +65 -0
  66. data/vendor/snowball/dart/generate_algorithms.pl +21 -0
  67. data/vendor/snowball/dart/lib/snowball.dart +18 -0
  68. data/vendor/snowball/dart/lib/src/snowball.dart +339 -0
  69. data/vendor/snowball/dart/pubspec.yaml +17 -0
  70. data/vendor/snowball/doc/libstemmer_dart_README +37 -0
  71. data/vendor/snowball/doc/libstemmer_js_README +2 -2
  72. data/vendor/snowball/doc/libstemmer_php_README +38 -0
  73. data/vendor/snowball/doc/libstemmer_python_README +3 -3
  74. data/vendor/snowball/examples/stemwords.c +18 -3
  75. data/vendor/snowball/go/README.md +12 -4
  76. data/vendor/snowball/go/env.go +12 -14
  77. data/vendor/snowball/go/stemwords/main.go +2 -1
  78. data/vendor/snowball/java/org/tartarus/snowball/CharArraySequence.java +36 -0
  79. data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +17 -34
  80. data/vendor/snowball/java/org/tartarus/snowball/SnowballStemmer.java +0 -2
  81. data/vendor/snowball/javascript/base-stemmer.js +219 -252
  82. data/vendor/snowball/javascript/stemwords.js +86 -58
  83. data/vendor/snowball/libstemmer/mkmodules.pl +1 -1
  84. data/vendor/snowball/libstemmer/modules.txt +4 -0
  85. data/vendor/snowball/pascal/SnowballProgram.pas +18 -31
  86. data/vendor/snowball/php/base-stemmer.php +453 -0
  87. data/vendor/snowball/php/stemwords.php +25 -0
  88. data/vendor/snowball/python/create_init.py +16 -21
  89. data/vendor/snowball/python/pyproject.toml +3 -0
  90. data/vendor/snowball/python/setup.py +5 -7
  91. data/vendor/snowball/python/snowballstemmer/among.py +1 -2
  92. data/vendor/snowball/python/snowballstemmer/basestemmer.py +24 -33
  93. data/vendor/snowball/python/stemwords.py +72 -63
  94. data/vendor/snowball/runtime/api.c +11 -42
  95. data/vendor/snowball/runtime/api.h +11 -9
  96. data/vendor/snowball/runtime/snowball_runtime.h +110 -0
  97. data/vendor/snowball/runtime/utilities.c +282 -106
  98. data/vendor/snowball/rust/src/main.rs +2 -2
  99. data/vendor/snowball/rust/src/snowball/snowball_env.rs +7 -9
  100. data/vendor/snowball/tests/compilertest +62 -0
  101. data/vendor/snowball/tests/errors/ae-errors.sbl +53 -0
  102. data/vendor/snowball/tests/errors/ae-errors.stderr +8 -0
  103. data/vendor/snowball/tests/errors/bad-dollar.sbl +14 -0
  104. data/vendor/snowball/tests/errors/bad-dollar.stderr +4 -0
  105. data/vendor/snowball/tests/errors/bad-grouping-definition.sbl +9 -0
  106. data/vendor/snowball/tests/errors/bad-grouping-definition.stderr +6 -0
  107. data/vendor/snowball/tests/errors/missing-bra.sbl +6 -0
  108. data/vendor/snowball/tests/errors/missing-bra.stderr +3 -0
  109. data/vendor/snowball/tests/errors/missing-command.sbl +9 -0
  110. data/vendor/snowball/tests/errors/missing-command.stderr +1 -0
  111. data/vendor/snowball/tests/errors/missing-ket-backwardmode.sbl +3 -0
  112. data/vendor/snowball/tests/errors/missing-ket-backwardmode.stderr +1 -0
  113. data/vendor/snowball/tests/errors/missing-ket.sbl +7 -0
  114. data/vendor/snowball/tests/errors/missing-ket.stderr +6 -0
  115. data/vendor/snowball/tests/errors/notdefined.sbl +4 -0
  116. data/vendor/snowball/tests/errors/notdefined.stderr +2 -0
  117. data/vendor/snowball/tests/errors/string-omitted.sbl +5 -0
  118. data/vendor/snowball/tests/errors/string-omitted.stderr +1 -0
  119. data/vendor/snowball/tests/errors/undeclared.sbl +20 -0
  120. data/vendor/snowball/tests/errors/undeclared.stderr +9 -0
  121. data/vendor/snowball/tests/errors/unexpected-token.sbl +24 -0
  122. data/vendor/snowball/tests/errors/unexpected-token.stderr +17 -0
  123. data/vendor/snowball/tests/errors/wrongdirection.sbl +14 -0
  124. data/vendor/snowball/tests/errors/wrongdirection.stderr +1 -0
  125. data/vendor/snowball/tests/runtime/among.sbl +19 -0
  126. data/vendor/snowball/tests/runtime/arithmeticexpr.sbl +86 -0
  127. data/vendor/snowball/tests/runtime/attachinsert.sbl +47 -0
  128. data/vendor/snowball/tests/runtime/booleans.sbl +19 -0
  129. data/vendor/snowball/tests/runtime/externals.sbl +22 -0
  130. data/vendor/snowball/tests/runtime/hop.sbl +12 -0
  131. data/vendor/snowball/tests/runtime/integertests.sbl +60 -0
  132. data/vendor/snowball/tests/runtime/intlimits.sbl +25 -0
  133. data/vendor/snowball/tests/runtime/naming.sbl +20 -0
  134. data/vendor/snowball/tests/runtime/not.sbl +30 -0
  135. data/vendor/snowball/tests/runtime/or.sbl +17 -0
  136. data/vendor/snowball/tests/runtime/repeat.sbl +16 -0
  137. data/vendor/snowball/tests/runtime/setlimit.sbl +24 -0
  138. data/vendor/snowball/tests/runtime/sizelen.sbl +56 -0
  139. data/vendor/snowball/tests/runtime/slice.sbl +27 -0
  140. data/vendor/snowball/tests/runtime/stringdollar.sbl +39 -0
  141. data/vendor/snowball/tests/runtime/strings.sbl +66 -0
  142. data/vendor/snowball/tests/runtime/test.sbl +19 -0
  143. data/vendor/snowball/tests/stemtest.c +41 -1
  144. data/vendor/snowball/tests/syntax/canon.sbl +32 -0
  145. data/vendor/snowball/tests/syntax/canon.stderr +0 -0
  146. data/vendor/snowball/tests/syntax/canon.syntax +57 -0
  147. data/vendor/snowball/tests/syntax/emptyprogram.sbl +2 -0
  148. data/vendor/snowball/tests/syntax/emptyprogram.syntax +0 -0
  149. data/vendor/snowball/tests/syntax/groupings.sbl +11 -0
  150. data/vendor/snowball/tests/syntax/inline.sbl +144 -0
  151. data/vendor/snowball/tests/syntax/inline.stderr +0 -0
  152. data/vendor/snowball/tests/syntax/inline.syntax +121 -0
  153. data/vendor/snowball/tests/syntax/legacy.sbl +17 -0
  154. data/vendor/snowball/tests/syntax/legacy.stderr +5 -0
  155. data/vendor/snowball/tests/syntax/legacy.syntax +19 -0
  156. data/vendor/snowball/tests/syntax/loops.sbl +14 -0
  157. data/vendor/snowball/tests/syntax/loops.stderr +9 -0
  158. data/vendor/snowball/tests/syntax/loops.syntax +29 -0
  159. data/vendor/snowball/tests/syntax/noops.sbl +76 -0
  160. data/vendor/snowball/tests/syntax/noops.stderr +27 -0
  161. data/vendor/snowball/tests/syntax/noops.syntax +135 -0
  162. data/vendor/snowball/tests/syntax/simplifyae.sbl +21 -0
  163. data/vendor/snowball/tests/syntax/simplifyae.stderr +0 -0
  164. data/vendor/snowball/tests/syntax/simplifyae.syntax +39 -0
  165. data/vendor/snowball/tests/syntax/unused.sbl +18 -0
  166. data/vendor/snowball/tests/syntax/unused.stderr +7 -0
  167. data/vendor/snowball/tests/syntax/unused.syntax +3 -0
  168. data/vendor/snowball/zig/env.zig +599 -0
  169. data/vendor/snowball/zig/generate_algorithms.pl +19 -0
  170. data/vendor/snowball/zig/stemwords.zig +123 -0
  171. metadata +102 -4
  172. data/vendor/snowball/compiler/syswords.h +0 -86
  173. data/vendor/snowball/runtime/header.h +0 -62
@@ -5,39 +5,42 @@
5
5
  #include <ctype.h> /* isalpha etc */
6
6
  #include "header.h"
7
7
 
8
- struct system_word {
9
- int s_size; /* size of system word */
10
- const byte * s; /* pointer to the system word */
11
- int code; /* its internal code */
12
- };
13
-
14
-
15
- /* ASCII collating assumed in syswords.h */
16
-
17
- #include "syswords.h"
8
+ #include "tokens.h"
18
9
 
19
10
  #define INITIAL_INPUT_BUFFER_SIZE 8192
20
11
 
21
12
  static int hex_to_num(int ch);
22
13
 
23
- static int smaller(int a, int b) { return a < b ? a : b; }
24
-
25
14
  extern byte * get_input(const char * filename) {
26
- FILE * input = fopen(filename, "r");
15
+ FILE * input = strcmp(filename, "-") == 0 ? stdin : fopen(filename, "rb");
27
16
  if (input == NULL) { return NULL; }
28
- {
29
- byte * u = create_s(INITIAL_INPUT_BUFFER_SIZE);
30
- int size = 0;
17
+ byte * u = NULL;
18
+ int size = fseek(input, 0, SEEK_END) == 0 ? ftell(input) : -1;
19
+ if (size >= 0 && fseek(input, 0, SEEK_SET) == 0) {
20
+ u = create_s(size);
21
+ if (fread(u, size, 1, input) != 1) {
22
+ fprintf(stderr, "%s: Read error\n", filename);
23
+ exit(1);
24
+ }
25
+ } else {
26
+ // Unseekable stream, e.g. piped stdin.
27
+ size = 0;
28
+ u = create_s(INITIAL_INPUT_BUFFER_SIZE);
31
29
  while (true) {
32
- int ch = getc(input);
33
- if (ch == EOF) break;
34
- if (size >= CAPACITY(u)) u = increase_capacity_s(u, size);
35
- u[size++] = ch;
30
+ int s = CAPACITY(u) - size;
31
+ int r = fread(u + size, 1, s, input);
32
+ if (r < 0) {
33
+ fprintf(stderr, "%s: Read error\n", filename);
34
+ exit(1);
35
+ }
36
+ size += r;
37
+ if (r < s) break;
38
+ u = increase_capacity_s(u, size);
36
39
  }
37
- fclose(input);
38
- SIZE(u) = size;
39
- return u;
40
40
  }
41
+ if (input != stdin) fclose(input);
42
+ SET_SIZE(u, size);
43
+ return u;
41
44
  }
42
45
 
43
46
  static void error(struct tokeniser * t, const char * s1, byte * p, int n, const char * s2) {
@@ -67,11 +70,12 @@ static int compare_words(int m, const byte * p, int n, const byte * q) {
67
70
  }
68
71
 
69
72
  static int find_word(int n, const byte * p) {
70
- int i = 0; int j = vocab->code;
73
+ int i = -1;
74
+ int j = NUM_ALPHA_TOKENS;
71
75
  do {
72
- int k = i + (j - i)/2;
73
- const struct system_word * w = vocab + k;
74
- int diff = compare_words(n, p, w->s_size, w->s);
76
+ int k = i + (j - i) / 2;
77
+ const struct token * w = alpha_tokens + k;
78
+ int diff = compare_words(n, p, w->s_size, (const byte*)w->s);
75
79
  if (diff == 0) return w->code;
76
80
  if (diff < 0) j = k; else i = k;
77
81
  } while (j - i != 1);
@@ -102,20 +106,19 @@ static symbol * find_in_m(struct tokeniser * t, int n, byte * p) {
102
106
 
103
107
  static int read_literal_string(struct tokeniser * t, int c) {
104
108
  byte * p = t->p;
105
- int ch;
106
- SIZE(t->b) = 0;
109
+ SET_SIZE(t->b, 0);
107
110
  while (true) {
108
111
  if (c >= SIZE(p) || p[c] == '\n') {
109
112
  error1(t, "string literal not terminated");
110
113
  return c;
111
114
  }
112
- ch = p[c];
115
+ int ch = p[c];
113
116
  c++;
114
117
  if (ch == t->m_start) {
115
118
  /* Inside insert characters. */
116
119
  int c0 = c;
117
- int newlines = false; /* no newlines as yet */
118
- int all_whitespace = true; /* no printing chars as yet */
120
+ bool newlines = false; /* no newlines as yet */
121
+ bool all_whitespace = true; /* no printing chars as yet */
119
122
  while (true) {
120
123
  if (c >= SIZE(p) || (p[c] == '\n' && !all_whitespace)) {
121
124
  error1(t, "string literal not terminated");
@@ -138,7 +141,6 @@ static int read_literal_string(struct tokeniser * t, int c) {
138
141
  t->b = add_symbol_to_b(t->b, p[c0]);
139
142
  else if (n >= 3 && firstch == 'U' && p[c0 + 1] == '+') {
140
143
  int codepoint = 0;
141
- int x;
142
144
  if (t->uplusmode == UPLUS_DEFINED) {
143
145
  /* See if found with xxxx upper-cased. */
144
146
  byte * uc = create_s(n);
@@ -156,7 +158,7 @@ static int read_literal_string(struct tokeniser * t, int c) {
156
158
  } else {
157
159
  t->uplusmode = UPLUS_UNICODE;
158
160
  }
159
- for (x = c0 + 2; x != c - 1; ++x) {
161
+ for (int x = c0 + 2; x != c - 1; ++x) {
160
162
  int hex = hex_to_num(p[x]);
161
163
  if (hex < 0) {
162
164
  error1(t, "Bad hex digit following U+");
@@ -170,10 +172,11 @@ static int read_literal_string(struct tokeniser * t, int c) {
170
172
  }
171
173
  /* Ensure there's enough space for a max length
172
174
  * UTF-8 sequence. */
173
- if (CAPACITY(t->b) < SIZE(t->b) + 3) {
175
+ int b_size = SIZE(t->b);
176
+ if (CAPACITY(t->b) < b_size + 3) {
174
177
  t->b = increase_capacity_b(t->b, 3);
175
178
  }
176
- SIZE(t->b) += put_utf8(codepoint, t->b + SIZE(t->b));
179
+ SET_SIZE(t->b, b_size + put_utf8(codepoint, t->b + b_size));
177
180
  } else {
178
181
  if (t->encoding == ENC_SINGLEBYTE) {
179
182
  /* Only ISO-8859-1 is handled this way - for
@@ -227,43 +230,105 @@ static int read_literal_string(struct tokeniser * t, int c) {
227
230
  static int next_token(struct tokeniser * t) {
228
231
  byte * p = t->p;
229
232
  int c = t->c;
230
- int ch;
231
233
  int code = -1;
232
234
  while (true) {
233
235
  if (c >= SIZE(p)) { t->c = c; return -1; }
234
- ch = p[c];
236
+ int ch = p[c];
235
237
  if (white_space(t, ch)) { c++; continue; }
238
+
236
239
  if (isalpha(ch)) {
237
240
  int c0 = c;
238
241
  while (c < SIZE(p) && (isalnum(p[c]) || p[c] == '_')) c++;
242
+ t->c = c;
239
243
  code = find_word(c - c0, p + c0);
240
- if (code < 0 || t->token_disabled[code]) {
241
- SIZE(t->s) = 0;
242
- t->s = add_s_to_s(t->s, (const char*)p + c0, c - c0);
243
- code = c_name;
244
+ if (code >= 0 && !t->token_disabled[code]) {
245
+ return code;
244
246
  }
245
- } else if (isdigit(ch)) {
247
+ SET_SIZE(t->s, 0);
248
+ t->s = add_slen_to_s(t->s, (const char*)p + c0, c - c0);
249
+ return c_name;
250
+ }
251
+
252
+ if (isdigit(ch)) {
246
253
  int value = ch - '0';
247
254
  while (++c < SIZE(p) && isdigit(p[c])) {
248
255
  value = 10 * value + (p[c] - '0');
249
256
  }
257
+ t->c = c;
250
258
  t->number = value;
251
- code = c_number;
252
- } else if (ch == '\'') {
253
- c = read_literal_string(t, c + 1);
254
- code = c_literalstring;
255
- } else {
256
- int lim = smaller(2, SIZE(p) - c);
257
- int i;
258
- for (i = lim; i > 0; i--) {
259
- code = find_word(i, p + c);
260
- if (code >= 0) { c += i; break; }
261
- }
259
+ return c_number;
262
260
  }
263
- if (code >= 0) {
264
- t->c = c;
265
- return code;
261
+
262
+ byte ch1 = p[c];
263
+ byte ch2 = (SIZE(p) - c > 1) ? p[c + 1] : 0;
264
+ t->c = c + 2;
265
+ switch (ch1) {
266
+ case '\'':
267
+ t->c = read_literal_string(t, c + 1);
268
+ return c_literalstring;
269
+ case '!':
270
+ if (ch2 == '=') return c_ne; // !=
271
+ break;
272
+ case '$':
273
+ --t->c;
274
+ return c_dollar; // $
275
+ case '(':
276
+ --t->c;
277
+ return c_bra; // (
278
+ case ')':
279
+ --t->c;
280
+ return c_ket; // )
281
+ case '*':
282
+ if (ch2 == '=') return c_multiplyassign; // *=
283
+ --t->c;
284
+ return c_multiply; // *
285
+ case '+':
286
+ if (ch2 == '=') return c_plusassign; // +=
287
+ --t->c;
288
+ return c_plus; // +
289
+ case '-':
290
+ if (ch2 == '=') return c_minusassign; // -=
291
+ if (ch2 == '>') return c_sliceto; // ->
292
+ --t->c;
293
+ return c_minus; // -
294
+ case '/':
295
+ if (ch2 == '/') return c_comment1; // //
296
+ if (ch2 == '*') return c_comment2; // /*
297
+ if (ch2 == '=') return c_divideassign; // /=
298
+ --t->c;
299
+ return c_divide; // /
300
+ case '<':
301
+ if (ch2 == '-') return c_slicefrom; // <-
302
+ if (ch2 == '=') return c_le; // <=
303
+ if (ch2 == '+') { // <+
304
+ fprintf(stderr,
305
+ "%s:%d: warning: `<+` is a legacy feature - "
306
+ "use `insert` instead\n",
307
+ t->file, t->line_number);
308
+ return c_insert;
309
+ }
310
+ --t->c;
311
+ return c_lt; // <
312
+ case '=':
313
+ if (ch2 == '=') return c_eq; // ==
314
+ if (ch2 == '>') return c_assignto; // =>
315
+ --t->c;
316
+ return c_assign; // =
317
+ case '>':
318
+ if (ch2 == '=') return c_ge; // >=
319
+ --t->c;
320
+ return c_gt; // >
321
+ case '?':
322
+ --t->c;
323
+ return c_debug; // ?
324
+ case '[':
325
+ --t->c;
326
+ return c_leftslice; // [
327
+ case ']':
328
+ --t->c;
329
+ return c_rightslice; // ]
266
330
  }
331
+
267
332
  error(t, "'", p + c, 1, "' unknown");
268
333
  c++;
269
334
  continue;
@@ -285,15 +350,13 @@ static int next_real_char(struct tokeniser * t) {
285
350
  static void read_chars(struct tokeniser * t) {
286
351
  int ch = next_real_char(t);
287
352
  if (ch < 0) { error2(t, "stringdef"); return; }
288
- {
289
- int c0 = t->c-1;
290
- while (true) {
291
- ch = next_char(t);
292
- if (white_space(t, ch) || ch < 0) break;
293
- }
294
- SIZE(t->s) = 0;
295
- t->s = add_s_to_s(t->s, (const char*)t->p + c0, t->c - c0 - 1);
353
+ int c0 = t->c-1;
354
+ while (true) {
355
+ ch = next_char(t);
356
+ if (white_space(t, ch) || ch < 0) break;
296
357
  }
358
+ SET_SIZE(t->s, 0);
359
+ t->s = add_slen_to_s(t->s, (const char*)t->p + c0, t->c - c0 - 1);
297
360
  }
298
361
 
299
362
  static int decimal_to_num(int ch) {
@@ -313,53 +376,53 @@ static void convert_numeric_string(struct tokeniser * t, symbol * p, int base) {
313
376
  while (true) {
314
377
  while (c < SIZE(p) && p[c] == ' ') c++;
315
378
  if (c == SIZE(p)) break;
316
- {
317
- int number = 0;
318
- while (c != SIZE(p)) {
319
- int ch = p[c];
320
- if (ch == ' ') break;
321
- if (base == 10) {
322
- ch = decimal_to_num(ch);
323
- if (ch < 0) {
324
- error1(t, "decimal string contains non-digits");
325
- return;
326
- }
327
- } else {
328
- ch = hex_to_num(ch);
329
- if (ch < 0) {
330
- error1(t, "hex string contains non-hex characters");
331
- return;
332
- }
333
- }
334
- number = base * number + ch;
335
- c++;
336
- }
337
- if (t->encoding == ENC_SINGLEBYTE) {
338
- if (number < 0 || number > 0xff) {
339
- error1(t, "character values exceed 256");
379
+
380
+ int number = 0;
381
+ while (c != SIZE(p)) {
382
+ int ch = p[c];
383
+ if (ch == ' ') break;
384
+ if (base == 10) {
385
+ ch = decimal_to_num(ch);
386
+ if (ch < 0) {
387
+ error1(t, "decimal string contains non-digits");
340
388
  return;
341
389
  }
342
390
  } else {
343
- if (number < 0 || number > 0xffff) {
344
- error1(t, "character values exceed 64K");
391
+ ch = hex_to_num(ch);
392
+ if (ch < 0) {
393
+ error1(t, "hex string contains non-hex characters");
345
394
  return;
346
395
  }
347
396
  }
348
- if (t->encoding == ENC_UTF8)
349
- d += put_utf8(number, p + d);
350
- else
351
- p[d++] = number;
397
+ number = base * number + ch;
398
+ c++;
352
399
  }
400
+ if (t->encoding == ENC_SINGLEBYTE) {
401
+ if (number < 0 || number > 0xff) {
402
+ error1(t, "character values exceed 256");
403
+ return;
404
+ }
405
+ } else {
406
+ if (number < 0 || number > 0xffff) {
407
+ error1(t, "character values exceed 64K");
408
+ return;
409
+ }
410
+ }
411
+ if (t->encoding == ENC_UTF8)
412
+ d += put_utf8(number, p + d);
413
+ else
414
+ p[d++] = number;
353
415
  }
354
- SIZE(p) = d;
416
+ SET_SIZE(p, d);
355
417
  }
356
418
 
357
419
  extern int read_token(struct tokeniser * t) {
358
- byte * p = t->p;
359
- int held = t->token_held;
360
- t->token_held = false;
361
- if (held) return t->token;
420
+ if (t->token_held) {
421
+ t->token_held = false;
422
+ return t->token;
423
+ }
362
424
  t->token_reported_as_unexpected = false;
425
+ byte * p = t->p;
363
426
  while (true) {
364
427
  int code = next_token(t);
365
428
  switch (code) {
@@ -407,83 +470,105 @@ extern int read_token(struct tokeniser * t) {
407
470
  int base = 0;
408
471
  read_chars(t);
409
472
  code = read_token(t);
410
- if (code == c_hex) { base = 16; code = read_token(t); } else
411
- if (code == c_decimal) { base = 10; code = read_token(t); }
473
+ if (code == c_hex) {
474
+ // We use `hex` to define U+xxxx stringdefs for single-byte
475
+ // character sets so suppress the warning there, e.g.:
476
+ //
477
+ // stringdef U+02D9 hex 'FF'
478
+ if (!(t->s[0] == 'U' && t->s[1] == '+')) {
479
+ fprintf(stderr,
480
+ "%s:%d: warning: `hex` is a legacy feature - "
481
+ "use {U+1234} notation instead\n",
482
+ t->file, t->line_number);
483
+ }
484
+ base = 16;
485
+ code = read_token(t);
486
+ } else if (code == c_decimal) {
487
+ fprintf(stderr,
488
+ "%s:%d: warning: `decimal` is a legacy feature - "
489
+ "use {U+1234} notation instead\n",
490
+ t->file, t->line_number);
491
+ base = 10;
492
+ code = read_token(t);
493
+ }
412
494
  if (code != c_literalstring) {
413
495
  error1(t, "string omitted after stringdef");
414
496
  continue;
415
497
  }
416
498
  if (base > 0) convert_numeric_string(t, t->b, base);
417
- { NEW(m_pair, q);
418
- q->next = t->m_pairs;
419
- q->name = copy_s(t->s);
420
- q->value = copy_b(t->b);
421
- t->m_pairs = q;
422
- if (t->uplusmode != UPLUS_DEFINED &&
423
- (SIZE(t->s) >= 3 && t->s[0] == 'U' && t->s[1] == '+')) {
424
- if (t->uplusmode == UPLUS_UNICODE) {
425
- error1(t, "U+xxxx already used with implicit meaning");
426
- } else {
427
- t->uplusmode = UPLUS_DEFINED;
428
- }
499
+
500
+ NEW(m_pair, q);
501
+ q->next = t->m_pairs;
502
+ q->name = copy_s(t->s);
503
+ q->value = copy_b(t->b);
504
+ t->m_pairs = q;
505
+ if (t->uplusmode != UPLUS_DEFINED &&
506
+ (SIZE(t->s) >= 3 && t->s[0] == 'U' && t->s[1] == '+')) {
507
+ if (t->uplusmode == UPLUS_UNICODE) {
508
+ error1(t, "U+xxxx already used with implicit meaning");
509
+ } else {
510
+ t->uplusmode = UPLUS_DEFINED;
429
511
  }
430
512
  }
431
513
  continue;
432
514
  }
433
- case c_get:
515
+ case c_get: {
434
516
  code = read_token(t);
435
517
  if (code != c_literalstring) {
436
- error1(t, "string omitted after get"); continue;
518
+ error1(t, "string omitted after get");
519
+ continue;
437
520
  }
438
521
  t->get_depth++;
439
522
  if (t->get_depth > 10) {
440
523
  error1(t, "get directives go 10 deep. Looping?");
441
524
  exit(1);
442
525
  }
443
- {
444
- NEW(input, q);
445
- char * file = b_to_sz(t->b);
446
- int file_owned = 1;
447
- byte * u = get_input(file);
448
- if (u == NULL) {
449
- struct include * r;
450
- for (r = t->includes; r; r = r->next) {
451
- byte * s = copy_s(r->s);
452
- s = add_sz_to_s(s, file);
453
- s[SIZE(s)] = 0;
454
- if (file_owned > 0) {
455
- free(file);
456
- } else {
457
- lose_s((byte *)file);
458
- }
459
- file = (char*)s;
460
- file_owned = -1;
461
- u = get_input(file);
462
- if (u != NULL) break;
526
+
527
+ NEW(input, q);
528
+ char * file = b_to_sz(t->b);
529
+ int file_owned = 1;
530
+ byte * u = get_input(file);
531
+ if (u == NULL) {
532
+ struct include * r;
533
+ for (r = t->includes; r; r = r->next) {
534
+ byte * s = copy_s(r->s);
535
+ s = add_sz_to_s(s, file);
536
+ s[SIZE(s)] = 0;
537
+ if (file_owned > 0) {
538
+ free(file);
539
+ } else {
540
+ lose_s((byte *)file);
463
541
  }
542
+ file = (char*)s;
543
+ file_owned = -1;
544
+ u = get_input(file);
545
+ if (u != NULL) break;
464
546
  }
465
- if (u == NULL) {
466
- error(t, "Can't get '", (byte *)file, strlen(file), "'");
467
- exit(1);
468
- }
469
- memmove(q, t, sizeof(struct input));
470
- t->next = q;
471
- t->p = u;
472
- t->c = 0;
473
- t->file = file;
474
- t->file_owned = file_owned;
475
- t->line_number = 1;
476
547
  }
548
+ if (u == NULL) {
549
+ error(t, "Can't get '", (byte *)file, strlen(file), "'");
550
+ exit(1);
551
+ }
552
+ memmove(q, t, sizeof(struct input));
553
+ t->next = q;
554
+ t->p = u;
555
+ t->c = 0;
556
+ t->file = file;
557
+ t->file_owned = file_owned;
558
+ t->line_number = 1;
559
+
477
560
  p = t->p;
478
561
  continue;
562
+ }
479
563
  case -1:
480
564
  if (t->next) {
481
565
  lose_s(p);
482
- {
483
- struct input * q = t->next;
484
- memmove(t, q, sizeof(struct input)); p = t->p;
485
- FREE(q);
486
- }
566
+
567
+ struct input * q = t->next;
568
+ memmove(t, q, sizeof(struct input));
569
+ p = t->p;
570
+ FREE(q);
571
+
487
572
  t->get_depth--;
488
573
  continue;
489
574
  }
@@ -503,28 +588,55 @@ extern int peek_token(struct tokeniser * t) {
503
588
  }
504
589
 
505
590
  extern const char * name_of_token(int code) {
506
- int i;
507
- for (i = 1; i < vocab->code; i++)
508
- if ((vocab + i)->code == code) return (const char *)(vocab + i)->s;
591
+ for (int i = 0; i < NUM_ALPHA_TOKENS; i++) {
592
+ if (alpha_tokens[i].code == code)
593
+ return alpha_tokens[i].s;
594
+ }
509
595
  switch (code) {
510
- case c_mathassign: return "=";
511
- case c_name: return "name";
512
- case c_number: return "number";
513
- case c_literalstring:return "literal";
514
- case c_neg: return "neg";
515
- case c_grouping: return "grouping";
516
- case c_call: return "call";
517
- case c_booltest: return "Boolean test";
518
- case c_functionend: return "Function end";
519
- case c_goto_grouping:
520
- return "goto grouping";
521
- case c_gopast_grouping:
522
- return "gopast grouping";
523
- case c_goto_non: return "goto non";
524
- case c_gopast_non: return "gopast non";
525
- case -2: return "start of text";
526
- case -1: return "end of text";
527
- default: return "?";
596
+ case c_dollar: return "$";
597
+ case c_bra: return "(";
598
+ case c_ket: return ")";
599
+ case c_multiply: return "*";
600
+ case c_plus: return "+";
601
+ case c_minus: return "-";
602
+ case c_divide: return "/";
603
+ case c_lt: return "<";
604
+ case c_stringassign:
605
+ case c_assign: return "=";
606
+ case c_gt: return ">";
607
+ case c_debug: return "?";
608
+ case c_leftslice: return "[";
609
+ case c_rightslice: return "]";
610
+ case c_ne: return "!=";
611
+ case c_multiplyassign: return "*=";
612
+ case c_plusassign: return "+=";
613
+ case c_minusassign: return "-=";
614
+ case c_sliceto: return "->";
615
+ case c_comment2: return "/*";
616
+ case c_comment1: return "//";
617
+ case c_divideassign: return "/=";
618
+ case c_insert: return "<+";
619
+ case c_slicefrom: return "<-";
620
+ case c_le: return "<=";
621
+ case c_eq: return "==";
622
+ case c_assignto: return "=>";
623
+ case c_ge: return ">=";
624
+ case c_name: return "name";
625
+ case c_number: return "number";
626
+ case c_literalstring: return "literal";
627
+ case c_neg: return "neg";
628
+ case c_grouping: return "grouping";
629
+ case c_call: return "call";
630
+ case c_booltest: return "Boolean test";
631
+ case c_functionend: return "Function end";
632
+ case c_goto_grouping: return "goto grouping";
633
+ case c_gopast_grouping: return "gopast grouping";
634
+ case c_goto_non: return "goto non";
635
+ case c_gopast_non: return "gopast non";
636
+ case c_not_booltest: return "Inverted boolean test";
637
+ case -2: return "start of text";
638
+ case -1: return "end of text";
639
+ default: return "?";
528
640
  }
529
641
  }
530
642
 
@@ -534,24 +646,16 @@ extern void disable_token(struct tokeniser * t, int code) {
534
646
 
535
647
  extern struct tokeniser * create_tokeniser(byte * p, char * file) {
536
648
  NEW(tokeniser, t);
537
- t->next = NULL;
649
+ *t = (struct tokeniser){0};
538
650
  t->p = p;
539
- t->c = 0;
540
651
  t->file = file;
541
- t->file_owned = 0;
542
652
  t->line_number = 1;
543
653
  t->b = create_b(0);
544
654
  t->s = create_s(0);
545
655
  t->m_start = -1;
546
- t->m_pairs = NULL;
547
- t->get_depth = 0;
548
- t->error_count = 0;
549
- t->token_held = false;
550
- t->token_reported_as_unexpected = false;
551
656
  t->token = -2;
552
657
  t->previous_token = -2;
553
658
  t->uplusmode = UPLUS_NONE;
554
- memset(t->token_disabled, 0, sizeof(t->token_disabled));
555
659
  return t;
556
660
  }
557
661