diff --git a/source/quickjs.c b/source/quickjs.c index a6f82fb1..64e73aea 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -29873,7 +29873,8 @@ static cJSON *ast_parse_postfix (ASTParseState *s) { ast_next_token (s); cJSON *new_node = ast_node (s, ".", start); cJSON_AddItemToObject (new_node, "left", node); - if (s->token_val == TOK_IDENT) { + if (s->token_val == TOK_IDENT + || (s->token_val >= TOK_FIRST_KEYWORD && s->token_val <= TOK_LAST_KEYWORD)) { cjson_add_strn (new_node, "right", s->token_u.ident.str, s->token_u.ident.len); ast_next_token (s); } else { diff --git a/vm_suite.ce b/vm_suite.ce index 686fb4eb..3becf158 100644 --- a/vm_suite.ce +++ b/vm_suite.ce @@ -3369,6 +3369,182 @@ run("gc object from keys function under pressure", function() { } }) +// ============================================================================ +// DEFAULT PARAMETER TESTS +// ============================================================================ + +run("default param constant", function() { + var f = function(a, b=10) { return a + b } + assert_eq(f(1), 11, "default param constant") +}) + +run("default param overridden", function() { + var f = function(a, b=10) { return a + b } + assert_eq(f(1, 2), 3, "default param overridden") +}) + +run("default param uses earlier param", function() { + var f = function(a, b=a+1) { return b } + assert_eq(f(5), 6, "default param uses earlier param") +}) + +run("default param uses earlier param overridden", function() { + var f = function(a, b=a+1) { return b } + assert_eq(f(5, 20), 20, "default param uses earlier param overridden") +}) + +run("multiple default params", function() { + var f = function(a, b=10, c=a+1) { return a + b + c } + assert_eq(f(1), 13, "multiple defaults f(1)") + assert_eq(f(1, 2), 5, "multiple defaults f(1,2)") + assert_eq(f(1, 2, 3), 6, "multiple defaults f(1,2,3)") +}) + +run("arrow function default param", function() { + var g = (x, y=100) => x + y + assert_eq(g(5), 105, "arrow default param") + assert_eq(g(5, 20), 25, "arrow default param overridden") +}) + +run("default param null passed explicitly", function() { + var f = function(a, b=10) { return b } + assert_eq(f(1, null), 10, "explicit null triggers default") +}) + +run("default param with string", function() { + var f = function(a, b="hello") { return b } + assert_eq(f(1), "hello", "default string param") + assert_eq(f(1, "world"), "world", "default string overridden") +}) + +run("default param first param has no default", function() { + var f = function(a, b=42) { return a } + assert_eq(f(7), 7, "first param no default") +}) + +// ============================================================================ +// FUNCTINO TESTS +// ============================================================================ + +run("functino +! addition", function() { + assert_eq(+!(3, 4), 7, "+! addition") +}) + +run("functino -! subtraction", function() { + assert_eq(-!(10, 3), 7, "-! subtraction") +}) + +run("functino *! multiplication", function() { + assert_eq(*!(5, 6), 30, "*! multiplication") +}) + +run("functino /! division", function() { + assert_eq(/!(10, 2), 5, "/! division") +}) + +run("functino %! modulo", function() { + assert_eq(%!(10, 3), 1, "%! modulo") +}) + +run("functino **! power", function() { + assert_eq(**!(2, 10), 1024, "**! power") +}) + +run("functino ! greater than", function() { + assert_eq(>!(5, 3), true, ">! true") + assert_eq(>!(3, 5), false, ">! false") + assert_eq(>!(3, 3), false, ">! equal") +}) + +run("functino <=! less or equal", function() { + assert_eq(<=!(3, 5), true, "<=! less") + assert_eq(<=!(3, 3), true, "<=! equal") + assert_eq(<=!(5, 3), false, "<=! greater") +}) + +run("functino >=! greater or equal", function() { + assert_eq(>=!(5, 3), true, ">=! greater") + assert_eq(>=!(3, 3), true, ">=! equal") + assert_eq(>=!(3, 5), false, ">=! less") +}) + +run("functino =! equality", function() { + assert_eq(=!(5, 5), true, "=! true") + assert_eq(=!(5, 3), false, "=! false") +}) + +run("functino !=! inequality", function() { + assert_eq(!=!(5, 3), true, "!=! true") + assert_eq(!=!(5, 5), false, "!=! false") +}) + +run("functino =! with tolerance", function() { + assert_eq(=!(1.0, 1.0001, 0.001), true, "=! within tolerance") + assert_eq(=!(1.0, 1.01, 0.001), false, "=! outside tolerance") +}) + +run("functino !=! with tolerance", function() { + assert_eq(!=!(1.0, 1.01, 0.001), true, "!=! outside tolerance") + assert_eq(!=!(1.0, 1.0001, 0.001), false, "!=! within tolerance") +}) + +run("functino &! bitwise and", function() { + assert_eq(&!(0xff, 0x0f), 0x0f, "&! bitwise and") +}) + +run("functino |! bitwise or", function() { + assert_eq(|!(0xf0, 0x0f), 0xff, "|! bitwise or") +}) + +run("functino ^! bitwise xor", function() { + assert_eq(^!(0xff, 0x0f), 0xf0, "^! bitwise xor") +}) + +run("functino <>! shift right", function() { + assert_eq(>>!(16, 4), 1, ">>! shift right") +}) + +run("functino ~! bitwise not", function() { + assert_eq(~!(0), -1, "~! bitwise not 0") +}) + +run("functino []! array index", function() { + var arr = [10, 20, 30] + assert_eq([]!(arr, 0), 10, "[]! index 0") + assert_eq([]!(arr, 1), 20, "[]! index 1") + assert_eq([]!(arr, 2), 30, "[]! index 2") +}) + +run("functino &&! logical and", function() { + assert_eq(&&!(true, true), true, "&&! true true") + assert_eq(&&!(true, false), false, "&&! true false") + assert_eq(&&!(false, true), false, "&&! false true") + assert_eq(&&!(1, 2), 2, "&&! truthy returns right") + assert_eq(&&!(0, 2), 0, "&&! falsy returns left") +}) + +run("functino ||! logical or", function() { + assert_eq(||!(false, true), true, "||! false true") + assert_eq(||!(true, false), true, "||! true false") + assert_eq(||!(false, false), false, "||! false false") + assert_eq(||!(0, 5), 5, "||! falsy returns right") + assert_eq(||!(3, 5), 3, "||! truthy returns left") +}) + +run("functino >>>! unsigned shift right", function() { + assert_eq(>>>!(-1, 28), 15, ">>>! unsigned shift right") +}) + // ============================================================================ // SUMMARY // ============================================================================