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,113 +1,90 @@
|
|
|
1
1
|
#include <assert.h>
|
|
2
|
+
#include <ctype.h>
|
|
3
|
+
#include <stdio.h> /* for fprintf etc */
|
|
2
4
|
#include <stdlib.h> /* for exit */
|
|
3
5
|
#include <string.h> /* for strlen */
|
|
4
|
-
#include <stdio.h> /* for fprintf etc */
|
|
5
6
|
#include "header.h"
|
|
6
7
|
|
|
7
8
|
#define BASE_UNIT "SnowballProgram"
|
|
8
9
|
#define BASE_CLASS "T" BASE_UNIT
|
|
9
10
|
|
|
10
|
-
/*
|
|
11
|
+
/* prototype functions for recursive use: */
|
|
11
12
|
|
|
12
13
|
static void generate(struct generator * g, struct node * p);
|
|
13
14
|
static void w(struct generator * g, const char * s);
|
|
14
15
|
static void writef(struct generator * g, const char * s, struct node * p);
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
return g->next_label++;
|
|
18
|
-
}
|
|
17
|
+
/* Write routines for items from the syntax tree */
|
|
19
18
|
|
|
20
|
-
static
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
static void write_relop(struct generator * g, int relop) {
|
|
20
|
+
// Relational operators are the same as C, save for (in-)equality.
|
|
21
|
+
switch (relop) {
|
|
22
|
+
case c_eq: write_string(g, " = "); break;
|
|
23
|
+
case c_ne: write_string(g, " <> "); break;
|
|
24
|
+
default: write_c_relop(g, relop);
|
|
25
|
+
}
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
/* Write routines for items from the syntax tree */
|
|
30
|
-
|
|
31
28
|
static void write_varname(struct generator * g, struct name * p) {
|
|
32
|
-
if (p->type
|
|
29
|
+
if (p->type == t_external) {
|
|
30
|
+
if (g->options->externals_prefix) {
|
|
31
|
+
write_string(g, g->options->externals_prefix);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
33
34
|
/* Pascal identifiers are case-insensitive but Snowball identifiers
|
|
34
|
-
* should be case-sensitive. To address this,
|
|
35
|
-
* the
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* encode the case pattern in the Snowball identifier using "U" for
|
|
40
|
-
* an upper-case letter, "l" for a lower-case letter and nothing for
|
|
41
|
-
* other characters. Any trailing string of "l" is omitted (since
|
|
42
|
-
* it's redundant and decreases readability).
|
|
43
|
-
*
|
|
44
|
-
* Identifiers without any upper-case encode most simply, e.g. I_foo2
|
|
35
|
+
* should be case-sensitive. To address this, if any groups of
|
|
36
|
+
* identifiers of the same type have the same case, we insert a counter
|
|
37
|
+
* after the type-code for all but one of them. This count is unique
|
|
38
|
+
* within each type of variable so this avoid collisions while being
|
|
39
|
+
* minimally intrusive on the readability of the generated code.
|
|
45
40
|
*
|
|
46
|
-
*
|
|
41
|
+
* So for example:
|
|
47
42
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* But any example can be handled, e.g. IUllU_Foo79_Bar
|
|
43
|
+
* Snowball integer `i` -> Pascal `I_i`
|
|
44
|
+
* Snowball integer `I` -> Pascal `I2_i`
|
|
51
45
|
*
|
|
52
46
|
* We don't try to solve this problem for external identifiers - it
|
|
53
47
|
* seems more helpful to leave those alone and encourage snowball
|
|
54
48
|
* program authors to avoid naming externals which only differ by
|
|
55
49
|
* case.
|
|
50
|
+
*
|
|
51
|
+
* We use the same naming scheme for both global and local variables.
|
|
56
52
|
*/
|
|
57
|
-
int len = SIZE(p->s);
|
|
58
|
-
int lower_pending = 0;
|
|
59
53
|
write_char(g, "SBIrxg"[p->type]);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (ch >= 'a' && ch <= 'z') {
|
|
63
|
-
++lower_pending;
|
|
64
|
-
} else if (ch >= 'A' && ch <= 'Z') {
|
|
65
|
-
while (lower_pending) {
|
|
66
|
-
write_char(g, 'l');
|
|
67
|
-
--lower_pending;
|
|
68
|
-
}
|
|
69
|
-
write_char(g, 'U');
|
|
70
|
-
}
|
|
54
|
+
if (p->case_collision) {
|
|
55
|
+
write_int(g, p->count);
|
|
71
56
|
}
|
|
72
|
-
|
|
73
57
|
write_char(g, '_');
|
|
74
58
|
}
|
|
75
59
|
write_s(g, p->s);
|
|
76
60
|
}
|
|
77
61
|
|
|
78
62
|
static void write_literal_string(struct generator * g, symbol * p) {
|
|
79
|
-
|
|
63
|
+
if (SIZE(p) == 0) {
|
|
64
|
+
write_string(g, "''");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
bool in_quotes = false;
|
|
80
68
|
for (int i = 0; i < SIZE(p); i++) {
|
|
81
69
|
int ch = p[i];
|
|
82
|
-
if (ch
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
if (32 <= ch && ch < 127) {
|
|
71
|
+
if (!in_quotes) {
|
|
72
|
+
write_char(g, '\'');
|
|
73
|
+
in_quotes = true;
|
|
74
|
+
}
|
|
75
|
+
if (ch == '\'') write_char(g, '\'');
|
|
85
76
|
write_char(g, ch);
|
|
86
77
|
} else {
|
|
87
|
-
|
|
78
|
+
if (in_quotes) {
|
|
79
|
+
write_char(g, '\'');
|
|
80
|
+
in_quotes = false;
|
|
81
|
+
}
|
|
88
82
|
write_char(g, '#');
|
|
89
|
-
write_int
|
|
90
|
-
write_char(g, '\'');
|
|
83
|
+
write_int(g, ch);
|
|
91
84
|
}
|
|
92
85
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
static void write_margin(struct generator * g) {
|
|
97
|
-
for (int i = 0; i < g->margin; i++) write_string(g, " ");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
static void write_relop(struct generator * g, int relop) {
|
|
101
|
-
switch (relop) {
|
|
102
|
-
case c_eq: write_string(g, " = "); break;
|
|
103
|
-
case c_ne: write_string(g, " <> "); break;
|
|
104
|
-
case c_gt: write_string(g, " > "); break;
|
|
105
|
-
case c_ge: write_string(g, " >= "); break;
|
|
106
|
-
case c_lt: write_string(g, " < "); break;
|
|
107
|
-
case c_le: write_string(g, " <= "); break;
|
|
108
|
-
default:
|
|
109
|
-
fprintf(stderr, "Unexpected type #%d in generate_integer_test\n", relop);
|
|
110
|
-
exit(1);
|
|
86
|
+
if (in_quotes) {
|
|
87
|
+
write_char(g, '\'');
|
|
111
88
|
}
|
|
112
89
|
}
|
|
113
90
|
|
|
@@ -119,7 +96,7 @@ static void write_declare(struct generator * g,
|
|
|
119
96
|
g->outbuf = g->declarations;
|
|
120
97
|
write_string(g, " ");
|
|
121
98
|
writef(g, declaration, p);
|
|
122
|
-
|
|
99
|
+
write_char(g, ';');
|
|
123
100
|
write_newline(g);
|
|
124
101
|
g->outbuf = temp;
|
|
125
102
|
}
|
|
@@ -127,9 +104,8 @@ static void write_declare(struct generator * g,
|
|
|
127
104
|
static void write_comment(struct generator * g, struct node * p) {
|
|
128
105
|
if (!g->options->comments) return;
|
|
129
106
|
write_margin(g);
|
|
130
|
-
write_string(g, "
|
|
131
|
-
write_comment_content(g, p);
|
|
132
|
-
write_string(g, " }");
|
|
107
|
+
write_string(g, "// ");
|
|
108
|
+
write_comment_content(g, p, NULL);
|
|
133
109
|
write_newline(g);
|
|
134
110
|
}
|
|
135
111
|
|
|
@@ -154,7 +130,7 @@ static void append_restore_string(struct node * p, struct str * out, struct str
|
|
|
154
130
|
str_append_string(out, "FCursor := ");
|
|
155
131
|
if (p->mode != m_forward) str_append_string(out, "FLimit - ");
|
|
156
132
|
str_append(out, savevar);
|
|
157
|
-
|
|
133
|
+
str_append_ch(out, ';');
|
|
158
134
|
}
|
|
159
135
|
|
|
160
136
|
static void write_restorecursor(struct generator * g, struct node * p, struct str * savevar) {
|
|
@@ -169,25 +145,12 @@ static void write_inc_cursor(struct generator * g, struct node * p) {
|
|
|
169
145
|
write_newline(g);
|
|
170
146
|
}
|
|
171
147
|
|
|
172
|
-
static void
|
|
173
|
-
w(g, "~MRepeat~N~+");
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
static void wsetlab_end(struct generator * g, int n) {
|
|
177
|
-
w(g, "~-~MUntil True;~N");
|
|
148
|
+
static void wsetl(struct generator * g, int n) {
|
|
178
149
|
w(g, "lab");
|
|
179
150
|
write_int(g, n);
|
|
180
151
|
w(g, ":~N");
|
|
181
152
|
}
|
|
182
153
|
|
|
183
|
-
static void wgotol(struct generator * g, int n) {
|
|
184
|
-
write_margin(g);
|
|
185
|
-
write_string(g, "goto lab");
|
|
186
|
-
write_int(g, n);
|
|
187
|
-
write_string(g, ";");
|
|
188
|
-
write_newline(g);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
154
|
static void write_failure(struct generator * g) {
|
|
192
155
|
if (str_len(g->failure_str) != 0) {
|
|
193
156
|
write_margin(g);
|
|
@@ -198,15 +161,15 @@ static void write_failure(struct generator * g) {
|
|
|
198
161
|
switch (g->failure_label) {
|
|
199
162
|
case x_return:
|
|
200
163
|
write_string(g, "Begin Result := False; Exit; End;");
|
|
201
|
-
g->unreachable = true;
|
|
202
164
|
break;
|
|
203
165
|
default:
|
|
204
166
|
write_string(g, "goto lab");
|
|
205
167
|
write_int(g, g->failure_label);
|
|
206
|
-
|
|
207
|
-
g->
|
|
168
|
+
write_char(g, ';');
|
|
169
|
+
g->label_used = 1;
|
|
208
170
|
}
|
|
209
171
|
write_newline(g);
|
|
172
|
+
g->unreachable = true;
|
|
210
173
|
}
|
|
211
174
|
|
|
212
175
|
static void write_failure_if(struct generator * g, const char * s, struct node * p) {
|
|
@@ -230,7 +193,6 @@ static void write_check_limit(struct generator * g, struct node * p) {
|
|
|
230
193
|
|
|
231
194
|
/* Formatted write. */
|
|
232
195
|
static void writef(struct generator * g, const char * input, struct node * p) {
|
|
233
|
-
(void)p;
|
|
234
196
|
int i = 0;
|
|
235
197
|
|
|
236
198
|
while (input[i]) {
|
|
@@ -276,23 +238,18 @@ static void writef(struct generator * g, const char * input, struct node * p) {
|
|
|
276
238
|
continue;
|
|
277
239
|
}
|
|
278
240
|
case 'V':
|
|
279
|
-
case 'W':
|
|
280
|
-
|
|
281
|
-
if (j < 0 || j > (int)(sizeof(g->V) / sizeof(g->V[0])))
|
|
282
|
-
goto invalid_escape2;
|
|
283
|
-
write_varname(g, g->V[j]);
|
|
241
|
+
case 'W':
|
|
242
|
+
write_varname(g, p->name);
|
|
284
243
|
continue;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
write_literal_string(g, g->L[j]);
|
|
244
|
+
case 'L':
|
|
245
|
+
write_literal_string(g, p->literalstring);
|
|
246
|
+
continue;
|
|
247
|
+
case 's':
|
|
248
|
+
write_int(g, SIZE(p->literalstring));
|
|
291
249
|
continue;
|
|
292
|
-
}
|
|
293
250
|
case '+': g->margin++; continue;
|
|
294
251
|
case '-': g->margin--; continue;
|
|
295
|
-
case 'n':
|
|
252
|
+
case 'n': write_s(g, g->options->name); continue;
|
|
296
253
|
default:
|
|
297
254
|
printf("Invalid escape sequence ~%c in writef(g, \"%s\", p)\n",
|
|
298
255
|
ch, input);
|
|
@@ -313,38 +270,52 @@ static void generate_AE(struct generator * g, struct node * p) {
|
|
|
313
270
|
const char * s;
|
|
314
271
|
switch (p->type) {
|
|
315
272
|
case c_name:
|
|
316
|
-
write_varname(g, p->name);
|
|
273
|
+
write_varname(g, p->name);
|
|
274
|
+
break;
|
|
317
275
|
case c_number:
|
|
318
|
-
write_int(g, p->number);
|
|
276
|
+
write_int(g, p->number);
|
|
277
|
+
break;
|
|
319
278
|
case c_maxint:
|
|
320
|
-
write_string(g, "MAXINT");
|
|
279
|
+
write_string(g, "MAXINT");
|
|
280
|
+
break;
|
|
321
281
|
case c_minint:
|
|
322
|
-
write_string(g, "(-MAXINT - 1)");
|
|
282
|
+
write_string(g, "(-MAXINT - 1)");
|
|
283
|
+
break;
|
|
323
284
|
case c_neg:
|
|
324
|
-
write_char(g, '-');
|
|
285
|
+
write_char(g, '-');
|
|
286
|
+
generate_AE(g, p->right);
|
|
287
|
+
break;
|
|
325
288
|
case c_multiply:
|
|
326
|
-
s = " * ";
|
|
327
|
-
|
|
328
|
-
s = " + "; goto label0;
|
|
329
|
-
case c_minus:
|
|
330
|
-
s = " - "; goto label0;
|
|
289
|
+
s = " * ";
|
|
290
|
+
goto label0;
|
|
331
291
|
case c_divide:
|
|
332
292
|
s = " div ";
|
|
293
|
+
goto label0;
|
|
294
|
+
case c_plus:
|
|
295
|
+
s = " + ";
|
|
296
|
+
goto label0;
|
|
297
|
+
case c_minus:
|
|
298
|
+
s = " - ";
|
|
333
299
|
label0:
|
|
334
|
-
write_char(g, '(');
|
|
335
|
-
|
|
300
|
+
write_char(g, '(');
|
|
301
|
+
generate_AE(g, p->left);
|
|
302
|
+
write_string(g, s);
|
|
303
|
+
generate_AE(g, p->right);
|
|
304
|
+
write_char(g, ')');
|
|
305
|
+
break;
|
|
336
306
|
case c_cursor:
|
|
337
|
-
w(g, "FCursor");
|
|
307
|
+
w(g, "FCursor");
|
|
308
|
+
break;
|
|
338
309
|
case c_limit:
|
|
339
|
-
w(g, p->mode == m_forward ? "FLimit" : "FBkLimit");
|
|
310
|
+
w(g, p->mode == m_forward ? "FLimit" : "FBkLimit");
|
|
311
|
+
break;
|
|
340
312
|
case c_len:
|
|
341
313
|
case c_size:
|
|
342
314
|
w(g, "Length(current)");
|
|
343
315
|
break;
|
|
344
316
|
case c_lenof:
|
|
345
317
|
case c_sizeof:
|
|
346
|
-
g
|
|
347
|
-
w(g, "Length(~V0)");
|
|
318
|
+
writef(g, "Length(~V)", p);
|
|
348
319
|
break;
|
|
349
320
|
}
|
|
350
321
|
}
|
|
@@ -360,13 +331,15 @@ static void generate_bra(struct generator * g, struct node * p) {
|
|
|
360
331
|
|
|
361
332
|
static void generate_and(struct generator * g, struct node * p) {
|
|
362
333
|
struct str * savevar = NULL;
|
|
363
|
-
if (
|
|
334
|
+
if (K_needed_for_and(p->left)) {
|
|
364
335
|
savevar = vars_newname(g);
|
|
365
336
|
}
|
|
366
337
|
|
|
367
338
|
write_comment(g, p);
|
|
368
339
|
|
|
369
|
-
if (savevar)
|
|
340
|
+
if (savevar) {
|
|
341
|
+
write_savecursor(g, p, savevar);
|
|
342
|
+
}
|
|
370
343
|
|
|
371
344
|
p = p->left;
|
|
372
345
|
while (p) {
|
|
@@ -383,20 +356,22 @@ static void generate_and(struct generator * g, struct node * p) {
|
|
|
383
356
|
|
|
384
357
|
static void generate_or(struct generator * g, struct node * p) {
|
|
385
358
|
struct str * savevar = NULL;
|
|
386
|
-
if (
|
|
359
|
+
if (K_needed_for_or(p->left)) {
|
|
387
360
|
savevar = vars_newname(g);
|
|
388
361
|
}
|
|
389
362
|
|
|
363
|
+
int used = g->label_used;
|
|
390
364
|
int a0 = g->failure_label;
|
|
391
365
|
struct str * a1 = str_copy(g->failure_str);
|
|
392
366
|
|
|
393
|
-
|
|
394
|
-
int end_unreachable = true;
|
|
367
|
+
bool end_unreachable = true;
|
|
395
368
|
|
|
396
369
|
write_comment(g, p);
|
|
397
|
-
|
|
370
|
+
w(g, "~MRepeat~N~+");
|
|
398
371
|
|
|
399
|
-
if (savevar
|
|
372
|
+
if (savevar && K_needed_node_on_f(p)) {
|
|
373
|
+
write_savecursor(g, p, savevar);
|
|
374
|
+
}
|
|
400
375
|
|
|
401
376
|
p = p->left;
|
|
402
377
|
str_clear(g->failure_str);
|
|
@@ -407,26 +382,33 @@ static void generate_or(struct generator * g, struct node * p) {
|
|
|
407
382
|
fprintf(stderr, "Error: \"or\" node without children nodes.");
|
|
408
383
|
exit(1);
|
|
409
384
|
}
|
|
410
|
-
while (p->right) {
|
|
411
|
-
|
|
412
|
-
|
|
385
|
+
while (p->right != NULL) {
|
|
386
|
+
int label = new_label(g);
|
|
387
|
+
g->failure_label = label;
|
|
388
|
+
g->label_used = 0;
|
|
413
389
|
generate(g, p);
|
|
414
390
|
if (!g->unreachable) {
|
|
415
|
-
|
|
391
|
+
w(g, "~MBreak;~N");
|
|
416
392
|
end_unreachable = false;
|
|
417
393
|
}
|
|
418
|
-
|
|
394
|
+
|
|
395
|
+
if (g->label_used)
|
|
396
|
+
wsetl(g, g->failure_label);
|
|
419
397
|
g->unreachable = false;
|
|
420
|
-
if (savevar)
|
|
398
|
+
if (savevar) {
|
|
399
|
+
write_restorecursor(g, p, savevar);
|
|
400
|
+
}
|
|
421
401
|
p = p->right;
|
|
422
402
|
}
|
|
423
403
|
|
|
404
|
+
g->label_used = used;
|
|
424
405
|
g->failure_label = a0;
|
|
425
406
|
str_delete(g->failure_str);
|
|
426
407
|
g->failure_str = a1;
|
|
427
408
|
|
|
428
409
|
generate(g, p);
|
|
429
|
-
|
|
410
|
+
|
|
411
|
+
w(g, "~-~MUntil True;~N");
|
|
430
412
|
if (!end_unreachable) {
|
|
431
413
|
g->unreachable = false;
|
|
432
414
|
}
|
|
@@ -443,10 +425,9 @@ static void generate_backwards(struct generator * g, struct node * p) {
|
|
|
443
425
|
w(g, "~MFCursor := FBkLimit;~N");
|
|
444
426
|
}
|
|
445
427
|
|
|
446
|
-
|
|
447
428
|
static void generate_not(struct generator * g, struct node * p) {
|
|
448
429
|
struct str * savevar = NULL;
|
|
449
|
-
if (
|
|
430
|
+
if (K_needed_node_on_f(p->left)) {
|
|
450
431
|
savevar = vars_newname(g);
|
|
451
432
|
}
|
|
452
433
|
|
|
@@ -459,12 +440,10 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
|
459
440
|
write_savecursor(g, p, savevar);
|
|
460
441
|
}
|
|
461
442
|
|
|
462
|
-
|
|
443
|
+
int label = new_label(g);
|
|
444
|
+
g->failure_label = label;
|
|
463
445
|
str_clear(g->failure_str);
|
|
464
446
|
|
|
465
|
-
wsetlab_begin(g);
|
|
466
|
-
int l = g->failure_label;
|
|
467
|
-
|
|
468
447
|
generate(g, p->left);
|
|
469
448
|
|
|
470
449
|
g->failure_label = a0;
|
|
@@ -473,7 +452,9 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
|
473
452
|
|
|
474
453
|
if (!g->unreachable) write_failure(g);
|
|
475
454
|
|
|
476
|
-
|
|
455
|
+
if (g->label_used)
|
|
456
|
+
wsetl(g, label);
|
|
457
|
+
|
|
477
458
|
g->unreachable = false;
|
|
478
459
|
|
|
479
460
|
if (savevar) {
|
|
@@ -483,14 +464,15 @@ static void generate_not(struct generator * g, struct node * p) {
|
|
|
483
464
|
}
|
|
484
465
|
}
|
|
485
466
|
|
|
486
|
-
|
|
487
467
|
static void generate_try(struct generator * g, struct node * p) {
|
|
488
468
|
struct str * savevar = NULL;
|
|
489
|
-
if (K_needed(
|
|
469
|
+
if (K_needed(p->left)) {
|
|
490
470
|
savevar = vars_newname(g);
|
|
491
471
|
}
|
|
492
472
|
|
|
493
|
-
|
|
473
|
+
int label = new_label(g);
|
|
474
|
+
g->failure_label = label;
|
|
475
|
+
g->label_used = 0;
|
|
494
476
|
str_clear(g->failure_str);
|
|
495
477
|
|
|
496
478
|
write_comment(g, p);
|
|
@@ -499,9 +481,10 @@ static void generate_try(struct generator * g, struct node * p) {
|
|
|
499
481
|
append_restore_string(p, g->failure_str, savevar);
|
|
500
482
|
}
|
|
501
483
|
|
|
502
|
-
wsetlab_begin(g);
|
|
503
484
|
generate(g, p->left);
|
|
504
|
-
|
|
485
|
+
|
|
486
|
+
if (g->label_used)
|
|
487
|
+
wsetl(g, g->failure_label);
|
|
505
488
|
g->unreachable = false;
|
|
506
489
|
|
|
507
490
|
if (savevar) {
|
|
@@ -511,14 +494,12 @@ static void generate_try(struct generator * g, struct node * p) {
|
|
|
511
494
|
|
|
512
495
|
static void generate_set(struct generator * g, struct node * p) {
|
|
513
496
|
write_comment(g, p);
|
|
514
|
-
g
|
|
515
|
-
writef(g, "~M~V0 := True;~N", p);
|
|
497
|
+
writef(g, "~M~V := True;~N", p);
|
|
516
498
|
}
|
|
517
499
|
|
|
518
500
|
static void generate_unset(struct generator * g, struct node * p) {
|
|
519
501
|
write_comment(g, p);
|
|
520
|
-
g
|
|
521
|
-
writef(g, "~M~V0 := False;~N", p);
|
|
502
|
+
writef(g, "~M~V := False;~N", p);
|
|
522
503
|
}
|
|
523
504
|
|
|
524
505
|
static void generate_fail(struct generator * g, struct node * p) {
|
|
@@ -528,10 +509,9 @@ static void generate_fail(struct generator * g, struct node * p) {
|
|
|
528
509
|
}
|
|
529
510
|
|
|
530
511
|
/* generate_test() also implements 'reverse' */
|
|
531
|
-
|
|
532
512
|
static void generate_test(struct generator * g, struct node * p) {
|
|
533
513
|
struct str * savevar = NULL;
|
|
534
|
-
if (K_needed(
|
|
514
|
+
if (K_needed(p->left)) {
|
|
535
515
|
savevar = vars_newname(g);
|
|
536
516
|
}
|
|
537
517
|
|
|
@@ -553,25 +533,28 @@ static void generate_test(struct generator * g, struct node * p) {
|
|
|
553
533
|
|
|
554
534
|
static void generate_do(struct generator * g, struct node * p) {
|
|
555
535
|
struct str * savevar = NULL;
|
|
556
|
-
if (K_needed(
|
|
536
|
+
if (K_needed(p->left)) {
|
|
557
537
|
savevar = vars_newname(g);
|
|
558
538
|
}
|
|
559
539
|
|
|
560
540
|
write_comment(g, p);
|
|
561
|
-
if (savevar)
|
|
541
|
+
if (savevar) {
|
|
542
|
+
write_savecursor(g, p, savevar);
|
|
543
|
+
}
|
|
562
544
|
|
|
563
545
|
if (p->left->type == c_call) {
|
|
564
546
|
/* Optimise do <call> */
|
|
565
547
|
write_comment(g, p->left);
|
|
566
|
-
g
|
|
567
|
-
w(g, "~M~V0();~N");
|
|
548
|
+
writef(g, "~M~V();~N", p->left);
|
|
568
549
|
} else {
|
|
569
|
-
|
|
550
|
+
int label = new_label(g);
|
|
551
|
+
g->failure_label = label;
|
|
570
552
|
str_clear(g->failure_str);
|
|
571
553
|
|
|
572
|
-
wsetlab_begin(g);
|
|
573
554
|
generate(g, p->left);
|
|
574
|
-
|
|
555
|
+
|
|
556
|
+
if (g->label_used)
|
|
557
|
+
wsetl(g, g->failure_label);
|
|
575
558
|
g->unreachable = false;
|
|
576
559
|
}
|
|
577
560
|
|
|
@@ -593,37 +576,36 @@ static void generate_GO_grouping(struct generator * g, struct node * p, int is_g
|
|
|
593
576
|
struct grouping * q = p->name->grouping;
|
|
594
577
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
|
595
578
|
g->S[1] = complement ? "In" : "Out";
|
|
596
|
-
g->V[0] = p->name;
|
|
597
579
|
g->I[0] = q->smallest_ch;
|
|
598
580
|
g->I[1] = q->largest_ch;
|
|
599
|
-
write_failure_if(g, "Not (Go~S1Grouping~S0(~
|
|
581
|
+
write_failure_if(g, "Not (Go~S1Grouping~S0(~V, ~I0, ~I1))", p);
|
|
600
582
|
if (!is_goto) {
|
|
601
|
-
|
|
583
|
+
w(g, p->mode == m_forward ? "~MInc(FCursor);~N" : "~MDec(FCursor);~N");
|
|
602
584
|
}
|
|
603
585
|
}
|
|
604
586
|
|
|
605
|
-
static void generate_GO(struct generator * g, struct node * p, int
|
|
587
|
+
static void generate_GO(struct generator * g, struct node * p, int is_goto) {
|
|
606
588
|
write_comment(g, p);
|
|
607
589
|
|
|
590
|
+
int used = g->label_used;
|
|
608
591
|
int a0 = g->failure_label;
|
|
609
592
|
struct str * a1 = str_copy(g->failure_str);
|
|
610
593
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
int golab = new_label(g);
|
|
594
|
+
bool end_unreachable = false;
|
|
614
595
|
|
|
615
596
|
w(g, "~MWhile True Do~N");
|
|
616
|
-
|
|
597
|
+
write_block_start(g);
|
|
617
598
|
|
|
618
599
|
struct str * savevar = NULL;
|
|
619
|
-
if (
|
|
600
|
+
if (is_goto || repeat_restore(p->left)) {
|
|
620
601
|
savevar = vars_newname(g);
|
|
621
602
|
write_savecursor(g, p, savevar);
|
|
622
603
|
}
|
|
623
604
|
|
|
624
|
-
|
|
605
|
+
int label = new_label(g);
|
|
606
|
+
g->failure_label = label;
|
|
607
|
+
g->label_used = 0;
|
|
625
608
|
str_clear(g->failure_str);
|
|
626
|
-
wsetlab_begin(g);
|
|
627
609
|
generate(g, p->left);
|
|
628
610
|
|
|
629
611
|
if (g->unreachable) {
|
|
@@ -632,32 +614,32 @@ static void generate_GO(struct generator * g, struct node * p, int style) {
|
|
|
632
614
|
end_unreachable = true;
|
|
633
615
|
} else {
|
|
634
616
|
/* include for goto; omit for gopast */
|
|
635
|
-
if (
|
|
636
|
-
g
|
|
637
|
-
w(g, "~Mgoto lab~I0;~N");
|
|
617
|
+
if (is_goto) write_restorecursor(g, p, savevar);
|
|
618
|
+
w(g, "~MBreak;~N");
|
|
638
619
|
}
|
|
620
|
+
|
|
639
621
|
g->unreachable = false;
|
|
640
|
-
|
|
622
|
+
if (g->label_used)
|
|
623
|
+
wsetl(g, g->failure_label);
|
|
641
624
|
if (savevar) {
|
|
642
625
|
write_restorecursor(g, p, savevar);
|
|
643
626
|
str_delete(savevar);
|
|
644
627
|
}
|
|
645
628
|
|
|
629
|
+
g->label_used = used;
|
|
646
630
|
g->failure_label = a0;
|
|
647
631
|
str_delete(g->failure_str);
|
|
648
632
|
g->failure_str = a1;
|
|
649
633
|
|
|
650
634
|
write_check_limit(g, p);
|
|
651
635
|
write_inc_cursor(g, p);
|
|
652
|
-
|
|
653
|
-
g->I[0] = golab;
|
|
654
|
-
w(g, "~}lab~I0:~N");
|
|
636
|
+
write_block_end(g);
|
|
655
637
|
g->unreachable = end_unreachable;
|
|
656
638
|
}
|
|
657
639
|
|
|
658
640
|
static void generate_loop(struct generator * g, struct node * p) {
|
|
659
|
-
struct str * loopvar = vars_newname(g);
|
|
660
641
|
write_comment(g, p);
|
|
642
|
+
struct str * loopvar = vars_newname(g);
|
|
661
643
|
g->B[0] = str_data(loopvar);
|
|
662
644
|
write_declare(g, "~B0 : Integer", p);
|
|
663
645
|
w(g, "~MFor ~B0 := ");
|
|
@@ -675,17 +657,18 @@ static void generate_loop(struct generator * g, struct node * p) {
|
|
|
675
657
|
static void generate_repeat_or_atleast(struct generator * g, struct node * p, struct str * loopvar) {
|
|
676
658
|
int replab = new_label(g);
|
|
677
659
|
g->I[0] = replab;
|
|
678
|
-
writef(g, "lab~I0:~N~
|
|
660
|
+
writef(g, "lab~I0:~N~{", p);
|
|
679
661
|
|
|
680
662
|
struct str * savevar = NULL;
|
|
681
|
-
if (repeat_restore(
|
|
663
|
+
if (repeat_restore(p->left)) {
|
|
682
664
|
savevar = vars_newname(g);
|
|
683
665
|
write_savecursor(g, p, savevar);
|
|
684
666
|
}
|
|
685
667
|
|
|
686
|
-
|
|
668
|
+
int label = new_label(g);
|
|
669
|
+
g->failure_label = label;
|
|
670
|
+
g->label_used = 0;
|
|
687
671
|
str_clear(g->failure_str);
|
|
688
|
-
wsetlab_begin(g);
|
|
689
672
|
generate(g, p->left);
|
|
690
673
|
|
|
691
674
|
if (!g->unreachable) {
|
|
@@ -697,8 +680,8 @@ static void generate_repeat_or_atleast(struct generator * g, struct node * p, st
|
|
|
697
680
|
g->I[0] = replab;
|
|
698
681
|
w(g, "~Mgoto lab~I0;~N");
|
|
699
682
|
}
|
|
700
|
-
|
|
701
|
-
|
|
683
|
+
if (g->label_used)
|
|
684
|
+
wsetl(g, g->failure_label);
|
|
702
685
|
g->unreachable = false;
|
|
703
686
|
|
|
704
687
|
if (savevar) {
|
|
@@ -706,7 +689,7 @@ static void generate_repeat_or_atleast(struct generator * g, struct node * p, st
|
|
|
706
689
|
str_delete(savevar);
|
|
707
690
|
}
|
|
708
691
|
|
|
709
|
-
w(g, "~
|
|
692
|
+
w(g, "~}");
|
|
710
693
|
}
|
|
711
694
|
|
|
712
695
|
static void generate_repeat(struct generator * g, struct node * p) {
|
|
@@ -715,10 +698,10 @@ static void generate_repeat(struct generator * g, struct node * p) {
|
|
|
715
698
|
}
|
|
716
699
|
|
|
717
700
|
static void generate_atleast(struct generator * g, struct node * p) {
|
|
718
|
-
struct str * loopvar = vars_newname(g);
|
|
719
|
-
|
|
720
701
|
write_comment(g, p);
|
|
702
|
+
|
|
721
703
|
w(g, "~{");
|
|
704
|
+
struct str * loopvar = vars_newname(g);
|
|
722
705
|
g->B[0] = str_data(loopvar);
|
|
723
706
|
write_declare(g, "~B0 : Integer", p);
|
|
724
707
|
w(g, "~M~B0 := ");
|
|
@@ -740,12 +723,6 @@ static void generate_atleast(struct generator * g, struct node * p) {
|
|
|
740
723
|
str_delete(loopvar);
|
|
741
724
|
}
|
|
742
725
|
|
|
743
|
-
static void generate_setmark(struct generator * g, struct node * p) {
|
|
744
|
-
write_comment(g, p);
|
|
745
|
-
g->V[0] = p->name;
|
|
746
|
-
writef(g, "~M~W0 := FCursor;~N", p);
|
|
747
|
-
}
|
|
748
|
-
|
|
749
726
|
static void generate_tomark(struct generator * g, struct node * p) {
|
|
750
727
|
write_comment(g, p);
|
|
751
728
|
g->S[0] = p->mode == m_forward ? ">" : "<";
|
|
@@ -758,15 +735,6 @@ static void generate_tomark(struct generator * g, struct node * p) {
|
|
|
758
735
|
w(g, "~MFCursor := "); generate_AE(g, p->AE); writef(g, ";~N", p);
|
|
759
736
|
}
|
|
760
737
|
|
|
761
|
-
static void generate_atmark(struct generator * g, struct node * p) {
|
|
762
|
-
write_comment(g, p);
|
|
763
|
-
w(g, "~MIf (FCursor <> "); generate_AE(g, p->AE); writef(g, ") Then~N", p);
|
|
764
|
-
write_block_start(g);
|
|
765
|
-
write_failure(g);
|
|
766
|
-
write_block_end(g);
|
|
767
|
-
g->unreachable = false;
|
|
768
|
-
}
|
|
769
|
-
|
|
770
738
|
static void generate_hop(struct generator * g, struct node * p) {
|
|
771
739
|
write_comment(g, p);
|
|
772
740
|
g->S[0] = p->mode == m_forward ? "+" : "-";
|
|
@@ -791,24 +759,12 @@ static void generate_hop(struct generator * g, struct node * p) {
|
|
|
791
759
|
g->temporary_used = true;
|
|
792
760
|
}
|
|
793
761
|
|
|
794
|
-
static void generate_delete(struct generator * g, struct node * p) {
|
|
795
|
-
write_comment(g, p);
|
|
796
|
-
writef(g, "~MSliceDel;~N", p);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
762
|
static void generate_tolimit(struct generator * g, struct node * p) {
|
|
800
763
|
write_comment(g, p);
|
|
801
764
|
g->S[0] = p->mode == m_forward ? "FLimit" : "FBkLimit";
|
|
802
765
|
writef(g, "~MFCursor := ~S0;~N", p);
|
|
803
766
|
}
|
|
804
767
|
|
|
805
|
-
static void generate_atlimit(struct generator * g, struct node * p) {
|
|
806
|
-
write_comment(g, p);
|
|
807
|
-
g->S[0] = p->mode == m_forward ? "FLimit" : "FBkLimit";
|
|
808
|
-
g->S[1] = p->mode == m_forward ? "<" : ">";
|
|
809
|
-
write_failure_if(g, "FCursor ~S1 ~S0", p);
|
|
810
|
-
}
|
|
811
|
-
|
|
812
768
|
static void generate_leftslice(struct generator * g, struct node * p) {
|
|
813
769
|
write_comment(g, p);
|
|
814
770
|
g->S[0] = p->mode == m_forward ? "FBra" : "FKet";
|
|
@@ -823,14 +779,12 @@ static void generate_rightslice(struct generator * g, struct node * p) {
|
|
|
823
779
|
|
|
824
780
|
static void generate_assignto(struct generator * g, struct node * p) {
|
|
825
781
|
write_comment(g, p);
|
|
826
|
-
g
|
|
827
|
-
writef(g, "~M~V0 := AssignTo();~N", p);
|
|
782
|
+
writef(g, "~M~V := AssignTo();~N", p);
|
|
828
783
|
}
|
|
829
784
|
|
|
830
785
|
static void generate_sliceto(struct generator * g, struct node * p) {
|
|
831
786
|
write_comment(g, p);
|
|
832
|
-
g
|
|
833
|
-
writef(g, "~M~V0 := SliceTo();~N", p);
|
|
787
|
+
writef(g, "~M~V := SliceTo();~N", p);
|
|
834
788
|
}
|
|
835
789
|
|
|
836
790
|
static void generate_address(struct generator * g, struct node * p) {
|
|
@@ -843,8 +797,8 @@ static void generate_address(struct generator * g, struct node * p) {
|
|
|
843
797
|
}
|
|
844
798
|
|
|
845
799
|
static void generate_insert(struct generator * g, struct node * p, int style) {
|
|
846
|
-
int keep_c = style == c_attach;
|
|
847
800
|
write_comment(g, p);
|
|
801
|
+
int keep_c = style == c_attach;
|
|
848
802
|
if (p->mode == m_backward) keep_c = !keep_c;
|
|
849
803
|
if (keep_c) {
|
|
850
804
|
w(g, "~{~MC := FCursor;~N");
|
|
@@ -856,10 +810,9 @@ static void generate_insert(struct generator * g, struct node * p, int style) {
|
|
|
856
810
|
if (keep_c) w(g, "~MFCursor := C;~N~}");
|
|
857
811
|
}
|
|
858
812
|
|
|
859
|
-
static void
|
|
860
|
-
int keep_c = p->mode == m_forward; /* like 'attach' */
|
|
861
|
-
|
|
813
|
+
static void generate_stringassign(struct generator * g, struct node * p) {
|
|
862
814
|
write_comment(g, p);
|
|
815
|
+
int keep_c = p->mode == m_forward; /* like 'attach' */
|
|
863
816
|
if (keep_c) {
|
|
864
817
|
writef(g, "~{~MC := FCursor;~N", p);
|
|
865
818
|
g->temporary_used = true;
|
|
@@ -871,19 +824,26 @@ static void generate_assignfrom(struct generator * g, struct node * p) {
|
|
|
871
824
|
}
|
|
872
825
|
generate_address(g, p);
|
|
873
826
|
writef(g, ");~N", p);
|
|
874
|
-
if (keep_c)
|
|
827
|
+
if (keep_c) {
|
|
828
|
+
w(g, "~MFCursor := c;~N~}");
|
|
829
|
+
}
|
|
875
830
|
}
|
|
876
831
|
|
|
877
832
|
static void generate_slicefrom(struct generator * g, struct node * p) {
|
|
878
833
|
write_comment(g, p);
|
|
834
|
+
if (p->literalstring && SIZE(p->literalstring) == 0) {
|
|
835
|
+
w(g, "~MSliceDel;~N");
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
879
838
|
w(g, "~MSliceFrom(");
|
|
880
839
|
generate_address(g, p);
|
|
881
|
-
|
|
840
|
+
w(g, ");~N");
|
|
882
841
|
}
|
|
883
842
|
|
|
884
843
|
static void generate_setlimit(struct generator * g, struct node * p) {
|
|
885
|
-
struct str * varname = vars_newname(g);
|
|
886
844
|
write_comment(g, p);
|
|
845
|
+
struct str * varname = vars_newname(g);
|
|
846
|
+
|
|
887
847
|
if (p->left && p->left->type == c_tomark) {
|
|
888
848
|
/* Special case for:
|
|
889
849
|
*
|
|
@@ -895,6 +855,7 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
|
895
855
|
*/
|
|
896
856
|
struct node * q = p->left;
|
|
897
857
|
write_comment(g, q);
|
|
858
|
+
|
|
898
859
|
g->S[0] = q->mode == m_forward ? ">" : "<";
|
|
899
860
|
w(g, "~MIf (FCursor ~S0 "); generate_AE(g, q->AE); w(g, ") Then~N");
|
|
900
861
|
write_block_start(g);
|
|
@@ -905,14 +866,17 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
|
905
866
|
g->B[0] = str_data(varname);
|
|
906
867
|
write_declare(g, "~B0 : Integer", p);
|
|
907
868
|
if (p->mode == m_forward) {
|
|
908
|
-
w(g, "~M~B0 := FLimit
|
|
869
|
+
w(g, "~M~B0 := FLimit;~N");
|
|
909
870
|
w(g, "~MFLimit := ");
|
|
871
|
+
generate_AE(g, q->AE);
|
|
872
|
+
w(g, ";~N");
|
|
873
|
+
w(g, "~M~B0 := ~B0 - FLimit;~N");
|
|
910
874
|
} else {
|
|
911
875
|
w(g, "~M~B0 := FBkLimit;~N");
|
|
912
876
|
w(g, "~MFBkLimit := ");
|
|
877
|
+
generate_AE(g, q->AE);
|
|
878
|
+
w(g, ";~N");
|
|
913
879
|
}
|
|
914
|
-
generate_AE(g, q->AE);
|
|
915
|
-
writef(g, ";~N", q);
|
|
916
880
|
|
|
917
881
|
if (p->mode == m_forward) {
|
|
918
882
|
str_assign(g->failure_str, "FLimit := FLimit + ");
|
|
@@ -971,24 +935,16 @@ static void generate_setlimit(struct generator * g, struct node * p) {
|
|
|
971
935
|
static void generate_dollar(struct generator * g, struct node * p) {
|
|
972
936
|
write_comment(g, p);
|
|
973
937
|
|
|
938
|
+
int used = g->label_used;
|
|
939
|
+
int a0 = g->failure_label;
|
|
940
|
+
struct str * a1 = str_copy(g->failure_str);
|
|
941
|
+
int label = new_label(g);
|
|
942
|
+
g->failure_label = label;
|
|
943
|
+
g->label_used = 0;
|
|
944
|
+
str_clear(g->failure_str);
|
|
945
|
+
|
|
974
946
|
struct str * savevar = vars_newname(g);
|
|
975
947
|
g->B[0] = str_data(savevar);
|
|
976
|
-
g->V[0] = p->name;
|
|
977
|
-
|
|
978
|
-
{
|
|
979
|
-
struct str * saved_output = g->outbuf;
|
|
980
|
-
str_clear(g->failure_str);
|
|
981
|
-
g->outbuf = g->failure_str;
|
|
982
|
-
writef(g, "~V0 := FCurrent; "
|
|
983
|
-
"FCurrent := ~B0_Current; "
|
|
984
|
-
"FCursor := ~B0_Cursor; "
|
|
985
|
-
"FLimit := ~B0_Limit; "
|
|
986
|
-
"FBkLimit := ~B0_BkLimit; "
|
|
987
|
-
"FBra := ~B0_Bra; "
|
|
988
|
-
"FKet := ~B0_Ket;", p);
|
|
989
|
-
g->failure_str = g->outbuf;
|
|
990
|
-
g->outbuf = saved_output;
|
|
991
|
-
}
|
|
992
948
|
|
|
993
949
|
write_declare(g, "~B0_Current : AnsiString", p);
|
|
994
950
|
write_declare(g, "~B0_Cursor : Integer", p);
|
|
@@ -1003,27 +959,58 @@ static void generate_dollar(struct generator * g, struct node * p) {
|
|
|
1003
959
|
"~M~B0_BkLimit := FBkLimit;~N"
|
|
1004
960
|
"~M~B0_Bra := FBra;~N"
|
|
1005
961
|
"~M~B0_Ket := FKet;~N"
|
|
1006
|
-
"~MFCurrent := ~
|
|
962
|
+
"~MFCurrent := ~V;~N"
|
|
1007
963
|
"~MFCursor := 0;~N"
|
|
1008
964
|
"~MFLimit := Length(current);~N", p);
|
|
965
|
+
if (p->left->possible_signals == -1) {
|
|
966
|
+
/* Assume failure. */
|
|
967
|
+
write_declare(g, "~B0_F : Boolean", p);
|
|
968
|
+
w(g, "~M~B0_F := True;~N");
|
|
969
|
+
}
|
|
970
|
+
|
|
1009
971
|
generate(g, p->left);
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
972
|
+
|
|
973
|
+
if (!g->unreachable && p->left->possible_signals == -1) {
|
|
974
|
+
/* Mark success. */
|
|
975
|
+
g->B[0] = str_data(savevar);
|
|
976
|
+
w(g, "~M~B0_F := False;~N");
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
if (g->label_used)
|
|
980
|
+
wsetl(g, g->failure_label);
|
|
981
|
+
|
|
982
|
+
g->label_used = used;
|
|
983
|
+
g->failure_label = a0;
|
|
984
|
+
str_delete(g->failure_str);
|
|
985
|
+
g->failure_str = a1;
|
|
986
|
+
|
|
987
|
+
g->B[0] = str_data(savevar);
|
|
988
|
+
writef(g, "~M~V := FCurrent;~N"
|
|
989
|
+
"~MFCurrent := ~B0_Current;~N"
|
|
990
|
+
"~MFCursor := ~B0_Cursor;~N"
|
|
991
|
+
"~MFLimit := ~B0_Limit;~N"
|
|
992
|
+
"~MFBkLimit := ~B0_BkLimit;~N"
|
|
993
|
+
"~MFBra := ~B0_Bra;~N"
|
|
994
|
+
"~MFKet := ~B0_Ket;~N", p);
|
|
995
|
+
|
|
996
|
+
if (p->left->possible_signals == 0) {
|
|
997
|
+
// p->left always signals f.
|
|
998
|
+
w(g, "~M~f~N");
|
|
999
|
+
} else if (p->left->possible_signals == -1) {
|
|
1000
|
+
write_failure_if(g, "~B0_F", p);
|
|
1014
1001
|
}
|
|
1015
1002
|
w(g, "~}");
|
|
1003
|
+
|
|
1016
1004
|
str_delete(savevar);
|
|
1017
1005
|
}
|
|
1018
1006
|
|
|
1019
1007
|
static void generate_integer_assign(struct generator * g, struct node * p, const char * s) {
|
|
1020
1008
|
write_comment(g, p);
|
|
1021
|
-
g
|
|
1022
|
-
w(g, "~M~W0 := ");
|
|
1009
|
+
writef(g, "~M~W := ", p);
|
|
1023
1010
|
|
|
1024
1011
|
if (s != NULL) {
|
|
1025
1012
|
g->S[0] = s;
|
|
1026
|
-
|
|
1013
|
+
writef(g, "~W ~S0 ", p);
|
|
1027
1014
|
}
|
|
1028
1015
|
|
|
1029
1016
|
generate_AE(g, p->AE);
|
|
@@ -1033,7 +1020,7 @@ static void generate_integer_assign(struct generator * g, struct node * p, const
|
|
|
1033
1020
|
static void generate_integer_test(struct generator * g, struct node * p) {
|
|
1034
1021
|
write_comment(g, p);
|
|
1035
1022
|
int relop = p->type;
|
|
1036
|
-
int optimise_to_return = (g
|
|
1023
|
+
int optimise_to_return = tailcallable(g, p);
|
|
1037
1024
|
if (optimise_to_return) {
|
|
1038
1025
|
w(g, "~MResult := ");
|
|
1039
1026
|
p->right = NULL;
|
|
@@ -1057,30 +1044,29 @@ static void generate_integer_test(struct generator * g, struct node * p) {
|
|
|
1057
1044
|
}
|
|
1058
1045
|
|
|
1059
1046
|
static void generate_call(struct generator * g, struct node * p) {
|
|
1060
|
-
int signals =
|
|
1047
|
+
int signals = p->name->definition->possible_signals;
|
|
1061
1048
|
write_comment(g, p);
|
|
1062
|
-
g
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
}
|
|
1049
|
+
if (tailcallable(g, p)) {
|
|
1050
|
+
/* Tail call. */
|
|
1051
|
+
writef(g, "~MResult := ~V;~N", p);
|
|
1052
|
+
p->right = NULL;
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
if (just_return_on_fail(g) && signals == 0) {
|
|
1056
|
+
/* Always fails. */
|
|
1057
|
+
writef(g, "~MBegin; Result := ~V; Exit; End;~N", p);
|
|
1058
|
+
g->unreachable = true;
|
|
1059
|
+
return;
|
|
1074
1060
|
}
|
|
1075
1061
|
if (signals == 1) {
|
|
1076
1062
|
/* Always succeeds. */
|
|
1077
|
-
writef(g, "~M~
|
|
1063
|
+
writef(g, "~M~V;~N", p);
|
|
1078
1064
|
} else if (signals == 0) {
|
|
1079
1065
|
/* Always fails. */
|
|
1080
|
-
writef(g, "~M~
|
|
1066
|
+
writef(g, "~M~V;~N", p);
|
|
1081
1067
|
write_failure(g);
|
|
1082
1068
|
} else {
|
|
1083
|
-
write_failure_if(g, "Not ~
|
|
1069
|
+
write_failure_if(g, "Not ~V", p);
|
|
1084
1070
|
}
|
|
1085
1071
|
}
|
|
1086
1072
|
|
|
@@ -1090,42 +1076,50 @@ static void generate_grouping(struct generator * g, struct node * p, int complem
|
|
|
1090
1076
|
struct grouping * q = p->name->grouping;
|
|
1091
1077
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
|
1092
1078
|
g->S[1] = complement ? "Out" : "In";
|
|
1093
|
-
g->V[0] = p->name;
|
|
1094
1079
|
g->I[0] = q->smallest_ch;
|
|
1095
1080
|
g->I[1] = q->largest_ch;
|
|
1096
|
-
|
|
1081
|
+
if (tailcallable(g, p)) {
|
|
1082
|
+
writef(g, "~MResult := ~S1Grouping~S0(~V, ~I0, ~I1);~N", p);
|
|
1083
|
+
p->right = NULL;
|
|
1084
|
+
} else {
|
|
1085
|
+
write_failure_if(g, "Not (~S1Grouping~S0(~V, ~I0, ~I1))", p);
|
|
1086
|
+
}
|
|
1097
1087
|
}
|
|
1098
1088
|
|
|
1099
1089
|
static void generate_namedstring(struct generator * g, struct node * p) {
|
|
1100
1090
|
write_comment(g, p);
|
|
1101
1091
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
|
1102
|
-
g
|
|
1103
|
-
|
|
1092
|
+
if (tailcallable(g, p)) {
|
|
1093
|
+
writef(g, "~MResult := EqS~S0(~V);~N", p);
|
|
1094
|
+
p->right = NULL;
|
|
1095
|
+
} else {
|
|
1096
|
+
write_failure_if(g, "Not (EqS~S0(~V))", p);
|
|
1097
|
+
}
|
|
1104
1098
|
}
|
|
1105
1099
|
|
|
1106
1100
|
static void generate_literalstring(struct generator * g, struct node * p) {
|
|
1107
|
-
symbol * b = p->literalstring;
|
|
1108
1101
|
write_comment(g, p);
|
|
1109
1102
|
g->S[0] = p->mode == m_forward ? "" : "Bk";
|
|
1110
|
-
g
|
|
1111
|
-
|
|
1112
|
-
|
|
1103
|
+
if (tailcallable(g, p)) {
|
|
1104
|
+
writef(g, "~MResult := EqS~S0(~L);~N", p);
|
|
1105
|
+
p->right = NULL;
|
|
1106
|
+
} else {
|
|
1107
|
+
write_failure_if(g, "Not (EqS~S0(~L))", p);
|
|
1108
|
+
}
|
|
1113
1109
|
}
|
|
1114
1110
|
|
|
1115
1111
|
static void generate_define(struct generator * g, struct node * p) {
|
|
1116
1112
|
struct name * q = p->name;
|
|
1117
|
-
if (q->type == t_routine && !q->used) return;
|
|
1118
1113
|
|
|
1119
1114
|
write_newline(g);
|
|
1120
1115
|
write_comment(g, p);
|
|
1121
1116
|
|
|
1122
1117
|
/* Generate function header. */
|
|
1123
|
-
g
|
|
1124
|
-
w(g, "~MFunction T~n.~W0 : Boolean;~N");
|
|
1118
|
+
writef(g, "~MFunction T~n.~W : Boolean;~N", p);
|
|
1125
1119
|
|
|
1126
1120
|
/* Save output. */
|
|
1127
|
-
struct str *saved_output = g->outbuf;
|
|
1128
|
-
struct str *saved_declarations = g->declarations;
|
|
1121
|
+
struct str * saved_output = g->outbuf;
|
|
1122
|
+
struct str * saved_declarations = g->declarations;
|
|
1129
1123
|
g->outbuf = str_new();
|
|
1130
1124
|
g->declarations = str_new();
|
|
1131
1125
|
|
|
@@ -1138,24 +1132,49 @@ static void generate_define(struct generator * g, struct node * p) {
|
|
|
1138
1132
|
|
|
1139
1133
|
/* Generate function body. */
|
|
1140
1134
|
w(g, "~{");
|
|
1141
|
-
int signals = check_possible_signals_list(g, p->left, c_define, 0);
|
|
1142
1135
|
g->temporary_used = false;
|
|
1143
1136
|
generate(g, p->left);
|
|
1144
1137
|
if (p->left->right) {
|
|
1145
1138
|
assert(p->left->right->type == c_functionend);
|
|
1146
|
-
if (
|
|
1139
|
+
if (p->left->possible_signals) {
|
|
1147
1140
|
generate(g, p->left->right);
|
|
1148
1141
|
}
|
|
1149
1142
|
}
|
|
1150
1143
|
w(g, "~}");
|
|
1151
1144
|
|
|
1145
|
+
if (q->amongvar_needed) {
|
|
1146
|
+
str_append_string(g->declarations, " AmongVar : Integer;\n");
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1152
1149
|
if (g->temporary_used) {
|
|
1153
1150
|
str_append_string(g->declarations, " C : Integer;\n");
|
|
1154
1151
|
}
|
|
1155
1152
|
|
|
1156
|
-
|
|
1157
|
-
|
|
1153
|
+
/* Declare localised variables. */
|
|
1154
|
+
struct str * temp = g->outbuf;
|
|
1155
|
+
g->outbuf = g->declarations;
|
|
1156
|
+
for (struct name * name = g->analyser->names; name; name = name->next) {
|
|
1157
|
+
if (name->local_to == q) {
|
|
1158
|
+
switch (name->type) {
|
|
1159
|
+
case t_string:
|
|
1160
|
+
w(g, " ");
|
|
1161
|
+
write_varname(g, name);
|
|
1162
|
+
w(g, " : AnsiString;\n");
|
|
1163
|
+
break;
|
|
1164
|
+
case t_integer:
|
|
1165
|
+
w(g, " ");
|
|
1166
|
+
write_varname(g, name);
|
|
1167
|
+
w(g, " : Integer;\n");
|
|
1168
|
+
break;
|
|
1169
|
+
case t_boolean:
|
|
1170
|
+
w(g, " ");
|
|
1171
|
+
write_varname(g, name);
|
|
1172
|
+
w(g, " : Boolean;\n");
|
|
1173
|
+
break;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1158
1176
|
}
|
|
1177
|
+
g->outbuf = temp;
|
|
1159
1178
|
|
|
1160
1179
|
if (str_len(g->declarations) > 0) {
|
|
1161
1180
|
str_append_string(saved_output, "Var\n");
|
|
@@ -1201,6 +1220,9 @@ static void generate_substring(struct generator * g, struct node * p) {
|
|
|
1201
1220
|
}
|
|
1202
1221
|
} else if (x->always_matches) {
|
|
1203
1222
|
writef(g, "~MFindAmong~S0(a_~I0, ~I1);~N", p);
|
|
1223
|
+
} else if (x->command_count == 0 && tailcallable(g, p)) {
|
|
1224
|
+
writef(g, "~MResult := FindAmong~S0(a_~I0, ~I1) <> 0;~N", p);
|
|
1225
|
+
x->node->right = NULL;
|
|
1204
1226
|
} else {
|
|
1205
1227
|
write_failure_if(g, "FindAmong~S0(a_~I0, ~I1) = 0", p);
|
|
1206
1228
|
}
|
|
@@ -1231,10 +1253,23 @@ static void generate_among(struct generator * g, struct node * p) {
|
|
|
1231
1253
|
}
|
|
1232
1254
|
}
|
|
1233
1255
|
|
|
1234
|
-
static void generate_booltest(struct generator * g, struct node * p) {
|
|
1256
|
+
static void generate_booltest(struct generator * g, struct node * p, int inverted) {
|
|
1235
1257
|
write_comment(g, p);
|
|
1236
|
-
g
|
|
1237
|
-
|
|
1258
|
+
if (tailcallable(g, p)) {
|
|
1259
|
+
// Optimise at end of function.
|
|
1260
|
+
if (inverted) {
|
|
1261
|
+
writef(g, "~MResult := !~V;~N", p);
|
|
1262
|
+
} else {
|
|
1263
|
+
writef(g, "~MResult := ~V;~N", p);
|
|
1264
|
+
}
|
|
1265
|
+
p->right = NULL;
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
if (inverted) {
|
|
1269
|
+
write_failure_if(g, "~V", p);
|
|
1270
|
+
} else {
|
|
1271
|
+
write_failure_if(g, "Not (~V)", p);
|
|
1272
|
+
}
|
|
1238
1273
|
}
|
|
1239
1274
|
|
|
1240
1275
|
static void generate_false(struct generator * g, struct node * p) {
|
|
@@ -1279,25 +1314,21 @@ static void generate(struct generator * g, struct node * p) {
|
|
|
1279
1314
|
case c_repeat: generate_repeat(g, p); break;
|
|
1280
1315
|
case c_loop: generate_loop(g, p); break;
|
|
1281
1316
|
case c_atleast: generate_atleast(g, p); break;
|
|
1282
|
-
case c_setmark: generate_setmark(g, p); break;
|
|
1283
1317
|
case c_tomark: generate_tomark(g, p); break;
|
|
1284
|
-
case c_atmark: generate_atmark(g, p); break;
|
|
1285
1318
|
case c_hop: generate_hop(g, p); break;
|
|
1286
|
-
case c_delete: generate_delete(g, p); break;
|
|
1287
1319
|
case c_next: generate_next(g, p); break;
|
|
1288
1320
|
case c_tolimit: generate_tolimit(g, p); break;
|
|
1289
|
-
case c_atlimit: generate_atlimit(g, p); break;
|
|
1290
1321
|
case c_leftslice: generate_leftslice(g, p); break;
|
|
1291
1322
|
case c_rightslice: generate_rightslice(g, p); break;
|
|
1292
1323
|
case c_assignto: generate_assignto(g, p); break;
|
|
1293
1324
|
case c_sliceto: generate_sliceto(g, p); break;
|
|
1294
|
-
case
|
|
1325
|
+
case c_stringassign: generate_stringassign(g, p); break;
|
|
1295
1326
|
case c_insert:
|
|
1296
1327
|
case c_attach: generate_insert(g, p, p->type); break;
|
|
1297
1328
|
case c_slicefrom: generate_slicefrom(g, p); break;
|
|
1298
1329
|
case c_setlimit: generate_setlimit(g, p); break;
|
|
1299
1330
|
case c_dollar: generate_dollar(g, p); break;
|
|
1300
|
-
case
|
|
1331
|
+
case c_assign: generate_integer_assign(g, p, NULL); break;
|
|
1301
1332
|
case c_plusassign: generate_integer_assign(g, p, "+"); break;
|
|
1302
1333
|
case c_minusassign: generate_integer_assign(g, p, "-"); break;
|
|
1303
1334
|
case c_multiplyassign:generate_integer_assign(g, p, "*"); break;
|
|
@@ -1317,7 +1348,8 @@ static void generate(struct generator * g, struct node * p) {
|
|
|
1317
1348
|
case c_literalstring: generate_literalstring(g, p); break;
|
|
1318
1349
|
case c_among: generate_among(g, p); break;
|
|
1319
1350
|
case c_substring: generate_substring(g, p); break;
|
|
1320
|
-
case c_booltest: generate_booltest(g, p); break;
|
|
1351
|
+
case c_booltest: generate_booltest(g, p, false); break;
|
|
1352
|
+
case c_not_booltest: generate_booltest(g, p, true); break;
|
|
1321
1353
|
case c_false: generate_false(g, p); break;
|
|
1322
1354
|
case c_true: break;
|
|
1323
1355
|
case c_debug: generate_debug(g, p); break;
|
|
@@ -1333,7 +1365,7 @@ static void generate(struct generator * g, struct node * p) {
|
|
|
1333
1365
|
|
|
1334
1366
|
/* Class declaration generation. */
|
|
1335
1367
|
static void generate_unit_start(struct generator * g) {
|
|
1336
|
-
write_start_comment(g, "
|
|
1368
|
+
write_start_comment(g, "// ", NULL);
|
|
1337
1369
|
w(g, "Unit ~n;~N~N{$HINTS OFF}~N~NInterface~N~NUses " BASE_UNIT ";~N");
|
|
1338
1370
|
}
|
|
1339
1371
|
|
|
@@ -1350,10 +1382,13 @@ static void generate_class_end(struct generator * g) {
|
|
|
1350
1382
|
}
|
|
1351
1383
|
|
|
1352
1384
|
static void generate_method_decl(struct generator * g, struct name * q) {
|
|
1353
|
-
g
|
|
1354
|
-
|
|
1385
|
+
w(g, "~MFunction ");
|
|
1386
|
+
write_varname(g, q);
|
|
1387
|
+
w(g, " : Boolean;");
|
|
1355
1388
|
if (q->type == t_external) {
|
|
1356
|
-
|
|
1389
|
+
if (SIZE(q->s) == 4 && memcmp(q->s, "stem", 4) == 0) {
|
|
1390
|
+
w(g, " Override;");
|
|
1391
|
+
}
|
|
1357
1392
|
}
|
|
1358
1393
|
w(g, "~N");
|
|
1359
1394
|
}
|
|
@@ -1369,7 +1404,7 @@ static void generate_method_decls(struct generator * g) {
|
|
|
1369
1404
|
}
|
|
1370
1405
|
w(g, "~-");
|
|
1371
1406
|
|
|
1372
|
-
|
|
1407
|
+
bool first = true;
|
|
1373
1408
|
for (struct name * q = g->analyser->names; q; q = q->next) {
|
|
1374
1409
|
if (q->type == t_routine) {
|
|
1375
1410
|
if (first) {
|
|
@@ -1383,9 +1418,9 @@ static void generate_method_decls(struct generator * g) {
|
|
|
1383
1418
|
}
|
|
1384
1419
|
|
|
1385
1420
|
static void generate_member_decls(struct generator * g) {
|
|
1386
|
-
|
|
1421
|
+
bool first = true;
|
|
1387
1422
|
for (struct name * q = g->analyser->names; q; q = q->next) {
|
|
1388
|
-
|
|
1423
|
+
if (q->local_to) continue;
|
|
1389
1424
|
switch (q->type) {
|
|
1390
1425
|
case t_string:
|
|
1391
1426
|
case t_integer:
|
|
@@ -1396,13 +1431,19 @@ static void generate_member_decls(struct generator * g) {
|
|
|
1396
1431
|
}
|
|
1397
1432
|
switch (q->type) {
|
|
1398
1433
|
case t_string:
|
|
1399
|
-
|
|
1434
|
+
write_margin(g);
|
|
1435
|
+
write_varname(g, q);
|
|
1436
|
+
w(g, " : AnsiString;~N");
|
|
1400
1437
|
break;
|
|
1401
1438
|
case t_integer:
|
|
1402
|
-
|
|
1439
|
+
write_margin(g);
|
|
1440
|
+
write_varname(g, q);
|
|
1441
|
+
w(g, " : Integer;~N");
|
|
1403
1442
|
break;
|
|
1404
1443
|
case t_boolean:
|
|
1405
|
-
|
|
1444
|
+
write_margin(g);
|
|
1445
|
+
write_varname(g, q);
|
|
1446
|
+
w(g, " : Boolean;~N");
|
|
1406
1447
|
break;
|
|
1407
1448
|
}
|
|
1408
1449
|
}
|
|
@@ -1439,8 +1480,9 @@ static void generate_among_table(struct generator * g, struct among * x) {
|
|
|
1439
1480
|
g->I[1] = i;
|
|
1440
1481
|
|
|
1441
1482
|
/* Write among's string. */
|
|
1442
|
-
g
|
|
1443
|
-
|
|
1483
|
+
w(g, "~Ma_~I0[~I1].Str := ");
|
|
1484
|
+
write_literal_string(g, v[i].b);
|
|
1485
|
+
w(g, ";~N");
|
|
1444
1486
|
|
|
1445
1487
|
/* Write among's index & result. */
|
|
1446
1488
|
g->I[2] = v[i].i;
|
|
@@ -1453,8 +1495,9 @@ static void generate_among_table(struct generator * g, struct among * x) {
|
|
|
1453
1495
|
if (v[i].function == NULL) {
|
|
1454
1496
|
w(g, "nil;~N~N");
|
|
1455
1497
|
} else {
|
|
1456
|
-
g
|
|
1457
|
-
|
|
1498
|
+
w(g, "Self.");
|
|
1499
|
+
write_varname(g, v[i].function);
|
|
1500
|
+
w(g, ";~N~N");
|
|
1458
1501
|
}
|
|
1459
1502
|
}
|
|
1460
1503
|
w(g, "~-");
|
|
@@ -1473,19 +1516,17 @@ static void generate_constructor(struct generator * g) {
|
|
|
1473
1516
|
}
|
|
1474
1517
|
|
|
1475
1518
|
static void generate_methods(struct generator * g) {
|
|
1476
|
-
struct node * p = g->analyser->program;
|
|
1477
|
-
while (p != NULL) {
|
|
1519
|
+
for (struct node * p = g->analyser->program; p; p = p->right) {
|
|
1478
1520
|
generate(g, p);
|
|
1479
1521
|
g->unreachable = false;
|
|
1480
|
-
p = p->right;
|
|
1481
1522
|
}
|
|
1482
1523
|
}
|
|
1483
1524
|
|
|
1484
|
-
static void set_bit(symbol * b, int i) { b[i
|
|
1525
|
+
static void set_bit(symbol * b, int i) { b[i >> 3] |= 1 << (i & 7); }
|
|
1485
1526
|
|
|
1486
1527
|
static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
|
1487
1528
|
int range = q->largest_ch - q->smallest_ch + 1;
|
|
1488
|
-
int size = (range + 7)/ 8; /* assume 8 bits per symbol */
|
|
1529
|
+
int size = (range + 7) / 8; /* assume 8 bits per symbol */
|
|
1489
1530
|
symbol * b = q->b;
|
|
1490
1531
|
symbol * map = create_b(size);
|
|
1491
1532
|
|
|
@@ -1493,9 +1534,10 @@ static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
|
|
1493
1534
|
|
|
1494
1535
|
for (int i = 0; i < SIZE(b); i++) set_bit(map, b[i] - q->smallest_ch);
|
|
1495
1536
|
|
|
1496
|
-
g->V[0] = q->name;
|
|
1497
1537
|
g->I[0] = size - 1;
|
|
1498
|
-
w(g, "~N~MConst~+~N~M
|
|
1538
|
+
w(g, "~N~MConst~+~N~M");
|
|
1539
|
+
write_varname(g, q->name);
|
|
1540
|
+
w(g, " : Array [0..~I0] Of Char = (~N~+");
|
|
1499
1541
|
for (int i = 0; i < size; i++) {
|
|
1500
1542
|
if (i != 0) w(g, ",~N");
|
|
1501
1543
|
g->I[0] = map[i];
|
|
@@ -1508,8 +1550,7 @@ static void generate_grouping_table(struct generator * g, struct grouping * q) {
|
|
|
1508
1550
|
|
|
1509
1551
|
static void generate_groupings(struct generator * g) {
|
|
1510
1552
|
for (struct grouping * q = g->analyser->groupings; q; q = q->next) {
|
|
1511
|
-
|
|
1512
|
-
generate_grouping_table(g, q);
|
|
1553
|
+
generate_grouping_table(g, q);
|
|
1513
1554
|
}
|
|
1514
1555
|
}
|
|
1515
1556
|
|