bit2 0.0.2 → 0.0.4
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.
- package/README.md +5 -0
- package/dist/src/common/Exp.d.ts +3 -3
- package/dist/src/core/AST.d.ts +1 -1
- package/dist/src/fuse/Update.d.ts +1 -1
- package/dist/src/lambda/AST.d.ts +2 -2
- package/dist/src/partial/AST.d.ts +5 -4
- package/dist/src/surface/AST.d.ts +4 -4
- package/package.json +8 -4
- package/dist/bit2.js +0 -1
- package/dist/src/bx/biEval.js +0 -59
- package/dist/src/bx/biEval.js.map +0 -1
- package/dist/src/common/Exp.js +0 -44
- package/dist/src/common/Exp.js.map +0 -1
- package/dist/src/common/PrettyPrint.js +0 -32
- package/dist/src/common/PrettyPrint.js.map +0 -1
- package/dist/src/common/Print.js +0 -73
- package/dist/src/common/Print.js.map +0 -1
- package/dist/src/core/AST.js +0 -47
- package/dist/src/core/AST.js.map +0 -1
- package/dist/src/core/PrettyPrint.js +0 -64
- package/dist/src/core/PrettyPrint.js.map +0 -1
- package/dist/src/core/Print.js +0 -77
- package/dist/src/core/Print.js.map +0 -1
- package/dist/src/fuse/Fuse.js +0 -1436
- package/dist/src/fuse/Fuse.js.map +0 -1
- package/dist/src/fuse/Print.js +0 -22
- package/dist/src/fuse/Print.js.map +0 -1
- package/dist/src/fuse/Update.js +0 -3
- package/dist/src/fuse/Update.js.map +0 -1
- package/dist/src/lambda/AST.js +0 -3
- package/dist/src/lambda/AST.js.map +0 -1
- package/dist/src/lambda/Evaluation.js +0 -98
- package/dist/src/lambda/Evaluation.js.map +0 -1
- package/dist/src/lambda/Print.js +0 -31
- package/dist/src/lambda/Print.js.map +0 -1
- package/dist/src/lambdalize/lambdalize.js +0 -94
- package/dist/src/lambdalize/lambdalize.js.map +0 -1
- package/dist/src/lambdalize/unLambdalize.js +0 -59
- package/dist/src/lambdalize/unLambdalize.js.map +0 -1
- package/dist/src/partial/AST.js +0 -3
- package/dist/src/partial/AST.js.map +0 -1
- package/dist/src/partial/Print.js +0 -93
- package/dist/src/partial/Print.js.map +0 -1
- package/dist/src/partialEval/peval.js +0 -322
- package/dist/src/partialEval/peval.js.map +0 -1
- package/dist/src/partialEval/unpeval.js +0 -360
- package/dist/src/partialEval/unpeval.js.map +0 -1
- package/dist/src/surface/AST.js +0 -3
- package/dist/src/surface/AST.js.map +0 -1
- package/dist/src/surface/Parser.js +0 -314
- package/dist/src/surface/Parser.js.map +0 -1
- package/dist/src/translate/Translate.js +0 -91
- package/dist/src/translate/Translate.js.map +0 -1
- package/dist/src/utils/Utils.js +0 -7
- package/dist/src/utils/Utils.js.map +0 -1
- package/dist/test/bx/biEval.test.d.ts +0 -1
- package/dist/test/bx/biEval.test.js +0 -41
- package/dist/test/bx/biEval.test.js.map +0 -1
- package/dist/test/bx/test.d.ts +0 -1
- package/dist/test/bx/test.js +0 -29
- package/dist/test/bx/test.js.map +0 -1
- package/dist/test/core/0.simple.test.d.ts +0 -4
- package/dist/test/core/0.simple.test.js +0 -68
- package/dist/test/core/0.simple.test.js.map +0 -1
- package/dist/test/core/1.core.test.d.ts +0 -2
- package/dist/test/core/1.core.test.js +0 -30
- package/dist/test/core/1.core.test.js.map +0 -1
- package/dist/test/core/core.test.d.ts +0 -1
- package/dist/test/core/core.test.js +0 -28
- package/dist/test/core/core.test.js.map +0 -1
- package/dist/test/fuse/branchnop.test.d.ts +0 -1
- package/dist/test/fuse/branchnop.test.js +0 -47
- package/dist/test/fuse/branchnop.test.js.map +0 -1
- package/dist/test/fuse/bulk.test.d.ts +0 -1
- package/dist/test/fuse/bulk.test.js +0 -111
- package/dist/test/fuse/bulk.test.js.map +0 -1
- package/dist/test/fuse/const.test.d.ts +0 -1
- package/dist/test/fuse/const.test.js +0 -118
- package/dist/test/fuse/const.test.js.map +0 -1
- package/dist/test/fuse/exp.test.d.ts +0 -1
- package/dist/test/fuse/exp.test.js +0 -225
- package/dist/test/fuse/exp.test.js.map +0 -1
- package/dist/test/fuse/lambda.test.d.ts +0 -1
- package/dist/test/fuse/lambda.test.js +0 -139
- package/dist/test/fuse/lambda.test.js.map +0 -1
- package/dist/test/fuse/loop.test.d.ts +0 -1
- package/dist/test/fuse/loop.test.js +0 -39
- package/dist/test/fuse/loop.test.js.map +0 -1
- package/dist/test/fuse/seq.test.d.ts +0 -1
- package/dist/test/fuse/seq.test.js +0 -64
- package/dist/test/fuse/seq.test.js.map +0 -1
- package/dist/test/fuse/space.test.d.ts +0 -1
- package/dist/test/fuse/space.test.js +0 -136
- package/dist/test/fuse/space.test.js.map +0 -1
- package/dist/test/lambda/evaluation.test.d.ts +0 -1
- package/dist/test/lambda/evaluation.test.js +0 -24
- package/dist/test/lambda/evaluation.test.js.map +0 -1
- package/dist/test/lambda/lambda.test.d.ts +0 -1
- package/dist/test/lambda/lambda.test.js +0 -45
- package/dist/test/lambda/lambda.test.js.map +0 -1
- package/dist/test/lambdalize/lambdalize.test.d.ts +0 -1
- package/dist/test/lambdalize/lambdalize.test.js +0 -23
- package/dist/test/lambdalize/lambdalize.test.js.map +0 -1
- package/dist/test/lambdalize/unLambdalize.test.d.ts +0 -1
- package/dist/test/lambdalize/unLambdalize.test.js +0 -35
- package/dist/test/lambdalize/unLambdalize.test.js.map +0 -1
- package/dist/test/partial/partial.test.d.ts +0 -1
- package/dist/test/partial/partial.test.js +0 -35
- package/dist/test/partial/partial.test.js.map +0 -1
- package/dist/test/partialEval/peval.test.d.ts +0 -1
- package/dist/test/partialEval/peval.test.js +0 -29
- package/dist/test/partialEval/peval.test.js.map +0 -1
- package/dist/test/partialEval/unPeval.test.d.ts +0 -1
- package/dist/test/partialEval/unPeval.test.js +0 -40
- package/dist/test/partialEval/unPeval.test.js.map +0 -1
- package/dist/test/surface/AST.test.d.ts +0 -1
- package/dist/test/surface/AST.test.js +0 -41
- package/dist/test/surface/AST.test.js.map +0 -1
- package/dist/test/translate/translate.test.d.ts +0 -1
- package/dist/test/translate/translate.test.js +0 -45
- package/dist/test/translate/translate.test.js.map +0 -1
package/dist/src/fuse/Fuse.js
DELETED
@@ -1,1436 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
3
|
-
var t = {};
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
5
|
-
t[p] = s[p];
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
9
|
-
t[p[i]] = s[p[i]];
|
10
|
-
}
|
11
|
-
return t;
|
12
|
-
};
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
14
|
-
const Utils_1 = require("../utils/Utils");
|
15
|
-
const Exp_1 = require("../common/Exp");
|
16
|
-
const peval_1 = require("../partialEval/peval");
|
17
|
-
const Print_1 = require("../partial/Print");
|
18
|
-
const Evaluation_1 = require("../lambda/Evaluation");
|
19
|
-
// Apply update to a TermNode and return the updated TermNode and remaining operation
|
20
|
-
function fuse(env, operation, term) {
|
21
|
-
// Check if the term is a ConstNode
|
22
|
-
if ((term.type === "const" ||
|
23
|
-
term.type === "sep" ||
|
24
|
-
term.type === "loopfront" ||
|
25
|
-
term.type === "looprear") &&
|
26
|
-
typeof term.value === "string") {
|
27
|
-
// add a new arr to env
|
28
|
-
if (term.type === "loopfront") {
|
29
|
-
let exp = term.lst;
|
30
|
-
if (exp.name) {
|
31
|
-
// Ensure exp is a Variable and has a name property
|
32
|
-
let expName = exp.name;
|
33
|
-
env[expName + "_new"] = [[], []]; // Set env[expName_new] to [[], []]
|
34
|
-
}
|
35
|
-
else {
|
36
|
-
throw new Error("exp is not a Variable with a name property in loopfront");
|
37
|
-
}
|
38
|
-
}
|
39
|
-
else if (term.type === "looprear") {
|
40
|
-
let exp = term.lst;
|
41
|
-
if (exp.name) {
|
42
|
-
let expName = exp.name;
|
43
|
-
env[expName] = env[expName + "_new"]; // assign back
|
44
|
-
}
|
45
|
-
else {
|
46
|
-
throw new Error("exp is not a Variable with a name property in loopfront");
|
47
|
-
}
|
48
|
-
}
|
49
|
-
const s_c = term.value;
|
50
|
-
switch (operation.type) {
|
51
|
-
case "insert":
|
52
|
-
const { str, position } = operation;
|
53
|
-
if (s_c.length === 0) {
|
54
|
-
return [
|
55
|
-
{ newEnv: env, newTermNode: term, remainingOperation: operation },
|
56
|
-
{
|
57
|
-
newEnv: env,
|
58
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: str }),
|
59
|
-
remainingOperation: { type: "id" },
|
60
|
-
},
|
61
|
-
];
|
62
|
-
}
|
63
|
-
else if (position === 0) {
|
64
|
-
// 两种更新策略
|
65
|
-
return [
|
66
|
-
{
|
67
|
-
newEnv: Object.assign({}, env),
|
68
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: str + s_c }),
|
69
|
-
remainingOperation: { type: "id" },
|
70
|
-
},
|
71
|
-
{
|
72
|
-
newEnv: Object.assign({}, env),
|
73
|
-
newTermNode: {
|
74
|
-
type: "seq",
|
75
|
-
nodes: [{ type: "const", value: str }, term],
|
76
|
-
},
|
77
|
-
remainingOperation: { type: "id" },
|
78
|
-
},
|
79
|
-
];
|
80
|
-
}
|
81
|
-
else if (position < s_c.length) {
|
82
|
-
const newStr = s_c.slice(0, position) + str + s_c.slice(position);
|
83
|
-
return [
|
84
|
-
{
|
85
|
-
newEnv: env,
|
86
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: newStr }),
|
87
|
-
remainingOperation: { type: "id" },
|
88
|
-
},
|
89
|
-
];
|
90
|
-
}
|
91
|
-
else if (position === s_c.length) {
|
92
|
-
// 两种策略
|
93
|
-
return [
|
94
|
-
{
|
95
|
-
newEnv: Object.assign({}, env),
|
96
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: s_c + str }),
|
97
|
-
remainingOperation: { type: "id" },
|
98
|
-
},
|
99
|
-
{
|
100
|
-
newEnv: Object.assign({}, env),
|
101
|
-
newTermNode: term,
|
102
|
-
remainingOperation: {
|
103
|
-
type: "insert",
|
104
|
-
str,
|
105
|
-
position: position - s_c.length,
|
106
|
-
},
|
107
|
-
},
|
108
|
-
];
|
109
|
-
}
|
110
|
-
else {
|
111
|
-
const newPos = position - s_c.length;
|
112
|
-
return [
|
113
|
-
{
|
114
|
-
newEnv: env,
|
115
|
-
newTermNode: term,
|
116
|
-
remainingOperation: { type: "insert", str, position: newPos },
|
117
|
-
},
|
118
|
-
];
|
119
|
-
}
|
120
|
-
case "delete":
|
121
|
-
const { str: delStr, position: delPos } = operation;
|
122
|
-
if (delPos === 0) {
|
123
|
-
if (s_c.startsWith(delStr) && delStr.length <= s_c.length) {
|
124
|
-
// 如果delStr===s_c,那么 newStr=""; 还有一个策略,即bot
|
125
|
-
const newStr = s_c.slice(delStr.length);
|
126
|
-
let result = [
|
127
|
-
{
|
128
|
-
newEnv: env,
|
129
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: newStr }),
|
130
|
-
remainingOperation: { type: "id" },
|
131
|
-
},
|
132
|
-
];
|
133
|
-
if (delStr.length === s_c.length) {
|
134
|
-
result.push({
|
135
|
-
newEnv: Object.assign({}, env),
|
136
|
-
//@ts-ignore
|
137
|
-
newTermNode: { type: "bot" },
|
138
|
-
remainingOperation: { type: "id" },
|
139
|
-
});
|
140
|
-
}
|
141
|
-
//@ts-ignore
|
142
|
-
return result;
|
143
|
-
}
|
144
|
-
else if (delStr.startsWith(s_c) && delStr.length > s_c.length) {
|
145
|
-
const remainingStr = delStr.slice(s_c.length);
|
146
|
-
return [
|
147
|
-
{
|
148
|
-
newEnv: env,
|
149
|
-
newTermNode: { type: "bot" },
|
150
|
-
remainingOperation: {
|
151
|
-
type: "delete",
|
152
|
-
str: remainingStr,
|
153
|
-
position: 0,
|
154
|
-
},
|
155
|
-
},
|
156
|
-
{
|
157
|
-
newEnv: Object.assign({}, env),
|
158
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: "" }),
|
159
|
-
remainingOperation: {
|
160
|
-
type: "delete",
|
161
|
-
str: remainingStr,
|
162
|
-
position: 0,
|
163
|
-
},
|
164
|
-
},
|
165
|
-
];
|
166
|
-
}
|
167
|
-
}
|
168
|
-
else if (delPos < s_c.length &&
|
169
|
-
delPos + delStr.length <= s_c.length) {
|
170
|
-
const newStr = s_c.slice(0, delPos) + s_c.slice(delPos + delStr.length);
|
171
|
-
return [
|
172
|
-
{
|
173
|
-
newEnv: env,
|
174
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: newStr }),
|
175
|
-
remainingOperation: { type: "id" },
|
176
|
-
},
|
177
|
-
];
|
178
|
-
}
|
179
|
-
else if (delPos < s_c.length && delPos + delStr.length > s_c.length) {
|
180
|
-
const remainingS_c = s_c.substring(0, delPos); // 保留s_c删除位置之前的部分
|
181
|
-
const remainingDelStr = delStr.substring(s_c.length - delPos); // 剩余需要删除的字符串
|
182
|
-
return [
|
183
|
-
{
|
184
|
-
newEnv: env,
|
185
|
-
newTermNode: { type: "const", value: remainingS_c },
|
186
|
-
remainingOperation: {
|
187
|
-
type: "delete",
|
188
|
-
str: remainingDelStr,
|
189
|
-
position: 0,
|
190
|
-
},
|
191
|
-
},
|
192
|
-
];
|
193
|
-
}
|
194
|
-
else {
|
195
|
-
const newPos = delPos - s_c.length;
|
196
|
-
return [
|
197
|
-
{
|
198
|
-
newEnv: env,
|
199
|
-
newTermNode: term,
|
200
|
-
remainingOperation: {
|
201
|
-
type: "delete",
|
202
|
-
str: delStr,
|
203
|
-
position: newPos,
|
204
|
-
},
|
205
|
-
},
|
206
|
-
];
|
207
|
-
}
|
208
|
-
case "replace":
|
209
|
-
const { str1, str2, position: repPos, } = operation;
|
210
|
-
if (repPos === 0) {
|
211
|
-
if (s_c.startsWith(str1) && str1.length <= s_c.length) {
|
212
|
-
const newStr = str2 + s_c.slice(str1.length);
|
213
|
-
return [
|
214
|
-
{
|
215
|
-
newEnv: env,
|
216
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: newStr }),
|
217
|
-
remainingOperation: { type: "id" },
|
218
|
-
},
|
219
|
-
];
|
220
|
-
}
|
221
|
-
else if (str1.startsWith(s_c) && str1.length > s_c.length) {
|
222
|
-
const remainingS_c = str2.slice(0, s_c.length);
|
223
|
-
const remainingStr1 = str1.slice(s_c.length);
|
224
|
-
const remainingStr2 = str2.slice(s_c.length);
|
225
|
-
return [
|
226
|
-
{
|
227
|
-
newEnv: env,
|
228
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: remainingS_c }),
|
229
|
-
remainingOperation: {
|
230
|
-
type: "replace",
|
231
|
-
str1: remainingStr1,
|
232
|
-
str2: remainingStr2,
|
233
|
-
position: 0,
|
234
|
-
},
|
235
|
-
},
|
236
|
-
];
|
237
|
-
}
|
238
|
-
}
|
239
|
-
else if (repPos < s_c.length && repPos + str1.length <= s_c.length) {
|
240
|
-
const newStr = s_c.slice(0, repPos) + str2 + s_c.slice(repPos + str1.length);
|
241
|
-
return [
|
242
|
-
{
|
243
|
-
newEnv: env,
|
244
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: newStr }),
|
245
|
-
remainingOperation: { type: "id" },
|
246
|
-
},
|
247
|
-
];
|
248
|
-
}
|
249
|
-
else if (repPos < s_c.length && repPos + str1.length > s_c.length) {
|
250
|
-
const part1 = s_c.substring(0, repPos); // 替换位置之前的部分
|
251
|
-
const overlapPart = s_c.substring(repPos); // 与替换的 str1 重叠的部分
|
252
|
-
const overlapStr2 = str2.substring(0, overlapPart.length);
|
253
|
-
const remainingStr1 = str1.substring(overlapPart.length); // 剩余需要替换的 str1 部分
|
254
|
-
const remainingStr2 = str2.substring(overlapPart.length); // 剩余替换的 str2 部分
|
255
|
-
const newOperation = {
|
256
|
-
type: "replace",
|
257
|
-
str1: remainingStr1,
|
258
|
-
str2: remainingStr2,
|
259
|
-
position: 0,
|
260
|
-
};
|
261
|
-
const newExpression = {
|
262
|
-
type: "const",
|
263
|
-
value: part1 + overlapStr2,
|
264
|
-
};
|
265
|
-
return [
|
266
|
-
{
|
267
|
-
newEnv: env,
|
268
|
-
newTermNode: newExpression,
|
269
|
-
remainingOperation: newOperation,
|
270
|
-
},
|
271
|
-
];
|
272
|
-
}
|
273
|
-
else {
|
274
|
-
const newPos = repPos - s_c.length;
|
275
|
-
return [
|
276
|
-
{
|
277
|
-
newEnv: env,
|
278
|
-
newTermNode: Object.assign(Object.assign({}, term), { value: s_c }),
|
279
|
-
remainingOperation: {
|
280
|
-
type: "replace",
|
281
|
-
str1,
|
282
|
-
str2,
|
283
|
-
position: newPos,
|
284
|
-
},
|
285
|
-
},
|
286
|
-
];
|
287
|
-
}
|
288
|
-
case "bulk":
|
289
|
-
return fuseBulk(env, operation, term);
|
290
|
-
case "id":
|
291
|
-
return [
|
292
|
-
{
|
293
|
-
newEnv: env,
|
294
|
-
newTermNode: term,
|
295
|
-
remainingOperation: { type: "id" },
|
296
|
-
},
|
297
|
-
];
|
298
|
-
default:
|
299
|
-
const exhaustiveCheck = operation;
|
300
|
-
throw new Error(`Unhandled operation type: ${exhaustiveCheck}`);
|
301
|
-
}
|
302
|
-
}
|
303
|
-
else if (term.type === "space") {
|
304
|
-
switch (operation.type) {
|
305
|
-
case "insert":
|
306
|
-
const { str, position } = operation;
|
307
|
-
// zero-width space
|
308
|
-
if (term.width == 0) {
|
309
|
-
return [
|
310
|
-
{ newEnv: env, newTermNode: term, remainingOperation: operation },
|
311
|
-
{
|
312
|
-
newEnv: Object.assign({}, env),
|
313
|
-
newTermNode: {
|
314
|
-
type: "seq",
|
315
|
-
nodes: [{ type: "const", value: str }, term],
|
316
|
-
},
|
317
|
-
remainingOperation: { type: "id" },
|
318
|
-
},
|
319
|
-
];
|
320
|
-
}
|
321
|
-
else if (position == 0) {
|
322
|
-
// non-zero space
|
323
|
-
let resultList = [
|
324
|
-
{
|
325
|
-
newEnv: env,
|
326
|
-
newTermNode: {
|
327
|
-
type: "seq",
|
328
|
-
nodes: [{ type: "const", value: str }, term],
|
329
|
-
},
|
330
|
-
remainingOperation: { type: "id" },
|
331
|
-
},
|
332
|
-
];
|
333
|
-
if (Utils_1.isWhitespace(str)) {
|
334
|
-
resultList.push({
|
335
|
-
newEnv: Object.assign({}, env),
|
336
|
-
newTermNode: {
|
337
|
-
type: "space",
|
338
|
-
width: term.width + str.length,
|
339
|
-
},
|
340
|
-
remainingOperation: { type: "id" },
|
341
|
-
});
|
342
|
-
}
|
343
|
-
return resultList;
|
344
|
-
}
|
345
|
-
else if (position < term.width) {
|
346
|
-
if (Utils_1.isWhitespace(str)) {
|
347
|
-
return [
|
348
|
-
{
|
349
|
-
newEnv: env,
|
350
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: str.length + term.width }),
|
351
|
-
remainingOperation: { type: "id" },
|
352
|
-
},
|
353
|
-
];
|
354
|
-
}
|
355
|
-
else {
|
356
|
-
throw new Error(`Cannot insert non-space between space term: ${operation}`);
|
357
|
-
}
|
358
|
-
}
|
359
|
-
else if (position === term.width) {
|
360
|
-
// 两种策略
|
361
|
-
let resultList = [
|
362
|
-
{ newEnv: env, newTermNode: term, remainingOperation: operation },
|
363
|
-
];
|
364
|
-
if (Utils_1.isWhitespace(str)) {
|
365
|
-
resultList.push({
|
366
|
-
newEnv: Object.assign({}, env),
|
367
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: term.width + str.length }),
|
368
|
-
remainingOperation: { type: "id" },
|
369
|
-
});
|
370
|
-
}
|
371
|
-
return resultList;
|
372
|
-
}
|
373
|
-
else {
|
374
|
-
const newPos = position - term.width;
|
375
|
-
return [
|
376
|
-
{
|
377
|
-
newEnv: env,
|
378
|
-
newTermNode: term,
|
379
|
-
remainingOperation: { type: "insert", str, position: newPos },
|
380
|
-
},
|
381
|
-
];
|
382
|
-
}
|
383
|
-
case "delete":
|
384
|
-
const { str: delStr, position: delPos } = operation;
|
385
|
-
if (delPos === 0) {
|
386
|
-
if (Utils_1.isWhitespace(delStr) && delStr.length <= term.width) {
|
387
|
-
// 如果delStr===s_c,还有一个策略, 即bot
|
388
|
-
const newWidth = term.width - delStr.length;
|
389
|
-
let result = [
|
390
|
-
{
|
391
|
-
newEnv: env,
|
392
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: newWidth }),
|
393
|
-
remainingOperation: { type: "id" },
|
394
|
-
},
|
395
|
-
];
|
396
|
-
// if (delStr.length === term.width) {
|
397
|
-
// result.push({
|
398
|
-
// newEnv: {...env},
|
399
|
-
// //@ts-ignore
|
400
|
-
// newTermNode: { type: "bot" },
|
401
|
-
// remainingOperation: { type: "id" },
|
402
|
-
// });
|
403
|
-
// }
|
404
|
-
//@ts-ignore
|
405
|
-
return result;
|
406
|
-
}
|
407
|
-
else if (delStr.length > term.width) {
|
408
|
-
const remainingStr = delStr.slice(term.width);
|
409
|
-
return [
|
410
|
-
{
|
411
|
-
newEnv: env,
|
412
|
-
newTermNode: { type: "bot" },
|
413
|
-
remainingOperation: {
|
414
|
-
type: "delete",
|
415
|
-
str: remainingStr,
|
416
|
-
position: 0,
|
417
|
-
},
|
418
|
-
},
|
419
|
-
{
|
420
|
-
newEnv: Object.assign({}, env),
|
421
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: 0 }),
|
422
|
-
remainingOperation: {
|
423
|
-
type: "delete",
|
424
|
-
str: remainingStr,
|
425
|
-
position: 0,
|
426
|
-
},
|
427
|
-
},
|
428
|
-
];
|
429
|
-
}
|
430
|
-
}
|
431
|
-
else if (delPos < term.width &&
|
432
|
-
delPos + delStr.length <= term.width) {
|
433
|
-
const newWidth = term.width - delStr.length;
|
434
|
-
return [
|
435
|
-
{
|
436
|
-
newEnv: env,
|
437
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: newWidth }),
|
438
|
-
remainingOperation: { type: "id" },
|
439
|
-
},
|
440
|
-
];
|
441
|
-
}
|
442
|
-
else if (delPos < term.width && delPos + delStr.length > term.width) {
|
443
|
-
const remainingWidth = delPos;
|
444
|
-
const remainingDelStr = delStr.substring(term.width - delPos); // 剩余需要删除的字符串
|
445
|
-
return [
|
446
|
-
{
|
447
|
-
newEnv: env,
|
448
|
-
newTermNode: { type: "space", width: remainingWidth },
|
449
|
-
remainingOperation: {
|
450
|
-
type: "delete",
|
451
|
-
str: remainingDelStr,
|
452
|
-
position: 0,
|
453
|
-
},
|
454
|
-
},
|
455
|
-
];
|
456
|
-
}
|
457
|
-
else {
|
458
|
-
const newPos = delPos - term.width;
|
459
|
-
return [
|
460
|
-
{
|
461
|
-
newEnv: env,
|
462
|
-
newTermNode: term,
|
463
|
-
remainingOperation: {
|
464
|
-
type: "delete",
|
465
|
-
str: delStr,
|
466
|
-
position: newPos,
|
467
|
-
},
|
468
|
-
},
|
469
|
-
];
|
470
|
-
}
|
471
|
-
case "replace":
|
472
|
-
const { str1, str2, position: repPos, } = operation;
|
473
|
-
if (repPos === 0) {
|
474
|
-
if (str1.length <= term.width) {
|
475
|
-
if (Utils_1.isWhitespace(str2)) {
|
476
|
-
const newWidth = term.width - str1.length + str2.length;
|
477
|
-
return [
|
478
|
-
{
|
479
|
-
newEnv: env,
|
480
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: newWidth }),
|
481
|
-
remainingOperation: { type: "id" },
|
482
|
-
},
|
483
|
-
];
|
484
|
-
}
|
485
|
-
else {
|
486
|
-
return [
|
487
|
-
{
|
488
|
-
newEnv: env,
|
489
|
-
newTermNode: {
|
490
|
-
type: "seq",
|
491
|
-
nodes: [
|
492
|
-
{ type: "const", value: str2 },
|
493
|
-
Object.assign(Object.assign({}, term), { width: term.width - str1.length }),
|
494
|
-
],
|
495
|
-
},
|
496
|
-
remainingOperation: { type: "id" },
|
497
|
-
},
|
498
|
-
];
|
499
|
-
}
|
500
|
-
}
|
501
|
-
else if (str1.length > term.width) {
|
502
|
-
const remainingS_c = str2.slice(0, term.width);
|
503
|
-
const remainingStr1 = str1.slice(term.width);
|
504
|
-
const remainingStr2 = str2.slice(term.width);
|
505
|
-
return [
|
506
|
-
{
|
507
|
-
newEnv: env,
|
508
|
-
newTermNode: { type: "const", value: remainingS_c },
|
509
|
-
remainingOperation: {
|
510
|
-
type: "replace",
|
511
|
-
str1: remainingStr1,
|
512
|
-
str2: remainingStr2,
|
513
|
-
position: 0,
|
514
|
-
},
|
515
|
-
},
|
516
|
-
];
|
517
|
-
}
|
518
|
-
}
|
519
|
-
else if (repPos < term.width && repPos + str1.length <= term.width) {
|
520
|
-
if (Utils_1.isWhitespace(str2)) {
|
521
|
-
return [
|
522
|
-
{
|
523
|
-
newEnv: env,
|
524
|
-
newTermNode: Object.assign(Object.assign({}, term), { width: str2.length + term.width - str1.length }),
|
525
|
-
remainingOperation: { type: "id" },
|
526
|
-
},
|
527
|
-
];
|
528
|
-
}
|
529
|
-
else {
|
530
|
-
const newStr = " ".repeat(repPos) +
|
531
|
-
str2 +
|
532
|
-
" ".repeat(term.width - (repPos + str1.length));
|
533
|
-
return [
|
534
|
-
{
|
535
|
-
newEnv: env,
|
536
|
-
newTermNode: { type: "const", value: newStr },
|
537
|
-
remainingOperation: { type: "id" },
|
538
|
-
},
|
539
|
-
];
|
540
|
-
}
|
541
|
-
}
|
542
|
-
else if (repPos < term.width && repPos + str1.length > term.width) {
|
543
|
-
const part1 = " ".repeat(repPos); // 替换位置之前的部分
|
544
|
-
const overlapPartLength = term.width - repPos; // 与替换的 str1 重叠的部分
|
545
|
-
const overlapStr2 = str2.substring(0, overlapPartLength);
|
546
|
-
const remainingStr1 = str1.substring(overlapPartLength); // 剩余需要替换的 str1 部分
|
547
|
-
const remainingStr2 = str2.substring(overlapPartLength); // 剩余替换的 str2 部分
|
548
|
-
const newOperation = {
|
549
|
-
type: "replace",
|
550
|
-
str1: remainingStr1,
|
551
|
-
str2: remainingStr2,
|
552
|
-
position: 0,
|
553
|
-
};
|
554
|
-
const newExpression = {
|
555
|
-
type: "const",
|
556
|
-
value: part1 + overlapStr2,
|
557
|
-
};
|
558
|
-
return [
|
559
|
-
{
|
560
|
-
newEnv: env,
|
561
|
-
newTermNode: newExpression,
|
562
|
-
remainingOperation: newOperation,
|
563
|
-
},
|
564
|
-
];
|
565
|
-
}
|
566
|
-
else {
|
567
|
-
const newPos = repPos - term.width;
|
568
|
-
return [
|
569
|
-
{
|
570
|
-
newEnv: env,
|
571
|
-
newTermNode: term,
|
572
|
-
remainingOperation: {
|
573
|
-
type: "replace",
|
574
|
-
str1,
|
575
|
-
str2,
|
576
|
-
position: newPos,
|
577
|
-
},
|
578
|
-
},
|
579
|
-
];
|
580
|
-
}
|
581
|
-
case "bulk":
|
582
|
-
return fuseBulk(env, operation, term);
|
583
|
-
case "id":
|
584
|
-
return [
|
585
|
-
{
|
586
|
-
newEnv: env,
|
587
|
-
newTermNode: term,
|
588
|
-
remainingOperation: { type: "id" },
|
589
|
-
},
|
590
|
-
];
|
591
|
-
default:
|
592
|
-
throw new Error(`Unhandled operation type: ${operation}`);
|
593
|
-
}
|
594
|
-
}
|
595
|
-
else if (term.type === "exp") {
|
596
|
-
const expTerm = term;
|
597
|
-
const binding = term.binding;
|
598
|
-
const exp = binding[0];
|
599
|
-
const val = binding[1];
|
600
|
-
const valStr = valToStr(val);
|
601
|
-
switch (operation.type) {
|
602
|
-
case "insert":
|
603
|
-
const { str, position } = operation;
|
604
|
-
if (position === 0) {
|
605
|
-
let resultList = [];
|
606
|
-
resultList.push({
|
607
|
-
newEnv: env,
|
608
|
-
newTermNode: {
|
609
|
-
type: "seq",
|
610
|
-
nodes: [{ type: "const", value: str }, term],
|
611
|
-
},
|
612
|
-
remainingOperation: { type: "id" },
|
613
|
-
});
|
614
|
-
if (!Utils_1.isWhitespace(str)) {
|
615
|
-
// another choice:
|
616
|
-
let newStr = str + valStr;
|
617
|
-
try {
|
618
|
-
let newVal = strToVal(newStr, val);
|
619
|
-
let { newEnv, newExp } = fuseExp(Object.assign({}, env), newVal, exp);
|
620
|
-
resultList.push({
|
621
|
-
newEnv: newEnv,
|
622
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
623
|
-
remainingOperation: { type: "id" },
|
624
|
-
});
|
625
|
-
}
|
626
|
-
catch (error) {
|
627
|
-
// console.error(error);
|
628
|
-
}
|
629
|
-
}
|
630
|
-
return resultList;
|
631
|
-
}
|
632
|
-
else if (position < valStr.length) {
|
633
|
-
const newStr = valStr.slice(0, position) + str + valStr.slice(position);
|
634
|
-
const newVal = strToVal(newStr, val);
|
635
|
-
let { newEnv, newExp } = fuseExp(env, newVal, exp);
|
636
|
-
return [
|
637
|
-
{
|
638
|
-
newEnv: newEnv,
|
639
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
640
|
-
remainingOperation: { type: "id" },
|
641
|
-
},
|
642
|
-
];
|
643
|
-
}
|
644
|
-
else if (position == valStr.length) {
|
645
|
-
let resultList = [];
|
646
|
-
if (!Utils_1.isWhitespace(str)) {
|
647
|
-
const newStr = valStr + str;
|
648
|
-
try {
|
649
|
-
const newVal = strToVal(newStr, val);
|
650
|
-
let { newEnv, newExp } = fuseExp(Object.assign({}, env), newVal, exp);
|
651
|
-
resultList.push({
|
652
|
-
newEnv: newEnv,
|
653
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
654
|
-
remainingOperation: { type: "id" },
|
655
|
-
});
|
656
|
-
}
|
657
|
-
catch (error) {
|
658
|
-
console.error(error);
|
659
|
-
}
|
660
|
-
}
|
661
|
-
// If the expression is a variable, them add variable's bidning to env to mark it unmodifiable.
|
662
|
-
let env2 = Object.assign({}, env);
|
663
|
-
if (exp.name) {
|
664
|
-
let x = exp.name;
|
665
|
-
env2[x] = [val, [val]]; // mark x as unmodifiable.
|
666
|
-
}
|
667
|
-
resultList.push({
|
668
|
-
newEnv: env2,
|
669
|
-
newTermNode: term,
|
670
|
-
remainingOperation: Object.assign(Object.assign({}, operation), { position: 0 }),
|
671
|
-
});
|
672
|
-
return resultList;
|
673
|
-
}
|
674
|
-
else {
|
675
|
-
const newPosition = position - valStr.length;
|
676
|
-
// If the expression is a variable, them add variable's bidning to env to mark it unmodifiable.
|
677
|
-
if (exp.name) {
|
678
|
-
let x = exp.name;
|
679
|
-
env[x] = [val, [val]]; // mark x as unmodifiable.
|
680
|
-
}
|
681
|
-
return [
|
682
|
-
{
|
683
|
-
newEnv: env,
|
684
|
-
newTermNode: term,
|
685
|
-
remainingOperation: Object.assign(Object.assign({}, operation), { position: newPosition }),
|
686
|
-
},
|
687
|
-
];
|
688
|
-
}
|
689
|
-
case "delete":
|
690
|
-
const { str: delStr, position: delPos } = operation;
|
691
|
-
if (delPos === 0) {
|
692
|
-
if (delStr.length < valStr.length) {
|
693
|
-
const newValStr = valStr.slice(delStr.length);
|
694
|
-
const newVal = strToVal(newValStr, val);
|
695
|
-
let { newEnv, newExp } = fuseExp(env, newVal, exp);
|
696
|
-
return [
|
697
|
-
{
|
698
|
-
newEnv: newEnv,
|
699
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
700
|
-
remainingOperation: { type: "id" },
|
701
|
-
},
|
702
|
-
];
|
703
|
-
}
|
704
|
-
else if (delStr.length == valStr.length) {
|
705
|
-
if (exp.name) {
|
706
|
-
let x = exp.name;
|
707
|
-
if (typeof val == "string") {
|
708
|
-
// two choice: update exp to "", or delete exp
|
709
|
-
let { newEnv, newExp } = fuseExp(Object.assign({}, env), "", exp);
|
710
|
-
return [
|
711
|
-
{
|
712
|
-
newEnv: newEnv,
|
713
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, ""] }),
|
714
|
-
remainingOperation: { type: "id" },
|
715
|
-
},
|
716
|
-
{
|
717
|
-
newEnv: deleteFromEnv(env, x),
|
718
|
-
newTermNode: { type: "bot" },
|
719
|
-
remainingOperation: { type: "id" },
|
720
|
-
},
|
721
|
-
];
|
722
|
-
}
|
723
|
-
else {
|
724
|
-
// delete exp, delete from env
|
725
|
-
return [
|
726
|
-
{
|
727
|
-
newEnv: deleteFromEnv(env, x),
|
728
|
-
newTermNode: { type: "bot" },
|
729
|
-
remainingOperation: { type: "id" },
|
730
|
-
},
|
731
|
-
];
|
732
|
-
}
|
733
|
-
}
|
734
|
-
else if (exp) {
|
735
|
-
let x = exp.object.name;
|
736
|
-
let field = exp.field;
|
737
|
-
let xVal = env[x][0];
|
738
|
-
let xValUpdatedMark = env[x][1][0];
|
739
|
-
if (xValUpdatedMark.fields[field].length == 0) {
|
740
|
-
let newXVal = deleteField(xVal, field);
|
741
|
-
let newXValUpdatedMark = deleteField(xValUpdatedMark, field);
|
742
|
-
let newEnv = deleteFromEnv(env, x);
|
743
|
-
newEnv[x] = [newXVal, [newXValUpdatedMark]];
|
744
|
-
return [
|
745
|
-
{
|
746
|
-
newEnv: newEnv,
|
747
|
-
newTermNode: { type: "bot" },
|
748
|
-
remainingOperation: { type: "id" },
|
749
|
-
},
|
750
|
-
];
|
751
|
-
}
|
752
|
-
else {
|
753
|
-
throw new Error(`field has been updaeted, cannot be remvoed: ${field}$`);
|
754
|
-
}
|
755
|
-
}
|
756
|
-
}
|
757
|
-
else if (delStr.length > valStr.length) {
|
758
|
-
let delStr1 = delStr.slice(0, valStr.length);
|
759
|
-
let delStr2 = delStr.slice(valStr.length);
|
760
|
-
let op1 = {
|
761
|
-
type: "delete",
|
762
|
-
str: delStr1,
|
763
|
-
position: 0,
|
764
|
-
};
|
765
|
-
let resultList = fuse(env, op1, term);
|
766
|
-
let op2 = {
|
767
|
-
type: "delete",
|
768
|
-
str: delStr2,
|
769
|
-
position: 0,
|
770
|
-
};
|
771
|
-
resultList.forEach((result) => {
|
772
|
-
result.remainingOperation = op2;
|
773
|
-
});
|
774
|
-
return resultList;
|
775
|
-
}
|
776
|
-
}
|
777
|
-
else if (delPos + delStr.length <= valStr.length) {
|
778
|
-
const newStr = valStr.slice(0, delPos) + valStr.slice(delPos + delStr.length);
|
779
|
-
const newVal = strToVal(newStr, val);
|
780
|
-
let { newEnv, newExp } = fuseExp(env, newVal, exp);
|
781
|
-
return [
|
782
|
-
{
|
783
|
-
newEnv: newEnv,
|
784
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
785
|
-
remainingOperation: { type: "id" },
|
786
|
-
},
|
787
|
-
];
|
788
|
-
}
|
789
|
-
else if (delPos <= valStr.length &&
|
790
|
-
delPos + delStr.length > valStr.length) {
|
791
|
-
const newStr = valStr.slice(0, delPos);
|
792
|
-
const remainingDelStr = delStr.slice(valStr.length - delPos);
|
793
|
-
const newVal = strToVal(newStr, val);
|
794
|
-
let { newEnv, newExp } = fuseExp(env, newVal, exp);
|
795
|
-
return [
|
796
|
-
{
|
797
|
-
newEnv: newEnv,
|
798
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
799
|
-
remainingOperation: {
|
800
|
-
type: "delete",
|
801
|
-
str: remainingDelStr,
|
802
|
-
position: 0,
|
803
|
-
},
|
804
|
-
},
|
805
|
-
];
|
806
|
-
}
|
807
|
-
else if (delPos > valStr.length) {
|
808
|
-
const newDelPos = delPos - valStr.length;
|
809
|
-
let [{ newEnv, newTermNode, remainingOperation }] = fuse(env, { type: "id" }, term);
|
810
|
-
return [
|
811
|
-
{
|
812
|
-
newEnv: newEnv,
|
813
|
-
newTermNode: newTermNode,
|
814
|
-
remainingOperation: {
|
815
|
-
type: "delete",
|
816
|
-
str: delStr,
|
817
|
-
position: newDelPos,
|
818
|
-
},
|
819
|
-
},
|
820
|
-
];
|
821
|
-
}
|
822
|
-
case "replace":
|
823
|
-
const { str1, str2, position: repPos, } = operation;
|
824
|
-
if (repPos === 0) {
|
825
|
-
if (valStr.startsWith(str1)) {
|
826
|
-
const newValStr = str2 + valStr.slice(str1.length);
|
827
|
-
const newVal = strToVal(newValStr, val);
|
828
|
-
let { newEnv, newExp } = fuseExp(env, newVal, exp);
|
829
|
-
// console.log("fuseExp, newVal:", newVal);
|
830
|
-
// console.log("newEnv:", newEnv);
|
831
|
-
return [
|
832
|
-
{
|
833
|
-
newEnv: newEnv,
|
834
|
-
newTermNode: Object.assign(Object.assign({}, term), { binding: [newExp, newVal] }),
|
835
|
-
remainingOperation: { type: "id" },
|
836
|
-
},
|
837
|
-
];
|
838
|
-
}
|
839
|
-
else {
|
840
|
-
throw new Error(`unsupported replacement: ${str1}; ${valStr}`);
|
841
|
-
}
|
842
|
-
}
|
843
|
-
else if (repPos > valStr.length) {
|
844
|
-
const newRepPos = repPos - valStr.length;
|
845
|
-
let [{ newEnv, newTermNode, remainingOperation }] = fuse(env, { type: "id" }, term);
|
846
|
-
return [
|
847
|
-
{
|
848
|
-
newEnv: newEnv,
|
849
|
-
newTermNode: newTermNode,
|
850
|
-
remainingOperation: Object.assign(Object.assign({}, operation), { position: newRepPos }),
|
851
|
-
},
|
852
|
-
];
|
853
|
-
}
|
854
|
-
else {
|
855
|
-
throw new Error(`Unsupported replacement`);
|
856
|
-
}
|
857
|
-
case "bulk":
|
858
|
-
return fuseBulk(env, operation, term);
|
859
|
-
case "id":
|
860
|
-
// find variables in e, and update them in env
|
861
|
-
let { variables, fields } = Exp_1.findVariablesAndFields(exp);
|
862
|
-
variables.forEach((variable) => {
|
863
|
-
env = markVariableInEnv(variable, env);
|
864
|
-
});
|
865
|
-
fields.forEach(({ variable, field }) => {
|
866
|
-
env = markFieldOfObjectInEnv(field, variable, env);
|
867
|
-
});
|
868
|
-
return [
|
869
|
-
{
|
870
|
-
newEnv: env,
|
871
|
-
newTermNode: term,
|
872
|
-
remainingOperation: { type: "id" },
|
873
|
-
},
|
874
|
-
];
|
875
|
-
default:
|
876
|
-
throw new Error(`Unhandled operation type: ${operation}`);
|
877
|
-
}
|
878
|
-
}
|
879
|
-
else if (term.type === "lambda") {
|
880
|
-
let marker = term.marker;
|
881
|
-
if (marker.type === "loopitem") {
|
882
|
-
let varName = term.variable.name;
|
883
|
-
let varExp = term.binding[0];
|
884
|
-
let varVal = term.binding[1];
|
885
|
-
let env1 = Object.assign({}, env);
|
886
|
-
env1[varName] = [varVal, []];
|
887
|
-
let newArrVarName = "";
|
888
|
-
if (marker.lst) {
|
889
|
-
let expName = marker.lst.name;
|
890
|
-
newArrVarName = expName + "_new";
|
891
|
-
}
|
892
|
-
else {
|
893
|
-
throw new Error("exp is not a Variable with a name property in loopitem's marker");
|
894
|
-
}
|
895
|
-
let resultList = fuse(env1, operation, term.body);
|
896
|
-
return resultList.map(({ newEnv, newTermNode, remainingOperation }) => {
|
897
|
-
let newVarVal = newEnv[varName][0];
|
898
|
-
let newArrVal = env[newArrVarName][0]; // must be an array
|
899
|
-
newArrVal.push(newVarVal);
|
900
|
-
env[newArrVarName] = [newArrVal, [newArrVal]];
|
901
|
-
let { newEnv: updatedEnv, newExp } = fuseExp(env, newVarVal, varExp);
|
902
|
-
return {
|
903
|
-
newEnv: updatedEnv,
|
904
|
-
newTermNode: {
|
905
|
-
type: "lambda",
|
906
|
-
variable: term.variable,
|
907
|
-
body: newTermNode,
|
908
|
-
binding: [newExp, newVarVal],
|
909
|
-
marker: term.marker,
|
910
|
-
},
|
911
|
-
remainingOperation: remainingOperation,
|
912
|
-
};
|
913
|
-
});
|
914
|
-
}
|
915
|
-
else {
|
916
|
-
let varName = term.variable.name;
|
917
|
-
let varExp = term.binding[0];
|
918
|
-
let varVal = term.binding[1];
|
919
|
-
let env1 = Object.assign({}, env);
|
920
|
-
env1[varName] = [varVal, []];
|
921
|
-
// console.log("--------lambda----------");
|
922
|
-
// console.log("operation:", operation);
|
923
|
-
// console.log("term.body:", term.body);
|
924
|
-
// console.log("env1:", env1);
|
925
|
-
let resultList = fuse(env1, operation, term.body);
|
926
|
-
return resultList.map(({ newEnv, newTermNode, remainingOperation }) => {
|
927
|
-
// console.log("newEnv:", newEnv);
|
928
|
-
let newVarVal = newEnv[varName][0];
|
929
|
-
delete newEnv[varName];
|
930
|
-
let updatedOldEnv = updateEnvByEnv(env, newEnv);
|
931
|
-
let { newEnv: updatedEnv, newExp } = fuseExp(updatedOldEnv, newVarVal, varExp);
|
932
|
-
// console.log("lambda, newVarVal:", newVarVal);
|
933
|
-
// console.log("updatedOldEnv:", updatedOldEnv);
|
934
|
-
// console.log("exp:", varExp);
|
935
|
-
// console.log("newExp:", newExp);
|
936
|
-
// console.log("updatedEnv:", updatedEnv);
|
937
|
-
return {
|
938
|
-
newEnv: updatedEnv,
|
939
|
-
newTermNode: {
|
940
|
-
type: "lambda",
|
941
|
-
variable: term.variable,
|
942
|
-
body: newTermNode,
|
943
|
-
binding: [newExp, newVarVal],
|
944
|
-
marker: term.marker,
|
945
|
-
},
|
946
|
-
remainingOperation: remainingOperation,
|
947
|
-
};
|
948
|
-
});
|
949
|
-
}
|
950
|
-
}
|
951
|
-
else if (term.type === "branchstart" ||
|
952
|
-
term.type === "branchend" ||
|
953
|
-
term.type === "nop") {
|
954
|
-
let resultList = [];
|
955
|
-
resultList.push({
|
956
|
-
newEnv: env,
|
957
|
-
newTermNode: term,
|
958
|
-
remainingOperation: operation,
|
959
|
-
});
|
960
|
-
switch (operation.type) {
|
961
|
-
case "insert":
|
962
|
-
const { str, position } = operation;
|
963
|
-
if (position === 0) {
|
964
|
-
resultList.push({
|
965
|
-
newEnv: env,
|
966
|
-
newTermNode: {
|
967
|
-
type: "seq",
|
968
|
-
nodes: [{ type: "const", value: str }, term],
|
969
|
-
},
|
970
|
-
remainingOperation: { type: "id" },
|
971
|
-
});
|
972
|
-
}
|
973
|
-
case "delete":
|
974
|
-
case "replace":
|
975
|
-
return resultList;
|
976
|
-
case "bulk":
|
977
|
-
return fuseBulk(env, operation, term);
|
978
|
-
default:
|
979
|
-
throw new Error(`Unhandled operation type: ${operation}`);
|
980
|
-
}
|
981
|
-
}
|
982
|
-
else if (term.type === "seq") {
|
983
|
-
if (operation.type === "bulk") {
|
984
|
-
return fuseBulk(env, operation, term);
|
985
|
-
}
|
986
|
-
const terms = term.nodes;
|
987
|
-
let results = [
|
988
|
-
{
|
989
|
-
newEnv: env,
|
990
|
-
newTermNode: { type: "seq", nodes: [] },
|
991
|
-
remainingOperation: operation,
|
992
|
-
},
|
993
|
-
];
|
994
|
-
for (const subTerm of terms) {
|
995
|
-
const newResults = [];
|
996
|
-
for (const result of results) {
|
997
|
-
// console.log("-------------seq-----------");
|
998
|
-
// console.log(result);
|
999
|
-
// console.log(subTerm);
|
1000
|
-
const subResults = fuse(result.newEnv, result.remainingOperation, subTerm);
|
1001
|
-
for (const subResult of subResults) {
|
1002
|
-
const updatedNodes = (result.newTermNode.type === "seq"
|
1003
|
-
? result.newTermNode.nodes
|
1004
|
-
: [result.newTermNode]).concat(subResult.newTermNode.type === "seq"
|
1005
|
-
? subResult.newTermNode.nodes
|
1006
|
-
: [subResult.newTermNode]);
|
1007
|
-
newResults.push({
|
1008
|
-
newEnv: subResult.newEnv,
|
1009
|
-
newTermNode: {
|
1010
|
-
type: "seq",
|
1011
|
-
nodes: updatedNodes,
|
1012
|
-
},
|
1013
|
-
remainingOperation: subResult.remainingOperation,
|
1014
|
-
});
|
1015
|
-
}
|
1016
|
-
}
|
1017
|
-
results = newResults;
|
1018
|
-
}
|
1019
|
-
return results.map((result) => ({
|
1020
|
-
newEnv: result.newEnv,
|
1021
|
-
newTermNode: result.newTermNode.type === "seq" &&
|
1022
|
-
result.newTermNode.nodes.length === 1
|
1023
|
-
? result.newTermNode.nodes[0]
|
1024
|
-
: result.newTermNode,
|
1025
|
-
remainingOperation: result.remainingOperation,
|
1026
|
-
}));
|
1027
|
-
}
|
1028
|
-
else if (term.type === "end") {
|
1029
|
-
let results = [{ newEnv: env, newTermNode: term, remainingOperation: operation }];
|
1030
|
-
return results;
|
1031
|
-
}
|
1032
|
-
else {
|
1033
|
-
throw new Error("Operation can only be applied to ConstNode with string value");
|
1034
|
-
}
|
1035
|
-
}
|
1036
|
-
exports.fuse = fuse;
|
1037
|
-
function fuseExp(env, value, exp) {
|
1038
|
-
switch (exp.type) {
|
1039
|
-
case "constant":
|
1040
|
-
return { newEnv: env, newExp: valueToConstantExpr(value) };
|
1041
|
-
case "variable":
|
1042
|
-
if (!(exp.name in env)) {
|
1043
|
-
throw new Error(`Variable ${exp.name} not found in environment.`);
|
1044
|
-
}
|
1045
|
-
const [varValue, marks] = env[exp.name];
|
1046
|
-
if (marks.length === 0) {
|
1047
|
-
const newEnv = Object.assign({}, env);
|
1048
|
-
newEnv[exp.name] = [value, [value]];
|
1049
|
-
return { newEnv, newExp: exp };
|
1050
|
-
}
|
1051
|
-
else if (marks.length === 1 && marks[0] === value) {
|
1052
|
-
return { newEnv: env, newExp: exp };
|
1053
|
-
}
|
1054
|
-
else {
|
1055
|
-
throw new Error(`Fail, variable cannot be updated to different value ${exp.name}, previous: ${marks[0]}, new: ${value}`);
|
1056
|
-
}
|
1057
|
-
case "freeze":
|
1058
|
-
let [_, evaluated] = peval_1.evaluateExpr(transformEnvironment(env), exp.expression);
|
1059
|
-
if (evaluated !== value) {
|
1060
|
-
throw new Error(`Fail, freezed expression cannot be changed, old: ${value}, new: ${evaluated}`);
|
1061
|
-
}
|
1062
|
-
else {
|
1063
|
-
return { newEnv: env, newExp: exp };
|
1064
|
-
}
|
1065
|
-
case "field":
|
1066
|
-
// Rule for field access
|
1067
|
-
const objExp = exp.object;
|
1068
|
-
if (objExp.type === "variable" && objExp.name in env) {
|
1069
|
-
const [objValue, objMarks] = env[objExp.name];
|
1070
|
-
if (objValue.type === "object") {
|
1071
|
-
const newFields = Object.assign(Object.assign({}, objValue.fields), { [exp.field]: value });
|
1072
|
-
const newObjValue = {
|
1073
|
-
type: "object",
|
1074
|
-
fields: newFields,
|
1075
|
-
};
|
1076
|
-
const newMarks = updateFieldMarkWithValue(objMarks[0], exp.field, value);
|
1077
|
-
const newEnv = Object.assign({}, env);
|
1078
|
-
newEnv[objExp.name] = [newObjValue, [newMarks]];
|
1079
|
-
return { newEnv, newExp: exp };
|
1080
|
-
}
|
1081
|
-
else {
|
1082
|
-
throw new Error("Field access's value is not an object");
|
1083
|
-
}
|
1084
|
-
}
|
1085
|
-
else {
|
1086
|
-
throw new Error(`Field access not start with variable.`);
|
1087
|
-
}
|
1088
|
-
case "binary":
|
1089
|
-
let transformedEnv = transformEnvironment(env);
|
1090
|
-
let [envLeft, left] = peval_1.evaluateExpr(transformedEnv, exp.left);
|
1091
|
-
// let [envRight, right] = evaluateExpr(transformedEnv, exp.right);
|
1092
|
-
// if(value as number){
|
1093
|
-
// console.log("transformedEnv:", transformedEnv);
|
1094
|
-
// console.log("left:", left);
|
1095
|
-
// console.log("value:", value);
|
1096
|
-
// console.log("exp:", exp);
|
1097
|
-
if (typeof value === "number") {
|
1098
|
-
if (typeof value !== "number" || value === null) {
|
1099
|
-
throw new Error("Value must be a non-null number");
|
1100
|
-
}
|
1101
|
-
switch (exp.operator) {
|
1102
|
-
case "+":
|
1103
|
-
let subResultForPlus = fuseExp(env, value - left, exp.right);
|
1104
|
-
// console.log("subResult:", subResultForPlus);
|
1105
|
-
return {
|
1106
|
-
newEnv: subResultForPlus.newEnv,
|
1107
|
-
newExp: Object.assign(Object.assign({}, exp), { right: subResultForPlus.newExp }),
|
1108
|
-
};
|
1109
|
-
case "-":
|
1110
|
-
let subResultForMinus = fuseExp(env, left - value, exp.right);
|
1111
|
-
return {
|
1112
|
-
newEnv: subResultForMinus.newEnv,
|
1113
|
-
newExp: Object.assign(Object.assign({}, exp), { right: subResultForMinus.newExp }),
|
1114
|
-
};
|
1115
|
-
case "*":
|
1116
|
-
let subResultForTimes = fuseExp(env, value / left, exp.right);
|
1117
|
-
return {
|
1118
|
-
newEnv: subResultForTimes.newEnv,
|
1119
|
-
newExp: Object.assign(Object.assign({}, exp), { right: subResultForTimes.newExp }),
|
1120
|
-
};
|
1121
|
-
case "/":
|
1122
|
-
let subResultForDivide = fuseExp(env, left / value, exp.right);
|
1123
|
-
return {
|
1124
|
-
newEnv: subResultForDivide.newEnv,
|
1125
|
-
newExp: Object.assign(Object.assign({}, exp), { right: subResultForDivide.newExp }),
|
1126
|
-
};
|
1127
|
-
}
|
1128
|
-
// } else if (value as boolean) {
|
1129
|
-
}
|
1130
|
-
else if (typeof value === "boolean") {
|
1131
|
-
// TODO
|
1132
|
-
}
|
1133
|
-
case "unary":
|
1134
|
-
// Add logic for unary operations here
|
1135
|
-
return { newEnv: env, newExp: exp };
|
1136
|
-
default:
|
1137
|
-
throw new Error(`Unsupported expression type: ${exp.type}`);
|
1138
|
-
}
|
1139
|
-
}
|
1140
|
-
exports.fuseExp = fuseExp;
|
1141
|
-
function strToVal(s, v) {
|
1142
|
-
if (typeof v === "number") {
|
1143
|
-
const parsedNumber = parseFloat(s);
|
1144
|
-
if (isNaN(parsedNumber)) {
|
1145
|
-
throw new Error("convert to number fail: ${s}");
|
1146
|
-
}
|
1147
|
-
else {
|
1148
|
-
return parsedNumber;
|
1149
|
-
}
|
1150
|
-
}
|
1151
|
-
else if (typeof v === "boolean") {
|
1152
|
-
if (s === "true") {
|
1153
|
-
return true;
|
1154
|
-
}
|
1155
|
-
else if (s === "false") {
|
1156
|
-
return false;
|
1157
|
-
}
|
1158
|
-
else {
|
1159
|
-
throw new Error("convert to boolean fail: ${s}");
|
1160
|
-
}
|
1161
|
-
}
|
1162
|
-
else if (typeof v === "string") {
|
1163
|
-
return s; // v is already string, return s as is
|
1164
|
-
}
|
1165
|
-
else {
|
1166
|
-
throw new Error(`Unsupported type: ${typeof v}`);
|
1167
|
-
}
|
1168
|
-
}
|
1169
|
-
function valToStr(value) {
|
1170
|
-
if (typeof value === "number" ||
|
1171
|
-
typeof value === "boolean" ||
|
1172
|
-
typeof value === "string") {
|
1173
|
-
return String(value); // Convert number, boolean, and string to string
|
1174
|
-
}
|
1175
|
-
else {
|
1176
|
-
return "Unknown"; // Handle unexpected types
|
1177
|
-
}
|
1178
|
-
}
|
1179
|
-
function deleteFromEnv(env, key) {
|
1180
|
-
const newEnv = Object.assign({}, env); // Create a shallow copy of env
|
1181
|
-
delete newEnv[key]; // Delete the specified key from the new environment
|
1182
|
-
return newEnv; // Return the modified environment
|
1183
|
-
}
|
1184
|
-
/**
|
1185
|
-
* Deletes a specified field from an ObjectValue.
|
1186
|
-
* @param obj The ObjectValue from which to delete the field.
|
1187
|
-
* @param field The field to delete.
|
1188
|
-
* @returns A new ObjectValue with the specified field removed.
|
1189
|
-
*/
|
1190
|
-
function deleteField(obj, field) {
|
1191
|
-
// Destructure the fields, omitting the specified field
|
1192
|
-
const _a = obj.fields, _b = field, _ = _a[_b], newFields = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
1193
|
-
// Return a new ObjectValue with the updated fields
|
1194
|
-
return {
|
1195
|
-
type: "object",
|
1196
|
-
fields: newFields,
|
1197
|
-
};
|
1198
|
-
}
|
1199
|
-
function updateFieldMark(obj, field, objVal) {
|
1200
|
-
// Destructure the fields, omitting the specified field
|
1201
|
-
const _a = obj.fields, _b = field, _ = _a[_b], newFields = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
1202
|
-
newFields[field] = objVal.fields[field];
|
1203
|
-
// Return a new ObjectValue with the updated fields
|
1204
|
-
return {
|
1205
|
-
type: "object",
|
1206
|
-
fields: newFields,
|
1207
|
-
};
|
1208
|
-
}
|
1209
|
-
function updateFieldMarkWithValue(obj, field, value) {
|
1210
|
-
// Destructure the fields, omitting the specified field
|
1211
|
-
const _a = obj.fields, _b = field, val = _a[_b], newFields = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
1212
|
-
newFields[field] = [value];
|
1213
|
-
// Return a new ObjectValue with the updated fields
|
1214
|
-
return {
|
1215
|
-
type: "object",
|
1216
|
-
fields: newFields,
|
1217
|
-
};
|
1218
|
-
}
|
1219
|
-
function markVariableInEnv(variable, env) {
|
1220
|
-
if (!(variable.name in env)) {
|
1221
|
-
throw new Error(`Variable ${variable.name} not found in environment.`);
|
1222
|
-
}
|
1223
|
-
let val = env[variable.name][0];
|
1224
|
-
let newEnv = deleteFromEnv(env, variable.name);
|
1225
|
-
newEnv[variable.name] = [val, [val]];
|
1226
|
-
return newEnv;
|
1227
|
-
}
|
1228
|
-
function markFieldOfObjectInEnv(field, variable, env) {
|
1229
|
-
let x = variable.name;
|
1230
|
-
if (!(x in env)) {
|
1231
|
-
throw new Error(`Variable ${x} not found in environment.`);
|
1232
|
-
}
|
1233
|
-
let xVal = env[x][0];
|
1234
|
-
let xValMark = env[x][1][0];
|
1235
|
-
let newXValUpdatedMark = updateFieldMark(xValMark, field, xVal);
|
1236
|
-
let newEnv = deleteFromEnv(env, x);
|
1237
|
-
newEnv[x] = [xVal, [newXValUpdatedMark]];
|
1238
|
-
return newEnv;
|
1239
|
-
}
|
1240
|
-
function updateEnvByEnv(env, env2) {
|
1241
|
-
// Create a copy of env to avoid mutating the original env
|
1242
|
-
let updatedEnv = Object.assign({}, env);
|
1243
|
-
// Iterate over keys in env2
|
1244
|
-
for (const key in env2) {
|
1245
|
-
if (env2.hasOwnProperty(key)) {
|
1246
|
-
// Update the value in the updatedEnv
|
1247
|
-
updatedEnv[key] = env2[key];
|
1248
|
-
}
|
1249
|
-
}
|
1250
|
-
return updatedEnv;
|
1251
|
-
}
|
1252
|
-
function transformEnvironment(env) {
|
1253
|
-
const map = new Map();
|
1254
|
-
for (const variable in env) {
|
1255
|
-
if (env.hasOwnProperty(variable)) {
|
1256
|
-
map.set(variable, env[variable][0]);
|
1257
|
-
}
|
1258
|
-
}
|
1259
|
-
return map;
|
1260
|
-
}
|
1261
|
-
function valueToConstantExpr(value) {
|
1262
|
-
if (value === null ||
|
1263
|
-
typeof value === "number" ||
|
1264
|
-
typeof value === "boolean" ||
|
1265
|
-
typeof value === "string") {
|
1266
|
-
return { type: "constant", value: value };
|
1267
|
-
}
|
1268
|
-
else if (Array.isArray(value)) {
|
1269
|
-
return {
|
1270
|
-
type: "constant",
|
1271
|
-
value: value.map((v) => valueToConstantExpr(v)),
|
1272
|
-
};
|
1273
|
-
}
|
1274
|
-
else if (value.type === "object") {
|
1275
|
-
const objectValue = value;
|
1276
|
-
const fields = {};
|
1277
|
-
for (const key in objectValue.fields) {
|
1278
|
-
if (objectValue.fields.hasOwnProperty(key)) {
|
1279
|
-
fields[key] = valueToConstantExpr(objectValue.fields[key]);
|
1280
|
-
}
|
1281
|
-
}
|
1282
|
-
return {
|
1283
|
-
type: "constant",
|
1284
|
-
value: { type: "object", fields: fields },
|
1285
|
-
};
|
1286
|
-
}
|
1287
|
-
else {
|
1288
|
-
throw new Error(`Unhandled value type: ${typeof value}`);
|
1289
|
-
}
|
1290
|
-
}
|
1291
|
-
exports.valueToConstantExpr = valueToConstantExpr;
|
1292
|
-
function printEnvironment(env) {
|
1293
|
-
console.log("{\n");
|
1294
|
-
for (const variable in env) {
|
1295
|
-
if (env.hasOwnProperty(variable)) {
|
1296
|
-
const [currentValue, marks] = env[variable];
|
1297
|
-
console.log(`${variable}: {`);
|
1298
|
-
console.log(" val: ");
|
1299
|
-
Print_1.printValue(currentValue, " ");
|
1300
|
-
console.log(",marks: [");
|
1301
|
-
marks.forEach((v, index) => {
|
1302
|
-
Print_1.printValue(v, " ");
|
1303
|
-
if (index < marks.length - 1) {
|
1304
|
-
console.log(", ");
|
1305
|
-
}
|
1306
|
-
});
|
1307
|
-
console.log("]\n },\n");
|
1308
|
-
}
|
1309
|
-
}
|
1310
|
-
console.log("}");
|
1311
|
-
}
|
1312
|
-
exports.printEnvironment = printEnvironment;
|
1313
|
-
function fuseBulk(env, bulkOp, term) {
|
1314
|
-
if (bulkOp.type === "id") {
|
1315
|
-
// console.log("Bulk, term:", term);
|
1316
|
-
return fuse(env, bulkOp, term);
|
1317
|
-
// return [{ newEnv: env, newTermNode: term, remainingOperation: { type: 'id' } }];
|
1318
|
-
}
|
1319
|
-
if (bulkOp.type !== "bulk" || !bulkOp.operations) {
|
1320
|
-
throw new Error("Invalid bulk operation");
|
1321
|
-
}
|
1322
|
-
// ending of recursive call
|
1323
|
-
if (bulkOp.operations.length == 0) {
|
1324
|
-
return [
|
1325
|
-
{ newEnv: env, newTermNode: term, remainingOperation: { type: "id" } },
|
1326
|
-
];
|
1327
|
-
}
|
1328
|
-
else if (term.type === "seq" && term.nodes.length == 0) {
|
1329
|
-
return [{ newEnv: env, newTermNode: term, remainingOperation: bulkOp }];
|
1330
|
-
}
|
1331
|
-
const [op1, ...restOps] = bulkOp.operations;
|
1332
|
-
if (term.type === "seq") {
|
1333
|
-
const firstTerm = term.nodes[0];
|
1334
|
-
const remainingTerms = term.nodes.slice(1);
|
1335
|
-
const fuseResultsOfFirstTerm = fuseBulk(env, bulkOp, firstTerm);
|
1336
|
-
// console.log("fuseResultsOfFirstTerm:", fuseResultsOfFirstTerm);
|
1337
|
-
const results = [];
|
1338
|
-
for (const result of fuseResultsOfFirstTerm) {
|
1339
|
-
const subResults = fuseBulk(result.newEnv, result.remainingOperation, {
|
1340
|
-
type: "seq",
|
1341
|
-
nodes: remainingTerms,
|
1342
|
-
});
|
1343
|
-
for (const subResult of subResults) {
|
1344
|
-
let remainingNodesTerm = [];
|
1345
|
-
if (subResult.newTermNode.type != "seq") {
|
1346
|
-
remainingNodesTerm.push(subResult.newTermNode);
|
1347
|
-
}
|
1348
|
-
else {
|
1349
|
-
remainingNodesTerm = subResult.newTermNode.nodes;
|
1350
|
-
}
|
1351
|
-
results.push({
|
1352
|
-
newEnv: subResult.newEnv,
|
1353
|
-
newTermNode: {
|
1354
|
-
type: "seq",
|
1355
|
-
nodes: [result.newTermNode, ...remainingNodesTerm],
|
1356
|
-
},
|
1357
|
-
remainingOperation: subResult.remainingOperation,
|
1358
|
-
});
|
1359
|
-
}
|
1360
|
-
}
|
1361
|
-
return results;
|
1362
|
-
}
|
1363
|
-
else if (term.type === "lambda") {
|
1364
|
-
return fuse(env, bulkOp, term);
|
1365
|
-
}
|
1366
|
-
else {
|
1367
|
-
if (op1.type === "insert" ||
|
1368
|
-
op1.type === "delete" ||
|
1369
|
-
op1.type === "replace") {
|
1370
|
-
const n1 = op1.position;
|
1371
|
-
// 这里不能简单的fuse整个term,要根据term类型来,就好比上一个if判断是seq,除了seq外,LambdaAppNode需要特殊处理
|
1372
|
-
const op1Results = fuse(env, op1, term);
|
1373
|
-
let listOfList = op1Results.map((op1Result) => {
|
1374
|
-
let op1Prime = op1Result.remainingOperation;
|
1375
|
-
if (op1Prime.type === "id" ||
|
1376
|
-
op1Prime.type === "insert" ||
|
1377
|
-
op1Prime.type === "delete" ||
|
1378
|
-
op1Prime.type === "replace") {
|
1379
|
-
let termStr = Evaluation_1.evaluateTermNode(op1Result.newTermNode);
|
1380
|
-
let deltaN = termStr.length;
|
1381
|
-
// Adjust positions for the remaining operations
|
1382
|
-
const adjustedRestOps = restOps.map((op) => {
|
1383
|
-
if (op.type === "id") {
|
1384
|
-
return op;
|
1385
|
-
}
|
1386
|
-
else if (!("position" in op)) {
|
1387
|
-
throw new Error("All operations must have positions");
|
1388
|
-
}
|
1389
|
-
else {
|
1390
|
-
return Object.assign(Object.assign({}, op), { position: op.position - deltaN });
|
1391
|
-
}
|
1392
|
-
});
|
1393
|
-
// Combine the remaining operations
|
1394
|
-
let remainingBulkOp = {
|
1395
|
-
type: "bulk",
|
1396
|
-
operations: [op1Result.remainingOperation, ...adjustedRestOps],
|
1397
|
-
};
|
1398
|
-
return [
|
1399
|
-
{
|
1400
|
-
newEnv: op1Result.newEnv,
|
1401
|
-
newTermNode: op1Result.newTermNode,
|
1402
|
-
remainingOperation: remainingBulkOp,
|
1403
|
-
},
|
1404
|
-
];
|
1405
|
-
}
|
1406
|
-
else {
|
1407
|
-
throw new Error("nested bulk current not supported");
|
1408
|
-
}
|
1409
|
-
});
|
1410
|
-
return listOfList.reduce((acc, val) => acc.concat(val), []);
|
1411
|
-
}
|
1412
|
-
else if (op1.type === "id") {
|
1413
|
-
// case 3
|
1414
|
-
// Create a new bulk operation with the remaining operations
|
1415
|
-
const newBulkOp = {
|
1416
|
-
type: "bulk",
|
1417
|
-
operations: restOps,
|
1418
|
-
};
|
1419
|
-
return fuseBulk(env, newBulkOp, term);
|
1420
|
-
}
|
1421
|
-
}
|
1422
|
-
return [];
|
1423
|
-
}
|
1424
|
-
exports.fuseBulk = fuseBulk;
|
1425
|
-
function getOpStr(op1) {
|
1426
|
-
if (op1.type === "insert" || op1.type === "delete") {
|
1427
|
-
return op1.str;
|
1428
|
-
}
|
1429
|
-
else if (op1.type === "replace") {
|
1430
|
-
return op1.str1;
|
1431
|
-
}
|
1432
|
-
else {
|
1433
|
-
return undefined;
|
1434
|
-
}
|
1435
|
-
}
|
1436
|
-
//# sourceMappingURL=Fuse.js.map
|