comprehensive syntax test; fix multiple default args
This commit is contained in:
@@ -29520,7 +29520,7 @@ static cJSON *ast_parse_function_inner (ASTParseState *s, BOOL is_expr) {
|
||||
ast_next_token (s);
|
||||
if (s->token_val == '=' || s->token_val == '|') {
|
||||
ast_next_token (s);
|
||||
cJSON *default_val = ast_parse_expr (s);
|
||||
cJSON *default_val = ast_parse_assign_expr (s);
|
||||
cJSON_AddItemToObject (param, "expression", default_val);
|
||||
}
|
||||
cJSON_AddItemToArray (params, param);
|
||||
@@ -29606,7 +29606,7 @@ static cJSON *ast_parse_arrow_function (ASTParseState *s) {
|
||||
/* Check for default value */
|
||||
if (s->token_val == '=' || s->token_val == '|') {
|
||||
ast_next_token (s);
|
||||
cJSON *default_val = ast_parse_expr (s);
|
||||
cJSON *default_val = ast_parse_assign_expr (s);
|
||||
cJSON_AddItemToObject (param, "expression", default_val);
|
||||
}
|
||||
cJSON_AddItemToArray (params, param);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
void 0
|
||||
366
vm_test/syntax.txt
Normal file
366
vm_test/syntax.txt
Normal file
@@ -0,0 +1,366 @@
|
||||
/* comprehensive syntax test - exercises all AST paths */
|
||||
|
||||
// --- variables and constants ---
|
||||
var a
|
||||
var b = 1
|
||||
var c = 2, d = 3
|
||||
def PI = 3.14159
|
||||
def MSG = "hello"
|
||||
|
||||
// --- number literals ---
|
||||
var n_int = 42
|
||||
var n_float = 3.14
|
||||
var n_hex = 0xFF
|
||||
var n_octal = 0o77
|
||||
var n_binary = 0b1010
|
||||
var n_underscore = 1_000_000
|
||||
var n_exp = 1e10
|
||||
var n_exp_neg = 2.5e-3
|
||||
|
||||
// --- string literals ---
|
||||
var s_single = 'single'
|
||||
var s_double = "double"
|
||||
var s_escape = "tab\there\nnewline\\slash\"quote"
|
||||
var s_unicode = "\u0041\u0042"
|
||||
|
||||
// --- template literals ---
|
||||
var t_basic = `hello ${b} world`
|
||||
var t_nested = `a ${b + c} b ${d}`
|
||||
var t_expr = `result: ${b > 0 ? "yes" : "no"}`
|
||||
|
||||
// --- array literals ---
|
||||
var arr_empty = []
|
||||
var arr_simple = [1, 2, 3]
|
||||
var arr_mixed = [1, "two", true, null]
|
||||
var arr_nested = [[1, 2], [3, [4, 5]]]
|
||||
|
||||
// --- record/object literals ---
|
||||
var rec_empty = {}
|
||||
var rec_simple = {x: 1, y: 2}
|
||||
var rec_nested = {a: {b: {c: 3}}}
|
||||
var shorthand_var = 10
|
||||
var rec_shorthand = {shorthand_var}
|
||||
var rec_computed = {["key" + "1"]: 100}
|
||||
var rec_method = {
|
||||
greet() { return "hi" }
|
||||
}
|
||||
var rec_mixed = {
|
||||
name: "test",
|
||||
value: 42,
|
||||
nested: {inner: true},
|
||||
items: [1, 2, 3]
|
||||
}
|
||||
|
||||
// --- all binary arithmetic operators ---
|
||||
var arith_add = 1 + 2
|
||||
var arith_sub = 5 - 3
|
||||
var arith_mul = 4 * 5
|
||||
var arith_div = 10 / 3
|
||||
var arith_mod = 10 % 3
|
||||
var arith_pow = 2 ** 8
|
||||
|
||||
// --- comparison operators ---
|
||||
var cmp_lt = 1 < 2
|
||||
var cmp_gt = 2 > 1
|
||||
var cmp_lte = 1 <= 1
|
||||
var cmp_gte = 2 >= 2
|
||||
var cmp_eq = 1 == 1
|
||||
var cmp_neq = 1 != 2
|
||||
|
||||
// --- logical operators ---
|
||||
var log_and = true && false
|
||||
var log_or = false || true
|
||||
var log_not = !false
|
||||
|
||||
// --- bitwise operators ---
|
||||
var bit_and = 0xFF & 0x0F
|
||||
var bit_or = 0xF0 | 0x0F
|
||||
var bit_xor = 0xFF ^ 0x0F
|
||||
var bit_not = ~0
|
||||
var bit_shl = 1 << 8
|
||||
var bit_shr = 256 >> 4
|
||||
var bit_shru = -1 >>> 0
|
||||
|
||||
// --- nullish coalescing ---
|
||||
var nullish = null ?? "default"
|
||||
|
||||
// --- ternary operator ---
|
||||
var tern = b > 0 ? "pos" : "neg"
|
||||
var tern_nested = b > 0 ? (b > 10 ? "big" : "small") : "neg"
|
||||
|
||||
// --- comma operator ---
|
||||
var comma_result = (1, 2, 3)
|
||||
|
||||
// --- unary operators ---
|
||||
var unary_pos = +b
|
||||
var unary_neg = -b
|
||||
|
||||
// --- increment/decrement ---
|
||||
var inc_val = 0
|
||||
inc_val++
|
||||
inc_val--
|
||||
;++inc_val
|
||||
;--inc_val
|
||||
|
||||
// --- all compound assignments ---
|
||||
var ca = 10
|
||||
ca += 5
|
||||
ca -= 3
|
||||
ca *= 2
|
||||
ca /= 4
|
||||
ca %= 3
|
||||
ca **= 2
|
||||
ca <<= 1
|
||||
ca >>= 1
|
||||
ca >>>= 0
|
||||
ca &= 0xFF
|
||||
ca |= 0x01
|
||||
ca ^= 0x10
|
||||
ca &&= true
|
||||
ca ||= false
|
||||
ca ??= 1
|
||||
|
||||
// --- chained assignment ---
|
||||
var ch1, ch2
|
||||
ch1 = ch2 = 42
|
||||
|
||||
// --- property access ---
|
||||
var obj = {a: {b: {c: 1}}, items: [10, 20, 30]}
|
||||
var dot_access = obj.a
|
||||
var dot_chain = obj.a.b.c
|
||||
var bracket_access = obj["a"]
|
||||
var bracket_dynamic = obj["it" + "ems"]
|
||||
var bracket_index = obj.items[1]
|
||||
|
||||
// --- optional chaining ---
|
||||
var opt_obj = {x: {y: 1}}
|
||||
var opt_prop = opt_obj?.x
|
||||
var opt_deep = opt_obj?.x?.y
|
||||
var opt_null = null?.foo
|
||||
var opt_bracket = opt_obj?.["x"]
|
||||
var opt_call_obj = {f: function() { return 1 }}
|
||||
var opt_call = opt_call_obj?.f?.()
|
||||
|
||||
// --- function declarations ---
|
||||
function add(a, b) {
|
||||
return a + b
|
||||
}
|
||||
|
||||
function no_params() {
|
||||
return 42
|
||||
}
|
||||
|
||||
function with_default(x = 10, y = 20) {
|
||||
return x + y
|
||||
}
|
||||
|
||||
// --- function expressions ---
|
||||
var func_expr = function(x) { return x * 2 }
|
||||
var func_named = function multiply(x, y) { return x * y }
|
||||
|
||||
// --- arrow functions (all forms) ---
|
||||
var arrow_no_param = () => 0
|
||||
var arrow_one = x => x + 1
|
||||
var arrow_multi = (a, b) => a + b
|
||||
var arrow_block = (a, b) => { return a + b }
|
||||
var arrow_default = (x = 1, y = 2) => x + y
|
||||
var arrow_default_expr = (x = 1 + 2, y = arr_simple[0]) => x + y
|
||||
|
||||
// --- closures ---
|
||||
function make_counter() {
|
||||
var count = 0
|
||||
return function() {
|
||||
count += 1
|
||||
return count
|
||||
}
|
||||
}
|
||||
|
||||
function outer_fn() {
|
||||
var x = 10
|
||||
function middle() {
|
||||
var y = 20
|
||||
function inner() {
|
||||
return x + y
|
||||
}
|
||||
return inner()
|
||||
}
|
||||
return middle()
|
||||
}
|
||||
|
||||
// --- this in methods ---
|
||||
var counter = {
|
||||
val: 0,
|
||||
inc() { this.val += 1 },
|
||||
get() { return this.val }
|
||||
}
|
||||
|
||||
// --- if/else/else-if ---
|
||||
var if_result
|
||||
if (b > 0) {
|
||||
if_result = "positive"
|
||||
} else if (b == 0) {
|
||||
if_result = "zero"
|
||||
} else {
|
||||
if_result = "negative"
|
||||
}
|
||||
|
||||
// --- while loop ---
|
||||
var w = 0
|
||||
while (w < 5) {
|
||||
w += 1
|
||||
}
|
||||
|
||||
// --- do-while loop ---
|
||||
var dw = 0
|
||||
do {
|
||||
dw += 1
|
||||
} while (dw < 3)
|
||||
|
||||
// --- for loop ---
|
||||
var f_sum = 0
|
||||
for (var i = 0; i < 10; i++) {
|
||||
f_sum += i
|
||||
}
|
||||
|
||||
// --- for loop with break ---
|
||||
var fb = 0
|
||||
for (var j = 0; j < 100; j++) {
|
||||
if (j == 5) break
|
||||
fb = j
|
||||
}
|
||||
|
||||
// --- for loop with continue ---
|
||||
var fc = 0
|
||||
for (var k = 0; k < 10; k++) {
|
||||
if (k % 2 == 0) continue
|
||||
fc += k
|
||||
}
|
||||
|
||||
// --- labeled break ---
|
||||
outer: for (var x = 0; x < 3; x++) {
|
||||
for (var y = 0; y < 3; y++) {
|
||||
if (y == 1) break outer
|
||||
}
|
||||
}
|
||||
|
||||
// --- labeled continue ---
|
||||
var lc = 0
|
||||
loop: for (var m = 0; m < 3; m++) {
|
||||
for (var n = 0; n < 3; n++) {
|
||||
if (n == 1) continue loop
|
||||
lc += 1
|
||||
}
|
||||
}
|
||||
|
||||
// --- switch/case/default ---
|
||||
var sw
|
||||
switch (2) {
|
||||
case 1:
|
||||
sw = "one"
|
||||
break
|
||||
case 2:
|
||||
sw = "two"
|
||||
break
|
||||
case 3:
|
||||
sw = "three"
|
||||
break
|
||||
default:
|
||||
sw = "other"
|
||||
}
|
||||
|
||||
// --- try/catch/finally ---
|
||||
var tc
|
||||
try {
|
||||
throw "error"
|
||||
} catch (e) {
|
||||
tc = e
|
||||
}
|
||||
|
||||
var tcf = 0
|
||||
try {
|
||||
throw "err"
|
||||
} catch (e) {
|
||||
tcf = 1
|
||||
} finally {
|
||||
tcf += 10
|
||||
}
|
||||
|
||||
// --- try/finally (no catch) ---
|
||||
var tf = 0
|
||||
try {
|
||||
tf = 1
|
||||
} finally {
|
||||
tf += 1
|
||||
}
|
||||
|
||||
// --- delete operator ---
|
||||
var del_obj = {a: 1, b: 2}
|
||||
delete del_obj.a
|
||||
|
||||
// --- in operator ---
|
||||
var in_result = "b" in del_obj
|
||||
|
||||
// --- new expression ---
|
||||
var new_obj = new Object()
|
||||
|
||||
// --- go statement ---
|
||||
function async_task() { return 1 }
|
||||
function caller() { go async_task() }
|
||||
|
||||
// --- IIFE ---
|
||||
var iife = (function() { return 99 })()
|
||||
|
||||
// --- recursive function ---
|
||||
function factorial(n) {
|
||||
if (n <= 1) return 1
|
||||
return n * factorial(n - 1)
|
||||
}
|
||||
|
||||
// --- mutually recursive functions ---
|
||||
function is_even(n) {
|
||||
if (n == 0) return true
|
||||
return is_odd(n - 1)
|
||||
}
|
||||
function is_odd(n) {
|
||||
if (n == 0) return false
|
||||
return is_even(n - 1)
|
||||
}
|
||||
|
||||
// --- block scoping ---
|
||||
var block_val = 1
|
||||
{
|
||||
var block_val = 2
|
||||
}
|
||||
|
||||
// --- nested blocks ---
|
||||
{
|
||||
var nb = 1
|
||||
{
|
||||
var nb2 = nb + 1
|
||||
{
|
||||
var nb3 = nb2 + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- empty statement ---
|
||||
;
|
||||
|
||||
// --- parenthesized expression for precedence ---
|
||||
var prec = (1 + 2) * (3 + 4)
|
||||
|
||||
// --- complex expressions ---
|
||||
var complex = arr_simple[0] + rec_simple.x * (b > 0 ? 2 : 1)
|
||||
|
||||
// --- operator precedence chain ---
|
||||
var prec_chain = 1 + 2 * 3 ** 2 - 4 / 2 % 3
|
||||
|
||||
// --- regex literals ---
|
||||
var re = /hello/
|
||||
var re_flags = /world/gi
|
||||
|
||||
// --- void operator ---
|
||||
var v = void 0
|
||||
|
||||
// --- line comment at end ---
|
||||
var end = 1 // done
|
||||
Reference in New Issue
Block a user