mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 21:14:28 -08:00
WIP
This commit is contained in:
21
src/eval.js
21
src/eval.js
@@ -211,7 +211,7 @@ const codegen = (node, cxt, parent) => {
|
|||||||
+ ']'
|
+ ']'
|
||||||
} else if(node.type == 'unary') {
|
} else if(node.type == 'unary') {
|
||||||
if(node.operator == 'await') {
|
if(node.operator == 'await') {
|
||||||
return `(await __with_restore_children(${do_codegen(node.expr)}))`
|
return `(await __do_await(${do_codegen(node.expr)}))`
|
||||||
} else {
|
} else {
|
||||||
return '(' + node.operator + ' ' + do_codegen(node.expr) + ')'
|
return '(' + node.operator + ' ' + do_codegen(node.expr) + ')'
|
||||||
}
|
}
|
||||||
@@ -367,9 +367,15 @@ export const eval_modules = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const set_promise_status = value => {
|
const set_promise_status = value => {
|
||||||
|
// TODO refactor, put is_status_requested inside status
|
||||||
if(value instanceof Promise) {
|
if(value instanceof Promise) {
|
||||||
|
if(value.is_status_requested) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
value.is_status_requested = true
|
||||||
// record stack for async calls, so expand calls works sync
|
// record stack for async calls, so expand calls works sync
|
||||||
set_record_call()
|
set_record_call()
|
||||||
|
// TODO why we set status for wrapped value and not for wrapper?
|
||||||
return value
|
return value
|
||||||
.then(v => {
|
.then(v => {
|
||||||
value.status = {ok: true, value: v}
|
value.status = {ok: true, value: v}
|
||||||
@@ -384,7 +390,7 @@ export const eval_modules = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const __with_restore_children = async value => {
|
const __do_await = async value => {
|
||||||
// children is an array of child calls for current function call. But it
|
// children is an array of child calls for current function call. But it
|
||||||
// can be null to save one empty array allocation in case it has no child
|
// can be null to save one empty array allocation in case it has no child
|
||||||
// calls. Allocate array now, so we can have a reference to this array
|
// calls. Allocate array now, so we can have a reference to this array
|
||||||
@@ -393,6 +399,17 @@ export const eval_modules = (
|
|||||||
children = []
|
children = []
|
||||||
}
|
}
|
||||||
const children_copy = children
|
const children_copy = children
|
||||||
|
if(value instanceof Promise && !value.is_status_requested) {
|
||||||
|
value.is_status_requested = true
|
||||||
|
value.then(
|
||||||
|
v => {
|
||||||
|
value.status = {ok: true, value: v}
|
||||||
|
},
|
||||||
|
e => {
|
||||||
|
value.status = {ok: false, error: e}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return await value
|
return await value
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
13
test/test.js
13
test/test.js
@@ -2821,6 +2821,19 @@ const y = x()`
|
|||||||
assert_equal(root.children.at(-1).children[0].fn.name, 'x')
|
assert_equal(root.children.at(-1).children[0].fn.name, 'x')
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
test('async/await await promise wrapped to some data structure', async () => {
|
||||||
|
const i = await assert_code_evals_to_async(
|
||||||
|
`
|
||||||
|
const async_fn = async () => 1
|
||||||
|
const x = () => {
|
||||||
|
return {promise: async_fn()}
|
||||||
|
}
|
||||||
|
await x().promise
|
||||||
|
`,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TODO
|
// TODO
|
||||||
test('async/await move_cursor', async () => {
|
test('async/await move_cursor', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user