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 {
|
if args.len > 0 {
|
||||||
g.write(', ')
|
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)')
|
g.write('${it.params[0].name} = new \$ref(this)')
|
||||||
} else {
|
} else {
|
||||||
g.write('${it.params[0].name} = this')
|
g.write('${it.params[0].name} = this')
|
||||||
|
@ -2174,7 +2174,53 @@ fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
|
||||||
g.write(')')
|
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) {
|
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)
|
g.expr(it.expr)
|
||||||
mut ltyp := it.expr_type
|
mut ltyp := it.expr_type
|
||||||
for ltyp.is_ptr() {
|
for ltyp.is_ptr() {
|
||||||
|
|
Loading…
Reference in New Issue