@silverbulletmd/silverbullet 2.5.3 → 2.6.1
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 +4 -5
- package/client/asset_bundle/bundle.ts +3 -9
- package/client/data/datastore.ts +4 -5
- package/client/markdown_parser/constants.ts +3 -2
- package/client/plugos/hooks/code_widget.ts +3 -5
- package/client/plugos/hooks/command.ts +8 -8
- package/client/plugos/hooks/document_editor.ts +10 -12
- package/client/plugos/hooks/event.ts +33 -36
- package/client/plugos/hooks/mq.ts +17 -17
- package/client/plugos/hooks/plug_namespace.ts +3 -5
- package/client/plugos/hooks/slash_command.ts +12 -27
- package/client/plugos/hooks/syscall.ts +3 -3
- package/client/plugos/manifest_cache.ts +22 -15
- package/client/plugos/plug.ts +2 -5
- package/client/plugos/plug_compile.ts +67 -65
- package/client/plugos/protocol.ts +28 -28
- package/client/plugos/proxy_fetch.ts +7 -6
- package/client/plugos/sandboxes/worker_sandbox.ts +16 -15
- package/client/plugos/syscalls/asset.ts +1 -3
- package/client/plugos/syscalls/code_widget.ts +1 -3
- package/client/plugos/syscalls/config.ts +1 -5
- package/client/plugos/syscalls/datastore.ts +1 -1
- package/client/plugos/syscalls/editor.ts +63 -60
- package/client/plugos/syscalls/event.ts +9 -12
- package/client/plugos/syscalls/fetch.ts +30 -22
- package/client/plugos/syscalls/index.ts +10 -1
- package/client/plugos/syscalls/jsonschema.ts +72 -32
- package/client/plugos/syscalls/language.ts +9 -5
- package/client/plugos/syscalls/markdown.ts +29 -7
- package/client/plugos/syscalls/mq.ts +3 -11
- package/client/plugos/syscalls/service_registry.ts +1 -4
- package/client/plugos/syscalls/shell.ts +2 -5
- package/client/plugos/syscalls/sync.ts +69 -60
- package/client/plugos/syscalls/system.ts +2 -3
- package/client/plugos/system.ts +4 -10
- package/client/plugos/worker_runtime.ts +4 -3
- package/client/space_lua/aggregates.ts +632 -59
- package/client/space_lua/ast.ts +21 -9
- package/client/space_lua/ast_narrow.ts +4 -2
- package/client/space_lua/eval.ts +842 -536
- package/client/space_lua/labels.ts +6 -11
- package/client/space_lua/liq_null.ts +6 -0
- package/client/space_lua/numeric.ts +5 -8
- package/client/space_lua/parse.ts +290 -169
- package/client/space_lua/query_collection.ts +213 -149
- package/client/space_lua/render_lua_markdown.ts +369 -0
- package/client/space_lua/rp.ts +5 -4
- package/client/space_lua/runtime.ts +245 -142
- package/client/space_lua/stdlib/format.ts +34 -20
- package/client/space_lua/stdlib/js.ts +3 -7
- package/client/space_lua/stdlib/load.ts +1 -3
- package/client/space_lua/stdlib/math.ts +15 -14
- package/client/space_lua/stdlib/net.ts +25 -15
- package/client/space_lua/stdlib/os.ts +76 -85
- package/client/space_lua/stdlib/pattern.ts +28 -35
- package/client/space_lua/stdlib/prng.ts +15 -12
- package/client/space_lua/stdlib/space_lua.ts +16 -17
- package/client/space_lua/stdlib/string.ts +7 -17
- package/client/space_lua/stdlib/string_pack.ts +23 -19
- package/client/space_lua/stdlib/table.ts +5 -9
- package/client/space_lua/stdlib.ts +20 -30
- package/client/space_lua/tonumber.ts +79 -40
- package/client/space_lua/util.ts +14 -10
- package/dist/plug-compile.js +44 -41
- package/package.json +24 -22
- package/plug-api/lib/async.ts +19 -6
- package/plug-api/lib/crypto.ts +5 -6
- package/plug-api/lib/dates.ts +15 -7
- package/plug-api/lib/json.ts +10 -4
- package/plug-api/lib/ref.ts +18 -18
- package/plug-api/lib/resolve.ts +7 -11
- package/plug-api/lib/tags.ts +13 -4
- package/plug-api/lib/transclusion.ts +6 -17
- package/plug-api/lib/tree.ts +115 -43
- package/plug-api/lib/yaml.ts +25 -15
- package/plug-api/syscalls/asset.ts +1 -1
- package/plug-api/syscalls/config.ts +1 -4
- package/plug-api/syscalls/editor.ts +14 -14
- package/plug-api/syscalls/jsonschema.ts +1 -3
- package/plug-api/syscalls/lua.ts +3 -9
- package/plug-api/syscalls/mq.ts +1 -4
- package/plug-api/syscalls/shell.ts +4 -1
- package/plug-api/syscalls/space.ts +3 -10
- package/plug-api/syscalls/system.ts +1 -4
- package/plug-api/syscalls/yaml.ts +2 -6
- package/plug-api/types/client.ts +16 -1
- package/plug-api/types/event.ts +6 -4
- package/plug-api/types/manifest.ts +8 -9
- package/plugs/builtin_plugs.ts +2 -2
- package/dist/worker_runtime_bundle.js +0 -233
|
@@ -54,7 +54,7 @@ function toBytes(s: string): Uint8Array {
|
|
|
54
54
|
const len = s.length;
|
|
55
55
|
const arr = new Uint8Array(len);
|
|
56
56
|
for (let i = 0; i < len; i++) {
|
|
57
|
-
arr[i] = s.charCodeAt(i) &
|
|
57
|
+
arr[i] = s.charCodeAt(i) & 0xff;
|
|
58
58
|
}
|
|
59
59
|
return arr;
|
|
60
60
|
}
|
|
@@ -79,8 +79,11 @@ function matchClass(c: number, cl: number): boolean {
|
|
|
79
79
|
res = c >= 97 && c <= 122;
|
|
80
80
|
break;
|
|
81
81
|
case 112: // 'p'
|
|
82
|
-
res =
|
|
83
|
-
(c >=
|
|
82
|
+
res =
|
|
83
|
+
(c >= 33 && c <= 47) ||
|
|
84
|
+
(c >= 58 && c <= 64) ||
|
|
85
|
+
(c >= 91 && c <= 96) ||
|
|
86
|
+
(c >= 123 && c <= 126);
|
|
84
87
|
break;
|
|
85
88
|
case 115: // 's'
|
|
86
89
|
res = c === 32 || (c >= 9 && c <= 13);
|
|
@@ -89,12 +92,12 @@ function matchClass(c: number, cl: number): boolean {
|
|
|
89
92
|
res = c >= 65 && c <= 90;
|
|
90
93
|
break;
|
|
91
94
|
case 119: // 'w'
|
|
92
|
-
res =
|
|
93
|
-
(c >= 48 && c <= 57);
|
|
95
|
+
res =
|
|
96
|
+
(c >= 65 && c <= 90) || (c >= 97 && c <= 122) || (c >= 48 && c <= 57);
|
|
94
97
|
break;
|
|
95
98
|
case 120: // 'x'
|
|
96
|
-
res =
|
|
97
|
-
(c >= 97 && c <= 102);
|
|
99
|
+
res =
|
|
100
|
+
(c >= 48 && c <= 57) || (c >= 65 && c <= 70) || (c >= 97 && c <= 102);
|
|
98
101
|
break;
|
|
99
102
|
case 122: // 'z'
|
|
100
103
|
res = c === 0;
|
|
@@ -102,7 +105,7 @@ function matchClass(c: number, cl: number): boolean {
|
|
|
102
105
|
default:
|
|
103
106
|
return cl === c;
|
|
104
107
|
}
|
|
105
|
-
return
|
|
108
|
+
return cl >= 97 && cl <= 122 ? res : !res;
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
function classEnd(p: Uint8Array, plen: number, pi: number): number {
|
|
@@ -150,9 +153,7 @@ function matchBracketClass(
|
|
|
150
153
|
if (pch === CH_ESC) {
|
|
151
154
|
pi++;
|
|
152
155
|
if (matchClass(c, p[pi])) return sig;
|
|
153
|
-
} else if (
|
|
154
|
-
pi + 2 < ec && p[pi + 1] === CH_DASH
|
|
155
|
-
) {
|
|
156
|
+
} else if (pi + 2 < ec && p[pi + 1] === CH_DASH) {
|
|
156
157
|
pi += 2;
|
|
157
158
|
if (pch <= c && c <= p[pi]) return sig;
|
|
158
159
|
} else if (pch === c) {
|
|
@@ -182,11 +183,7 @@ function singleMatch(
|
|
|
182
183
|
return pch === c;
|
|
183
184
|
}
|
|
184
185
|
|
|
185
|
-
function matchBalance(
|
|
186
|
-
ms: MatchState,
|
|
187
|
-
si: number,
|
|
188
|
-
pi: number,
|
|
189
|
-
): number {
|
|
186
|
+
function matchBalance(ms: MatchState, si: number, pi: number): number {
|
|
190
187
|
if (pi >= ms.plen - 1) {
|
|
191
188
|
throw new Error("malformed pattern (missing arguments to '%b')");
|
|
192
189
|
}
|
|
@@ -209,12 +206,7 @@ function matchBalance(
|
|
|
209
206
|
return -1;
|
|
210
207
|
}
|
|
211
208
|
|
|
212
|
-
function maxExpand(
|
|
213
|
-
ms: MatchState,
|
|
214
|
-
si: number,
|
|
215
|
-
pi: number,
|
|
216
|
-
ep: number,
|
|
217
|
-
): number {
|
|
209
|
+
function maxExpand(ms: MatchState, si: number, pi: number, ep: number): number {
|
|
218
210
|
let i = 0;
|
|
219
211
|
while (singleMatch(ms, si + i, pi, ep)) i++;
|
|
220
212
|
while (i >= 0) {
|
|
@@ -225,12 +217,7 @@ function maxExpand(
|
|
|
225
217
|
return -1;
|
|
226
218
|
}
|
|
227
219
|
|
|
228
|
-
function minExpand(
|
|
229
|
-
ms: MatchState,
|
|
230
|
-
si: number,
|
|
231
|
-
pi: number,
|
|
232
|
-
ep: number,
|
|
233
|
-
): number {
|
|
220
|
+
function minExpand(ms: MatchState, si: number, pi: number, ep: number): number {
|
|
234
221
|
for (;;) {
|
|
235
222
|
const res = match(ms, si, ep + 1);
|
|
236
223
|
if (res >= 0) return res;
|
|
@@ -326,7 +313,8 @@ function match(ms: MatchState, si: number, pi: number): number {
|
|
|
326
313
|
}
|
|
327
314
|
if (pch === CH_ESC && pi + 1 < ms.plen) {
|
|
328
315
|
const next = ms.p[pi + 1];
|
|
329
|
-
if (next === 98) {
|
|
316
|
+
if (next === 98) {
|
|
317
|
+
// 'b'
|
|
330
318
|
si = matchBalance(ms, si, pi + 2);
|
|
331
319
|
if (si >= 0) {
|
|
332
320
|
pi += 4;
|
|
@@ -335,7 +323,8 @@ function match(ms: MatchState, si: number, pi: number): number {
|
|
|
335
323
|
ms.matchdepth++;
|
|
336
324
|
return -1;
|
|
337
325
|
}
|
|
338
|
-
if (next === 102) {
|
|
326
|
+
if (next === 102) {
|
|
327
|
+
// 'f'
|
|
339
328
|
pi += 2;
|
|
340
329
|
if (pi >= ms.plen || ms.p[pi] !== CH_LBRACKET) {
|
|
341
330
|
throw new Error("missing '[' after '%f' in pattern");
|
|
@@ -370,7 +359,9 @@ function match(ms: MatchState, si: number, pi: number): number {
|
|
|
370
359
|
if (ep < ms.plen) {
|
|
371
360
|
const suffix = ms.p[ep];
|
|
372
361
|
if (
|
|
373
|
-
suffix === CH_STAR ||
|
|
362
|
+
suffix === CH_STAR ||
|
|
363
|
+
suffix === CH_QUESTION ||
|
|
364
|
+
suffix === CH_DASH
|
|
374
365
|
) {
|
|
375
366
|
pi = ep + 1;
|
|
376
367
|
continue;
|
|
@@ -614,10 +605,12 @@ function expandReplacementString(
|
|
|
614
605
|
} else if (rc === CH_0) {
|
|
615
606
|
parts.push(ms.src.substring(matchStart, matchEnd));
|
|
616
607
|
} else if (rc >= 49 && rc <= CH_9) {
|
|
617
|
-
parts.push(
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
608
|
+
parts.push(
|
|
609
|
+
getRawCaptureString(
|
|
610
|
+
ms,
|
|
611
|
+
getOneRawCapture(ms, rc - 49, matchStart, matchEnd),
|
|
612
|
+
),
|
|
613
|
+
);
|
|
621
614
|
} else {
|
|
622
615
|
throw new Error("invalid use of '%' in replacement string");
|
|
623
616
|
}
|
|
@@ -10,7 +10,7 @@ export class LuaPRNG {
|
|
|
10
10
|
|
|
11
11
|
private rotl(x: bigint, k: number): bigint {
|
|
12
12
|
k = k & 63;
|
|
13
|
-
return ((x << BigInt(k)) | (x >> BigInt(64 - k))) &
|
|
13
|
+
return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & 0xffffffffffffffffn;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
private nextrand(): bigint {
|
|
@@ -20,10 +20,11 @@ export class LuaPRNG {
|
|
|
20
20
|
const s2 = s[2];
|
|
21
21
|
const s3 = s[3];
|
|
22
22
|
|
|
23
|
-
const res =
|
|
24
|
-
|
|
23
|
+
const res =
|
|
24
|
+
(this.rotl((s1 * 5n) & 0xffffffffffffffffn, 7) * 9n) &
|
|
25
|
+
0xffffffffffffffffn;
|
|
25
26
|
|
|
26
|
-
const t = (s1 << 17n) &
|
|
27
|
+
const t = (s1 << 17n) & 0xffffffffffffffffn;
|
|
27
28
|
s[2] = s2 ^ s0;
|
|
28
29
|
s[3] = s3 ^ s1;
|
|
29
30
|
s[1] = s1 ^ s[2];
|
|
@@ -35,17 +36,17 @@ export class LuaPRNG {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
public setSeed(seed1: bigint, seed2: bigint = 0n): [bigint, bigint] {
|
|
38
|
-
const MASK =
|
|
39
|
+
const MASK = 0xffffffffffffffffn;
|
|
39
40
|
const s = this.state;
|
|
40
41
|
|
|
41
42
|
const sm64 = (x: bigint): bigint => {
|
|
42
|
-
x = (x ^ (x >> 30n)) *
|
|
43
|
-
x = (x ^ (x >> 27n)) *
|
|
43
|
+
x = ((x ^ (x >> 30n)) * 0xbf58476d1ce4e5b9n) & MASK;
|
|
44
|
+
x = ((x ^ (x >> 27n)) * 0x94d049bb133111ebn) & MASK;
|
|
44
45
|
return (x ^ (x >> 31n)) & MASK;
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
s[0] = sm64(seed1 & MASK);
|
|
48
|
-
s[1] = sm64((seed1 & MASK) |
|
|
49
|
+
s[1] = sm64((seed1 & MASK) | 0xffn);
|
|
49
50
|
s[2] = sm64(seed2 & MASK);
|
|
50
51
|
s[3] = sm64(0n);
|
|
51
52
|
|
|
@@ -101,9 +102,8 @@ export class LuaPRNG {
|
|
|
101
102
|
if (arg2 === undefined) {
|
|
102
103
|
if (arg1 === 0) {
|
|
103
104
|
// Raw 64-bit as signed bigint
|
|
104
|
-
const signed =
|
|
105
|
-
? rv - 0x10000000000000000n
|
|
106
|
-
: rv;
|
|
105
|
+
const signed =
|
|
106
|
+
rv > 0x7fffffffffffffffn ? rv - 0x10000000000000000n : rv;
|
|
107
107
|
return signed;
|
|
108
108
|
}
|
|
109
109
|
if (arg1 < 1) {
|
|
@@ -133,7 +133,10 @@ export class LuaPRNG {
|
|
|
133
133
|
"bad argument #1 to 'randomseed' (number has no integer representation)",
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
|
-
if (
|
|
136
|
+
if (
|
|
137
|
+
arg2 !== undefined &&
|
|
138
|
+
(!Number.isFinite(arg2) || !Number.isInteger(arg2))
|
|
139
|
+
) {
|
|
137
140
|
throw new Error(
|
|
138
141
|
"bad argument #2 to 'randomseed' (number has no integer representation)",
|
|
139
142
|
);
|
|
@@ -2,6 +2,7 @@ import { parseExpressionString } from "../parse.ts";
|
|
|
2
2
|
import type { LuaExpression } from "../ast.ts";
|
|
3
3
|
import { evalExpression } from "../eval.ts";
|
|
4
4
|
import {
|
|
5
|
+
jsToLuaValue,
|
|
5
6
|
LuaBuiltinFunction,
|
|
6
7
|
LuaEnv,
|
|
7
8
|
LuaRuntimeError,
|
|
@@ -11,6 +12,7 @@ import {
|
|
|
11
12
|
luaValueToJS,
|
|
12
13
|
singleResult,
|
|
13
14
|
} from "../runtime.ts";
|
|
15
|
+
import { isSqlNull } from "../liq_null.ts";
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* These are Space Lua specific functions that are available to all scripts, but are not part of the standard Lua language.
|
|
@@ -31,7 +33,8 @@ function createAugmentedEnv(
|
|
|
31
33
|
if (envAugmentation) {
|
|
32
34
|
env.setLocal("_", envAugmentation);
|
|
33
35
|
for (const key of envAugmentation.keys()) {
|
|
34
|
-
|
|
36
|
+
const v = envAugmentation.rawGet(key);
|
|
37
|
+
env.setLocal(key, isSqlNull(v) ? null : v);
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
return env;
|
|
@@ -89,10 +92,7 @@ export async function interpolateLuaString(
|
|
|
89
92
|
const luaResult = singleResult(await evalExpression(parsedExpr, env, sf));
|
|
90
93
|
result += await luaToString(luaResult);
|
|
91
94
|
} catch (e: any) {
|
|
92
|
-
throw new LuaRuntimeError(
|
|
93
|
-
`Error evaluating "${expr}": ${e.message}`,
|
|
94
|
-
sf,
|
|
95
|
-
);
|
|
95
|
+
throw new LuaRuntimeError(`Error evaluating "${expr}": ${e.message}`, sf);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
currentIndex = endIndex + 1;
|
|
@@ -109,11 +109,9 @@ export const spaceluaApi = new LuaTable({
|
|
|
109
109
|
* @param luaExpression - The lua expression to parse.
|
|
110
110
|
* @returns The parsed expression.
|
|
111
111
|
*/
|
|
112
|
-
parseExpression: new LuaBuiltinFunction(
|
|
113
|
-
(
|
|
114
|
-
|
|
115
|
-
},
|
|
116
|
-
),
|
|
112
|
+
parseExpression: new LuaBuiltinFunction((_sf, luaExpression: string) => {
|
|
113
|
+
return parseExpressionString(luaExpression);
|
|
114
|
+
}),
|
|
117
115
|
/**
|
|
118
116
|
* Evaluates a parsed lua expression and returns the result.
|
|
119
117
|
*
|
|
@@ -132,17 +130,18 @@ export const spaceluaApi = new LuaTable({
|
|
|
132
130
|
* Interpolates a string with lua expressions and returns the result.
|
|
133
131
|
*/
|
|
134
132
|
interpolate: new LuaBuiltinFunction(
|
|
135
|
-
(sf, template: string, envAugmentation?: LuaTable) => {
|
|
133
|
+
(sf, template: string, envAugmentation?: LuaTable | any) => {
|
|
134
|
+
if (envAugmentation && !(envAugmentation instanceof LuaTable)) {
|
|
135
|
+
envAugmentation = jsToLuaValue(envAugmentation);
|
|
136
|
+
}
|
|
136
137
|
return interpolateLuaString(sf, template, envAugmentation);
|
|
137
138
|
},
|
|
138
139
|
),
|
|
139
140
|
/**
|
|
140
141
|
* Returns your SilverBullet instance's base URL
|
|
141
142
|
*/
|
|
142
|
-
baseUrl: new LuaBuiltinFunction(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
},
|
|
147
|
-
),
|
|
143
|
+
baseUrl: new LuaBuiltinFunction(() => {
|
|
144
|
+
//NOTE: Removing trailing slash to stay compatible with original code: `location.protocol + "//" + location.host;`
|
|
145
|
+
return document.baseURI.replace(/\/*$/, "");
|
|
146
|
+
}),
|
|
148
147
|
});
|
|
@@ -24,9 +24,7 @@ function capturesToLua(caps: CaptureResult[]): any {
|
|
|
24
24
|
const c = caps[0];
|
|
25
25
|
return "s" in c ? c.s : c.position;
|
|
26
26
|
}
|
|
27
|
-
return new LuaMultiRes(
|
|
28
|
-
caps.map((c) => ("s" in c ? c.s : c.position)),
|
|
29
|
-
);
|
|
27
|
+
return new LuaMultiRes(caps.map((c) => ("s" in c ? c.s : c.position)));
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
export const stringApi = new LuaTable({
|
|
@@ -72,13 +70,7 @@ export const stringApi = new LuaTable({
|
|
|
72
70
|
},
|
|
73
71
|
),
|
|
74
72
|
gsub: new LuaBuiltinFunction(
|
|
75
|
-
async (
|
|
76
|
-
sf,
|
|
77
|
-
s: string,
|
|
78
|
-
pattern: string,
|
|
79
|
-
repl: any,
|
|
80
|
-
n?: number,
|
|
81
|
-
) => {
|
|
73
|
+
async (sf, s: string, pattern: string, repl: any, n?: number) => {
|
|
82
74
|
const callbacks: GsubCallbacks = {};
|
|
83
75
|
if (typeof repl === "string") {
|
|
84
76
|
callbacks.replString = repl;
|
|
@@ -121,13 +113,11 @@ export const stringApi = new LuaTable({
|
|
|
121
113
|
upper: new LuaBuiltinFunction((_sf, s: string) => {
|
|
122
114
|
return luaToString(s.toUpperCase());
|
|
123
115
|
}),
|
|
124
|
-
match: new LuaBuiltinFunction(
|
|
125
|
-
(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
},
|
|
130
|
-
),
|
|
116
|
+
match: new LuaBuiltinFunction((_sf, s: string, pattern: string, init = 1) => {
|
|
117
|
+
const caps = patternMatch(s, pattern, init);
|
|
118
|
+
if (!caps) return null;
|
|
119
|
+
return capturesToLua(caps);
|
|
120
|
+
}),
|
|
131
121
|
rep: new LuaBuiltinFunction((_sf, s: string, n: number, sep?: string) => {
|
|
132
122
|
if (n <= 0) return "";
|
|
133
123
|
sep = sep ?? "";
|
|
@@ -73,7 +73,8 @@ function getOption(
|
|
|
73
73
|
fmt: string,
|
|
74
74
|
pos: number,
|
|
75
75
|
h: Header,
|
|
76
|
-
): [KOption, number, number] {
|
|
76
|
+
): [KOption, number, number] {
|
|
77
|
+
// [opt, size, newPos]
|
|
77
78
|
const c = fmt[pos++];
|
|
78
79
|
switch (c) {
|
|
79
80
|
case "b":
|
|
@@ -171,7 +172,10 @@ function getDetails(
|
|
|
171
172
|
|
|
172
173
|
let ntoalign = 0;
|
|
173
174
|
if (
|
|
174
|
-
opt !== "char" &&
|
|
175
|
+
opt !== "char" &&
|
|
176
|
+
opt !== "nop" &&
|
|
177
|
+
opt !== "padding" &&
|
|
178
|
+
opt !== "paddalign"
|
|
175
179
|
) {
|
|
176
180
|
const realign = Math.min(align, h.maxalign);
|
|
177
181
|
if (realign > 0) {
|
|
@@ -381,7 +385,9 @@ export const strUnpackFn = new LuaBuiltinFunction(
|
|
|
381
385
|
|
|
382
386
|
if (opt.ntoalign + opt.size > buf.length - pos) {
|
|
383
387
|
if (
|
|
384
|
-
opt.opt !== "nop" &&
|
|
388
|
+
opt.opt !== "nop" &&
|
|
389
|
+
opt.opt !== "paddalign" &&
|
|
390
|
+
opt.opt !== "padding"
|
|
385
391
|
) {
|
|
386
392
|
throw new LuaRuntimeError("data string too short", sf);
|
|
387
393
|
}
|
|
@@ -464,23 +470,21 @@ export const strUnpackFn = new LuaBuiltinFunction(
|
|
|
464
470
|
},
|
|
465
471
|
);
|
|
466
472
|
|
|
467
|
-
export const strPackSizeFn = new LuaBuiltinFunction(
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
let pos = 0;
|
|
472
|
-
|
|
473
|
-
while (pos < fmt.length) {
|
|
474
|
-
let opt: ParsedOption;
|
|
475
|
-
[opt, pos] = getDetails(fmt, pos, h, totalsize);
|
|
473
|
+
export const strPackSizeFn = new LuaBuiltinFunction((_sf, fmt: string) => {
|
|
474
|
+
const h = makeHeader();
|
|
475
|
+
let totalsize = 0;
|
|
476
|
+
let pos = 0;
|
|
476
477
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
478
|
+
while (pos < fmt.length) {
|
|
479
|
+
let opt: ParsedOption;
|
|
480
|
+
[opt, pos] = getDetails(fmt, pos, h, totalsize);
|
|
480
481
|
|
|
481
|
-
|
|
482
|
+
if (opt.opt === "string" || opt.opt === "zstr") {
|
|
483
|
+
throw new LuaRuntimeError("variable-length format", _sf);
|
|
482
484
|
}
|
|
483
485
|
|
|
484
|
-
|
|
485
|
-
}
|
|
486
|
-
|
|
486
|
+
totalsize += opt.ntoalign + opt.size;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return totalsize;
|
|
490
|
+
});
|
|
@@ -84,9 +84,8 @@ export const tableApi = new LuaTable({
|
|
|
84
84
|
return luaFormatNumber(v.value, "float");
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
const ty =
|
|
88
|
-
? "table"
|
|
89
|
-
: typeof v;
|
|
87
|
+
const ty =
|
|
88
|
+
typeof v === "object" && v instanceof LuaTable ? "table" : typeof v;
|
|
90
89
|
throw new LuaRuntimeError(
|
|
91
90
|
`invalid value (${ty}) at index ${idx} in table for 'concat'`,
|
|
92
91
|
sf,
|
|
@@ -301,10 +300,7 @@ export const tableApi = new LuaTable({
|
|
|
301
300
|
|
|
302
301
|
const ta = typeof av;
|
|
303
302
|
const tb = typeof bv;
|
|
304
|
-
throw new LuaRuntimeError(
|
|
305
|
-
`attempt to compare ${ta} with ${tb}`,
|
|
306
|
-
sf,
|
|
307
|
-
);
|
|
303
|
+
throw new LuaRuntimeError(`attempt to compare ${ta} with ${tb}`, sf);
|
|
308
304
|
};
|
|
309
305
|
|
|
310
306
|
const sorted = await asyncQuickSort(values, cmp);
|
|
@@ -399,7 +395,7 @@ export const tableApi = new LuaTable({
|
|
|
399
395
|
for (let i = 0; i < n; i++) {
|
|
400
396
|
await luaSet(tbl, i + 1, args[i], sf);
|
|
401
397
|
}
|
|
402
|
-
tbl.rawSet("n", n);
|
|
398
|
+
void tbl.rawSet("n", n);
|
|
403
399
|
return tbl;
|
|
404
400
|
}),
|
|
405
401
|
|
|
@@ -410,7 +406,7 @@ export const tableApi = new LuaTable({
|
|
|
410
406
|
*/
|
|
411
407
|
unpack: new LuaBuiltinFunction(
|
|
412
408
|
async (sf, tbl: LuaTable | any[], i?: number, j?: number) => {
|
|
413
|
-
i =
|
|
409
|
+
i = i === undefined || i === null ? 1 : i;
|
|
414
410
|
if (j === undefined || j === null) {
|
|
415
411
|
j = Array.isArray(tbl)
|
|
416
412
|
? tbl.length
|
|
@@ -35,17 +35,15 @@ import { cryptoApi } from "./stdlib/crypto.ts";
|
|
|
35
35
|
import { netApi } from "./stdlib/net.ts";
|
|
36
36
|
import { isTaggedFloat, makeLuaFloat } from "./numeric.ts";
|
|
37
37
|
import { isPromise } from "./rp.ts";
|
|
38
|
+
import { isSqlNull } from "./liq_null.ts";
|
|
38
39
|
|
|
39
40
|
const printFunction = new LuaBuiltinFunction(async (_sf, ...args) => {
|
|
40
|
-
console.log(
|
|
41
|
-
"[Lua]",
|
|
42
|
-
...(await Promise.all(args.map((v) => luaToString(v)))),
|
|
43
|
-
);
|
|
41
|
+
console.log("[Lua]", ...(await Promise.all(args.map((v) => luaToString(v)))));
|
|
44
42
|
});
|
|
45
43
|
|
|
46
44
|
const assertFunction = new LuaBuiltinFunction(
|
|
47
45
|
async (sf, value: any, message?: string) => {
|
|
48
|
-
if (!await value) {
|
|
46
|
+
if (!(await value)) {
|
|
49
47
|
throw new LuaRuntimeError(`Assertion failed: ${message}`, sf);
|
|
50
48
|
}
|
|
51
49
|
},
|
|
@@ -143,10 +141,7 @@ const tostringFunction = new LuaBuiltinFunction(
|
|
|
143
141
|
const unwrap = (v: any): string => {
|
|
144
142
|
const s = singleResult(v);
|
|
145
143
|
if (typeof s !== "string") {
|
|
146
|
-
throw new LuaRuntimeError(
|
|
147
|
-
"'__tostring' must return a string",
|
|
148
|
-
sf,
|
|
149
|
-
);
|
|
144
|
+
throw new LuaRuntimeError("'__tostring' must return a string", sf);
|
|
150
145
|
}
|
|
151
146
|
return s;
|
|
152
147
|
};
|
|
@@ -203,10 +198,7 @@ async function pcallBoundary(
|
|
|
203
198
|
sf: LuaStackFrame,
|
|
204
199
|
fn: ILuaFunction,
|
|
205
200
|
args: LuaValue[],
|
|
206
|
-
): Promise<
|
|
207
|
-
| { ok: true; values: LuaValue[] }
|
|
208
|
-
| { ok: false; message: string }
|
|
209
|
-
> {
|
|
201
|
+
): Promise<{ ok: true; values: LuaValue[] } | { ok: false; message: string }> {
|
|
210
202
|
const closeStack = luaEnsureCloseStack(sf);
|
|
211
203
|
const mark = closeStack.length;
|
|
212
204
|
|
|
@@ -274,11 +266,9 @@ const setmetatableFunction = new LuaBuiltinFunction(
|
|
|
274
266
|
},
|
|
275
267
|
);
|
|
276
268
|
|
|
277
|
-
const rawlenFunction = new LuaBuiltinFunction(
|
|
278
|
-
(_sf,
|
|
279
|
-
|
|
280
|
-
},
|
|
281
|
-
);
|
|
269
|
+
const rawlenFunction = new LuaBuiltinFunction((_sf, value: LuaValue) => {
|
|
270
|
+
return luaLen(value, _sf, true);
|
|
271
|
+
});
|
|
282
272
|
|
|
283
273
|
const rawsetFunction = new LuaBuiltinFunction(
|
|
284
274
|
(_sf, table: LuaTable, key: LuaValue, value: LuaValue) => {
|
|
@@ -290,7 +280,8 @@ const rawgetFunction = new LuaBuiltinFunction(
|
|
|
290
280
|
(_sf, table: any, key: LuaValue) => {
|
|
291
281
|
const isArray = Array.isArray(table);
|
|
292
282
|
|
|
293
|
-
const isPlainObj =
|
|
283
|
+
const isPlainObj =
|
|
284
|
+
typeof table === "object" &&
|
|
294
285
|
table !== null &&
|
|
295
286
|
(table as any).constructor === Object;
|
|
296
287
|
|
|
@@ -320,7 +311,7 @@ const rawgetFunction = new LuaBuiltinFunction(
|
|
|
320
311
|
|
|
321
312
|
if (isLuaTable(table)) {
|
|
322
313
|
const v = table.rawGet(key);
|
|
323
|
-
return v === undefined ? null : v;
|
|
314
|
+
return v === undefined || isSqlNull(v) ? null : v;
|
|
324
315
|
}
|
|
325
316
|
|
|
326
317
|
const k = isTaggedFloat(key) ? key.value : key;
|
|
@@ -339,13 +330,11 @@ const rawgetFunction = new LuaBuiltinFunction(
|
|
|
339
330
|
},
|
|
340
331
|
);
|
|
341
332
|
|
|
342
|
-
const rawequalFunction = new LuaBuiltinFunction(
|
|
343
|
-
(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
},
|
|
348
|
-
);
|
|
333
|
+
const rawequalFunction = new LuaBuiltinFunction((_sf, a: any, b: any) => {
|
|
334
|
+
const av = isTaggedFloat(a) ? a.value : a;
|
|
335
|
+
const bv = isTaggedFloat(b) ? b.value : b;
|
|
336
|
+
return av === bv;
|
|
337
|
+
});
|
|
349
338
|
|
|
350
339
|
const getmetatableFunction = new LuaBuiltinFunction((_sf, table: LuaTable) => {
|
|
351
340
|
return (table as any).metatable;
|
|
@@ -353,12 +342,12 @@ const getmetatableFunction = new LuaBuiltinFunction((_sf, table: LuaTable) => {
|
|
|
353
342
|
|
|
354
343
|
const dofileFunction = new LuaBuiltinFunction(async (sf, filename: string) => {
|
|
355
344
|
const global = sf.threadLocal.get("_GLOBAL") as LuaEnv;
|
|
356
|
-
const file = await luaCall(
|
|
345
|
+
const file = (await luaCall(
|
|
357
346
|
(global.get("space") as any).get("readFile"),
|
|
358
347
|
[filename],
|
|
359
348
|
sf.astCtx!,
|
|
360
349
|
sf,
|
|
361
|
-
) as Uint8Array;
|
|
350
|
+
)) as Uint8Array;
|
|
362
351
|
const code = new TextDecoder().decode(file);
|
|
363
352
|
try {
|
|
364
353
|
const parsedExpr = parse(code);
|
|
@@ -434,7 +423,8 @@ const nextFunction = new LuaBuiltinFunction(
|
|
|
434
423
|
}
|
|
435
424
|
// Find index in the key list
|
|
436
425
|
const idx = keys.indexOf(index);
|
|
437
|
-
if (idx === -1) {
|
|
426
|
+
if (idx === -1) {
|
|
427
|
+
// Not found
|
|
438
428
|
throw new LuaRuntimeError("invalid key to 'next': key not found", sf);
|
|
439
429
|
}
|
|
440
430
|
const key = keys[idx + 1];
|