@sanbus/galley-bun 0.0.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 +8 -0
- package/build.mjs +85 -0
- package/dist/dispatch.d.ts +15 -0
- package/dist/dispatch.js +135 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/ffi.d.ts +255 -0
- package/dist/ffi.js +794 -0
- package/dist/ffi.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/session.d.ts +13 -0
- package/dist/session.js +23 -0
- package/dist/session.js.map +1 -0
- package/package.json +49 -0
- package/src/dispatch.ts +146 -0
- package/src/ffi.ts +1036 -0
- package/src/index.ts +79 -0
- package/src/session.ts +26 -0
package/src/ffi.ts
ADDED
|
@@ -0,0 +1,1036 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun adapter for the Galley JavaScript bindings: `bun:ffi` bindings over
|
|
3
|
+
* `bindings/c/galley.h`, implementing the core `FfiPort`.
|
|
4
|
+
*
|
|
5
|
+
* Zero npm dependencies: `bun:ffi` is built into the runtime. The core
|
|
6
|
+
* (`@sanbus/galley-core`) owns all session logic; memory copying and integer
|
|
7
|
+
* normalization live here. Library discovery mirrors the Node adapter.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Buffer } from "node:buffer";
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import process from "node:process";
|
|
14
|
+
import { dlopen, FFIType, ptr, toArrayBuffer, CString } from "bun:ffi";
|
|
15
|
+
import type { FfiPort, Handle, SessionCOptions, TreeSnapshot, WalkedStep } from "@sanbus/galley-core";
|
|
16
|
+
import { GalleyError, resolveArtifact, artifactFileName } from "@sanbus/galley-core";
|
|
17
|
+
|
|
18
|
+
/** Native handles are addresses; 0 is null. */
|
|
19
|
+
type NativeHandle = number;
|
|
20
|
+
|
|
21
|
+
/** Callable view of the native symbols (see `BASE_SYMBOLS` below). */
|
|
22
|
+
interface GalleySymbols {
|
|
23
|
+
galley_version(): string;
|
|
24
|
+
galley_parser_type(): bigint;
|
|
25
|
+
galley_error_recovery_mode(): bigint;
|
|
26
|
+
galley_has_ast(): number;
|
|
27
|
+
galley_has_procedures(): number;
|
|
28
|
+
galley_allows_no_ast_tree_procedures(): number;
|
|
29
|
+
galley_source_retention_enabled(): number;
|
|
30
|
+
galley_has_position_tracking(): number;
|
|
31
|
+
galley_has_input_streaming(): number;
|
|
32
|
+
galley_uses_verbatim(): number;
|
|
33
|
+
galley_stack_overflow_recovery_available(): number;
|
|
34
|
+
galley_symbol_count(): bigint;
|
|
35
|
+
galley_variable_count(): bigint;
|
|
36
|
+
galley_status_string(status: bigint): string;
|
|
37
|
+
galley_symbol_name(session: NativeHandle, index: bigint, outData: number, outLen: number): bigint;
|
|
38
|
+
galley_symbol_is_terminal(session: NativeHandle, index: bigint): number;
|
|
39
|
+
galley_variable_name(session: NativeHandle, index: bigint, outData: number, outLen: number): bigint;
|
|
40
|
+
galley_session_create(): NativeHandle;
|
|
41
|
+
galley_session_create_ex(options: number): NativeHandle;
|
|
42
|
+
galley_session_destroy(session: NativeHandle): void;
|
|
43
|
+
galley_session_set_message_override(session: NativeHandle, name: number, nameLen: bigint, message: number, messageLen: bigint): bigint;
|
|
44
|
+
galley_parse(session: NativeHandle, data: number, len: bigint): bigint;
|
|
45
|
+
galley_parse_file(session: NativeHandle, path: number): bigint;
|
|
46
|
+
galley_last_position(session: NativeHandle, outLine: number, outCol: number): bigint;
|
|
47
|
+
galley_node_count(session: NativeHandle): bigint;
|
|
48
|
+
galley_reserve_nodes(session: NativeHandle, capacity: bigint): bigint;
|
|
49
|
+
galley_node_capacity(session: NativeHandle): bigint;
|
|
50
|
+
galley_root_node(session: NativeHandle): bigint;
|
|
51
|
+
galley_node_is_valid(session: NativeHandle, node: bigint): number;
|
|
52
|
+
galley_node_child_count(session: NativeHandle, node: bigint): number;
|
|
53
|
+
galley_node_first_child(session: NativeHandle, node: bigint): bigint;
|
|
54
|
+
galley_node_last_child(session: NativeHandle, node: bigint): bigint;
|
|
55
|
+
galley_node_next_sibling(session: NativeHandle, node: bigint): bigint;
|
|
56
|
+
galley_node_prior_sibling(session: NativeHandle, node: bigint): bigint;
|
|
57
|
+
galley_node_parent(session: NativeHandle, node: bigint): bigint;
|
|
58
|
+
galley_tree_snapshot(
|
|
59
|
+
session: NativeHandle,
|
|
60
|
+
outParent: number,
|
|
61
|
+
outFirstChild: number,
|
|
62
|
+
outNext: number,
|
|
63
|
+
outChildCount: number,
|
|
64
|
+
outVariable: number,
|
|
65
|
+
outSpanStart: number,
|
|
66
|
+
outSpanLen: number,
|
|
67
|
+
capacity: bigint,
|
|
68
|
+
): bigint;
|
|
69
|
+
galley_walker_create(session: NativeHandle, node: bigint, skipSemanticErrors: number): NativeHandle;
|
|
70
|
+
galley_walker_next(walker: NativeHandle, outNode: number, outDepth: number, outFlag: number): number;
|
|
71
|
+
galley_walker_skip_children(walker: NativeHandle): void;
|
|
72
|
+
galley_walker_destroy(walker: NativeHandle): void;
|
|
73
|
+
galley_node_span(session: NativeHandle, node: bigint, outStart: number, outLen: number): bigint;
|
|
74
|
+
galley_node_symbol_name(session: NativeHandle, node: bigint, outData: number, outLen: number): bigint;
|
|
75
|
+
galley_node_variable_index(session: NativeHandle, node: bigint): bigint;
|
|
76
|
+
galley_node_text(session: NativeHandle, node: bigint, outData: number, outLen: number): bigint;
|
|
77
|
+
galley_node_line_column(session: NativeHandle, node: bigint, outLine: number, outCol: number): bigint;
|
|
78
|
+
galley_has_diagnostic(session: NativeHandle): number;
|
|
79
|
+
galley_diagnostic_kind(session: NativeHandle): bigint;
|
|
80
|
+
galley_diagnostic_message(session: NativeHandle, out: number): bigint;
|
|
81
|
+
galley_diagnostic_message_ansi(session: NativeHandle, out: number): bigint;
|
|
82
|
+
galley_diagnostic_position(session: NativeHandle, outLine: number, outCol: number): bigint;
|
|
83
|
+
galley_diagnostic_unexpected_token(session: NativeHandle, outData: number, outLen: number): bigint;
|
|
84
|
+
galley_diagnostic_expected_count(session: NativeHandle): bigint;
|
|
85
|
+
galley_diagnostic_expected_at(session: NativeHandle, index: bigint, outData: number, outLen: number): bigint;
|
|
86
|
+
galley_diagnostic_context_count(session: NativeHandle): bigint;
|
|
87
|
+
galley_diagnostic_context_at(session: NativeHandle, index: bigint, outData: number, outLen: number): bigint;
|
|
88
|
+
galley_diagnostic_indentation(session: NativeHandle, outSpaces: number, outWidth: number): bigint;
|
|
89
|
+
galley_syntax_error_count(session: NativeHandle): bigint;
|
|
90
|
+
galley_semantic_error_count(session: NativeHandle): bigint;
|
|
91
|
+
galley_diagnostic_semantic(session: NativeHandle, outVariable: number, outVariableLen: number, outMessage: number, outMessageLen: number): bigint;
|
|
92
|
+
galley_diagnostic_recovery_kind(session: NativeHandle): bigint;
|
|
93
|
+
galley_diagnostic_recovery_terminal(session: NativeHandle, outData: number, outLen: number): bigint;
|
|
94
|
+
galley_diagnostic_recovery_resume(session: NativeHandle, out: number): bigint;
|
|
95
|
+
galley_diagnostic_recovery_lhs_variable(session: NativeHandle, outData: number, outLen: number): bigint;
|
|
96
|
+
galley_diagnostic_recovery_production(session: NativeHandle, outVar: number, outLen: number, outIdx: number): bigint;
|
|
97
|
+
galley_diagnostic_recovery_occurrence(session: NativeHandle, outParent: number, outParentLen: number, outRhs: number, outSym: number, outVar: number, outVarLen: number): bigint;
|
|
98
|
+
galley_recorded_diagnostic_count(session: NativeHandle): bigint;
|
|
99
|
+
galley_recorded_diagnostic_kind(session: NativeHandle, diagIndex: bigint): bigint;
|
|
100
|
+
galley_recorded_diagnostic_position(session: NativeHandle, diagIndex: bigint, outLine: number, outCol: number): bigint;
|
|
101
|
+
galley_recorded_unexpected_token(session: NativeHandle, diagIndex: bigint, outData: number, outLen: number): bigint;
|
|
102
|
+
galley_recorded_diagnostic_message(session: NativeHandle, diagIndex: bigint, out: number): bigint;
|
|
103
|
+
galley_recorded_indentation(session: NativeHandle, diagIndex: bigint, outSpaces: number, outWidth: number): bigint;
|
|
104
|
+
galley_recorded_semantic(session: NativeHandle, diagIndex: bigint, outVariable: number, outVariableLen: number, outMessage: number, outMessageLen: number): bigint;
|
|
105
|
+
galley_recorded_expected_count(session: NativeHandle, diagIndex: bigint): bigint;
|
|
106
|
+
galley_recorded_expected_token(session: NativeHandle, diagIndex: bigint, tokenIndex: bigint, outData: number, outLen: number): bigint;
|
|
107
|
+
galley_recorded_context_count(session: NativeHandle, diagIndex: bigint): bigint;
|
|
108
|
+
galley_recorded_context_name(session: NativeHandle, diagIndex: bigint, ctxIndex: bigint, outData: number, outLen: number): bigint;
|
|
109
|
+
// NB: the implementation exports galley_recorded_diagnostic_recovery_kind
|
|
110
|
+
// (the header's shorter name is stale); bun has no symbol remapping, so
|
|
111
|
+
// the table and this interface use the true name.
|
|
112
|
+
galley_recorded_diagnostic_recovery_kind(session: NativeHandle, diagIndex: bigint): bigint;
|
|
113
|
+
galley_recorded_recovery_terminal(session: NativeHandle, diagIndex: bigint, outData: number, outLen: number): bigint;
|
|
114
|
+
galley_recorded_recovery_resume(session: NativeHandle, diagIndex: bigint, out: number): bigint;
|
|
115
|
+
galley_recorded_recovery_lhs_variable(session: NativeHandle, diagIndex: bigint, outData: number, outLen: number): bigint;
|
|
116
|
+
galley_recorded_recovery_production(session: NativeHandle, diagIndex: bigint, outVar: number, outLen: number, outIdx: number): bigint;
|
|
117
|
+
galley_recorded_recovery_occurrence(session: NativeHandle, diagIndex: bigint, outParent: number, outParentLen: number, outRhs: number, outSym: number, outVar: number, outVarLen: number): bigint;
|
|
118
|
+
galley_tree_append_children(session: NativeHandle, parent: bigint, first: bigint): bigint;
|
|
119
|
+
galley_tree_insert_before(session: NativeHandle, target: bigint, first: bigint): bigint;
|
|
120
|
+
galley_tree_insert_after(session: NativeHandle, target: bigint, first: bigint): bigint;
|
|
121
|
+
galley_tree_remove_siblings(session: NativeHandle, node: bigint, count: bigint, outHead: number): bigint;
|
|
122
|
+
galley_tree_remove_self(session: NativeHandle, node: bigint, outHead: number): bigint;
|
|
123
|
+
galley_tree_promote_children_over_wrapper(session: NativeHandle, wrapper: bigint, outHead: number): bigint;
|
|
124
|
+
galley_tree_clean_children(session: NativeHandle, node: bigint, outHead: number): bigint;
|
|
125
|
+
galley_tree_unlink_wrapper(session: NativeHandle, wrapper: bigint): bigint;
|
|
126
|
+
galley_tree_insert_children_at(session: NativeHandle, parent: bigint, index: bigint, first: bigint): bigint;
|
|
127
|
+
galley_tree_remove_children_at(session: NativeHandle, parent: bigint, index: bigint, count: bigint, outHead: number): bigint;
|
|
128
|
+
galley_procedure_session(args: NativeHandle): NativeHandle;
|
|
129
|
+
galley_procedure_current_node(args: NativeHandle): bigint;
|
|
130
|
+
galley_procedure_set_current_node(args: NativeHandle, node: bigint): void;
|
|
131
|
+
galley_procedure_drop_self(args: NativeHandle): bigint;
|
|
132
|
+
galley_procedure_drop_children(args: NativeHandle): bigint;
|
|
133
|
+
galley_procedure_drop_if_empty(args: NativeHandle): bigint;
|
|
134
|
+
galley_procedure_replace_with_children(args: NativeHandle): bigint;
|
|
135
|
+
galley_procedure_context_line(args: NativeHandle): number;
|
|
136
|
+
galley_procedure_context_column(args: NativeHandle): number;
|
|
137
|
+
galley_procedure_report_semantic_error(args: NativeHandle, message: number, messageLen: bigint): bigint;
|
|
138
|
+
galley_install_js_dispatch(callback: NativeHandle): void;
|
|
139
|
+
galley_install_js_dispatch_id?(callback: NativeHandle): void;
|
|
140
|
+
galley_js_procedure_count?(): number;
|
|
141
|
+
galley_js_procedure_name_ptr?(index: number): bigint;
|
|
142
|
+
galley_js_procedure_name_len?(index: number): bigint;
|
|
143
|
+
galley_js_procedure_enable?(name: number, nameLen: bigint): number;
|
|
144
|
+
galley_js_procedure_clear?(): void;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// --- library discovery -------------------------------------------------
|
|
148
|
+
// One place, named up front: an explicit path or GALLEY_LIBRARY_PATH.
|
|
149
|
+
// Anything else is a loud error, never a search.
|
|
150
|
+
|
|
151
|
+
const BUILD_HINT =
|
|
152
|
+
`Build it first: bunx galley-js-bun <language-dir>\n` +
|
|
153
|
+
`or set GALLEY_LIBRARY_PATH=/path/to/${libFileName()}`;
|
|
154
|
+
|
|
155
|
+
export function libFileName(base = "galley-js-bun"): string {
|
|
156
|
+
return artifactFileName(base, process.platform);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function exists(candidate: string): boolean {
|
|
160
|
+
try {
|
|
161
|
+
fs.accessSync(candidate);
|
|
162
|
+
return true;
|
|
163
|
+
} catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function findLibrary(explicit?: string): string {
|
|
169
|
+
return resolveArtifact(explicit, {
|
|
170
|
+
getEnv: (name) => process.env[name],
|
|
171
|
+
resolvePath: (candidate) => path.resolve(candidate),
|
|
172
|
+
existsSync: exists,
|
|
173
|
+
buildHint: BUILD_HINT,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// --- loader ------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
const BASE_SYMBOLS = {
|
|
180
|
+
galley_version: { args: [], returns: FFIType.cstring },
|
|
181
|
+
galley_parser_type: { args: [], returns: FFIType.i64 },
|
|
182
|
+
galley_error_recovery_mode: { args: [], returns: FFIType.i64 },
|
|
183
|
+
galley_has_ast: { args: [], returns: FFIType.i32 },
|
|
184
|
+
galley_has_procedures: { args: [], returns: FFIType.i32 },
|
|
185
|
+
galley_allows_no_ast_tree_procedures: { args: [], returns: FFIType.i32 },
|
|
186
|
+
galley_source_retention_enabled: { args: [], returns: FFIType.i32 },
|
|
187
|
+
galley_has_position_tracking: { args: [], returns: FFIType.i32 },
|
|
188
|
+
galley_has_input_streaming: { args: [], returns: FFIType.i32 },
|
|
189
|
+
galley_uses_verbatim: { args: [], returns: FFIType.i32 },
|
|
190
|
+
galley_stack_overflow_recovery_available: { args: [], returns: FFIType.i32 },
|
|
191
|
+
galley_symbol_count: { args: [], returns: FFIType.u64 },
|
|
192
|
+
galley_variable_count: { args: [], returns: FFIType.u64 },
|
|
193
|
+
galley_status_string: { args: [FFIType.i64], returns: FFIType.cstring },
|
|
194
|
+
galley_symbol_name: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
195
|
+
galley_symbol_is_terminal: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
|
|
196
|
+
galley_variable_name: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
197
|
+
galley_session_create: { args: [], returns: FFIType.ptr },
|
|
198
|
+
galley_session_create_ex: { args: [FFIType.ptr], returns: FFIType.ptr },
|
|
199
|
+
galley_session_destroy: { args: [FFIType.ptr], returns: FFIType.void },
|
|
200
|
+
galley_session_set_message_override: { args: [FFIType.ptr, FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
201
|
+
galley_parse: { args: [FFIType.ptr, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
202
|
+
galley_parse_file: { args: [FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
203
|
+
galley_last_position: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
204
|
+
galley_node_count: { args: [FFIType.ptr], returns: FFIType.u64 },
|
|
205
|
+
galley_reserve_nodes: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
206
|
+
galley_node_capacity: { args: [FFIType.ptr], returns: FFIType.u64 },
|
|
207
|
+
galley_root_node: { args: [FFIType.ptr], returns: FFIType.u64 },
|
|
208
|
+
galley_node_is_valid: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
|
|
209
|
+
galley_node_child_count: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.u32 },
|
|
210
|
+
galley_node_first_child: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.u64 },
|
|
211
|
+
galley_node_last_child: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.u64 },
|
|
212
|
+
galley_node_next_sibling: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.u64 },
|
|
213
|
+
galley_node_prior_sibling: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.u64 },
|
|
214
|
+
galley_node_parent: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.u64 },
|
|
215
|
+
galley_tree_snapshot: {
|
|
216
|
+
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.u64],
|
|
217
|
+
returns: FFIType.i64,
|
|
218
|
+
},
|
|
219
|
+
galley_walker_create: { args: [FFIType.ptr, FFIType.u64, FFIType.i32], returns: FFIType.ptr },
|
|
220
|
+
galley_walker_next: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i32 },
|
|
221
|
+
galley_walker_skip_children: { args: [FFIType.ptr], returns: FFIType.void },
|
|
222
|
+
galley_walker_destroy: { args: [FFIType.ptr], returns: FFIType.void },
|
|
223
|
+
galley_node_span: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
224
|
+
galley_node_symbol_name: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
225
|
+
galley_node_variable_index: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
226
|
+
galley_node_text: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
227
|
+
galley_node_line_column: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
228
|
+
galley_has_diagnostic: { args: [FFIType.ptr], returns: FFIType.i32 },
|
|
229
|
+
galley_diagnostic_kind: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
230
|
+
galley_diagnostic_message: { args: [FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
231
|
+
galley_diagnostic_message_ansi: { args: [FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
232
|
+
galley_diagnostic_position: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
233
|
+
galley_diagnostic_unexpected_token: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
234
|
+
galley_diagnostic_expected_count: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
235
|
+
galley_diagnostic_expected_at: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
236
|
+
galley_diagnostic_context_count: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
237
|
+
galley_diagnostic_context_at: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
238
|
+
galley_diagnostic_indentation: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
239
|
+
galley_syntax_error_count: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
240
|
+
galley_semantic_error_count: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
241
|
+
galley_diagnostic_semantic: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
242
|
+
galley_diagnostic_recovery_kind: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
243
|
+
galley_diagnostic_recovery_terminal: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
244
|
+
galley_diagnostic_recovery_resume: { args: [FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
245
|
+
galley_diagnostic_recovery_lhs_variable: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
246
|
+
galley_diagnostic_recovery_production: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
247
|
+
galley_diagnostic_recovery_occurrence: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
248
|
+
galley_recorded_diagnostic_count: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
249
|
+
galley_recorded_diagnostic_kind: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
250
|
+
galley_recorded_diagnostic_position: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
251
|
+
galley_recorded_unexpected_token: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
252
|
+
galley_recorded_diagnostic_message: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
253
|
+
galley_recorded_indentation: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
254
|
+
galley_recorded_semantic: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
255
|
+
galley_recorded_expected_count: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
256
|
+
galley_recorded_expected_token: { args: [FFIType.ptr, FFIType.u64, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
257
|
+
galley_recorded_context_count: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
258
|
+
galley_recorded_context_name: { args: [FFIType.ptr, FFIType.u64, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
259
|
+
galley_recorded_diagnostic_recovery_kind: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
260
|
+
galley_recorded_recovery_terminal: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
261
|
+
galley_recorded_recovery_resume: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
262
|
+
galley_recorded_recovery_lhs_variable: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
263
|
+
galley_recorded_recovery_production: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
264
|
+
galley_recorded_recovery_occurrence: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i64 },
|
|
265
|
+
galley_tree_append_children: { args: [FFIType.ptr, FFIType.u64, FFIType.u64], returns: FFIType.i64 },
|
|
266
|
+
galley_tree_insert_before: { args: [FFIType.ptr, FFIType.u64, FFIType.u64], returns: FFIType.i64 },
|
|
267
|
+
galley_tree_insert_after: { args: [FFIType.ptr, FFIType.u64, FFIType.u64], returns: FFIType.i64 },
|
|
268
|
+
galley_tree_remove_siblings: { args: [FFIType.ptr, FFIType.u64, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
269
|
+
galley_tree_remove_self: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
270
|
+
galley_tree_promote_children_over_wrapper: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
271
|
+
galley_tree_clean_children: { args: [FFIType.ptr, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
272
|
+
galley_tree_unlink_wrapper: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
273
|
+
galley_tree_insert_children_at: { args: [FFIType.ptr, FFIType.u64, FFIType.u64, FFIType.u64], returns: FFIType.i64 },
|
|
274
|
+
galley_tree_remove_children_at: { args: [FFIType.ptr, FFIType.u64, FFIType.u64, FFIType.u64, FFIType.ptr], returns: FFIType.i64 },
|
|
275
|
+
galley_procedure_session: { args: [FFIType.ptr], returns: FFIType.ptr },
|
|
276
|
+
galley_procedure_current_node: { args: [FFIType.ptr], returns: FFIType.u64 },
|
|
277
|
+
galley_procedure_set_current_node: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.void },
|
|
278
|
+
galley_procedure_drop_self: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
279
|
+
galley_procedure_drop_children: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
280
|
+
galley_procedure_drop_if_empty: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
281
|
+
galley_procedure_replace_with_children: { args: [FFIType.ptr], returns: FFIType.i64 },
|
|
282
|
+
galley_procedure_context_line: { args: [FFIType.ptr], returns: FFIType.u32 },
|
|
283
|
+
galley_procedure_context_column: { args: [FFIType.ptr], returns: FFIType.u32 },
|
|
284
|
+
galley_procedure_report_semantic_error: { args: [FFIType.ptr, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
|
|
285
|
+
} as const;
|
|
286
|
+
|
|
287
|
+
const DISPATCH_SYMBOL = {
|
|
288
|
+
galley_install_js_dispatch: { args: [FFIType.function], returns: FFIType.void },
|
|
289
|
+
} as const;
|
|
290
|
+
|
|
291
|
+
const ID_DISPATCH_SYMBOL = {
|
|
292
|
+
galley_install_js_dispatch_id: { args: [FFIType.function], returns: FFIType.void },
|
|
293
|
+
galley_js_procedure_count: { args: [], returns: FFIType.u32 },
|
|
294
|
+
galley_js_procedure_name_ptr: { args: [FFIType.u32], returns: FFIType.ptr },
|
|
295
|
+
galley_js_procedure_name_len: { args: [FFIType.u32], returns: FFIType.u64 },
|
|
296
|
+
} as const;
|
|
297
|
+
|
|
298
|
+
const SELECTIVE_SYMBOL = {
|
|
299
|
+
galley_js_procedure_enable: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
|
|
300
|
+
galley_js_procedure_clear: { args: [], returns: FFIType.void },
|
|
301
|
+
} as const;
|
|
302
|
+
|
|
303
|
+
function openNative(libPath: string, level: number): { symbols: GalleySymbols } {
|
|
304
|
+
const table =
|
|
305
|
+
level >= 3
|
|
306
|
+
? { ...BASE_SYMBOLS, ...ID_DISPATCH_SYMBOL, ...SELECTIVE_SYMBOL }
|
|
307
|
+
: level >= 2
|
|
308
|
+
? { ...BASE_SYMBOLS, ...DISPATCH_SYMBOL, ...SELECTIVE_SYMBOL }
|
|
309
|
+
: level >= 1
|
|
310
|
+
? { ...BASE_SYMBOLS, ...DISPATCH_SYMBOL }
|
|
311
|
+
: BASE_SYMBOLS;
|
|
312
|
+
return dlopen(libPath, table) as unknown as { symbols: GalleySymbols };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// --- read helpers ----------------------------------------------------------
|
|
316
|
+
|
|
317
|
+
/** Copy (addr,len) into a Uint8Array owning its bytes. */
|
|
318
|
+
export function readBytes(addr: bigint, len: bigint): Uint8Array {
|
|
319
|
+
if (addr === 0n || len === 0n) return new Uint8Array(0);
|
|
320
|
+
const view = toArrayBuffer(Number(addr), 0, Number(len)) as ArrayBuffer;
|
|
321
|
+
return new Uint8Array(view.slice(0));
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export function readCString(addr: bigint): string {
|
|
325
|
+
return String(new CString(Number(addr)));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function ptrOut64(): BigUint64Array {
|
|
329
|
+
return new BigUint64Array(1);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function u32Out(): Uint32Array {
|
|
333
|
+
return new Uint32Array(1);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function i64Out(): BigInt64Array {
|
|
337
|
+
return new BigInt64Array(1);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// --- FfiPort implementation ----------------------------------------------
|
|
341
|
+
|
|
342
|
+
export class BunPort implements FfiPort {
|
|
343
|
+
readonly native: GalleySymbols;
|
|
344
|
+
readonly libraryPath: string;
|
|
345
|
+
readonly supportsDispatch: boolean;
|
|
346
|
+
|
|
347
|
+
constructor(native: GalleySymbols, libraryPath: string, supportsDispatch: boolean) {
|
|
348
|
+
this.native = native;
|
|
349
|
+
this.libraryPath = libraryPath;
|
|
350
|
+
this.supportsDispatch = supportsDispatch;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
syncProcedures(names: string[]): void {
|
|
354
|
+
if (typeof this.native.galley_js_procedure_clear !== "function") return;
|
|
355
|
+
if (typeof this.native.galley_js_procedure_enable !== "function") return;
|
|
356
|
+
this.native.galley_js_procedure_clear();
|
|
357
|
+
const encoder = new TextEncoder();
|
|
358
|
+
for (const name of names) {
|
|
359
|
+
const bytes = encoder.encode(name);
|
|
360
|
+
this.native.galley_js_procedure_enable(ptr(bytes), BigInt(bytes.length));
|
|
361
|
+
}
|
|
362
|
+
// Warm the ID table outside any parse so the hot path never queries.
|
|
363
|
+
this.procedureNames();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
#procedureNameTable: string[] | null = null;
|
|
367
|
+
|
|
368
|
+
procedureNames(): string[] {
|
|
369
|
+
if (this.#procedureNameTable !== null) return this.#procedureNameTable;
|
|
370
|
+
const table: string[] = [];
|
|
371
|
+
if (
|
|
372
|
+
typeof this.native.galley_js_procedure_count === "function" &&
|
|
373
|
+
typeof this.native.galley_js_procedure_name_ptr === "function" &&
|
|
374
|
+
typeof this.native.galley_js_procedure_name_len === "function"
|
|
375
|
+
) {
|
|
376
|
+
const decoder = new TextDecoder();
|
|
377
|
+
const n = this.native.galley_js_procedure_count();
|
|
378
|
+
for (let i = 0; i < n; i++) {
|
|
379
|
+
const ptrValue = this.native.galley_js_procedure_name_ptr(i);
|
|
380
|
+
if (ptrValue === 0n) break;
|
|
381
|
+
const len = this.native.galley_js_procedure_name_len(i);
|
|
382
|
+
table.push(decoder.decode(readBytes(ptrValue, len)));
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
this.#procedureNameTable = table;
|
|
386
|
+
return table;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// -- module-level queries --------------------------------------------
|
|
390
|
+
|
|
391
|
+
version(): string {
|
|
392
|
+
return String(this.native.galley_version());
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
parserType(): number {
|
|
396
|
+
return Number(this.native.galley_parser_type());
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
errorRecoveryMode(): number {
|
|
400
|
+
return Number(this.native.galley_error_recovery_mode());
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
hasAst(): boolean {
|
|
404
|
+
return this.native.galley_has_ast() !== 0;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
hasProcedures(): boolean {
|
|
408
|
+
return this.native.galley_has_procedures() !== 0;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
allowsNoAstTreeProcedures(): boolean {
|
|
412
|
+
return this.native.galley_allows_no_ast_tree_procedures() !== 0;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
sourceRetentionEnabled(): boolean {
|
|
416
|
+
return this.native.galley_source_retention_enabled() !== 0;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
hasPositionTracking(): boolean {
|
|
420
|
+
return this.native.galley_has_position_tracking() !== 0;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
hasInputStreaming(): boolean {
|
|
424
|
+
return this.native.galley_has_input_streaming() !== 0;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
usesVerbatim(): boolean {
|
|
428
|
+
return this.native.galley_uses_verbatim() !== 0;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
stackOverflowRecoveryAvailable(): boolean {
|
|
432
|
+
return this.native.galley_stack_overflow_recovery_available() !== 0;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
symbolCount(): number {
|
|
436
|
+
return Number(this.native.galley_symbol_count());
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
variableCount(): number {
|
|
440
|
+
return Number(this.native.galley_variable_count());
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
statusString(status: number): string | null {
|
|
444
|
+
// Native returns NULL for unknown codes; bun:ffi coerces that to "".
|
|
445
|
+
const rendered = String(this.native.galley_status_string(BigInt(status)));
|
|
446
|
+
return rendered === "" ? null : rendered;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// -- sessions ---------------------------------------------------------
|
|
450
|
+
|
|
451
|
+
createSession(options: SessionCOptions | null): Handle {
|
|
452
|
+
let handle: NativeHandle;
|
|
453
|
+
if (options === null) {
|
|
454
|
+
handle = this.native.galley_session_create();
|
|
455
|
+
} else {
|
|
456
|
+
// GalleyCOptions layout: int32 x5, double, uint64 (40 bytes, LE).
|
|
457
|
+
const buf = new ArrayBuffer(40);
|
|
458
|
+
const view = new DataView(buf);
|
|
459
|
+
view.setInt32(0, options.maxErrors, true);
|
|
460
|
+
view.setInt32(4, options.recoveryWindow, true);
|
|
461
|
+
view.setInt32(8, options.stackOverflowRecovery, true);
|
|
462
|
+
view.setUint32(12, options.syntaxErrorStackDepth, true);
|
|
463
|
+
view.setInt32(16, options.verbosity, true);
|
|
464
|
+
view.setFloat64(24, options.astPreallocationRatio, true);
|
|
465
|
+
view.setBigUint64(32, options.astPreallocationCap, true);
|
|
466
|
+
handle = this.native.galley_session_create_ex(ptr(new Uint8Array(buf)));
|
|
467
|
+
}
|
|
468
|
+
if (handle === 0 || handle === null || handle === undefined) return null;
|
|
469
|
+
return handle;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
destroySession(handle: Handle): void {
|
|
473
|
+
this.native.galley_session_destroy(handle as NativeHandle);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
setMessageOverride(handle: Handle, name: Uint8Array, message: Uint8Array): number {
|
|
477
|
+
return Number(
|
|
478
|
+
this.native.galley_session_set_message_override(
|
|
479
|
+
handle as NativeHandle, ptr(name), BigInt(name.length), ptr(message), BigInt(message.length),
|
|
480
|
+
),
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// -- parsing ----------------------------------------------------------
|
|
485
|
+
|
|
486
|
+
parse(handle: Handle, data: Uint8Array): number {
|
|
487
|
+
return Number(this.native.galley_parse(handle as NativeHandle, ptr(data), BigInt(data.length)));
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
parseFile(handle: Handle, filePath: string): number {
|
|
491
|
+
const bytes = Buffer.from(filePath, "utf-8");
|
|
492
|
+
const nul = Buffer.alloc(bytes.length + 1);
|
|
493
|
+
bytes.copy(nul);
|
|
494
|
+
return Number(this.native.galley_parse_file(handle as NativeHandle, ptr(nul)));
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
lastPosition(handle: Handle): [number, number] | null {
|
|
498
|
+
const outLine = u32Out();
|
|
499
|
+
const outCol = u32Out();
|
|
500
|
+
if (this.native.galley_last_position(handle as NativeHandle, ptr(outLine), ptr(outCol)) < 0n) return null;
|
|
501
|
+
return [outLine[0], outCol[0]];
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// -- arena and navigation ----------------------------------------------
|
|
505
|
+
|
|
506
|
+
nodeCount(handle: Handle): number {
|
|
507
|
+
return Number(this.native.galley_node_count(handle as NativeHandle));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
reserveNodes(handle: Handle, capacity: bigint): number {
|
|
511
|
+
return Number(this.native.galley_reserve_nodes(handle as NativeHandle, capacity));
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
nodeCapacity(handle: Handle): number {
|
|
515
|
+
return Number(this.native.galley_node_capacity(handle as NativeHandle));
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
rootNode(handle: Handle): bigint {
|
|
519
|
+
return this.native.galley_root_node(handle as NativeHandle);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
nodeValid(handle: Handle, node: bigint): boolean {
|
|
523
|
+
return this.native.galley_node_is_valid(handle as NativeHandle, node) !== 0;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
childCount(handle: Handle, node: bigint): number {
|
|
527
|
+
return this.native.galley_node_child_count(handle as NativeHandle, node);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
firstChild(handle: Handle, node: bigint): bigint {
|
|
531
|
+
return this.native.galley_node_first_child(handle as NativeHandle, node);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
lastChild(handle: Handle, node: bigint): bigint {
|
|
535
|
+
return this.native.galley_node_last_child(handle as NativeHandle, node);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
nextSibling(handle: Handle, node: bigint): bigint {
|
|
539
|
+
return this.native.galley_node_next_sibling(handle as NativeHandle, node);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
priorSibling(handle: Handle, node: bigint): bigint {
|
|
543
|
+
return this.native.galley_node_prior_sibling(handle as NativeHandle, node);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
parent(handle: Handle, node: bigint): bigint {
|
|
547
|
+
return this.native.galley_node_parent(handle as NativeHandle, node);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
treeSnapshot(handle: Handle): TreeSnapshot {
|
|
551
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
552
|
+
const count = this.nodeCount(handle);
|
|
553
|
+
const parent = new BigUint64Array(count);
|
|
554
|
+
const firstChild = new BigUint64Array(count);
|
|
555
|
+
const next = new BigUint64Array(count);
|
|
556
|
+
const childCount = new Uint32Array(count);
|
|
557
|
+
const variable = new BigInt64Array(count);
|
|
558
|
+
const spanStart = new BigUint64Array(count);
|
|
559
|
+
const spanLen = new BigUint64Array(count);
|
|
560
|
+
const total = this.native.galley_tree_snapshot(
|
|
561
|
+
handle as NativeHandle, ptr(parent), ptr(firstChild), ptr(next), ptr(childCount),
|
|
562
|
+
ptr(variable), ptr(spanStart), ptr(spanLen), BigInt(count),
|
|
563
|
+
);
|
|
564
|
+
if (total < 0n) throw new GalleyError("galley_tree_snapshot failed", Number(total));
|
|
565
|
+
if (total === BigInt(count)) {
|
|
566
|
+
return { count, parent, firstChild, next, childCount, variable, spanStart, spanLen };
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
throw new GalleyError("node count changed during galley_tree_snapshot", -8);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// -- walker ------------------------------------------------------------
|
|
573
|
+
|
|
574
|
+
walkerCreate(handle: Handle, node: bigint, skipSemanticErrors: boolean): Handle | null {
|
|
575
|
+
const walker = this.native.galley_walker_create(handle as NativeHandle, node, skipSemanticErrors ? 1 : 0);
|
|
576
|
+
if (walker === 0 || walker === null || walker === undefined) return null;
|
|
577
|
+
return walker;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
walkerNext(walker: Handle): WalkedStep | null {
|
|
581
|
+
const outNode = ptrOut64();
|
|
582
|
+
const outDepth = u32Out();
|
|
583
|
+
const outFlag = u32Out();
|
|
584
|
+
if (this.native.galley_walker_next(walker as NativeHandle, ptr(outNode), ptr(outDepth), ptr(outFlag)) === 0) return null;
|
|
585
|
+
return { node: outNode[0], depth: outDepth[0], isSemanticError: outFlag[0] !== 0 };
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
walkerSkipChildren(walker: Handle): void {
|
|
589
|
+
this.native.galley_walker_skip_children(walker as NativeHandle);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
walkerDestroy(walker: Handle): void {
|
|
593
|
+
this.native.galley_walker_destroy(walker as NativeHandle);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// -- node accessors -----------------------------------------------------
|
|
597
|
+
|
|
598
|
+
#tryCopyBytes(fn: (outData: BigUint64Array, outLen: BigUint64Array) => bigint): Uint8Array | null {
|
|
599
|
+
const outData = ptrOut64();
|
|
600
|
+
const outLen = ptrOut64();
|
|
601
|
+
if (fn(outData, outLen) < 0n) return null;
|
|
602
|
+
if (outData[0] === 0n) return null;
|
|
603
|
+
return readBytes(outData[0], outLen[0]);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
#readSemanticPair(
|
|
607
|
+
fn: (outVariable: BigUint64Array, outVariableLen: BigUint64Array, outMessage: BigUint64Array, outMessageLen: BigUint64Array) => bigint,
|
|
608
|
+
): [string, string] | null {
|
|
609
|
+
const outVariable = ptrOut64();
|
|
610
|
+
const outVariableLen = ptrOut64();
|
|
611
|
+
const outMessage = ptrOut64();
|
|
612
|
+
const outMessageLen = ptrOut64();
|
|
613
|
+
if (fn(outVariable, outVariableLen, outMessage, outMessageLen) < 0n) return null;
|
|
614
|
+
if (outVariable[0] === 0n || outMessage[0] === 0n) return null;
|
|
615
|
+
const decoder = new TextDecoder();
|
|
616
|
+
return [
|
|
617
|
+
decoder.decode(readBytes(outVariable[0], outVariableLen[0])),
|
|
618
|
+
decoder.decode(readBytes(outMessage[0], outMessageLen[0])),
|
|
619
|
+
];
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
nodeSymbolName(handle: Handle, node: bigint): Uint8Array | null {
|
|
623
|
+
const h = handle as NativeHandle;
|
|
624
|
+
const outData = ptrOut64();
|
|
625
|
+
const outLen = ptrOut64();
|
|
626
|
+
if (this.native.galley_node_symbol_name(h, node, ptr(outData), ptr(outLen)) < 0n) return null;
|
|
627
|
+
return readBytes(outData[0], outLen[0]);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
nodeText(handle: Handle, node: bigint): Uint8Array | null {
|
|
631
|
+
const h = handle as NativeHandle;
|
|
632
|
+
const outData = ptrOut64();
|
|
633
|
+
const outLen = ptrOut64();
|
|
634
|
+
if (this.native.galley_node_text(h, node, ptr(outData), ptr(outLen)) < 0n) return null;
|
|
635
|
+
return readBytes(outData[0], outLen[0]);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
nodeSpan(handle: Handle, node: bigint): [bigint, bigint] | null {
|
|
639
|
+
const outStart = ptrOut64();
|
|
640
|
+
const outLen = ptrOut64();
|
|
641
|
+
if (this.native.galley_node_span(handle as NativeHandle, node, ptr(outStart), ptr(outLen)) < 0n) return null;
|
|
642
|
+
return [outStart[0], outLen[0]];
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
nodeLineColumn(handle: Handle, node: bigint): [number, number] | null {
|
|
646
|
+
const outLine = u32Out();
|
|
647
|
+
const outCol = u32Out();
|
|
648
|
+
if (this.native.galley_node_line_column(handle as NativeHandle, node, ptr(outLine), ptr(outCol)) < 0n) return null;
|
|
649
|
+
return [outLine[0], outCol[0]];
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
nodeVariableIndex(handle: Handle, node: bigint): number {
|
|
653
|
+
return Number(this.native.galley_node_variable_index(handle as NativeHandle, node));
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
symbolNameAt(handle: Handle, index: number): Uint8Array | null {
|
|
657
|
+
const h = handle as NativeHandle;
|
|
658
|
+
const outData = ptrOut64();
|
|
659
|
+
const outLen = ptrOut64();
|
|
660
|
+
if (this.native.galley_symbol_name(h, BigInt(index), ptr(outData), ptr(outLen)) < 0n) return null;
|
|
661
|
+
return readBytes(outData[0], outLen[0]);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
symbolIsTerminal(handle: Handle, index: number): boolean {
|
|
665
|
+
return this.native.galley_symbol_is_terminal(handle as NativeHandle, BigInt(index)) !== 0;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
variableNameAt(handle: Handle, index: number): Uint8Array | null {
|
|
669
|
+
const h = handle as NativeHandle;
|
|
670
|
+
const outData = ptrOut64();
|
|
671
|
+
const outLen = ptrOut64();
|
|
672
|
+
if (this.native.galley_variable_name(h, BigInt(index), ptr(outData), ptr(outLen)) < 0n) return null;
|
|
673
|
+
return readBytes(outData[0], outLen[0]);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// -- diagnostics ---------------------------------------------------------
|
|
677
|
+
|
|
678
|
+
hasDiagnostic(handle: Handle): boolean {
|
|
679
|
+
return this.native.galley_has_diagnostic(handle as NativeHandle) !== 0;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
diagnosticKind(handle: Handle): number {
|
|
683
|
+
return Number(this.native.galley_diagnostic_kind(handle as NativeHandle));
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
diagnosticMessage(handle: Handle): string | null {
|
|
687
|
+
const out = ptrOut64();
|
|
688
|
+
if (this.native.galley_diagnostic_message(handle as NativeHandle, ptr(out)) !== 0n) return null;
|
|
689
|
+
return readCString(out[0]);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
diagnosticMessageAnsi(handle: Handle): string | null {
|
|
693
|
+
const out = ptrOut64();
|
|
694
|
+
if (this.native.galley_diagnostic_message_ansi(handle as NativeHandle, ptr(out)) !== 0n) return null;
|
|
695
|
+
return readCString(out[0]);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
diagnosticPosition(handle: Handle): [number, number] | null {
|
|
699
|
+
const outLine = u32Out();
|
|
700
|
+
const outCol = u32Out();
|
|
701
|
+
if (this.native.galley_diagnostic_position(handle as NativeHandle, ptr(outLine), ptr(outCol)) < 0n) return null;
|
|
702
|
+
return [outLine[0], outCol[0]];
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
diagnosticUnexpectedToken(handle: Handle): Uint8Array | null {
|
|
706
|
+
const h = handle as NativeHandle;
|
|
707
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_diagnostic_unexpected_token(h, ptr(od), ptr(ol)));
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
diagnosticExpectedCount(handle: Handle): number {
|
|
711
|
+
return Number(this.native.galley_diagnostic_expected_count(handle as NativeHandle));
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
diagnosticExpectedAt(handle: Handle, index: number): Uint8Array | null {
|
|
715
|
+
const h = handle as NativeHandle;
|
|
716
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_diagnostic_expected_at(h, BigInt(index), ptr(od), ptr(ol)));
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
diagnosticContextCount(handle: Handle): number {
|
|
720
|
+
return Number(this.native.galley_diagnostic_context_count(handle as NativeHandle));
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
diagnosticContextAt(handle: Handle, index: number): Uint8Array | null {
|
|
724
|
+
const h = handle as NativeHandle;
|
|
725
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_diagnostic_context_at(h, BigInt(index), ptr(od), ptr(ol)));
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
syntaxErrorCount(handle: Handle): number {
|
|
729
|
+
return Number(this.native.galley_syntax_error_count(handle as NativeHandle));
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
semanticErrorCount(handle: Handle): number {
|
|
733
|
+
return Number(this.native.galley_semantic_error_count(handle as NativeHandle));
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
diagnosticSemantic(handle: Handle): [string, string] | null {
|
|
737
|
+
const h = handle as NativeHandle;
|
|
738
|
+
return this.#readSemanticPair((ov, ovl, om, oml) =>
|
|
739
|
+
this.native.galley_diagnostic_semantic(h, ptr(ov), ptr(ovl), ptr(om), ptr(oml)));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
diagnosticIndentation(handle: Handle): [number, number] | null {
|
|
743
|
+
const outSpaces = u32Out();
|
|
744
|
+
const outWidth = u32Out();
|
|
745
|
+
if (this.native.galley_diagnostic_indentation(handle as NativeHandle, ptr(outSpaces), ptr(outWidth)) !== 0n) return null;
|
|
746
|
+
return [outSpaces[0], outWidth[0]];
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
diagnosticRecoveryKind(handle: Handle): number {
|
|
750
|
+
return Number(this.native.galley_diagnostic_recovery_kind(handle as NativeHandle));
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
diagnosticRecoveryTerminal(handle: Handle): Uint8Array | null {
|
|
754
|
+
const h = handle as NativeHandle;
|
|
755
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_diagnostic_recovery_terminal(h, ptr(od), ptr(ol)));
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
diagnosticRecoveryResume(handle: Handle): number | null {
|
|
759
|
+
const out = i64Out();
|
|
760
|
+
if (this.native.galley_diagnostic_recovery_resume(handle as NativeHandle, ptr(out)) !== 0n) return null;
|
|
761
|
+
return Number(out[0]);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
diagnosticRecoveryLhsVariable(handle: Handle): string | null {
|
|
765
|
+
const h = handle as NativeHandle;
|
|
766
|
+
const outData = ptrOut64();
|
|
767
|
+
const outLen = ptrOut64();
|
|
768
|
+
if (this.native.galley_diagnostic_recovery_lhs_variable(h, ptr(outData), ptr(outLen)) < 0n || outData[0] === 0n) return null;
|
|
769
|
+
return new TextDecoder().decode(readBytes(outData[0], outLen[0]));
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
diagnosticRecoveryProduction(handle: Handle): [string, number] | null {
|
|
773
|
+
const h = handle as NativeHandle;
|
|
774
|
+
const outVar = ptrOut64();
|
|
775
|
+
const outLen = ptrOut64();
|
|
776
|
+
const outIdx = u32Out();
|
|
777
|
+
if (this.native.galley_diagnostic_recovery_production(h, ptr(outVar), ptr(outLen), ptr(outIdx)) !== 0n) return null;
|
|
778
|
+
return [new TextDecoder().decode(readBytes(outVar[0], outLen[0])), outIdx[0]];
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
diagnosticRecoveryOccurrence(handle: Handle): [string, number, number, string] | null {
|
|
782
|
+
const h = handle as NativeHandle;
|
|
783
|
+
const outParent = ptrOut64();
|
|
784
|
+
const outParentLen = ptrOut64();
|
|
785
|
+
const outRhs = u32Out();
|
|
786
|
+
const outSym = u32Out();
|
|
787
|
+
const outVar = ptrOut64();
|
|
788
|
+
const outVarLen = ptrOut64();
|
|
789
|
+
if (this.native.galley_diagnostic_recovery_occurrence(h, ptr(outParent), ptr(outParentLen), ptr(outRhs), ptr(outSym), ptr(outVar), ptr(outVarLen)) !== 0n) return null;
|
|
790
|
+
const decoder = new TextDecoder();
|
|
791
|
+
return [
|
|
792
|
+
decoder.decode(readBytes(outParent[0], outParentLen[0])),
|
|
793
|
+
outRhs[0],
|
|
794
|
+
outSym[0],
|
|
795
|
+
decoder.decode(readBytes(outVar[0], outVarLen[0])),
|
|
796
|
+
];
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
recordedDiagnosticCount(handle: Handle): number {
|
|
800
|
+
return Number(this.native.galley_recorded_diagnostic_count(handle as NativeHandle));
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
recordedDiagnosticKind(handle: Handle, diagIndex: number): number {
|
|
804
|
+
return Number(this.native.galley_recorded_diagnostic_kind(handle as NativeHandle, BigInt(diagIndex)));
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
recordedDiagnosticPosition(handle: Handle, diagIndex: number): [number, number] | null {
|
|
808
|
+
const outLine = u32Out();
|
|
809
|
+
const outCol = u32Out();
|
|
810
|
+
if (this.native.galley_recorded_diagnostic_position(handle as NativeHandle, BigInt(diagIndex), ptr(outLine), ptr(outCol)) < 0n) return null;
|
|
811
|
+
return [outLine[0], outCol[0]];
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
recordedUnexpectedToken(handle: Handle, diagIndex: number): Uint8Array | null {
|
|
815
|
+
const h = handle as NativeHandle;
|
|
816
|
+
const d = BigInt(diagIndex);
|
|
817
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_recorded_unexpected_token(h, d, ptr(od), ptr(ol)));
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
recordedDiagnosticMessage(handle: Handle, diagIndex: number): string | null {
|
|
821
|
+
const out = ptrOut64();
|
|
822
|
+
if (this.native.galley_recorded_diagnostic_message(handle as NativeHandle, BigInt(diagIndex), ptr(out)) !== 0n) return null;
|
|
823
|
+
return readCString(out[0]);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
recordedIndentation(handle: Handle, diagIndex: number): [number, number] | null {
|
|
827
|
+
const outSpaces = u32Out();
|
|
828
|
+
const outWidth = u32Out();
|
|
829
|
+
if (this.native.galley_recorded_indentation(handle as NativeHandle, BigInt(diagIndex), ptr(outSpaces), ptr(outWidth)) !== 0n) return null;
|
|
830
|
+
return [outSpaces[0], outWidth[0]];
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
recordedSemantic(handle: Handle, diagIndex: number): [string, string] | null {
|
|
834
|
+
const h = handle as NativeHandle;
|
|
835
|
+
const d = BigInt(diagIndex);
|
|
836
|
+
return this.#readSemanticPair((ov, ovl, om, oml) =>
|
|
837
|
+
this.native.galley_recorded_semantic(h, d, ptr(ov), ptr(ovl), ptr(om), ptr(oml)));
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
recordedExpectedCount(handle: Handle, diagIndex: number): number {
|
|
841
|
+
return Number(this.native.galley_recorded_expected_count(handle as NativeHandle, BigInt(diagIndex)));
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
recordedExpectedToken(handle: Handle, diagIndex: number, tokenIndex: number): Uint8Array | null {
|
|
845
|
+
const h = handle as NativeHandle;
|
|
846
|
+
const d = BigInt(diagIndex);
|
|
847
|
+
const t = BigInt(tokenIndex);
|
|
848
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_recorded_expected_token(h, d, t, ptr(od), ptr(ol)));
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
recordedContextCount(handle: Handle, diagIndex: number): number {
|
|
852
|
+
return Number(this.native.galley_recorded_context_count(handle as NativeHandle, BigInt(diagIndex)));
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
recordedContextName(handle: Handle, diagIndex: number, contextIndex: number): Uint8Array | null {
|
|
856
|
+
const h = handle as NativeHandle;
|
|
857
|
+
const d = BigInt(diagIndex);
|
|
858
|
+
const c = BigInt(contextIndex);
|
|
859
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_recorded_context_name(h, d, c, ptr(od), ptr(ol)));
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
recordedRecoveryKind(handle: Handle, diagIndex: number): number {
|
|
863
|
+
return Number(this.native.galley_recorded_diagnostic_recovery_kind(handle as NativeHandle, BigInt(diagIndex)));
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
recordedRecoveryTerminal(handle: Handle, diagIndex: number): Uint8Array | null {
|
|
867
|
+
const h = handle as NativeHandle;
|
|
868
|
+
const d = BigInt(diagIndex);
|
|
869
|
+
return this.#tryCopyBytes((od, ol) => this.native.galley_recorded_recovery_terminal(h, d, ptr(od), ptr(ol)));
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
recordedRecoveryResume(handle: Handle, diagIndex: number): number | null {
|
|
873
|
+
const out = i64Out();
|
|
874
|
+
if (this.native.galley_recorded_recovery_resume(handle as NativeHandle, BigInt(diagIndex), ptr(out)) !== 0n) return null;
|
|
875
|
+
return Number(out[0]);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
recordedRecoveryLhsVariable(handle: Handle, diagIndex: number): string | null {
|
|
879
|
+
const h = handle as NativeHandle;
|
|
880
|
+
const d = BigInt(diagIndex);
|
|
881
|
+
const outData = ptrOut64();
|
|
882
|
+
const outLen = ptrOut64();
|
|
883
|
+
if (this.native.galley_recorded_recovery_lhs_variable(h, d, ptr(outData), ptr(outLen)) < 0n || outData[0] === 0n) return null;
|
|
884
|
+
return new TextDecoder().decode(readBytes(outData[0], outLen[0]));
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
recordedRecoveryProduction(handle: Handle, diagIndex: number): [string, number] | null {
|
|
888
|
+
const h = handle as NativeHandle;
|
|
889
|
+
const d = BigInt(diagIndex);
|
|
890
|
+
const outVar = ptrOut64();
|
|
891
|
+
const outLen = ptrOut64();
|
|
892
|
+
const outIdx = u32Out();
|
|
893
|
+
if (this.native.galley_recorded_recovery_production(h, d, ptr(outVar), ptr(outLen), ptr(outIdx)) !== 0n) return null;
|
|
894
|
+
return [new TextDecoder().decode(readBytes(outVar[0], outLen[0])), outIdx[0]];
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
recordedRecoveryOccurrence(handle: Handle, diagIndex: number): [string, number, number, string] | null {
|
|
898
|
+
const h = handle as NativeHandle;
|
|
899
|
+
const d = BigInt(diagIndex);
|
|
900
|
+
const outParent = ptrOut64();
|
|
901
|
+
const outParentLen = ptrOut64();
|
|
902
|
+
const outRhs = u32Out();
|
|
903
|
+
const outSym = u32Out();
|
|
904
|
+
const outVar = ptrOut64();
|
|
905
|
+
const outVarLen = ptrOut64();
|
|
906
|
+
if (this.native.galley_recorded_recovery_occurrence(h, d, ptr(outParent), ptr(outParentLen), ptr(outRhs), ptr(outSym), ptr(outVar), ptr(outVarLen)) !== 0n) return null;
|
|
907
|
+
const decoder = new TextDecoder();
|
|
908
|
+
return [
|
|
909
|
+
decoder.decode(readBytes(outParent[0], outParentLen[0])),
|
|
910
|
+
outRhs[0],
|
|
911
|
+
outSym[0],
|
|
912
|
+
decoder.decode(readBytes(outVar[0], outVarLen[0])),
|
|
913
|
+
];
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// -- tree editing ----------------------------------------------------------
|
|
917
|
+
|
|
918
|
+
treeAppendChildren(handle: Handle, parent: bigint, first: bigint): number {
|
|
919
|
+
return Number(this.native.galley_tree_append_children(handle as NativeHandle, parent, first));
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
treeInsertBefore(handle: Handle, target: bigint, first: bigint): number {
|
|
923
|
+
return Number(this.native.galley_tree_insert_before(handle as NativeHandle, target, first));
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
treeInsertAfter(handle: Handle, target: bigint, first: bigint): number {
|
|
927
|
+
return Number(this.native.galley_tree_insert_after(handle as NativeHandle, target, first));
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
treeRemoveSiblings(handle: Handle, node: bigint, count: number): { status: number; head: bigint } {
|
|
931
|
+
const outHead = ptrOut64();
|
|
932
|
+
const st = this.native.galley_tree_remove_siblings(handle as NativeHandle, node, BigInt(count), ptr(outHead));
|
|
933
|
+
return { status: Number(st), head: outHead[0] };
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
treeRemoveSelf(handle: Handle, node: bigint): { status: number; head: bigint } {
|
|
937
|
+
const outHead = ptrOut64();
|
|
938
|
+
const st = this.native.galley_tree_remove_self(handle as NativeHandle, node, ptr(outHead));
|
|
939
|
+
return { status: Number(st), head: outHead[0] };
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
treePromoteChildrenOverWrapper(handle: Handle, wrapper: bigint): { status: number; head: bigint } {
|
|
943
|
+
const outHead = ptrOut64();
|
|
944
|
+
const st = this.native.galley_tree_promote_children_over_wrapper(handle as NativeHandle, wrapper, ptr(outHead));
|
|
945
|
+
return { status: Number(st), head: outHead[0] };
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
treeCleanChildren(handle: Handle, node: bigint): { status: number; head: bigint } {
|
|
949
|
+
const outHead = ptrOut64();
|
|
950
|
+
const st = this.native.galley_tree_clean_children(handle as NativeHandle, node, ptr(outHead));
|
|
951
|
+
return { status: Number(st), head: outHead[0] };
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
treeUnlinkWrapper(handle: Handle, wrapper: bigint): number {
|
|
955
|
+
return Number(this.native.galley_tree_unlink_wrapper(handle as NativeHandle, wrapper));
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
treeInsertChildrenAt(handle: Handle, parent: bigint, index: number, first: bigint): number {
|
|
959
|
+
return Number(this.native.galley_tree_insert_children_at(handle as NativeHandle, parent, BigInt(index), first));
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
treeRemoveChildrenAt(handle: Handle, parent: bigint, index: number, count: number): { status: number; head: bigint } {
|
|
963
|
+
const outHead = ptrOut64();
|
|
964
|
+
const st = this.native.galley_tree_remove_children_at(handle as NativeHandle, parent, BigInt(index), BigInt(count), ptr(outHead));
|
|
965
|
+
return { status: Number(st), head: outHead[0] };
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// -- procedure hooks ----------------------------------------------------------
|
|
969
|
+
|
|
970
|
+
procCurrentNode(args: Handle): bigint {
|
|
971
|
+
return this.native.galley_procedure_current_node(args as NativeHandle);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
procSetCurrentNode(args: Handle, node: bigint): void {
|
|
975
|
+
this.native.galley_procedure_set_current_node(args as NativeHandle, node);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
procDropSelf(args: Handle): number {
|
|
979
|
+
return Number(this.native.galley_procedure_drop_self(args as NativeHandle));
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
procDropChildren(args: Handle): number {
|
|
983
|
+
return Number(this.native.galley_procedure_drop_children(args as NativeHandle));
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
procDropIfEmpty(args: Handle): number {
|
|
987
|
+
return Number(this.native.galley_procedure_drop_if_empty(args as NativeHandle));
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
procReplaceWithChildren(args: Handle): number {
|
|
991
|
+
return Number(this.native.galley_procedure_replace_with_children(args as NativeHandle));
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
procContextLine(args: Handle): number {
|
|
995
|
+
return this.native.galley_procedure_context_line(args as NativeHandle);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
procContextColumn(args: Handle): number {
|
|
999
|
+
return this.native.galley_procedure_context_column(args as NativeHandle);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
procReportSemanticError(args: Handle, message: Uint8Array): number {
|
|
1003
|
+
return Number(
|
|
1004
|
+
this.native.galley_procedure_report_semantic_error(args as NativeHandle, ptr(message), BigInt(message.length)),
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
const portCache = new Map<string, BunPort>();
|
|
1010
|
+
|
|
1011
|
+
/** Port for the library at `explicitPath` (or default discovery), cached per path. */
|
|
1012
|
+
export function getBunPort(explicitPath?: string): BunPort {
|
|
1013
|
+
const libPath = findLibrary(explicitPath);
|
|
1014
|
+
const cached = portCache.get(libPath);
|
|
1015
|
+
if (cached) return cached;
|
|
1016
|
+
// Libraries built for C procedures lack the JS dispatch symbol.
|
|
1017
|
+
let native: GalleySymbols;
|
|
1018
|
+
let supportsDispatch = true;
|
|
1019
|
+
try {
|
|
1020
|
+
native = openNative(libPath, 3).symbols;
|
|
1021
|
+
} catch {
|
|
1022
|
+
try {
|
|
1023
|
+
native = openNative(libPath, 2).symbols;
|
|
1024
|
+
} catch {
|
|
1025
|
+
try {
|
|
1026
|
+
native = openNative(libPath, 1).symbols;
|
|
1027
|
+
} catch {
|
|
1028
|
+
native = openNative(libPath, 0).symbols;
|
|
1029
|
+
supportsDispatch = false;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
const port = new BunPort(native, libPath, supportsDispatch);
|
|
1034
|
+
portCache.set(libPath, port);
|
|
1035
|
+
return port;
|
|
1036
|
+
}
|