js: math.big support, f{32,64}_bits,from_bits support, typeof(expr).name support (#11260)
parent
0d81d0c0c6
commit
2f6b2dd189
|
@ -0,0 +1,198 @@
|
|||
module big
|
||||
|
||||
struct JS.BigInt {}
|
||||
|
||||
#const jsNumber = Number;
|
||||
|
||||
pub struct Number {
|
||||
}
|
||||
|
||||
pub fn new() Number {
|
||||
return Number{}
|
||||
}
|
||||
|
||||
pub fn from_int(i int) Number {
|
||||
n := Number{}
|
||||
#n.value = BigInt(+i)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
pub fn from_u64(u u64) Number {
|
||||
n := Number{}
|
||||
#n.value = BigInt(u.val)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
pub fn from_hex_string(input string) Number {
|
||||
n := Number{}
|
||||
#n.value = BigInt(input.val)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
pub fn from_string(input string) Number {
|
||||
n := Number{}
|
||||
#n.value = BigInt(input.val)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
pub fn (n &Number) int() int {
|
||||
r := 0
|
||||
#r.val = jsNumber(n.val.value)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
pub fn (n &Number) str() string {
|
||||
s := ''
|
||||
#s.str = n.val.value + ""
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (a &Number) + (b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value + b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn (a &Number) - (b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value - b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn (a &Number) / (b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value / b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn (a &Number) * (b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value * b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (a &Number) % (b &Number) Number {
|
||||
c := Number{}
|
||||
# c.value = a.val.value % b.val.value
|
||||
return c
|
||||
}*/
|
||||
|
||||
pub fn divmod(a &Number, b &Number) (Number, Number) {
|
||||
c := Number{}
|
||||
d := Number{}
|
||||
#c.value = a.val.value / b.val.value
|
||||
#d.value = a.val.value % b.val.value
|
||||
|
||||
return c, d
|
||||
}
|
||||
|
||||
pub fn cmp(a &Number, b &Number) int {
|
||||
res := 0
|
||||
|
||||
#if (a.val.value < b.val.value) res.val = -1
|
||||
#else if (a.val.value > b.val.value) res.val = 1
|
||||
#else res.val = 0
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (a &Number) is_zero() bool {
|
||||
res := false
|
||||
#res.val = a.val.value == BigInt(0)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (mut a Number) inc() {
|
||||
#a.val.value = a.val.value + BigInt(1)
|
||||
}
|
||||
|
||||
pub fn (mut a Number) dec() {
|
||||
#a.val.value = a.val.value - BigInt(1)
|
||||
}
|
||||
|
||||
pub fn (a &Number) isqrt() Number {
|
||||
b := Number{}
|
||||
#let x0 = a.val.value >> 1n
|
||||
#if (x0) {
|
||||
#let x1 = (x0 + a.val.value / x0) >> 1n
|
||||
#while (x1 < x0) {
|
||||
#x0 = x1
|
||||
#x1 = (x0 + a.val.value / x0) >> 1n
|
||||
#}
|
||||
#b.value = x0
|
||||
#} else { b.value = a.val.value; }
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
pub fn b_and(a &Number, b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value & b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn b_or(a &Number, b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value | b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn b_xor(a &Number, b &Number) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value ^ b.val.value
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn (a &Number) lshift(nbits int) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value << BigInt(+nbits)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn (a &Number) rshift(nbits int) Number {
|
||||
c := Number{}
|
||||
#c.value = a.val.value << BigInt(+nbits)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
pub fn (a &Number) clone() Number {
|
||||
b := Number{}
|
||||
#b.value = a.val.value
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
pub fn factorial(nn &Number) Number {
|
||||
mut n := nn.clone()
|
||||
mut a := nn.clone()
|
||||
n.dec()
|
||||
mut i := 1
|
||||
for !n.is_zero() {
|
||||
res := a * n
|
||||
n.dec()
|
||||
a = res
|
||||
i++
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
pub fn fact(n int) Number {
|
||||
return factorial(from_int(n))
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
module math
|
||||
|
||||
// f32_bits returns the IEEE 754 binary representation of f,
|
||||
// with the sign bit of f and the result in the same bit position.
|
||||
// f32_bits(f32_from_bits(x)) == x.
|
||||
pub fn f32_bits(f f32) u32 {
|
||||
p := u32(0)
|
||||
#let buffer = new ArrayBuffer(4)
|
||||
#let floatArr = new Float32Array(buffer)
|
||||
#floatArr[0] = f.val
|
||||
#let uintArr = new Uint32Array(buffer)
|
||||
#p.val = uintArr[0]
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// f32_from_bits returns the floating-point number corresponding
|
||||
// to the IEEE 754 binary representation b, with the sign bit of b
|
||||
// and the result in the same bit position.
|
||||
// f32_from_bits(f32_bits(x)) == x.
|
||||
pub fn f32_from_bits(b u32) f32 {
|
||||
p := f32(0.0)
|
||||
#let buffer = new ArrayBuffer(4)
|
||||
#let floatArr = new Float32Array(buffer)
|
||||
#let uintArr = new Uint32Array(buffer)
|
||||
#uintArr[0] = Number(b.val)
|
||||
#p.val = floatArr[0]
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// f64_bits returns the IEEE 754 binary representation of f,
|
||||
// with the sign bit of f and the result in the same bit position,
|
||||
// and f64_bits(f64_from_bits(x)) == x.
|
||||
pub fn f64_bits(f f64) u64 {
|
||||
p := u64(0)
|
||||
#let buffer = new ArrayBuffer(8)
|
||||
#let floatArr = new Float64Array(buffer)
|
||||
#floatArr[0] = f.val
|
||||
#let uintArr = new BigUint64Array(buffer)
|
||||
#p.val = uintArr[0]
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// f64_from_bits returns the floating-point number corresponding
|
||||
// to the IEEE 754 binary representation b, with the sign bit of b
|
||||
// and the result in the same bit position.
|
||||
// f64_from_bits(f64_bits(x)) == x.
|
||||
pub fn f64_from_bits(b u64) f64 {
|
||||
p := 0.0
|
||||
#let buffer = new ArrayBuffer(8)
|
||||
#let floatArr = new Float64Array(buffer)
|
||||
#let uintArr = new BigUint64Array(buffer)
|
||||
#uintArr[0] = Number(b.val)
|
||||
#p.val = floatArr[0]
|
||||
|
||||
return p
|
||||
}
|
|
@ -1149,7 +1149,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
|
|||
if args.len > 0 {
|
||||
g.write(', ')
|
||||
}
|
||||
if it.params[0].is_mut {
|
||||
if it.params[0].is_mut || it.params[0].typ.is_ptr() {
|
||||
g.write('${it.params[0].name} = new \$ref(this)')
|
||||
} else {
|
||||
g.write('${it.params[0].name} = this')
|
||||
|
@ -2174,7 +2174,53 @@ fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
|
|||
g.write(')')
|
||||
}
|
||||
|
||||
fn (mut g JsGen) type_name(raw_type ast.Type) {
|
||||
typ := raw_type
|
||||
sym := g.table.get_type_symbol(typ)
|
||||
mut s := ''
|
||||
if sym.kind == .function {
|
||||
// todo: properly print function signatures
|
||||
if typ.is_ptr() {
|
||||
s = '&function'
|
||||
} else {
|
||||
s = 'function'
|
||||
}
|
||||
} else {
|
||||
s = g.table.type_to_str(g.unwrap_generic(typ))
|
||||
}
|
||||
g.write('new builtin.string("$s")')
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
|
||||
if it.name_type > 0 {
|
||||
node := it
|
||||
match node.gkind_field {
|
||||
.name {
|
||||
g.type_name(it.name_type)
|
||||
return
|
||||
}
|
||||
.typ {
|
||||
g.write('new builtin.int(')
|
||||
|
||||
g.write('${int(g.unwrap_generic(it.name_type))}')
|
||||
g.write(')')
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
.unknown {
|
||||
if node.field_name == 'name' {
|
||||
g.type_name(it.name_type)
|
||||
return
|
||||
} else if node.field_name == 'idx' {
|
||||
g.write('new builtin.int(')
|
||||
g.write('${int(g.unwrap_generic(it.name_type))}')
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
panic('unknown generic field $it.pos')
|
||||
}
|
||||
}
|
||||
}
|
||||
g.expr(it.expr)
|
||||
mut ltyp := it.expr_type
|
||||
for ltyp.is_ptr() {
|
||||
|
|
Loading…
Reference in New Issue