/* 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 } } // --- disrupt and disruption --- function disrupt_test() { disrupt } function disruption_test() { var x = 1 } disruption { var y = 2 } function disrupt_with_disruption() { disrupt } disruption { var handled = true } // --- delete operator --- var del_obj = {a: 1, b: 2} delete del_obj.a // --- in operator --- var in_result = "b" in del_obj // --- 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 // --- line comment at end --- var end = 1 // done