js: math.big support, f{32,64}_bits,from_bits support, typeof(expr).name support (#11260)

pull/11265/head
playX 2021-08-21 17:18:57 +03:00 committed by GitHub
parent 0d81d0c0c6
commit 2f6b2dd189
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 304 additions and 1 deletions

View File

@ -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))
}

View File

@ -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
}

View File

@ -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() {