Merge remote-tracking branch 'origin/js-def' into js-rm-modules
This commit is contained in:
@@ -42,34 +42,34 @@ for (let i = 0; i < 100; i++) {
|
|||||||
|
|
||||||
// Calculate statistics
|
// Calculate statistics
|
||||||
function getStats(arr) {
|
function getStats(arr) {
|
||||||
const avg = arr.reduce((a, b) => a + b) / arr.length;
|
def avg = arr.reduce((a, b) => a + b) / arr.length;
|
||||||
const min = Math.min(...arr);
|
def min = Math.min(...arr);
|
||||||
const max = Math.max(...arr);
|
def max = Math.max(...arr);
|
||||||
return { avg, min, max };
|
return { avg, min, max };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretty print results
|
// Pretty print results
|
||||||
log.console("\n=== Performance Test Results (100 iterations) ===");
|
log.console("\n=== Performance Test Results (100 iterations) ===");
|
||||||
log.console("\nJSON Decoding (ms):");
|
log.console("\nJSON Decoding (ms):");
|
||||||
const jsonDecStats = getStats(jsonDecodeTimes);
|
def jsonDecStats = getStats(jsonDecodeTimes);
|
||||||
log.console(`Average: ${jsonDecStats.avg.toFixed(2)} ms`);
|
log.console(`Average: ${jsonDecStats.avg.toFixed(2)} ms`);
|
||||||
log.console(`Min: ${jsonDecStats.min.toFixed(2)} ms`);
|
log.console(`Min: ${jsonDecStats.min.toFixed(2)} ms`);
|
||||||
log.console(`Max: ${jsonDecStats.max.toFixed(2)} ms`);
|
log.console(`Max: ${jsonDecStats.max.toFixed(2)} ms`);
|
||||||
|
|
||||||
log.console("\nJSON Encoding (ms):");
|
log.console("\nJSON Encoding (ms):");
|
||||||
const jsonEncStats = getStats(jsonEncodeTimes);
|
def jsonEncStats = getStats(jsonEncodeTimes);
|
||||||
log.console(`Average: ${jsonEncStats.avg.toFixed(2)} ms`);
|
log.console(`Average: ${jsonEncStats.avg.toFixed(2)} ms`);
|
||||||
log.console(`Min: ${jsonEncStats.min.toFixed(2)} ms`);
|
log.console(`Min: ${jsonEncStats.min.toFixed(2)} ms`);
|
||||||
log.console(`Max: ${jsonEncStats.max.toFixed(2)} ms`);
|
log.console(`Max: ${jsonEncStats.max.toFixed(2)} ms`);
|
||||||
|
|
||||||
log.console("\nNOTA Encoding (ms):");
|
log.console("\nNOTA Encoding (ms):");
|
||||||
const notaEncStats = getStats(notaEncodeTimes);
|
def notaEncStats = getStats(notaEncodeTimes);
|
||||||
log.console(`Average: ${notaEncStats.avg.toFixed(2)} ms`);
|
log.console(`Average: ${notaEncStats.avg.toFixed(2)} ms`);
|
||||||
log.console(`Min: ${notaEncStats.min.toFixed(2)} ms`);
|
log.console(`Min: ${notaEncStats.min.toFixed(2)} ms`);
|
||||||
log.console(`Max: ${notaEncStats.max.toFixed(2)} ms`);
|
log.console(`Max: ${notaEncStats.max.toFixed(2)} ms`);
|
||||||
|
|
||||||
log.console("\nNOTA Decoding (ms):");
|
log.console("\nNOTA Decoding (ms):");
|
||||||
const notaDecStats = getStats(notaDecodeTimes);
|
def notaDecStats = getStats(notaDecodeTimes);
|
||||||
log.console(`Average: ${notaDecStats.avg.toFixed(2)} ms`);
|
log.console(`Average: ${notaDecStats.avg.toFixed(2)} ms`);
|
||||||
log.console(`Min: ${notaDecStats.min.toFixed(2)} ms`);
|
log.console(`Min: ${notaDecStats.min.toFixed(2)} ms`);
|
||||||
log.console(`Max: ${notaDecStats.max.toFixed(2)} ms`);
|
log.console(`Max: ${notaDecStats.max.toFixed(2)} ms`);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ function roundTripWota(value) {
|
|||||||
// iterations: how many times to loop
|
// iterations: how many times to loop
|
||||||
//
|
//
|
||||||
// You can tweak these as you like for heavier or lighter tests.
|
// You can tweak these as you like for heavier or lighter tests.
|
||||||
const benchmarks = [
|
def benchmarks = [
|
||||||
{
|
{
|
||||||
name: "Small Integers",
|
name: "Small Integers",
|
||||||
data: [0, 42, -1, 2023],
|
data: [0, 42, -1, 2023],
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ var scenario_name = arg[1];
|
|||||||
// 1. Setup "libraries" array to easily switch among wota, nota, and json
|
// 1. Setup "libraries" array to easily switch among wota, nota, and json
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const libraries = [
|
def libraries = [
|
||||||
{
|
{
|
||||||
name: "wota",
|
name: "wota",
|
||||||
encode: wota.encode,
|
encode: wota.encode,
|
||||||
@@ -62,7 +62,7 @@ const libraries = [
|
|||||||
// Each scenario has { name, data, iterations }
|
// Each scenario has { name, data, iterations }
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const benchmarks = [
|
def benchmarks = [
|
||||||
{
|
{
|
||||||
name: "empty",
|
name: "empty",
|
||||||
data: [{}, {}, {}, {}],
|
data: [{}, {}, {}, {}],
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ function make_handle(obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
function wrapSurface(surf, maybeRect){
|
function wrapSurface(surf, maybeRect){
|
||||||
const h = make_handle(surf);
|
def h = make_handle(surf);
|
||||||
if(maybeRect) h.rect = maybeRect; /* honour frame sub-rect */
|
if(maybeRect) h.rect = maybeRect; /* honour frame sub-rect */
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ function decode_image(bytes, ext)
|
|||||||
|
|
||||||
function create_image(path){
|
function create_image(path){
|
||||||
try{
|
try{
|
||||||
const bytes = io.slurpbytes(path);
|
def bytes = io.slurpbytes(path);
|
||||||
|
|
||||||
let raw = decode_image(bytes, path.ext());
|
let raw = decode_image(bytes, path.ext());
|
||||||
|
|
||||||
@@ -169,8 +169,8 @@ function create_image(path){
|
|||||||
return makeAnim( wrapFrames(raw.frames), !!raw.loop );
|
return makeAnim( wrapFrames(raw.frames), !!raw.loop );
|
||||||
|
|
||||||
/* ── Case D: ASE helpers returned { animName:{frames,loop}, … } ── */
|
/* ── Case D: ASE helpers returned { animName:{frames,loop}, … } ── */
|
||||||
const anims = {};
|
def anims = {};
|
||||||
for(const [name, anim] of Object.entries(raw)){
|
for(def [name, anim] of Object.entries(raw)){
|
||||||
if(anim && Array.isArray(anim.frames))
|
if(anim && Array.isArray(anim.frames))
|
||||||
anims[name] = makeAnim( wrapFrames(anim.frames), !!anim.loop );
|
anims[name] = makeAnim( wrapFrames(anim.frames), !!anim.loop );
|
||||||
else if(anim && anim.surface) /* ase with flat surface */
|
else if(anim && anim.surface) /* ase with flat surface */
|
||||||
|
|||||||
@@ -36,16 +36,16 @@ var geometry = use('geometry')
|
|||||||
|
|
||||||
function updateCameraMatrix(camera, winW, winH) {
|
function updateCameraMatrix(camera, winW, winH) {
|
||||||
// world→NDC
|
// world→NDC
|
||||||
const sx = 1 / camera.size[0];
|
def sx = 1 / camera.size[0];
|
||||||
const sy = 1 / camera.size[1];
|
def sy = 1 / camera.size[1];
|
||||||
const ox = camera.pos[0] - camera.size[0] * camera.anchor[0];
|
def ox = camera.pos[0] - camera.size[0] * camera.anchor[0];
|
||||||
const oy = camera.pos[1] - camera.size[1] * camera.anchor[1];
|
def oy = camera.pos[1] - camera.size[1] * camera.anchor[1];
|
||||||
|
|
||||||
// NDC→pixels
|
// NDC→pixels
|
||||||
const vx = camera.viewport.x * winW;
|
def vx = camera.viewport.x * winW;
|
||||||
const vy = camera.viewport.y * winH;
|
def vy = camera.viewport.y * winH;
|
||||||
const vw = camera.viewport.width * winW;
|
def vw = camera.viewport.width * winW;
|
||||||
const vh = camera.viewport.height * winH;
|
def vh = camera.viewport.height * winH;
|
||||||
|
|
||||||
// final “mat” coefficients
|
// final “mat” coefficients
|
||||||
// [ a 0 c ]
|
// [ a 0 c ]
|
||||||
@@ -82,14 +82,14 @@ function screenToWorldPoint(pos, camera) {
|
|||||||
//---- rectangle (two corner) ----
|
//---- rectangle (two corner) ----
|
||||||
function worldToScreenRect(rect, camera) {
|
function worldToScreenRect(rect, camera) {
|
||||||
// map bottom-left and top-right
|
// map bottom-left and top-right
|
||||||
const x1 = camera.a * rect.x + camera.c;
|
def x1 = camera.a * rect.x + camera.c;
|
||||||
const y1 = camera.e * rect.y + camera.f;
|
def y1 = camera.e * rect.y + camera.f;
|
||||||
const x2 = camera.a * (rect.x + rect.width) + camera.c;
|
def x2 = camera.a * (rect.x + rect.width) + camera.c;
|
||||||
const y2 = camera.e * (rect.y + rect.height) + camera.f;
|
def y2 = camera.e * (rect.y + rect.height) + camera.f;
|
||||||
|
|
||||||
// pick mins and abs deltas
|
// pick mins and abs deltas
|
||||||
const x0 = x1 < x2 ? x1 : x2;
|
def x0 = x1 < x2 ? x1 : x2;
|
||||||
const y0 = y1 < y2 ? y1 : y2;
|
def y0 = y1 < y2 ? y1 : y2;
|
||||||
return {
|
return {
|
||||||
x: x0,
|
x: x0,
|
||||||
y: y0,
|
y: y0,
|
||||||
@@ -335,7 +335,7 @@ function poll_input() {
|
|||||||
|
|
||||||
// 2) helper to build & send a batch, then call done()
|
// 2) helper to build & send a batch, then call done()
|
||||||
function create_batch(draw_cmds, done) {
|
function create_batch(draw_cmds, done) {
|
||||||
const batch = [
|
def batch = [
|
||||||
{op:'set', prop:'drawColor', value:[0.1,0.1,0.15,1]},
|
{op:'set', prop:'drawColor', value:[0.1,0.1,0.15,1]},
|
||||||
{op:'clear'}
|
{op:'clear'}
|
||||||
]
|
]
|
||||||
@@ -349,8 +349,8 @@ function create_batch(draw_cmds, done) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
send(video, {kind:'renderer', op:'batch', data:batch}, () => {
|
send(video, {kind:'renderer', op:'batch', data:batch}, () => {
|
||||||
const now = time.number()
|
def now = time.number()
|
||||||
const dt = now - last_time
|
def dt = now - last_time
|
||||||
last_time = now
|
last_time = now
|
||||||
|
|
||||||
frames.push(dt)
|
frames.push(dt)
|
||||||
@@ -376,7 +376,7 @@ function start_pipeline() {
|
|||||||
|
|
||||||
function render_step() {
|
function render_step() {
|
||||||
// a) fire off the next update→draw immediately
|
// a) fire off the next update→draw immediately
|
||||||
const dt = time.number() - last_time
|
def dt = time.number() - last_time
|
||||||
send(gameactor, {kind:'update', dt:1/60}, () =>
|
send(gameactor, {kind:'update', dt:1/60}, () =>
|
||||||
send(gameactor, {kind:'draw'}, cmds => pending_next = cmds)
|
send(gameactor, {kind:'draw'}, cmds => pending_next = cmds)
|
||||||
)
|
)
|
||||||
@@ -390,8 +390,8 @@ function render_step() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// d) schedule the next render step
|
// d) schedule the next render step
|
||||||
const render_dur = time.number() - last_time
|
def render_dur = time.number() - last_time
|
||||||
const wait = Math.max(0, 1/60 - ttr)
|
def wait = Math.max(0, 1/60 - ttr)
|
||||||
$_.delay(render_step, 0)
|
$_.delay(render_step, 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* anim.js – drop this at top of your script or in a module */
|
/* anim.js – drop this at top of your script or in a module */
|
||||||
var Anim = (() => {
|
var Anim = (() => {
|
||||||
const DEFAULT_MIN = 1 / 60; /* 16 ms – one frame */
|
def DEFAULT_MIN = 1 / 60; /* 16 ms – one frame */
|
||||||
|
|
||||||
function play(source, loop=true){
|
function play(source, loop=true){
|
||||||
return {
|
return {
|
||||||
@@ -13,9 +13,9 @@ var Anim = (() => {
|
|||||||
|
|
||||||
function update(a, dt){
|
function update(a, dt){
|
||||||
a.timer += dt;
|
a.timer += dt;
|
||||||
const frames = a.src.frames;
|
def frames = a.src.frames;
|
||||||
while(true){
|
while(true){
|
||||||
const time = Math.max(frames[a.idx].time || 0, Anim.minDelay);
|
def time = Math.max(frames[a.idx].time || 0, Anim.minDelay);
|
||||||
if(a.timer < time) break; /* still on current frame */
|
if(a.timer < time) break; /* still on current frame */
|
||||||
|
|
||||||
a.timer -= time;
|
a.timer -= time;
|
||||||
@@ -29,7 +29,7 @@ var Anim = (() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function current(a){ return a.src.frames[a.idx].image; }
|
function current(a){ return a.src.frames[a.idx].image; }
|
||||||
function updateAll(arr, dt){ for(const a of arr) update(a, dt); }
|
function updateAll(arr, dt){ for(def a of arr) update(a, dt); }
|
||||||
function draw(a, pos, opt, pipe){
|
function draw(a, pos, opt, pipe){
|
||||||
draw2d.image(current(a), pos, 0, [0,0], [0,0], opt, pipe);
|
draw2d.image(current(a), pos, 0, [0,0], [0,0], opt, pipe);
|
||||||
}
|
}
|
||||||
@@ -60,10 +60,10 @@ var camera = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ── load animations ───────────────────── */
|
/* ── load animations ───────────────────── */
|
||||||
const crab = gfx.texture('tests/crab'); // gif → Animation
|
def crab = gfx.texture('tests/crab'); // gif → Animation
|
||||||
const warrior = gfx.texture('tests/warrior'); // ase → {Original:Animation}
|
def warrior = gfx.texture('tests/warrior'); // ase → {Original:Animation}
|
||||||
|
|
||||||
const anims = [
|
def anims = [
|
||||||
Anim.play(crab), // crab.frames
|
Anim.play(crab), // crab.frames
|
||||||
Anim.play(warrior.Run) // warrior.Original.frames
|
Anim.play(warrior.Run) // warrior.Original.frames
|
||||||
];
|
];
|
||||||
@@ -76,8 +76,8 @@ Anim.minDelay = 1 / 100; // 10 ms, feel free to tune later
|
|||||||
let last = os.now();
|
let last = os.now();
|
||||||
|
|
||||||
function loop(){
|
function loop(){
|
||||||
const now = os.now();
|
def now = os.now();
|
||||||
const dt = now - last; // real frame time
|
def dt = now - last; // real frame time
|
||||||
last = now;
|
last = now;
|
||||||
|
|
||||||
Anim.updateAll(anims, dt);
|
Anim.updateAll(anims, dt);
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
Each factory returns a **requestor** function as described by the spec.
|
Each factory returns a **requestor** function as described by the spec.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const delay = arg[0] // may be undefined
|
def delay = arg[0] // may be undefined
|
||||||
|
|
||||||
// ———————————————————————————————————————— helpers
|
// ———————————————————————————————————————— helpers
|
||||||
|
|
||||||
function make_reason (factory, excuse, evidence) {
|
function make_reason (factory, excuse, evidence) {
|
||||||
const reason = new Error(`parseq.${factory}${excuse ? ': ' + excuse : ''}`)
|
def reason = new Error(`parseq.${factory}${excuse ? ': ' + excuse : ''}`)
|
||||||
reason.evidence = evidence
|
reason.evidence = evidence
|
||||||
return reason
|
return reason
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
|
|||||||
function start_requestor (value) {
|
function start_requestor (value) {
|
||||||
if (!cancel_list || next >= requestors.length) return
|
if (!cancel_list || next >= requestors.length) return
|
||||||
let idx = next++
|
let idx = next++
|
||||||
const req = requestors[idx]
|
def req = requestors[idx]
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cancel_list[idx] = req(function req_cb (val, reason) {
|
cancel_list[idx] = req(function req_cb (val, reason) {
|
||||||
@@ -86,7 +86,7 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
|
|||||||
if (time_limit > 0) timer_cancel = schedule(() => cancel(make_reason(factory, 'Timeout.', time_limit)), time_limit)
|
if (time_limit > 0) timer_cancel = schedule(() => cancel(make_reason(factory, 'Timeout.', time_limit)), time_limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
const concurrent = throttle ? Math.min(throttle, requestors.length) : requestors.length
|
def concurrent = throttle ? Math.min(throttle, requestors.length) : requestors.length
|
||||||
for (let i = 0; i < concurrent; i++) start_requestor(initial)
|
for (let i = 0; i < concurrent; i++) start_requestor(initial)
|
||||||
|
|
||||||
return cancel
|
return cancel
|
||||||
@@ -97,8 +97,8 @@ function run (factory, requestors, initial, action, time_limit, throttle = 0) {
|
|||||||
function _normalize (collection, factory) {
|
function _normalize (collection, factory) {
|
||||||
if (Array.isArray(collection)) return { names: null, list: collection }
|
if (Array.isArray(collection)) return { names: null, list: collection }
|
||||||
if (collection && typeof collection === 'object') {
|
if (collection && typeof collection === 'object') {
|
||||||
const names = Object.keys(collection)
|
def names = Object.keys(collection)
|
||||||
const list = names.map(k => collection[k]).filter(is_requestor)
|
def list = names.map(k => collection[k]).filter(is_requestor)
|
||||||
return { names, list }
|
return { names, list }
|
||||||
}
|
}
|
||||||
throw make_reason(factory, 'Expected array or record.', collection)
|
throw make_reason(factory, 'Expected array or record.', collection)
|
||||||
@@ -106,23 +106,23 @@ function _normalize (collection, factory) {
|
|||||||
|
|
||||||
function _denormalize (names, list) {
|
function _denormalize (names, list) {
|
||||||
if (!names) return list
|
if (!names) return list
|
||||||
const obj = Object.create(null)
|
def obj = Object.create(null)
|
||||||
names.forEach((k, i) => { obj[k] = list[i] })
|
names.forEach((k, i) => { obj[k] = list[i] })
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
function par_all (collection, time_limit, throttle) {
|
function par_all (collection, time_limit, throttle) {
|
||||||
const factory = 'par_all'
|
def factory = 'par_all'
|
||||||
const { names, list } = _normalize(collection, factory)
|
def { names, list } = _normalize(collection, factory)
|
||||||
if (list.length === 0) return (cb, v) => cb(names ? {} : [])
|
if (list.length === 0) return (cb, v) => cb(names ? {} : [])
|
||||||
check_requestors(list, factory)
|
check_requestors(list, factory)
|
||||||
|
|
||||||
return function par_all_req (cb, initial) {
|
return function par_all_req (cb, initial) {
|
||||||
check_callback(cb, factory)
|
check_callback(cb, factory)
|
||||||
let pending = list.length
|
let pending = list.length
|
||||||
const results = new Array(list.length)
|
def results = new Array(list.length)
|
||||||
|
|
||||||
const cancel = run(factory, list, initial, (val, reason, idx) => {
|
def cancel = run(factory, list, initial, (val, reason, idx) => {
|
||||||
if (val === undefined) {
|
if (val === undefined) {
|
||||||
cancel(reason)
|
cancel(reason)
|
||||||
return cb(undefined, reason)
|
return cb(undefined, reason)
|
||||||
@@ -136,17 +136,17 @@ function par_all (collection, time_limit, throttle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function par_any (collection, time_limit, throttle) {
|
function par_any (collection, time_limit, throttle) {
|
||||||
const factory = 'par_any'
|
def factory = 'par_any'
|
||||||
const { names, list } = _normalize(collection, factory)
|
def { names, list } = _normalize(collection, factory)
|
||||||
if (list.length === 0) return (cb, v) => cb(names ? {} : [])
|
if (list.length === 0) return (cb, v) => cb(names ? {} : [])
|
||||||
check_requestors(list, factory)
|
check_requestors(list, factory)
|
||||||
|
|
||||||
return function par_any_req (cb, initial) {
|
return function par_any_req (cb, initial) {
|
||||||
check_callback(cb, factory)
|
check_callback(cb, factory)
|
||||||
let pending = list.length
|
let pending = list.length
|
||||||
const successes = new Array(list.length)
|
def successes = new Array(list.length)
|
||||||
|
|
||||||
const cancel = run(factory, list, initial, (val, reason, idx) => {
|
def cancel = run(factory, list, initial, (val, reason, idx) => {
|
||||||
pending--
|
pending--
|
||||||
if (val !== undefined) successes[idx] = val
|
if (val !== undefined) successes[idx] = val
|
||||||
if (successes.some(v => v !== undefined)) {
|
if (successes.some(v => v !== undefined)) {
|
||||||
@@ -161,7 +161,7 @@ function par_any (collection, time_limit, throttle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function race (list, time_limit, throttle) {
|
function race (list, time_limit, throttle) {
|
||||||
const factory = throttle === 1 ? 'fallback' : 'race'
|
def factory = throttle === 1 ? 'fallback' : 'race'
|
||||||
if (!Array.isArray(list) || list.length === 0)
|
if (!Array.isArray(list) || list.length === 0)
|
||||||
throw make_reason(factory, 'No requestors.')
|
throw make_reason(factory, 'No requestors.')
|
||||||
check_requestors(list, factory)
|
check_requestors(list, factory)
|
||||||
@@ -169,7 +169,7 @@ function race (list, time_limit, throttle) {
|
|||||||
return function race_req (cb, initial) {
|
return function race_req (cb, initial) {
|
||||||
check_callback(cb, factory)
|
check_callback(cb, factory)
|
||||||
let done = false
|
let done = false
|
||||||
const cancel = run(factory, list, initial, (val, reason, idx) => {
|
def cancel = run(factory, list, initial, (val, reason, idx) => {
|
||||||
if (done) return
|
if (done) return
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
done = true
|
done = true
|
||||||
@@ -190,7 +190,7 @@ function fallback (list, time_limit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sequence (list, time_limit) {
|
function sequence (list, time_limit) {
|
||||||
const factory = 'sequence'
|
def factory = 'sequence'
|
||||||
if (!Array.isArray(list)) throw make_reason(factory, 'Not an array.', list)
|
if (!Array.isArray(list)) throw make_reason(factory, 'Not an array.', list)
|
||||||
check_requestors(list, factory)
|
check_requestors(list, factory)
|
||||||
if (list.length === 0) return (cb, v) => cb(v)
|
if (list.length === 0) return (cb, v) => cb(v)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ DEF(if, "if")
|
|||||||
DEF(else, "else")
|
DEF(else, "else")
|
||||||
DEF(return, "return")
|
DEF(return, "return")
|
||||||
DEF(var, "var")
|
DEF(var, "var")
|
||||||
|
DEF(def, "def")
|
||||||
DEF(this, "this")
|
DEF(this, "this")
|
||||||
DEF(delete, "delete")
|
DEF(delete, "delete")
|
||||||
DEF(void, "void")
|
DEF(void, "void")
|
||||||
|
|||||||
@@ -18183,6 +18183,7 @@ enum {
|
|||||||
TOK_ELSE,
|
TOK_ELSE,
|
||||||
TOK_RETURN,
|
TOK_RETURN,
|
||||||
TOK_VAR,
|
TOK_VAR,
|
||||||
|
TOK_DEF,
|
||||||
TOK_THIS,
|
TOK_THIS,
|
||||||
TOK_DELETE,
|
TOK_DELETE,
|
||||||
TOK_VOID,
|
TOK_VOID,
|
||||||
@@ -21624,14 +21625,14 @@ static __exception int js_define_var(JSParseState *s, JSAtom name, int tok)
|
|||||||
return js_parse_error(s, "invalid variable name in strict mode");
|
return js_parse_error(s, "invalid variable name in strict mode");
|
||||||
}
|
}
|
||||||
if (name == JS_ATOM_let
|
if (name == JS_ATOM_let
|
||||||
&& (tok == TOK_LET || tok == TOK_CONST)) {
|
&& (tok == TOK_LET || tok == TOK_DEF)) {
|
||||||
return js_parse_error(s, "invalid lexical variable name");
|
return js_parse_error(s, "invalid lexical variable name");
|
||||||
}
|
}
|
||||||
switch(tok) {
|
switch(tok) {
|
||||||
case TOK_LET:
|
case TOK_LET:
|
||||||
var_def_type = JS_VAR_DEF_LET;
|
var_def_type = JS_VAR_DEF_LET;
|
||||||
break;
|
break;
|
||||||
case TOK_CONST:
|
case TOK_DEF:
|
||||||
var_def_type = JS_VAR_DEF_CONST;
|
var_def_type = JS_VAR_DEF_CONST;
|
||||||
break;
|
break;
|
||||||
case TOK_VAR:
|
case TOK_VAR:
|
||||||
@@ -21693,7 +21694,7 @@ duplicate:
|
|||||||
return js_parse_error(s, "duplicate parameter names not allowed in this context");
|
return js_parse_error(s, "duplicate parameter names not allowed in this context");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tok = TOK_VAR, TOK_LET or TOK_CONST. Return whether a reference
|
/* tok = TOK_VAR, TOK_LET or TOK_DEF. Return whether a reference
|
||||||
must be taken to the variable for proper 'with' or global variable
|
must be taken to the variable for proper 'with' or global variable
|
||||||
evaluation */
|
evaluation */
|
||||||
/* Note: this function is needed only because variable references are
|
/* Note: this function is needed only because variable references are
|
||||||
@@ -22024,7 +22025,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
|
|||||||
/* store value into lvalue object */
|
/* store value into lvalue object */
|
||||||
put_lvalue(s, opcode, scope, var_name, label_lvalue,
|
put_lvalue(s, opcode, scope, var_name, label_lvalue,
|
||||||
PUT_LVALUE_NOKEEP_DEPTH,
|
PUT_LVALUE_NOKEEP_DEPTH,
|
||||||
(tok == TOK_CONST || tok == TOK_LET));
|
(tok == TOK_DEF || tok == TOK_LET));
|
||||||
if (s->token.val == '}')
|
if (s->token.val == '}')
|
||||||
break;
|
break;
|
||||||
/* accept a trailing comma before the '}' */
|
/* accept a trailing comma before the '}' */
|
||||||
@@ -22138,7 +22139,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
|
|||||||
/* store value into lvalue object */
|
/* store value into lvalue object */
|
||||||
put_lvalue(s, opcode, scope, var_name,
|
put_lvalue(s, opcode, scope, var_name,
|
||||||
label_lvalue, PUT_LVALUE_NOKEEP_DEPTH,
|
label_lvalue, PUT_LVALUE_NOKEEP_DEPTH,
|
||||||
(tok == TOK_CONST || tok == TOK_LET));
|
(tok == TOK_DEF || tok == TOK_LET));
|
||||||
}
|
}
|
||||||
if (s->token.val == ']')
|
if (s->token.val == ']')
|
||||||
break;
|
break;
|
||||||
@@ -23490,7 +23491,7 @@ static __exception int js_parse_var(JSParseState *s, int parse_flags, int tok,
|
|||||||
return js_parse_error_reserved_identifier(s);
|
return js_parse_error_reserved_identifier(s);
|
||||||
}
|
}
|
||||||
name = JS_DupAtom(ctx, s->token.u.ident.atom);
|
name = JS_DupAtom(ctx, s->token.u.ident.atom);
|
||||||
if (name == JS_ATOM_let && (tok == TOK_LET || tok == TOK_CONST)) {
|
if (name == JS_ATOM_let && (tok == TOK_LET || tok == TOK_DEF)) {
|
||||||
js_parse_error(s, "'let' is not a valid lexical identifier");
|
js_parse_error(s, "'let' is not a valid lexical identifier");
|
||||||
goto var_error;
|
goto var_error;
|
||||||
}
|
}
|
||||||
@@ -23523,13 +23524,13 @@ static __exception int js_parse_var(JSParseState *s, int parse_flags, int tok,
|
|||||||
if (js_parse_assign_expr2(s, parse_flags))
|
if (js_parse_assign_expr2(s, parse_flags))
|
||||||
goto var_error;
|
goto var_error;
|
||||||
set_object_name(s, name);
|
set_object_name(s, name);
|
||||||
emit_op(s, (tok == TOK_CONST || tok == TOK_LET) ?
|
emit_op(s, (tok == TOK_DEF || tok == TOK_LET) ?
|
||||||
OP_scope_put_var_init : OP_scope_put_var);
|
OP_scope_put_var_init : OP_scope_put_var);
|
||||||
emit_atom(s, name);
|
emit_atom(s, name);
|
||||||
emit_u16(s, fd->scope_level);
|
emit_u16(s, fd->scope_level);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (tok == TOK_CONST) {
|
if (tok == TOK_DEF) {
|
||||||
js_parse_error(s, "missing initializer for const variable");
|
js_parse_error(s, "missing initializer for const variable");
|
||||||
goto var_error;
|
goto var_error;
|
||||||
}
|
}
|
||||||
@@ -23665,7 +23666,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name)
|
|||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (tok == TOK_VAR || tok == TOK_LET || tok == TOK_CONST) {
|
if (tok == TOK_VAR || tok == TOK_LET || tok == TOK_DEF) {
|
||||||
if (next_token(s))
|
if (next_token(s))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -23688,7 +23689,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name)
|
|||||||
JS_FreeAtom(s->ctx, var_name);
|
JS_FreeAtom(s->ctx, var_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
emit_op(s, (tok == TOK_CONST || tok == TOK_LET) ?
|
emit_op(s, (tok == TOK_DEF || tok == TOK_LET) ?
|
||||||
OP_scope_put_var_init : OP_scope_put_var);
|
OP_scope_put_var_init : OP_scope_put_var);
|
||||||
emit_atom(s, var_name);
|
emit_atom(s, var_name);
|
||||||
emit_u16(s, fd->scope_level);
|
emit_u16(s, fd->scope_level);
|
||||||
@@ -23929,7 +23930,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_LET:
|
case TOK_LET:
|
||||||
case TOK_CONST:
|
case TOK_DEF:
|
||||||
haslet:
|
haslet:
|
||||||
if (!(decl_mask & DECL_MASK_OTHER)) {
|
if (!(decl_mask & DECL_MASK_OTHER)) {
|
||||||
js_parse_error(s, "lexical declarations can't appear in single-statement context");
|
js_parse_error(s, "lexical declarations can't appear in single-statement context");
|
||||||
@@ -24088,7 +24089,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
|
|||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (tok == TOK_VAR || tok == TOK_LET || tok == TOK_CONST) {
|
if (tok == TOK_VAR || tok == TOK_LET || tok == TOK_DEF) {
|
||||||
if (next_token(s))
|
if (next_token(s))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (js_parse_var(s, FALSE, tok, FALSE))
|
if (js_parse_var(s, FALSE, tok, FALSE))
|
||||||
@@ -28448,7 +28449,7 @@ static __exception int js_parse_directives(JSParseState *s)
|
|||||||
case TOK_TRY:
|
case TOK_TRY:
|
||||||
case TOK_FUNCTION:
|
case TOK_FUNCTION:
|
||||||
case TOK_DEBUGGER:
|
case TOK_DEBUGGER:
|
||||||
case TOK_CONST:
|
case TOK_DEF:
|
||||||
case TOK_ENUM:
|
case TOK_ENUM:
|
||||||
case TOK_EXPORT:
|
case TOK_EXPORT:
|
||||||
case TOK_IMPORT:
|
case TOK_IMPORT:
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function deepCompare(expected, actual, path = '') {
|
|||||||
if (isNaN(expected) && isNaN(actual))
|
if (isNaN(expected) && isNaN(actual))
|
||||||
return { passed: true, messages: [] };
|
return { passed: true, messages: [] };
|
||||||
|
|
||||||
const diff = Math.abs(expected - actual);
|
def diff = Math.abs(expected - actual);
|
||||||
if (diff <= EPSILON)
|
if (diff <= EPSILON)
|
||||||
return { passed: true, messages: [] };
|
return { passed: true, messages: [] };
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ function deepCompare(expected, actual, path = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (expected instanceof ArrayBuffer && actual instanceof ArrayBuffer) {
|
if (expected instanceof ArrayBuffer && actual instanceof ArrayBuffer) {
|
||||||
const expArray = Array.from(new Uint8Array(expected));
|
def expArray = Array.from(new Uint8Array(expected));
|
||||||
const actArray = Array.from(new Uint8Array(actual));
|
def actArray = Array.from(new Uint8Array(actual));
|
||||||
return deepCompare(expArray, actArray, path);
|
return deepCompare(expArray, actArray, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ function deepCompare(expected, actual, path = '') {
|
|||||||
};
|
};
|
||||||
let messages = [];
|
let messages = [];
|
||||||
for (let i = 0; i < expected.length; i++) {
|
for (let i = 0; i < expected.length; i++) {
|
||||||
const result = deepCompare(expected[i], actual[i], `${path}[${i}]`);
|
def result = deepCompare(expected[i], actual[i], `${path}[${i}]`);
|
||||||
if (!result.passed) messages.push(...result.messages);
|
if (!result.passed) messages.push(...result.messages);
|
||||||
}
|
}
|
||||||
return { passed: messages.length === 0, messages };
|
return { passed: messages.length === 0, messages };
|
||||||
@@ -65,8 +65,8 @@ function deepCompare(expected, actual, path = '') {
|
|||||||
|
|
||||||
if (typeof expected === 'object' && expected !== null &&
|
if (typeof expected === 'object' && expected !== null &&
|
||||||
typeof actual === 'object' && actual !== null) {
|
typeof actual === 'object' && actual !== null) {
|
||||||
const expKeys = Object.keys(expected).sort();
|
def expKeys = Object.keys(expected).sort();
|
||||||
const actKeys = Object.keys(actual).sort();
|
def actKeys = Object.keys(actual).sort();
|
||||||
if (JSON.stringify(expKeys) !== JSON.stringify(actKeys))
|
if (JSON.stringify(expKeys) !== JSON.stringify(actKeys))
|
||||||
return {
|
return {
|
||||||
passed: false,
|
passed: false,
|
||||||
@@ -74,7 +74,7 @@ function deepCompare(expected, actual, path = '') {
|
|||||||
};
|
};
|
||||||
let messages = [];
|
let messages = [];
|
||||||
for (let key of expKeys) {
|
for (let key of expKeys) {
|
||||||
const result = deepCompare(expected[key], actual[key], `${path}.${key}`);
|
def result = deepCompare(expected[key], actual[key], `${path}.${key}`);
|
||||||
if (!result.passed) messages.push(...result.messages);
|
if (!result.passed) messages.push(...result.messages);
|
||||||
}
|
}
|
||||||
return { passed: messages.length === 0, messages };
|
return { passed: messages.length === 0, messages };
|
||||||
@@ -228,11 +228,11 @@ for (let test of testCases) {
|
|||||||
if (decoded instanceof ArrayBuffer)
|
if (decoded instanceof ArrayBuffer)
|
||||||
decoded = Array.from(new Uint8Array(decoded));
|
decoded = Array.from(new Uint8Array(decoded));
|
||||||
if (expected && (expected.private || expected.system)) {
|
if (expected && (expected.private || expected.system)) {
|
||||||
const key = expected.private ? 'private' : 'system';
|
def key = expected.private ? 'private' : 'system';
|
||||||
expected = { [key]: expected[key] };
|
expected = { [key]: expected[key] };
|
||||||
}
|
}
|
||||||
|
|
||||||
const compareResult = deepCompare(expected, decoded);
|
def compareResult = deepCompare(expected, decoded);
|
||||||
if (!compareResult.passed) {
|
if (!compareResult.passed) {
|
||||||
passed = false;
|
passed = false;
|
||||||
messages.push("Decoding failed:");
|
messages.push("Decoding failed:");
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ send(ioguy, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function strToArrayBuffer(binStr) {
|
function strToArrayBuffer(binStr) {
|
||||||
const view = new Uint8Array(binStr.length);
|
def view = new Uint8Array(binStr.length);
|
||||||
for (let i = 0; i < binStr.length; i++)
|
for (let i = 0; i < binStr.length; i++)
|
||||||
view[i] = binStr.codePointAt(i) & 0xff; // mask keeps it 0-255
|
view[i] = binStr.codePointAt(i) & 0xff; // mask keeps it 0-255
|
||||||
return view.buffer;
|
return view.buffer;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ var Blob = use('blob')
|
|||||||
/* Helper utilities */
|
/* Helper utilities */
|
||||||
/*──────────────────────────────────────────────────────────────────────────*/
|
/*──────────────────────────────────────────────────────────────────────────*/
|
||||||
|
|
||||||
const EPSILON = 1e-12
|
def EPSILON = 1e-12
|
||||||
|
|
||||||
function stone_if_needed(b) { if (!stone.p(b)) stone(b) }
|
function stone_if_needed(b) { if (!stone.p(b)) stone(b) }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user