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,14 +1,13 @@
|
|
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 */
|
4
5
|
#include <ctype.h>
|
5
|
-
#include <limits.h>
|
6
6
|
#include "header.h"
|
7
7
|
|
8
8
|
/* prototypes */
|
9
9
|
|
10
10
|
static void generate(struct generator * g, struct node * p);
|
11
|
-
static void generate_next(struct generator * g, struct node * p);
|
12
11
|
static void w(struct generator * g, const char * s);
|
13
12
|
static void writef(struct generator * g, const char * s, struct node * p);
|
14
13
|
|
@@ -17,7 +16,6 @@ static int new_label(struct generator * g) {
|
|
17
16
|
}
|
18
17
|
|
19
18
|
static struct str * vars_newname(struct generator * g) {
|
20
|
-
|
21
19
|
struct str * output;
|
22
20
|
g->var_number++;
|
23
21
|
output = str_new();
|
@@ -29,17 +27,19 @@ static struct str * vars_newname(struct generator * g) {
|
|
29
27
|
/* Write routines for items from the syntax tree */
|
30
28
|
|
31
29
|
static void write_varname(struct generator * g, struct name * p) {
|
32
|
-
|
33
|
-
int ch = p->b[0];
|
34
30
|
if (p->type != t_external) {
|
35
31
|
write_char(g, "SBIRXG"[p->type]);
|
36
32
|
write_char(g, '_');
|
37
|
-
}
|
38
|
-
write_char(g, toupper(ch));
|
39
|
-
str_append_b_tail(g->outbuf, p->b, 1);
|
33
|
+
}
|
40
34
|
|
41
|
-
|
42
|
-
|
35
|
+
{
|
36
|
+
char save_initial = p->s[0];
|
37
|
+
p->s[0] = toupper(save_initial);
|
38
|
+
str_append_s(g->outbuf, p->s);
|
39
|
+
p->s[0] = save_initial;
|
40
|
+
}
|
41
|
+
|
42
|
+
if (p->s[SIZE(p->s) - 1] == '_') {
|
43
43
|
write_char(g, 'E');
|
44
44
|
}
|
45
45
|
}
|
@@ -50,11 +50,10 @@ static void write_varref(struct generator * g, struct name * p) { /* reference
|
|
50
50
|
}
|
51
51
|
|
52
52
|
static void write_literal_string(struct generator * g, symbol * p) {
|
53
|
-
int i;
|
54
53
|
// Ada supports UTF-8 literal strings, we only need to escape the quote and
|
55
54
|
// special characters.
|
56
55
|
write_char(g, '"');
|
57
|
-
for (i = 0; i < SIZE(p); i++) {
|
56
|
+
for (int i = 0; i < SIZE(p); i++) {
|
58
57
|
int ch = p[i];
|
59
58
|
if (ch == '"') {
|
60
59
|
write_string(g, "\"\"");
|
@@ -72,17 +71,30 @@ static void write_literal_string(struct generator * g, symbol * p) {
|
|
72
71
|
}
|
73
72
|
|
74
73
|
static void write_margin(struct generator * g) {
|
75
|
-
int i;
|
76
|
-
|
74
|
+
for (int i = 0; i < g->margin; i++) write_string(g, " ");
|
75
|
+
}
|
76
|
+
|
77
|
+
static void write_relop(struct generator * g, int relop) {
|
78
|
+
switch (relop) {
|
79
|
+
case c_eq: write_string(g, " = "); break;
|
80
|
+
case c_ne: write_string(g, " /= "); break;
|
81
|
+
case c_gt: write_string(g, " > "); break;
|
82
|
+
case c_ge: write_string(g, " >= "); break;
|
83
|
+
case c_lt: write_string(g, " < "); break;
|
84
|
+
case c_le: write_string(g, " <= "); break;
|
85
|
+
default:
|
86
|
+
fprintf(stderr, "Unexpected type #%d in generate_integer_test\n", relop);
|
87
|
+
exit(1);
|
88
|
+
}
|
77
89
|
}
|
78
90
|
|
79
91
|
/* Write a variable declaration. */
|
80
92
|
static void write_declare(struct generator * g,
|
81
|
-
char * declaration,
|
93
|
+
const char * declaration,
|
82
94
|
struct node * p) {
|
83
95
|
struct str * temp = g->outbuf;
|
84
96
|
g->outbuf = g->declarations;
|
85
|
-
write_string(g, "
|
97
|
+
write_string(g, " ");
|
86
98
|
writef(g, declaration, p);
|
87
99
|
write_string(g, ";");
|
88
100
|
write_newline(g);
|
@@ -90,54 +102,44 @@ static void write_declare(struct generator * g,
|
|
90
102
|
}
|
91
103
|
|
92
104
|
static void write_comment(struct generator * g, struct node * p) {
|
93
|
-
if (g->options->comments)
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
}
|
105
|
+
if (!g->options->comments) return;
|
106
|
+
write_margin(g);
|
107
|
+
write_string(g, "-- ");
|
108
|
+
write_comment_content(g, p);
|
109
|
+
write_newline(g);
|
99
110
|
}
|
100
111
|
|
101
112
|
static void write_block_start(struct generator * g) {
|
102
113
|
w(g, "~Mbegin~+~N");
|
103
114
|
}
|
104
115
|
|
105
|
-
static void write_block_end(struct generator * g) {
|
116
|
+
static void write_block_end(struct generator * g) {
|
106
117
|
w(g, "~-~Mend;~N");
|
107
118
|
}
|
108
119
|
|
109
|
-
static void restore_string(struct node * p, struct str * out, struct str * savevar) {
|
110
|
-
|
111
|
-
str_clear(out);
|
112
|
-
str_append_string(out, "Z.C := ");
|
113
|
-
if (p->mode != m_forward) str_append_string(out, "Z.L - ");
|
114
|
-
str_append(out, savevar);
|
115
|
-
str_append_string(out, ";");
|
116
|
-
}
|
117
|
-
|
118
120
|
static void write_savecursor(struct generator * g, struct node * p,
|
119
121
|
struct str * savevar) {
|
120
122
|
g->B[0] = str_data(savevar);
|
121
123
|
g->S[1] = "";
|
122
124
|
if (p->mode != m_forward) g->S[1] = "Z.L - ";
|
123
|
-
write_declare(g, "
|
125
|
+
write_declare(g, "~B0 : Char_Index", p);
|
124
126
|
writef(g, "~M~B0 := ~S1Z.C;~N" , p);
|
125
127
|
}
|
126
128
|
|
129
|
+
static void append_restore_string(struct node * p, struct str * out, struct str * savevar) {
|
130
|
+
str_append_string(out, "Z.C := ");
|
131
|
+
if (p->mode != m_forward) str_append_string(out, "Z.L - ");
|
132
|
+
str_append(out, savevar);
|
133
|
+
str_append_string(out, ";");
|
134
|
+
}
|
135
|
+
|
127
136
|
static void write_restorecursor(struct generator * g, struct node * p, struct str * savevar) {
|
128
137
|
write_margin(g);
|
129
|
-
|
130
|
-
write_string(g, "Z.C := ");
|
131
|
-
} else {
|
132
|
-
write_string(g, "Z.C := Z.L - ");
|
133
|
-
}
|
134
|
-
write_str(g, savevar);
|
135
|
-
write_string(g, ";");
|
138
|
+
append_restore_string(p, g->outbuf, savevar);
|
136
139
|
write_newline(g);
|
137
140
|
}
|
138
141
|
|
139
142
|
static void wsetl(struct generator * g, int n) {
|
140
|
-
|
141
143
|
write_newline(g);
|
142
144
|
write_margin(g);
|
143
145
|
write_string(g, "<<lab");
|
@@ -156,7 +158,6 @@ static void wgotol(struct generator * g, int n) {
|
|
156
158
|
}
|
157
159
|
|
158
160
|
static void write_failure(struct generator * g) {
|
159
|
-
|
160
161
|
if (str_len(g->failure_str) != 0) {
|
161
162
|
write_margin(g);
|
162
163
|
write_str(g, g->failure_str);
|
@@ -180,8 +181,7 @@ static void write_failure(struct generator * g) {
|
|
180
181
|
g->unreachable = true;
|
181
182
|
}
|
182
183
|
|
183
|
-
static void write_failure_if(struct generator * g, char * s, struct node * p) {
|
184
|
-
|
184
|
+
static void write_failure_if(struct generator * g, const char * s, struct node * p) {
|
185
185
|
writef(g, "~Mif ", p);
|
186
186
|
writef(g, s, p);
|
187
187
|
writef(g, " then~N~+", p);
|
@@ -201,19 +201,19 @@ static void write_check_limit(struct generator * g, struct node * p) {
|
|
201
201
|
|
202
202
|
/* Formatted write. */
|
203
203
|
static void writef(struct generator * g, const char * input, struct node * p) {
|
204
|
+
(void)p;
|
204
205
|
int i = 0;
|
205
|
-
int l = strlen(input);
|
206
206
|
|
207
|
-
while (i
|
207
|
+
while (input[i]) {
|
208
208
|
int ch = input[i++];
|
209
209
|
if (ch != '~') {
|
210
210
|
write_char(g, ch);
|
211
211
|
continue;
|
212
212
|
}
|
213
|
-
|
214
|
-
|
215
|
-
case '
|
216
|
-
case 'f':
|
213
|
+
ch = input[i++];
|
214
|
+
switch (ch) {
|
215
|
+
case '~': write_char(g, '~'); continue;
|
216
|
+
case 'f':
|
217
217
|
write_failure(g);
|
218
218
|
g->unreachable = false;
|
219
219
|
continue;
|
@@ -221,47 +221,80 @@ static void writef(struct generator * g, const char * input, struct node * p) {
|
|
221
221
|
case 'N': write_newline(g); continue;
|
222
222
|
case '{': write_block_start(g); continue;
|
223
223
|
case '}': write_block_end(g); continue;
|
224
|
-
case 'S':
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
224
|
+
case 'S': {
|
225
|
+
int j = input[i++] - '0';
|
226
|
+
if (j < 0 || j > (int)(sizeof(g->S) / sizeof(g->S[0]))) {
|
227
|
+
printf("Invalid escape sequence ~%c%c in writef(g, \"%s\", p)\n",
|
228
|
+
ch, input[i - 1], input);
|
229
|
+
exit(1);
|
230
|
+
}
|
231
|
+
write_string(g, g->S[j]);
|
232
|
+
continue;
|
233
|
+
}
|
234
|
+
case 'B': {
|
235
|
+
int j = input[i++] - '0';
|
236
|
+
if (j < 0 || j > (int)(sizeof(g->B) / sizeof(g->B[0])))
|
237
|
+
goto invalid_escape2;
|
238
|
+
write_s(g, g->B[j]);
|
239
|
+
continue;
|
240
|
+
}
|
241
|
+
case 'I': {
|
242
|
+
int j = input[i++] - '0';
|
243
|
+
if (j < 0 || j > (int)(sizeof(g->I) / sizeof(g->I[0])))
|
244
|
+
goto invalid_escape2;
|
245
|
+
write_int(g, g->I[j]);
|
246
|
+
continue;
|
247
|
+
}
|
248
|
+
case 'V':
|
249
|
+
case 'W': {
|
250
|
+
int j = input[i++] - '0';
|
251
|
+
if (j < 0 || j > (int)(sizeof(g->V) / sizeof(g->V[0])))
|
252
|
+
goto invalid_escape2;
|
253
|
+
if (ch == 'V')
|
254
|
+
write_varref(g, g->V[j]);
|
255
|
+
else
|
256
|
+
write_varname(g, g->V[j]);
|
257
|
+
continue;
|
258
|
+
}
|
259
|
+
case 'L': {
|
260
|
+
int j = input[i++] - '0';
|
261
|
+
if (j < 0 || j > (int)(sizeof(g->L) / sizeof(g->L[0])))
|
262
|
+
goto invalid_escape2;
|
263
|
+
write_literal_string(g, g->L[j]);
|
264
|
+
continue;
|
265
|
+
}
|
230
266
|
case '+': g->margin++; continue;
|
231
267
|
case '-': g->margin--; continue;
|
232
268
|
case 'n': write_string(g, g->options->name); continue;
|
269
|
+
default:
|
270
|
+
printf("Invalid escape sequence ~%c in writef(g, \"%s\", p)\n",
|
271
|
+
ch, input);
|
272
|
+
exit(1);
|
273
|
+
invalid_escape2:
|
274
|
+
printf("Invalid escape sequence ~%c%c in writef(g, \"%s\", p)\n",
|
275
|
+
ch, input[i - 1], input);
|
276
|
+
exit(1);
|
233
277
|
}
|
234
278
|
}
|
235
279
|
}
|
236
280
|
|
237
281
|
static void w(struct generator * g, const char * s) {
|
238
|
-
writef(g, s,
|
282
|
+
writef(g, s, NULL);
|
239
283
|
}
|
240
284
|
|
241
285
|
static int need_among_var(struct node *p) {
|
242
|
-
|
243
286
|
while (p) {
|
244
|
-
if (p->type ==
|
287
|
+
if (p->type == c_among) {
|
245
288
|
return 1;
|
246
289
|
}
|
247
|
-
if (p->
|
290
|
+
if (p->left && need_among_var(p->left)) {
|
248
291
|
return 1;
|
249
292
|
}
|
250
|
-
p
|
251
|
-
}
|
252
|
-
return 0;
|
253
|
-
}
|
254
|
-
|
255
|
-
static int need_among_handler(struct among *a) {
|
256
|
-
int i;
|
257
|
-
struct amongvec * v = a->b;
|
258
|
-
|
259
|
-
for (i = 0; i < a->literalstring_count; i++, v++) {
|
260
|
-
if (v->function != 0) {
|
293
|
+
if (p->aux && need_among_var(p->aux)) {
|
261
294
|
return 1;
|
262
295
|
}
|
296
|
+
p = p->right;
|
263
297
|
}
|
264
|
-
|
265
298
|
return 0;
|
266
299
|
}
|
267
300
|
|
@@ -303,12 +336,15 @@ static void generate_AE(struct generator * g, struct node * p) {
|
|
303
336
|
w(g, "Length_Utf8 (Z)");
|
304
337
|
break;
|
305
338
|
case c_size:
|
306
|
-
w(g, "
|
339
|
+
w(g, "Z.Len");
|
307
340
|
break;
|
308
341
|
case c_lenof:
|
342
|
+
g->V[0] = p->name;
|
343
|
+
w(g, "Length_Utf8 (Ada.Strings.Unbounded.To_String (~V0))");
|
344
|
+
break;
|
309
345
|
case c_sizeof:
|
310
346
|
g->V[0] = p->name;
|
311
|
-
w(g, "
|
347
|
+
w(g, "Ada.Strings.Unbounded.Length (~V0)");
|
312
348
|
break;
|
313
349
|
default:
|
314
350
|
break;
|
@@ -325,27 +361,34 @@ static void generate_bra(struct generator * g, struct node * p) {
|
|
325
361
|
}
|
326
362
|
|
327
363
|
static void generate_and(struct generator * g, struct node * p) {
|
328
|
-
struct str * savevar =
|
329
|
-
|
364
|
+
struct str * savevar = NULL;
|
365
|
+
if (K_needed(g, p->left)) {
|
366
|
+
savevar = vars_newname(g);
|
367
|
+
}
|
330
368
|
|
331
369
|
write_comment(g, p);
|
332
370
|
|
333
|
-
if (
|
371
|
+
if (savevar) write_savecursor(g, p, savevar);
|
334
372
|
|
335
373
|
p = p->left;
|
336
374
|
while (p) {
|
337
375
|
generate(g, p);
|
338
376
|
if (g->unreachable) break;
|
339
|
-
if (
|
377
|
+
if (savevar && p->right != NULL) write_restorecursor(g, p, savevar);
|
340
378
|
p = p->right;
|
341
379
|
}
|
342
|
-
|
380
|
+
|
381
|
+
if (savevar) {
|
382
|
+
str_delete(savevar);
|
383
|
+
}
|
343
384
|
}
|
344
385
|
|
345
386
|
static void generate_or(struct generator * g, struct node * p) {
|
346
|
-
struct str * savevar =
|
387
|
+
struct str * savevar = NULL;
|
388
|
+
if (K_needed(g, p->left)) {
|
389
|
+
savevar = vars_newname(g);
|
390
|
+
}
|
347
391
|
int used = g->label_used;
|
348
|
-
int keep_c = K_needed(g, p->left);
|
349
392
|
|
350
393
|
int a0 = g->failure_label;
|
351
394
|
struct str * a1 = str_copy(g->failure_str);
|
@@ -355,13 +398,13 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
355
398
|
|
356
399
|
write_comment(g, p);
|
357
400
|
|
358
|
-
if (
|
401
|
+
if (savevar) write_savecursor(g, p, savevar);
|
359
402
|
|
360
403
|
p = p->left;
|
361
404
|
str_clear(g->failure_str);
|
362
405
|
|
363
|
-
if (p ==
|
364
|
-
/* p should never be
|
406
|
+
if (p == NULL) {
|
407
|
+
/* p should never be NULL after an or: there should be at least two
|
365
408
|
* sub nodes. */
|
366
409
|
fprintf(stderr, "Error: \"or\" node without children nodes.");
|
367
410
|
exit(1);
|
@@ -374,13 +417,11 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
374
417
|
wgotol(g, out_lab);
|
375
418
|
end_unreachable = false;
|
376
419
|
}
|
377
|
-
|
420
|
+
|
378
421
|
if (g->label_used)
|
379
422
|
wsetl(g, g->failure_label);
|
380
423
|
g->unreachable = false;
|
381
|
-
if (
|
382
|
-
write_restorecursor(g, p, savevar);
|
383
|
-
}
|
424
|
+
if (savevar) write_restorecursor(g, p, savevar);
|
384
425
|
p = p->right;
|
385
426
|
}
|
386
427
|
g->label_used = used;
|
@@ -393,32 +434,37 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
393
434
|
if (!end_unreachable) {
|
394
435
|
g->unreachable = false;
|
395
436
|
}
|
396
|
-
|
437
|
+
|
438
|
+
if (savevar) {
|
439
|
+
str_delete(savevar);
|
440
|
+
}
|
397
441
|
}
|
398
442
|
|
399
443
|
static void generate_backwards(struct generator * g, struct node * p) {
|
400
|
-
|
444
|
+
write_comment(g, p);
|
445
|
+
writef(g, "~MZ.Lb := Z.C; Z.C := Z.L;~N", p);
|
401
446
|
generate(g, p->left);
|
402
447
|
w(g, "~MZ.C := Z.Lb;~N");
|
403
448
|
}
|
404
449
|
|
405
|
-
|
406
450
|
static void generate_not(struct generator * g, struct node * p) {
|
407
|
-
struct str * savevar =
|
408
|
-
|
451
|
+
struct str * savevar = NULL;
|
452
|
+
if (K_needed(g, p->left)) {
|
453
|
+
savevar = vars_newname(g);
|
454
|
+
}
|
409
455
|
|
410
|
-
int a0 = g->failure_label
|
456
|
+
int a0 = g->failure_label;
|
411
457
|
struct str * a1 = str_copy(g->failure_str);
|
412
458
|
|
413
459
|
write_comment(g, p);
|
414
|
-
if (
|
460
|
+
if (savevar) {
|
415
461
|
write_savecursor(g, p, savevar);
|
416
462
|
}
|
417
463
|
|
418
464
|
g->failure_label = new_label(g);
|
419
465
|
str_clear(g->failure_str);
|
420
466
|
|
421
|
-
l = g->failure_label;
|
467
|
+
int l = g->failure_label;
|
422
468
|
|
423
469
|
generate(g, p->left);
|
424
470
|
|
@@ -433,32 +479,34 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
433
479
|
|
434
480
|
g->unreachable = false;
|
435
481
|
|
436
|
-
if (
|
437
|
-
|
482
|
+
if (savevar) {
|
483
|
+
write_restorecursor(g, p, savevar);
|
484
|
+
str_delete(savevar);
|
485
|
+
}
|
438
486
|
}
|
439
487
|
|
440
|
-
|
441
488
|
static void generate_try(struct generator * g, struct node * p) {
|
442
|
-
struct str * savevar;
|
443
|
-
|
489
|
+
struct str * savevar = NULL;
|
490
|
+
if (K_needed(g, p->left)) {
|
491
|
+
savevar = vars_newname(g);
|
492
|
+
}
|
444
493
|
|
445
494
|
g->failure_label = new_label(g);
|
446
495
|
g->label_used = 0;
|
447
496
|
str_clear(g->failure_str);
|
448
497
|
|
449
498
|
write_comment(g, p);
|
450
|
-
if (
|
451
|
-
savevar = vars_newname(g);
|
499
|
+
if (savevar) {
|
452
500
|
write_savecursor(g, p, savevar);
|
453
|
-
|
454
|
-
}
|
501
|
+
append_restore_string(p, g->failure_str, savevar);
|
502
|
+
}
|
455
503
|
|
456
504
|
generate(g, p->left);
|
457
505
|
if (g->label_used)
|
458
506
|
wsetl(g, g->failure_label);
|
459
507
|
g->unreachable = false;
|
460
508
|
|
461
|
-
if (
|
509
|
+
if (savevar) {
|
462
510
|
str_delete(savevar);
|
463
511
|
}
|
464
512
|
}
|
@@ -484,30 +532,35 @@ static void generate_fail(struct generator * g, struct node * p) {
|
|
484
532
|
/* generate_test() also implements 'reverse' */
|
485
533
|
|
486
534
|
static void generate_test(struct generator * g, struct node * p) {
|
487
|
-
struct str * savevar =
|
488
|
-
|
535
|
+
struct str * savevar = NULL;
|
536
|
+
if (K_needed(g, p->left)) {
|
537
|
+
savevar = vars_newname(g);
|
538
|
+
}
|
489
539
|
|
490
540
|
write_comment(g, p);
|
491
541
|
|
492
|
-
if (
|
542
|
+
if (savevar) {
|
493
543
|
write_savecursor(g, p, savevar);
|
494
544
|
}
|
495
545
|
|
496
546
|
generate(g, p->left);
|
497
547
|
|
498
|
-
if (
|
499
|
-
if (
|
548
|
+
if (savevar) {
|
549
|
+
if (!g->unreachable) {
|
500
550
|
write_restorecursor(g, p, savevar);
|
501
551
|
}
|
552
|
+
str_delete(savevar);
|
502
553
|
}
|
503
|
-
str_delete(savevar);
|
504
554
|
}
|
505
555
|
|
506
556
|
static void generate_do(struct generator * g, struct node * p) {
|
507
|
-
struct str * savevar =
|
508
|
-
|
557
|
+
struct str * savevar = NULL;
|
558
|
+
if (K_needed(g, p->left)) {
|
559
|
+
savevar = vars_newname(g);
|
560
|
+
}
|
561
|
+
|
509
562
|
write_comment(g, p);
|
510
|
-
if (
|
563
|
+
if (savevar) write_savecursor(g, p, savevar);
|
511
564
|
|
512
565
|
if (p->left->type == c_call) {
|
513
566
|
/* Optimise do <call> */
|
@@ -524,62 +577,60 @@ static void generate_do(struct generator * g, struct node * p) {
|
|
524
577
|
g->unreachable = false;
|
525
578
|
}
|
526
579
|
|
527
|
-
if (
|
528
|
-
|
580
|
+
if (savevar) {
|
581
|
+
write_restorecursor(g, p, savevar);
|
582
|
+
str_delete(savevar);
|
583
|
+
}
|
584
|
+
}
|
585
|
+
|
586
|
+
static void generate_next(struct generator * g, struct node * p) {
|
587
|
+
write_comment(g, p);
|
588
|
+
if (p->mode == m_forward)
|
589
|
+
w(g, "~MC := Skip_Utf8 (Z);~N");
|
590
|
+
else
|
591
|
+
w(g, "~MC := Skip_Utf8_Backward (Z);~N");
|
592
|
+
write_failure_if(g, "C < 0", p);
|
593
|
+
w(g, "~MZ.C := C;~N");
|
594
|
+
g->temporary_used = true;
|
529
595
|
}
|
530
596
|
|
531
597
|
static void generate_GO_grouping(struct generator * g, struct node * p, int is_goto, int complement) {
|
598
|
+
write_comment(g, p);
|
532
599
|
|
533
600
|
struct grouping * q = p->name->grouping;
|
534
601
|
g->S[0] = p->mode == m_forward ? "" : "_Backward";
|
535
602
|
g->S[1] = complement ? "In" : "Out";
|
536
|
-
g->S[2] = g->options->encoding == ENC_UTF8 ? "" : "";
|
537
603
|
g->V[0] = p->name;
|
538
604
|
g->I[0] = q->smallest_ch;
|
539
605
|
g->I[1] = q->largest_ch;
|
540
606
|
if (is_goto) {
|
541
|
-
writef(g, "~M~S1_Grouping~S0
|
607
|
+
writef(g, "~M~S1_Grouping~S0 (Z, ~V0, ~I0, ~I1, True, C);~N", p);
|
542
608
|
write_failure_if(g, "C < 0", p);
|
543
609
|
} else {
|
544
|
-
writef(g, "~C"
|
545
|
-
"~M~S1_Grouping~S0~S2 (Z, ~V0, ~I0, ~I1, True, C);~N", p);
|
610
|
+
writef(g, "~M~S1_Grouping~S0 (Z, ~V0, ~I0, ~I1, True, C);~N", p);
|
546
611
|
write_failure_if(g, "C < 0", p);
|
547
|
-
|
612
|
+
|
548
613
|
if (p->mode == m_forward)
|
549
614
|
w(g, "~MZ.C := Z.C + C;~N");
|
550
615
|
else
|
551
616
|
w(g, "~MZ.C := Z.C - C;~N");
|
552
617
|
}
|
618
|
+
g->temporary_used = true;
|
553
619
|
}
|
554
620
|
|
555
621
|
static void generate_GO(struct generator * g, struct node * p, int style) {
|
556
|
-
|
622
|
+
write_comment(g, p);
|
623
|
+
|
557
624
|
int used = g->label_used;
|
558
|
-
|
559
|
-
struct str * savevar = NULL;
|
560
|
-
int keep_c = style == 1 || repeat_restore(g, p->left);
|
625
|
+
|
561
626
|
int a0 = g->failure_label;
|
562
627
|
|
628
|
+
int end_unreachable = false;
|
563
629
|
int golab = new_label(g);
|
564
|
-
|
565
|
-
if (p->left->type == c_grouping || p->left->type == c_non) {
|
566
|
-
/* Special case for "goto" or "gopast" when used on a grouping or an
|
567
|
-
* inverted grouping - the movement of c by the matching action is
|
568
|
-
* exactly what we want! */
|
569
|
-
#ifdef OPTIMISATION_WARNINGS
|
570
|
-
printf("Optimising %s %s\n", style ? "goto" : "gopast", p->left->type == c_non ? "non" : "grouping");
|
571
|
-
#endif
|
572
|
-
if (g->options->comments) {
|
573
|
-
writef(g, "~M~C", p);
|
574
|
-
}
|
575
|
-
generate_GO_grouping(g, p->left, style, p->left->type == c_non);
|
576
|
-
return;
|
577
|
-
}
|
578
|
-
|
579
|
-
write_comment(g, p);
|
580
630
|
w(g, "~Mloop~N~+");
|
581
631
|
|
582
|
-
|
632
|
+
struct str * savevar = NULL;
|
633
|
+
if (style == 1 || repeat_restore(g, p->left)) {
|
583
634
|
savevar = vars_newname(g);
|
584
635
|
write_savecursor(g, p, savevar);
|
585
636
|
}
|
@@ -602,7 +653,7 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
602
653
|
g->unreachable = false;
|
603
654
|
if (g->label_used)
|
604
655
|
wsetl(g, g->failure_label);
|
605
|
-
if (
|
656
|
+
if (savevar) {
|
606
657
|
write_restorecursor(g, p, savevar);
|
607
658
|
str_delete(savevar);
|
608
659
|
}
|
@@ -612,8 +663,8 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
612
663
|
write_check_limit(g, p);
|
613
664
|
generate_next(g, p);
|
614
665
|
|
615
|
-
g->I[0] = golab;
|
616
666
|
w(g, "~-~Mend loop;~N");
|
667
|
+
|
617
668
|
g->unreachable = end_unreachable;
|
618
669
|
}
|
619
670
|
|
@@ -621,35 +672,34 @@ static void generate_loop(struct generator * g, struct node * p) {
|
|
621
672
|
struct str * loopvar = vars_newname(g);
|
622
673
|
write_comment(g, p);
|
623
674
|
g->B[0] = str_data(loopvar);
|
624
|
-
|
625
|
-
w(g, "~MFor ~B0 := ");
|
675
|
+
w(g, "~Mfor ~B0 in reverse 1 .. ");
|
626
676
|
generate_AE(g, p->AE);
|
627
|
-
writef(g, "
|
628
|
-
writef(g, "~{", p);
|
677
|
+
writef(g, " loop~N~+", p);
|
629
678
|
|
630
679
|
generate(g, p->left);
|
631
680
|
|
632
|
-
w(g, "
|
681
|
+
w(g, "~-~Mend loop;~N");
|
633
682
|
str_delete(loopvar);
|
634
683
|
g->unreachable = false;
|
635
684
|
}
|
636
685
|
|
637
686
|
static void generate_repeat_or_atleast(struct generator * g, struct node * p, struct str * loopvar) {
|
638
|
-
struct str * savevar = vars_newname(g);
|
639
|
-
int keep_c = repeat_restore(g, p->left);
|
640
687
|
int replab = new_label(g);
|
641
|
-
g->I[0] = replab;
|
642
688
|
wsetl(g, replab);
|
643
689
|
writef(g, "~N~Mloop~N~+", p);
|
644
690
|
|
645
|
-
|
691
|
+
struct str * savevar = NULL;
|
692
|
+
if (repeat_restore(g, p->left)) {
|
693
|
+
savevar = vars_newname(g);
|
694
|
+
write_savecursor(g, p, savevar);
|
695
|
+
}
|
646
696
|
|
647
697
|
g->failure_label = new_label(g);
|
648
698
|
g->label_used = 0;
|
649
699
|
generate(g, p->left);
|
650
700
|
|
651
701
|
if (!g->unreachable) {
|
652
|
-
if (loopvar !=
|
702
|
+
if (loopvar != NULL) {
|
653
703
|
g->B[0] = str_data(loopvar);
|
654
704
|
w(g, "~M~B0 := ~B0 - 1;~N");
|
655
705
|
}
|
@@ -661,10 +711,12 @@ static void generate_repeat_or_atleast(struct generator * g, struct node * p, st
|
|
661
711
|
wsetl(g, g->failure_label);
|
662
712
|
g->unreachable = false;
|
663
713
|
|
664
|
-
if (
|
714
|
+
if (savevar) {
|
715
|
+
write_restorecursor(g, p, savevar);
|
716
|
+
str_delete(savevar);
|
717
|
+
}
|
665
718
|
|
666
719
|
w(g, "~N~Mexit;~N~-~Mend loop;~N");
|
667
|
-
str_delete(savevar);
|
668
720
|
}
|
669
721
|
|
670
722
|
static void generate_repeat(struct generator * g, struct node * p) {
|
@@ -678,8 +730,7 @@ static void generate_atleast(struct generator * g, struct node * p) {
|
|
678
730
|
write_comment(g, p);
|
679
731
|
w(g, "~{");
|
680
732
|
g->B[0] = str_data(loopvar);
|
681
|
-
|
682
|
-
write_declare(g, " ~B0 : Integer", p);
|
733
|
+
write_declare(g, "~B0 : Integer", p);
|
683
734
|
w(g, "~M~B0 := ");
|
684
735
|
generate_AE(g, p->AE);
|
685
736
|
w(g, ";~N");
|
@@ -722,22 +773,14 @@ static void generate_atmark(struct generator * g, struct node * p) {
|
|
722
773
|
}
|
723
774
|
|
724
775
|
static void generate_hop(struct generator * g, struct node * p) {
|
776
|
+
write_comment(g, p);
|
725
777
|
g->S[0] = p->mode == m_forward ? "" : "_Backward";
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
} else {
|
731
|
-
w(g, "~MC := Z.C ~S0 ");
|
732
|
-
generate_AE(g, p->AE);
|
733
|
-
writef(g, ";~C~N", p);
|
734
|
-
if (p->mode == m_forward) {
|
735
|
-
write_failure_if(g, "C > Z.L or C < Z.C", p);
|
736
|
-
} else {
|
737
|
-
write_failure_if(g, "C < Z.Lb or C > Z.C", p);
|
738
|
-
}
|
739
|
-
}
|
778
|
+
|
779
|
+
w(g, "~MC := Skip_Utf8~S0 (Z, ");
|
780
|
+
generate_AE(g, p->AE); writef(g, ");~N", p);
|
781
|
+
write_failure_if(g, "C < 0", p);
|
740
782
|
writef(g, "~MZ.C := C;~N", p);
|
783
|
+
g->temporary_used = true;
|
741
784
|
}
|
742
785
|
|
743
786
|
static void generate_delete(struct generator * g, struct node * p) {
|
@@ -745,19 +788,10 @@ static void generate_delete(struct generator * g, struct node * p) {
|
|
745
788
|
writef(g, "~MSlice_Del (Z);~N", p);
|
746
789
|
}
|
747
790
|
|
748
|
-
static void generate_next(struct generator * g, struct node * p) {
|
749
|
-
write_comment(g, p);
|
750
|
-
if (p->mode == m_forward)
|
751
|
-
w(g, "~MC := Skip_Utf8 (Z);~N");
|
752
|
-
else
|
753
|
-
w(g, "~MC := Skip_Utf8_Backward (Z);~N");
|
754
|
-
write_failure_if(g, "C < 0", p);
|
755
|
-
w(g, "~MZ.C := C;~N");
|
756
|
-
}
|
757
|
-
|
758
791
|
static void generate_tolimit(struct generator * g, struct node * p) {
|
792
|
+
write_comment(g, p);
|
759
793
|
g->S[0] = p->mode == m_forward ? "" : "b";
|
760
|
-
writef(g, "~MZ.C := Z.L~S0;~
|
794
|
+
writef(g, "~MZ.C := Z.L~S0;~N", p);
|
761
795
|
}
|
762
796
|
|
763
797
|
static void generate_atlimit(struct generator * g, struct node * p) {
|
@@ -768,18 +802,21 @@ static void generate_atlimit(struct generator * g, struct node * p) {
|
|
768
802
|
}
|
769
803
|
|
770
804
|
static void generate_leftslice(struct generator * g, struct node * p) {
|
805
|
+
write_comment(g, p);
|
771
806
|
g->S[0] = p->mode == m_forward ? "Bra" : "Ket";
|
772
|
-
writef(g, "~MZ.~S0 := Z.C;~
|
807
|
+
writef(g, "~MZ.~S0 := Z.C;~N", p);
|
773
808
|
}
|
774
809
|
|
775
810
|
static void generate_rightslice(struct generator * g, struct node * p) {
|
811
|
+
write_comment(g, p);
|
776
812
|
g->S[0] = p->mode == m_forward ? "Ket" : "Bra";
|
777
|
-
writef(g, "~MZ.~S0 := Z.C;~
|
813
|
+
writef(g, "~MZ.~S0 := Z.C;~N", p);
|
778
814
|
}
|
779
815
|
|
780
816
|
static void generate_assignto(struct generator * g, struct node * p) {
|
817
|
+
write_comment(g, p);
|
781
818
|
g->V[0] = p->name;
|
782
|
-
writef(g, "~M~V0 := Assign_To (Z, ~V0);~
|
819
|
+
writef(g, "~M~V0 := Assign_To (Z, ~V0);~N", p);
|
783
820
|
write_failure_if(g, "~V0 == 0", p);
|
784
821
|
}
|
785
822
|
|
@@ -791,15 +828,16 @@ static void generate_sliceto(struct generator * g, struct node * p) {
|
|
791
828
|
|
792
829
|
static void generate_address(struct generator * g, struct node * p) {
|
793
830
|
symbol * b = p->literalstring;
|
794
|
-
if (b !=
|
831
|
+
if (b != NULL) {
|
795
832
|
write_literal_string(g, b);
|
796
833
|
} else {
|
797
|
-
|
834
|
+
w(g, "Ada.Strings.Unbounded.To_String (");
|
835
|
+
write_varref(g, p->name);
|
836
|
+
w(g, ")");
|
798
837
|
}
|
799
838
|
}
|
800
839
|
|
801
840
|
static void generate_insert(struct generator * g, struct node * p, int style) {
|
802
|
-
|
803
841
|
int keep_c = style == c_attach;
|
804
842
|
write_comment(g, p);
|
805
843
|
if (p->mode == m_backward) keep_c = !keep_c;
|
@@ -807,7 +845,10 @@ static void generate_insert(struct generator * g, struct node * p, int style) {
|
|
807
845
|
writef(g, "~MInsert (Z, Z.C, Z.C, ", p);
|
808
846
|
generate_address(g, p);
|
809
847
|
writef(g, ");~N", p);
|
810
|
-
if (keep_c)
|
848
|
+
if (keep_c) {
|
849
|
+
w(g, "~MZ.C := C;~N");
|
850
|
+
g->temporary_used = true;
|
851
|
+
}
|
811
852
|
}
|
812
853
|
|
813
854
|
static void generate_assignfrom(struct generator * g, struct node * p) {
|
@@ -822,7 +863,10 @@ static void generate_assignfrom(struct generator * g, struct node * p) {
|
|
822
863
|
}
|
823
864
|
generate_address(g, p);
|
824
865
|
writef(g, ");~N", p);
|
825
|
-
if (keep_c)
|
866
|
+
if (keep_c) {
|
867
|
+
w(g, "~MZ.C := C;~N");
|
868
|
+
g->temporary_used = true;
|
869
|
+
}
|
826
870
|
}
|
827
871
|
|
828
872
|
static void generate_slicefrom(struct generator * g, struct node * p) {
|
@@ -833,11 +877,11 @@ static void generate_slicefrom(struct generator * g, struct node * p) {
|
|
833
877
|
}
|
834
878
|
|
835
879
|
static void generate_setlimit(struct generator * g, struct node * p) {
|
836
|
-
struct str * savevar = vars_newname(g);
|
837
880
|
struct str * varname = vars_newname(g);
|
881
|
+
write_comment(g, p);
|
838
882
|
|
839
883
|
g->B[0] = str_data(varname);
|
840
|
-
write_declare(g, "
|
884
|
+
write_declare(g, "~B0 : Integer", p);
|
841
885
|
if (p->left && p->left->type == c_tomark) {
|
842
886
|
/* Special case for:
|
843
887
|
*
|
@@ -848,8 +892,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
848
892
|
* restore c.
|
849
893
|
*/
|
850
894
|
struct node * q = p->left;
|
851
|
-
|
852
|
-
++g->keep_count;
|
895
|
+
write_comment(g, q);
|
853
896
|
|
854
897
|
g->S[0] = q->mode == m_forward ? ">" : "<";
|
855
898
|
|
@@ -877,8 +920,8 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
877
920
|
str_append(g->failure_str, varname);
|
878
921
|
str_append_ch(g->failure_str, ';');
|
879
922
|
}
|
880
|
-
|
881
923
|
} else {
|
924
|
+
struct str * savevar = vars_newname(g);
|
882
925
|
write_savecursor(g, p, savevar);
|
883
926
|
|
884
927
|
generate(g, p->left);
|
@@ -904,6 +947,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
904
947
|
str_append_ch(g->failure_str, ';');
|
905
948
|
}
|
906
949
|
}
|
950
|
+
str_delete(savevar);
|
907
951
|
}
|
908
952
|
|
909
953
|
if (!g->unreachable) {
|
@@ -916,15 +960,15 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
916
960
|
}
|
917
961
|
}
|
918
962
|
str_delete(varname);
|
919
|
-
str_delete(savevar);
|
920
963
|
}
|
921
964
|
|
922
965
|
/* dollar sets snowball up to operate on a string variable as if it were the
|
923
966
|
* current string */
|
924
967
|
static void generate_dollar(struct generator * g, struct node * p) {
|
968
|
+
write_comment(g, p);
|
969
|
+
|
925
970
|
struct str * savevar = vars_newname(g);
|
926
971
|
g->B[0] = str_data(savevar);
|
927
|
-
write_comment(g, p);
|
928
972
|
g->V[0] = p->name;
|
929
973
|
|
930
974
|
{
|
@@ -969,12 +1013,12 @@ static void generate_dollar(struct generator * g, struct node * p) {
|
|
969
1013
|
str_delete(savevar);
|
970
1014
|
}
|
971
1015
|
|
972
|
-
static void generate_integer_assign(struct generator * g, struct node * p, char * s) {
|
973
|
-
|
1016
|
+
static void generate_integer_assign(struct generator * g, struct node * p, const char * s) {
|
1017
|
+
write_comment(g, p);
|
974
1018
|
g->V[0] = p->name;
|
975
1019
|
w(g, "~M~V0 := ");
|
976
1020
|
|
977
|
-
if (s !=
|
1021
|
+
if (s != NULL) {
|
978
1022
|
g->S[0] = s;
|
979
1023
|
w(g, "~V0 ~S0 ");
|
980
1024
|
}
|
@@ -983,60 +1027,82 @@ static void generate_integer_assign(struct generator * g, struct node * p, char
|
|
983
1027
|
w(g, ";~N");
|
984
1028
|
}
|
985
1029
|
|
986
|
-
static void generate_integer_test(struct generator * g, struct node * p
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
}
|
999
|
-
|
1000
|
-
static void generate_integer_function(struct generator * g, struct node * p, char * s) {
|
1001
|
-
|
1002
|
-
w(g, "~MResult := (");
|
1030
|
+
static void generate_integer_test(struct generator * g, struct node * p) {
|
1031
|
+
write_comment(g, p);
|
1032
|
+
int relop = p->type;
|
1033
|
+
int optimise_to_return = (g->failure_label == x_return && p->right && p->right->type == c_functionend);
|
1034
|
+
if (optimise_to_return) {
|
1035
|
+
w(g, "~MResult := (");
|
1036
|
+
p->right = NULL;
|
1037
|
+
} else {
|
1038
|
+
w(g, "~Mif ");
|
1039
|
+
// We want the inverse of the snowball test here.
|
1040
|
+
relop ^= 1;
|
1041
|
+
}
|
1003
1042
|
generate_AE(g, p->left);
|
1004
|
-
|
1005
|
-
write_string(g, s);
|
1006
|
-
write_char(g, ' ');
|
1043
|
+
write_relop(g, relop);
|
1007
1044
|
generate_AE(g, p->AE);
|
1008
|
-
|
1009
|
-
|
1045
|
+
if (optimise_to_return) {
|
1046
|
+
w(g, ");~N");
|
1047
|
+
} else {
|
1048
|
+
w(g, " then~+~N");
|
1049
|
+
write_failure(g);
|
1050
|
+
w(g, "~-~Mend if;~N");
|
1051
|
+
g->unreachable = false;
|
1052
|
+
}
|
1010
1053
|
}
|
1011
1054
|
|
1012
1055
|
static void generate_call(struct generator * g, struct node * p) {
|
1013
|
-
|
1056
|
+
int signals = check_possible_signals_list(g, p->name->definition, c_define, 0);
|
1014
1057
|
write_comment(g, p);
|
1015
1058
|
g->V[0] = p->name;
|
1016
|
-
|
1017
|
-
|
1059
|
+
if (g->failure_label == x_return) {
|
1060
|
+
if (p->right && p->right->type == c_functionend) {
|
1061
|
+
/* Tail call. */
|
1062
|
+
writef(g, "~M~V0 (Z, Result);~N", p);
|
1063
|
+
return;
|
1064
|
+
}
|
1065
|
+
if (signals == 0) {
|
1066
|
+
/* Always fails. */
|
1067
|
+
writef(g, "~M~V0 (Z, Result);~N", p);
|
1068
|
+
w(g, "~Mreturn~N");
|
1069
|
+
return;
|
1070
|
+
}
|
1071
|
+
}
|
1072
|
+
if (signals == 1) {
|
1073
|
+
/* Always succeeds. */
|
1074
|
+
writef(g, "~M~V0 (Z, Result);~N", p);
|
1075
|
+
} else if (signals == 0) {
|
1076
|
+
/* Always fails. */
|
1077
|
+
writef(g, "~M~V0 (Z, Result);~N", p);
|
1078
|
+
write_failure(g);
|
1079
|
+
} else {
|
1080
|
+
writef(g, "~M~V0 (Z, Result);~N", p);
|
1081
|
+
write_failure_if(g, "not Result", p);
|
1082
|
+
}
|
1018
1083
|
}
|
1019
1084
|
|
1020
1085
|
static void generate_grouping(struct generator * g, struct node * p, int complement) {
|
1086
|
+
write_comment(g, p);
|
1021
1087
|
|
1022
1088
|
struct grouping * q = p->name->grouping;
|
1023
1089
|
g->S[0] = p->mode == m_forward ? "" : "_Backward";
|
1024
1090
|
g->S[1] = complement ? "Out_" : "In_";
|
1025
|
-
g->S[2] = g->options->encoding == ENC_UTF8 ? "" : "";
|
1026
1091
|
g->V[0] = p->name;
|
1027
1092
|
g->I[0] = q->smallest_ch;
|
1028
1093
|
g->I[1] = q->largest_ch;
|
1029
|
-
writef(g, "~M~S1Grouping~S0
|
1094
|
+
writef(g, "~M~S1Grouping~S0 (Z, ~V0, ~I0, ~I1, False, C);~N", p);
|
1030
1095
|
write_failure_if(g, "C /= 0", p);
|
1096
|
+
g->temporary_used = true;
|
1031
1097
|
}
|
1032
1098
|
|
1033
1099
|
static void generate_namedstring(struct generator * g, struct node * p) {
|
1034
|
-
|
1035
1100
|
write_comment(g, p);
|
1036
1101
|
g->S[0] = p->mode == m_forward ? "" : "_Backward";
|
1037
1102
|
g->V[0] = p->name;
|
1038
1103
|
writef(g, "~MC := Eq_S~S0 (Z, Ada.Strings.Unbounded.To_String (~V0));", p);
|
1039
1104
|
write_failure_if(g, "C = 0", p);
|
1105
|
+
g->temporary_used = true;
|
1040
1106
|
}
|
1041
1107
|
|
1042
1108
|
static void generate_literalstring(struct generator * g, struct node * p) {
|
@@ -1051,20 +1117,23 @@ static void generate_literalstring(struct generator * g, struct node * p) {
|
|
1051
1117
|
} else {
|
1052
1118
|
writef(g, "~MZ.C := Z.C - C;~N", p);
|
1053
1119
|
}
|
1120
|
+
g->temporary_used = true;
|
1054
1121
|
}
|
1055
1122
|
|
1056
1123
|
static void generate_define(struct generator * g, struct node * p) {
|
1057
|
-
struct
|
1058
|
-
|
1124
|
+
struct name * q = p->name;
|
1125
|
+
if (q->type == t_routine && !q->used) return;
|
1059
1126
|
|
1060
|
-
|
1061
|
-
g
|
1062
|
-
w(g, "~N~Mprocedure ~W0 (Z : in out Context_Type; Result : out Boolean) is~N");
|
1127
|
+
write_newline(g);
|
1128
|
+
write_comment(g, p);
|
1063
1129
|
|
1064
|
-
/*
|
1065
|
-
|
1066
|
-
|
1130
|
+
/* Generate function header. */
|
1131
|
+
g->V[0] = q;
|
1132
|
+
w(g, "~Mprocedure ~W0 (Z : in out Context_Type; Result : out Boolean) is~N");
|
1067
1133
|
|
1134
|
+
/* Save output. */
|
1135
|
+
struct str *saved_output = g->outbuf;
|
1136
|
+
struct str *saved_declarations = g->declarations;
|
1068
1137
|
g->outbuf = str_new();
|
1069
1138
|
g->declarations = str_new();
|
1070
1139
|
|
@@ -1076,25 +1145,26 @@ static void generate_define(struct generator * g, struct node * p) {
|
|
1076
1145
|
|
1077
1146
|
/* Generate function body. */
|
1078
1147
|
w(g, "~{");
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
generate(g, p->left);
|
1088
|
-
if (!g->unreachable) w(g, "~N~MResult := True;~N");
|
1089
|
-
str_append_string(saved_output, " C : Result_Index;\n");
|
1090
|
-
if (need_among_var(p->left) || 1) {
|
1091
|
-
str_append_string(saved_output, " A : Integer;\n");
|
1092
|
-
}
|
1093
|
-
break;
|
1148
|
+
int signals = check_possible_signals_list(g, p->left, c_define, 0);
|
1149
|
+
g->temporary_used = false;
|
1150
|
+
generate(g, p->left);
|
1151
|
+
if (p->left->right) {
|
1152
|
+
assert(p->left->right->type == c_functionend);
|
1153
|
+
if (signals) {
|
1154
|
+
generate(g, p->left->right);
|
1155
|
+
}
|
1094
1156
|
}
|
1095
|
-
g->V[0] =
|
1157
|
+
g->V[0] = q;
|
1096
1158
|
w(g, "~-~Mend ~W0;~N");
|
1097
1159
|
|
1160
|
+
if (g->temporary_used) {
|
1161
|
+
str_append_string(saved_output, " C : Result_Index;\n");
|
1162
|
+
}
|
1163
|
+
|
1164
|
+
if (need_among_var(p->left)) {
|
1165
|
+
str_append_string(saved_output, " A : Integer;\n");
|
1166
|
+
}
|
1167
|
+
|
1098
1168
|
if (g->var_number) {
|
1099
1169
|
str_append(saved_output, g->declarations);
|
1100
1170
|
}
|
@@ -1106,39 +1176,36 @@ static void generate_define(struct generator * g, struct node * p) {
|
|
1106
1176
|
g->outbuf = saved_output;
|
1107
1177
|
}
|
1108
1178
|
|
1179
|
+
static void generate_functionend(struct generator * g, struct node * p) {
|
1180
|
+
(void)p;
|
1181
|
+
w(g, "~MResult := True;~N");
|
1182
|
+
}
|
1183
|
+
|
1109
1184
|
static void generate_substring(struct generator * g, struct node * p) {
|
1185
|
+
write_comment(g, p);
|
1186
|
+
|
1110
1187
|
struct among * x = p->among;
|
1111
1188
|
int block = -1;
|
1112
1189
|
unsigned int bitmap = 0;
|
1113
1190
|
struct amongvec * among_cases = x->b;
|
1114
|
-
int c;
|
1115
1191
|
int empty_case = -1;
|
1116
1192
|
int n_cases = 0;
|
1117
1193
|
symbol cases[2];
|
1118
|
-
int shortest_size =
|
1194
|
+
int shortest_size = x->shortest_size;
|
1119
1195
|
int call_done = 0;
|
1120
|
-
int
|
1121
|
-
|
1122
|
-
write_comment(g, p);
|
1196
|
+
int need_among_handler = (x->function_count > 0);
|
1123
1197
|
|
1124
1198
|
g->S[0] = p->mode == m_forward ? "" : "_Backward";
|
1125
1199
|
g->I[0] = x->number;
|
1126
1200
|
|
1127
|
-
/* In forward mode with non-ASCII UTF-8 characters, the first
|
1201
|
+
/* In forward mode with non-ASCII UTF-8 characters, the first byte
|
1128
1202
|
* of the string will often be the same, so instead look at the last
|
1129
|
-
* common
|
1203
|
+
* common byte position.
|
1130
1204
|
*
|
1131
1205
|
* In backward mode, we can't match if there are fewer characters before
|
1132
1206
|
* the current position than the minimum length.
|
1133
1207
|
*/
|
1134
|
-
for (c = 0; c < x->literalstring_count; ++c) {
|
1135
|
-
int size = among_cases[c].size;
|
1136
|
-
if (size != 0 && size < shortest_size) {
|
1137
|
-
shortest_size = size;
|
1138
|
-
}
|
1139
|
-
}
|
1140
|
-
|
1141
|
-
for (c = 0; c < x->literalstring_count; ++c) {
|
1208
|
+
for (int c = 0; c < x->literalstring_count; ++c) {
|
1142
1209
|
symbol ch;
|
1143
1210
|
if (among_cases[c].size == 0) {
|
1144
1211
|
empty_case = c;
|
@@ -1225,16 +1292,18 @@ static void generate_substring(struct generator * g, struct node * p) {
|
|
1225
1292
|
* so not matching the bitmap means we match the empty string.
|
1226
1293
|
*/
|
1227
1294
|
g->I[4] = among_cases[empty_case].result;
|
1228
|
-
writef(g, "~MA := ~I4;~-~N~Melse~+~
|
1229
|
-
if (
|
1295
|
+
writef(g, "~MA := ~I4;~-~N~Melse~+~N", p);
|
1296
|
+
if (need_among_handler) {
|
1230
1297
|
writef(g, "~MFind_Among~S0 (Z, A_~I0, Among_String, Among_Handler'Access, A);~N", p);
|
1231
1298
|
} else {
|
1232
1299
|
writef(g, "~MFind_Among~S0 (Z, A_~I0, Among_String, null, A);~N", p);
|
1233
1300
|
}
|
1234
|
-
|
1301
|
+
if (!x->always_matches) {
|
1302
|
+
write_failure_if(g, "A = 0", p);
|
1303
|
+
}
|
1235
1304
|
call_done = 1;
|
1236
1305
|
} else {
|
1237
|
-
|
1306
|
+
write_failure(g);
|
1238
1307
|
}
|
1239
1308
|
writef(g, "~-~Mend if;~N", p);
|
1240
1309
|
} else {
|
@@ -1244,31 +1313,32 @@ static void generate_substring(struct generator * g, struct node * p) {
|
|
1244
1313
|
}
|
1245
1314
|
|
1246
1315
|
if (!call_done) {
|
1247
|
-
if (
|
1316
|
+
if (need_among_handler) {
|
1248
1317
|
writef(g, "~MFind_Among~S0 (Z, A_~I0, Among_String, Among_Handler'Access, A);~N", p);
|
1249
1318
|
} else {
|
1250
1319
|
writef(g, "~MFind_Among~S0 (Z, A_~I0, Among_String, null, A);~N", p);
|
1251
1320
|
}
|
1252
|
-
|
1321
|
+
if (!x->always_matches) {
|
1322
|
+
write_failure_if(g, "A = 0", p);
|
1323
|
+
}
|
1253
1324
|
}
|
1254
1325
|
}
|
1255
1326
|
|
1256
1327
|
static void generate_among(struct generator * g, struct node * p) {
|
1257
|
-
|
1258
1328
|
struct among * x = p->among;
|
1259
1329
|
|
1260
|
-
if (x->substring ==
|
1261
|
-
|
1262
|
-
|
1330
|
+
if (x->substring == NULL) {
|
1331
|
+
generate_substring(g, p);
|
1332
|
+
} else {
|
1333
|
+
write_comment(g, p);
|
1334
|
+
}
|
1263
1335
|
|
1264
1336
|
if (x->command_count == 1 && x->nocommand_count == 0) {
|
1265
1337
|
/* Only one outcome ("no match" already handled). */
|
1266
1338
|
generate(g, x->commands[0]);
|
1267
1339
|
} else if (x->command_count > 0) {
|
1268
|
-
int i;
|
1269
|
-
write_comment(g, p);
|
1270
1340
|
w(g, "~Mcase A is~N~+");
|
1271
|
-
for (i = 1; i <= x->command_count; i++) {
|
1341
|
+
for (int i = 1; i <= x->command_count; i++) {
|
1272
1342
|
g->I[0] = i;
|
1273
1343
|
w(g, "~Mwhen ~I0 =>~N");
|
1274
1344
|
g->margin++;
|
@@ -1283,20 +1353,17 @@ static void generate_among(struct generator * g, struct node * p) {
|
|
1283
1353
|
}
|
1284
1354
|
|
1285
1355
|
static void generate_booltest(struct generator * g, struct node * p) {
|
1286
|
-
|
1287
1356
|
write_comment(g, p);
|
1288
1357
|
g->V[0] = p->name;
|
1289
1358
|
write_failure_if(g, "not ~V0", p);
|
1290
1359
|
}
|
1291
1360
|
|
1292
1361
|
static void generate_false(struct generator * g, struct node * p) {
|
1293
|
-
|
1294
1362
|
write_comment(g, p);
|
1295
1363
|
write_failure(g);
|
1296
1364
|
}
|
1297
1365
|
|
1298
1366
|
static void generate_debug(struct generator * g, struct node * p) {
|
1299
|
-
|
1300
1367
|
write_comment(g, p);
|
1301
1368
|
g->I[0] = g->debug_count++;
|
1302
1369
|
g->I[1] = p->line_number;
|
@@ -1304,14 +1371,10 @@ static void generate_debug(struct generator * g, struct node * p) {
|
|
1304
1371
|
}
|
1305
1372
|
|
1306
1373
|
static void generate(struct generator * g, struct node * p) {
|
1307
|
-
|
1308
|
-
int a0;
|
1309
|
-
struct str * a1;
|
1310
|
-
|
1311
1374
|
if (g->unreachable) return;
|
1312
1375
|
|
1313
|
-
a0 = g->failure_label;
|
1314
|
-
a1 = str_copy(g->failure_str);
|
1376
|
+
int a0 = g->failure_label;
|
1377
|
+
struct str * a1 = str_copy(g->failure_str);
|
1315
1378
|
|
1316
1379
|
switch (p->type) {
|
1317
1380
|
case c_define: generate_define(g, p); break;
|
@@ -1329,6 +1392,11 @@ static void generate(struct generator * g, struct node * p) {
|
|
1329
1392
|
case c_do: generate_do(g, p); break;
|
1330
1393
|
case c_goto: generate_GO(g, p, 1); break;
|
1331
1394
|
case c_gopast: generate_GO(g, p, 0); break;
|
1395
|
+
case c_goto_grouping: generate_GO_grouping(g, p, 1, 0); break;
|
1396
|
+
case c_gopast_grouping:
|
1397
|
+
generate_GO_grouping(g, p, 0, 0); break;
|
1398
|
+
case c_goto_non: generate_GO_grouping(g, p, 1, 1); break;
|
1399
|
+
case c_gopast_non: generate_GO_grouping(g, p, 0, 1); break;
|
1332
1400
|
case c_repeat: generate_repeat(g, p); break;
|
1333
1401
|
case c_loop: generate_loop(g, p); break;
|
1334
1402
|
case c_atleast: generate_atleast(g, p); break;
|
@@ -1355,12 +1423,14 @@ static void generate(struct generator * g, struct node * p) {
|
|
1355
1423
|
case c_minusassign: generate_integer_assign(g, p, "-"); break;
|
1356
1424
|
case c_multiplyassign:generate_integer_assign(g, p, "*"); break;
|
1357
1425
|
case c_divideassign: generate_integer_assign(g, p, "/"); break;
|
1358
|
-
case c_eq:
|
1359
|
-
case c_ne:
|
1360
|
-
case
|
1361
|
-
case c_ge:
|
1362
|
-
case
|
1363
|
-
case c_le:
|
1426
|
+
case c_eq:
|
1427
|
+
case c_ne:
|
1428
|
+
case c_gt:
|
1429
|
+
case c_ge:
|
1430
|
+
case c_lt:
|
1431
|
+
case c_le:
|
1432
|
+
generate_integer_test(g, p);
|
1433
|
+
break;
|
1364
1434
|
case c_call: generate_call(g, p); break;
|
1365
1435
|
case c_grouping: generate_grouping(g, p, false); break;
|
1366
1436
|
case c_non: generate_grouping(g, p, true); break;
|
@@ -1372,6 +1442,7 @@ static void generate(struct generator * g, struct node * p) {
|
|
1372
1442
|
case c_false: generate_false(g, p); break;
|
1373
1443
|
case c_true: break;
|
1374
1444
|
case c_debug: generate_debug(g, p); break;
|
1445
|
+
case c_functionend: generate_functionend(g, p); break;
|
1375
1446
|
default: fprintf(stderr, "%d encountered\n", p->type);
|
1376
1447
|
exit(1);
|
1377
1448
|
}
|
@@ -1393,51 +1464,31 @@ static void generate_method_decl(struct generator * g, struct name * q) {
|
|
1393
1464
|
}
|
1394
1465
|
|
1395
1466
|
static void generate_method_decls(struct generator * g, enum name_types type) {
|
1396
|
-
struct name * q;
|
1397
1467
|
struct among * a = g->analyser->amongs;
|
1398
|
-
int
|
1468
|
+
int need_among_handler = 0;
|
1399
1469
|
|
1400
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1470
|
+
for (struct name * q = g->analyser->names; q; q = q->next) {
|
1401
1471
|
if ((enum name_types)q->type == type) {
|
1402
1472
|
generate_method_decl(g, q);
|
1403
1473
|
}
|
1404
1474
|
}
|
1405
1475
|
|
1406
|
-
while (a !=
|
1407
|
-
|
1476
|
+
while (a != NULL && need_among_handler == 0) {
|
1477
|
+
need_among_handler = (a->function_count > 0);
|
1408
1478
|
a = a->next;
|
1409
1479
|
}
|
1410
|
-
if (
|
1480
|
+
if (need_among_handler) {
|
1411
1481
|
w(g, "~N~Mprocedure Among_Handler (Context : in out Stemmer.Context_Type'Class; Operation : in Operation_Index; Result : out Boolean);~N");
|
1412
1482
|
}
|
1413
1483
|
}
|
1414
1484
|
|
1415
|
-
static int has_string_variable(struct generator * g) {
|
1416
|
-
struct name * q;
|
1417
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1418
|
-
g->V[0] = q;
|
1419
|
-
if (q->type == t_string) {
|
1420
|
-
return 1;
|
1421
|
-
}
|
1422
|
-
}
|
1423
|
-
|
1424
|
-
return 0;
|
1425
|
-
}
|
1426
|
-
|
1427
1485
|
static void generate_member_decls(struct generator * g) {
|
1428
|
-
struct name * q;
|
1429
|
-
int count = 0;
|
1430
|
-
|
1431
|
-
|
1432
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1433
|
-
if (q->type == t_string || q->type == t_integer || q->type == t_boolean)
|
1434
|
-
count++;
|
1435
|
-
}
|
1436
|
-
|
1437
1486
|
w(g, " type Context_Type is new Stemmer.Context_Type with");
|
1438
|
-
if (
|
1487
|
+
if (g->analyser->name_count[t_string] > 0 ||
|
1488
|
+
g->analyser->name_count[t_integer] > 0 ||
|
1489
|
+
g->analyser->name_count[t_boolean] > 0) {
|
1439
1490
|
w(g, " record~N~+");
|
1440
|
-
for (q = g->analyser->names; q; q = q->next) {
|
1491
|
+
for (struct name * q = g->analyser->names; q; q = q->next) {
|
1441
1492
|
g->V[0] = q;
|
1442
1493
|
switch (q->type) {
|
1443
1494
|
case t_string:
|
@@ -1460,13 +1511,12 @@ static void generate_member_decls(struct generator * g) {
|
|
1460
1511
|
}
|
1461
1512
|
|
1462
1513
|
static int generate_among_string(struct generator * g, struct among * x, int count) {
|
1463
|
-
int i;
|
1464
1514
|
struct amongvec * v = x->b;
|
1465
1515
|
int limit = count == 0 ? 38 : 80;
|
1466
1516
|
|
1467
1517
|
g->I[0] = x->number;
|
1468
1518
|
|
1469
|
-
for (i = 0; i < x->literalstring_count; i++, v++) {
|
1519
|
+
for (int i = 0; i < x->literalstring_count; i++, v++) {
|
1470
1520
|
/* Write among's string. */
|
1471
1521
|
g->L[0] = v->b;
|
1472
1522
|
g->I[1] = i;
|
@@ -1484,7 +1534,8 @@ static int generate_among_string(struct generator * g, struct among * x, int cou
|
|
1484
1534
|
}
|
1485
1535
|
|
1486
1536
|
static int generate_among_table(struct generator * g, struct among * x, int start_pos, int *operation) {
|
1487
|
-
|
1537
|
+
write_comment(g, x->node);
|
1538
|
+
|
1488
1539
|
struct amongvec * v = x->b;
|
1489
1540
|
|
1490
1541
|
g->I[0] = x->number;
|
@@ -1493,7 +1544,7 @@ static int generate_among_table(struct generator * g, struct among * x, int star
|
|
1493
1544
|
w(g, "~MA_~I0 : constant Among_Array_Type (0 .. ~I1) := ~+(~N");
|
1494
1545
|
|
1495
1546
|
v = x->b;
|
1496
|
-
for (i = 0; i < x->literalstring_count; i
|
1547
|
+
for (int i = 0; i < x->literalstring_count; i++) {
|
1497
1548
|
g->I[1] = start_pos;
|
1498
1549
|
|
1499
1550
|
/* Write among's string position. */
|
@@ -1502,18 +1553,18 @@ static int generate_among_table(struct generator * g, struct among * x, int star
|
|
1502
1553
|
} else {
|
1503
1554
|
w(g, "~M(~I1, ");
|
1504
1555
|
}
|
1505
|
-
start_pos = start_pos + SIZE(v
|
1556
|
+
start_pos = start_pos + SIZE(v[i].b);
|
1506
1557
|
g->I[1] = start_pos - 1;
|
1507
1558
|
w(g, "~I1, ");
|
1508
1559
|
|
1509
1560
|
/* Write among's index & result. */
|
1510
|
-
g->I[2] = v
|
1561
|
+
g->I[2] = v[i].i;
|
1511
1562
|
w(g, "~I2, ");
|
1512
|
-
g->I[2] = v
|
1563
|
+
g->I[2] = v[i].result;
|
1513
1564
|
w(g, "~I2, ");
|
1514
1565
|
|
1515
1566
|
/* Write among's handler. */
|
1516
|
-
if (v
|
1567
|
+
if (v[i].function == NULL) {
|
1517
1568
|
w(g, "0)");
|
1518
1569
|
} else {
|
1519
1570
|
*operation = *operation + 1;
|
@@ -1530,12 +1581,13 @@ static int generate_among_table(struct generator * g, struct among * x, int star
|
|
1530
1581
|
|
1531
1582
|
static int generate_amongs(struct generator * g) {
|
1532
1583
|
struct among * a = g->analyser->amongs;
|
1584
|
+
if (!a) return 0;
|
1533
1585
|
int count;
|
1534
1586
|
int start_pos;
|
1535
|
-
|
1587
|
+
|
1536
1588
|
w(g, "~MAmong_String : constant String := ~+");
|
1537
1589
|
count = 0;
|
1538
|
-
while (a !=
|
1590
|
+
while (a != NULL) {
|
1539
1591
|
count = generate_among_string(g, a, count);
|
1540
1592
|
a = a->next;
|
1541
1593
|
}
|
@@ -1544,7 +1596,7 @@ static int generate_amongs(struct generator * g) {
|
|
1544
1596
|
int operation = 0;
|
1545
1597
|
start_pos = 1;
|
1546
1598
|
a = g->analyser->amongs;
|
1547
|
-
while (a !=
|
1599
|
+
while (a != NULL) {
|
1548
1600
|
start_pos = generate_among_table(g, a, start_pos, &operation);
|
1549
1601
|
a = a->next;
|
1550
1602
|
}
|
@@ -1556,34 +1608,29 @@ static int generate_constructor(struct generator * g) {
|
|
1556
1608
|
}
|
1557
1609
|
|
1558
1610
|
static void generate_methods(struct generator * g) {
|
1559
|
-
struct node * p = g->analyser->program;
|
1560
|
-
while (p != 0) {
|
1611
|
+
for (struct node * p = g->analyser->program; p; p = p->right) {
|
1561
1612
|
generate(g, p);
|
1562
|
-
|
1613
|
+
g->unreachable = false;
|
1563
1614
|
}
|
1564
1615
|
}
|
1565
1616
|
|
1566
1617
|
static int generate_operations_dispatcher(struct generator * g) {
|
1567
|
-
struct among * a = g->analyser->amongs;
|
1568
|
-
int i;
|
1569
1618
|
int operation = 0;
|
1570
1619
|
|
1571
1620
|
w(g, "~N~Mprocedure Among_Handler (Context : in out Stemmer.Context_Type'Class; Operation : in Operation_Index; Result : out Boolean) is~N");
|
1572
1621
|
w(g, "~Mbegin~+~N~M");
|
1573
1622
|
w(g, "case Operation is~+~N~M");
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
if (v->function != 0) {
|
1623
|
+
for (struct among * x = g->analyser->amongs; x; x = x->next) {
|
1624
|
+
struct amongvec * v = x->b;
|
1625
|
+
for (int i = 0; i < x->literalstring_count; i++) {
|
1626
|
+
if (v[i].function != NULL) {
|
1579
1627
|
operation++;
|
1580
1628
|
g->I[2] = operation;
|
1581
1629
|
w(g, "when ~I2 =>~N~M");
|
1582
|
-
g->V[0] = v
|
1630
|
+
g->V[0] = v[i].function;
|
1583
1631
|
w(g, " ~W0 (Context_Type (Context), Result);~N~M");
|
1584
1632
|
}
|
1585
1633
|
}
|
1586
|
-
a = a->next;
|
1587
1634
|
}
|
1588
1635
|
w(g, "when others =>~N~M");
|
1589
1636
|
w(g, " Result := False;~-~N~Mend case;~-~N~M");
|
@@ -1594,36 +1641,29 @@ static int generate_operations_dispatcher(struct generator * g) {
|
|
1594
1641
|
static void set_bit(symbol * b, int i) { b[i/8] |= 1 << i%8; }
|
1595
1642
|
|
1596
1643
|
static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
1597
|
-
|
1598
1644
|
int range = q->largest_ch - q->smallest_ch + 1;
|
1599
1645
|
int size = (range + 7)/ 8; /* assume 8 bits per symbol */
|
1600
1646
|
symbol * b = q->b;
|
1601
1647
|
symbol * map = create_b(size);
|
1602
|
-
int i;
|
1603
|
-
int count = 0;
|
1604
1648
|
int need_comma = 0;
|
1605
1649
|
|
1606
|
-
for (i = 0; i < size; i++) map[i] = 0;
|
1650
|
+
for (int i = 0; i < size; i++) map[i] = 0;
|
1607
1651
|
|
1608
|
-
|
1609
|
-
|
1610
|
-
for (i = 0; i < SIZE(b); i++) set_bit(map, b[i] - q->smallest_ch);
|
1652
|
+
for (int i = 0; i < SIZE(b); i++) set_bit(map, b[i] - q->smallest_ch);
|
1611
1653
|
|
1612
1654
|
g->V[0] = q->name;
|
1613
1655
|
g->I[0] = 8 * size - 1;
|
1614
1656
|
w(g, "~N~M~W0 : constant Grouping_Array (0 .. ~I0) := (~N~+~M");
|
1615
|
-
for (i = 0; i < size; i++) {
|
1657
|
+
for (int i = 0; i < size; i++) {
|
1616
1658
|
unsigned char m = map[i];
|
1617
|
-
int j;
|
1618
|
-
count++;
|
1619
1659
|
if (i != 0) {
|
1620
1660
|
w(g, ",~N~M");
|
1621
1661
|
need_comma = 0;
|
1622
1662
|
}
|
1623
|
-
for (j = 0; j < 8; j++) {
|
1663
|
+
for (int j = 0; j < 8; j++) {
|
1624
1664
|
if (need_comma)
|
1625
1665
|
w(g, ", ");
|
1626
|
-
|
1666
|
+
|
1627
1667
|
if (m & (1 << j)) {
|
1628
1668
|
w(g, "True");
|
1629
1669
|
} else {
|
@@ -1633,20 +1673,18 @@ static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
|
1633
1673
|
}
|
1634
1674
|
}
|
1635
1675
|
w(g, "~N~-~M);~N");
|
1636
|
-
|
1676
|
+
|
1637
1677
|
lose_b(map);
|
1638
1678
|
}
|
1639
1679
|
|
1640
1680
|
static void generate_groupings(struct generator * g) {
|
1641
|
-
struct grouping * q;
|
1642
|
-
for (q = g->analyser->groupings; q; q = q->next) {
|
1681
|
+
for (struct grouping * q = g->analyser->groupings; q; q = q->next) {
|
1643
1682
|
if (q->name->used)
|
1644
1683
|
generate_grouping_table(g, q);
|
1645
1684
|
}
|
1646
1685
|
}
|
1647
1686
|
|
1648
1687
|
extern void generate_program_ada(struct generator * g) {
|
1649
|
-
|
1650
1688
|
g->outbuf = str_new();
|
1651
1689
|
g->failure_str = str_new();
|
1652
1690
|
|
@@ -1683,7 +1721,7 @@ extern void generate_program_ada(struct generator * g) {
|
|
1683
1721
|
|
1684
1722
|
g->margin = 0;
|
1685
1723
|
write_start_comment(g, "-- ", NULL);
|
1686
|
-
if (
|
1724
|
+
if (g->analyser->name_count[t_string]) {
|
1687
1725
|
w(g, "private with Ada.Strings.Unbounded;~N");
|
1688
1726
|
}
|
1689
1727
|
w(g, "package Stemmer.");
|