mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 21:14:28 -08:00
WIP
This commit is contained in:
@@ -7,6 +7,7 @@ import {eval_frame} from './eval.js'
|
|||||||
export const pp_calltree = tree => ({
|
export const pp_calltree = tree => ({
|
||||||
id: tree.id,
|
id: tree.id,
|
||||||
ok: tree.ok,
|
ok: tree.ok,
|
||||||
|
value: tree.value,
|
||||||
is_log: tree.is_log,
|
is_log: tree.is_log,
|
||||||
has_more_children: tree.has_more_children,
|
has_more_children: tree.has_more_children,
|
||||||
string: tree.code?.string,
|
string: tree.code?.string,
|
||||||
|
|||||||
14
src/effects.js
vendored
14
src/effects.js
vendored
@@ -177,7 +177,11 @@ export const render_common_side_effects = async (prev, next, command, ui) => {
|
|||||||
load_external_imports(next)
|
load_external_imports(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prev.eval_modules_state != next.eval_modules_state) {
|
if(
|
||||||
|
prev.eval_modules_state != next.eval_modules_state
|
||||||
|
&&
|
||||||
|
next.eval_modules_state != null
|
||||||
|
) {
|
||||||
const s = next.eval_modules_state
|
const s = next.eval_modules_state
|
||||||
s.promise.then(result => {
|
s.promise.then(result => {
|
||||||
exec('eval_modules_finished', result, s.node, s.toplevel)
|
exec('eval_modules_finished', result, s.node, s.toplevel)
|
||||||
@@ -188,7 +192,13 @@ export const render_common_side_effects = async (prev, next, command, ui) => {
|
|||||||
render_parse_result(ui, next)
|
render_parse_result(ui, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!next.parse_result.ok || next.loading_external_imports_state != null) {
|
if(
|
||||||
|
!next.parse_result.ok
|
||||||
|
||
|
||||||
|
next.loading_external_imports_state != null
|
||||||
|
||
|
||||||
|
next.eval_modules_state != null
|
||||||
|
) {
|
||||||
|
|
||||||
// TODO if loading external imports, show loading indicator
|
// TODO if loading external imports, show loading indicator
|
||||||
ui.calltree.clear_calltree()
|
ui.calltree.clear_calltree()
|
||||||
|
|||||||
11
src/eval.js
11
src/eval.js
@@ -260,16 +260,6 @@ const codegen = (node, cxt, parent) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO remove
|
|
||||||
const sync_promise = value => {
|
|
||||||
if(value instanceof run_window.Promise.Original) {
|
|
||||||
return value
|
|
||||||
} else {
|
|
||||||
return {is_sync_promise: true, then: fn => sync_promise(fn(value))}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const eval_modules = (
|
export const eval_modules = (
|
||||||
parse_result,
|
parse_result,
|
||||||
external_imports,
|
external_imports,
|
||||||
@@ -955,6 +945,7 @@ const do_eval_frame_expr = (node, scope, callsleft) => {
|
|||||||
ok = true
|
ok = true
|
||||||
value = typeof(expr.result.value)
|
value = typeof(expr.result.value)
|
||||||
} else if(node.operator == '-') {
|
} else if(node.operator == '-') {
|
||||||
|
ok = true
|
||||||
value = - expr.result.value
|
value = - expr.result.value
|
||||||
} else if(node.operator == 'await') {
|
} else if(node.operator == 'await') {
|
||||||
const run_window = globalThis.run_window ?? globalThis
|
const run_window = globalThis.run_window ?? globalThis
|
||||||
|
|||||||
@@ -203,9 +203,20 @@ export const topsort_modules = (modules) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const has_toplevel_await = modules =>
|
export const has_toplevel_await = modules =>
|
||||||
Object.values(modules).some(m =>
|
Object.values(modules).some(m => node_has_toplevel_await(m))
|
||||||
m.children.find(c => c.type == 'unary' && c.operator == 'await' ) != null
|
|
||||||
)
|
const node_has_toplevel_await = node => {
|
||||||
|
if(node.type == 'unary' && node.operator == 'await') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if(node.type == 'function_expr') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(node.children == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return node.children.find(c => node_has_toplevel_await(c)) != null
|
||||||
|
}
|
||||||
|
|
||||||
// TODO not implemented
|
// TODO not implemented
|
||||||
// TODO detect cycles when loading modules
|
// TODO detect cycles when loading modules
|
||||||
|
|||||||
@@ -13,11 +13,23 @@ export const patch_promise = window => {
|
|||||||
(resolve, reject) => {
|
(resolve, reject) => {
|
||||||
fn(
|
fn(
|
||||||
(value) => {
|
(value) => {
|
||||||
|
if(value instanceof window.Promise.Original) {
|
||||||
|
value
|
||||||
|
.then(v => {
|
||||||
|
this.status = {ok: true, value: v}
|
||||||
|
resolve(v)
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this.status = {ok: false, error: e}
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
status = {ok: true, value}
|
status = {ok: true, value}
|
||||||
if(is_constructor_finished) {
|
if(is_constructor_finished) {
|
||||||
this.status = status
|
this.status = status
|
||||||
}
|
}
|
||||||
resolve(value)
|
resolve(value)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
status = {ok: false, error}
|
status = {ok: false, error}
|
||||||
|
|||||||
55
test/test.js
55
test/test.js
@@ -2600,7 +2600,7 @@ const y = x()`
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
test('async/await await Promise', async () => {
|
test('async/await await resolved Promise', async () => {
|
||||||
await assert_code_evals_to_async(
|
await assert_code_evals_to_async(
|
||||||
`
|
`
|
||||||
await Promise.resolve(123)
|
await Promise.resolve(123)
|
||||||
@@ -2609,6 +2609,34 @@ const y = x()`
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
test('async/await await Promise resolved with resolved Promise', async () => {
|
||||||
|
await assert_code_evals_to_async(
|
||||||
|
`
|
||||||
|
await Promise.resolve(Promise.resolve(123))
|
||||||
|
`,
|
||||||
|
123
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
|
test('async/await await Promise resolved with async', async () => {
|
||||||
|
await assert_code_evals_to_async(
|
||||||
|
`
|
||||||
|
const x = async () => 1
|
||||||
|
await Promise.resolve(x())
|
||||||
|
`,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
|
test('async/await await Promise resolved with rejected Promise', async () => {
|
||||||
|
await assert_code_error_async(
|
||||||
|
`
|
||||||
|
await Promise.resolve(Promise.reject('boom'))
|
||||||
|
`,
|
||||||
|
'boom',
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
test('async/await await Promise returned from async function', async () => {
|
test('async/await await Promise returned from async function', async () => {
|
||||||
await assert_code_evals_to_async(
|
await assert_code_evals_to_async(
|
||||||
`
|
`
|
||||||
@@ -2640,15 +2668,6 @@ const y = x()`
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
test('async/await await rejected Promise', async () => {
|
|
||||||
await assert_code_error_async(
|
|
||||||
`
|
|
||||||
await Promise.reject('boom')
|
|
||||||
`,
|
|
||||||
'boom'
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
|
|
||||||
test('async/await await rejected Promise returned from async', async () => {
|
test('async/await await rejected Promise returned from async', async () => {
|
||||||
await assert_code_error_async(
|
await assert_code_error_async(
|
||||||
`
|
`
|
||||||
@@ -2659,10 +2678,14 @@ const y = x()`
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// TODO
|
test('async/await Promise.all', async () => {
|
||||||
//assert_equal('s', active_frame
|
await assert_code_evals_to_async(
|
||||||
//const result = await s.eval_modules_state
|
`
|
||||||
//const move = COMMANDS.move_cursor(s, code.indexOf('await x()')).state
|
const x = async i => i
|
||||||
//log('m', root_calltree_node(move).children[0].children[0].value)
|
await Promise.all([x(0), x(1), x(2)])
|
||||||
//log(s.parse_result.modules[''])
|
`,
|
||||||
|
[0,1,2]
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {parse, print_debug_node, load_modules} from '../src/parse_js.js'
|
import {parse, print_debug_node, load_modules} from '../src/parse_js.js'
|
||||||
import {eval_tree, eval_frame} from '../src/eval.js'
|
import {eval_tree, eval_frame} from '../src/eval.js'
|
||||||
import {active_frame} from '../src/calltree.js'
|
import {active_frame, pp_calltree} from '../src/calltree.js'
|
||||||
import {COMMANDS} from '../src/cmd.js'
|
import {COMMANDS} from '../src/cmd.js'
|
||||||
|
|
||||||
Object.assign(globalThis, {log: console.log})
|
Object.assign(globalThis, {log: console.log})
|
||||||
|
|||||||
Reference in New Issue
Block a user