mittens 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/lib/mittens/version.rb +1 -1
- data/mittens.gemspec +1 -1
- data/vendor/snowball/.github/workflows/ci.yml +216 -0
- data/vendor/snowball/CONTRIBUTING.rst +111 -62
- data/vendor/snowball/GNUmakefile +194 -136
- data/vendor/snowball/NEWS +798 -3
- data/vendor/snowball/README.rst +50 -1
- data/vendor/snowball/ada/src/stemmer.adb +25 -13
- data/vendor/snowball/ada/src/stemmer.ads +9 -9
- data/vendor/snowball/ada/stemmer_config.gpr +7 -7
- data/vendor/snowball/algorithms/basque.sbl +4 -19
- data/vendor/snowball/algorithms/catalan.sbl +2 -9
- data/vendor/snowball/algorithms/danish.sbl +1 -1
- data/vendor/snowball/algorithms/dutch.sbl +284 -122
- data/vendor/snowball/algorithms/dutch_porter.sbl +178 -0
- data/vendor/snowball/algorithms/english.sbl +52 -37
- data/vendor/snowball/algorithms/esperanto.sbl +157 -0
- data/vendor/snowball/algorithms/estonian.sbl +269 -0
- data/vendor/snowball/algorithms/finnish.sbl +2 -3
- data/vendor/snowball/algorithms/french.sbl +42 -16
- data/vendor/snowball/algorithms/german.sbl +35 -14
- data/vendor/snowball/algorithms/greek.sbl +76 -76
- data/vendor/snowball/algorithms/hungarian.sbl +8 -6
- data/vendor/snowball/algorithms/indonesian.sbl +14 -8
- data/vendor/snowball/algorithms/italian.sbl +11 -21
- data/vendor/snowball/algorithms/lithuanian.sbl +36 -37
- data/vendor/snowball/algorithms/lovins.sbl +0 -1
- data/vendor/snowball/algorithms/nepali.sbl +138 -37
- data/vendor/snowball/algorithms/norwegian.sbl +19 -5
- data/vendor/snowball/algorithms/porter.sbl +2 -2
- data/vendor/snowball/algorithms/portuguese.sbl +9 -13
- data/vendor/snowball/algorithms/romanian.sbl +17 -4
- data/vendor/snowball/algorithms/serbian.sbl +467 -468
- data/vendor/snowball/algorithms/spanish.sbl +5 -7
- data/vendor/snowball/algorithms/swedish.sbl +60 -6
- data/vendor/snowball/algorithms/tamil.sbl +207 -176
- data/vendor/snowball/algorithms/turkish.sbl +461 -445
- data/vendor/snowball/algorithms/yiddish.sbl +36 -38
- data/vendor/snowball/compiler/analyser.c +445 -192
- data/vendor/snowball/compiler/driver.c +109 -101
- data/vendor/snowball/compiler/generator.c +853 -464
- data/vendor/snowball/compiler/generator_ada.c +404 -366
- data/vendor/snowball/compiler/generator_csharp.c +297 -260
- data/vendor/snowball/compiler/generator_go.c +323 -254
- data/vendor/snowball/compiler/generator_java.c +326 -252
- data/vendor/snowball/compiler/generator_js.c +362 -252
- data/vendor/snowball/compiler/generator_pascal.c +349 -197
- data/vendor/snowball/compiler/generator_python.c +257 -240
- data/vendor/snowball/compiler/generator_rust.c +423 -251
- data/vendor/snowball/compiler/header.h +117 -71
- data/vendor/snowball/compiler/space.c +137 -68
- data/vendor/snowball/compiler/syswords.h +2 -2
- data/vendor/snowball/compiler/tokeniser.c +125 -107
- data/vendor/snowball/csharp/Snowball/Among.cs +14 -14
- data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +7 -7
- data/vendor/snowball/csharp/Snowball/Stemmer.cs +57 -37
- data/vendor/snowball/csharp/Stemwords/App.config +2 -2
- data/vendor/snowball/csharp/Stemwords/Program.cs +16 -12
- data/vendor/snowball/doc/libstemmer_c_README +7 -4
- data/vendor/snowball/doc/libstemmer_csharp_README +4 -1
- data/vendor/snowball/doc/libstemmer_java_README +12 -1
- data/vendor/snowball/doc/libstemmer_js_README +6 -4
- data/vendor/snowball/doc/libstemmer_python_README +9 -4
- data/vendor/snowball/examples/stemwords.c +12 -12
- data/vendor/snowball/go/env.go +107 -31
- data/vendor/snowball/go/util.go +0 -4
- data/vendor/snowball/include/libstemmer.h +4 -0
- data/vendor/snowball/java/org/tartarus/snowball/Among.java +32 -15
- data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +347 -261
- data/vendor/snowball/java/org/tartarus/snowball/SnowballStemmer.java +3 -0
- data/vendor/snowball/java/org/tartarus/snowball/TestApp.java +52 -37
- data/vendor/snowball/javascript/base-stemmer.js +186 -2
- data/vendor/snowball/javascript/stemwords.js +3 -6
- data/vendor/snowball/libstemmer/libstemmer_c.in +1 -1
- data/vendor/snowball/libstemmer/mkalgorithms.pl +6 -6
- data/vendor/snowball/libstemmer/mkmodules.pl +2 -2
- data/vendor/snowball/libstemmer/modules.txt +13 -10
- data/vendor/snowball/libstemmer/test.c +1 -1
- data/vendor/snowball/pascal/SnowballProgram.pas +84 -2
- data/vendor/snowball/pascal/generate.pl +13 -13
- data/vendor/snowball/python/create_init.py +4 -1
- data/vendor/snowball/python/setup.cfg +0 -3
- data/vendor/snowball/python/setup.py +8 -3
- data/vendor/snowball/python/snowballstemmer/basestemmer.py +20 -54
- data/vendor/snowball/python/stemwords.py +8 -12
- data/vendor/snowball/runtime/api.c +10 -5
- data/vendor/snowball/runtime/header.h +10 -9
- data/vendor/snowball/runtime/utilities.c +9 -9
- data/vendor/snowball/rust/build.rs +1 -1
- data/vendor/snowball/rust/src/snowball/snowball_env.rs +83 -5
- data/vendor/snowball/tests/stemtest.c +7 -4
- metadata +8 -12
- data/vendor/snowball/.travis.yml +0 -112
- data/vendor/snowball/algorithms/german2.sbl +0 -145
- data/vendor/snowball/algorithms/kraaij_pohlmann.sbl +0 -240
- data/vendor/snowball/compiler/syswords2.h +0 -13
@@ -1,3 +1,4 @@
|
|
1
|
+
#include <assert.h>
|
1
2
|
#include <stdlib.h> /* for exit */
|
2
3
|
#include <string.h> /* for strlen */
|
3
4
|
#include <stdio.h> /* for fprintf etc */
|
@@ -17,7 +18,6 @@ static int new_label(struct generator * g) {
|
|
17
18
|
}
|
18
19
|
|
19
20
|
static struct str * vars_newname(struct generator * g) {
|
20
|
-
|
21
21
|
struct str * output;
|
22
22
|
g->var_number++;
|
23
23
|
output = str_new();
|
@@ -29,7 +29,6 @@ static struct str * vars_newname(struct generator * g) {
|
|
29
29
|
/* Write routines for items from the syntax tree */
|
30
30
|
|
31
31
|
static void write_varname(struct generator * g, struct name * p) {
|
32
|
-
|
33
32
|
if (p->type != t_external) {
|
34
33
|
/* Pascal identifiers are case-insensitive but Snowball identifiers
|
35
34
|
* should be case-sensitive. To address this, we encode the case of
|
@@ -55,11 +54,11 @@ static void write_varname(struct generator * g, struct name * p) {
|
|
55
54
|
* program authors to avoid naming externals which only differ by
|
56
55
|
* case.
|
57
56
|
*/
|
58
|
-
int
|
57
|
+
int len = SIZE(p->s);
|
59
58
|
int lower_pending = 0;
|
60
59
|
write_char(g, "SBIrxg"[p->type]);
|
61
|
-
for (i = 0; i != len; ++i) {
|
62
|
-
int ch = p->
|
60
|
+
for (int i = 0; i != len; ++i) {
|
61
|
+
int ch = p->s[i];
|
63
62
|
if (ch >= 'a' && ch <= 'z') {
|
64
63
|
++lower_pending;
|
65
64
|
} else if (ch >= 'A' && ch <= 'Z') {
|
@@ -73,13 +72,12 @@ static void write_varname(struct generator * g, struct name * p) {
|
|
73
72
|
|
74
73
|
write_char(g, '_');
|
75
74
|
}
|
76
|
-
|
75
|
+
write_s(g, p->s);
|
77
76
|
}
|
78
77
|
|
79
78
|
static void write_literal_string(struct generator * g, symbol * p) {
|
80
|
-
int i;
|
81
79
|
write_char(g, '\'');
|
82
|
-
for (i = 0; i < SIZE(p); i++) {
|
80
|
+
for (int i = 0; i < SIZE(p); i++) {
|
83
81
|
int ch = p[i];
|
84
82
|
if (ch == '\'') {
|
85
83
|
write_string(g, "''");
|
@@ -96,13 +94,26 @@ static void write_literal_string(struct generator * g, symbol * p) {
|
|
96
94
|
}
|
97
95
|
|
98
96
|
static void write_margin(struct generator * g) {
|
99
|
-
int i;
|
100
|
-
|
97
|
+
for (int i = 0; i < g->margin; i++) write_string(g, " ");
|
98
|
+
}
|
99
|
+
|
100
|
+
static void write_relop(struct generator * g, int relop) {
|
101
|
+
switch (relop) {
|
102
|
+
case c_eq: write_string(g, " = "); break;
|
103
|
+
case c_ne: write_string(g, " <> "); break;
|
104
|
+
case c_gt: write_string(g, " > "); break;
|
105
|
+
case c_ge: write_string(g, " >= "); break;
|
106
|
+
case c_lt: write_string(g, " < "); break;
|
107
|
+
case c_le: write_string(g, " <= "); break;
|
108
|
+
default:
|
109
|
+
fprintf(stderr, "Unexpected type #%d in generate_integer_test\n", relop);
|
110
|
+
exit(1);
|
111
|
+
}
|
101
112
|
}
|
102
113
|
|
103
114
|
/* Write a variable declaration. */
|
104
115
|
static void write_declare(struct generator * g,
|
105
|
-
char * declaration,
|
116
|
+
const char * declaration,
|
106
117
|
struct node * p) {
|
107
118
|
struct str * temp = g->outbuf;
|
108
119
|
g->outbuf = g->declarations;
|
@@ -126,7 +137,7 @@ static void write_block_start(struct generator * g) {
|
|
126
137
|
w(g, "~MBegin~+~N");
|
127
138
|
}
|
128
139
|
|
129
|
-
static void write_block_end(struct generator * g) {
|
140
|
+
static void write_block_end(struct generator * g) {
|
130
141
|
w(g, "~-~MEnd;~N");
|
131
142
|
}
|
132
143
|
|
@@ -139,22 +150,17 @@ static void write_savecursor(struct generator * g, struct node * p,
|
|
139
150
|
writef(g, "~M~B0 := ~S1FCursor;~N" , p);
|
140
151
|
}
|
141
152
|
|
142
|
-
static void
|
143
|
-
str_clear(out);
|
153
|
+
static void append_restore_string(struct node * p, struct str * out, struct str * savevar) {
|
144
154
|
str_append_string(out, "FCursor := ");
|
145
155
|
if (p->mode != m_forward) str_append_string(out, "FLimit - ");
|
146
156
|
str_append(out, savevar);
|
147
157
|
str_append_string(out, ";");
|
148
158
|
}
|
149
159
|
|
150
|
-
static void write_restorecursor(struct generator * g, struct node * p,
|
151
|
-
struct str * savevar) {
|
152
|
-
struct str * temp = str_new();
|
160
|
+
static void write_restorecursor(struct generator * g, struct node * p, struct str * savevar) {
|
153
161
|
write_margin(g);
|
154
|
-
|
155
|
-
write_str(g, temp);
|
162
|
+
append_restore_string(p, g->outbuf, savevar);
|
156
163
|
write_newline(g);
|
157
|
-
str_delete(temp);
|
158
164
|
}
|
159
165
|
|
160
166
|
static void write_inc_cursor(struct generator * g, struct node * p) {
|
@@ -192,18 +198,18 @@ static void write_failure(struct generator * g) {
|
|
192
198
|
switch (g->failure_label) {
|
193
199
|
case x_return:
|
194
200
|
write_string(g, "Begin Result := False; Exit; End;");
|
201
|
+
g->unreachable = true;
|
195
202
|
break;
|
196
203
|
default:
|
197
204
|
write_string(g, "goto lab");
|
198
205
|
write_int(g, g->failure_label);
|
199
206
|
write_string(g, ";");
|
207
|
+
g->unreachable = true;
|
200
208
|
}
|
201
209
|
write_newline(g);
|
202
|
-
g->unreachable = true;
|
203
210
|
}
|
204
211
|
|
205
|
-
static void write_failure_if(struct generator * g, char * s, struct node * p) {
|
206
|
-
|
212
|
+
static void write_failure_if(struct generator * g, const char * s, struct node * p) {
|
207
213
|
writef(g, "~MIf (", p);
|
208
214
|
writef(g, s, p);
|
209
215
|
writef(g, ") Then~N", p);
|
@@ -224,18 +230,18 @@ static void write_check_limit(struct generator * g, struct node * p) {
|
|
224
230
|
|
225
231
|
/* Formatted write. */
|
226
232
|
static void writef(struct generator * g, const char * input, struct node * p) {
|
233
|
+
(void)p;
|
227
234
|
int i = 0;
|
228
|
-
int l = strlen(input);
|
229
235
|
|
230
|
-
while (i
|
236
|
+
while (input[i]) {
|
231
237
|
int ch = input[i++];
|
232
238
|
if (ch != '~') {
|
233
239
|
write_char(g, ch);
|
234
240
|
continue;
|
235
241
|
}
|
236
|
-
|
237
|
-
|
238
|
-
case '
|
242
|
+
ch = input[i++];
|
243
|
+
switch (ch) {
|
244
|
+
case '~': write_char(g, '~'); continue;
|
239
245
|
case 'f': write_block_start(g);
|
240
246
|
write_failure(g);
|
241
247
|
g->unreachable = false;
|
@@ -245,21 +251,62 @@ static void writef(struct generator * g, const char * input, struct node * p) {
|
|
245
251
|
case 'N': write_newline(g); continue;
|
246
252
|
case '{': write_block_start(g); continue;
|
247
253
|
case '}': write_block_end(g); continue;
|
248
|
-
case 'S':
|
249
|
-
|
250
|
-
|
254
|
+
case 'S': {
|
255
|
+
int j = input[i++] - '0';
|
256
|
+
if (j < 0 || j > (int)(sizeof(g->S) / sizeof(g->S[0]))) {
|
257
|
+
printf("Invalid escape sequence ~%c%c in writef(g, \"%s\", p)\n",
|
258
|
+
ch, input[i - 1], input);
|
259
|
+
exit(1);
|
260
|
+
}
|
261
|
+
write_string(g, g->S[j]);
|
262
|
+
continue;
|
263
|
+
}
|
264
|
+
case 'B': {
|
265
|
+
int j = input[i++] - '0';
|
266
|
+
if (j < 0 || j > (int)(sizeof(g->B) / sizeof(g->B[0])))
|
267
|
+
goto invalid_escape2;
|
268
|
+
write_s(g, g->B[j]);
|
269
|
+
continue;
|
270
|
+
}
|
271
|
+
case 'I': {
|
272
|
+
int j = input[i++] - '0';
|
273
|
+
if (j < 0 || j > (int)(sizeof(g->I) / sizeof(g->I[0])))
|
274
|
+
goto invalid_escape2;
|
275
|
+
write_int(g, g->I[j]);
|
276
|
+
continue;
|
277
|
+
}
|
251
278
|
case 'V':
|
252
|
-
case 'W':
|
253
|
-
|
279
|
+
case 'W': {
|
280
|
+
int j = input[i++] - '0';
|
281
|
+
if (j < 0 || j > (int)(sizeof(g->V) / sizeof(g->V[0])))
|
282
|
+
goto invalid_escape2;
|
283
|
+
write_varname(g, g->V[j]);
|
284
|
+
continue;
|
285
|
+
}
|
286
|
+
case 'L': {
|
287
|
+
int j = input[i++] - '0';
|
288
|
+
if (j < 0 || j > (int)(sizeof(g->L) / sizeof(g->L[0])))
|
289
|
+
goto invalid_escape2;
|
290
|
+
write_literal_string(g, g->L[j]);
|
291
|
+
continue;
|
292
|
+
}
|
254
293
|
case '+': g->margin++; continue;
|
255
294
|
case '-': g->margin--; continue;
|
256
295
|
case 'n': write_string(g, g->options->name); continue;
|
296
|
+
default:
|
297
|
+
printf("Invalid escape sequence ~%c in writef(g, \"%s\", p)\n",
|
298
|
+
ch, input);
|
299
|
+
exit(1);
|
300
|
+
invalid_escape2:
|
301
|
+
printf("Invalid escape sequence ~%c%c in writef(g, \"%s\", p)\n",
|
302
|
+
ch, input[i - 1], input);
|
303
|
+
exit(1);
|
257
304
|
}
|
258
305
|
}
|
259
306
|
}
|
260
307
|
|
261
308
|
static void w(struct generator * g, const char * s) {
|
262
|
-
writef(g, s,
|
309
|
+
writef(g, s, NULL);
|
263
310
|
}
|
264
311
|
|
265
312
|
static void generate_AE(struct generator * g, struct node * p) {
|
@@ -312,26 +359,33 @@ static void generate_bra(struct generator * g, struct node * p) {
|
|
312
359
|
}
|
313
360
|
|
314
361
|
static void generate_and(struct generator * g, struct node * p) {
|
315
|
-
struct str * savevar =
|
316
|
-
|
362
|
+
struct str * savevar = NULL;
|
363
|
+
if (K_needed(g, p->left)) {
|
364
|
+
savevar = vars_newname(g);
|
365
|
+
}
|
317
366
|
|
318
367
|
write_comment(g, p);
|
319
368
|
|
320
|
-
if (
|
369
|
+
if (savevar) write_savecursor(g, p, savevar);
|
321
370
|
|
322
371
|
p = p->left;
|
323
372
|
while (p) {
|
324
373
|
generate(g, p);
|
325
374
|
if (g->unreachable) break;
|
326
|
-
if (
|
375
|
+
if (savevar && p->right != NULL) write_restorecursor(g, p, savevar);
|
327
376
|
p = p->right;
|
328
377
|
}
|
329
|
-
|
378
|
+
|
379
|
+
if (savevar) {
|
380
|
+
str_delete(savevar);
|
381
|
+
}
|
330
382
|
}
|
331
383
|
|
332
384
|
static void generate_or(struct generator * g, struct node * p) {
|
333
|
-
struct str * savevar =
|
334
|
-
|
385
|
+
struct str * savevar = NULL;
|
386
|
+
if (K_needed(g, p->left)) {
|
387
|
+
savevar = vars_newname(g);
|
388
|
+
}
|
335
389
|
|
336
390
|
int a0 = g->failure_label;
|
337
391
|
struct str * a1 = str_copy(g->failure_str);
|
@@ -342,13 +396,13 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
342
396
|
write_comment(g, p);
|
343
397
|
wsetlab_begin(g);
|
344
398
|
|
345
|
-
if (
|
399
|
+
if (savevar) write_savecursor(g, p, savevar);
|
346
400
|
|
347
401
|
p = p->left;
|
348
402
|
str_clear(g->failure_str);
|
349
403
|
|
350
|
-
if (p ==
|
351
|
-
/* p should never be
|
404
|
+
if (p == NULL) {
|
405
|
+
/* p should never be NULL after an or: there should be at least two
|
352
406
|
* sub nodes. */
|
353
407
|
fprintf(stderr, "Error: \"or\" node without children nodes.");
|
354
408
|
exit(1);
|
@@ -363,7 +417,7 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
363
417
|
}
|
364
418
|
wsetlab_end(g, g->failure_label);
|
365
419
|
g->unreachable = false;
|
366
|
-
if (
|
420
|
+
if (savevar) write_restorecursor(g, p, savevar);
|
367
421
|
p = p->right;
|
368
422
|
}
|
369
423
|
|
@@ -376,7 +430,10 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
376
430
|
if (!end_unreachable) {
|
377
431
|
g->unreachable = false;
|
378
432
|
}
|
379
|
-
|
433
|
+
|
434
|
+
if (savevar) {
|
435
|
+
str_delete(savevar);
|
436
|
+
}
|
380
437
|
}
|
381
438
|
|
382
439
|
static void generate_backwards(struct generator * g, struct node * p) {
|
@@ -388,14 +445,16 @@ static void generate_backwards(struct generator * g, struct node * p) {
|
|
388
445
|
|
389
446
|
|
390
447
|
static void generate_not(struct generator * g, struct node * p) {
|
391
|
-
struct str * savevar =
|
392
|
-
|
448
|
+
struct str * savevar = NULL;
|
449
|
+
if (K_needed(g, p->left)) {
|
450
|
+
savevar = vars_newname(g);
|
451
|
+
}
|
393
452
|
|
394
|
-
int a0 = g->failure_label
|
453
|
+
int a0 = g->failure_label;
|
395
454
|
struct str * a1 = str_copy(g->failure_str);
|
396
455
|
|
397
456
|
write_comment(g, p);
|
398
|
-
if (
|
457
|
+
if (savevar) {
|
399
458
|
write_block_start(g);
|
400
459
|
write_savecursor(g, p, savevar);
|
401
460
|
}
|
@@ -404,7 +463,7 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
404
463
|
str_clear(g->failure_str);
|
405
464
|
|
406
465
|
wsetlab_begin(g);
|
407
|
-
l = g->failure_label;
|
466
|
+
int l = g->failure_label;
|
408
467
|
|
409
468
|
generate(g, p->left);
|
410
469
|
|
@@ -417,29 +476,37 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
417
476
|
wsetlab_end(g, l);
|
418
477
|
g->unreachable = false;
|
419
478
|
|
420
|
-
if (
|
421
|
-
|
422
|
-
|
479
|
+
if (savevar) {
|
480
|
+
write_restorecursor(g, p, savevar);
|
481
|
+
write_block_end(g);
|
482
|
+
str_delete(savevar);
|
483
|
+
}
|
423
484
|
}
|
424
485
|
|
425
486
|
|
426
487
|
static void generate_try(struct generator * g, struct node * p) {
|
427
|
-
struct str * savevar =
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
if (keep_c) write_savecursor(g, p, savevar);
|
488
|
+
struct str * savevar = NULL;
|
489
|
+
if (K_needed(g, p->left)) {
|
490
|
+
savevar = vars_newname(g);
|
491
|
+
}
|
432
492
|
|
433
493
|
g->failure_label = new_label(g);
|
434
494
|
str_clear(g->failure_str);
|
435
|
-
|
495
|
+
|
496
|
+
write_comment(g, p);
|
497
|
+
if (savevar) {
|
498
|
+
write_savecursor(g, p, savevar);
|
499
|
+
append_restore_string(p, g->failure_str, savevar);
|
500
|
+
}
|
436
501
|
|
437
502
|
wsetlab_begin(g);
|
438
503
|
generate(g, p->left);
|
439
504
|
wsetlab_end(g, g->failure_label);
|
440
505
|
g->unreachable = false;
|
441
506
|
|
442
|
-
|
507
|
+
if (savevar) {
|
508
|
+
str_delete(savevar);
|
509
|
+
}
|
443
510
|
}
|
444
511
|
|
445
512
|
static void generate_set(struct generator * g, struct node * p) {
|
@@ -463,30 +530,35 @@ static void generate_fail(struct generator * g, struct node * p) {
|
|
463
530
|
/* generate_test() also implements 'reverse' */
|
464
531
|
|
465
532
|
static void generate_test(struct generator * g, struct node * p) {
|
466
|
-
struct str * savevar =
|
467
|
-
|
533
|
+
struct str * savevar = NULL;
|
534
|
+
if (K_needed(g, p->left)) {
|
535
|
+
savevar = vars_newname(g);
|
536
|
+
}
|
468
537
|
|
469
538
|
write_comment(g, p);
|
470
539
|
|
471
|
-
if (
|
540
|
+
if (savevar) {
|
472
541
|
write_savecursor(g, p, savevar);
|
473
542
|
}
|
474
543
|
|
475
544
|
generate(g, p->left);
|
476
545
|
|
477
|
-
if (
|
478
|
-
if (
|
546
|
+
if (savevar) {
|
547
|
+
if (!g->unreachable) {
|
479
548
|
write_restorecursor(g, p, savevar);
|
480
549
|
}
|
550
|
+
str_delete(savevar);
|
481
551
|
}
|
482
|
-
str_delete(savevar);
|
483
552
|
}
|
484
553
|
|
485
554
|
static void generate_do(struct generator * g, struct node * p) {
|
486
|
-
struct str * savevar =
|
487
|
-
|
555
|
+
struct str * savevar = NULL;
|
556
|
+
if (K_needed(g, p->left)) {
|
557
|
+
savevar = vars_newname(g);
|
558
|
+
}
|
559
|
+
|
488
560
|
write_comment(g, p);
|
489
|
-
if (
|
561
|
+
if (savevar) write_savecursor(g, p, savevar);
|
490
562
|
|
491
563
|
if (p->left->type == c_call) {
|
492
564
|
/* Optimise do <call> */
|
@@ -503,24 +575,51 @@ static void generate_do(struct generator * g, struct node * p) {
|
|
503
575
|
g->unreachable = false;
|
504
576
|
}
|
505
577
|
|
506
|
-
if (
|
507
|
-
|
578
|
+
if (savevar) {
|
579
|
+
write_restorecursor(g, p, savevar);
|
580
|
+
str_delete(savevar);
|
581
|
+
}
|
582
|
+
}
|
583
|
+
|
584
|
+
static void generate_next(struct generator * g, struct node * p) {
|
585
|
+
write_comment(g, p);
|
586
|
+
write_check_limit(g, p);
|
587
|
+
write_inc_cursor(g, p);
|
588
|
+
}
|
589
|
+
|
590
|
+
static void generate_GO_grouping(struct generator * g, struct node * p, int is_goto, int complement) {
|
591
|
+
write_comment(g, p);
|
592
|
+
|
593
|
+
struct grouping * q = p->name->grouping;
|
594
|
+
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
595
|
+
g->S[1] = complement ? "In" : "Out";
|
596
|
+
g->V[0] = p->name;
|
597
|
+
g->I[0] = q->smallest_ch;
|
598
|
+
g->I[1] = q->largest_ch;
|
599
|
+
write_failure_if(g, "Not (Go~S1Grouping~S0(~V0, ~I0, ~I1))", p);
|
600
|
+
if (!is_goto) {
|
601
|
+
write_string(g, p->mode == m_forward ? "Inc(FCursor);" : "Dec(FCursor);");
|
602
|
+
}
|
508
603
|
}
|
509
604
|
|
510
605
|
static void generate_GO(struct generator * g, struct node * p, int style) {
|
511
|
-
|
512
|
-
|
513
|
-
int keep_c = style == 1 || repeat_restore(g, p->left);
|
606
|
+
write_comment(g, p);
|
607
|
+
|
514
608
|
int a0 = g->failure_label;
|
515
609
|
struct str * a1 = str_copy(g->failure_str);
|
516
610
|
|
611
|
+
int end_unreachable = false;
|
612
|
+
|
517
613
|
int golab = new_label(g);
|
518
614
|
|
519
|
-
write_comment(g, p);
|
520
615
|
w(g, "~MWhile True Do~N");
|
521
616
|
w(g, "~{");
|
522
617
|
|
523
|
-
|
618
|
+
struct str * savevar = NULL;
|
619
|
+
if (style == 1 || repeat_restore(g, p->left)) {
|
620
|
+
savevar = vars_newname(g);
|
621
|
+
write_savecursor(g, p, savevar);
|
622
|
+
}
|
524
623
|
|
525
624
|
g->failure_label = new_label(g);
|
526
625
|
str_clear(g->failure_str);
|
@@ -539,7 +638,10 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
539
638
|
}
|
540
639
|
g->unreachable = false;
|
541
640
|
wsetlab_end(g, g->failure_label);
|
542
|
-
if (
|
641
|
+
if (savevar) {
|
642
|
+
write_restorecursor(g, p, savevar);
|
643
|
+
str_delete(savevar);
|
644
|
+
}
|
543
645
|
|
544
646
|
g->failure_label = a0;
|
545
647
|
str_delete(g->failure_str);
|
@@ -550,7 +652,6 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
550
652
|
|
551
653
|
g->I[0] = golab;
|
552
654
|
w(g, "~}lab~I0:~N");
|
553
|
-
str_delete(savevar);
|
554
655
|
g->unreachable = end_unreachable;
|
555
656
|
}
|
556
657
|
|
@@ -572,13 +673,15 @@ static void generate_loop(struct generator * g, struct node * p) {
|
|
572
673
|
}
|
573
674
|
|
574
675
|
static void generate_repeat_or_atleast(struct generator * g, struct node * p, struct str * loopvar) {
|
575
|
-
struct str * savevar = vars_newname(g);
|
576
|
-
int keep_c = repeat_restore(g, p->left);
|
577
676
|
int replab = new_label(g);
|
578
677
|
g->I[0] = replab;
|
579
678
|
writef(g, "lab~I0:~N~MWhile True Do~N~{", p);
|
580
679
|
|
581
|
-
|
680
|
+
struct str * savevar = NULL;
|
681
|
+
if (repeat_restore(g, p->left)) {
|
682
|
+
savevar = vars_newname(g);
|
683
|
+
write_savecursor(g, p, savevar);
|
684
|
+
}
|
582
685
|
|
583
686
|
g->failure_label = new_label(g);
|
584
687
|
str_clear(g->failure_str);
|
@@ -586,7 +689,7 @@ static void generate_repeat_or_atleast(struct generator * g, struct node * p, st
|
|
586
689
|
generate(g, p->left);
|
587
690
|
|
588
691
|
if (!g->unreachable) {
|
589
|
-
if (loopvar !=
|
692
|
+
if (loopvar != NULL) {
|
590
693
|
g->B[0] = str_data(loopvar);
|
591
694
|
w(g, "~MDec(~B0);~N");
|
592
695
|
}
|
@@ -598,10 +701,12 @@ static void generate_repeat_or_atleast(struct generator * g, struct node * p, st
|
|
598
701
|
wsetlab_end(g, g->failure_label);
|
599
702
|
g->unreachable = false;
|
600
703
|
|
601
|
-
if (
|
704
|
+
if (savevar) {
|
705
|
+
write_restorecursor(g, p, savevar);
|
706
|
+
str_delete(savevar);
|
707
|
+
}
|
602
708
|
|
603
709
|
w(g, "~MBreak;~N~}");
|
604
|
-
str_delete(savevar);
|
605
710
|
}
|
606
711
|
|
607
712
|
static void generate_repeat(struct generator * g, struct node * p) {
|
@@ -615,7 +720,6 @@ static void generate_atleast(struct generator * g, struct node * p) {
|
|
615
720
|
write_comment(g, p);
|
616
721
|
w(g, "~{");
|
617
722
|
g->B[0] = str_data(loopvar);
|
618
|
-
|
619
723
|
write_declare(g, "~B0 : Integer", p);
|
620
724
|
w(g, "~M~B0 := ");
|
621
725
|
generate_AE(g, p->AE);
|
@@ -683,8 +787,8 @@ static void generate_hop(struct generator * g, struct node * p) {
|
|
683
787
|
write_failure_if(g, "(C ~S1) Or (C ~S2 FCursor)", p);
|
684
788
|
}
|
685
789
|
writef(g, "~MFCursor := C;~N", p);
|
686
|
-
g->temporary_used = true;
|
687
790
|
writef(g, "~}", p);
|
791
|
+
g->temporary_used = true;
|
688
792
|
}
|
689
793
|
|
690
794
|
static void generate_delete(struct generator * g, struct node * p) {
|
@@ -692,13 +796,6 @@ static void generate_delete(struct generator * g, struct node * p) {
|
|
692
796
|
writef(g, "~MSliceDel;~N", p);
|
693
797
|
}
|
694
798
|
|
695
|
-
|
696
|
-
static void generate_next(struct generator * g, struct node * p) {
|
697
|
-
write_comment(g, p);
|
698
|
-
write_check_limit(g, p);
|
699
|
-
write_inc_cursor(g, p);
|
700
|
-
}
|
701
|
-
|
702
799
|
static void generate_tolimit(struct generator * g, struct node * p) {
|
703
800
|
write_comment(g, p);
|
704
801
|
g->S[0] = p->mode == m_forward ? "FLimit" : "FBkLimit";
|
@@ -738,7 +835,7 @@ static void generate_sliceto(struct generator * g, struct node * p) {
|
|
738
835
|
|
739
836
|
static void generate_address(struct generator * g, struct node * p) {
|
740
837
|
symbol * b = p->literalstring;
|
741
|
-
if (b !=
|
838
|
+
if (b != NULL) {
|
742
839
|
write_literal_string(g, b);
|
743
840
|
} else {
|
744
841
|
write_varname(g, p->name);
|
@@ -746,7 +843,6 @@ static void generate_address(struct generator * g, struct node * p) {
|
|
746
843
|
}
|
747
844
|
|
748
845
|
static void generate_insert(struct generator * g, struct node * p, int style) {
|
749
|
-
|
750
846
|
int keep_c = style == c_attach;
|
751
847
|
write_comment(g, p);
|
752
848
|
if (p->mode == m_backward) keep_c = !keep_c;
|
@@ -786,7 +882,6 @@ static void generate_slicefrom(struct generator * g, struct node * p) {
|
|
786
882
|
}
|
787
883
|
|
788
884
|
static void generate_setlimit(struct generator * g, struct node * p) {
|
789
|
-
struct str * savevar = vars_newname(g);
|
790
885
|
struct str * varname = vars_newname(g);
|
791
886
|
write_comment(g, p);
|
792
887
|
if (p->left && p->left->type == c_tomark) {
|
@@ -799,6 +894,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
799
894
|
* restore c.
|
800
895
|
*/
|
801
896
|
struct node * q = p->left;
|
897
|
+
write_comment(g, q);
|
802
898
|
g->S[0] = q->mode == m_forward ? ">" : "<";
|
803
899
|
w(g, "~MIf (FCursor ~S0 "); generate_AE(g, q->AE); w(g, ") Then~N");
|
804
900
|
write_block_start(g);
|
@@ -815,7 +911,8 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
815
911
|
w(g, "~M~B0 := FBkLimit;~N");
|
816
912
|
w(g, "~MFBkLimit := ");
|
817
913
|
}
|
818
|
-
generate_AE(g, q->AE);
|
914
|
+
generate_AE(g, q->AE);
|
915
|
+
writef(g, ";~N", q);
|
819
916
|
|
820
917
|
if (p->mode == m_forward) {
|
821
918
|
str_assign(g->failure_str, "FLimit := FLimit + ");
|
@@ -827,7 +924,9 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
827
924
|
str_append_ch(g->failure_str, ';');
|
828
925
|
}
|
829
926
|
} else {
|
927
|
+
struct str * savevar = vars_newname(g);
|
830
928
|
write_savecursor(g, p, savevar);
|
929
|
+
|
831
930
|
generate(g, p->left);
|
832
931
|
|
833
932
|
if (!g->unreachable) {
|
@@ -852,6 +951,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
852
951
|
str_append_ch(g->failure_str, ';');
|
853
952
|
}
|
854
953
|
}
|
954
|
+
str_delete(savevar);
|
855
955
|
}
|
856
956
|
|
857
957
|
if (!g->unreachable) {
|
@@ -863,17 +963,16 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
863
963
|
write_newline(g);
|
864
964
|
}
|
865
965
|
}
|
866
|
-
|
867
966
|
str_delete(varname);
|
868
|
-
str_delete(savevar);
|
869
967
|
}
|
870
968
|
|
871
969
|
/* dollar sets snowball up to operate on a string variable as if it were the
|
872
970
|
* current string */
|
873
971
|
static void generate_dollar(struct generator * g, struct node * p) {
|
972
|
+
write_comment(g, p);
|
973
|
+
|
874
974
|
struct str * savevar = vars_newname(g);
|
875
975
|
g->B[0] = str_data(savevar);
|
876
|
-
write_comment(g, p);
|
877
976
|
g->V[0] = p->name;
|
878
977
|
|
879
978
|
{
|
@@ -899,7 +998,6 @@ static void generate_dollar(struct generator * g, struct node * p) {
|
|
899
998
|
write_declare(g, "~B0_Ket : Integer", p);
|
900
999
|
writef(g, "~{"
|
901
1000
|
"~M~B0_Current := FCurrent;~N"
|
902
|
-
"{ ~M~B0_Current := Copy(FCurrent, 1, FLimit); }~N"
|
903
1001
|
"~M~B0_Cursor := FCursor;~N"
|
904
1002
|
"~M~B0_Limit := FLimit;~N"
|
905
1003
|
"~M~B0_BkLimit := FBkLimit;~N"
|
@@ -918,12 +1016,12 @@ static void generate_dollar(struct generator * g, struct node * p) {
|
|
918
1016
|
str_delete(savevar);
|
919
1017
|
}
|
920
1018
|
|
921
|
-
static void generate_integer_assign(struct generator * g, struct node * p, char * s) {
|
922
|
-
|
1019
|
+
static void generate_integer_assign(struct generator * g, struct node * p, const char * s) {
|
1020
|
+
write_comment(g, p);
|
923
1021
|
g->V[0] = p->name;
|
924
1022
|
w(g, "~M~W0 := ");
|
925
1023
|
|
926
|
-
if (s !=
|
1024
|
+
if (s != NULL) {
|
927
1025
|
g->S[0] = s;
|
928
1026
|
w(g, "~W0 ~S0 ");
|
929
1027
|
}
|
@@ -932,29 +1030,62 @@ static void generate_integer_assign(struct generator * g, struct node * p, char
|
|
932
1030
|
w(g, ";~N");
|
933
1031
|
}
|
934
1032
|
|
935
|
-
static void generate_integer_test(struct generator * g, struct node * p
|
936
|
-
|
937
|
-
|
1033
|
+
static void generate_integer_test(struct generator * g, struct node * p) {
|
1034
|
+
write_comment(g, p);
|
1035
|
+
int relop = p->type;
|
1036
|
+
int optimise_to_return = (g->failure_label == x_return && p->right && p->right->type == c_functionend);
|
1037
|
+
if (optimise_to_return) {
|
1038
|
+
w(g, "~MResult := ");
|
1039
|
+
p->right = NULL;
|
1040
|
+
} else {
|
1041
|
+
w(g, "~MIf ");
|
1042
|
+
// We want the inverse of the snowball test here.
|
1043
|
+
relop ^= 1;
|
1044
|
+
}
|
938
1045
|
generate_AE(g, p->left);
|
939
|
-
|
940
|
-
write_string(g, s);
|
941
|
-
write_char(g, ' ');
|
1046
|
+
write_relop(g, relop);
|
942
1047
|
generate_AE(g, p->AE);
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
1048
|
+
if (optimise_to_return) {
|
1049
|
+
w(g, "~N");
|
1050
|
+
} else {
|
1051
|
+
w(g, " Then~N");
|
1052
|
+
write_block_start(g);
|
1053
|
+
write_failure(g);
|
1054
|
+
write_block_end(g);
|
1055
|
+
g->unreachable = false;
|
1056
|
+
}
|
948
1057
|
}
|
949
1058
|
|
950
1059
|
static void generate_call(struct generator * g, struct node * p) {
|
951
|
-
|
1060
|
+
int signals = check_possible_signals_list(g, p->name->definition, c_define, 0);
|
952
1061
|
write_comment(g, p);
|
953
1062
|
g->V[0] = p->name;
|
954
|
-
|
1063
|
+
if (g->failure_label == x_return) {
|
1064
|
+
if (p->right && p->right->type == c_functionend) {
|
1065
|
+
/* Tail call. */
|
1066
|
+
writef(g, "~MResult = ~V0;~N", p);
|
1067
|
+
return;
|
1068
|
+
}
|
1069
|
+
if (signals == 0) {
|
1070
|
+
/* Always fails. */
|
1071
|
+
writef(g, "~MBegin; Result = ~V0; Exit; End;~N", p);
|
1072
|
+
return;
|
1073
|
+
}
|
1074
|
+
}
|
1075
|
+
if (signals == 1) {
|
1076
|
+
/* Always succeeds. */
|
1077
|
+
writef(g, "~M~V0;~N", p);
|
1078
|
+
} else if (signals == 0) {
|
1079
|
+
/* Always fails. */
|
1080
|
+
writef(g, "~M~V0;~N", p);
|
1081
|
+
write_failure(g);
|
1082
|
+
} else {
|
1083
|
+
write_failure_if(g, "Not ~V0", p);
|
1084
|
+
}
|
955
1085
|
}
|
956
1086
|
|
957
1087
|
static void generate_grouping(struct generator * g, struct node * p, int complement) {
|
1088
|
+
write_comment(g, p);
|
958
1089
|
|
959
1090
|
struct grouping * q = p->name->grouping;
|
960
1091
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
@@ -966,7 +1097,6 @@ static void generate_grouping(struct generator * g, struct node * p, int complem
|
|
966
1097
|
}
|
967
1098
|
|
968
1099
|
static void generate_namedstring(struct generator * g, struct node * p) {
|
969
|
-
|
970
1100
|
write_comment(g, p);
|
971
1101
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
972
1102
|
g->V[0] = p->name;
|
@@ -983,17 +1113,19 @@ static void generate_literalstring(struct generator * g, struct node * p) {
|
|
983
1113
|
}
|
984
1114
|
|
985
1115
|
static void generate_define(struct generator * g, struct node * p) {
|
986
|
-
struct
|
987
|
-
|
1116
|
+
struct name * q = p->name;
|
1117
|
+
if (q->type == t_routine && !q->used) return;
|
988
1118
|
|
989
|
-
|
990
|
-
g
|
991
|
-
w(g, "~N~MFunction T~n.~W0 : Boolean;~N");
|
1119
|
+
write_newline(g);
|
1120
|
+
write_comment(g, p);
|
992
1121
|
|
993
|
-
/*
|
994
|
-
|
995
|
-
|
1122
|
+
/* Generate function header. */
|
1123
|
+
g->V[0] = q;
|
1124
|
+
w(g, "~MFunction T~n.~W0 : Boolean;~N");
|
996
1125
|
|
1126
|
+
/* Save output. */
|
1127
|
+
struct str *saved_output = g->outbuf;
|
1128
|
+
struct str *saved_declarations = g->declarations;
|
997
1129
|
g->outbuf = str_new();
|
998
1130
|
g->declarations = str_new();
|
999
1131
|
|
@@ -1006,9 +1138,15 @@ static void generate_define(struct generator * g, struct node * p) {
|
|
1006
1138
|
|
1007
1139
|
/* Generate function body. */
|
1008
1140
|
w(g, "~{");
|
1141
|
+
int signals = check_possible_signals_list(g, p->left, c_define, 0);
|
1009
1142
|
g->temporary_used = false;
|
1010
1143
|
generate(g, p->left);
|
1011
|
-
if (
|
1144
|
+
if (p->left->right) {
|
1145
|
+
assert(p->left->right->type == c_functionend);
|
1146
|
+
if (signals) {
|
1147
|
+
generate(g, p->left->right);
|
1148
|
+
}
|
1149
|
+
}
|
1012
1150
|
w(g, "~}");
|
1013
1151
|
|
1014
1152
|
if (g->temporary_used) {
|
@@ -1025,11 +1163,10 @@ static void generate_define(struct generator * g, struct node * p) {
|
|
1025
1163
|
}
|
1026
1164
|
|
1027
1165
|
if (g->next_label) {
|
1028
|
-
int i, num = g->next_label;
|
1029
|
-
|
1030
1166
|
str_append_string(saved_output, "Label\n");
|
1031
1167
|
|
1032
|
-
|
1168
|
+
int num = g->next_label;
|
1169
|
+
for (int i = 0; i < num; ++i) {
|
1033
1170
|
str_append_string(saved_output, " lab");
|
1034
1171
|
str_append_int(saved_output, i);
|
1035
1172
|
str_append_string(saved_output, i == num - 1 ? ";\n" : ",\n");
|
@@ -1043,39 +1180,47 @@ static void generate_define(struct generator * g, struct node * p) {
|
|
1043
1180
|
g->outbuf = saved_output;
|
1044
1181
|
}
|
1045
1182
|
|
1046
|
-
static void
|
1047
|
-
|
1183
|
+
static void generate_functionend(struct generator * g, struct node * p) {
|
1184
|
+
(void)p;
|
1185
|
+
w(g, "~MResult := True;~N");
|
1186
|
+
}
|
1048
1187
|
|
1188
|
+
static void generate_substring(struct generator * g, struct node * p) {
|
1049
1189
|
write_comment(g, p);
|
1050
1190
|
|
1191
|
+
struct among * x = p->among;
|
1192
|
+
|
1051
1193
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
1052
1194
|
g->I[0] = x->number;
|
1053
1195
|
g->I[1] = x->literalstring_count;
|
1054
1196
|
|
1055
|
-
if (
|
1056
|
-
write_failure_if(g, "FindAmong~S0(a_~I0, ~I1) = 0", p);
|
1057
|
-
} else {
|
1197
|
+
if (x->amongvar_needed) {
|
1058
1198
|
writef(g, "~MAmongVar := FindAmong~S0(a_~I0, ~I1);~N", p);
|
1059
|
-
|
1199
|
+
if (!x->always_matches) {
|
1200
|
+
write_failure_if(g, "AmongVar = 0", p);
|
1201
|
+
}
|
1202
|
+
} else if (x->always_matches) {
|
1203
|
+
writef(g, "~MFindAmong~S0(a_~I0, ~I1);~N", p);
|
1204
|
+
} else {
|
1205
|
+
write_failure_if(g, "FindAmong~S0(a_~I0, ~I1) = 0", p);
|
1060
1206
|
}
|
1061
1207
|
}
|
1062
1208
|
|
1063
1209
|
static void generate_among(struct generator * g, struct node * p) {
|
1064
|
-
|
1065
1210
|
struct among * x = p->among;
|
1066
1211
|
|
1067
|
-
if (x->substring ==
|
1068
|
-
|
1069
|
-
|
1212
|
+
if (x->substring == NULL) {
|
1213
|
+
generate_substring(g, p);
|
1214
|
+
} else {
|
1215
|
+
write_comment(g, p);
|
1216
|
+
}
|
1070
1217
|
|
1071
1218
|
if (x->command_count == 1 && x->nocommand_count == 0) {
|
1072
1219
|
/* Only one outcome ("no match" already handled). */
|
1073
1220
|
generate(g, x->commands[0]);
|
1074
1221
|
} else if (x->command_count > 0) {
|
1075
|
-
int i;
|
1076
|
-
write_comment(g, p);
|
1077
1222
|
w(g, "~MCase AmongVar Of~N~+");
|
1078
|
-
for (i = 1; i <= x->command_count; i++) {
|
1223
|
+
for (int i = 1; i <= x->command_count; i++) {
|
1079
1224
|
g->I[0] = i;
|
1080
1225
|
w(g, "~M~I0:~N~{");
|
1081
1226
|
generate(g, x->commands[i - 1]);
|
@@ -1087,20 +1232,17 @@ static void generate_among(struct generator * g, struct node * p) {
|
|
1087
1232
|
}
|
1088
1233
|
|
1089
1234
|
static void generate_booltest(struct generator * g, struct node * p) {
|
1090
|
-
|
1091
1235
|
write_comment(g, p);
|
1092
1236
|
g->V[0] = p->name;
|
1093
1237
|
write_failure_if(g, "Not (~V0)", p);
|
1094
1238
|
}
|
1095
1239
|
|
1096
1240
|
static void generate_false(struct generator * g, struct node * p) {
|
1097
|
-
|
1098
1241
|
write_comment(g, p);
|
1099
1242
|
write_failure(g);
|
1100
1243
|
}
|
1101
1244
|
|
1102
1245
|
static void generate_debug(struct generator * g, struct node * p) {
|
1103
|
-
|
1104
1246
|
write_comment(g, p);
|
1105
1247
|
g->I[0] = g->debug_count++;
|
1106
1248
|
g->I[1] = p->line_number;
|
@@ -1108,14 +1250,10 @@ static void generate_debug(struct generator * g, struct node * p) {
|
|
1108
1250
|
}
|
1109
1251
|
|
1110
1252
|
static void generate(struct generator * g, struct node * p) {
|
1111
|
-
|
1112
|
-
int a0;
|
1113
|
-
struct str * a1;
|
1114
|
-
|
1115
1253
|
if (g->unreachable) return;
|
1116
1254
|
|
1117
|
-
a0 = g->failure_label;
|
1118
|
-
a1 = str_copy(g->failure_str);
|
1255
|
+
int a0 = g->failure_label;
|
1256
|
+
struct str * a1 = str_copy(g->failure_str);
|
1119
1257
|
|
1120
1258
|
switch (p->type) {
|
1121
1259
|
case c_define: generate_define(g, p); break;
|
@@ -1133,6 +1271,11 @@ static void generate(struct generator * g, struct node * p) {
|
|
1133
1271
|
case c_do: generate_do(g, p); break;
|
1134
1272
|
case c_goto: generate_GO(g, p, 1); break;
|
1135
1273
|
case c_gopast: generate_GO(g, p, 0); break;
|
1274
|
+
case c_goto_grouping: generate_GO_grouping(g, p, 1, 0); break;
|
1275
|
+
case c_gopast_grouping:
|
1276
|
+
generate_GO_grouping(g, p, 0, 0); break;
|
1277
|
+
case c_goto_non: generate_GO_grouping(g, p, 1, 1); break;
|
1278
|
+
case c_gopast_non: generate_GO_grouping(g, p, 0, 1); break;
|
1136
1279
|
case c_repeat: generate_repeat(g, p); break;
|
1137
1280
|
case c_loop: generate_loop(g, p); break;
|
1138
1281
|
case c_atleast: generate_atleast(g, p); break;
|
@@ -1159,12 +1302,14 @@ static void generate(struct generator * g, struct node * p) {
|
|
1159
1302
|
case c_minusassign: generate_integer_assign(g, p, "-"); break;
|
1160
1303
|
case c_multiplyassign:generate_integer_assign(g, p, "*"); break;
|
1161
1304
|
case c_divideassign: generate_integer_assign(g, p, "div"); break;
|
1162
|
-
case c_eq:
|
1163
|
-
case c_ne:
|
1164
|
-
case
|
1165
|
-
case c_ge:
|
1166
|
-
case
|
1167
|
-
case c_le:
|
1305
|
+
case c_eq:
|
1306
|
+
case c_ne:
|
1307
|
+
case c_gt:
|
1308
|
+
case c_ge:
|
1309
|
+
case c_lt:
|
1310
|
+
case c_le:
|
1311
|
+
generate_integer_test(g, p);
|
1312
|
+
break;
|
1168
1313
|
case c_call: generate_call(g, p); break;
|
1169
1314
|
case c_grouping: generate_grouping(g, p, false); break;
|
1170
1315
|
case c_non: generate_grouping(g, p, true); break;
|
@@ -1176,6 +1321,7 @@ static void generate(struct generator * g, struct node * p) {
|
|
1176
1321
|
case c_false: generate_false(g, p); break;
|
1177
1322
|
case c_true: break;
|
1178
1323
|
case c_debug: generate_debug(g, p); break;
|
1324
|
+
case c_functionend: generate_functionend(g, p); break;
|
1179
1325
|
default: fprintf(stderr, "%d encountered\n", p->type);
|
1180
1326
|
exit(1);
|
1181
1327
|
}
|
@@ -1213,54 +1359,65 @@ static void generate_method_decl(struct generator * g, struct name * q) {
|
|
1213
1359
|
}
|
1214
1360
|
|
1215
1361
|
static void generate_method_decls(struct generator * g) {
|
1216
|
-
struct name * q;
|
1217
|
-
|
1218
1362
|
w(g, "~Mpublic~N~+");
|
1219
1363
|
w(g, "~MConstructor Create;~N");
|
1220
1364
|
|
1221
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1365
|
+
for (struct name * q = g->analyser->names; q; q = q->next) {
|
1222
1366
|
if (q->type == t_external) {
|
1223
1367
|
generate_method_decl(g, q);
|
1224
1368
|
}
|
1225
1369
|
}
|
1226
1370
|
w(g, "~-");
|
1227
1371
|
|
1228
|
-
|
1229
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1372
|
+
int first = true;
|
1373
|
+
for (struct name * q = g->analyser->names; q; q = q->next) {
|
1230
1374
|
if (q->type == t_routine) {
|
1375
|
+
if (first) {
|
1376
|
+
w(g, "~Mprivate~N~+");
|
1377
|
+
first = false;
|
1378
|
+
}
|
1231
1379
|
generate_method_decl(g, q);
|
1232
1380
|
}
|
1233
1381
|
}
|
1234
|
-
w(g, "~-");
|
1382
|
+
if (!first) w(g, "~-");
|
1235
1383
|
}
|
1236
1384
|
|
1237
1385
|
static void generate_member_decls(struct generator * g) {
|
1238
|
-
|
1239
|
-
|
1240
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1386
|
+
int first = true;
|
1387
|
+
for (struct name * q = g->analyser->names; q; q = q->next) {
|
1241
1388
|
g->V[0] = q;
|
1242
1389
|
switch (q->type) {
|
1243
1390
|
case t_string:
|
1244
|
-
w(g, "~M~W0 : AnsiString;~N");
|
1245
|
-
break;
|
1246
1391
|
case t_integer:
|
1247
|
-
w(g, "~M~W0 : Integer;~N");
|
1248
|
-
break;
|
1249
1392
|
case t_boolean:
|
1250
|
-
|
1251
|
-
|
1393
|
+
if (first) {
|
1394
|
+
w(g, "~Mprivate~N~+");
|
1395
|
+
first = false;
|
1396
|
+
}
|
1397
|
+
switch (q->type) {
|
1398
|
+
case t_string:
|
1399
|
+
w(g, "~M~W0 : AnsiString;~N");
|
1400
|
+
break;
|
1401
|
+
case t_integer:
|
1402
|
+
w(g, "~M~W0 : Integer;~N");
|
1403
|
+
break;
|
1404
|
+
case t_boolean:
|
1405
|
+
w(g, "~M~W0 : Boolean;~N");
|
1406
|
+
break;
|
1407
|
+
}
|
1252
1408
|
}
|
1253
1409
|
}
|
1254
1410
|
|
1255
|
-
w(g, "~-");
|
1411
|
+
if (!first) w(g, "~-");
|
1256
1412
|
}
|
1257
1413
|
|
1258
1414
|
static void generate_among_decls(struct generator * g) {
|
1259
1415
|
struct among *a = g->analyser->amongs;
|
1416
|
+
if (a == NULL) return;
|
1260
1417
|
|
1261
1418
|
w(g, "~Mprivate~N~+");
|
1262
1419
|
|
1263
|
-
while (a !=
|
1420
|
+
while (a != NULL) {
|
1264
1421
|
g->I[0] = a->number;
|
1265
1422
|
w(g, "~Ma_~I0 : Array Of TAmong;~N");
|
1266
1423
|
a = a->next;
|
@@ -1270,33 +1427,33 @@ static void generate_among_decls(struct generator * g) {
|
|
1270
1427
|
}
|
1271
1428
|
|
1272
1429
|
static void generate_among_table(struct generator * g, struct among * x) {
|
1273
|
-
|
1430
|
+
write_comment(g, x->node);
|
1431
|
+
|
1274
1432
|
struct amongvec * v = x->b;
|
1275
1433
|
|
1276
1434
|
g->I[0] = x->number;
|
1277
1435
|
g->I[1] = x->literalstring_count;
|
1278
1436
|
|
1279
1437
|
w(g, "~MSetLength(a_~I0, ~I1);~N~+");
|
1280
|
-
|
1281
|
-
for (i = 0; i < x->literalstring_count; i++, v++) {
|
1438
|
+
for (int i = 0; i < x->literalstring_count; i++) {
|
1282
1439
|
g->I[1] = i;
|
1283
1440
|
|
1284
1441
|
/* Write among's string. */
|
1285
|
-
g->L[0] = v
|
1442
|
+
g->L[0] = v[i].b;
|
1286
1443
|
w(g, "~Ma_~I0[~I1].Str := ~L0;~N");
|
1287
1444
|
|
1288
1445
|
/* Write among's index & result. */
|
1289
|
-
g->I[2] = v
|
1446
|
+
g->I[2] = v[i].i;
|
1290
1447
|
w(g, "~Ma_~I0[~I1].Index := ~I2;~N");
|
1291
|
-
g->I[2] = v
|
1448
|
+
g->I[2] = v[i].result;
|
1292
1449
|
w(g, "~Ma_~I0[~I1].Result := ~I2;~N");
|
1293
1450
|
|
1294
1451
|
/* Write among's handler. */
|
1295
1452
|
w(g, "~Ma_~I0[~I1].Method := ");
|
1296
|
-
if (v
|
1453
|
+
if (v[i].function == NULL) {
|
1297
1454
|
w(g, "nil;~N~N");
|
1298
1455
|
} else {
|
1299
|
-
g->V[0] = v
|
1456
|
+
g->V[0] = v[i].function;
|
1300
1457
|
w(g, "Self.~W0;~N~N");
|
1301
1458
|
}
|
1302
1459
|
}
|
@@ -1304,10 +1461,8 @@ static void generate_among_table(struct generator * g, struct among * x) {
|
|
1304
1461
|
}
|
1305
1462
|
|
1306
1463
|
static void generate_amongs(struct generator * g) {
|
1307
|
-
struct among *
|
1308
|
-
|
1309
|
-
generate_among_table(g, a);
|
1310
|
-
a = a->next;
|
1464
|
+
for (struct among * x = g->analyser->amongs; x; x = x->next) {
|
1465
|
+
generate_among_table(g, x);
|
1311
1466
|
}
|
1312
1467
|
}
|
1313
1468
|
|
@@ -1319,8 +1474,9 @@ static void generate_constructor(struct generator * g) {
|
|
1319
1474
|
|
1320
1475
|
static void generate_methods(struct generator * g) {
|
1321
1476
|
struct node * p = g->analyser->program;
|
1322
|
-
while (p !=
|
1477
|
+
while (p != NULL) {
|
1323
1478
|
generate(g, p);
|
1479
|
+
g->unreachable = false;
|
1324
1480
|
p = p->right;
|
1325
1481
|
}
|
1326
1482
|
}
|
@@ -1328,22 +1484,19 @@ static void generate_methods(struct generator * g) {
|
|
1328
1484
|
static void set_bit(symbol * b, int i) { b[i/8] |= 1 << i%8; }
|
1329
1485
|
|
1330
1486
|
static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
1331
|
-
|
1332
1487
|
int range = q->largest_ch - q->smallest_ch + 1;
|
1333
1488
|
int size = (range + 7)/ 8; /* assume 8 bits per symbol */
|
1334
1489
|
symbol * b = q->b;
|
1335
1490
|
symbol * map = create_b(size);
|
1336
|
-
int i;
|
1337
|
-
for (i = 0; i < size; i++) map[i] = 0;
|
1338
1491
|
|
1339
|
-
|
1492
|
+
for (int i = 0; i < size; i++) map[i] = 0;
|
1340
1493
|
|
1341
|
-
for (i = 0; i < SIZE(b); i++) set_bit(map, b[i] - q->smallest_ch);
|
1494
|
+
for (int i = 0; i < SIZE(b); i++) set_bit(map, b[i] - q->smallest_ch);
|
1342
1495
|
|
1343
1496
|
g->V[0] = q->name;
|
1344
1497
|
g->I[0] = size - 1;
|
1345
1498
|
w(g, "~N~MConst~+~N~M~W0 : Array [0..~I0] Of Char = (~N~+");
|
1346
|
-
for (i = 0; i < size; i++) {
|
1499
|
+
for (int i = 0; i < size; i++) {
|
1347
1500
|
if (i != 0) w(g, ",~N");
|
1348
1501
|
g->I[0] = map[i];
|
1349
1502
|
w(g, "~MChr(~I0)");
|
@@ -1354,8 +1507,7 @@ static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
|
1354
1507
|
}
|
1355
1508
|
|
1356
1509
|
static void generate_groupings(struct generator * g) {
|
1357
|
-
struct grouping * q;
|
1358
|
-
for (q = g->analyser->groupings; q; q = q->next) {
|
1510
|
+
for (struct grouping * q = g->analyser->groupings; q; q = q->next) {
|
1359
1511
|
if (q->name->used)
|
1360
1512
|
generate_grouping_table(g, q);
|
1361
1513
|
}
|