From 12b6c3544e8b4997c442613bba34c813f63b9632 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 17 Feb 2026 11:23:12 -0600 Subject: [PATCH] fix all core script syntax issues --- benchmarks/binarytree.ce | 13 +- benchmarks/eratosthenes.ce | 11 +- benchmarks/fannkuch.ce | 79 ++++++----- benchmarks/js_perf.ce | 244 ++++++++++++++++------------------ benchmarks/mandelbrot.ce | 34 +++-- benchmarks/montecarlo.ce | 9 +- benchmarks/nbody.ce | 165 +++++++++++++---------- benchmarks/nota.ce | 41 +++--- benchmarks/spectral-norm.ce | 42 +++--- benchmarks/wota.ce | 37 +----- benchmarks/wota_nota_json.ce | 79 +++-------- cellfs.cm | 242 +++++++++++++++++----------------- examples/nat_client.ce | 14 +- internal/shop.cm | 2 +- tests/blob.cm | 247 +++++++++++++++++++---------------- tests/cat.cm | 10 +- tests/chunkread.cm | 19 +-- tests/disrupt.cm | 2 +- tests/fit.cm | 122 ++++++++--------- tests/http.cm | 2 +- tests/kim.cm | 18 +-- tests/miniz.cm | 116 +++++++++------- tests/nota.cm | 62 +++++---- tests/overling.cm | 19 +-- tests/parseq.cm | 17 +-- tests/text.cm | 96 +++++++------- tests/toml.cm | 19 +-- tests/underling_actor.ce | 2 +- tests/use.cm | 7 +- tests/wota.cm | 37 +++--- 30 files changed, 910 insertions(+), 897 deletions(-) diff --git a/benchmarks/binarytree.ce b/benchmarks/binarytree.ce index 74c2d680..0a386ef0 100644 --- a/benchmarks/binarytree.ce +++ b/benchmarks/binarytree.ce @@ -1,14 +1,16 @@ function mainThread() { var maxDepth = max(6, Number(arg[0] || 16)); - var stretchDepth = maxDepth + 1; var check = itemCheck(bottomUpTree(stretchDepth)); + var longLivedTree = null + var depth = null + var iterations = null log.console(`stretch tree of depth ${stretchDepth}\t check: ${check}`); - var longLivedTree = bottomUpTree(maxDepth); + longLivedTree = bottomUpTree(maxDepth); - for (var depth = 4; depth <= maxDepth; depth += 2) { - var iterations = 1 << maxDepth - depth + 4; + for (depth = 4; depth <= maxDepth; depth += 2) { + iterations = 1 << maxDepth - depth + 4; work(iterations, depth); } @@ -17,7 +19,8 @@ function mainThread() { function work(iterations, depth) { var check = 0; - for (var i = 0; i < iterations; i++) + var i = 0 + for (i = 0; i < iterations; i++) check += itemCheck(bottomUpTree(depth)); log.console(`${iterations}\t trees of depth ${depth}\t check: ${check}`); } diff --git a/benchmarks/eratosthenes.ce b/benchmarks/eratosthenes.ce index 6562e89e..6c6abdad 100644 --- a/benchmarks/eratosthenes.ce +++ b/benchmarks/eratosthenes.ce @@ -1,6 +1,9 @@ var blob = use('blob') var math = use('math/radians') +var i = 0 +var j = 0 + function eratosthenes (n) { var sieve = blob(n, true) var sqrtN = whole(math.sqrt(n)); @@ -9,7 +12,7 @@ function eratosthenes (n) { if (sieve.read_logical(i)) for (j = i * i; j <= n; j += i) sieve.write_bit(j, false); - + return sieve; } @@ -17,9 +20,9 @@ var sieve = eratosthenes(10000000); stone(sieve) var c = 0 -for (var i = 0; i < length(sieve); i++) +for (i = 0; i < length(sieve); i++) if (sieve.read_logical(i)) c++ - + log.console(c) -$stop() \ No newline at end of file +$stop() diff --git a/benchmarks/fannkuch.ce b/benchmarks/fannkuch.ce index a2f371f5..5d5af000 100644 --- a/benchmarks/fannkuch.ce +++ b/benchmarks/fannkuch.ce @@ -1,58 +1,65 @@ function fannkuch(n) { - var perm1 = [n] - for (var i = 0; i < n; i++) perm1[i] = i + var perm1 = [n] + var i = 0 + var k = null + var r = null + var t = null + var p0 = null + var j = null + var more = null + for (i = 0; i < n; i++) perm1[i] = i var perm = [n] - var count = [n] - var f = 0, flips = 0, nperm = 0, checksum = 0 - var i, k, r - + var count = [n] + var f = 0 + var flips = 0 + var nperm = 0 + var checksum = 0 + r = n - while (r > 0) { - i = 0 - while (r != 1) { count[r-1] = r; r -= 1 } - while (i < n) { perm[i] = perm1[i]; i += 1 } - - // Count flips and update max and checksum + while (r > 0) { + i = 0 + while (r != 1) { count[r-1] = r; r -= 1 } + while (i < n) { perm[i] = perm1[i]; i += 1 } + f = 0 - k = perm[0] + k = perm[0] while (k != 0) { - i = 0 - while (2*i < k) { - var t = perm[i]; perm[i] = perm[k-i]; perm[k-i] = t - i += 1 + i = 0 + while (2*i < k) { + t = perm[i]; perm[i] = perm[k-i]; perm[k-i] = t + i += 1 } k = perm[0] - f += 1 - } - if (f > flips) flips = f + f += 1 + } + if (f > flips) flips = f if ((nperm & 0x1) == 0) checksum += f; else checksum -= f - - // Use incremental change to generate another permutation - var more = true - while (more) { + + more = true + while (more) { if (r == n) { - log.console( checksum ) - return flips + log.console( checksum ) + return flips } - var p0 = perm1[0] + p0 = perm1[0] i = 0 while (i < r) { - var j = i + 1 + j = i + 1 perm1[i] = perm1[j] - i = j + i = j } - perm1[r] = p0 - - count[r] -= 1 - if (count[r] > 0) more = false; else r += 1 + perm1[r] = p0 + + count[r] -= 1 + if (count[r] > 0) more = false; else r += 1 } nperm += 1 } - return flips; + return flips; } - + var n = arg[0] || 10 - + log.console(`Pfannkuchen(${n}) = ${fannkuch(n)}`) $stop() \ No newline at end of file diff --git a/benchmarks/js_perf.ce b/benchmarks/js_perf.ce index 5586f166..93f49756 100644 --- a/benchmarks/js_perf.ce +++ b/benchmarks/js_perf.ce @@ -1,22 +1,12 @@ var time = use('time') var math = use('math/radians') -//////////////////////////////////////////////////////////////////////////////// -// JavaScript Performance Benchmark Suite -// Tests core JS operations: property access, function calls, arithmetic, etc. -//////////////////////////////////////////////////////////////////////////////// - -// Test configurations def iterations = { simple: 10000000, medium: 1000000, complex: 100000 }; -//////////////////////////////////////////////////////////////////////////////// -// Utility: measureTime(fn) => how long fn() takes in seconds -//////////////////////////////////////////////////////////////////////////////// - function measureTime(fn) { var start = time.number(); fn(); @@ -24,26 +14,24 @@ function measureTime(fn) { return (end - start); } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: Property Access -//////////////////////////////////////////////////////////////////////////////// - function benchPropertyAccess() { var obj = { a: 1, b: 2, c: 3, d: 4, e: 5, nested: { x: 10, y: 20, z: 30 } }; - + var readTime = measureTime(function() { var sum = 0; - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { sum += obj.a + obj.b + obj.c + obj.d + obj.e; sum += obj.nested.x + obj.nested.y + obj.nested.z; } }); - + var writeTime = measureTime(function() { - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { obj.a = i; obj.b = i + 1; obj.c = i + 2; @@ -51,49 +39,48 @@ function benchPropertyAccess() { obj.nested.y = i * 3; } }); - + return { readTime: readTime, writeTime: writeTime }; } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: Function Calls -//////////////////////////////////////////////////////////////////////////////// - function benchFunctionCalls() { function add(a, b) { return a + b; } function multiply(a, b) { return a * b; } function complexCalc(a, b, c) { return (a + b) * c / 2; } - + var obj = { method: function(x) { return x * 2; }, nested: { deepMethod: function(x, y) { return x + y; } } }; - + var simpleCallTime = measureTime(function() { var result = 0; - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { result = add(i, 1); result = multiply(result, 2); } }); - + var methodCallTime = measureTime(function() { var result = 0; - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { result = obj.method(i); result = obj.nested.deepMethod(result, i); } }); - + var complexCallTime = measureTime(function() { var result = 0; - for (var i = 0; i < iterations.medium; i++) { + var i = 0 + for (i = 0; i < iterations.medium; i++) { result = complexCalc(i, i + 1, i + 2); } }); - + return { simpleCallTime: simpleCallTime, methodCallTime: methodCallTime, @@ -101,37 +88,39 @@ function benchFunctionCalls() { }; } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: Array Operations -//////////////////////////////////////////////////////////////////////////////// - function benchArrayOps() { + var i = 0 + var pushTime = measureTime(function() { var arr = []; - for (var i = 0; i < iterations.medium; i++) { - push(arr, i); + var j = 0 + for (j = 0; j < iterations.medium; j++) { + push(arr, j); } }); - + var arr = []; - for (var i = 0; i < 10000; i++) push(arr, i); - + for (i = 0; i < 10000; i++) push(arr, i); + var accessTime = measureTime(function() { var sum = 0; - for (var i = 0; i < iterations.medium; i++) { - sum += arr[i % 10000]; + var j = 0 + for (j = 0; j < iterations.medium; j++) { + sum += arr[j % 10000]; } }); - + var iterateTime = measureTime(function() { var sum = 0; - for (var j = 0; j < 1000; j++) { - for (var i = 0; i < length(arr); i++) { - sum += arr[i]; + var j = 0 + var k = 0 + for (j = 0; j < 1000; j++) { + for (k = 0; k < length(arr); k++) { + sum += arr[k]; } } }); - + return { pushTime: pushTime, accessTime: accessTime, @@ -139,27 +128,27 @@ function benchArrayOps() { }; } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: Object Creation -//////////////////////////////////////////////////////////////////////////////// - function benchObjectCreation() { var literalTime = measureTime(function() { - for (var i = 0; i < iterations.medium; i++) { - var obj = { x: i, y: i * 2, z: i * 3 }; + var i = 0 + var obj = null + for (i = 0; i < iterations.medium; i++) { + obj = { x: i, y: i * 2, z: i * 3 }; } }); - + function Point(x, y) { return {x,y} } - + var defructorTime = measureTime(function() { - for (var i = 0; i < iterations.medium; i++) { - var p = Point(i, i * 2); + var i = 0 + var p = null + for (i = 0; i < iterations.medium; i++) { + p = Point(i, i * 2); } }); - + var protoObj = { x: 0, y: 0, @@ -168,15 +157,17 @@ function benchObjectCreation() { this.y += dy; } }; - + var prototypeTime = measureTime(function() { - for (var i = 0; i < iterations.medium; i++) { - var obj = meme(protoObj); + var i = 0 + var obj = null + for (i = 0; i < iterations.medium; i++) { + obj = meme(protoObj); obj.x = i; obj.y = i * 2; } }); - + return { literalTime: literalTime, defructorTime: defructorTime, @@ -184,36 +175,39 @@ function benchObjectCreation() { }; } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: String Operations -//////////////////////////////////////////////////////////////////////////////// - function benchStringOps() { + var i = 0 + var strings = []; + var concatTime = measureTime(function() { var str = ""; - for (var i = 0; i < iterations.complex; i++) { - str = "test" + i + "value"; + var j = 0 + for (j = 0; j < iterations.complex; j++) { + str = "test" + j + "value"; } }); - - var strings = []; - for (var i = 0; i < 1000; i++) { + + for (i = 0; i < 1000; i++) { push(strings, "string" + i); } - + var joinTime = measureTime(function() { - for (var i = 0; i < iterations.complex; i++) { - var result = text(strings, ","); + var j = 0 + var result = null + for (j = 0; j < iterations.complex; j++) { + result = text(strings, ","); } }); - + var splitTime = measureTime(function() { var str = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p"; - for (var i = 0; i < iterations.medium; i++) { - var parts = array(str, ","); + var j = 0 + var parts = null + for (j = 0; j < iterations.medium; j++) { + parts = array(str, ","); } }); - + return { concatTime: concatTime, joinTime: joinTime, @@ -221,35 +215,34 @@ function benchStringOps() { }; } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: Arithmetic Operations -//////////////////////////////////////////////////////////////////////////////// - function benchArithmetic() { var intMathTime = measureTime(function() { var result = 1; - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { result = ((result + i) * 2 - 1) / 3; result = result % 1000 + 1; } }); - + var floatMathTime = measureTime(function() { var result = 1.5; - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { result = math.sine(result) + math.cosine(i * 0.01); result = math.sqrt(abs(result)) + 0.1; } }); - + var bitwiseTime = measureTime(function() { var result = 0; - for (var i = 0; i < iterations.simple; i++) { + var i = 0 + for (i = 0; i < iterations.simple; i++) { result = (result ^ i) & 0xFFFF; result = (result << 1) | (result >> 15); } }); - + return { intMathTime: intMathTime, floatMathTime: floatMathTime, @@ -257,134 +250,123 @@ function benchArithmetic() { }; } -//////////////////////////////////////////////////////////////////////////////// -// Benchmark: Closure Operations -//////////////////////////////////////////////////////////////////////////////// - function benchClosures() { + var i = 0 + function makeAdder(x) { return function(y) { return x + y; }; } - + var closureCreateTime = measureTime(function() { var funcs = []; - for (var i = 0; i < iterations.medium; i++) { - push(funcs, makeAdder(i)); + var j = 0 + for (j = 0; j < iterations.medium; j++) { + push(funcs, makeAdder(j)); } }); - + var adders = []; - for (var i = 0; i < 1000; i++) { + for (i = 0; i < 1000; i++) { push(adders, makeAdder(i)); } - + var closureCallTime = measureTime(function() { var sum = 0; - for (var i = 0; i < iterations.medium; i++) { - sum += adders[i % 1000](i); + var j = 0 + for (j = 0; j < iterations.medium; j++) { + sum += adders[j % 1000](j); } }); - + return { closureCreateTime: closureCreateTime, closureCallTime: closureCallTime }; } -//////////////////////////////////////////////////////////////////////////////// -// Main benchmark runner -//////////////////////////////////////////////////////////////////////////////// - log.console("JavaScript Performance Benchmark"); log.console("======================\n"); -// Property Access log.console("BENCHMARK: Property Access"); var propResults = benchPropertyAccess(); -log.console(" Read time: " + propResults.readTime.toFixed(3) + "s => " + +log.console(" Read time: " + propResults.readTime.toFixed(3) + "s => " + (iterations.simple / propResults.readTime).toFixed(1) + " reads/sec [" + (propResults.readTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); -log.console(" Write time: " + propResults.writeTime.toFixed(3) + "s => " + +log.console(" Write time: " + propResults.writeTime.toFixed(3) + "s => " + (iterations.simple / propResults.writeTime).toFixed(1) + " writes/sec [" + (propResults.writeTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); log.console(""); -// Function Calls log.console("BENCHMARK: Function Calls"); var funcResults = benchFunctionCalls(); -log.console(" Simple calls: " + funcResults.simpleCallTime.toFixed(3) + "s => " + +log.console(" Simple calls: " + funcResults.simpleCallTime.toFixed(3) + "s => " + (iterations.simple / funcResults.simpleCallTime).toFixed(1) + " calls/sec [" + (funcResults.simpleCallTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); -log.console(" Method calls: " + funcResults.methodCallTime.toFixed(3) + "s => " + +log.console(" Method calls: " + funcResults.methodCallTime.toFixed(3) + "s => " + (iterations.simple / funcResults.methodCallTime).toFixed(1) + " calls/sec [" + (funcResults.methodCallTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); -log.console(" Complex calls: " + funcResults.complexCallTime.toFixed(3) + "s => " + +log.console(" Complex calls: " + funcResults.complexCallTime.toFixed(3) + "s => " + (iterations.medium / funcResults.complexCallTime).toFixed(1) + " calls/sec [" + (funcResults.complexCallTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); log.console(""); -// Array Operations log.console("BENCHMARK: Array Operations"); var arrayResults = benchArrayOps(); -log.console(" Push: " + arrayResults.pushTime.toFixed(3) + "s => " + +log.console(" Push: " + arrayResults.pushTime.toFixed(3) + "s => " + (iterations.medium / arrayResults.pushTime).toFixed(1) + " pushes/sec [" + (arrayResults.pushTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); -log.console(" Access: " + arrayResults.accessTime.toFixed(3) + "s => " + +log.console(" Access: " + arrayResults.accessTime.toFixed(3) + "s => " + (iterations.medium / arrayResults.accessTime).toFixed(1) + " accesses/sec [" + (arrayResults.accessTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); -log.console(" Iterate: " + arrayResults.iterateTime.toFixed(3) + "s => " + +log.console(" Iterate: " + arrayResults.iterateTime.toFixed(3) + "s => " + (1000 / arrayResults.iterateTime).toFixed(1) + " full iterations/sec"); log.console(""); -// Object Creation log.console("BENCHMARK: Object Creation"); var objResults = benchObjectCreation(); -log.console(" Literal: " + objResults.literalTime.toFixed(3) + "s => " + +log.console(" Literal: " + objResults.literalTime.toFixed(3) + "s => " + (iterations.medium / objResults.literalTime).toFixed(1) + " creates/sec [" + (objResults.literalTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); -log.console(" Constructor: " + objResults.defructorTime.toFixed(3) + "s => " + +log.console(" Constructor: " + objResults.defructorTime.toFixed(3) + "s => " + (iterations.medium / objResults.defructorTime).toFixed(1) + " creates/sec [" + (objResults.defructorTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); -log.console(" Prototype: " + objResults.prototypeTime.toFixed(3) + "s => " + +log.console(" Prototype: " + objResults.prototypeTime.toFixed(3) + "s => " + (iterations.medium / objResults.prototypeTime).toFixed(1) + " creates/sec [" + (objResults.prototypeTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); log.console(""); -// String Operations log.console("BENCHMARK: String Operations"); var strResults = benchStringOps(); -log.console(" Concat: " + strResults.concatTime.toFixed(3) + "s => " + +log.console(" Concat: " + strResults.concatTime.toFixed(3) + "s => " + (iterations.complex / strResults.concatTime).toFixed(1) + " concats/sec [" + (strResults.concatTime / iterations.complex * 1e9).toFixed(1) + " ns/op]"); -log.console(" Join: " + strResults.joinTime.toFixed(3) + "s => " + +log.console(" Join: " + strResults.joinTime.toFixed(3) + "s => " + (iterations.complex / strResults.joinTime).toFixed(1) + " joins/sec [" + (strResults.joinTime / iterations.complex * 1e9).toFixed(1) + " ns/op]"); -log.console(" Split: " + strResults.splitTime.toFixed(3) + "s => " + +log.console(" Split: " + strResults.splitTime.toFixed(3) + "s => " + (iterations.medium / strResults.splitTime).toFixed(1) + " splits/sec [" + (strResults.splitTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); log.console(""); -// Arithmetic Operations log.console("BENCHMARK: Arithmetic Operations"); var mathResults = benchArithmetic(); -log.console(" Integer math: " + mathResults.intMathTime.toFixed(3) + "s => " + +log.console(" Integer math: " + mathResults.intMathTime.toFixed(3) + "s => " + (iterations.simple / mathResults.intMathTime).toFixed(1) + " ops/sec [" + (mathResults.intMathTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); -log.console(" Float math: " + mathResults.floatMathTime.toFixed(3) + "s => " + +log.console(" Float math: " + mathResults.floatMathTime.toFixed(3) + "s => " + (iterations.simple / mathResults.floatMathTime).toFixed(1) + " ops/sec [" + (mathResults.floatMathTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); -log.console(" Bitwise: " + mathResults.bitwiseTime.toFixed(3) + "s => " + +log.console(" Bitwise: " + mathResults.bitwiseTime.toFixed(3) + "s => " + (iterations.simple / mathResults.bitwiseTime).toFixed(1) + " ops/sec [" + (mathResults.bitwiseTime / iterations.simple * 1e9).toFixed(1) + " ns/op]"); log.console(""); -// Closures log.console("BENCHMARK: Closures"); var closureResults = benchClosures(); -log.console(" Create: " + closureResults.closureCreateTime.toFixed(3) + "s => " + +log.console(" Create: " + closureResults.closureCreateTime.toFixed(3) + "s => " + (iterations.medium / closureResults.closureCreateTime).toFixed(1) + " creates/sec [" + (closureResults.closureCreateTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); -log.console(" Call: " + closureResults.closureCallTime.toFixed(3) + "s => " + +log.console(" Call: " + closureResults.closureCallTime.toFixed(3) + "s => " + (iterations.medium / closureResults.closureCallTime).toFixed(1) + " calls/sec [" + (closureResults.closureCallTime / iterations.medium * 1e9).toFixed(1) + " ns/op]"); log.console(""); diff --git a/benchmarks/mandelbrot.ce b/benchmarks/mandelbrot.ce index 1e8d7b4b..a651a8b5 100644 --- a/benchmarks/mandelbrot.ce +++ b/benchmarks/mandelbrot.ce @@ -1,40 +1,46 @@ var blob = use('blob') -var iter = 50, limit = 2.0; -var zr, zi, cr, ci, tr, ti; +var iter = 50 +var limit = 2.0 +var zr = null +var zi = null +var cr = null +var ci = null +var tr = null +var ti = null +var y = 0 +var x = 0 +var i = 0 +var row = null var h = Number(arg[0]) || 500 var w = h log.console(`P4\n${w} ${h}`); -for (var y = 0; y < h; ++y) { - // Create a blob for the row - we need w bits - var row = blob(w); +for (y = 0; y < h; ++y) { + row = blob(w); - for (var x = 0; x < w; ++x) { - zr = zi = tr = ti = 0; + for (x = 0; x < w; ++x) { + zr = 0; zi = 0; tr = 0; ti = 0; cr = 2 * x / w - 1.5; ci = 2 * y / h - 1; - for (var i = 0; i < iter && (tr + ti <= limit * limit); ++i) { + for (i = 0; i < iter && (tr + ti <= limit * limit); ++i) { zi = 2 * zr * zi + ci; zr = tr - ti + cr; tr = zr * zr; ti = zi * zi; } - // Write a 1 bit if inside the set, 0 if outside if (tr + ti <= limit * limit) row.write_bit(1); else row.write_bit(0); } - - // Convert the blob to stone (immutable) to prepare for output + stone(row) - - // Output the blob data as raw bytes - log.console(text(row, 'b')); + + log.console(text(row, 'b')); } $stop() \ No newline at end of file diff --git a/benchmarks/montecarlo.ce b/benchmarks/montecarlo.ce index dfd867fa..cab2d1ac 100644 --- a/benchmarks/montecarlo.ce +++ b/benchmarks/montecarlo.ce @@ -1,9 +1,12 @@ var math = use('math/radians') var N = 1000000; var num = 0; -for (var i = 0; i < N; i ++) { - var x = 2 * $random(); - var y = $random(); +var i = 0 +var x = null +var y = null +for (i = 0; i < N; i++) { + x = 2 * $random(); + y = $random(); if (y < math.sine(x * x)) num++; } diff --git a/benchmarks/nbody.ce b/benchmarks/nbody.ce index 5786127c..05c3f17d 100644 --- a/benchmarks/nbody.ce +++ b/benchmarks/nbody.ce @@ -2,60 +2,60 @@ var math = use('math/radians') var SOLAR_MASS = 4 * pi * pi; var DAYS_PER_YEAR = 365.24; -function Body(x, y, z, vx, vy, vz, mass) { - return {x, y, z, vx, vy, vz, mass}; +function Body(p) { + return {x: p.x, y: p.y, z: p.z, vx: p.vx, vy: p.vy, vz: p.vz, mass: p.mass}; } function Jupiter() { - return Body( - 4.84143144246472090e+00, - -1.16032004402742839e+00, - -1.03622044471123109e-01, - 1.66007664274403694e-03 * DAYS_PER_YEAR, - 7.69901118419740425e-03 * DAYS_PER_YEAR, - -6.90460016972063023e-05 * DAYS_PER_YEAR, - 9.54791938424326609e-04 * SOLAR_MASS - ); + return Body({ + x: 4.84143144246472090e+00, + y: -1.16032004402742839e+00, + z: -1.03622044471123109e-01, + vx: 1.66007664274403694e-03 * DAYS_PER_YEAR, + vy: 7.69901118419740425e-03 * DAYS_PER_YEAR, + vz: -6.90460016972063023e-05 * DAYS_PER_YEAR, + mass: 9.54791938424326609e-04 * SOLAR_MASS + }); } function Saturn() { - return Body( - 8.34336671824457987e+00, - 4.12479856412430479e+00, - -4.03523417114321381e-01, - -2.76742510726862411e-03 * DAYS_PER_YEAR, - 4.99852801234917238e-03 * DAYS_PER_YEAR, - 2.30417297573763929e-05 * DAYS_PER_YEAR, - 2.85885980666130812e-04 * SOLAR_MASS - ); + return Body({ + x: 8.34336671824457987e+00, + y: 4.12479856412430479e+00, + z: -4.03523417114321381e-01, + vx: -2.76742510726862411e-03 * DAYS_PER_YEAR, + vy: 4.99852801234917238e-03 * DAYS_PER_YEAR, + vz: 2.30417297573763929e-05 * DAYS_PER_YEAR, + mass: 2.85885980666130812e-04 * SOLAR_MASS + }); } function Uranus() { - return Body( - 1.28943695621391310e+01, - -1.51111514016986312e+01, - -2.23307578892655734e-01, - 2.96460137564761618e-03 * DAYS_PER_YEAR, - 2.37847173959480950e-03 * DAYS_PER_YEAR, - -2.96589568540237556e-05 * DAYS_PER_YEAR, - 4.36624404335156298e-05 * SOLAR_MASS - ); + return Body({ + x: 1.28943695621391310e+01, + y: -1.51111514016986312e+01, + z: -2.23307578892655734e-01, + vx: 2.96460137564761618e-03 * DAYS_PER_YEAR, + vy: 2.37847173959480950e-03 * DAYS_PER_YEAR, + vz: -2.96589568540237556e-05 * DAYS_PER_YEAR, + mass: 4.36624404335156298e-05 * SOLAR_MASS + }); } function Neptune() { - return Body( - 1.53796971148509165e+01, - -2.59193146099879641e+01, - 1.79258772950371181e-01, - 2.68067772490389322e-03 * DAYS_PER_YEAR, - 1.62824170038242295e-03 * DAYS_PER_YEAR, - -9.51592254519715870e-05 * DAYS_PER_YEAR, - 5.15138902046611451e-05 * SOLAR_MASS - ); + return Body({ + x: 1.53796971148509165e+01, + y: -2.59193146099879641e+01, + z: 1.79258772950371181e-01, + vx: 2.68067772490389322e-03 * DAYS_PER_YEAR, + vy: 1.62824170038242295e-03 * DAYS_PER_YEAR, + vz: -9.51592254519715870e-05 * DAYS_PER_YEAR, + mass: 5.15138902046611451e-05 * SOLAR_MASS + }); } function Sun() { - return Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS); + return Body({x: 0.0, y: 0.0, z: 0.0, vx: 0.0, vy: 0.0, vz: 0.0, mass: SOLAR_MASS}); } var bodies = Array(Sun(), Jupiter(), Saturn(), Uranus(), Neptune()); @@ -65,15 +65,18 @@ function offsetMomentum() { var py = 0; var pz = 0; var size = length(bodies); - for (var i = 0; i < size; i++) { - var body = bodies[i]; - var mass = body.mass; + var i = 0 + var body = null + var mass = null + for (i = 0; i < size; i++) { + body = bodies[i]; + mass = body.mass; px += body.vx * mass; py += body.vy * mass; pz += body.vz * mass; } - var body = bodies[0]; + body = bodies[0]; body.vx = -px / SOLAR_MASS; body.vy = -py / SOLAR_MASS; body.vz = -pz / SOLAR_MASS; @@ -81,27 +84,42 @@ function offsetMomentum() { function advance(dt) { var size = length(bodies); + var i = 0 + var j = 0 + var bodyi = null + var bodyj = null + var vxi = null + var vyi = null + var vzi = null + var dx = null + var dy = null + var dz = null + var d2 = null + var mag = null + var massj = null + var massi = null + var body = null - for (var i = 0; i < size; i++) { - var bodyi = bodies[i]; - var vxi = bodyi.vx; - var vyi = bodyi.vy; - var vzi = bodyi.vz; - for (var j = i + 1; j < size; j++) { - var bodyj = bodies[j]; - var dx = bodyi.x - bodyj.x; - var dy = bodyi.y - bodyj.y; - var dz = bodyi.z - bodyj.z; + for (i = 0; i < size; i++) { + bodyi = bodies[i]; + vxi = bodyi.vx; + vyi = bodyi.vy; + vzi = bodyi.vz; + for (j = i + 1; j < size; j++) { + bodyj = bodies[j]; + dx = bodyi.x - bodyj.x; + dy = bodyi.y - bodyj.y; + dz = bodyi.z - bodyj.z; - var d2 = dx * dx + dy * dy + dz * dz; - var mag = dt / (d2 * math.sqrt(d2)); + d2 = dx * dx + dy * dy + dz * dz; + mag = dt / (d2 * math.sqrt(d2)); - var massj = bodyj.mass; + massj = bodyj.mass; vxi -= dx * massj * mag; vyi -= dy * massj * mag; vzi -= dz * massj * mag; - var massi = bodyi.mass; + massi = bodyi.mass; bodyj.vx += dx * massi * mag; bodyj.vy += dy * massi * mag; bodyj.vz += dz * massi * mag; @@ -111,8 +129,8 @@ function advance(dt) { bodyi.vz = vzi; } - for (var i = 0; i < size; i++) { - var body = bodies[i]; + for (i = 0; i < size; i++) { + body = bodies[i]; body.x += dt * body.vx; body.y += dt * body.vy; body.z += dt * body.vz; @@ -122,20 +140,28 @@ function advance(dt) { function energy() { var e = 0; var size = length(bodies); + var i = 0 + var j = 0 + var bodyi = null + var bodyj = null + var dx = null + var dy = null + var dz = null + var distance = null - for (var i = 0; i < size; i++) { - var bodyi = bodies[i]; + for (i = 0; i < size; i++) { + bodyi = bodies[i]; - e += 0.5 * bodyi.mass * ( bodyi.vx * bodyi.vx + + e += 0.5 * bodyi.mass * ( bodyi.vx * bodyi.vx + bodyi.vy * bodyi.vy + bodyi.vz * bodyi.vz ); - for (var j = i + 1; j < size; j++) { - var bodyj = bodies[j]; - var dx = bodyi.x - bodyj.x; - var dy = bodyi.y - bodyj.y; - var dz = bodyi.z - bodyj.z; + for (j = i + 1; j < size; j++) { + bodyj = bodies[j]; + dx = bodyi.x - bodyj.x; + dy = bodyi.y - bodyj.y; + dz = bodyi.z - bodyj.z; - var distance = math.sqrt(dx * dx + dy * dy + dz * dz); + distance = math.sqrt(dx * dx + dy * dy + dz * dz); e -= (bodyi.mass * bodyj.mass) / distance; } } @@ -143,12 +169,13 @@ function energy() { } var n = arg[0] || 100000 +var i = 0 offsetMomentum(); log.console(`n = ${n}`) log.console(energy().toFixed(9)) -for (var i = 0; i < n; i++) +for (i = 0; i < n; i++) advance(0.01); log.console(energy().toFixed(9)) diff --git a/benchmarks/nota.ce b/benchmarks/nota.ce index 84da7cf4..eb212cfc 100644 --- a/benchmarks/nota.ce +++ b/benchmarks/nota.ce @@ -7,41 +7,40 @@ var ll = io.slurp('benchmarks/nota.json') var newarr = [] var accstr = "" -for (var i = 0; i < 10000; i++) { +var i = 0 +var start = null +var jll = null +var jsonStr = null +var nll = null +var oll = null +for (i = 0; i < 10000; i++) { accstr += i; - newarrpush(i.toString()) + push(newarr, text(i)) } -// Arrays to store timing results var jsonDecodeTimes = []; var jsonEncodeTimes = []; var notaEncodeTimes = []; var notaDecodeTimes = []; var notaSizes = []; -// Run 100 tests -for (var i = 0; i < 100; i++) { - // JSON Decode test - var start = os.now(); - var jll = json.decode(ll); - jsonDecodeTimespush((os.now() - start) * 1000); - - // JSON Encode test +for (i = 0; i < 100; i++) { start = os.now(); - var jsonStr = JSON.stringify(jll); - jsonEncodeTimespush((os.now() - start) * 1000); + jll = json.decode(ll); + push(jsonDecodeTimes, (os.now() - start) * 1000); - // NOTA Encode test start = os.now(); - var nll = nota.encode(jll); - notaEncodeTimespush((os.now() - start) * 1000); + jsonStr = JSON.stringify(jll); + push(jsonEncodeTimes, (os.now() - start) * 1000); - // NOTA Decode test start = os.now(); - var oll = nota.decode(nll); - notaDecodeTimespush((os.now() - start) * 1000); + nll = nota.encode(jll); + push(notaEncodeTimes, (os.now() - start) * 1000); + + start = os.now(); + oll = nota.decode(nll); + push(notaDecodeTimes, (os.now() - start) * 1000); } -// Calculate statistics function getStats(arr) { return { avg: reduce(arr, (a,b) => a+b, 0) / length(arr), @@ -50,7 +49,6 @@ function getStats(arr) { }; } -// Pretty print results log.console("\n== Performance Test Results (100 iterations) =="); log.console("\nJSON Decoding (ms):"); def jsonDecStats = getStats(jsonDecodeTimes); @@ -75,4 +73,3 @@ def notaDecStats = getStats(notaDecodeTimes); log.console(`Average: ${notaDecStats.avg.toFixed(2)} ms`); log.console(`Min: ${notaDecStats.min.toFixed(2)} ms`); log.console(`Max: ${notaDecStats.max.toFixed(2)} ms`); - diff --git a/benchmarks/spectral-norm.ce b/benchmarks/spectral-norm.ce index 11f7e9cc..17db8396 100644 --- a/benchmarks/spectral-norm.ce +++ b/benchmarks/spectral-norm.ce @@ -5,21 +5,27 @@ function A(i,j) { } function Au(u,v) { - for (var i=0; i decode` for a given value: function roundTripWota(value) { var encoded = wota.encode(value); var decoded = wota.decode(encoded); - // Not doing a deep compare here, just measuring performance. - // (We trust the test suite to verify correctness.) } -// A small suite of data we want to benchmark. Each entry includes: -// name: label for printing -// data: the test value(s) to encode/decode -// iterations: how many times to loop -// -// You can tweak these as you like for heavier or lighter tests. def benchmarks = [ { name: "Small Integers", @@ -62,22 +43,17 @@ def benchmarks = [ }, { name: "Large Array (1k numbers)", - // A thousand random numbers data: [ array(1000, i => i *0.5) ], iterations: 1000 }, ]; -// Print a header log.console("Wota Encode/Decode Benchmark"); log.console("===================\n"); -// We'll run each benchmark scenario in turn. arrfor(benchmarks, function(bench) { var totalIterations = bench.iterations * length(bench.data); - - // We'll define a function that does a roundTrip for *each* data item in bench.data - // to measure in one loop iteration. Then we multiply by bench.iterations. + function runAllData() { arrfor(bench.data, roundTripWota) } @@ -91,5 +67,4 @@ arrfor(benchmarks, function(bench) { log.console(` Throughput: ${opsPerSec} encode+decode ops/sec\n`); }) -// All done log.console("Benchmark completed.\n"); diff --git a/benchmarks/wota_nota_json.ce b/benchmarks/wota_nota_json.ce index c1f3a918..68045b2e 100644 --- a/benchmarks/wota_nota_json.ce +++ b/benchmarks/wota_nota_json.ce @@ -1,18 +1,9 @@ -// -// benchmark_wota_nota_json.js -// -// Usage in QuickJS: -// qjs benchmark_wota_nota_json.js -// -// Ensure wota, nota, json, and os are all available, e.g.: - var wota = use('wota'); - var nota = use('nota'); - var json = use('json'); - var jswota = use('jswota') - var os = use('os'); -// +var wota = use('wota'); +var nota = use('nota'); +var json = use('json'); +var jswota = use('jswota') +var os = use('os'); -// Parse command line arguments if (length(arg) != 2) { log.console('Usage: cell benchmark_wota_nota_json.ce '); $stop() @@ -21,16 +12,11 @@ if (length(arg) != 2) { var lib_name = arg[0]; var scenario_name = arg[1]; -//////////////////////////////////////////////////////////////////////////////// -// 1. Setup "libraries" array to easily switch among wota, nota, and json -//////////////////////////////////////////////////////////////////////////////// - def libraries = [ { name: "wota", encode: wota.encode, decode: wota.decode, - // wota produces an ArrayBuffer. We'll count `buffer.byteLength` as size. getSize(encoded) { return length(encoded); } @@ -39,7 +25,6 @@ def libraries = [ name: "nota", encode: nota.encode, decode: nota.decode, - // nota also produces an ArrayBuffer: getSize(encoded) { return length(encoded); } @@ -48,19 +33,12 @@ def libraries = [ name: "json", encode: json.encode, decode: json.decode, - // json produces a JS string. We'll measure its UTF-16 code unit length - // as a rough "size". Alternatively, you could convert to UTF-8 for getSize(encodedStr) { return length(encodedStr); } } ]; -//////////////////////////////////////////////////////////////////////////////// -// 2. Test data sets (similar to wota benchmarks). -// Each scenario has { name, data, iterations } -//////////////////////////////////////////////////////////////////////////////// - def benchmarks = [ { name: "empty", @@ -102,42 +80,24 @@ def benchmarks = [ }, ]; -//////////////////////////////////////////////////////////////////////////////// -// 3. Utility: measureTime(fn) => how long fn() takes in seconds. -//////////////////////////////////////////////////////////////////////////////// - function measureTime(fn) { var start = os.now(); fn(); var end = os.now(); - return (end - start); // in seconds + return (end - start); } -//////////////////////////////////////////////////////////////////////////////// -// 4. For each library, we run each benchmark scenario and measure: -// - Encoding time (seconds) -// - Decoding time (seconds) -// - Total encoded size (bytes or code units for json) -// -//////////////////////////////////////////////////////////////////////////////// - function runBenchmarkForLibrary(lib, bench) { - // We'll encode and decode each item in `bench.data`. - // We do 'bench.iterations' times. Then sum up total time. - - // Pre-store the encoded results for all items so we can measure decode time - // in a separate pass. Also measure total size once. var encodedList = []; var totalSize = 0; + var i = 0 + var j = 0 + var e = null - // 1) Measure ENCODING var encodeTime = measureTime(() => { - for (var i = 0; i < bench.iterations; i++) { - // For each data item, encode it - for (var j = 0; j < length(bench.data); j++) { - var e = lib.encode(bench.data[j]); - // store only in the very first iteration, so we can decode them later - // but do not store them every iteration or we blow up memory. + for (i = 0; i < bench.iterations; i++) { + for (j = 0; j < length(bench.data); j++) { + e = lib.encode(bench.data[j]); if (i == 0) { push(encodedList, e); totalSize += lib.getSize(e); @@ -146,9 +106,8 @@ function runBenchmarkForLibrary(lib, bench) { } }); - // 2) Measure DECODING var decodeTime = measureTime(() => { - for (var i = 0; i < bench.iterations; i++) { + for (i = 0; i < bench.iterations; i++) { arrfor(encodedList, lib.decode) } }); @@ -156,11 +115,6 @@ function runBenchmarkForLibrary(lib, bench) { return { encodeTime, decodeTime, totalSize }; } -//////////////////////////////////////////////////////////////////////////////// -// 5. Main driver: run only the specified library and scenario -//////////////////////////////////////////////////////////////////////////////// - -// Find the requested library and scenario var lib = libraries[find(libraries, l => l.name == lib_name)]; var bench = benchmarks[find(benchmarks, b => b.name == scenario_name)]; @@ -176,10 +130,11 @@ if (!bench) { $stop() } -// Run the benchmark for this library/scenario combination -var { encodeTime, decodeTime, totalSize } = runBenchmarkForLibrary(lib, bench); +var bench_result = runBenchmarkForLibrary(lib, bench); +var encodeTime = bench_result.encodeTime; +var decodeTime = bench_result.decodeTime; +var totalSize = bench_result.totalSize; -// Output json for easy parsing by hyperfine or other tools var totalOps = bench.iterations * length(bench.data); var result = { lib: lib_name, diff --git a/cellfs.cm b/cellfs.cm index 2adf577b..d6a009bc 100644 --- a/cellfs.cm +++ b/cellfs.cm @@ -1,28 +1,23 @@ var cellfs = {} -// CellFS: A filesystem implementation using miniz and raw OS filesystem -// Supports mounting multiple sources (fs, zip) and named mounts (@name) - var fd = use('fd') var miniz = use('miniz') var qop = use('qop') var wildstar = use('wildstar') -// Internal state -var mounts = [] // Array of {source, type, handle, name} +var mounts = [] var writepath = "." -// Helper to normalize paths function normalize_path(path) { if (!path) return "" - // Remove leading/trailing slashes and normalize return replace(path, /^\/+|\/+$/, "") } -// Check if a file exists in a specific mount function mount_exists(mount, path) { var result = false + var full_path = null + var st = null var _check = null if (mount.type == 'zip') { _check = function() { @@ -36,9 +31,9 @@ function mount_exists(mount, path) { } disruption {} _check() } else { - var full_path = fd.join_paths(mount.source, path) + full_path = fd.join_paths(mount.source, path) _check = function() { - var st = fd.stat(full_path) + st = fd.stat(full_path) result = st.isFile || st.isDirectory } disruption {} _check() @@ -46,11 +41,12 @@ function mount_exists(mount, path) { return result } -// Check if a path refers to a directory in a specific mount function is_directory(path) { var res = resolve(path) var mount = res.mount var result = false + var full_path = null + var st = null var _check = null if (mount.type == 'zip') { _check = function() { @@ -63,9 +59,9 @@ function is_directory(path) { } disruption {} _check() } else { - var full_path = fd.join_paths(mount.source, path) + full_path = fd.join_paths(mount.source, path) _check = function() { - var st = fd.stat(full_path) + st = fd.stat(full_path) result = st.isDirectory } disruption {} _check() @@ -73,64 +69,63 @@ function is_directory(path) { return result } -// Resolve a path to a specific mount and relative path -// Returns { mount, path } or throws/returns null function resolve(path, must_exist) { - path = normalize_path(path) - - // Check for named mount - if (starts_with(path, "@")) { - var idx = search(path, "/") - var mount_name = "" - var rel_path = "" - + var idx = null + var mount_name = "" + var rel_path = "" + var mount = null + var found_mount = null + var npath = normalize_path(path) + + if (starts_with(npath, "@")) { + idx = search(npath, "/") + if (idx == null) { - mount_name = text(path, 1) + mount_name = text(npath, 1) rel_path = "" } else { - mount_name = text(path, 1, idx) - rel_path = text(path, idx + 1) + mount_name = text(npath, 1, idx) + rel_path = text(npath, idx + 1) } - - // Find named mount - var mount = null + arrfor(mounts, function(m) { if (m.name == mount_name) { mount = m return true } }, false, true) - + if (!mount) { print("Unknown mount point: @" + mount_name); disrupt } - + return { mount: mount, path: rel_path } } - - // Search path - var found_mount = null - arrfor(mounts, function(mount) { - if (mount_exists(mount, path)) { - found_mount = { mount: mount, path: path } + + arrfor(mounts, function(m) { + if (mount_exists(m, npath)) { + found_mount = { mount: m, path: npath } return true } }, false, true) - + if (found_mount) { return found_mount } - + if (must_exist) { - print("File not found in any mount: " + path); disrupt + print("File not found in any mount: " + npath); disrupt } } -// Mount a source function mount(source, name) { - // Check if source exists var st = fd.stat(source) - + var blob = null + var qop_archive = null + var zip = null + + var _try_qop = null + var mount_info = { source: source, name: name || null, @@ -138,14 +133,14 @@ function mount(source, name) { handle: null, zip_blob: null } - + if (st.isDirectory) { mount_info.type = 'fs' } else if (st.isFile) { - var blob = fd.slurp(source) - - var qop_archive = null - var _try_qop = function() { + blob = fd.slurp(source) + + qop_archive = null + _try_qop = function() { qop_archive = qop.open(blob) } disruption {} _try_qop() @@ -153,58 +148,56 @@ function mount(source, name) { if (qop_archive) { mount_info.type = 'qop' mount_info.handle = qop_archive - mount_info.zip_blob = blob // keep blob alive + mount_info.zip_blob = blob } else { - var zip = miniz.read(blob) + zip = miniz.read(blob) if (!is_object(zip) || !is_function(zip.count)) { print("Invalid archive file (not zip or qop): " + source); disrupt } - + mount_info.type = 'zip' mount_info.handle = zip - mount_info.zip_blob = blob // keep blob alive + mount_info.zip_blob = blob } } else { print("Unsupported mount source type: " + source); disrupt } - + push(mounts, mount_info) } -// Unmount function unmount(name_or_source) { - mounts = filter(mounts, function(mount) { - return mount.name != name_or_source && mount.source != name_or_source + mounts = filter(mounts, function(m) { + return m.name != name_or_source && m.source != name_or_source }) } -// Read file function slurp(path) { var res = resolve(path, true) + var data = null + var full_path = null if (!res) { print("File not found: " + path); disrupt } if (res.mount.type == 'zip') { return res.mount.handle.slurp(res.path) } else if (res.mount.type == 'qop') { - var data = res.mount.handle.read(res.path) + data = res.mount.handle.read(res.path) if (!data) { print("File not found in qop: " + path); disrupt } return data } else { - var full_path = fd.join_paths(res.mount.source, res.path) + full_path = fd.join_paths(res.mount.source, res.path) return fd.slurp(full_path) } } -// Write file function slurpwrite(path, data) { var full_path = writepath + "/" + path - + var f = fd.open(full_path, 'w') fd.write(f, data) fd.close(f) } -// Check existence function exists(path) { var res = resolve(path, false) if (starts_with(path, "@")) { @@ -213,20 +206,22 @@ function exists(path) { return res != null } -// Stat function stat(path) { var res = resolve(path, true) + var mod = null + var s = null + var full_path = null if (!res) { print("File not found: " + path); disrupt } if (res.mount.type == 'zip') { - var mod = res.mount.handle.mod(res.path) + mod = res.mount.handle.mod(res.path) return { - filesize: 0, + filesize: 0, modtime: mod * 1000, - isDirectory: false + isDirectory: false } } else if (res.mount.type == 'qop') { - var s = res.mount.handle.stat(res.path) + s = res.mount.handle.stat(res.path) if (!s) { print("File not found in qop: " + path); disrupt } return { filesize: s.size, @@ -234,8 +229,8 @@ function stat(path) { isDirectory: s.isDirectory } } else { - var full_path = fd.join_paths(res.mount.source, res.path) - var s = fd.stat(full_path) + full_path = fd.join_paths(res.mount.source, res.path) + s = fd.stat(full_path) return { filesize: s.size, modtime: s.mtime, @@ -244,18 +239,16 @@ function stat(path) { } } -// Get search paths function searchpath() { return array(mounts) } -// Mount a package using the shop system function mount_package(name) { if (name == null) { mount('.', null) return } - + var shop = use('internal/shop') var dir = shop.get_package_dir(name) @@ -266,18 +259,18 @@ function mount_package(name) { mount(dir, name) } -// New functions for qjs_io compatibility - function match(str, pattern) { return wildstar.match(pattern, str, wildstar.WM_PATHNAME | wildstar.WM_PERIOD | wildstar.WM_WILDSTAR) } function rm(path) { var res = resolve(path, true) + var full_path = null + var st = null if (res.mount.type != 'fs') { print("Cannot delete from non-fs mount"); disrupt } - - var full_path = fd.join_paths(res.mount.source, res.path) - var st = fd.stat(full_path) + + full_path = fd.join_paths(res.mount.source, res.path) + st = fd.stat(full_path) if (st.isDirectory) fd.rmdir(full_path) else fd.unlink(full_path) } @@ -305,55 +298,63 @@ function realdir(path) { return fd.join_paths(res.mount.source, res.path) } -function enumerate(path, recurse) { - if (path == null) path = "" - +function enumerate(_path, recurse) { + var path = _path == null ? "" : _path + var res = resolve(path, true) var results = [] - + var full = null + var st = null + var all = null + var prefix = null + var prefix_len = null + var seen = null + function visit(curr_full, rel_prefix) { var list = fd.readdir(curr_full) if (!list) return - + arrfor(list, function(item) { var item_rel = rel_prefix ? rel_prefix + "/" + item : item + var child_st = null push(results, item_rel) - + if (recurse) { - var st = fd.stat(fd.join_paths(curr_full, item)) - if (st.isDirectory) { + child_st = fd.stat(fd.join_paths(curr_full, item)) + if (child_st.isDirectory) { visit(fd.join_paths(curr_full, item), item_rel) } } }) } - + if (res.mount.type == 'fs') { - var full = fd.join_paths(res.mount.source, res.path) - var st = fd.stat(full) + full = fd.join_paths(res.mount.source, res.path) + st = fd.stat(full) if (st && st.isDirectory) { visit(full, "") } } else if (res.mount.type == 'qop') { - var all = res.mount.handle.list() - var prefix = res.path ? res.path + "/" : "" - var prefix_len = length(prefix) - - // Use a set to avoid duplicates if we are simulating directories - var seen = {} - + all = res.mount.handle.list() + prefix = res.path ? res.path + "/" : "" + prefix_len = length(prefix) + + seen = {} + arrfor(all, function(p) { + var rel = null + var slash = null if (starts_with(p, prefix)) { - var rel = text(p, prefix_len) + rel = text(p, prefix_len) if (length(rel) == 0) return if (!recurse) { - var slash = search(rel, '/') + slash = search(rel, '/') if (slash != null) { rel = text(rel, 0, slash) } } - + if (!seen[rel]) { seen[rel] = true push(results, rel) @@ -361,15 +362,20 @@ function enumerate(path, recurse) { } }) } - + return results } -function globfs(globs, dir) { - if (dir == null) dir = "" +function globfs(globs, _dir) { + var dir = _dir == null ? "" : _dir var res = resolve(dir, true) var results = [] - + var full = null + var st = null + var all = null + var prefix = null + var prefix_len = null + function check_neg(path) { var result = false arrfor(globs, function(g) { @@ -380,7 +386,7 @@ function globfs(globs, dir) { }, false, true) return result } - + function check_pos(path) { var result = false arrfor(globs, function(g) { @@ -397,14 +403,14 @@ function globfs(globs, dir) { var list = fd.readdir(curr_full) if (!list) return - + arrfor(list, function(item) { var item_rel = rel_prefix ? rel_prefix + "/" + item : item - + var child_full = fd.join_paths(curr_full, item) - var st = fd.stat(child_full) - - if (st.isDirectory) { + var child_st = fd.stat(child_full) + + if (child_st.isDirectory) { if (!check_neg(item_rel)) { visit(child_full, item_rel) } @@ -415,21 +421,22 @@ function globfs(globs, dir) { } }) } - + if (res.mount.type == 'fs') { - var full = fd.join_paths(res.mount.source, res.path) - var st = fd.stat(full) + full = fd.join_paths(res.mount.source, res.path) + st = fd.stat(full) if (st && st.isDirectory) { visit(full, "") } } else if (res.mount.type == 'qop') { - var all = res.mount.handle.list() - var prefix = res.path ? res.path + "/" : "" - var prefix_len = length(prefix) - + all = res.mount.handle.list() + prefix = res.path ? res.path + "/" : "" + prefix_len = length(prefix) + arrfor(all, function(p) { + var rel = null if (starts_with(p, prefix)) { - var rel = text(p, prefix_len) + rel = text(p, prefix_len) if (length(rel) == 0) return if (!check_neg(rel) && check_pos(rel)) { @@ -438,11 +445,10 @@ function globfs(globs, dir) { } }) } - + return results } -// Exports cellfs.mount = mount cellfs.mount_package = mount_package cellfs.unmount = unmount diff --git a/examples/nat_client.ce b/examples/nat_client.ce index 64725941..7e82be44 100644 --- a/examples/nat_client.ce +++ b/examples/nat_client.ce @@ -8,15 +8,17 @@ $contact((actor, reason) => { log.console(reason) } }, { - address: "108.210.60.32", // NAT server's public IP + address: "108.210.60.32", port: 4000, actor: $self }) -$receiver(e => { - switch(e.type) { - case 'greet': - log.console(`hello!`) - break +var handlers = { + greet: function() { + log.console(`hello!`) } +} + +$receiver(e => { + if (handlers[e.type]) handlers[e.type]() }) \ No newline at end of file diff --git a/internal/shop.cm b/internal/shop.cm index 6f4539f5..5bb1ac2d 100644 --- a/internal/shop.cm +++ b/internal/shop.cm @@ -1436,7 +1436,7 @@ Shop.build_package_scripts = function(package) // compiles all .ce and .cm files in a package // continues past failures and returns results var scripts = get_package_scripts(package) - var pkg_dir = get_package_abs_dir(package) + var pkg_dir = starts_with(package, '/') ? package : get_package_abs_dir(package) var errors = [] var ok = 0 diff --git a/tests/blob.cm b/tests/blob.cm index ccd80b37..b8671b12 100644 --- a/tests/blob.cm +++ b/tests/blob.cm @@ -1,17 +1,12 @@ -// blob_test.cm var Blob = use('blob'); var os = use('os'); function assert(condition, message) { - if (!condition) { - throw Error(message || "Assertion failed"); - } + if (!condition) disrupt } function assertEqual(actual, expected, message) { - if (actual != expected) { - throw Error(message || "Expected " + expected + ", got " + actual); - } + if (actual != expected) disrupt } return { @@ -19,12 +14,12 @@ return { var b = Blob(); assertEqual(length(b), 0, "Empty blob should have length 0"); }, - + test_create_blob_with_capacity: function() { var b = Blob(100); assertEqual(length(b), 0, "New blob with capacity should still have length 0"); }, - + test_write_and_read_single_bit: function() { var b = Blob(); b.write_bit(true); @@ -32,36 +27,39 @@ return { b.write_bit(1); b.write_bit(0); assertEqual(length(b), 4, "Should have 4 bits after writing"); - + stone(b); assertEqual(b.read_logical(0), true, "First bit should be true"); assertEqual(b.read_logical(1), false, "Second bit should be false"); assertEqual(b.read_logical(2), true, "Third bit should be true (1)"); assertEqual(b.read_logical(3), false, "Fourth bit should be false (0)"); }, - + test_out_of_range_read_throws_error: function() { var b = Blob(); + var threw = false; b.write_bit(true); stone(b); - - var threw = false; - try { - b.read_logical(100); - } catch (e) { - threw = true; - } - assert(threw, "Out of range read should throw"); - + threw = false; - try { - b.read_logical(-1); - } catch (e) { + var _try1 = function() { + b.read_logical(100); + } disruption { threw = true; } - assert(threw, "Negative index read should throw"); + _try1(); + assert(threw, "Out of range read should disrupt"); + + threw = false; + var _try2 = function() { + b.read_logical(-1); + } disruption { + threw = true; + } + _try2(); + assert(threw, "Negative index read should disrupt"); }, - + test_write_and_read_numbers: function() { var b = Blob(); b.write_number(3.14159); @@ -69,41 +67,41 @@ return { b.write_number(0); b.write_number(1e20); stone(b); - + assertEqual(b.read_number(0), 3.14159, "First number should match"); assertEqual(b.read_number(64), -42, "Second number should match"); assertEqual(b.read_number(128), 0, "Third number should match"); assertEqual(b.read_number(192), 1e20, "Fourth number should match"); }, - + test_write_and_read_text: function() { var b = Blob(); b.write_text("Hello"); b.write_text("World"); b.write_text("🎉"); stone(b); - + assertEqual(b.read_text(0), "Hello", "First text should match"); }, - + test_write_and_read_blobs: function() { var b1 = Blob(); b1.write_bit(true); b1.write_bit(false); b1.write_bit(true); - + var b2 = Blob(10); b2.write_blob(b1); b2.write_bit(false); assertEqual(length(b2), 4, "Combined blob should have 4 bits"); - + stone(b2); assertEqual(b2.read_logical(0), true); assertEqual(b2.read_logical(1), false); assertEqual(b2.read_logical(2), true); assertEqual(b2.read_logical(3), false); }, - + test_blob_copy_constructor: function() { var b1 = Blob(); b1.write_bit(true); @@ -111,98 +109,103 @@ return { b1.write_bit(true); b1.write_bit(true); stone(b1); - + var b2 = Blob(b1); stone(b2); assertEqual(length(b2), 4, "Copied blob should have same length"); assertEqual(b2.read_logical(0), true); assertEqual(b2.read_logical(3), true); }, - + test_blob_partial_copy_constructor: function() { var b1 = Blob(); - for (var i = 0; i < 10; i++) { + var i = 0; + for (i = 0; i < 10; i++) { b1.write_bit(i % 2 == 0); } stone(b1); - + var b2 = Blob(b1, 2, 7); stone(b2); assertEqual(length(b2), 5, "Partial copy should have 5 bits"); assertEqual(b2.read_logical(0), true); assertEqual(b2.read_logical(2), true); }, - + test_create_blob_with_fill: function() { var b1 = Blob(8, true); var b2 = Blob(8, false); - + var i = 0; + stone(b1); stone(b2); - - for (var i = 0; i < 8; i++) { + + for (i = 0; i < 8; i++) { assertEqual(b1.read_logical(i), true, "Bit " + i + " should be true"); assertEqual(b2.read_logical(i), false, "Bit " + i + " should be false"); } }, - + test_create_blob_with_random_function: function() { var sequence = [true, false, true, true, false]; var index = 0; - + var i = 0; + var b = Blob(5, function() { return sequence[index++] ? 1 : 0; }); - + stone(b); - for (var i = 0; i < 5; i++) { + for (i = 0; i < 5; i++) { assertEqual(b.read_logical(i), sequence[i], "Bit " + i + " should match sequence"); } }, - + test_write_pad_and_check_padding: function() { var b = Blob(); b.write_bit(true); b.write_bit(false); b.write_bit(true); b.write_pad(8); - + assertEqual(length(b), 8, "Should be padded to 8 bits"); stone(b); - + assert(b['pad?'](3, 8), "Should detect valid padding at position 3"); assert(!b['pad?'](2, 8), "Should detect invalid padding at position 2"); }, - + test_read_blob_from_stone_blob: function() { var b1 = Blob(); - for (var i = 0; i < 16; i++) { + var i = 0; + for (i = 0; i < 16; i++) { b1.write_bit(i % 3 == 0); } stone(b1); - + var b2 = b1.read_blob(4, 12); stone(b2); assertEqual(length(b2), 8, "Read blob should have 8 bits"); - + assertEqual(b2.read_logical(2), true); assertEqual(b2.read_logical(5), true); }, - + test_stone_blob_is_immutable: function() { var b = Blob(); + var threw = false; b.write_bit(true); stone(b); - - var threw = false; - try { + + var _try = function() { b.write_bit(false); - } catch (e) { + } disruption { threw = true; } - assert(threw, "Writing to stone blob should throw error"); + _try(); + assert(threw, "Writing to stone blob should disrupt"); }, - + test_multiple_stone_calls_are_safe: function() { var b = Blob(); b.write_bit(true); @@ -211,149 +214,161 @@ return { assert(stone.p(b), "Blob should be a stone after stone() call"); stone(b); assertEqual(b.read_logical(0), true, "Blob data should remain intact"); - + assert(b.stone == null, "blob.stone should not be available as a method"); }, - + test_invalid_constructor_arguments: function() { var threw = false; - try { + var _try = function() { var b = Blob("invalid"); - } catch (e) { + } disruption { threw = true; } - assert(threw, "Invalid constructor arguments should throw"); + _try(); + assert(threw, "Invalid constructor arguments should disrupt"); }, - + test_write_bit_validation: function() { var b = Blob(); + var threw = false; b.write_bit(0); b.write_bit(1); - - var threw = false; - try { + + var _try = function() { b.write_bit(2); - } catch (e) { + } disruption { threw = true; } - assert(threw, "write_bit with value 2 should throw"); + _try(); + assert(threw, "write_bit with value 2 should disrupt"); }, - + test_complex_data_round_trip: function() { var b = Blob(); - + b.write_text("Test"); b.write_number(123.456); b.write_bit(true); b.write_bit(false); b.write_number(-999.999); - + var originalLength = length(b); stone(b); - + var b2 = Blob(b); stone(b2); assertEqual(length(b2), originalLength, "Copy should have same length"); assertEqual(b2.read_text(0), "Test", "First text should match"); }, - + test_zero_capacity_blob: function() { var b = Blob(0); assertEqual(length(b), 0, "Zero capacity blob should have length 0"); b.write_bit(true); assertEqual(length(b), 1, "Should expand when writing"); }, - + test_large_blob_handling: function() { var b = Blob(); var testSize = 1000; - - for (var i = 0; i < testSize; i++) { + var i = 0; + + for (i = 0; i < testSize; i++) { b.write_bit(i % 7 == 0); } - + assertEqual(length(b), testSize, "Should have " + testSize + " bits"); stone(b); - + assertEqual(b.read_logical(0), true, "Bit 0 should be true"); assertEqual(b.read_logical(7), true, "Bit 7 should be true"); assertEqual(b.read_logical(14), true, "Bit 14 should be true"); assertEqual(b.read_logical(15), false, "Bit 15 should be false"); }, - + test_non_stone_blob_read_methods_should_throw: function() { var b = Blob(); + var threw = false; b.write_bit(true); b.write_number(42); b.write_text("test"); - - var threw = false; - try { + + threw = false; + var _try1 = function() { b.read_logical(0); - } catch (e) { + } disruption { threw = true; } - assert(threw, "read_logical on non-stone blob should throw"); - + _try1(); + assert(threw, "read_logical on non-stone blob should disrupt"); + threw = false; - try { + var _try2 = function() { b.read_number(0); - } catch (e) { + } disruption { threw = true; } - assert(threw, "read_number on non-stone blob should throw"); - + _try2(); + assert(threw, "read_number on non-stone blob should disrupt"); + threw = false; - try { + var _try3 = function() { b.read_text(0); - } catch (e) { + } disruption { threw = true; } - assert(threw, "read_text on non-stone blob should throw"); - + _try3(); + assert(threw, "read_text on non-stone blob should disrupt"); + threw = false; - try { + var _try4 = function() { b.read_blob(0, 10); - } catch (e) { + } disruption { threw = true; } - assert(threw, "read_blob on non-stone blob should throw"); - + _try4(); + assert(threw, "read_blob on non-stone blob should disrupt"); + threw = false; - try { + var _try5 = function() { b['pad?'](0, 8); - } catch (e) { + } disruption { threw = true; } - assert(threw, "pad? on non-stone blob should throw"); + _try5(); + assert(threw, "pad? on non-stone blob should disrupt"); }, - + test_empty_text_write_and_read: function() { var b = Blob(); b.write_text(""); stone(b); assertEqual(b.read_text(0), "", "Empty string should round-trip"); }, - + test_invalid_read_positions: function() { var b = Blob(); + var threw = false; b.write_number(42); stone(b); - - var threw = false; - try { - b.read_number(-10); - } catch (e) { - threw = true; - } - assert(threw, "Negative position should throw"); - + threw = false; - try { - b.read_number(1000); - } catch (e) { + var _try1 = function() { + b.read_number(-10); + } disruption { threw = true; } - assert(threw, "Position beyond length should throw"); + _try1(); + assert(threw, "Negative position should disrupt"); + + threw = false; + var _try2 = function() { + b.read_number(1000); + } disruption { + threw = true; + } + _try2(); + assert(threw, "Position beyond length should disrupt"); } } diff --git a/tests/cat.cm b/tests/cat.cm index de51f53b..8fb670b2 100644 --- a/tests/cat.cm +++ b/tests/cat.cm @@ -3,23 +3,21 @@ var time = use('time') return { test_cat: function() { - // Create temp file var tmp = "cat_test.tmp" var f = fd.open(tmp, 'w') fd.write(f, "Hello world") fd.close(f) - + var st = time.number() var f2 = fd.open(tmp, 'r') var stat = fd.fstat(f2) var data = fd.read(f2, stat.size); fd.close(f2) log.console(`cat took ${time.number()-st}`) - - // fd.read returns a blob, read it as text + stone(data) - if (data.read_text(0) != "Hello world") throw "Data mismatch" - + if (data.read_text(0) != "Hello world") disrupt + fd.unlink(tmp) } } diff --git a/tests/chunkread.cm b/tests/chunkread.cm index 616ecedb..1fd0e53a 100644 --- a/tests/chunkread.cm +++ b/tests/chunkread.cm @@ -4,27 +4,28 @@ var blob = use('blob') return { test_chunkread: function() { - // Create temp file var tmp = "chunk_test.tmp" var f = fd.open(tmp, 'w') var bigdata = "" - for(var i=0; i<100; i++) bigdata += "HelloWorld" // 1000 bytes + var i = 0 + var chunk = null + for (i = 0; i < 100; i++) bigdata += "HelloWorld" fd.write(f, bigdata) fd.close(f) - + var data = blob() var st = time.number() var f2 = fd.open(tmp, 'r') - var chunksize = 1024 // reduced for test - - while(true) { - var chunk = fd.read(f2, chunksize); + var chunksize = 1024 + + while (true) { + chunk = fd.read(f2, chunksize); data.write_blob(chunk); - if (length(chunk) < chunksize * 8) break; + if (length(chunk) < chunksize * 8) break; } fd.close(f2) log.console(`read took ${time.number()-st}`) - + fd.unlink(tmp) } } diff --git a/tests/disrupt.cm b/tests/disrupt.cm index 2a817f1c..2c147167 100644 --- a/tests/disrupt.cm +++ b/tests/disrupt.cm @@ -1,5 +1,5 @@ return { test_disrupt: function() { - throw 1 + disrupt } } diff --git a/tests/fit.cm b/tests/fit.cm index b5904241..55f25a6d 100644 --- a/tests/fit.cm +++ b/tests/fit.cm @@ -2,186 +2,186 @@ var fit = use("fit"); return { and_12_10: function() { - if (fit.and(12, 10) != 8) throw "fit.and(12, 10) expected 8"; + if (fit.and(12, 10) != 8) disrupt }, and_16_2: function() { - if (fit.and(16, 2) != 0) throw "fit.and(16, 2) expected 0"; + if (fit.and(16, 2) != 0) disrupt }, and_15_3: function() { - if (fit.and(15, 3) != 3) throw "fit.and(15, 3) expected 3"; + if (fit.and(15, 3) != 3) disrupt }, and_13_3: function() { - if (fit.and(13, 3) != 1) throw "fit.and(13, 3) expected 1"; + if (fit.and(13, 3) != 1) disrupt }, and_string_input: function() { - if (fit.and("10", 3) != null) throw "fit.and('10', 3) expected null"; + if (fit.and("10", 3) != null) disrupt }, or_12_10: function() { - if (fit.or(12, 10) != 14) throw "fit.or(12, 10) expected 14"; + if (fit.or(12, 10) != 14) disrupt }, or_16_2: function() { - if (fit.or(16, 2) != 18) throw "fit.or(16, 2) expected 18"; + if (fit.or(16, 2) != 18) disrupt }, or_15_3: function() { - if (fit.or(15, 3) != 15) throw "fit.or(15, 3) expected 15"; + if (fit.or(15, 3) != 15) disrupt }, or_13_3: function() { - if (fit.or(13, 3) != 15) throw "fit.or(13, 3) expected 15"; + if (fit.or(13, 3) != 15) disrupt }, xor_12_10: function() { - if (fit.xor(12, 10) != 6) throw "fit.xor(12, 10) expected 6"; + if (fit.xor(12, 10) != 6) disrupt }, xor_16_2: function() { - if (fit.xor(16, 2) != 18) throw "fit.xor(16, 2) expected 18"; + if (fit.xor(16, 2) != 18) disrupt }, xor_15_3: function() { - if (fit.xor(15, 3) != 12) throw "fit.xor(15, 3) expected 12"; + if (fit.xor(15, 3) != 12) disrupt }, xor_13_3: function() { - if (fit.xor(13, 3) != 14) throw "fit.xor(13, 3) expected 14"; + if (fit.xor(13, 3) != 14) disrupt }, xor_float_input: function() { - if (fit.xor(13.01, 3) != null) throw "fit.xor(13.01, 3) expected null"; + if (fit.xor(13.01, 3) != null) disrupt }, left_12_10: function() { - if (fit.left(12, 10) != 12288) throw "fit.left(12, 10) expected 12288"; + if (fit.left(12, 10) != 12288) disrupt }, left_16_2: function() { - if (fit.left(16, 2) != 64) throw "fit.left(16, 2) expected 64"; + if (fit.left(16, 2) != 64) disrupt }, left_15_53: function() { - if (fit.left(15, 53) != -9007199254740992) throw "fit.left(15, 53) expected -9007199254740992"; + if (fit.left(15, 53) != -9007199254740992) disrupt }, right_12_10: function() { - if (fit.right(12, 10) != 0) throw "fit.right(12, 10) expected 0"; + if (fit.right(12, 10) != 0) disrupt }, right_19_2: function() { - if (fit.right(19, 2) != 4) throw "fit.right(19, 2) expected 4"; + if (fit.right(19, 2) != 4) disrupt }, right_large: function() { - if (fit.right(-9007199254740992, 53) != 7) throw "fit.right(-9007199254740992, 53) expected 7"; + if (fit.right(-9007199254740992, 53) != 7) disrupt }, right_signed: function() { - if (fit.right_signed(-2, 1) != -1) throw "fit.right_signed(-2, 1) expected -1"; + if (fit.right_signed(-2, 1) != -1) disrupt }, mask_0: function() { - if (fit.mask(0) != 0) throw "fit.mask(0) expected 0"; + if (fit.mask(0) != 0) disrupt }, mask_1: function() { - if (fit.mask(1) != 1) throw "fit.mask(1) expected 1"; + if (fit.mask(1) != 1) disrupt }, mask_3: function() { - if (fit.mask(3) != 7) throw "fit.mask(3) expected 7"; + if (fit.mask(3) != 7) disrupt }, mask_8: function() { - if (fit.mask(8) != 255) throw "fit.mask(8) expected 255"; + if (fit.mask(8) != 255) disrupt }, mask_16: function() { - if (fit.mask(16) != 65535) throw "fit.mask(16) expected 65535"; + if (fit.mask(16) != 65535) disrupt }, mask_32: function() { - if (fit.mask(32) != 4294967295) throw "fit.mask(32) expected 4294967295"; + if (fit.mask(32) != 4294967295) disrupt }, mask_55: function() { - if (fit.mask(55) != 36028797018963967) throw "fit.mask(55) expected 36028797018963967"; + if (fit.mask(55) != 36028797018963967) disrupt }, mask_56: function() { - if (fit.mask(56) != -1) throw "fit.mask(56) expected -1"; + if (fit.mask(56) != -1) disrupt }, mask_57: function() { - if (fit.mask(57) != null) throw "fit.mask(57) expected null"; + if (fit.mask(57) != null) disrupt }, mask_neg1: function() { - if (fit.mask(-1) != -2) throw "fit.mask(-1) expected -2"; + if (fit.mask(-1) != -2) disrupt }, mask_neg3: function() { - if (fit.mask(-3) != -8) throw "fit.mask(-3) expected -8"; + if (fit.mask(-3) != -8) disrupt }, mask_neg8: function() { - if (fit.mask(-8) != -256) throw "fit.mask(-8) expected -256"; + if (fit.mask(-8) != -256) disrupt }, mask_neg16: function() { - if (fit.mask(-16) != -65536) throw "fit.mask(-16) expected -65536"; + if (fit.mask(-16) != -65536) disrupt }, mask_neg32: function() { - if (fit.mask(-32) != -4294967296) throw "fit.mask(-32) expected -4294967296"; + if (fit.mask(-32) != -4294967296) disrupt }, mask_neg55: function() { - if (fit.mask(-55) != -36028797018963968) throw "fit.mask(-55) expected -36028797018963968"; + if (fit.mask(-55) != -36028797018963968) disrupt }, mask_neg56: function() { - if (fit.mask(-56) != 0) throw "fit.mask(-56) expected 0"; + if (fit.mask(-56) != 0) disrupt }, not_0: function() { - if (fit.not(0) != -1) throw "fit.not(0) expected -1"; + if (fit.not(0) != -1) disrupt }, not_1: function() { - if (fit.not(1) != -2) throw "fit.not(1) expected -2"; + if (fit.not(1) != -2) disrupt }, not_neg1: function() { - if (fit.not(-1) != 0) throw "fit.not(-1) expected 0"; + if (fit.not(-1) != 0) disrupt }, ones_neg1: function() { - if (fit.ones(-1) != 56) throw "fit.ones(-1) expected 56"; + if (fit.ones(-1) != 56) disrupt }, ones_0: function() { - if (fit.ones(0) != 0) throw "fit.ones(0) expected 0"; + if (fit.ones(0) != 0) disrupt }, ones_8: function() { - if (fit.ones(8) != 1) throw "fit.ones(8) expected 1"; + if (fit.ones(8) != 1) disrupt }, ones_18: function() { - if (fit.ones(18) != 2) throw "fit.ones(18) expected 2"; + if (fit.ones(18) != 2) disrupt }, ones_255: function() { - if (fit.ones(255) != 8) throw "fit.ones(255) expected 8"; + if (fit.ones(255) != 8) disrupt }, zeros_neg1: function() { - if (fit.zeros(-1) != 0) throw "fit.zeros(-1) expected 0"; + if (fit.zeros(-1) != 0) disrupt }, zeros_0: function() { - if (fit.zeros(0) != 56) throw "fit.zeros(0) expected 56"; + if (fit.zeros(0) != 56) disrupt }, zeros_1: function() { - if (fit.zeros(1) != 55) throw "fit.zeros(1) expected 55"; + if (fit.zeros(1) != 55) disrupt }, zeros_2: function() { - if (fit.zeros(2) != 54) throw "fit.zeros(2) expected 54"; + if (fit.zeros(2) != 54) disrupt }, zeros_1024: function() { - if (fit.zeros(1024) != 45) throw "fit.zeros(1024) expected 45"; + if (fit.zeros(1024) != 45) disrupt }, rotate_1_1: function() { - if (fit.rotate(1, 1) != 2) throw "fit.rotate(1, 1) expected 2"; + if (fit.rotate(1, 1) != 2) disrupt }, rotate_neg2_1: function() { - if (fit.rotate(-2, 1) != -3) throw "fit.rotate(-2, 1) expected -3"; + if (fit.rotate(-2, 1) != -3) disrupt }, rotate_full: function() { - if (fit.rotate(1, 56) != 1) throw "fit.rotate(1, 56) expected 1"; + if (fit.rotate(1, 56) != 1) disrupt }, rotate_right: function() { - if (fit.rotate(1, -1) != 1 << 55) throw "fit.rotate(1, -1) expected 1 << 55"; + if (fit.rotate(1, -1) != 1 << 55) disrupt }, reverse_neg: function() { - if (fit.reverse(-36028797018963968) != 1) throw "fit.reverse(-36028797018963968) expected 1"; + if (fit.reverse(-36028797018963968) != 1) disrupt }, reverse_pi: function() { - if (fit.reverse(3141592653589793) != 2334719610726733) throw "fit.reverse(3141592653589793) expected 2334719610726733"; + if (fit.reverse(3141592653589793) != 2334719610726733) disrupt }, and_out_of_range: function() { - if (fit.and(1 << 56, 1) != null) throw "fit.and with out-of-range expected null"; + if (fit.and(1 << 56, 1) != null) disrupt }, left_negative_shift: function() { - if (fit.left(1, -1) != null) throw "fit.left with negative shift expected null"; + if (fit.left(1, -1) != null) disrupt }, left_large_shift: function() { - if (fit.left(1, 100) != null) throw "fit.left with large shift expected null"; + if (fit.left(1, 100) != null) disrupt }, right_negative_shift: function() { - if (fit.right(1, -1) != null) throw "fit.right with negative shift expected null"; + if (fit.right(1, -1) != null) disrupt }, mask_float: function() { - if (fit.mask(3.5) != null) throw "fit.mask with float expected null"; + if (fit.mask(3.5) != null) disrupt } } diff --git a/tests/http.cm b/tests/http.cm index 85289397..85d1b540 100644 --- a/tests/http.cm +++ b/tests/http.cm @@ -3,5 +3,5 @@ var http = use('http') return function() { var url = "http://example.com" var b2 = http.fetch(url) - if (length(b2) == 0) throw "Empty response" + if (length(b2) == 0) disrupt } \ No newline at end of file diff --git a/tests/kim.cm b/tests/kim.cm index 9af38d00..d5d4ca1b 100644 --- a/tests/kim.cm +++ b/tests/kim.cm @@ -6,34 +6,34 @@ return { var input = "Hello, World!"; var encoded = kim.encode(input); var decoded = kim.decode(encoded); - if (input != decoded) throw "ASCII encoding/decoding failed" + if (input != decoded) disrupt }, - + unicode_multilingual: function() { var input = "Hello, 世界! 🌍 Привет мир"; var encoded = kim.encode(input); var decoded = kim.decode(encoded); - if (input != decoded) throw "Unicode multilingual encoding/decoding failed" + if (input != decoded) disrupt }, - + empty_string: function() { var input = " "; var encoded = kim.encode(input); var decoded = kim.decode(encoded); - if (input != decoded) throw "Empty string encoding/decoding failed" + if (input != decoded) disrupt }, - + mixed_unicode_ranges: function() { var input = "αβγδε АБВГД 你好 😀😎🎉 ∑∏∫"; var encoded = kim.encode(input); var decoded = kim.decode(encoded); - if (input != decoded) throw "Mixed Unicode ranges encoding/decoding failed" + if (input != decoded) disrupt }, - + high_codepoints: function() { var input = "🌍🌎🌏🗺️🧭"; var encoded = kim.encode(input); var decoded = kim.decode(encoded); - if (input != decoded) throw "High codepoints encoding/decoding failed" + if (input != decoded) disrupt } } diff --git a/tests/miniz.cm b/tests/miniz.cm index 84009cdd..cb8840ad 100644 --- a/tests/miniz.cm +++ b/tests/miniz.cm @@ -8,79 +8,99 @@ return { var SOURCE_PATH = "miniz_source.txt" var ENTRY_PATH = "sample/hello.txt" var PAYLOAD = "Miniz integration test payload." - - function write_text_file(path, text) { + var source_blob = null + var writer = null + var zip_blob = null + var reader = null + var extracted_blob = null + var extracted_text = null + + function write_text_file(path, txt) { var handle = fd.open(path, "w") - fd.write(handle, text) + fd.write(handle, txt) fd.close(handle) } - - try { + + var _run = function() { write_text_file(SOURCE_PATH, PAYLOAD) - var source_blob = fd.slurp(SOURCE_PATH) - var writer = miniz.write(ZIP_PATH) + source_blob = fd.slurp(SOURCE_PATH) + writer = miniz.write(ZIP_PATH) writer.add_file(ENTRY_PATH, source_blob) writer = null - - var zip_blob = fd.slurp(ZIP_PATH) - var reader = miniz.read(zip_blob) - + + zip_blob = fd.slurp(ZIP_PATH) + reader = miniz.read(zip_blob) + if (!reader.exists(ENTRY_PATH)) - throw "entry missing in archive" - - var extracted_blob = reader.slurp(ENTRY_PATH) - var extracted_text = utf8.decode(extracted_blob) - + disrupt + + extracted_blob = reader.slurp(ENTRY_PATH) + extracted_text = utf8.decode(extracted_blob) + if (extracted_text != PAYLOAD) - throw "extracted text mismatch" - } finally { - try { fd.unlink(ZIP_PATH) } catch(e) {} - try { fd.unlink(SOURCE_PATH) } catch(e) {} - } + disrupt + } disruption {} + _run() + + var _clean1 = function() { fd.unlink(ZIP_PATH) } disruption {} + _clean1() + var _clean2 = function() { fd.unlink(SOURCE_PATH) } disruption {} + _clean2() }, - + list_and_count: function() { var ZIP_PATH = "miniz_list_test.zip" var ENTRY1 = "file1.txt" var ENTRY2 = "dir/file2.txt" - - try { - var writer = miniz.write(ZIP_PATH) + var writer = null + var zip_blob = null + var reader = null + var listed = null + + var _run = function() { + writer = miniz.write(ZIP_PATH) writer.add_file(ENTRY1, utf8.encode("content1")) writer.add_file(ENTRY2, utf8.encode("content2")) writer = null - - var zip_blob = fd.slurp(ZIP_PATH) - var reader = miniz.read(zip_blob) - - var listed = reader.list() + + zip_blob = fd.slurp(ZIP_PATH) + reader = miniz.read(zip_blob) + + listed = reader.list() if (length(listed) != reader.count()) - throw "list/count mismatch" + disrupt if (length(listed) != 2) - throw "unexpected entry count" - } finally { - try { fd.unlink(ZIP_PATH) } catch(e) {} - } + disrupt + } disruption {} + _run() + + var _clean = function() { fd.unlink(ZIP_PATH) } disruption {} + _clean() }, - + exists_check: function() { var ZIP_PATH = "miniz_exists_test.zip" var ENTRY_PATH = "existing.txt" - - try { - var writer = miniz.write(ZIP_PATH) + var writer = null + var zip_blob = null + var reader = null + + var _run = function() { + writer = miniz.write(ZIP_PATH) writer.add_file(ENTRY_PATH, utf8.encode("data")) writer = null - - var zip_blob = fd.slurp(ZIP_PATH) - var reader = miniz.read(zip_blob) - + + zip_blob = fd.slurp(ZIP_PATH) + reader = miniz.read(zip_blob) + if (!reader.exists(ENTRY_PATH)) - throw "existing entry not found" + disrupt if (reader.exists("nonexistent.txt")) - throw "nonexistent entry reported as existing" - } finally { - try { fd.unlink(ZIP_PATH) } catch(e) {} - } + disrupt + } disruption {} + _run() + + var _clean = function() { fd.unlink(ZIP_PATH) } disruption {} + _clean() } } diff --git a/tests/nota.cm b/tests/nota.cm index 9a38eec5..75681dc2 100644 --- a/tests/nota.cm +++ b/tests/nota.cm @@ -8,26 +8,34 @@ function stone_if_needed(b) { if (!stone.p(b)) stone(b) } function bytes_to_blob(bytes) { var b = blob() - for (var i = 0; i < length(bytes); i++) { - var byte = bytes[i] - for (var bit = 7; bit >= 0; bit--) b.write_bit((byte >> bit) & 1) + var i = 0 + var byte = null + var bit = null + for (i = 0; i < length(bytes); i++) { + byte = bytes[i] + for (bit = 7; bit >= 0; bit--) b.write_bit((byte >> bit) & 1) } stone(b) return b } -function deepCompare(expected, actual, path) { - path = path || '' +function deepCompare(expected, actual, _path) { + var diff = null + var messages = null + var expKeys = null + var actKeys = null + var i = 0 + var path = _path || '' if (expected == actual) return { passed: true, messages: [] }; if (is_number(expected) && is_number(actual)) { if (isNaN(expected) && isNaN(actual)) return { passed: true, messages: [] }; - - var diff = abs(expected - actual); + + diff = abs(expected - actual); if (diff <= EPSILON) return { passed: true, messages: [] }; - + return { passed: false, messages: [ @@ -41,7 +49,7 @@ function deepCompare(expected, actual, path) { stone_if_needed(expected); stone_if_needed(actual) if (length(expected) != length(actual)) return { passed: false, messages: [`blob length mismatch at ${path}: ${length(expected)} vs ${length(actual)}`] } - for (var i = 0; i < length(expected); i++) { + for (i = 0; i < length(expected); i++) { if (expected.read_logical(i) != actual.read_logical(i)) return { passed: false, messages: [`blob bit mismatch at ${path}[${i}]`] } } @@ -54,7 +62,7 @@ function deepCompare(expected, actual, path) { passed: false, messages: [`Array length mismatch at ${path}: expected ${length(expected)}, got ${length(actual)}`] }; - var messages = []; + messages = []; arrfor(expected, function(val, i) { var result = deepCompare(val, actual[i], `${path}[${i}]`); if (!result.passed) @@ -64,17 +72,17 @@ function deepCompare(expected, actual, path) { } if (is_object(expected) && is_object(actual)) { - var expKeys = sort(array(expected)) - var actKeys = sort(array(actual)) + expKeys = sort(array(expected)) + actKeys = sort(array(actual)) if (JSON.stringify(expKeys) != JSON.stringify(actKeys)) return { passed: false, messages: [`Object keys mismatch at ${path}: expected ${expKeys}, got ${actKeys}`] }; - var messages = []; + messages = []; arrfor(expKeys, function(key) { var result = deepCompare(expected[key], actual[key], `${path}.${key}`); - if (!result.passed) + if (!result.passed) messages = array(messages, result.messages) }) return { passed: length(messages) == 0, messages: messages }; @@ -89,26 +97,32 @@ function deepCompare(expected, actual, path) { function makeTest(test) { return function() { var encoded = test.replacer ? nota.encode(test.input, test.replacer) : nota.encode(test.input); - if (!is_blob(encoded)){ - throw "encode() should return blob"; + var decoded = null + var expected = null + var key = null + var compareResult = null + if (!is_blob(encoded)) { + disrupt } - var decoded = test.reviver ? nota.decode(encoded, test.reviver) : nota.decode(encoded); - var expected = test.expected || test.input; + decoded = test.reviver ? nota.decode(encoded, test.reviver) : nota.decode(encoded); + expected = test.expected || test.input; if (expected && (expected.private || expected.system)) { - var key = expected.private ? 'private' : 'system'; + key = expected.private ? 'private' : 'system'; expected = { [key]: expected[key] }; } - var compareResult = deepCompare(expected, decoded); + compareResult = deepCompare(expected, decoded); if (!compareResult.passed) { - throw text(compareResult.messages, '; '); + disrupt } }; } var testarr = [] -for (var i = 0; i < 500; i++) { +var i = 0 +var t = null +for (i = 0; i < 500; i++) { push(testarr, 1) } @@ -172,8 +186,8 @@ var testCases = [ ]; var tests = {}; -for (var i = 0; i < length(testCases); i++) { - var t = testCases[i]; +for (i = 0; i < length(testCases); i++) { + t = testCases[i]; tests[t.name] = makeTest(t); } diff --git a/tests/overling.cm b/tests/overling.cm index 2bc8b7b4..84628756 100644 --- a/tests/overling.cm +++ b/tests/overling.cm @@ -2,28 +2,17 @@ var time = use('time'); return { test_overling: function() { - // Ported from overling.ce - // Note: This test spawns actors and waits for them. - // In a sync function test, we can't easily wait for async actor events unless we block/poll. - // However, the new test runner might expect sync return or a promise (not available yet?). - // For now, we'll just spawn them to ensure no immediate crashes. - // Full async testing might require a different approach or `dmon.poll` style loop if events are exposed. - // Assuming for now that we just verify strict logical errors. - var underlingCount = 0; var targetCount = 3; - - // Spawn several underlings - for (var i = 0; i < targetCount; i++) { + var i = 0; + + for (i = 0; i < targetCount; i++) { $start(function(greet) { underlingCount++; log.console("Underling spawned: " + underlingCount); }, "tests/underling_actor", ["test" + i]); } - - // We can't easily wait here without a loop that yields, but this is a single threaded JS env usually. - // If $delay is async, we return immediately. - + log.console("Spawned " + targetCount + " underlings (async)"); } } diff --git a/tests/parseq.cm b/tests/parseq.cm index 51d39e40..153d848a 100644 --- a/tests/parseq.cm +++ b/tests/parseq.cm @@ -20,17 +20,10 @@ return { } ] } - + var st = time.number() - var actor - - // This test depends on 'tests/comments' which we created as 'comments.cm' - // but 'comments.cm' wraps the actor logic in a function. - // The original 'comments.ce' was an actor script. - // We should probably restore 'comments.ce' as 'comments_actor.ce' for this test to work if it relies on spawning it. - // But 'comments.cm' (the new test file) also has the logic. - // We need an actor file for $start to work with. - + var actor = null + $start(e => { if (actor) return actor = e.actor @@ -39,9 +32,9 @@ return { log.console(reason) else log.console(result) - + log.console(`took ${time.number()-st} secs`) }); - }, "tests/comments_actor") // We will create this next + }, "tests/comments_actor") } } diff --git a/tests/text.cm b/tests/text.cm index a0b04ce2..1a44d82a 100644 --- a/tests/text.cm +++ b/tests/text.cm @@ -1,247 +1,241 @@ return { - // Array conversion tests test_array_basic: function() { var arr1 = ["Hello", " ", "World"] var result1 = text(arr1) - if (result1 != "Hello World") throw "Basic array concat failed" + if (result1 != "Hello World") disrupt }, test_array_separator: function() { var arr2 = ["one", "two", "three"] var result2 = text(arr2, ", ") - if (result2 != "one, two, three") throw "Array with separator failed" + if (result2 != "one, two, three") disrupt }, test_array_codepoints: function() { var arr3 = [72, 101, 108, 108, 111] var result3 = text(arr3) - if (result3 != "Hello") throw "Codepoints failed" + if (result3 != "Hello") disrupt }, test_array_mixed: function() { var arr4 = ["Hi", 32, "there", 33] var result4 = text(arr4) - if (result4 != "Hi there!") throw "Mixed array failed" + if (result4 != "Hi there!") disrupt }, - // Radix tests test_radix_10: function() { var result = text(12, 10) - if (result != "12") throw "Radix 10 failed" + if (result != "12") disrupt }, test_radix_8: function() { var result = text(12, 8) - if (result != "14") throw "Radix 8 failed" + if (result != "14") disrupt }, test_radix_16: function() { var result = text(12, 16) - if (result != "c") throw "Radix 16 failed" + if (result != "c") disrupt }, test_radix_2: function() { var result = text(12, 2) - if (result != "1100") throw "Radix 2 failed" + if (result != "1100") disrupt }, test_radix_32: function() { var result = text(12, 32) - if (result != "c") throw "Radix 32 failed" + if (result != "c") disrupt }, test_radix_hex_large: function() { var result = text(255, 16) - if (result != "ff") throw "Radix 16 large failed" + if (result != "ff") disrupt }, test_radix_negative: function() { var result = text(-42, 10) - if (result != "-42") throw "Radix negative failed" + if (result != "-42") disrupt }, test_radix_36: function() { var result = text(100, 36) - if (result != "2s") throw "Radix 36 failed" + if (result != "2s") disrupt }, - // Formatted number tests test_format_n: function() { var result = text(123456789.1, "n") - if (result != "123456789.1") throw "Format n failed" + if (result != "123456789.1") disrupt }, test_format_spaced_decimal: function() { var result = text(123456789.1, "3s4") - if (result != "123 456 789.1000") throw "Format 3s4 failed" + if (result != "123 456 789.1000") disrupt }, test_format_s: function() { var result = text(123456789.1, "s") - if (result != "123 456 789.1") throw "Format s failed" + if (result != "123 456 789.1") disrupt }, test_format_d2: function() { var result = text(123456789.1, "d2") - if (result != "123,456,789.10") throw "Format d2 failed" + if (result != "123,456,789.10") disrupt }, test_format_4d0: function() { var result = text(123456789.1, "4d0") - if (result != "1,2345,6789.1") throw "Format 4d0 failed" + if (result != "1,2345,6789.1") disrupt }, test_format_e: function() { var result = text(123456789.1, "e") - if (result != "1.234567891e+8") throw "Format e failed" + if (result != "1.234567891e+8") disrupt }, test_format_e4: function() { var result = text(123456789.1, "e4") - if (result != "1.2346e+8") throw "Format e4 failed" + if (result != "1.2346e+8") disrupt }, test_format_i: function() { var result = text(123456789.1, "i") - if (result != "123456789") throw "Format i failed" + if (result != "123456789") disrupt }, test_format_8b: function() { var result = text(123456789.1, "8b") - if (result != "111_01011011_11001101_00010101") throw "Format 8b failed" + if (result != "111_01011011_11001101_00010101") disrupt }, test_format_o: function() { var result = text(123456789.1, "o") - if (result != "726746425") throw "Format o failed" + if (result != "726746425") disrupt }, test_format_h: function() { var result = text(123456789.1, "h") - if (result != "75BCD15") throw "Format h failed" + if (result != "75BCD15") disrupt }, test_format_t: function() { var result = text(123456789.1, "t") - if (result != "3NQK8N") throw "Format t failed" + if (result != "3NQK8N") disrupt }, - // Integer formatting tests test_int_4b8: function() { var result = text(12, "4b8") - if (result != "0000_1100") throw "Int format 4b8 failed" + if (result != "0000_1100") disrupt }, test_int_o3: function() { var result = text(12, "o3") - if (result != "014") throw "Int format o3 failed" + if (result != "014") disrupt }, test_int_h4: function() { var result = text(12, "h4") - if (result != "000C") throw "Int format h4 failed" + if (result != "000C") disrupt }, test_int_t2: function() { var result = text(12, "t2") - if (result != "0C") throw "Int format t2 failed" + if (result != "0C") disrupt }, test_int_h_negative: function() { var result = text(-15, "h") - if (result != "-F") throw "Int format negative h failed" + if (result != "-F") disrupt }, test_int_b_zero: function() { var result = text(0, "b") - if (result != "0") throw "Int format zero b failed" + if (result != "0") disrupt }, - // Substring tests test_substr_start: function() { var str = "miskatonic" var result = text(str, 0, 3) - if (result != "mis") throw "Substr start failed" + if (result != "mis") disrupt }, test_substr_middle: function() { var str = "miskatonic" var result = text(str, 3, 6) - if (result != "kat") throw "Substr middle failed" + if (result != "kat") disrupt }, test_substr_to_end: function() { var str = "miskatonic" var result = text(str, 5, null) - if (result != "tonic") throw "Substr to end failed" + if (result != "tonic") disrupt }, test_substr_negative_to: function() { var str = "miskatonic" var result = text(str, 0, -4) - if (result != "miskat") throw "Substr negative to failed" + if (result != "miskat") disrupt }, test_substr_negative_from: function() { var str = "miskatonic" var result = text(str, -3, null) - if (result != "nic") throw "Substr negative from failed" + if (result != "nic") disrupt }, test_substr_empty_range: function() { var str = "miskatonic" var result = text(str, 0, 0) - if (result != "") throw "Substr empty range failed" + if (result != "") disrupt }, test_substr_past_end: function() { var str = "miskatonic" var result = text(str, 10, null) - if (result != "") throw "Substr past end failed" + if (result != "") disrupt }, test_substr_out_of_bounds: function() { var str = "miskatonic" var result = text(str, 11, null) - if (result != null) throw "Substr out of bounds failed" + if (result != null) disrupt }, test_substr_invalid_range: function() { var str = "miskatonic" var result = text(str, 2, 1) - if (result != null) throw "Substr invalid range failed" + if (result != null) disrupt }, - // Edge cases test_empty_array: function() { var result = text([]) - if (result != "") throw "Empty array test failed" + if (result != "") disrupt }, test_single_element: function() { var result = text([42]) - if (result != "42") throw "Single element array test failed" + if (result != "42") disrupt }, test_identity: function() { var result = text("hello") - if (result != "hello") throw "Text identity test failed" + if (result != "hello") disrupt }, test_invalid_format: function() { var result = text(123, "xyz") - if (result != null) throw "Invalid format test failed" + if (result != null) disrupt }, test_tiny_number: function() { var tiny = 0.0000001 var result = text(tiny, "n") - if (search(result, 'e', 0) == null) throw "Tiny number format failed" + if (search(result, 'e', 0) == null) disrupt }, test_huge_number: function() { var huge = 1e22 var result = text(huge, "n") - if (search(result, 'e', 0) == null) throw "Huge number format failed" + if (search(result, 'e', 0) == null) disrupt } } diff --git a/tests/toml.cm b/tests/toml.cm index 63a8976d..14dc5f1d 100644 --- a/tests/toml.cm +++ b/tests/toml.cm @@ -1,21 +1,24 @@ var toml = use('toml') function deep_equal(a, b) { + var keys_a = null + var keys_b = null + var i = 0 if (a == b) return true if (is_null(a) || is_null(b)) return false if ((is_number(a) && !is_number(b)) || (is_text(a) && !is_text(b)) || (is_object(a) && !is_object(b)) || (is_array(a) && !is_array(b)) || (is_blob(a) && !is_blob(b)) || (is_function(a) && !is_function(b)) || (is_logical(a) && !is_logical(b))) return false - + if (is_object(a)) { - var keys_a = array(a) - var keys_b = array(b) + keys_a = array(a) + keys_b = array(b) if (length(keys_a) != length(keys_b)) return false - - for (var i = 0; i < length(keys_a); i++) { + + for (i = 0; i < length(keys_a); i++) { if (!deep_equal(a[keys_a[i]], b[keys_a[i]])) return false } return true } - + return false } @@ -25,7 +28,7 @@ function test_roundtrip(obj, name) { if (!deep_equal(obj, decoded)) { log.console(name + " - Original:", obj) log.console(name + " - Round-trip:", decoded) - throw name + " round-trip failed" + disrupt } } @@ -79,7 +82,7 @@ return { port: 8080 }, beta: { - ip: "192.168.1.2", + ip: "192.168.1.2", port: 8081 } }, diff --git a/tests/underling_actor.ce b/tests/underling_actor.ce index e4fb6f26..96b15f90 100644 --- a/tests/underling_actor.ce +++ b/tests/underling_actor.ce @@ -1,7 +1,7 @@ var cmds = { stop: $stop, disrupt: _ => { - $delay(_ => { throw Error() }, 0.5) + $delay(_ => { disrupt }, 0.5) } } diff --git a/tests/use.cm b/tests/use.cm index 5d78bc95..7edc4780 100644 --- a/tests/use.cm +++ b/tests/use.cm @@ -1,5 +1,6 @@ -try { +var _try = function() { var u = use('tests/use') -} catch(e) { - log.console(e) +} disruption { + log.console("disruption caught") } +_try() diff --git a/tests/wota.cm b/tests/wota.cm index 3e4ec60d..5e40bf19 100644 --- a/tests/wota.cm +++ b/tests/wota.cm @@ -7,14 +7,18 @@ var EPSILON = 1e-12 function stone_if_needed(b) { if (!stone.p(b)) stone(b) } -/* Deep comparison capable of blobs + tolerance for floating diff */ -function deep_compare(expected, actual, path) { - path = path || '' +function deep_compare(expected, actual, _path) { + var diff = null + var msgs = null + var expKeys = null + var actKeys = null + var i = 0 + var path = _path || '' if (expected == actual) return { passed: true, messages: [] } if (is_number(expected) && is_number(actual)) { if (isNaN(expected) && isNaN(actual)) return { passed: true, messages: [] } - var diff = abs(expected - actual) + diff = abs(expected - actual) if (diff <= EPSILON) return { passed: true, messages: [] } return { passed: false, messages: [`Value mismatch at ${path}: ${expected} vs ${actual} (diff ${diff})`] } } @@ -33,7 +37,7 @@ function deep_compare(expected, actual, path) { if (is_array(expected) && is_array(actual)) { if (length(expected) != length(actual)) return { passed: false, messages: [`Array length mismatch at ${path}: ${length(expected)} vs ${length(actual)}`] } - var msgs = [] + msgs = [] arrfor(array(expected), function(i) { var res = deep_compare(expected[i], actual[i], `${path}[${i}]`) if (!res.passed) array(msgs, res.messages) @@ -42,11 +46,11 @@ function deep_compare(expected, actual, path) { } if (is_object(expected) && is_object(actual)) { - var expKeys = sort(array(expected)) - var actKeys = sort(array(actual)) + expKeys = sort(array(expected)) + actKeys = sort(array(actual)) if (JSON.stringify(expKeys) != JSON.stringify(actKeys)) return { passed: false, messages: [`Object keys mismatch at ${path}: ${expKeys} vs ${actKeys}`] } - var msgs = [] + msgs = [] arrfor(expKeys, function(k) { var res = deep_compare(expected[k], actual[k], `${path}.${k}`) if (!res.passed) array(msgs, res.messages) @@ -58,7 +62,10 @@ function deep_compare(expected, actual, path) { } var testarr = [] -for (var i = 0; i < 500; i++) { push(testarr, 1) } +var i = 0 +var t = null +var name = null +for (i = 0; i < 500; i++) { push(testarr, 1) } var testCases = [ { name: 'zero', input: 0 }, @@ -84,7 +91,7 @@ var testCases = [ { name: 'empty_string', input: '' }, { name: 'string_cat', input: 'cat' }, - { name: 'string_unicode', input: 'U+1F4A9 πÇîπüåπéôπüíτ╡╡µûçσ¡ùπÇì ┬½≡ƒÆ⌐┬╗' }, + { name: 'string_unicode', input: 'U+1F4A9 「うんち絵文字」 «💩»' }, { name: 'large_array', input: testarr }, @@ -106,19 +113,19 @@ var testCases = [ function make_test(t) { return function() { var enc = wota.encode(t.input) - if (!is_blob(enc)) throw 'encode() should return a blob' + if (!is_blob(enc)) disrupt var dec = wota.decode(enc) var cmp = deep_compare(t.input, dec) - if (!cmp.passed) throw text(cmp.messages, '; ') + if (!cmp.passed) disrupt } } var tests = {} -for (var i = 0; i < length(testCases); i++) { - var t = testCases[i] - var name = t.name || ('case_' + i) +for (i = 0; i < length(testCases); i++) { + t = testCases[i] + name = t.name || ('case_' + i) tests[name] = make_test(t) }