function declarations

This commit is contained in:
Dmitry Vasilev
2023-05-16 00:04:53 +03:00
parent 096ca5e495
commit 5b5938ee61
6 changed files with 202 additions and 41 deletions

View File

@@ -905,7 +905,43 @@ const object_literal =
)
)
const function_expr =
const block_function_body = if_ok(
seq_select(1, [
literal('{'),
cxt => parse_do(cxt),
literal('}'),
]),
({value, ...node}) => ({...value, ...node}),
)
const function_expr = must_have_name =>
if_ok(
seq([
optional(literal('async')),
literal('function'),
must_have_name ? identifier : optional(identifier),
list_destructuring(['(', ')'], 'function_args'),
block_function_body,
]),
({value, ...node}) => {
const [is_async, _fn, name, args, body] = value
const function_args = {...args,
not_evaluatable: args.children.length == 0
}
return {
...node,
type: 'function_expr',
is_async: is_async != null,
is_arrow: false,
name: name?.value,
body,
children: [function_args, body]
}
},
)
const arrow_function_expr =
if_ok(
seq([
optional(literal('async')),
@@ -920,16 +956,7 @@ const function_expr =
either(
// With curly braces
if_ok(
seq_select(1, [
literal('{'),
cxt => parse_do(cxt),
literal('}'),
]),
({value, ...node}) => ({...value, ...node}),
),
block_function_body,
// Just expression
cxt => expr(cxt),
)
@@ -953,6 +980,7 @@ const function_expr =
...node,
type: 'function_expr',
is_async: is_async != null,
is_arrow: true,
body,
children: [function_args, body]
}
@@ -1008,7 +1036,8 @@ const primary = if_fail(
new_expr,
object_literal,
array_literal,
function_expr,
function_expr(false),
arrow_function_expr,
// not_followed_by for better error messages
// y => { <garbage> } must parse as function expr, not as identifier `y`
@@ -1046,6 +1075,12 @@ const expr =
cxt => expr(cxt)
)
const function_decl = if_ok(
function_expr(true),
// wrap function_expr with function_decl
node => ({...node, type: 'function_decl', children: [node]})
)
// TODO multiple decls, like `const x = 1, y = 2`
const const_statement =
if_ok(
@@ -1246,6 +1281,7 @@ const do_statement = either(
if_statement,
throw_statement,
return_statement,
function_decl,
)
const module_statement = either(
@@ -1256,6 +1292,7 @@ const module_statement = either(
throw_statement,
import_statement,
export_statement,
function_decl,
)
const parse_do_or_module = (is_module) =>
@@ -1362,6 +1399,10 @@ const update_children_not_rec = (node, children = node.children) => {
stmts: children,
is_statement: true,
}
} else if(node.type == 'function_decl'){
return {...node,
is_statement: true,
}
} else if(node.type == 'unary') {
return {...node,
expr: children[0],
@@ -1486,7 +1527,12 @@ const do_deduce_fn_names = (node, parent) => {
}
}
if(node_result.type == 'function_expr') {
if(
node_result.type == 'function_expr'
&&
// not a named function
node_result.name == null
) {
let name
if(parent?.type == 'const') {
name = parent.name