@holoscript/core 2.0.1 → 2.1.0
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/dist/chunk-2XXE34KS.js +344 -0
- package/dist/chunk-2XXE34KS.js.map +1 -0
- package/dist/chunk-3X2EGU7Z.cjs +52 -0
- package/dist/chunk-3X2EGU7Z.cjs.map +1 -0
- package/dist/chunk-AFFVFO4D.js +1689 -0
- package/dist/chunk-AFFVFO4D.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/{src/HoloScriptDebugger.ts → dist/chunk-DOY73HDH.js} +118 -257
- package/dist/chunk-DOY73HDH.js.map +1 -0
- package/dist/chunk-JEQ2X3Z6.cjs +12 -0
- package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
- package/dist/chunk-L6VLNVKP.cjs +1691 -0
- package/dist/chunk-L6VLNVKP.cjs.map +1 -0
- package/dist/chunk-MFNO57XL.cjs +347 -0
- package/dist/chunk-MFNO57XL.cjs.map +1 -0
- package/dist/chunk-R75MREOS.cjs +424 -0
- package/dist/chunk-R75MREOS.cjs.map +1 -0
- package/dist/chunk-SATNCODL.js +45 -0
- package/dist/chunk-SATNCODL.js.map +1 -0
- package/dist/chunk-T57ZL7KR.cjs +1281 -0
- package/dist/chunk-T57ZL7KR.cjs.map +1 -0
- package/dist/chunk-U72GEJZT.js +1279 -0
- package/dist/chunk-U72GEJZT.js.map +1 -0
- package/dist/debugger.cjs +20 -0
- package/dist/debugger.cjs.map +1 -0
- package/dist/debugger.d.cts +171 -0
- package/dist/debugger.d.ts +171 -0
- package/dist/debugger.js +7 -0
- package/dist/debugger.js.map +1 -0
- package/dist/index.cjs +6803 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4093 -0
- package/dist/index.d.ts +4093 -0
- package/dist/index.js +6715 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.cjs +14 -0
- package/dist/parser.cjs.map +1 -0
- package/dist/parser.d.cts +172 -0
- package/dist/parser.d.ts +172 -0
- package/dist/parser.js +5 -0
- package/dist/parser.js.map +1 -0
- package/dist/runtime.cjs +14 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +200 -0
- package/dist/runtime.d.ts +200 -0
- package/dist/runtime.js +5 -0
- package/dist/runtime.js.map +1 -0
- package/dist/type-checker.cjs +17 -0
- package/dist/type-checker.cjs.map +1 -0
- package/dist/type-checker.d.cts +105 -0
- package/dist/type-checker.d.ts +105 -0
- package/dist/type-checker.js +4 -0
- package/dist/type-checker.js.map +1 -0
- package/dist/types-4h8cbtF_.d.cts +329 -0
- package/dist/types-4h8cbtF_.d.ts +329 -0
- package/package.json +17 -13
- package/src/HoloScript2DParser.js +0 -227
- package/src/HoloScript2DParser.ts +0 -261
- package/src/HoloScriptCodeParser.js +0 -1102
- package/src/HoloScriptCodeParser.ts +0 -1188
- package/src/HoloScriptDebugger.js +0 -458
- package/src/HoloScriptParser.js +0 -338
- package/src/HoloScriptParser.ts +0 -397
- package/src/HoloScriptPlusParser.js +0 -371
- package/src/HoloScriptPlusParser.ts +0 -543
- package/src/HoloScriptRuntime.js +0 -1399
- package/src/HoloScriptRuntime.test.js +0 -351
- package/src/HoloScriptRuntime.test.ts +0 -436
- package/src/HoloScriptRuntime.ts +0 -1653
- package/src/HoloScriptTypeChecker.js +0 -356
- package/src/HoloScriptTypeChecker.ts +0 -475
- package/src/__tests__/GraphicsServices.test.js +0 -357
- package/src/__tests__/GraphicsServices.test.ts +0 -427
- package/src/__tests__/HoloScriptPlusParser.test.js +0 -317
- package/src/__tests__/HoloScriptPlusParser.test.ts +0 -392
- package/src/__tests__/integration.test.js +0 -336
- package/src/__tests__/integration.test.ts +0 -416
- package/src/__tests__/performance.bench.js +0 -218
- package/src/__tests__/performance.bench.ts +0 -262
- package/src/__tests__/type-checker.test.js +0 -60
- package/src/__tests__/type-checker.test.ts +0 -73
- package/src/index.js +0 -217
- package/src/index.ts +0 -426
- package/src/interop/Interoperability.js +0 -413
- package/src/interop/Interoperability.ts +0 -494
- package/src/logger.js +0 -42
- package/src/logger.ts +0 -57
- package/src/parser/EnhancedParser.js +0 -205
- package/src/parser/EnhancedParser.ts +0 -251
- package/src/parser/HoloScriptPlusParser.js +0 -928
- package/src/parser/HoloScriptPlusParser.ts +0 -1089
- package/src/runtime/HoloScriptPlusRuntime.js +0 -674
- package/src/runtime/HoloScriptPlusRuntime.ts +0 -861
- package/src/runtime/PerformanceTelemetry.js +0 -323
- package/src/runtime/PerformanceTelemetry.ts +0 -467
- package/src/runtime/RuntimeOptimization.js +0 -361
- package/src/runtime/RuntimeOptimization.ts +0 -416
- package/src/services/HololandGraphicsPipelineService.js +0 -506
- package/src/services/HololandGraphicsPipelineService.ts +0 -662
- package/src/services/PlatformPerformanceOptimizer.js +0 -356
- package/src/services/PlatformPerformanceOptimizer.ts +0 -503
- package/src/state/ReactiveState.js +0 -427
- package/src/state/ReactiveState.ts +0 -572
- package/src/tools/DeveloperExperience.js +0 -376
- package/src/tools/DeveloperExperience.ts +0 -438
- package/src/traits/AIDriverTrait.js +0 -322
- package/src/traits/AIDriverTrait.test.js +0 -329
- package/src/traits/AIDriverTrait.test.ts +0 -357
- package/src/traits/AIDriverTrait.ts +0 -474
- package/src/traits/LightingTrait.js +0 -313
- package/src/traits/LightingTrait.test.js +0 -410
- package/src/traits/LightingTrait.test.ts +0 -462
- package/src/traits/LightingTrait.ts +0 -505
- package/src/traits/MaterialTrait.js +0 -194
- package/src/traits/MaterialTrait.test.js +0 -286
- package/src/traits/MaterialTrait.test.ts +0 -329
- package/src/traits/MaterialTrait.ts +0 -324
- package/src/traits/RenderingTrait.js +0 -356
- package/src/traits/RenderingTrait.test.js +0 -363
- package/src/traits/RenderingTrait.test.ts +0 -427
- package/src/traits/RenderingTrait.ts +0 -555
- package/src/traits/VRTraitSystem.js +0 -740
- package/src/traits/VRTraitSystem.ts +0 -1040
- package/src/traits/VoiceInputTrait.js +0 -284
- package/src/traits/VoiceInputTrait.test.js +0 -226
- package/src/traits/VoiceInputTrait.test.ts +0 -252
- package/src/traits/VoiceInputTrait.ts +0 -401
- package/src/types/AdvancedTypeSystem.js +0 -226
- package/src/types/AdvancedTypeSystem.ts +0 -494
- package/src/types/HoloScriptPlus.d.ts +0 -853
- package/src/types.js +0 -6
- package/src/types.ts +0 -369
- package/tsconfig.json +0 -23
- package/tsup.config.d.ts +0 -2
- package/tsup.config.js +0 -18
- package/tsup.config.ts +0 -19
|
@@ -1,458 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HoloScript Debugger
|
|
3
|
-
*
|
|
4
|
-
* Step-through debugging with breakpoints, call stack inspection,
|
|
5
|
-
* and variable watch capabilities.
|
|
6
|
-
*/
|
|
7
|
-
import { HoloScriptRuntime } from './HoloScriptRuntime';
|
|
8
|
-
import { HoloScriptCodeParser } from './HoloScriptCodeParser';
|
|
9
|
-
/**
|
|
10
|
-
* HoloScript Debugger with breakpoints and step-through execution
|
|
11
|
-
*/
|
|
12
|
-
export class HoloScriptDebugger {
|
|
13
|
-
constructor(runtime) {
|
|
14
|
-
this.breakpoints = new Map();
|
|
15
|
-
this.callStack = [];
|
|
16
|
-
this.currentAST = [];
|
|
17
|
-
this.currentNodeIndex = 0;
|
|
18
|
-
this.frameIdCounter = 0;
|
|
19
|
-
this.breakpointIdCounter = 0;
|
|
20
|
-
this.eventHandlers = new Map();
|
|
21
|
-
this.state = {
|
|
22
|
-
status: 'stopped',
|
|
23
|
-
currentLine: 0,
|
|
24
|
-
currentColumn: 0,
|
|
25
|
-
currentNode: null,
|
|
26
|
-
callStack: [],
|
|
27
|
-
breakpoints: [],
|
|
28
|
-
};
|
|
29
|
-
this.runtime = runtime || new HoloScriptRuntime();
|
|
30
|
-
this.parser = new HoloScriptCodeParser();
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Load source code for debugging
|
|
34
|
-
*/
|
|
35
|
-
loadSource(code, file) {
|
|
36
|
-
const parseResult = this.parser.parse(code);
|
|
37
|
-
if (!parseResult.success) {
|
|
38
|
-
return {
|
|
39
|
-
success: false,
|
|
40
|
-
errors: parseResult.errors.map(e => `Line ${e.line}: ${e.message}`),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
this.currentAST = parseResult.ast;
|
|
44
|
-
this.currentNodeIndex = 0;
|
|
45
|
-
this.state.status = 'stopped';
|
|
46
|
-
this.callStack = [];
|
|
47
|
-
// Store file reference in nodes
|
|
48
|
-
if (file) {
|
|
49
|
-
for (const node of this.currentAST) {
|
|
50
|
-
node.file = file;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return { success: true };
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Set a breakpoint at a line
|
|
57
|
-
*/
|
|
58
|
-
setBreakpoint(line, options = {}) {
|
|
59
|
-
const id = `bp_${++this.breakpointIdCounter}`;
|
|
60
|
-
const breakpoint = {
|
|
61
|
-
id,
|
|
62
|
-
line,
|
|
63
|
-
column: options.column,
|
|
64
|
-
condition: options.condition,
|
|
65
|
-
hitCount: 0,
|
|
66
|
-
enabled: options.enabled !== false,
|
|
67
|
-
file: options.file,
|
|
68
|
-
};
|
|
69
|
-
this.breakpoints.set(id, breakpoint);
|
|
70
|
-
this.updateBreakpointList();
|
|
71
|
-
return breakpoint;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Remove a breakpoint by ID
|
|
75
|
-
*/
|
|
76
|
-
removeBreakpoint(id) {
|
|
77
|
-
const removed = this.breakpoints.delete(id);
|
|
78
|
-
if (removed) {
|
|
79
|
-
this.updateBreakpointList();
|
|
80
|
-
}
|
|
81
|
-
return removed;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Remove all breakpoints at a line
|
|
85
|
-
*/
|
|
86
|
-
removeBreakpointsAtLine(line) {
|
|
87
|
-
let removed = 0;
|
|
88
|
-
for (const [id, bp] of this.breakpoints) {
|
|
89
|
-
if (bp.line === line) {
|
|
90
|
-
this.breakpoints.delete(id);
|
|
91
|
-
removed++;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (removed > 0) {
|
|
95
|
-
this.updateBreakpointList();
|
|
96
|
-
}
|
|
97
|
-
return removed;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Toggle breakpoint enabled state
|
|
101
|
-
*/
|
|
102
|
-
toggleBreakpoint(id) {
|
|
103
|
-
const bp = this.breakpoints.get(id);
|
|
104
|
-
if (bp) {
|
|
105
|
-
bp.enabled = !bp.enabled;
|
|
106
|
-
this.updateBreakpointList();
|
|
107
|
-
return bp.enabled;
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Get all breakpoints
|
|
113
|
-
*/
|
|
114
|
-
getBreakpoints() {
|
|
115
|
-
return Array.from(this.breakpoints.values());
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Clear all breakpoints
|
|
119
|
-
*/
|
|
120
|
-
clearBreakpoints() {
|
|
121
|
-
this.breakpoints.clear();
|
|
122
|
-
this.updateBreakpointList();
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Start debugging from the beginning
|
|
126
|
-
*/
|
|
127
|
-
async start() {
|
|
128
|
-
this.currentNodeIndex = 0;
|
|
129
|
-
this.callStack = [];
|
|
130
|
-
this.frameIdCounter = 0;
|
|
131
|
-
this.runtime.reset();
|
|
132
|
-
this.state.status = 'running';
|
|
133
|
-
await this.runUntilBreakpoint();
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Continue execution until next breakpoint or end
|
|
137
|
-
*/
|
|
138
|
-
async continue() {
|
|
139
|
-
if (this.state.status !== 'paused')
|
|
140
|
-
return;
|
|
141
|
-
this.state.status = 'running';
|
|
142
|
-
this.currentNodeIndex++;
|
|
143
|
-
await this.runUntilBreakpoint();
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Step into the next node
|
|
147
|
-
*/
|
|
148
|
-
async stepInto() {
|
|
149
|
-
if (this.state.status !== 'paused')
|
|
150
|
-
return;
|
|
151
|
-
this.state.status = 'stepping';
|
|
152
|
-
await this.executeStep('into');
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Step over the current node
|
|
156
|
-
*/
|
|
157
|
-
async stepOver() {
|
|
158
|
-
if (this.state.status !== 'paused')
|
|
159
|
-
return;
|
|
160
|
-
this.state.status = 'stepping';
|
|
161
|
-
await this.executeStep('over');
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Step out of the current function
|
|
165
|
-
*/
|
|
166
|
-
async stepOut() {
|
|
167
|
-
if (this.state.status !== 'paused')
|
|
168
|
-
return;
|
|
169
|
-
this.state.status = 'stepping';
|
|
170
|
-
await this.executeStep('out');
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Stop debugging
|
|
174
|
-
*/
|
|
175
|
-
stop() {
|
|
176
|
-
this.state.status = 'stopped';
|
|
177
|
-
this.callStack = [];
|
|
178
|
-
this.currentNodeIndex = 0;
|
|
179
|
-
this.emitEvent({ type: 'state-change', data: { status: 'stopped' } });
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Pause execution
|
|
183
|
-
*/
|
|
184
|
-
pause() {
|
|
185
|
-
if (this.state.status === 'running') {
|
|
186
|
-
this.state.status = 'paused';
|
|
187
|
-
this.emitEvent({ type: 'state-change', data: { status: 'paused' } });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Get current debug state
|
|
192
|
-
*/
|
|
193
|
-
getState() {
|
|
194
|
-
return { ...this.state };
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Get call stack
|
|
198
|
-
*/
|
|
199
|
-
getCallStack() {
|
|
200
|
-
return [...this.callStack];
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Get variables at a specific stack frame
|
|
204
|
-
*/
|
|
205
|
-
getVariables(frameId) {
|
|
206
|
-
if (frameId !== undefined) {
|
|
207
|
-
const frame = this.callStack.find(f => f.id === frameId);
|
|
208
|
-
return frame?.variables || new Map();
|
|
209
|
-
}
|
|
210
|
-
// Return all variables from runtime context
|
|
211
|
-
return new Map(this.runtime.getContext().variables);
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Evaluate an expression in the current context
|
|
215
|
-
*/
|
|
216
|
-
async evaluate(expression) {
|
|
217
|
-
try {
|
|
218
|
-
// Try to evaluate as a variable lookup first
|
|
219
|
-
const varValue = this.runtime.getVariable(expression);
|
|
220
|
-
if (varValue !== undefined) {
|
|
221
|
-
return { value: varValue };
|
|
222
|
-
}
|
|
223
|
-
// Try to parse and execute as an expression
|
|
224
|
-
const parseResult = this.parser.parse(expression);
|
|
225
|
-
if (!parseResult.success) {
|
|
226
|
-
return { value: undefined, error: parseResult.errors[0]?.message };
|
|
227
|
-
}
|
|
228
|
-
// Execute the expression
|
|
229
|
-
const results = await this.runtime.executeProgram(parseResult.ast);
|
|
230
|
-
const lastResult = results[results.length - 1];
|
|
231
|
-
return { value: lastResult?.output };
|
|
232
|
-
}
|
|
233
|
-
catch (error) {
|
|
234
|
-
return { value: undefined, error: String(error) };
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Set a watch expression
|
|
239
|
-
*/
|
|
240
|
-
watch(expression) {
|
|
241
|
-
const id = `watch_${Date.now()}`;
|
|
242
|
-
return { id, expression };
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Register an event handler
|
|
246
|
-
*/
|
|
247
|
-
on(event, handler) {
|
|
248
|
-
if (!this.eventHandlers.has(event)) {
|
|
249
|
-
this.eventHandlers.set(event, []);
|
|
250
|
-
}
|
|
251
|
-
this.eventHandlers.get(event).push(handler);
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Remove an event handler
|
|
255
|
-
*/
|
|
256
|
-
off(event, handler) {
|
|
257
|
-
const handlers = this.eventHandlers.get(event);
|
|
258
|
-
if (handlers) {
|
|
259
|
-
const index = handlers.indexOf(handler);
|
|
260
|
-
if (index !== -1) {
|
|
261
|
-
handlers.splice(index, 1);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Get the underlying runtime
|
|
267
|
-
*/
|
|
268
|
-
getRuntime() {
|
|
269
|
-
return this.runtime;
|
|
270
|
-
}
|
|
271
|
-
// Private methods
|
|
272
|
-
async runUntilBreakpoint() {
|
|
273
|
-
while (this.currentNodeIndex < this.currentAST.length) {
|
|
274
|
-
if (this.state.status === 'stopped')
|
|
275
|
-
break;
|
|
276
|
-
const node = this.currentAST[this.currentNodeIndex];
|
|
277
|
-
// Check for breakpoint
|
|
278
|
-
if (this.shouldBreakAt(node)) {
|
|
279
|
-
this.state.status = 'paused';
|
|
280
|
-
this.updateCurrentState(node);
|
|
281
|
-
const bp = this.findBreakpointAtLine(node.line ?? 0);
|
|
282
|
-
if (bp) {
|
|
283
|
-
bp.hitCount++;
|
|
284
|
-
this.emitEvent({
|
|
285
|
-
type: 'breakpoint-hit',
|
|
286
|
-
data: { breakpoint: bp, node, line: node.line ?? 0 },
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
// Execute the node
|
|
292
|
-
await this.executeNode(node);
|
|
293
|
-
this.currentNodeIndex++;
|
|
294
|
-
}
|
|
295
|
-
// Execution complete
|
|
296
|
-
this.state.status = 'stopped';
|
|
297
|
-
this.emitEvent({ type: 'state-change', data: { status: 'stopped', reason: 'complete' } });
|
|
298
|
-
}
|
|
299
|
-
async executeStep(mode) {
|
|
300
|
-
const startStackDepth = this.callStack.length;
|
|
301
|
-
if (this.currentNodeIndex >= this.currentAST.length) {
|
|
302
|
-
this.state.status = 'stopped';
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
const node = this.currentAST[this.currentNodeIndex];
|
|
306
|
-
switch (mode) {
|
|
307
|
-
case 'into':
|
|
308
|
-
// Execute one node, stepping into function calls
|
|
309
|
-
await this.executeNode(node);
|
|
310
|
-
this.currentNodeIndex++;
|
|
311
|
-
break;
|
|
312
|
-
case 'over':
|
|
313
|
-
// Execute one node, treating function calls as single steps
|
|
314
|
-
await this.executeNode(node);
|
|
315
|
-
this.currentNodeIndex++;
|
|
316
|
-
break;
|
|
317
|
-
case 'out':
|
|
318
|
-
// Execute until we leave the current stack frame
|
|
319
|
-
while (this.currentNodeIndex < this.currentAST.length) {
|
|
320
|
-
await this.executeNode(this.currentAST[this.currentNodeIndex]);
|
|
321
|
-
this.currentNodeIndex++;
|
|
322
|
-
if (this.callStack.length < startStackDepth) {
|
|
323
|
-
break;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
// Update state after step
|
|
329
|
-
if (this.currentNodeIndex < this.currentAST.length) {
|
|
330
|
-
this.state.status = 'paused';
|
|
331
|
-
this.updateCurrentState(this.currentAST[this.currentNodeIndex]);
|
|
332
|
-
this.emitEvent({
|
|
333
|
-
type: 'step-complete',
|
|
334
|
-
data: { mode, node: this.currentAST[this.currentNodeIndex] },
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
this.state.status = 'stopped';
|
|
339
|
-
this.emitEvent({ type: 'state-change', data: { status: 'stopped', reason: 'complete' } });
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
async executeNode(node) {
|
|
343
|
-
// Push stack frame for functions
|
|
344
|
-
if (node.type === 'function') {
|
|
345
|
-
const funcNode = node;
|
|
346
|
-
this.pushStackFrame(funcNode.name, node);
|
|
347
|
-
}
|
|
348
|
-
try {
|
|
349
|
-
// Execute via runtime
|
|
350
|
-
const result = await this.runtime.executeNode(node);
|
|
351
|
-
if (!result.success && result.error) {
|
|
352
|
-
this.emitEvent({
|
|
353
|
-
type: 'exception',
|
|
354
|
-
data: { error: result.error, node, line: node.line },
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
if (result.output !== undefined) {
|
|
358
|
-
this.emitEvent({
|
|
359
|
-
type: 'output',
|
|
360
|
-
data: { output: result.output, node },
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
catch (error) {
|
|
365
|
-
this.emitEvent({
|
|
366
|
-
type: 'exception',
|
|
367
|
-
data: { error: String(error), node, line: node.line },
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
// Pop stack frame when function completes
|
|
371
|
-
if (node.type === 'function') {
|
|
372
|
-
this.popStackFrame();
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
shouldBreakAt(node) {
|
|
376
|
-
const line = node.line;
|
|
377
|
-
for (const bp of this.breakpoints.values()) {
|
|
378
|
-
if (!bp.enabled)
|
|
379
|
-
continue;
|
|
380
|
-
if (bp.line !== line)
|
|
381
|
-
continue;
|
|
382
|
-
// Check condition if present
|
|
383
|
-
if (bp.condition) {
|
|
384
|
-
try {
|
|
385
|
-
const value = this.runtime.getVariable(bp.condition);
|
|
386
|
-
if (!value)
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
catch {
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
return true;
|
|
394
|
-
}
|
|
395
|
-
return false;
|
|
396
|
-
}
|
|
397
|
-
findBreakpointAtLine(line) {
|
|
398
|
-
for (const bp of this.breakpoints.values()) {
|
|
399
|
-
if (bp.line === line && bp.enabled) {
|
|
400
|
-
return bp;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
pushStackFrame(name, node) {
|
|
406
|
-
const frame = {
|
|
407
|
-
id: ++this.frameIdCounter,
|
|
408
|
-
name,
|
|
409
|
-
file: node.file,
|
|
410
|
-
line: node.line ?? 0,
|
|
411
|
-
column: node.column ?? 0,
|
|
412
|
-
variables: new Map(this.runtime.getContext().variables),
|
|
413
|
-
node,
|
|
414
|
-
};
|
|
415
|
-
this.callStack.push(frame);
|
|
416
|
-
this.state.callStack = [...this.callStack];
|
|
417
|
-
}
|
|
418
|
-
popStackFrame() {
|
|
419
|
-
const frame = this.callStack.pop();
|
|
420
|
-
this.state.callStack = [...this.callStack];
|
|
421
|
-
return frame;
|
|
422
|
-
}
|
|
423
|
-
updateCurrentState(node) {
|
|
424
|
-
this.state.currentLine = node.line ?? 0;
|
|
425
|
-
this.state.currentColumn = node.column ?? 0;
|
|
426
|
-
this.state.currentNode = node;
|
|
427
|
-
}
|
|
428
|
-
updateBreakpointList() {
|
|
429
|
-
this.state.breakpoints = Array.from(this.breakpoints.values());
|
|
430
|
-
}
|
|
431
|
-
emitEvent(event) {
|
|
432
|
-
const handlers = this.eventHandlers.get(event.type) || [];
|
|
433
|
-
for (const handler of handlers) {
|
|
434
|
-
try {
|
|
435
|
-
handler(event);
|
|
436
|
-
}
|
|
437
|
-
catch (error) {
|
|
438
|
-
console.error('Debug event handler error:', error);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
// Also emit to 'all' handlers
|
|
442
|
-
const allHandlers = this.eventHandlers.get('all') || [];
|
|
443
|
-
for (const handler of allHandlers) {
|
|
444
|
-
try {
|
|
445
|
-
handler(event);
|
|
446
|
-
}
|
|
447
|
-
catch (error) {
|
|
448
|
-
console.error('Debug event handler error:', error);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Create a debugger instance
|
|
455
|
-
*/
|
|
456
|
-
export function createDebugger(runtime) {
|
|
457
|
-
return new HoloScriptDebugger(runtime);
|
|
458
|
-
}
|