mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-19 01:01:59 +03:00
26a47ddafe
I was getting a stack overflow on the tailrec002 test, caused by this primitive being recursive. I've made it iterative. I'm no JS expert but I've tested its behaviour against the old version.
206 lines
5.2 KiB
JavaScript
206 lines
5.2 KiB
JavaScript
class IdrisError extends Error { }
|
|
|
|
function __prim_js2idris_array(x){
|
|
let acc = { h:0 };
|
|
|
|
for (i = x.length-1; i>=0; i--) {
|
|
acc = { a1:x[i], a2:acc };
|
|
}
|
|
return acc;
|
|
}
|
|
|
|
function __prim_idris2js_array(x){
|
|
const result = Array();
|
|
while (x.h === undefined) {
|
|
result.push(x.a1); x = x.a2;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function __lazy(thunk) {
|
|
let res;
|
|
return function () {
|
|
if (thunk === undefined) return res;
|
|
res = thunk();
|
|
thunk = undefined;
|
|
return res;
|
|
};
|
|
};
|
|
|
|
function __prim_stringIteratorNew(str) {
|
|
return 0
|
|
}
|
|
|
|
function __prim_stringIteratorToString(_, str, it, f) {
|
|
return f(str.slice(it))
|
|
}
|
|
|
|
function __prim_stringIteratorNext(str, it) {
|
|
if (it >= str.length)
|
|
return {h: 0};
|
|
else
|
|
return {a1: str.charAt(it), a2: it + 1};
|
|
}
|
|
|
|
function __tailRec(f,ini) {
|
|
let obj = ini;
|
|
while(true){
|
|
switch(obj.h){
|
|
case 0: return obj.a1;
|
|
default: obj = f(obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
const _idrisworld = Symbol('idrisworld')
|
|
|
|
const _crashExp = x=>{throw new IdrisError(x)}
|
|
|
|
const _bigIntOfString = s=> {
|
|
try {
|
|
const idx = s.indexOf('.')
|
|
return idx === -1 ? BigInt(s) : BigInt(s.slice(0, idx))
|
|
} catch (e) { return 0n }
|
|
}
|
|
|
|
const _numberOfString = s=> {
|
|
try {
|
|
const res = Number(s);
|
|
return isNaN(res) ? 0 : res;
|
|
} catch (e) { return 0 }
|
|
}
|
|
|
|
const _intOfString = s=> Math.trunc(_numberOfString(s))
|
|
|
|
const _truncToChar = x=> String.fromCodePoint(
|
|
(x >= 0 && x <= 55295) || (x >= 57344 && x <= 1114111) ? x : 0
|
|
)
|
|
|
|
// Int8
|
|
const _truncInt8 = x => {
|
|
const res = x & 0xff;
|
|
return res >= 0x80 ? res - 0x100 : res;
|
|
}
|
|
|
|
const _truncBigInt8 = x => {
|
|
const res = Number(x & 0xffn);
|
|
return res >= 0x80 ? res - 0x100 : res;
|
|
}
|
|
|
|
const _add8s = (a,b) => _truncInt8(a + b)
|
|
const _sub8s = (a,b) => _truncInt8(a - b)
|
|
const _mul8s = (a,b) => _truncInt8(a * b)
|
|
const _div8s = (a,b) => _truncInt8(Math.trunc(a / b))
|
|
const _shl8s = (a,b) => _truncInt8(a << b)
|
|
const _shr8s = (a,b) => _truncInt8(a >> b)
|
|
|
|
// Int16
|
|
const _truncInt16 = x => {
|
|
const res = x & 0xffff;
|
|
return res >= 0x8000 ? res - 0x10000 : res;
|
|
}
|
|
|
|
const _truncBigInt16 = x => {
|
|
const res = Number(x & 0xffffn);
|
|
return res >= 0x8000 ? res - 0x10000 : res;
|
|
}
|
|
|
|
const _add16s = (a,b) => _truncInt16(a + b)
|
|
const _sub16s = (a,b) => _truncInt16(a - b)
|
|
const _mul16s = (a,b) => _truncInt16(a * b)
|
|
const _div16s = (a,b) => _truncInt16(Math.trunc(a / b))
|
|
const _shl16s = (a,b) => _truncInt16(a << b)
|
|
const _shr16s = (a,b) => _truncInt16(a >> b)
|
|
|
|
//Int32
|
|
const _truncInt32 = x => x & 0xffffffff
|
|
|
|
const _truncBigInt32 = x => {
|
|
const res = Number(x & 0xffffffffn);
|
|
return res >= 0x80000000 ? res - 0x100000000 : res;
|
|
}
|
|
|
|
const _add32s = (a,b) => _truncInt32(a + b)
|
|
const _sub32s = (a,b) => _truncInt32(a - b)
|
|
const _div32s = (a,b) => _truncInt32(Math.trunc(a / b))
|
|
|
|
const _mul32s = (a,b) => {
|
|
const res = a * b;
|
|
if (res <= Number.MIN_SAFE_INTEGER || res >= Number.MAX_SAFE_INTEGER) {
|
|
return _truncInt32((a & 0xffff) * b + (b & 0xffff) * (a & 0xffff0000))
|
|
} else {
|
|
return _truncInt32(res)
|
|
}
|
|
}
|
|
|
|
//Int64
|
|
const _truncBigInt64 = x => {
|
|
const res = x & 0xffffffffffffffffn;
|
|
return res >= 0x8000000000000000n ? res - 0x10000000000000000n : res;
|
|
}
|
|
|
|
const _add64s = (a,b) => _truncBigInt64(a + b)
|
|
const _sub64s = (a,b) => _truncBigInt64(a - b)
|
|
const _mul64s = (a,b) => _truncBigInt64(a * b)
|
|
const _div64s = (a,b) => _truncBigInt64(a / b)
|
|
const _shl64s = (a,b) => _truncBigInt64(a << b)
|
|
const _shr64s = (a,b) => _truncBigInt64(a >> b)
|
|
|
|
//Bits8
|
|
const _truncUInt8 = x => x & 0xff
|
|
|
|
const _truncUBigInt8 = x => Number(x & 0xffn)
|
|
|
|
const _add8u = (a,b) => (a + b) & 0xff
|
|
const _sub8u = (a,b) => (a - b) & 0xff
|
|
const _mul8u = (a,b) => (a * b) & 0xff
|
|
const _div8u = (a,b) => Math.trunc(a / b)
|
|
const _shl8u = (a,b) => (a << b) & 0xff
|
|
const _shr8u = (a,b) => (a >> b) & 0xff
|
|
|
|
//Bits16
|
|
const _truncUInt16 = x => x & 0xffff
|
|
|
|
const _truncUBigInt16 = x => Number(x & 0xffffn)
|
|
|
|
const _add16u = (a,b) => (a + b) & 0xffff
|
|
const _sub16u = (a,b) => (a - b) & 0xffff
|
|
const _mul16u = (a,b) => (a * b) & 0xffff
|
|
const _div16u = (a,b) => Math.trunc(a / b)
|
|
const _shl16u = (a,b) => (a << b) & 0xffff
|
|
const _shr16u = (a,b) => (a >> b) & 0xffff
|
|
|
|
//Bits32
|
|
const _truncUBigInt32 = x => Number(x & 0xffffffffn)
|
|
|
|
const _truncUInt32 = x => {
|
|
const res = x & -1;
|
|
return res < 0 ? res + 0x100000000 : res;
|
|
}
|
|
|
|
const _add32u = (a,b) => _truncUInt32(a + b)
|
|
const _sub32u = (a,b) => _truncUInt32(a - b)
|
|
const _mul32u = (a,b) => _truncUInt32(_mul32s(a,b))
|
|
const _div32u = (a,b) => Math.trunc(a / b)
|
|
|
|
const _shl32u = (a,b) => _truncUInt32(a << b)
|
|
const _shr32u = (a,b) => _truncUInt32(a <= 0x7fffffff ? a >> b : (b == 0 ? a : (a >> b) ^ ((-0x80000000) >> (b-1))))
|
|
const _and32u = (a,b) => _truncUInt32(a & b)
|
|
const _or32u = (a,b) => _truncUInt32(a | b)
|
|
const _xor32u = (a,b) => _truncUInt32(a ^ b)
|
|
|
|
//Bits64
|
|
const _truncUBigInt64 = x => x & 0xffffffffffffffffn
|
|
|
|
const _add64u = (a,b) => (a + b) & 0xffffffffffffffffn
|
|
const _mul64u = (a,b) => (a * b) & 0xffffffffffffffffn
|
|
const _div64u = (a,b) => a / b
|
|
const _shl64u = (a,b) => (a << b) & 0xffffffffffffffffn
|
|
const _shr64u = (a,b) => (a >> b) & 0xffffffffffffffffn
|
|
const _sub64u = (a,b) => (a - b) & 0xffffffffffffffffn
|
|
|
|
//String
|
|
const _strReverse = x => x.split('').reverse().join('')
|
|
|
|
const _substr = (o,l,x) => x.slice(o, o + l)
|