// Regression test: exercises grammar constructs documented in grammar/chaiscript.ebnf // --- Variable declarations --- var a = 1 auto b = 2 global c = 3 const d = 42 assert_equal(1, a) assert_equal(2, b) assert_equal(3, c) assert_equal(42, d) // --- Reference variables --- var orig = 10 var &ref = orig ref = 20 assert_equal(20, orig) // --- Numeric literals --- assert_equal(255, 0xFF) assert_equal(255, 0xff) assert_equal(5, 0b101) assert_equal(42, 42) assert_equal(3.14, 3.14) // --- String interpolation --- var name = "world" assert_equal("hello world", "hello ${name}") // --- Escape sequences --- assert_equal("\n", "\n") assert_equal("\t", "\t") // --- Single-quoted char --- assert_equal('A', 'A') // --- Operators and precedence --- assert_equal(7, 1 + 2 * 3) assert_equal(true, 5 > 3 && 2 < 4) assert_equal(true, false || true) assert_equal(6, 3 << 1) assert_equal(1, 3 >> 1) assert_equal(5, 7 & 5) assert_equal(7, 5 | 3) assert_equal(6, 5 ^ 3) assert_equal(-1, ~0) // --- Ternary operator --- assert_equal("yes", true ? "yes" : "no") assert_equal("no", false ? "yes" : "no") // --- Prefix operators --- var x = 5 ++x assert_equal(6, x) --x assert_equal(5, x) assert_equal(true, !false) // --- Assignment operators --- var v = 10 v += 5; assert_equal(15, v) v -= 3; assert_equal(12, v) v *= 2; assert_equal(24, v) v /= 4; assert_equal(6, v) v %= 4; assert_equal(2, v) v <<= 2; assert_equal(8, v) v >>= 1; assert_equal(4, v) v |= 3; assert_equal(7, v) v &= 5; assert_equal(5, v) v ^= 3; assert_equal(6, v) // --- Lambda --- var add = fun(a, b) { a + b } assert_equal(5, add(2, 3)) // --- Lambda with capture --- var captured = 100 var get_captured = fun[captured]() { captured } assert_equal(100, get_captured()) // --- Function definition --- def multiply(a, b) { a * b } assert_equal(12, multiply(3, 4)) // --- Guard condition on function --- def abs_val(x) : x >= 0 { x } def abs_val(x) : x < 0 { -x } assert_equal(5, abs_val(5)) assert_equal(5, abs_val(-5)) // --- Class definition --- class Animal { attr sound def Animal(s) { this.sound = s } def speak() { this.sound } } var dog = Animal("woof") assert_equal("woof", dog.speak()) // --- Class with inheritance --- class Puppy : Animal { attr name def Puppy(n, s) { this.name = n; this.sound = s } def greet() { to_string(this.name) + " says " + to_string(this.speak()) } } var p = Puppy("Rex", "yip") assert_equal("Rex says yip", p.greet()) // --- Control flow: if/else --- var result = "" if (true) { result = "yes" } else { result = "no" } assert_equal("yes", result) // --- Control flow: while --- var counter = 0 while (counter < 3) { ++counter } assert_equal(3, counter) // --- Control flow: for --- var sum = 0 for (var i = 0; i < 5; ++i) { sum += i } assert_equal(10, sum) // --- Control flow: ranged for --- var items = [10, 20, 30] var total = 0 for (item : items) { total += item } assert_equal(60, total) // --- Switch/case --- def classify(n) { var label = "" switch (n) { case (1) { label = "one"; break } case (2) { label = "two"; break } default { label = "other" } } return label } assert_equal("one", classify(1)) assert_equal("two", classify(2)) assert_equal("other", classify(99)) // --- Try/catch/finally --- var caught = false var finalized = false try { throw("oops") } catch (e) { caught = true } finally { finalized = true } assert_true(caught) assert_true(finalized) // --- Inline containers --- var vec = [1, 2, 3] assert_equal(3, vec.size()) var m = ["a": 1, "b": 2] assert_equal(1, m["a"]) var r = [1, 2, 3, 4, 5] assert_equal(5, r.size()) // --- Dot access chaining --- assert_equal(3, [1, 2, 3].size()) // --- Array access --- var arr = [10, 20, 30] assert_equal(20, arr[1]) // --- Backtick identifier --- var `my var` = 42 assert_equal(42, `my var`) // --- Special identifiers --- assert_equal(true, true) assert_equal(false, false) // --- Nested block --- var block_result = 0 { block_result = 42 } assert_equal(42, block_result) // --- Break and continue --- var break_sum = 0 for (var i = 0; i < 10; ++i) { if (i == 5) { break } break_sum += i } assert_equal(10, break_sum) var cont_sum = 0 for (var i = 0; i < 5; ++i) { if (i == 2) { continue } cont_sum += i } assert_equal(8, cont_sum) // --- Return from function --- def early_return(n) { if (n > 0) { return "positive" } return "non-positive" } assert_equal("positive", early_return(1)) assert_equal("non-positive", early_return(-1)) // --- Colon assignment --- var ca = 0 ca := 99 assert_equal(99, ca)