#!/usr/bin/env node // Test js_of_ocaml build of SX kernel const path = require('path'); require(path.join(__dirname, '../_build/default/browser/sx_browser.bc.js')); const sx = globalThis.SxKernel; console.log('Engine:', sx.engine()); const tests = [ ['(+ 1 2)', 3], ['(- 10 3)', 7], ['(* 6 7)', 42], ['(/ 10 2)', 5], ['(= 5 5)', true], ['(< 3 5)', true], ['(> 5 3)', true], ['(not false)', true], ['(inc 5)', 6], ['(dec 5)', 4], ['(len (list 1 2 3))', 3], ['(len "hello")', 5], ['(first (list 10 20))', 10], ['(nth "hello" 0)', 'h'], ['(nth "hello" 4)', 'o'], ['(str "a" "b")', 'ab'], ['(join ", " (list "a" "b" "c"))', 'a, b, c'], ['(let ((x 10) (y 20)) (+ x y))', 30], ['(if true "yes" "no")', 'yes'], ['(cond (= 1 2) "one" :else "other")', 'other'], ['(case 2 1 "one" 2 "two" :else "other")', 'two'], ['(render-to-html (list (quote div) "hello"))', '
hello
'], ['(render-to-html (list (quote span) (list (quote b) "bold")))', 'bold'], // Lambda + closure ['(let ((add (fn (a b) (+ a b)))) (add 3 4))', 7], ['(let ((x 10)) (let ((f (fn () x))) (f)))', 10], // Higher-order ['(len (filter (fn (x) (> x 2)) (list 1 2 3 4 5)))', 3], // Recursion ['(let ((fact (fn (n) (if (<= n 1) 1 (* n (fact (- n 1))))))) (fact 5))', 120], ]; let passed = 0, failed = 0; for (const [expr, expected] of tests) { try { const result = sx.eval(expr); const ok = typeof expected === 'object' ? result && result._type === expected._type : result === expected; if (ok) { passed++; } else { console.log(` FAIL: ${expr} = ${JSON.stringify(result)} (expected ${JSON.stringify(expected)})`); failed++; } } catch (e) { console.log(` ERROR: ${expr}: ${e.message || e}`); failed++; } } console.log(`${passed} passed, ${failed} failed`); process.exit(failed > 0 ? 1 : 0);