mittens 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile +2 -1
- data/README.md +2 -2
- data/Rakefile +12 -5
- data/ext/mittens/extconf.rb +3 -1
- data/lib/mittens/version.rb +1 -1
- data/vendor/snowball/.github/workflows/ci.yml +144 -17
- data/vendor/snowball/.github/workflows/coverage.yml +117 -0
- data/vendor/snowball/.github/workflows/runtime-tests.yml +26 -0
- data/vendor/snowball/.gitignore +33 -7
- data/vendor/snowball/CONTRIBUTING.rst +7 -0
- data/vendor/snowball/COPYING +1 -1
- data/vendor/snowball/GNUmakefile +736 -298
- data/vendor/snowball/NEWS +1394 -7
- data/vendor/snowball/README.rst +8 -8
- data/vendor/snowball/ada/generate/generate.adb +5 -5
- data/vendor/snowball/ada/src/stemmer.adb +177 -188
- data/vendor/snowball/ada/src/stemmer.ads +86 -89
- data/vendor/snowball/ada/src/stemwords.adb +21 -5
- data/vendor/snowball/algorithms/czech.sbl +255 -0
- data/vendor/snowball/algorithms/danish.sbl +22 -10
- data/vendor/snowball/algorithms/english.sbl +7 -4
- data/vendor/snowball/algorithms/esperanto.sbl +6 -7
- data/vendor/snowball/algorithms/estonian.sbl +9 -4
- data/vendor/snowball/algorithms/finnish.sbl +33 -21
- data/vendor/snowball/algorithms/german.sbl +5 -0
- data/vendor/snowball/algorithms/indonesian.sbl +115 -96
- data/vendor/snowball/algorithms/italian.sbl +26 -1
- data/vendor/snowball/algorithms/lithuanian.sbl +13 -13
- data/vendor/snowball/algorithms/norwegian.sbl +17 -6
- data/vendor/snowball/algorithms/persian.sbl +387 -0
- data/vendor/snowball/algorithms/polish.sbl +177 -0
- data/vendor/snowball/algorithms/sesotho.sbl +115 -0
- data/vendor/snowball/algorithms/turkish.sbl +4 -4
- data/vendor/snowball/compiler/analyser.c +2002 -711
- data/vendor/snowball/compiler/driver.c +460 -298
- data/vendor/snowball/compiler/generator.c +439 -1965
- data/vendor/snowball/compiler/generator_ada.c +605 -430
- data/vendor/snowball/compiler/generator_c.c +2227 -0
- data/vendor/snowball/compiler/generator_csharp.c +365 -274
- data/vendor/snowball/compiler/generator_dart.c +1476 -0
- data/vendor/snowball/compiler/generator_go.c +348 -270
- data/vendor/snowball/compiler/generator_java.c +330 -233
- data/vendor/snowball/compiler/generator_js.c +534 -385
- data/vendor/snowball/compiler/generator_pascal.c +361 -320
- data/vendor/snowball/compiler/generator_php.c +1445 -0
- data/vendor/snowball/compiler/generator_python.c +399 -299
- data/vendor/snowball/compiler/generator_rust.c +370 -261
- data/vendor/snowball/compiler/generator_zig.c +1474 -0
- data/vendor/snowball/compiler/header.h +153 -86
- data/vendor/snowball/compiler/space.c +121 -63
- data/vendor/snowball/compiler/tokeniser.c +286 -182
- data/vendor/snowball/compiler/tokens.h +71 -0
- data/vendor/snowball/csharp/Snowball/Among.cs +14 -26
- data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +3 -3
- data/vendor/snowball/csharp/Snowball/Stemmer.cs +41 -45
- data/vendor/snowball/csharp/Stemwords/Program.cs +20 -14
- data/vendor/snowball/cxx/.gitignore +4 -0
- data/vendor/snowball/cxx/generate_algorithms.pl +87 -0
- data/vendor/snowball/cxx/stemmer.h +12 -0
- data/vendor/snowball/cxx/stemwords.cxx +176 -0
- data/vendor/snowball/cxx/utilities.cxx +2 -0
- data/vendor/snowball/dart/.gitignore +4 -0
- data/vendor/snowball/dart/analysis_options.yaml +1 -0
- data/vendor/snowball/dart/example/test_app.dart +65 -0
- data/vendor/snowball/dart/generate_algorithms.pl +21 -0
- data/vendor/snowball/dart/lib/snowball.dart +18 -0
- data/vendor/snowball/dart/lib/src/snowball.dart +339 -0
- data/vendor/snowball/dart/pubspec.yaml +17 -0
- data/vendor/snowball/doc/libstemmer_dart_README +37 -0
- data/vendor/snowball/doc/libstemmer_js_README +2 -2
- data/vendor/snowball/doc/libstemmer_php_README +38 -0
- data/vendor/snowball/doc/libstemmer_python_README +3 -3
- data/vendor/snowball/examples/stemwords.c +18 -3
- data/vendor/snowball/go/README.md +12 -4
- data/vendor/snowball/go/env.go +12 -14
- data/vendor/snowball/go/stemwords/main.go +2 -1
- data/vendor/snowball/java/org/tartarus/snowball/CharArraySequence.java +36 -0
- data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +17 -34
- data/vendor/snowball/java/org/tartarus/snowball/SnowballStemmer.java +0 -2
- data/vendor/snowball/javascript/base-stemmer.js +219 -252
- data/vendor/snowball/javascript/stemwords.js +86 -58
- data/vendor/snowball/libstemmer/mkmodules.pl +1 -1
- data/vendor/snowball/libstemmer/modules.txt +4 -0
- data/vendor/snowball/pascal/SnowballProgram.pas +18 -31
- data/vendor/snowball/php/base-stemmer.php +453 -0
- data/vendor/snowball/php/stemwords.php +25 -0
- data/vendor/snowball/python/create_init.py +16 -21
- data/vendor/snowball/python/pyproject.toml +3 -0
- data/vendor/snowball/python/setup.py +5 -7
- data/vendor/snowball/python/snowballstemmer/among.py +1 -2
- data/vendor/snowball/python/snowballstemmer/basestemmer.py +24 -33
- data/vendor/snowball/python/stemwords.py +72 -63
- data/vendor/snowball/runtime/api.c +11 -42
- data/vendor/snowball/runtime/api.h +11 -9
- data/vendor/snowball/runtime/snowball_runtime.h +110 -0
- data/vendor/snowball/runtime/utilities.c +282 -106
- data/vendor/snowball/rust/src/main.rs +2 -2
- data/vendor/snowball/rust/src/snowball/snowball_env.rs +7 -9
- data/vendor/snowball/tests/compilertest +62 -0
- data/vendor/snowball/tests/errors/ae-errors.sbl +53 -0
- data/vendor/snowball/tests/errors/ae-errors.stderr +8 -0
- data/vendor/snowball/tests/errors/bad-dollar.sbl +14 -0
- data/vendor/snowball/tests/errors/bad-dollar.stderr +4 -0
- data/vendor/snowball/tests/errors/bad-grouping-definition.sbl +9 -0
- data/vendor/snowball/tests/errors/bad-grouping-definition.stderr +6 -0
- data/vendor/snowball/tests/errors/missing-bra.sbl +6 -0
- data/vendor/snowball/tests/errors/missing-bra.stderr +3 -0
- data/vendor/snowball/tests/errors/missing-command.sbl +9 -0
- data/vendor/snowball/tests/errors/missing-command.stderr +1 -0
- data/vendor/snowball/tests/errors/missing-ket-backwardmode.sbl +3 -0
- data/vendor/snowball/tests/errors/missing-ket-backwardmode.stderr +1 -0
- data/vendor/snowball/tests/errors/missing-ket.sbl +7 -0
- data/vendor/snowball/tests/errors/missing-ket.stderr +6 -0
- data/vendor/snowball/tests/errors/notdefined.sbl +4 -0
- data/vendor/snowball/tests/errors/notdefined.stderr +2 -0
- data/vendor/snowball/tests/errors/string-omitted.sbl +5 -0
- data/vendor/snowball/tests/errors/string-omitted.stderr +1 -0
- data/vendor/snowball/tests/errors/undeclared.sbl +20 -0
- data/vendor/snowball/tests/errors/undeclared.stderr +9 -0
- data/vendor/snowball/tests/errors/unexpected-token.sbl +24 -0
- data/vendor/snowball/tests/errors/unexpected-token.stderr +17 -0
- data/vendor/snowball/tests/errors/wrongdirection.sbl +14 -0
- data/vendor/snowball/tests/errors/wrongdirection.stderr +1 -0
- data/vendor/snowball/tests/runtime/among.sbl +19 -0
- data/vendor/snowball/tests/runtime/arithmeticexpr.sbl +86 -0
- data/vendor/snowball/tests/runtime/attachinsert.sbl +47 -0
- data/vendor/snowball/tests/runtime/booleans.sbl +19 -0
- data/vendor/snowball/tests/runtime/externals.sbl +22 -0
- data/vendor/snowball/tests/runtime/hop.sbl +12 -0
- data/vendor/snowball/tests/runtime/integertests.sbl +60 -0
- data/vendor/snowball/tests/runtime/intlimits.sbl +25 -0
- data/vendor/snowball/tests/runtime/naming.sbl +20 -0
- data/vendor/snowball/tests/runtime/not.sbl +30 -0
- data/vendor/snowball/tests/runtime/or.sbl +17 -0
- data/vendor/snowball/tests/runtime/repeat.sbl +16 -0
- data/vendor/snowball/tests/runtime/setlimit.sbl +24 -0
- data/vendor/snowball/tests/runtime/sizelen.sbl +56 -0
- data/vendor/snowball/tests/runtime/slice.sbl +27 -0
- data/vendor/snowball/tests/runtime/stringdollar.sbl +39 -0
- data/vendor/snowball/tests/runtime/strings.sbl +66 -0
- data/vendor/snowball/tests/runtime/test.sbl +19 -0
- data/vendor/snowball/tests/stemtest.c +41 -1
- data/vendor/snowball/tests/syntax/canon.sbl +32 -0
- data/vendor/snowball/tests/syntax/canon.stderr +0 -0
- data/vendor/snowball/tests/syntax/canon.syntax +57 -0
- data/vendor/snowball/tests/syntax/emptyprogram.sbl +2 -0
- data/vendor/snowball/tests/syntax/emptyprogram.syntax +0 -0
- data/vendor/snowball/tests/syntax/groupings.sbl +11 -0
- data/vendor/snowball/tests/syntax/inline.sbl +144 -0
- data/vendor/snowball/tests/syntax/inline.stderr +0 -0
- data/vendor/snowball/tests/syntax/inline.syntax +121 -0
- data/vendor/snowball/tests/syntax/legacy.sbl +17 -0
- data/vendor/snowball/tests/syntax/legacy.stderr +5 -0
- data/vendor/snowball/tests/syntax/legacy.syntax +19 -0
- data/vendor/snowball/tests/syntax/loops.sbl +14 -0
- data/vendor/snowball/tests/syntax/loops.stderr +9 -0
- data/vendor/snowball/tests/syntax/loops.syntax +29 -0
- data/vendor/snowball/tests/syntax/noops.sbl +76 -0
- data/vendor/snowball/tests/syntax/noops.stderr +27 -0
- data/vendor/snowball/tests/syntax/noops.syntax +135 -0
- data/vendor/snowball/tests/syntax/simplifyae.sbl +21 -0
- data/vendor/snowball/tests/syntax/simplifyae.stderr +0 -0
- data/vendor/snowball/tests/syntax/simplifyae.syntax +39 -0
- data/vendor/snowball/tests/syntax/unused.sbl +18 -0
- data/vendor/snowball/tests/syntax/unused.stderr +7 -0
- data/vendor/snowball/tests/syntax/unused.syntax +3 -0
- data/vendor/snowball/zig/env.zig +599 -0
- data/vendor/snowball/zig/generate_algorithms.pl +19 -0
- data/vendor/snowball/zig/stemwords.zig +123 -0
- metadata +102 -4
- data/vendor/snowball/compiler/syswords.h +0 -86
- data/vendor/snowball/runtime/header.h +0 -62
|
@@ -1,72 +1,66 @@
|
|
|
1
1
|
#include <assert.h>
|
|
2
|
+
#include <stdio.h> /* for fprintf etc */
|
|
2
3
|
#include <stdlib.h> /* for exit */
|
|
3
4
|
#include <string.h> /* for strlen */
|
|
4
|
-
#include <stdio.h> /* for fprintf etc */
|
|
5
5
|
#include "header.h"
|
|
6
6
|
|
|
7
|
-
/*
|
|
7
|
+
/* prototype functions for recursive use: */
|
|
8
8
|
|
|
9
9
|
static void generate(struct generator * g, struct node * p);
|
|
10
10
|
static void w(struct generator * g, const char * s);
|
|
11
11
|
static void writef(struct generator * g, const char * s, struct node * p);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
return g->next_label++;
|
|
15
|
-
}
|
|
13
|
+
/* Write routines for items from the syntax tree */
|
|
16
14
|
|
|
17
|
-
static
|
|
18
|
-
|
|
19
|
-
g
|
|
20
|
-
output = str_new();
|
|
21
|
-
str_append_string(output, "c");
|
|
22
|
-
str_append_int(output, g->var_number);
|
|
23
|
-
return output;
|
|
15
|
+
static void write_relop(struct generator * g, int relop) {
|
|
16
|
+
// Relational operators are the same as C.
|
|
17
|
+
write_c_relop(g, relop);
|
|
24
18
|
}
|
|
25
19
|
|
|
26
|
-
/* Write routines for items from the syntax tree */
|
|
27
|
-
|
|
28
20
|
static void write_varname(struct generator * g, struct name * p) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
if (p->type == t_external) {
|
|
22
|
+
if (g->options->externals_prefix) {
|
|
23
|
+
write_string(g, g->options->externals_prefix);
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
// We use the same naming scheme for both global and local variables.
|
|
27
|
+
write_char(g, "SBIrxg"[p->type]);
|
|
32
28
|
write_char(g, '_');
|
|
33
29
|
}
|
|
34
30
|
write_s(g, p->s);
|
|
35
31
|
}
|
|
36
32
|
|
|
33
|
+
/* Reference to variable, e.g. when assigning to or using in an expression. */
|
|
37
34
|
static void write_varref(struct generator * g, struct name * p) {
|
|
38
|
-
/* In
|
|
35
|
+
/* In C#, references look just the same */
|
|
39
36
|
write_varname(g, p);
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
static void write_literal_string(struct generator * g, symbol * p) {
|
|
43
|
-
|
|
40
|
+
write_char(g, '"');
|
|
44
41
|
for (int i = 0; i < SIZE(p); i++) {
|
|
45
42
|
int ch = p[i];
|
|
46
|
-
|
|
43
|
+
// Write out ASCII and lower Unicode printables as literal characters.
|
|
44
|
+
// Use escapes for anything over 0x590 as a crude way to avoid LTR
|
|
45
|
+
// characters affecting the rendering of source character order in
|
|
46
|
+
// confusing ways.
|
|
47
|
+
if ((32 <= ch && ch < 127) || (0xa0 < ch && ch < 0x590)) {
|
|
47
48
|
if (ch == '"' || ch == '\\') write_char(g, '\\');
|
|
48
49
|
// Our C# generator uses ENC_WIDECHARS so we need to convert.
|
|
49
50
|
write_wchar_as_utf8(g, ch);
|
|
50
51
|
} else {
|
|
51
|
-
// Use escapes for anything over 0x590 as a crude way to avoid
|
|
52
|
-
// LTR characters affecting the rendering of source character
|
|
53
|
-
// order in confusing ways.
|
|
54
52
|
write_string(g, "\\u");
|
|
55
53
|
write_hex4(g, ch);
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
static void write_margin(struct generator * g) {
|
|
62
|
-
for (int i = 0; i < g->margin; i++) write_string(g, " ");
|
|
56
|
+
write_char(g, '"');
|
|
63
57
|
}
|
|
64
58
|
|
|
65
59
|
static void write_comment(struct generator * g, struct node * p) {
|
|
66
60
|
if (!g->options->comments) return;
|
|
67
61
|
write_margin(g);
|
|
68
62
|
write_string(g, "// ");
|
|
69
|
-
write_comment_content(g, p);
|
|
63
|
+
write_comment_content(g, p, NULL);
|
|
70
64
|
write_newline(g);
|
|
71
65
|
}
|
|
72
66
|
|
|
@@ -90,7 +84,7 @@ static void append_restore_string(struct node * p, struct str * out, struct str
|
|
|
90
84
|
str_append_string(out, "cursor = ");
|
|
91
85
|
if (p->mode != m_forward) str_append_string(out, "limit - ");
|
|
92
86
|
str_append(out, savevar);
|
|
93
|
-
|
|
87
|
+
str_append_ch(out, ';');
|
|
94
88
|
}
|
|
95
89
|
|
|
96
90
|
static void write_restorecursor(struct generator * g, struct node * p, struct str * savevar) {
|
|
@@ -115,7 +109,7 @@ static void wgotol(struct generator * g, int n) {
|
|
|
115
109
|
write_margin(g);
|
|
116
110
|
write_string(g, "goto lab");
|
|
117
111
|
write_int(g, n);
|
|
118
|
-
|
|
112
|
+
write_char(g, ';');
|
|
119
113
|
write_newline(g);
|
|
120
114
|
}
|
|
121
115
|
|
|
@@ -134,7 +128,7 @@ static void write_failure(struct generator * g) {
|
|
|
134
128
|
default:
|
|
135
129
|
write_string(g, "goto lab");
|
|
136
130
|
write_int(g, g->failure_label);
|
|
137
|
-
|
|
131
|
+
write_char(g, ';');
|
|
138
132
|
g->label_used = 1;
|
|
139
133
|
}
|
|
140
134
|
write_newline(g);
|
|
@@ -162,7 +156,6 @@ static void write_check_limit(struct generator * g, struct node * p) {
|
|
|
162
156
|
|
|
163
157
|
/* Formatted write. */
|
|
164
158
|
static void writef(struct generator * g, const char * input, struct node * p) {
|
|
165
|
-
(void)p;
|
|
166
159
|
int i = 0;
|
|
167
160
|
|
|
168
161
|
while (input[i]) {
|
|
@@ -199,6 +192,32 @@ static void writef(struct generator * g, const char * input, struct node * p) {
|
|
|
199
192
|
write_s(g, g->B[j]);
|
|
200
193
|
continue;
|
|
201
194
|
}
|
|
195
|
+
case 'F': { // Among function dispatcher.
|
|
196
|
+
struct among * x = p->among;
|
|
197
|
+
if (x->function_count == 0) {
|
|
198
|
+
write_string(g, "null");
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (x->function_count == 1) {
|
|
203
|
+
// Only one different function used in this among.
|
|
204
|
+
struct amongvec * v = x->b;
|
|
205
|
+
for (int j = 0; j < x->literalstring_count; j++) {
|
|
206
|
+
if (v[j].function) {
|
|
207
|
+
write_varref(g, v[j].function);
|
|
208
|
+
goto continue_outer_loop;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
fprintf(stderr, "function_count == 1 but no among functions\n");
|
|
212
|
+
exit(1);
|
|
213
|
+
continue_outer_loop:
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
w(g, "af_");
|
|
218
|
+
write_int(g, x->number);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
202
221
|
case 'I': {
|
|
203
222
|
int j = input[i++] - '0';
|
|
204
223
|
if (j < 0 || j > (int)(sizeof(g->I) / sizeof(g->I[0])))
|
|
@@ -207,26 +226,17 @@ static void writef(struct generator * g, const char * input, struct node * p) {
|
|
|
207
226
|
continue;
|
|
208
227
|
}
|
|
209
228
|
case 'V':
|
|
210
|
-
|
|
211
|
-
int j = input[i++] - '0';
|
|
212
|
-
if (j < 0 || j > (int)(sizeof(g->V) / sizeof(g->V[0])))
|
|
213
|
-
goto invalid_escape2;
|
|
214
|
-
if (ch == 'V')
|
|
215
|
-
write_varref(g, g->V[j]);
|
|
216
|
-
else
|
|
217
|
-
write_varname(g, g->V[j]);
|
|
229
|
+
write_varref(g, p->name);
|
|
218
230
|
continue;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
write_literal_string(g, g->L[j]);
|
|
231
|
+
case 'W':
|
|
232
|
+
write_varname(g, p->name);
|
|
233
|
+
continue;
|
|
234
|
+
case 'L':
|
|
235
|
+
write_literal_string(g, p->literalstring);
|
|
225
236
|
continue;
|
|
226
|
-
}
|
|
227
237
|
case '+': g->margin++; continue;
|
|
228
238
|
case '-': g->margin--; continue;
|
|
229
|
-
case 'n':
|
|
239
|
+
case 'n': write_s(g, g->options->name); continue;
|
|
230
240
|
default:
|
|
231
241
|
printf("Invalid escape sequence ~%c in writef(g, \"%s\", p)\n",
|
|
232
242
|
ch, input);
|
|
@@ -247,39 +257,53 @@ static void generate_AE(struct generator * g, struct node * p) {
|
|
|
247
257
|
const char * s;
|
|
248
258
|
switch (p->type) {
|
|
249
259
|
case c_name:
|
|
250
|
-
write_varref(g, p->name);
|
|
260
|
+
write_varref(g, p->name);
|
|
261
|
+
break;
|
|
251
262
|
case c_number:
|
|
252
|
-
write_int(g, p->number);
|
|
263
|
+
write_int(g, p->number);
|
|
264
|
+
break;
|
|
253
265
|
case c_maxint:
|
|
254
|
-
write_string(g, "int.MaxValue");
|
|
266
|
+
write_string(g, "int.MaxValue");
|
|
267
|
+
break;
|
|
255
268
|
case c_minint:
|
|
256
|
-
write_string(g, "int.MinValue");
|
|
269
|
+
write_string(g, "int.MinValue");
|
|
270
|
+
break;
|
|
257
271
|
case c_neg:
|
|
258
|
-
write_char(g, '-');
|
|
272
|
+
write_char(g, '-');
|
|
273
|
+
generate_AE(g, p->right);
|
|
274
|
+
break;
|
|
259
275
|
case c_multiply:
|
|
260
|
-
s = " * ";
|
|
261
|
-
|
|
262
|
-
s = " + "; goto label0;
|
|
263
|
-
case c_minus:
|
|
264
|
-
s = " - "; goto label0;
|
|
276
|
+
s = " * ";
|
|
277
|
+
goto label0;
|
|
265
278
|
case c_divide:
|
|
266
279
|
s = " / ";
|
|
280
|
+
goto label0;
|
|
281
|
+
case c_plus:
|
|
282
|
+
s = " + ";
|
|
283
|
+
goto label0;
|
|
284
|
+
case c_minus:
|
|
285
|
+
s = " - ";
|
|
267
286
|
label0:
|
|
268
|
-
write_char(g, '(');
|
|
269
|
-
|
|
287
|
+
write_char(g, '(');
|
|
288
|
+
generate_AE(g, p->left);
|
|
289
|
+
write_string(g, s);
|
|
290
|
+
generate_AE(g, p->right);
|
|
291
|
+
write_char(g, ')');
|
|
292
|
+
break;
|
|
270
293
|
case c_cursor:
|
|
271
|
-
w(g, "cursor");
|
|
294
|
+
w(g, "cursor");
|
|
295
|
+
break;
|
|
272
296
|
case c_limit:
|
|
273
|
-
w(g, p->mode == m_forward ? "limit" : "limit_backward");
|
|
274
|
-
case c_lenof: /* Same as sizeof() for C#. */
|
|
275
|
-
case c_sizeof:
|
|
276
|
-
g->V[0] = p->name;
|
|
277
|
-
w(g, "~V0.Length");
|
|
297
|
+
w(g, p->mode == m_forward ? "limit" : "limit_backward");
|
|
278
298
|
break;
|
|
279
299
|
case c_len: /* Same as size() for C#. */
|
|
280
300
|
case c_size:
|
|
281
301
|
w(g, "current.Length");
|
|
282
302
|
break;
|
|
303
|
+
case c_lenof: /* Same as sizeof() for C#. */
|
|
304
|
+
case c_sizeof:
|
|
305
|
+
writef(g, "~V.Length", p);
|
|
306
|
+
break;
|
|
283
307
|
}
|
|
284
308
|
}
|
|
285
309
|
|
|
@@ -294,13 +318,15 @@ static void generate_bra(struct generator * g, struct node * p) {
|
|
|
294
318
|
|
|
295
319
|
static void generate_and(struct generator * g, struct node * p) {
|
|
296
320
|
struct str * savevar = NULL;
|
|
297
|
-
if (
|
|
321
|
+
if (K_needed_for_and(p->left)) {
|
|
298
322
|
savevar = vars_newname(g);
|
|
299
323
|
}
|
|
300
324
|
|
|
301
325
|
write_comment(g, p);
|
|
302
326
|
|
|
303
|
-
if (savevar)
|
|
327
|
+
if (savevar) {
|
|
328
|
+
write_savecursor(g, p, savevar);
|
|
329
|
+
}
|
|
304
330
|
|
|
305
331
|
p = p->left;
|
|
306
332
|
while (p) {
|
|
@@ -316,7 +342,7 @@ static void generate_and(struct generator * g, struct node * p) {
|
|
|
316
342
|
|
|
317
343
|
static void generate_or(struct generator * g, struct node * p) {
|
|
318
344
|
struct str * savevar = NULL;
|
|
319
|
-
if (
|
|
345
|
+
if (K_needed_for_or(p->left)) {
|
|
320
346
|
savevar = vars_newname(g);
|
|
321
347
|
}
|
|
322
348
|
|
|
@@ -327,7 +353,7 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
|
327
353
|
int out_lab = new_label(g);
|
|
328
354
|
write_comment(g, p);
|
|
329
355
|
|
|
330
|
-
if (savevar) {
|
|
356
|
+
if (savevar && K_needed_node_on_f(p)) {
|
|
331
357
|
write_block_start(g);
|
|
332
358
|
write_savecursor(g, p, savevar);
|
|
333
359
|
}
|
|
@@ -342,13 +368,16 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
|
342
368
|
exit(1);
|
|
343
369
|
}
|
|
344
370
|
while (p->right != NULL) {
|
|
345
|
-
|
|
371
|
+
int label = new_label(g);
|
|
372
|
+
g->failure_label = label;
|
|
346
373
|
g->label_used = 0;
|
|
347
374
|
generate(g, p);
|
|
348
375
|
wgotol(g, out_lab);
|
|
349
376
|
if (g->label_used)
|
|
350
377
|
wsetl(g, g->failure_label);
|
|
351
|
-
if (savevar)
|
|
378
|
+
if (savevar) {
|
|
379
|
+
write_restorecursor(g, p, savevar);
|
|
380
|
+
}
|
|
352
381
|
p = p->right;
|
|
353
382
|
}
|
|
354
383
|
|
|
@@ -375,10 +404,9 @@ static void generate_backwards(struct generator * g, struct node * p) {
|
|
|
375
404
|
w(g, "~Mcursor = limit_backward;~N");
|
|
376
405
|
}
|
|
377
406
|
|
|
378
|
-
|
|
379
407
|
static void generate_not(struct generator * g, struct node * p) {
|
|
380
408
|
struct str * savevar = NULL;
|
|
381
|
-
if (
|
|
409
|
+
if (K_needed_node_on_f(p->left)) {
|
|
382
410
|
savevar = vars_newname(g);
|
|
383
411
|
}
|
|
384
412
|
|
|
@@ -392,25 +420,24 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
|
392
420
|
write_savecursor(g, p, savevar);
|
|
393
421
|
}
|
|
394
422
|
|
|
395
|
-
|
|
423
|
+
int label = new_label(g);
|
|
424
|
+
g->failure_label = label;
|
|
396
425
|
g->label_used = 0;
|
|
397
426
|
str_clear(g->failure_str);
|
|
398
427
|
generate(g, p->left);
|
|
399
428
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
int u = g->label_used;
|
|
429
|
+
int l = g->failure_label;
|
|
430
|
+
int u = g->label_used;
|
|
403
431
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
432
|
+
g->label_used = used;
|
|
433
|
+
g->failure_label = a0;
|
|
434
|
+
str_delete(g->failure_str);
|
|
435
|
+
g->failure_str = a1;
|
|
408
436
|
|
|
409
|
-
|
|
437
|
+
write_failure(g);
|
|
410
438
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
439
|
+
if (u)
|
|
440
|
+
wsetl(g, l);
|
|
414
441
|
|
|
415
442
|
if (savevar) {
|
|
416
443
|
write_restorecursor(g, p, savevar);
|
|
@@ -419,14 +446,14 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
|
419
446
|
}
|
|
420
447
|
}
|
|
421
448
|
|
|
422
|
-
|
|
423
449
|
static void generate_try(struct generator * g, struct node * p) {
|
|
424
450
|
struct str * savevar = NULL;
|
|
425
|
-
if (K_needed(
|
|
451
|
+
if (K_needed(p->left)) {
|
|
426
452
|
savevar = vars_newname(g);
|
|
427
453
|
}
|
|
428
454
|
|
|
429
|
-
|
|
455
|
+
int label = new_label(g);
|
|
456
|
+
g->failure_label = label;
|
|
430
457
|
g->label_used = 0;
|
|
431
458
|
str_clear(g->failure_str);
|
|
432
459
|
|
|
@@ -450,14 +477,12 @@ static void generate_try(struct generator * g, struct node * p) {
|
|
|
450
477
|
|
|
451
478
|
static void generate_set(struct generator * g, struct node * p) {
|
|
452
479
|
write_comment(g, p);
|
|
453
|
-
g
|
|
454
|
-
writef(g, "~M~V0 = true;~N", p);
|
|
480
|
+
writef(g, "~M~V = true;~N", p);
|
|
455
481
|
}
|
|
456
482
|
|
|
457
483
|
static void generate_unset(struct generator * g, struct node * p) {
|
|
458
484
|
write_comment(g, p);
|
|
459
|
-
g
|
|
460
|
-
writef(g, "~M~V0 = false;~N", p);
|
|
485
|
+
writef(g, "~M~V = false;~N", p);
|
|
461
486
|
}
|
|
462
487
|
|
|
463
488
|
static void generate_fail(struct generator * g, struct node * p) {
|
|
@@ -467,10 +492,9 @@ static void generate_fail(struct generator * g, struct node * p) {
|
|
|
467
492
|
}
|
|
468
493
|
|
|
469
494
|
/* generate_test() also implements 'reverse' */
|
|
470
|
-
|
|
471
495
|
static void generate_test(struct generator * g, struct node * p) {
|
|
472
496
|
struct str * savevar = NULL;
|
|
473
|
-
if (K_needed(
|
|
497
|
+
if (K_needed(p->left)) {
|
|
474
498
|
savevar = vars_newname(g);
|
|
475
499
|
}
|
|
476
500
|
|
|
@@ -492,7 +516,7 @@ static void generate_test(struct generator * g, struct node * p) {
|
|
|
492
516
|
|
|
493
517
|
static void generate_do(struct generator * g, struct node * p) {
|
|
494
518
|
struct str * savevar = NULL;
|
|
495
|
-
if (K_needed(
|
|
519
|
+
if (K_needed(p->left)) {
|
|
496
520
|
savevar = vars_newname(g);
|
|
497
521
|
}
|
|
498
522
|
|
|
@@ -505,10 +529,10 @@ static void generate_do(struct generator * g, struct node * p) {
|
|
|
505
529
|
if (p->left->type == c_call) {
|
|
506
530
|
/* Optimise do <call> */
|
|
507
531
|
write_comment(g, p->left);
|
|
508
|
-
g
|
|
509
|
-
w(g, "~M~V0();~N");
|
|
532
|
+
writef(g, "~M~V();~N", p->left);
|
|
510
533
|
} else {
|
|
511
|
-
|
|
534
|
+
int label = new_label(g);
|
|
535
|
+
g->failure_label = label;
|
|
512
536
|
g->label_used = 0;
|
|
513
537
|
str_clear(g->failure_str);
|
|
514
538
|
|
|
@@ -537,15 +561,15 @@ static void generate_GO_grouping(struct generator * g, struct node * p, int is_g
|
|
|
537
561
|
struct grouping * q = p->name->grouping;
|
|
538
562
|
g->S[0] = p->mode == m_forward ? "" : "_b";
|
|
539
563
|
g->S[1] = complement ? "in" : "out";
|
|
540
|
-
g->V[0] = p->name;
|
|
541
564
|
g->I[0] = q->smallest_ch;
|
|
542
565
|
g->I[1] = q->largest_ch;
|
|
543
566
|
if (is_goto) {
|
|
544
|
-
|
|
567
|
+
writef(g, "~Mif (~S1_grouping~S0(~V, ~I0, ~I1, true) < 0)~N~f~N", p);
|
|
545
568
|
} else {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
569
|
+
writef(g, "~{~N"
|
|
570
|
+
"~Mint ret = ~S1_grouping~S0(~V, ~I0, ~I1, true);~N"
|
|
571
|
+
"~Mif (ret < 0)~N~f~N", p);
|
|
572
|
+
|
|
549
573
|
if (p->mode == m_forward)
|
|
550
574
|
w(g, "~Mcursor += ret;~N");
|
|
551
575
|
else
|
|
@@ -554,7 +578,7 @@ static void generate_GO_grouping(struct generator * g, struct node * p, int is_g
|
|
|
554
578
|
}
|
|
555
579
|
}
|
|
556
580
|
|
|
557
|
-
static void generate_GO(struct generator * g, struct node * p, int
|
|
581
|
+
static void generate_GO(struct generator * g, struct node * p, int is_goto) {
|
|
558
582
|
write_comment(g, p);
|
|
559
583
|
|
|
560
584
|
int used = g->label_used;
|
|
@@ -564,22 +588,21 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
|
564
588
|
w(g, "~Mwhile (true)~N~{");
|
|
565
589
|
|
|
566
590
|
struct str * savevar = NULL;
|
|
567
|
-
if (
|
|
591
|
+
if (is_goto || repeat_restore(p->left)) {
|
|
568
592
|
savevar = vars_newname(g);
|
|
569
593
|
write_savecursor(g, p, savevar);
|
|
570
594
|
}
|
|
571
595
|
|
|
572
|
-
|
|
596
|
+
int label = new_label(g);
|
|
597
|
+
g->failure_label = label;
|
|
573
598
|
g->label_used = 0;
|
|
574
599
|
str_clear(g->failure_str);
|
|
575
600
|
generate(g, p->left);
|
|
576
601
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
write_restorecursor(g, p, savevar);
|
|
580
|
-
}
|
|
581
|
-
|
|
602
|
+
/* include for goto; omit for gopast */
|
|
603
|
+
if (is_goto) write_restorecursor(g, p, savevar);
|
|
582
604
|
w(g, "~Mbreak;~N");
|
|
605
|
+
|
|
583
606
|
if (g->label_used)
|
|
584
607
|
wsetl(g, g->failure_label);
|
|
585
608
|
if (savevar) {
|
|
@@ -598,8 +621,8 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
|
598
621
|
}
|
|
599
622
|
|
|
600
623
|
static void generate_loop(struct generator * g, struct node * p) {
|
|
601
|
-
struct str * loopvar = vars_newname(g);
|
|
602
624
|
write_comment(g, p);
|
|
625
|
+
struct str * loopvar = vars_newname(g);
|
|
603
626
|
g->B[0] = str_data(loopvar);
|
|
604
627
|
w(g, "~Mfor (int ~B0 = ");
|
|
605
628
|
generate_AE(g, p->AE);
|
|
@@ -613,22 +636,24 @@ static void generate_loop(struct generator * g, struct node * p) {
|
|
|
613
636
|
str_delete(loopvar);
|
|
614
637
|
}
|
|
615
638
|
|
|
616
|
-
static void generate_repeat_or_atleast(struct generator * g, struct node * p, struct str *
|
|
639
|
+
static void generate_repeat_or_atleast(struct generator * g, struct node * p, struct str * loopvar) {
|
|
617
640
|
writef(g, "~Mwhile (true)~N~{", p);
|
|
618
641
|
|
|
619
642
|
struct str * savevar = NULL;
|
|
620
|
-
if (repeat_restore(
|
|
643
|
+
if (repeat_restore(p->left)) {
|
|
621
644
|
savevar = vars_newname(g);
|
|
622
645
|
write_savecursor(g, p, savevar);
|
|
623
646
|
}
|
|
624
647
|
|
|
625
|
-
|
|
648
|
+
int label = new_label(g);
|
|
649
|
+
g->failure_label = label;
|
|
626
650
|
g->label_used = 0;
|
|
627
651
|
str_clear(g->failure_str);
|
|
652
|
+
|
|
628
653
|
generate(g, p->left);
|
|
629
654
|
|
|
630
|
-
if (
|
|
631
|
-
g->B[0] = str_data(
|
|
655
|
+
if (loopvar != NULL) {
|
|
656
|
+
g->B[0] = str_data(loopvar);
|
|
632
657
|
w(g, "~M~B0--;~N");
|
|
633
658
|
}
|
|
634
659
|
|
|
@@ -651,10 +676,10 @@ static void generate_repeat(struct generator * g, struct node * p) {
|
|
|
651
676
|
}
|
|
652
677
|
|
|
653
678
|
static void generate_atleast(struct generator * g, struct node * p) {
|
|
654
|
-
struct str * loopvar = vars_newname(g);
|
|
655
|
-
|
|
656
679
|
write_comment(g, p);
|
|
680
|
+
|
|
657
681
|
w(g, "~{");
|
|
682
|
+
struct str * loopvar = vars_newname(g);
|
|
658
683
|
g->B[0] = str_data(loopvar);
|
|
659
684
|
w(g, "~Mint ~B0 = ");
|
|
660
685
|
generate_AE(g, p->AE);
|
|
@@ -677,12 +702,6 @@ static void generate_atleast(struct generator * g, struct node * p) {
|
|
|
677
702
|
str_delete(loopvar);
|
|
678
703
|
}
|
|
679
704
|
|
|
680
|
-
static void generate_setmark(struct generator * g, struct node * p) {
|
|
681
|
-
write_comment(g, p);
|
|
682
|
-
g->V[0] = p->name;
|
|
683
|
-
writef(g, "~M~V0 = cursor;~N", p);
|
|
684
|
-
}
|
|
685
|
-
|
|
686
705
|
static void generate_tomark(struct generator * g, struct node * p) {
|
|
687
706
|
write_comment(g, p);
|
|
688
707
|
g->S[0] = p->mode == m_forward ? ">" : "<";
|
|
@@ -694,14 +713,6 @@ static void generate_tomark(struct generator * g, struct node * p) {
|
|
|
694
713
|
w(g, "~Mcursor = "); generate_AE(g, p->AE); writef(g, ";~N", p);
|
|
695
714
|
}
|
|
696
715
|
|
|
697
|
-
static void generate_atmark(struct generator * g, struct node * p) {
|
|
698
|
-
write_comment(g, p);
|
|
699
|
-
w(g, "~Mif (cursor != "); generate_AE(g, p->AE); writef(g, ")~N", p);
|
|
700
|
-
write_block_start(g);
|
|
701
|
-
write_failure(g);
|
|
702
|
-
write_block_end(g);
|
|
703
|
-
}
|
|
704
|
-
|
|
705
716
|
static void generate_hop(struct generator * g, struct node * p) {
|
|
706
717
|
write_comment(g, p);
|
|
707
718
|
g->S[0] = p->mode == m_forward ? "+" : "-";
|
|
@@ -725,24 +736,12 @@ static void generate_hop(struct generator * g, struct node * p) {
|
|
|
725
736
|
writef(g, "~}", p);
|
|
726
737
|
}
|
|
727
738
|
|
|
728
|
-
static void generate_delete(struct generator * g, struct node * p) {
|
|
729
|
-
write_comment(g, p);
|
|
730
|
-
writef(g, "~Mslice_del();~N", p);
|
|
731
|
-
}
|
|
732
|
-
|
|
733
739
|
static void generate_tolimit(struct generator * g, struct node * p) {
|
|
734
740
|
write_comment(g, p);
|
|
735
741
|
g->S[0] = p->mode == m_forward ? "limit" : "limit_backward";
|
|
736
742
|
writef(g, "~Mcursor = ~S0;~N", p);
|
|
737
743
|
}
|
|
738
744
|
|
|
739
|
-
static void generate_atlimit(struct generator * g, struct node * p) {
|
|
740
|
-
write_comment(g, p);
|
|
741
|
-
g->S[0] = p->mode == m_forward ? "limit" : "limit_backward";
|
|
742
|
-
g->S[1] = p->mode == m_forward ? "<" : ">";
|
|
743
|
-
write_failure_if(g, "cursor ~S1 ~S0", p);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
745
|
static void generate_leftslice(struct generator * g, struct node * p) {
|
|
747
746
|
write_comment(g, p);
|
|
748
747
|
g->S[0] = p->mode == m_forward ? "bra" : "ket";
|
|
@@ -757,14 +756,12 @@ static void generate_rightslice(struct generator * g, struct node * p) {
|
|
|
757
756
|
|
|
758
757
|
static void generate_assignto(struct generator * g, struct node * p) {
|
|
759
758
|
write_comment(g, p);
|
|
760
|
-
g
|
|
761
|
-
writef(g, "~Massign_to(~V0);~N", p);
|
|
759
|
+
writef(g, "~Massign_to(~V);~N", p);
|
|
762
760
|
}
|
|
763
761
|
|
|
764
762
|
static void generate_sliceto(struct generator * g, struct node * p) {
|
|
765
763
|
write_comment(g, p);
|
|
766
|
-
g
|
|
767
|
-
writef(g, "~Mslice_to(~V0);~N", p);
|
|
764
|
+
writef(g, "~Mslice_to(~V);~N", p);
|
|
768
765
|
}
|
|
769
766
|
|
|
770
767
|
static void generate_address(struct generator * g, struct node * p) {
|
|
@@ -773,12 +770,13 @@ static void generate_address(struct generator * g, struct node * p) {
|
|
|
773
770
|
write_literal_string(g, b);
|
|
774
771
|
} else {
|
|
775
772
|
write_varref(g, p->name);
|
|
773
|
+
write_string(g, ".ToString()");
|
|
776
774
|
}
|
|
777
775
|
}
|
|
778
776
|
|
|
779
777
|
static void generate_insert(struct generator * g, struct node * p, int style) {
|
|
780
|
-
int keep_c = style == c_attach;
|
|
781
778
|
write_comment(g, p);
|
|
779
|
+
int keep_c = style == c_attach;
|
|
782
780
|
if (p->mode == m_backward) keep_c = !keep_c;
|
|
783
781
|
if (keep_c) w(g, "~{~Mint c = cursor;~N");
|
|
784
782
|
writef(g, "~Minsert(cursor, cursor, ", p);
|
|
@@ -787,11 +785,12 @@ static void generate_insert(struct generator * g, struct node * p, int style) {
|
|
|
787
785
|
if (keep_c) w(g, "~Mcursor = c;~N~}");
|
|
788
786
|
}
|
|
789
787
|
|
|
790
|
-
static void
|
|
791
|
-
int keep_c = p->mode == m_forward; /* like 'attach' */
|
|
792
|
-
|
|
788
|
+
static void generate_stringassign(struct generator * g, struct node * p) {
|
|
793
789
|
write_comment(g, p);
|
|
794
|
-
|
|
790
|
+
int keep_c = p->mode == m_forward; /* like 'attach' */
|
|
791
|
+
if (keep_c) {
|
|
792
|
+
writef(g, "~{~Mint c = cursor;~N", p);
|
|
793
|
+
}
|
|
795
794
|
if (p->mode == m_forward) {
|
|
796
795
|
writef(g, "~Minsert(cursor, limit, ", p);
|
|
797
796
|
} else {
|
|
@@ -799,19 +798,26 @@ static void generate_assignfrom(struct generator * g, struct node * p) {
|
|
|
799
798
|
}
|
|
800
799
|
generate_address(g, p);
|
|
801
800
|
writef(g, ");~N", p);
|
|
802
|
-
if (keep_c)
|
|
801
|
+
if (keep_c) {
|
|
802
|
+
w(g, "~Mcursor = c;~N~}");
|
|
803
|
+
}
|
|
803
804
|
}
|
|
804
805
|
|
|
805
806
|
static void generate_slicefrom(struct generator * g, struct node * p) {
|
|
806
807
|
write_comment(g, p);
|
|
808
|
+
if (p->literalstring && SIZE(p->literalstring) == 0) {
|
|
809
|
+
w(g, "~Mslice_del();~N");
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
807
812
|
w(g, "~Mslice_from(");
|
|
808
813
|
generate_address(g, p);
|
|
809
|
-
|
|
814
|
+
w(g, ");~N");
|
|
810
815
|
}
|
|
811
816
|
|
|
812
817
|
static void generate_setlimit(struct generator * g, struct node * p) {
|
|
813
|
-
struct str * varname = vars_newname(g);
|
|
814
818
|
write_comment(g, p);
|
|
819
|
+
struct str * varname = vars_newname(g);
|
|
820
|
+
|
|
815
821
|
if (p->left && p->left->type == c_tomark) {
|
|
816
822
|
/* Special case for:
|
|
817
823
|
*
|
|
@@ -823,6 +829,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
|
823
829
|
*/
|
|
824
830
|
struct node * q = p->left;
|
|
825
831
|
write_comment(g, q);
|
|
832
|
+
|
|
826
833
|
g->S[0] = q->mode == m_forward ? ">" : "<";
|
|
827
834
|
w(g, "~Mif (cursor ~S0 "); generate_AE(g, q->AE); w(g, ")~N");
|
|
828
835
|
write_block_start(g);
|
|
@@ -831,13 +838,17 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
|
831
838
|
|
|
832
839
|
g->B[0] = str_data(varname);
|
|
833
840
|
if (p->mode == m_forward) {
|
|
834
|
-
w(g, "~Mint ~B0 = limit
|
|
841
|
+
w(g, "~Mint ~B0 = limit;~N");
|
|
835
842
|
w(g, "~Mlimit = ");
|
|
843
|
+
generate_AE(g, q->AE);
|
|
844
|
+
w(g, ";~N");
|
|
845
|
+
w(g, "~M~B0 -= limit;~N");
|
|
836
846
|
} else {
|
|
837
847
|
w(g, "~Mint ~B0 = limit_backward;~N");
|
|
838
848
|
w(g, "~Mlimit_backward = ");
|
|
849
|
+
generate_AE(g, q->AE);
|
|
850
|
+
w(g, ";~N");
|
|
839
851
|
}
|
|
840
|
-
generate_AE(g, q->AE); writef(g, ";~N", q);
|
|
841
852
|
|
|
842
853
|
if (p->mode == m_forward) {
|
|
843
854
|
str_assign(g->failure_str, "limit += ");
|
|
@@ -890,32 +901,60 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
|
890
901
|
static void generate_dollar(struct generator * g, struct node * p) {
|
|
891
902
|
write_comment(g, p);
|
|
892
903
|
|
|
893
|
-
|
|
894
|
-
|
|
904
|
+
int used = g->label_used;
|
|
905
|
+
int a0 = g->failure_label;
|
|
906
|
+
struct str * a1 = str_copy(g->failure_str);
|
|
907
|
+
int label = new_label(g);
|
|
908
|
+
g->failure_label = label;
|
|
909
|
+
g->label_used = 0;
|
|
910
|
+
str_clear(g->failure_str);
|
|
895
911
|
|
|
896
|
-
|
|
897
|
-
str_append(g->failure_str, savevar);
|
|
898
|
-
str_append_string(g->failure_str, ");");
|
|
912
|
+
struct str * savevar = vars_newname(g);
|
|
899
913
|
g->B[0] = str_data(savevar);
|
|
914
|
+
|
|
900
915
|
writef(g, "~{~MEnv ~B0 = new Env(this);~N"
|
|
901
|
-
"~Mcurrent = ~
|
|
916
|
+
"~Mcurrent = ~V;~N"
|
|
902
917
|
"~Mcursor = 0;~N"
|
|
903
918
|
"~Mlimit = current.Length;~N", p);
|
|
919
|
+
if (p->left->possible_signals == -1) {
|
|
920
|
+
/* Assume failure. */
|
|
921
|
+
w(g, "~Mbool ~B0_f = true;~N");
|
|
922
|
+
}
|
|
923
|
+
|
|
904
924
|
generate(g, p->left);
|
|
905
925
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
926
|
+
if (p->left->possible_signals == -1) {
|
|
927
|
+
/* Mark success. */
|
|
928
|
+
g->B[0] = str_data(savevar);
|
|
929
|
+
w(g, "~M~B0_f = false;~N");
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (g->label_used)
|
|
933
|
+
wsetl(g, g->failure_label);
|
|
934
|
+
|
|
935
|
+
g->label_used = used;
|
|
936
|
+
g->failure_label = a0;
|
|
937
|
+
str_delete(g->failure_str);
|
|
938
|
+
g->failure_str = a1;
|
|
939
|
+
|
|
940
|
+
g->B[0] = str_data(savevar);
|
|
941
|
+
writef(g, "~Mcopy_from(~B0);~N", p);
|
|
909
942
|
|
|
943
|
+
if (p->left->possible_signals == 0) {
|
|
944
|
+
// p->left always signals f.
|
|
945
|
+
w(g, "~M~f~N");
|
|
946
|
+
} else if (p->left->possible_signals == -1) {
|
|
947
|
+
write_failure_if(g, "~B0_f", p);
|
|
948
|
+
}
|
|
910
949
|
w(g, "~}");
|
|
950
|
+
|
|
911
951
|
str_delete(savevar);
|
|
912
952
|
}
|
|
913
953
|
|
|
914
954
|
static void generate_integer_assign(struct generator * g, struct node * p, const char * s) {
|
|
915
955
|
write_comment(g, p);
|
|
916
|
-
g->V[0] = p->name;
|
|
917
956
|
g->S[0] = s;
|
|
918
|
-
|
|
957
|
+
writef(g, "~M~V ~S0 ", p);
|
|
919
958
|
generate_AE(g, p->AE);
|
|
920
959
|
w(g, ";~N");
|
|
921
960
|
}
|
|
@@ -923,7 +962,7 @@ static void generate_integer_assign(struct generator * g, struct node * p, const
|
|
|
923
962
|
static void generate_integer_test(struct generator * g, struct node * p) {
|
|
924
963
|
write_comment(g, p);
|
|
925
964
|
int relop = p->type;
|
|
926
|
-
int optimise_to_return = (g
|
|
965
|
+
int optimise_to_return = tailcallable(g, p);
|
|
927
966
|
if (optimise_to_return) {
|
|
928
967
|
w(g, "~Mreturn ");
|
|
929
968
|
p->right = NULL;
|
|
@@ -933,8 +972,7 @@ static void generate_integer_test(struct generator * g, struct node * p) {
|
|
|
933
972
|
relop ^= 1;
|
|
934
973
|
}
|
|
935
974
|
generate_AE(g, p->left);
|
|
936
|
-
|
|
937
|
-
write_c_relop(g, relop);
|
|
975
|
+
write_relop(g, relop);
|
|
938
976
|
generate_AE(g, p->AE);
|
|
939
977
|
if (optimise_to_return) {
|
|
940
978
|
w(g, ";~N");
|
|
@@ -947,24 +985,28 @@ static void generate_integer_test(struct generator * g, struct node * p) {
|
|
|
947
985
|
}
|
|
948
986
|
|
|
949
987
|
static void generate_call(struct generator * g, struct node * p) {
|
|
950
|
-
int signals =
|
|
988
|
+
int signals = p->name->definition->possible_signals;
|
|
951
989
|
write_comment(g, p);
|
|
952
|
-
g
|
|
953
|
-
|
|
954
|
-
(
|
|
955
|
-
|
|
956
|
-
|
|
990
|
+
if (tailcallable(g, p)) {
|
|
991
|
+
/* Tail call. */
|
|
992
|
+
writef(g, "~Mreturn ~V();~N", p);
|
|
993
|
+
p->right = NULL;
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
if (just_return_on_fail(g) && signals == 0) {
|
|
997
|
+
/* Always fails. */
|
|
998
|
+
writef(g, "~Mreturn ~V();~N", p);
|
|
957
999
|
return;
|
|
958
1000
|
}
|
|
959
1001
|
if (signals == 1) {
|
|
960
1002
|
/* Always succeeds. */
|
|
961
|
-
writef(g, "~M~
|
|
1003
|
+
writef(g, "~M~V();~N", p);
|
|
962
1004
|
} else if (signals == 0) {
|
|
963
1005
|
/* Always fails. */
|
|
964
|
-
writef(g, "~M~
|
|
1006
|
+
writef(g, "~M~V();~N", p);
|
|
965
1007
|
write_failure(g);
|
|
966
1008
|
} else {
|
|
967
|
-
|
|
1009
|
+
writef(g, "~Mif (!~V())~N~+", p);
|
|
968
1010
|
write_failure(g);
|
|
969
1011
|
w(g, "~-");
|
|
970
1012
|
}
|
|
@@ -976,68 +1018,102 @@ static void generate_grouping(struct generator * g, struct node * p, int complem
|
|
|
976
1018
|
struct grouping * q = p->name->grouping;
|
|
977
1019
|
g->S[0] = p->mode == m_forward ? "" : "_b";
|
|
978
1020
|
g->S[1] = complement ? "out" : "in";
|
|
979
|
-
g->V[0] = p->name;
|
|
980
1021
|
g->I[0] = q->smallest_ch;
|
|
981
1022
|
g->I[1] = q->largest_ch;
|
|
982
|
-
|
|
1023
|
+
if (tailcallable(g, p)) {
|
|
1024
|
+
writef(g, "~Mreturn (~S1_grouping~S0(~V, ~I0, ~I1, false) == 0);~N", p);
|
|
1025
|
+
p->right = NULL;
|
|
1026
|
+
} else {
|
|
1027
|
+
writef(g, "~Mif (~S1_grouping~S0(~V, ~I0, ~I1, false) != 0)~N~f", p);
|
|
1028
|
+
}
|
|
983
1029
|
}
|
|
984
1030
|
|
|
985
1031
|
static void generate_namedstring(struct generator * g, struct node * p) {
|
|
986
1032
|
write_comment(g, p);
|
|
987
1033
|
g->S[0] = p->mode == m_forward ? "" : "_b";
|
|
988
|
-
g
|
|
989
|
-
|
|
1034
|
+
if (tailcallable(g, p)) {
|
|
1035
|
+
writef(g, "~Mreturn eq_s~S0(~V);~N", p);
|
|
1036
|
+
p->right = NULL;
|
|
1037
|
+
} else {
|
|
1038
|
+
write_failure_if(g, "!(eq_s~S0(~V))", p);
|
|
1039
|
+
}
|
|
990
1040
|
}
|
|
991
1041
|
|
|
992
1042
|
static void generate_literalstring(struct generator * g, struct node * p) {
|
|
993
|
-
symbol * b = p->literalstring;
|
|
994
1043
|
write_comment(g, p);
|
|
995
1044
|
g->S[0] = p->mode == m_forward ? "" : "_b";
|
|
996
|
-
g
|
|
997
|
-
|
|
1045
|
+
if (tailcallable(g, p)) {
|
|
1046
|
+
writef(g, "~Mreturn eq_s~S0(~L);~N", p);
|
|
1047
|
+
p->right = NULL;
|
|
1048
|
+
} else {
|
|
1049
|
+
write_failure_if(g, "!(eq_s~S0(~L))", p);
|
|
1050
|
+
}
|
|
998
1051
|
}
|
|
999
1052
|
|
|
1000
1053
|
static void generate_define(struct generator * g, struct node * p) {
|
|
1001
|
-
struct name * q = p->name;
|
|
1002
|
-
if (q->type == t_routine && !q->used) return;
|
|
1003
|
-
|
|
1004
1054
|
write_newline(g);
|
|
1005
1055
|
write_comment(g, p);
|
|
1006
1056
|
|
|
1057
|
+
struct name * q = p->name;
|
|
1007
1058
|
if (q->type == t_routine) {
|
|
1008
1059
|
g->S[0] = "private";
|
|
1009
1060
|
} else {
|
|
1010
|
-
|
|
1061
|
+
if (SIZE(q->s) == 4 && memcmp(q->s, "stem", 4) == 0) {
|
|
1062
|
+
g->S[0] = "protected override";
|
|
1063
|
+
} else {
|
|
1064
|
+
g->S[0] = "protected";
|
|
1065
|
+
}
|
|
1011
1066
|
}
|
|
1012
|
-
g
|
|
1013
|
-
w(g, "~M~S0 bool ~V0()~N~M{~+~N");
|
|
1014
|
-
|
|
1015
|
-
/* Save output. */
|
|
1016
|
-
struct str * saved_output = g->outbuf;
|
|
1017
|
-
g->outbuf = str_new();
|
|
1067
|
+
writef(g, "~M~S0 bool ~V()~N~M{~+~N", p);
|
|
1018
1068
|
|
|
1019
1069
|
g->next_label = 0;
|
|
1020
1070
|
g->var_number = 0;
|
|
1021
1071
|
|
|
1022
|
-
if (
|
|
1072
|
+
if (q->amongvar_needed) {
|
|
1073
|
+
w(g, "~Mint among_var;~N");
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
/* Declare localised variables. */
|
|
1077
|
+
for (struct name * name = g->analyser->names; name; name = name->next) {
|
|
1078
|
+
if (name->local_to == q) {
|
|
1079
|
+
switch (name->type) {
|
|
1080
|
+
case t_string:
|
|
1081
|
+
// String variables not localised for C# currently.
|
|
1082
|
+
w(g, "~M");
|
|
1083
|
+
write_string(g, g->options->string_class);
|
|
1084
|
+
write_char(g, ' ');
|
|
1085
|
+
write_varname(g, name);
|
|
1086
|
+
write_string(g, " = new ");
|
|
1087
|
+
write_string(g, g->options->string_class);
|
|
1088
|
+
w(g, "();~N");
|
|
1089
|
+
break;
|
|
1090
|
+
case t_integer:
|
|
1091
|
+
w(g, "~Mint ");
|
|
1092
|
+
write_varname(g, name);
|
|
1093
|
+
w(g, ";~N");
|
|
1094
|
+
break;
|
|
1095
|
+
case t_boolean:
|
|
1096
|
+
w(g, "~Mbool ");
|
|
1097
|
+
write_varname(g, name);
|
|
1098
|
+
w(g, ";~N");
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1023
1104
|
str_clear(g->failure_str);
|
|
1024
1105
|
g->failure_label = x_return;
|
|
1025
1106
|
g->label_used = 0;
|
|
1026
|
-
int signals = check_possible_signals_list(g, p->left, c_define, 0);
|
|
1027
1107
|
|
|
1028
1108
|
/* Generate function body. */
|
|
1029
1109
|
generate(g, p->left);
|
|
1030
1110
|
if (p->left->right) {
|
|
1031
1111
|
assert(p->left->right->type == c_functionend);
|
|
1032
|
-
if (
|
|
1112
|
+
if (p->left->possible_signals) {
|
|
1033
1113
|
generate(g, p->left->right);
|
|
1034
1114
|
}
|
|
1035
1115
|
}
|
|
1036
1116
|
w(g, "~}");
|
|
1037
|
-
|
|
1038
|
-
str_append(saved_output, g->outbuf);
|
|
1039
|
-
str_delete(g->outbuf);
|
|
1040
|
-
g->outbuf = saved_output;
|
|
1041
1117
|
}
|
|
1042
1118
|
|
|
1043
1119
|
static void generate_functionend(struct generator * g, struct node * p) {
|
|
@@ -1054,14 +1130,17 @@ static void generate_substring(struct generator * g, struct node * p) {
|
|
|
1054
1130
|
g->I[0] = x->number;
|
|
1055
1131
|
|
|
1056
1132
|
if (x->amongvar_needed) {
|
|
1057
|
-
writef(g, "~Mamong_var = find_among~S0(a_~I0);~N", p);
|
|
1133
|
+
writef(g, "~Mamong_var = find_among~S0(a_~I0, ~F);~N", p);
|
|
1058
1134
|
if (!x->always_matches) {
|
|
1059
1135
|
write_failure_if(g, "among_var == 0", p);
|
|
1060
1136
|
}
|
|
1061
1137
|
} else if (x->always_matches) {
|
|
1062
|
-
writef(g, "~Mfind_among~S0(a_~I0);~N", p);
|
|
1138
|
+
writef(g, "~Mfind_among~S0(a_~I0, ~F);~N", p);
|
|
1139
|
+
} else if (x->command_count == 0 && tailcallable(g, p)) {
|
|
1140
|
+
writef(g, "~Mreturn find_among~S0(a_~I0, ~F) != 0;~N", p);
|
|
1141
|
+
x->node->right = NULL;
|
|
1063
1142
|
} else {
|
|
1064
|
-
write_failure_if(g, "find_among~S0(a_~I0) == 0", p);
|
|
1143
|
+
write_failure_if(g, "find_among~S0(a_~I0, ~F) == 0", p);
|
|
1065
1144
|
}
|
|
1066
1145
|
}
|
|
1067
1146
|
|
|
@@ -1082,14 +1161,15 @@ static void generate_among(struct generator * g, struct node * p) {
|
|
|
1082
1161
|
for (int i = 1; i <= x->command_count; i++) {
|
|
1083
1162
|
g->I[0] = i;
|
|
1084
1163
|
/* Put a block around each case which seems to workaround bogus
|
|
1085
|
-
* compiler errors (typically with repeat reports at the same
|
|
1164
|
+
* C# compiler errors (typically with repeat reports at the same
|
|
1086
1165
|
* location):
|
|
1087
1166
|
*
|
|
1088
1167
|
* dutchStemmer.generated.cs(543,25): error CS0165: Use of unassigned local variable `c5'
|
|
1089
1168
|
*
|
|
1090
1169
|
* The c5 variable is initialised at point of declaration and we
|
|
1091
1170
|
* don't `goto` into the block it is declared in from outside so
|
|
1092
|
-
* this seems to be buggy code flow analysis in the compiler.
|
|
1171
|
+
* this seems to be buggy code flow analysis in the C# compiler.
|
|
1172
|
+
*
|
|
1093
1173
|
* Unclear where to usefully report mono bugs in 2025 so I've
|
|
1094
1174
|
* not tried.
|
|
1095
1175
|
*/
|
|
@@ -1101,10 +1181,23 @@ static void generate_among(struct generator * g, struct node * p) {
|
|
|
1101
1181
|
}
|
|
1102
1182
|
}
|
|
1103
1183
|
|
|
1104
|
-
static void generate_booltest(struct generator * g, struct node * p) {
|
|
1184
|
+
static void generate_booltest(struct generator * g, struct node * p, int inverted) {
|
|
1105
1185
|
write_comment(g, p);
|
|
1106
|
-
g
|
|
1107
|
-
|
|
1186
|
+
if (tailcallable(g, p)) {
|
|
1187
|
+
// Optimise at end of function.
|
|
1188
|
+
if (inverted) {
|
|
1189
|
+
writef(g, "~Mreturn !~V;~N", p);
|
|
1190
|
+
} else {
|
|
1191
|
+
writef(g, "~Mreturn ~V;~N", p);
|
|
1192
|
+
}
|
|
1193
|
+
p->right = NULL;
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
if (inverted) {
|
|
1197
|
+
write_failure_if(g, "~V", p);
|
|
1198
|
+
} else {
|
|
1199
|
+
write_failure_if(g, "!~V", p);
|
|
1200
|
+
}
|
|
1108
1201
|
}
|
|
1109
1202
|
|
|
1110
1203
|
static void generate_false(struct generator * g, struct node * p) {
|
|
@@ -1148,25 +1241,21 @@ static void generate(struct generator * g, struct node * p) {
|
|
|
1148
1241
|
case c_repeat: generate_repeat(g, p); break;
|
|
1149
1242
|
case c_loop: generate_loop(g, p); break;
|
|
1150
1243
|
case c_atleast: generate_atleast(g, p); break;
|
|
1151
|
-
case c_setmark: generate_setmark(g, p); break;
|
|
1152
1244
|
case c_tomark: generate_tomark(g, p); break;
|
|
1153
|
-
case c_atmark: generate_atmark(g, p); break;
|
|
1154
1245
|
case c_hop: generate_hop(g, p); break;
|
|
1155
|
-
case c_delete: generate_delete(g, p); break;
|
|
1156
1246
|
case c_next: generate_next(g, p); break;
|
|
1157
1247
|
case c_tolimit: generate_tolimit(g, p); break;
|
|
1158
|
-
case c_atlimit: generate_atlimit(g, p); break;
|
|
1159
1248
|
case c_leftslice: generate_leftslice(g, p); break;
|
|
1160
1249
|
case c_rightslice: generate_rightslice(g, p); break;
|
|
1161
1250
|
case c_assignto: generate_assignto(g, p); break;
|
|
1162
1251
|
case c_sliceto: generate_sliceto(g, p); break;
|
|
1163
|
-
case
|
|
1252
|
+
case c_stringassign: generate_stringassign(g, p); break;
|
|
1164
1253
|
case c_insert:
|
|
1165
1254
|
case c_attach: generate_insert(g, p, p->type); break;
|
|
1166
1255
|
case c_slicefrom: generate_slicefrom(g, p); break;
|
|
1167
1256
|
case c_setlimit: generate_setlimit(g, p); break;
|
|
1168
1257
|
case c_dollar: generate_dollar(g, p); break;
|
|
1169
|
-
case
|
|
1258
|
+
case c_assign: generate_integer_assign(g, p, "="); break;
|
|
1170
1259
|
case c_plusassign: generate_integer_assign(g, p, "+="); break;
|
|
1171
1260
|
case c_minusassign: generate_integer_assign(g, p, "-="); break;
|
|
1172
1261
|
case c_multiplyassign:generate_integer_assign(g, p, "*="); break;
|
|
@@ -1186,7 +1275,8 @@ static void generate(struct generator * g, struct node * p) {
|
|
|
1186
1275
|
case c_literalstring: generate_literalstring(g, p); break;
|
|
1187
1276
|
case c_among: generate_among(g, p); break;
|
|
1188
1277
|
case c_substring: generate_substring(g, p); break;
|
|
1189
|
-
case c_booltest: generate_booltest(g, p); break;
|
|
1278
|
+
case c_booltest: generate_booltest(g, p, false); break;
|
|
1279
|
+
case c_not_booltest: generate_booltest(g, p, true); break;
|
|
1190
1280
|
case c_false: generate_false(g, p); break;
|
|
1191
1281
|
case c_true: break;
|
|
1192
1282
|
case c_debug: generate_debug(g, p); break;
|
|
@@ -1208,7 +1298,7 @@ static void generate_class_begin(struct generator * g) {
|
|
|
1208
1298
|
w(g, "#pragma warning disable 0162~N~N");
|
|
1209
1299
|
|
|
1210
1300
|
w(g, "~Mnamespace ");
|
|
1211
|
-
|
|
1301
|
+
write_string(g, g->options->package);
|
|
1212
1302
|
w(g, "~N~{");
|
|
1213
1303
|
|
|
1214
1304
|
w(g, "~Musing System;~N");
|
|
@@ -1224,7 +1314,7 @@ static void generate_class_begin(struct generator * g) {
|
|
|
1224
1314
|
w(g, "~M/// ~N");
|
|
1225
1315
|
w(g, "~M[System.CodeDom.Compiler.GeneratedCode(\"Snowball\", \"" SNOWBALL_VERSION "\")]~N");
|
|
1226
1316
|
w(g, "~Mpublic partial class ~n : ");
|
|
1227
|
-
|
|
1317
|
+
write_string(g, g->options->parent_class_name);
|
|
1228
1318
|
w(g, "~N~{");
|
|
1229
1319
|
}
|
|
1230
1320
|
|
|
@@ -1235,97 +1325,96 @@ static void generate_class_end(struct generator * g) {
|
|
|
1235
1325
|
w(g, "~N");
|
|
1236
1326
|
}
|
|
1237
1327
|
|
|
1238
|
-
static void generate_among_table(struct generator * g, struct among * x
|
|
1328
|
+
static void generate_among_table(struct generator * g, struct among * x) {
|
|
1239
1329
|
write_newline(g);
|
|
1240
1330
|
write_comment(g, x->node);
|
|
1241
1331
|
|
|
1242
1332
|
struct amongvec * v = x->b;
|
|
1243
1333
|
|
|
1244
1334
|
g->I[0] = x->number;
|
|
1245
|
-
g
|
|
1246
|
-
w(g, "~M~S0a_~I0 = new[] ~N~M{~N~+");
|
|
1335
|
+
w(g, "~Mprivate static readonly Among[] a_~I0 = new[] ~N~M{~N~+");
|
|
1247
1336
|
for (int i = 0; i < x->literalstring_count; i++) {
|
|
1248
|
-
g
|
|
1249
|
-
g->I[
|
|
1250
|
-
g->
|
|
1251
|
-
g->
|
|
1252
|
-
|
|
1253
|
-
w(g, "~Mnew Among(
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1337
|
+
if (i) w(g, ",~N");
|
|
1338
|
+
g->I[3] = v[i].i;
|
|
1339
|
+
g->I[4] = v[i].result;
|
|
1340
|
+
g->I[5] = v[i].function_index;
|
|
1341
|
+
|
|
1342
|
+
w(g, "~Mnew Among(");
|
|
1343
|
+
write_literal_string(g, v[i].b);
|
|
1344
|
+
w(g, ", ~I3, ~I4, ~I5)");
|
|
1345
|
+
}
|
|
1346
|
+
w(g, "~N~-~M};~N");
|
|
1347
|
+
|
|
1348
|
+
if (x->function_count <= 1) return;
|
|
1349
|
+
|
|
1350
|
+
w(g, "~N~Mprivate bool af_~I0() {~N~+");
|
|
1351
|
+
w(g, "~Mswitch (af) {~N~+");
|
|
1352
|
+
for (int n = 1; n <= x->function_count; n++) {
|
|
1353
|
+
w(g, "~Mcase ");
|
|
1354
|
+
write_int(g, n);
|
|
1355
|
+
w(g, ": return ");
|
|
1356
|
+
for (int i = 0; i < x->literalstring_count; i++) {
|
|
1357
|
+
if (v[i].function_index == n) {
|
|
1358
|
+
write_varref(g, v[i].function);
|
|
1359
|
+
w(g, "();~N");
|
|
1360
|
+
break;
|
|
1361
|
+
}
|
|
1257
1362
|
}
|
|
1258
|
-
w(g, ")~S0~N");
|
|
1259
1363
|
}
|
|
1260
|
-
w(g, "~-~M}
|
|
1364
|
+
w(g, "~-~M}~N");
|
|
1365
|
+
w(g, "~Mreturn false;~N");
|
|
1366
|
+
w(g, "~-~M}~N");
|
|
1261
1367
|
}
|
|
1262
1368
|
|
|
1263
1369
|
static void generate_amongs(struct generator * g) {
|
|
1264
1370
|
for (struct among * x = g->analyser->amongs; x; x = x->next) {
|
|
1265
|
-
|
|
1266
|
-
g->I[0] = x->number;
|
|
1267
|
-
g->I[1] = x->literalstring_count;
|
|
1268
|
-
|
|
1269
|
-
w(g, "~N~Mprivate readonly Among[] a_~I0;~N");
|
|
1270
|
-
} else {
|
|
1271
|
-
generate_among_table(g, x, "private static readonly Among[] ");
|
|
1272
|
-
}
|
|
1371
|
+
generate_among_table(g, x);
|
|
1273
1372
|
}
|
|
1274
1373
|
w(g, "~N");
|
|
1275
|
-
|
|
1276
|
-
if (g->analyser->among_with_function_count == 0) return;
|
|
1277
|
-
|
|
1278
|
-
w(g, "~M/// <summary>~N");
|
|
1279
|
-
w(g, "~M/// Initializes a new instance of the <see cref=\"~n\"/> class.~N");
|
|
1280
|
-
w(g, "~M/// </summary>~N");
|
|
1281
|
-
w(g, "~M/// ~N");
|
|
1282
|
-
w(g, "~Mpublic ~n()~N~{");
|
|
1283
|
-
for (struct among * x = g->analyser->amongs; x; x = x->next) {
|
|
1284
|
-
if (x->function_count) {
|
|
1285
|
-
generate_among_table(g, x, "");
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
w(g, "~}~N~N");
|
|
1290
1374
|
}
|
|
1291
1375
|
|
|
1292
1376
|
static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
|
1293
1377
|
symbol * b = q->b;
|
|
1294
1378
|
|
|
1295
|
-
g
|
|
1296
|
-
|
|
1297
|
-
|
|
1379
|
+
w(g, "~Mprivate const string ");
|
|
1380
|
+
write_varname(g, q->name);
|
|
1381
|
+
write_string(g, " = ");
|
|
1298
1382
|
write_literal_string(g, b);
|
|
1299
1383
|
w(g, ";~N");
|
|
1300
1384
|
}
|
|
1301
1385
|
|
|
1302
1386
|
static void generate_groupings(struct generator * g) {
|
|
1303
1387
|
for (struct grouping * q = g->analyser->groupings; q; q = q->next) {
|
|
1304
|
-
|
|
1305
|
-
generate_grouping_table(g, q);
|
|
1388
|
+
generate_grouping_table(g, q);
|
|
1306
1389
|
}
|
|
1307
1390
|
}
|
|
1308
1391
|
|
|
1309
1392
|
static void generate_members(struct generator * g) {
|
|
1310
|
-
|
|
1393
|
+
bool wrote_members = false;
|
|
1311
1394
|
|
|
1312
1395
|
for (struct name * q = g->analyser->names; q; q = q->next) {
|
|
1313
|
-
|
|
1396
|
+
if (q->local_to) continue;
|
|
1314
1397
|
switch (q->type) {
|
|
1315
1398
|
case t_string:
|
|
1316
1399
|
w(g, "~Mprivate ");
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1400
|
+
write_string(g, g->options->string_class);
|
|
1401
|
+
write_char(g, ' ');
|
|
1402
|
+
write_varname(g, q);
|
|
1403
|
+
write_string(g, " = new ");
|
|
1404
|
+
write_string(g, g->options->string_class);
|
|
1320
1405
|
w(g, "();~N");
|
|
1321
1406
|
wrote_members = true;
|
|
1322
1407
|
break;
|
|
1323
1408
|
case t_integer:
|
|
1324
|
-
w(g, "~Mprivate int
|
|
1409
|
+
w(g, "~Mprivate int ");
|
|
1410
|
+
write_varname(g, q);
|
|
1411
|
+
w(g, ";~N");
|
|
1325
1412
|
wrote_members = true;
|
|
1326
1413
|
break;
|
|
1327
1414
|
case t_boolean:
|
|
1328
|
-
w(g, "~Mprivate bool
|
|
1415
|
+
w(g, "~Mprivate bool ");
|
|
1416
|
+
write_varname(g, q);
|
|
1417
|
+
w(g, ";~N");
|
|
1329
1418
|
wrote_members = true;
|
|
1330
1419
|
break;
|
|
1331
1420
|
}
|
|
@@ -1340,6 +1429,8 @@ static void generate_methods(struct generator * g) {
|
|
|
1340
1429
|
}
|
|
1341
1430
|
|
|
1342
1431
|
extern void generate_program_csharp(struct generator * g) {
|
|
1432
|
+
g->varname_prefix = "c";
|
|
1433
|
+
|
|
1343
1434
|
g->outbuf = str_new();
|
|
1344
1435
|
g->failure_str = str_new();
|
|
1345
1436
|
|