intrinsics rewritten without ++, --, etc

This commit is contained in:
2026-02-10 07:19:45 -06:00
parent 3f7e34cd7a
commit c4ff0bc109
13 changed files with 545 additions and 468 deletions

204
pronto.cm
View File

@@ -4,9 +4,9 @@
// Time is in seconds.
function make_reason(factory, excuse, evidence) {
def reason = Error(`pronto.${factory}${excuse ? ': ' + excuse : ''}`)
reason.evidence = evidence
return reason
var msg = 'pronto.' + factory
if (excuse) msg = msg + ': ' + excuse
return { message: msg, evidence: evidence }
}
function is_requestor(fn) {
@@ -14,21 +14,27 @@ function is_requestor(fn) {
}
function check_requestors(list, factory) {
if (!is_array(list) || some(list, r => !is_requestor(r)))
throw make_reason(factory, 'Bad requestor array.', list)
if (!is_array(list) || some(list, r => !is_requestor(r))) {
print(make_reason(factory, 'Bad requestor array.', list).message + '\n')
disrupt
}
}
function check_callback(cb, factory) {
if (!is_function(cb) || length(cb) != 2)
throw make_reason(factory, 'Not a callback.', cb)
if (!is_function(cb) || length(cb) != 2) {
print(make_reason(factory, 'Not a callback.', cb).message + '\n')
disrupt
}
}
// fallback(requestor_array)
// Tries each requestor in order until one succeeds.
function fallback(requestor_array) {
def factory = 'fallback'
if (!is_array(requestor_array) || length(requestor_array) == 0)
throw make_reason(factory, 'Empty requestor array.')
if (!is_array(requestor_array) || length(requestor_array) == 0) {
print(make_reason(factory, 'Empty requestor array.').message + '\n')
disrupt
}
check_requestors(requestor_array, factory)
return function fallback_requestor(callback, value) {
@@ -40,7 +46,8 @@ function fallback(requestor_array) {
function cancel(reason) {
cancelled = true
if (current_cancel) {
try { current_cancel(reason) } catch (_) {}
var _c = function() { current_cancel(reason) } disruption {}
_c()
current_cancel = null
}
}
@@ -53,9 +60,9 @@ function fallback(requestor_array) {
}
def requestor = requestor_array[index]
index += 1
index = index + 1
try {
var _run = function() {
current_cancel = requestor(function(val, reason) {
if (cancelled) return
current_cancel = null
@@ -65,9 +72,10 @@ function fallback(requestor_array) {
try_next()
}
}, value)
} catch (ex) {
} disruption {
try_next()
}
_run()
}
try_next()
@@ -79,25 +87,32 @@ function fallback(requestor_array) {
// Runs requestors in parallel, collecting all results.
function parallel(requestor_array, throttle, need) {
def factory = 'parallel'
if (!is_array(requestor_array))
throw make_reason(factory, 'Not an array.', requestor_array)
if (!is_array(requestor_array)) {
print(make_reason(factory, 'Not an array.', requestor_array).message + '\n')
disrupt
}
check_requestors(requestor_array, factory)
def length = length(requestor_array)
if (length == 0)
def len = length(requestor_array)
if (len == 0)
return function(callback, value) { callback([]) }
if (need == null) need = length
if (!is_number(need) || need < 0 || need > length)
throw make_reason(factory, 'Bad need.', need)
var _need = need
if (_need == null) _need = len
if (!is_number(_need) || _need < 0 || _need > len) {
print(make_reason(factory, 'Bad need.', _need).message + '\n')
disrupt
}
if (throttle != null && (!is_number(throttle) || throttle < 1))
throw make_reason(factory, 'Bad throttle.', throttle)
if (throttle != null && (!is_number(throttle) || throttle < 1)) {
print(make_reason(factory, 'Bad throttle.', throttle).message + '\n')
disrupt
}
return function parallel_requestor(callback, value) {
check_callback(callback, factory)
def results = array(length)
def cancel_list = array(length)
def results = array(len)
def cancel_list = array(len)
var next_index = 0
var successes = 0
var failures = 0
@@ -107,33 +122,34 @@ function parallel(requestor_array, throttle, need) {
if (finished) return
finished = true
arrfor(cancel_list, c => {
try { if (is_function(c)) c(reason) } catch (_) {}
var _c = function() { if (is_function(c)) c(reason) } disruption {}
_c()
})
}
function start_one() {
if (finished || next_index >= length) return
if (finished || next_index >= len) return
def idx = next_index
next_index += 1
next_index = next_index + 1
def requestor = requestor_array[idx]
try {
var _run = function() {
cancel_list[idx] = requestor(function(val, reason) {
if (finished) return
cancel_list[idx] = null
if (val != null) {
results[idx] = val
successes += 1
if (successes >= need) {
successes = successes + 1
if (successes >= _need) {
finished = true
cancel(make_reason(factory, 'Finished.'))
callback(results)
return
}
} else {
failures += 1
if (failures > length - need) {
failures = failures + 1
if (failures > len - _need) {
cancel(reason)
callback(null, reason || make_reason(factory, 'Too many failures.'))
return
@@ -142,20 +158,21 @@ function parallel(requestor_array, throttle, need) {
start_one()
}, value)
} catch (ex) {
failures += 1
if (failures > length - need) {
cancel(ex)
callback(null, ex)
} disruption {
failures = failures + 1
if (failures > len - _need) {
cancel(make_reason(factory, 'Requestor threw.'))
callback(null, make_reason(factory, 'Requestor threw.'))
return
}
start_one()
}
_run()
}
def concurrent = throttle ? min(throttle, length) : length
for (var i = 0; i < concurrent; i++) start_one()
def concurrent = throttle ? min(throttle, len) : len
var i = 0
while (i < concurrent) { start_one(); i = i + 1 }
return cancel
}
@@ -165,22 +182,29 @@ function parallel(requestor_array, throttle, need) {
// Runs requestors in parallel, returns first success(es).
function race(requestor_array, throttle, need) {
def factory = 'race'
if (!is_array(requestor_array) || length(requestor_array) == 0)
throw make_reason(factory, 'Empty requestor array.')
if (!is_array(requestor_array) || length(requestor_array) == 0) {
print(make_reason(factory, 'Empty requestor array.').message + '\n')
disrupt
}
check_requestors(requestor_array, factory)
def length = length(requestor_array)
if (need == null) need = 1
if (!is_number(need) || need < 1 || need > length)
throw make_reason(factory, 'Bad need.', need)
def len = length(requestor_array)
var _need = need
if (_need == null) _need = 1
if (!is_number(_need) || _need < 1 || _need > len) {
print(make_reason(factory, 'Bad need.', _need).message + '\n')
disrupt
}
if (throttle != null && (!is_number(throttle) || throttle < 1))
throw make_reason(factory, 'Bad throttle.', throttle)
if (throttle != null && (!is_number(throttle) || throttle < 1)) {
print(make_reason(factory, 'Bad throttle.', throttle).message + '\n')
disrupt
}
return function race_requestor(callback, value) {
check_callback(callback, factory)
def results = array(length)
def cancel_list = array(length)
def results = array(len)
def cancel_list = array(len)
var next_index = 0
var successes = 0
var failures = 0
@@ -190,27 +214,28 @@ function race(requestor_array, throttle, need) {
if (finished) return
finished = true
arrfor(cancel_list, c => {
try { if (is_function(c)) c(reason) } catch (_) {}
var _c = function() { if (is_function(c)) c(reason) } disruption {}
_c()
})
}
function start_one() {
if (finished || next_index >= length) return
if (finished || next_index >= len) return
def idx = next_index
next_index += 1
next_index = next_index + 1
def requestor = requestor_array[idx]
try {
var _run = function() {
cancel_list[idx] = requestor(function(val, reason) {
if (finished) return
cancel_list[idx] = null
if (val != null) {
results[idx] = val
successes += 1
if (successes >= need) {
successes = successes + 1
if (successes >= _need) {
cancel(make_reason(factory, 'Winner.'))
if (need == 1) {
if (_need == 1) {
callback(val)
} else {
callback(results)
@@ -218,8 +243,8 @@ function race(requestor_array, throttle, need) {
return
}
} else {
failures += 1
if (failures > length - need) {
failures = failures + 1
if (failures > len - _need) {
cancel(reason)
callback(null, reason || make_reason(factory, 'All failed.'))
return
@@ -228,19 +253,21 @@ function race(requestor_array, throttle, need) {
start_one()
}, value)
} catch (ex) {
failures += 1
if (failures > length - need) {
cancel(ex)
callback(null, ex)
} disruption {
failures = failures + 1
if (failures > len - _need) {
cancel(make_reason(factory, 'Requestor threw.'))
callback(null, make_reason(factory, 'Requestor threw.'))
return
}
start_one()
}
_run()
}
def concurrent = throttle ? min(throttle, length) : length
for (var i = 0; i < concurrent; i++) start_one()
def concurrent = throttle ? min(throttle, len) : len
var i = 0
while (i < concurrent) { start_one(); i = i + 1 }
return cancel
}
@@ -250,8 +277,10 @@ function race(requestor_array, throttle, need) {
// Runs requestors one at a time, passing result to next.
function sequence(requestor_array) {
def factory = 'sequence'
if (!is_array(requestor_array))
throw make_reason(factory, 'Not an array.', requestor_array)
if (!is_array(requestor_array)) {
print(make_reason(factory, 'Not an array.', requestor_array).message + '\n')
disrupt
}
check_requestors(requestor_array, factory)
if (length(requestor_array) == 0)
@@ -266,7 +295,8 @@ function sequence(requestor_array) {
function cancel(reason) {
cancelled = true
if (current_cancel) {
try { current_cancel(reason) } catch (_) {}
var _c = function() { current_cancel(reason) } disruption {}
_c()
current_cancel = null
}
}
@@ -279,9 +309,9 @@ function sequence(requestor_array) {
}
def requestor = requestor_array[index]
index += 1
index = index + 1
try {
var _run = function() {
current_cancel = requestor(function(result, reason) {
if (cancelled) return
current_cancel = null
@@ -291,9 +321,10 @@ function sequence(requestor_array) {
run_next(result)
}
}, val)
} catch (ex) {
callback(null, ex)
} disruption {
callback(null, make_reason(factory, 'Requestor threw.'))
}
_run()
}
run_next(value)
@@ -305,26 +336,29 @@ function sequence(requestor_array) {
// Converts a unary function into a requestor.
function requestorize(unary) {
def factory = 'requestorize'
if (!is_function(unary))
throw make_reason(factory, 'Not a function.', unary)
if (!is_function(unary)) {
print(make_reason(factory, 'Not a function.', unary).message + '\n')
disrupt
}
return function requestorized(callback, value) {
check_callback(callback, factory)
try {
var _run = function() {
def result = unary(value)
callback(result == null ? true : result)
} catch (ex) {
callback(null, ex)
} disruption {
callback(null, make_reason(factory, 'Function threw.'))
}
_run()
}
}
return {
fallback,
parallel,
race,
sequence,
requestorize,
is_requestor,
check_callback
fallback: fallback,
parallel: parallel,
race: race,
sequence: sequence,
requestorize: requestorize,
is_requestor: is_requestor,
check_callback: check_callback
}