Anonymous View
Skip to content

Commit 7906d78

Browse files
committed
feat: support early return from the script
1 parent 7451cac commit 7906d78

4 files changed

Lines changed: 115 additions & 1 deletion

File tree

packages/core/src/runtime/tests/ifelse.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,68 @@ test('if statement, else if', async () => {
253253
expect(agent.root).toEqual(expectedStack);
254254
expect(agent.status).toBe('done');
255255
});
256+
257+
test('early return in if statement', async () => {
258+
const code = joinLines([
259+
//
260+
'let a = 2',
261+
'if (a > 1) {',
262+
' a = 3',
263+
' return',
264+
'}',
265+
'let b = 3',
266+
]);
267+
268+
const script = parseScript(code);
269+
const agent = createAgent({ script });
270+
271+
await executeAgent({ agent });
272+
273+
const expectedStack = rootFrame({
274+
status: 'done',
275+
children: [
276+
// var a declaration
277+
completedFrame({ node: 'var' }),
278+
// if statement
279+
completedFrame({
280+
node: 'if',
281+
children: [
282+
// condition
283+
completedFrame({
284+
node: 'binary',
285+
value: true,
286+
children: [
287+
// left operand
288+
completedFrame({
289+
node: 'ident',
290+
value: 2,
291+
}),
292+
],
293+
}),
294+
// body
295+
completedFrame({
296+
node: 'block',
297+
children: [
298+
// assignment
299+
completedFrame({
300+
node: 'assign',
301+
value: 3,
302+
}),
303+
// return
304+
completedFrame({
305+
node: 'return',
306+
}),
307+
],
308+
}),
309+
],
310+
}),
311+
],
312+
value: undefined,
313+
variables: {
314+
a: 3,
315+
},
316+
});
317+
318+
expect(agent.root).toEqual(expectedStack);
319+
expect(agent.status).toBe('done');
320+
});

packages/core/src/runtime/tests/nativeCalls.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,39 @@ test('array.push()', async () => {
210210
expect(agent.root).toEqual(expectedStack);
211211
expect(agent.status).toBe('done');
212212
});
213+
214+
test('array.filter(Boolean)', async () => {
215+
const script = parseScript([
216+
//
217+
'const a = [0, 1, 2, 3];',
218+
'a.filter(Boolean)',
219+
]);
220+
221+
const agent = createAgent({ script });
222+
const result = await executeAgent({ agent });
223+
224+
const expectedStack = rootFrame({
225+
status: 'done',
226+
children: [
227+
// variable init
228+
completedFrame({ node: 'var' }),
229+
// filter()
230+
completedFrame({
231+
node: 'call',
232+
value: [1, 2, 3],
233+
children: [
234+
// this
235+
completedFrame({
236+
node: 'ident',
237+
value: [0, 1, 2, 3],
238+
}),
239+
],
240+
}),
241+
],
242+
variables: { a: [0, 1, 2, 3] },
243+
});
244+
245+
expect(result).toEqual(agentResult({ ticks: 0 }));
246+
expect(agent.root).toEqual(expectedStack);
247+
expect(agent.status).toBe('done');
248+
});

packages/parser/src/parseScript.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,3 +434,14 @@ test('array map with function', () => {
434434

435435
expect(script).toEqual(expected);
436436
});
437+
438+
test('top level return', () => {
439+
const code = 'return 1';
440+
const script = parseScript(code);
441+
const expected: Script = {
442+
code,
443+
ast: [{ type: 'return', value: { type: 'literal', value: 1 } }],
444+
};
445+
446+
expect(script).toEqual(expected);
447+
});

packages/parser/src/parseScript.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export function parseScript(code: string | string[]): Script {
2626
code = code.join('\n');
2727
}
2828

29-
const ast = parse(code);
29+
const ast = parse(code, {
30+
allowReturnOutsideFunction: true,
31+
});
3032
const parsed: AstNode[] = [];
3133

3234
for (const node of ast.program.body) {

0 commit comments

Comments
 (0)