mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-05-01 03:19:28 +08:00
Resolve merge conflicts with ChaiScript:develop. Upstream added nested namespace support (#675), grammar railroad diagrams (#673), and WASM exception support (#689). Conflicts in chaiscript_common.hpp, chaiscript_eval.hpp, and chaiscript_parser.hpp resolved by keeping both Using and Namespace_Block AST node types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
220 lines
4.4 KiB
ChaiScript
220 lines
4.4 KiB
ChaiScript
// 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)
|