fix function shorthand default params

This commit is contained in:
2026-02-10 10:13:46 -06:00
parent 6df3b741cf
commit bd577712d9
3 changed files with 162 additions and 1 deletions

View File

@@ -391,7 +391,7 @@ var parse = function(tokens, src, filename, tokenizer) {
ast_node_end(param)
if (tok.kind == "=" || tok.kind == "|") {
advance()
param.expression = parse_expr()
param.expression = parse_assign_expr()
}
push(params, param)
} else {

Binary file not shown.

View File

@@ -3671,6 +3671,167 @@ run("functino >>>! unsigned shift right", function() {
assert_eq(>>>!(-1, 28), 15, ">>>! unsigned shift right")
})
// ============================================================================
// FUNCTION DEFAULT PARAMETERS
// ============================================================================
run("default param basic", function() {
var fn = function(a = 3, b = 5) { return a + b }
assert_eq(fn(), 8, "both defaults")
assert_eq(fn(10), 15, "first provided")
assert_eq(fn(10, 20), 30, "both provided")
})
run("default param null triggers default", function() {
var fn = function(a = 99) { return a }
assert_eq(fn(null), 99, "null should trigger default")
assert_eq(fn(), 99, "missing should trigger default")
assert_eq(fn(0), 0, "zero should not trigger default")
assert_eq(fn(false), false, "false should not trigger default")
assert_eq(fn(""), "", "empty string should not trigger default")
})
run("default param pipe syntax", function() {
var fn = function(a | 3, b | 5) { return a + b }
assert_eq(fn(), 8, "pipe both defaults")
assert_eq(fn(10), 15, "pipe first provided")
assert_eq(fn(10, 20), 30, "pipe both provided")
})
run("default param object literal", function() {
var fn = function(a = {x: 1, y: 2}) { return a.x + a.y }
assert_eq(fn(), 3, "object default")
assert_eq(fn({x: 10, y: 20}), 30, "object provided")
})
run("default param array literal", function() {
var fn = function(a = [10, 20, 30]) { return a[1] }
assert_eq(fn(), 20, "array default")
assert_eq(fn([99]), null, "array provided")
})
run("default param nested object", function() {
var fn = function(a = {inner: {val: 42}}) { return a.inner.val }
assert_eq(fn(), 42, "nested object default")
})
run("default param expression", function() {
var fn = function(a = 1 + 2, b = 3 * 4) { return a + b }
assert_eq(fn(), 15, "expression defaults")
})
run("default param negative number", function() {
var fn = function(a = -1) { return a }
assert_eq(fn(), -1, "negative default")
})
run("default param function call", function() {
var double = function(x) { return x * 2 }
var fn = function(a = double(21)) { return a }
assert_eq(fn(), 42, "function call default")
})
run("default param function value", function() {
var fn = function(f = function() { return 42 }) { return f() }
assert_eq(fn(), 42, "function as default")
})
run("default param arrow function", function() {
var fn = function(f = (x) => x * 2) { return f(5) }
assert_eq(fn(), 10, "arrow function as default")
})
run("default param ternary in default", function() {
var fn = function(a = true ? 10 : 20) { return a }
assert_eq(fn(), 10, "ternary default")
})
run("default param string with comma", function() {
var fn = function(a = "hello, world") { return a }
assert_eq(fn(), "hello, world", "string comma default")
})
run("default param empty object", function() {
var fn = function(a = {}) { return is_object(a) }
assert_eq(fn(), true, "empty object default")
})
run("default param empty array", function() {
var fn = function(a = []) { return is_array(a) }
assert_eq(fn(), true, "empty array default")
})
run("default param multiple complex", function() {
var fn = function(a = {k: 1}, b = [4, 5], c = "hi") {
return text(a.k) + text(b[0]) + c
}
assert_eq(fn(), "14hi", "multiple complex defaults")
assert_eq(fn({k: 9}), "94hi", "first overridden")
assert_eq(fn({k: 9}, [7]), "97hi", "first two overridden")
assert_eq(fn({k: 9}, [7], "yo"), "97yo", "all overridden")
})
run("default param independent defaults", function() {
var fn = function(a = 1, b = 2) { return a + b }
assert_eq(fn(), 3, "both defaults")
assert_eq(fn(10), 12, "first provided")
})
run("default param arrow function syntax", function() {
var fn = (a = 7, b = 8) => a + b
assert_eq(fn(), 15, "arrow defaults")
assert_eq(fn(100), 108, "arrow first provided")
assert_eq(fn(100, 200), 300, "arrow both provided")
})
run("default param single arrow", function() {
var fn = (a = 42) => a
assert_eq(fn(), 42, "single arrow default")
assert_eq(fn(0), 0, "single arrow zero")
})
run("default param method shorthand", function() {
var obj = {
calc(a = 10, b = 20) {
return a + b
}
}
assert_eq(obj.calc(), 30, "method defaults")
assert_eq(obj.calc(1), 21, "method first provided")
assert_eq(obj.calc(1, 2), 3, "method both provided")
})
run("default param each fresh object", function() {
var fn = function(a = {count: 0}) {
a.count = a.count + 1
return a.count
}
assert_eq(fn(), 1, "first call fresh object")
assert_eq(fn(), 1, "second call fresh object")
})
run("default param each fresh array", function() {
var fn = function(a = []) {
a[] = 1
return length(a)
}
assert_eq(fn(), 1, "first call fresh array")
assert_eq(fn(), 1, "second call fresh array")
})
run("default param nested parens", function() {
var fn = function(a = (1 + 2) * 3) { return a }
assert_eq(fn(), 9, "nested parens default")
})
run("default param closure over outer", function() {
var base = 100
var fn = function(a = base) { return a }
assert_eq(fn(), 100, "closure over outer")
base = 200
assert_eq(fn(), 200, "closure sees updated outer")
})
// ============================================================================
// SUMMARY
// ============================================================================