js: add more tests for array, support array insert_many, minor fixes for references (#10983)
parent
66bc8bc0cb
commit
e3cf95b058
|
@ -4,6 +4,7 @@ struct array {
|
|||
arr JS.Array
|
||||
pub:
|
||||
len int
|
||||
cap int
|
||||
}
|
||||
|
||||
#function flatIntoArray(target, source, sourceLength, targetIndex, depth) {
|
||||
|
@ -50,6 +51,14 @@ pub fn (a array) repeat_to_depth(count int, depth int) array {
|
|||
return arr
|
||||
}
|
||||
|
||||
// last returns the last element of the array.
|
||||
pub fn (a array) last() voidptr {
|
||||
mut res := voidptr(0)
|
||||
#res = a.arr[a.len-1];
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
fn (a array) get(ix int) voidptr {
|
||||
mut result := voidptr(0)
|
||||
#result = a.arr[ix]
|
||||
|
@ -104,6 +113,10 @@ pub fn (mut a array) insert(i int, val voidptr) {
|
|||
#a.arr.splice(i,0,val)
|
||||
}
|
||||
|
||||
pub fn (mut a array) insert_many(i int, val voidptr, size int) {
|
||||
#a.arr.splice(i,0,...val.slice(0,+size))
|
||||
}
|
||||
|
||||
pub fn (mut a array) join(separator string) string {
|
||||
mut res := ''
|
||||
#res = new builtin.string(a.arr.join(separator +''));
|
||||
|
@ -115,7 +128,24 @@ fn (a array) push(val voidptr) {
|
|||
#a.arr.push(val)
|
||||
}
|
||||
|
||||
pub fn (a array) str() string {
|
||||
mut res := ''
|
||||
#res = new builtin.string(a + '')
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
#array.prototype[Symbol.iterator] = function () { return this.arr[Symbol.iterator](); }
|
||||
#array.prototype.entries = function () { return this.arr.entries(); }
|
||||
#array.prototype.map = function(callback) { return this.arr.map(callback); }
|
||||
#array.prototype.filter = function(callback) { return this.arr.filter(callback); }
|
||||
#Object.defineProperty(array.prototype,'cap',{ get: function () { return this.len; } })
|
||||
// delete deletes array element at index `i`.
|
||||
pub fn (mut a array) delete(i int) {
|
||||
a.delete_many(i, 1)
|
||||
}
|
||||
|
||||
// delete_many deletes `size` elements beginning with index `i`
|
||||
pub fn (mut a array) delete_many(i int, size int) {
|
||||
#a.arr.splice(i.valueOf(),size.valueOf())
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
|
|||
.struct_ {
|
||||
styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})'
|
||||
}
|
||||
.voidptr {
|
||||
styp = 'null'
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
styp = 'undefined'
|
||||
|
@ -100,6 +103,9 @@ fn (mut g JsGen) sym_to_js_typ(sym ast.TypeSymbol) string {
|
|||
.array {
|
||||
styp = 'array'
|
||||
}
|
||||
.voidptr {
|
||||
styp = 'any'
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
styp = 'undefined'
|
||||
|
@ -358,6 +364,17 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
|||
eq: 'vEq(this, other)'
|
||||
)
|
||||
}
|
||||
'any' {
|
||||
g.gen_builtin_prototype(
|
||||
typ_name: typ_name
|
||||
val_name: 'any'
|
||||
default_value: 'null'
|
||||
constructor: 'this.val = any'
|
||||
value_of: 'this.val'
|
||||
to_string: '"&" + this.val'
|
||||
eq: 'this == other' // compare by ptr
|
||||
)
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@ function vEq(a, b) {
|
|||
|
||||
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
||||
if (a.constructor !== b.constructor) return false;
|
||||
|
||||
a = a.valueOf();
|
||||
b = b.valueOf();
|
||||
var length, i, keys;
|
||||
if (Array.isArray(a)) {
|
||||
length = a.length;
|
||||
|
@ -62,5 +63,5 @@ function vEq(a, b) {
|
|||
}
|
||||
|
||||
// true if both NaN, false otherwise
|
||||
return a!==a && b!==b;
|
||||
return a !== a && b !== b;
|
||||
};
|
|
@ -25,7 +25,7 @@ const (
|
|||
'Array', 'Map']
|
||||
// used to generate type structs
|
||||
v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64',
|
||||
'int_literal', 'float_literal', 'size_t', 'bool', 'string', 'map', 'array']
|
||||
'int_literal', 'float_literal', 'size_t', 'bool', 'string', 'map', 'array', 'any']
|
||||
shallow_equatables = [ast.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64,
|
||||
.int_literal, .float_literal, .size_t, .bool, .string]
|
||||
)
|
||||
|
@ -682,9 +682,7 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
|||
if node.op in [.amp, .mul] {
|
||||
// C pointers/references: ignore them
|
||||
if node.op == .amp {
|
||||
type_sym := g.table.get_type_symbol(node.right_type)
|
||||
|
||||
if !type_sym.is_primitive() && !node.right_type.is_pointer() {
|
||||
if !node.right_type.is_pointer() {
|
||||
// kind of weird way to handle references but it allows us to access type methods easily.
|
||||
g.write('(function(x) {')
|
||||
g.write(' return { val: x, __proto__: Object.getPrototypeOf(x), valueOf: function() { return this.val; } }})( ')
|
||||
|
@ -696,12 +694,14 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
|||
} else {
|
||||
g.write('(')
|
||||
g.expr(node.right)
|
||||
g.write(').val')
|
||||
g.write(').valueOf()')
|
||||
}
|
||||
} else {
|
||||
g.write(node.op.str())
|
||||
g.write('(')
|
||||
g.expr(node.right)
|
||||
g.write('.valueOf()')
|
||||
g.write(')')
|
||||
}
|
||||
}
|
||||
ast.RangeExpr {
|
||||
|
@ -1103,7 +1103,7 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
|||
g.expr(it.cond)
|
||||
g.write('; $i < ')
|
||||
g.expr(it.high)
|
||||
g.writeln('; ++$i) {')
|
||||
g.writeln('; $i = new builtin.int($i + 1)) {')
|
||||
g.inside_loop = false
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
|
@ -1379,6 +1379,7 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
|||
g.write('return builtin.unwrap(')
|
||||
}
|
||||
g.expr(it.left)
|
||||
|
||||
if it.is_method { // foo.bar.baz()
|
||||
sym := g.table.get_type_symbol(it.receiver_type)
|
||||
g.write('.')
|
||||
|
@ -1410,11 +1411,42 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
|||
}
|
||||
else {}
|
||||
}
|
||||
|
||||
g.write('it => ')
|
||||
g.expr(node.args[0].expr)
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
|
||||
left_sym := g.table.get_type_symbol(it.left_type)
|
||||
if left_sym.kind == .array {
|
||||
node := it
|
||||
match node.name {
|
||||
'insert' {
|
||||
arg2_sym := g.table.get_type_symbol(node.args[1].typ)
|
||||
is_arg2_array := arg2_sym.kind == .array && node.args[1].typ == node.left_type
|
||||
if is_arg2_array {
|
||||
g.write('insert_many(')
|
||||
} else {
|
||||
g.write('insert(')
|
||||
}
|
||||
|
||||
g.expr(node.args[0].expr)
|
||||
g.write(',')
|
||||
if is_arg2_array {
|
||||
g.expr(node.args[1].expr)
|
||||
g.write('.arr,')
|
||||
g.expr(node.args[1].expr)
|
||||
g.write('.len')
|
||||
} else {
|
||||
g.expr(node.args[1].expr)
|
||||
}
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if name in g.builtin_fns {
|
||||
g.write('builtin.')
|
||||
|
@ -1647,8 +1679,9 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
g.write('Array.prototype.push.call(')
|
||||
g.expr(it.left)
|
||||
g.write('.arr,')
|
||||
array_info := l_sym.info as ast.Array
|
||||
// arr << [1, 2]
|
||||
if r_sym.kind == .array {
|
||||
if r_sym.kind == .array && array_info.elem_type != it.right_type {
|
||||
g.write('...')
|
||||
}
|
||||
g.expr(it.right)
|
||||
|
|
|
@ -9,7 +9,8 @@ function vEq(a, b) {
|
|||
|
||||
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
||||
if (a.constructor !== b.constructor) return false;
|
||||
|
||||
a = a.valueOf();
|
||||
b = b.valueOf();
|
||||
var length, i, keys;
|
||||
if (Array.isArray(a)) {
|
||||
length = a.length;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
3
|
||||
1
|
||||
2
|
||||
4
|
||||
255
|
||||
256
|
||||
2
|
||||
4
|
||||
131
|
||||
4
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
4
|
||||
4
|
||||
[1,5,2,3,4]
|
||||
5
|
||||
4
|
||||
5
|
||||
[1,5,2,3,4]
|
||||
[5,2,3,4]
|
||||
4
|
||||
[5,3,4]
|
||||
3
|
||||
[5,3]
|
||||
2
|
||||
[2.5,3.25,4.5,5.75]
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
1
|
||||
2
|
||||
3
|
||||
10000
|
||||
234
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
3
|
||||
[1,3]
|
||||
3
|
||||
2
|
||||
3
|
||||
4
|
||||
1
|
||||
4
|
||||
5
|
||||
2
|
||||
5
|
||||
0
|
||||
1
|
||||
1.1
|
||||
[1,2,3,4]
|
||||
[1,5,6,2,3,4]
|
|
@ -0,0 +1,186 @@
|
|||
struct Chunk {
|
||||
val string
|
||||
}
|
||||
|
||||
struct Kkk {
|
||||
q []Chunk
|
||||
}
|
||||
|
||||
fn main() {
|
||||
{
|
||||
// test pointer
|
||||
mut arr := []&int{}
|
||||
a := 1
|
||||
b := 2
|
||||
c := 3
|
||||
arr << &a
|
||||
arr << &b
|
||||
arr << &c
|
||||
assert *arr[0] == 1
|
||||
arr[1] = &c
|
||||
assert *arr[1] == 3
|
||||
mut d_arr := [arr] // [][]&int
|
||||
d_arr << arr
|
||||
println(*d_arr[0][1]) // 3
|
||||
println(*d_arr[1][0]) // 1
|
||||
}
|
||||
{
|
||||
// test assign
|
||||
mut arr := [2, 4, 8, 16, 32, 64, 128]
|
||||
arr[0] = 2
|
||||
arr[1] &= 255
|
||||
arr[2] |= 255
|
||||
arr[3] <<= 4
|
||||
arr[4] >>= 4
|
||||
arr[5] %= 5
|
||||
arr[6] ^= 3
|
||||
println(arr[0])
|
||||
println(arr[1])
|
||||
println(arr[2])
|
||||
println(arr[3])
|
||||
println(arr[4])
|
||||
println(arr[5])
|
||||
println(arr[6])
|
||||
}
|
||||
{
|
||||
// test ints
|
||||
mut a := [1, 5, 2, 3]
|
||||
println(a.len) // 4
|
||||
println(a[0])
|
||||
println(a[2])
|
||||
println(a.last())
|
||||
|
||||
a << 4
|
||||
println(a.len)
|
||||
println(a[4])
|
||||
println(a.last())
|
||||
|
||||
s := a.str()
|
||||
println(s)
|
||||
println(a[1])
|
||||
println(a.last())
|
||||
}
|
||||
{
|
||||
// test deleting
|
||||
mut a := [1, 5, 2, 3, 4]
|
||||
|
||||
println(a.len)
|
||||
println(a.str())
|
||||
|
||||
a.delete(0)
|
||||
|
||||
println(a.str())
|
||||
println(a.len) // 4
|
||||
|
||||
a.delete(1)
|
||||
|
||||
println(a.str())
|
||||
println(a.len)
|
||||
a.delete(a.len - 1)
|
||||
|
||||
println(a.str())
|
||||
println(a.len)
|
||||
}
|
||||
{
|
||||
// test slice delete
|
||||
mut a := [1.5, 2.5, 3.25, 4.5, 5.75]
|
||||
b := a[2..4]
|
||||
a.delete(0)
|
||||
// assert a == [2.5, 3.25, 4.5, 5.75]
|
||||
// assert b == [3.25, 4.5]
|
||||
println(a)
|
||||
println(a == [2.5, 3.25, 4.5, 5.75])
|
||||
println(b == [3.25, 4.5])
|
||||
a = [3.75, 4.25, -1.5, 2.25, 6.0]
|
||||
c := a[..3]
|
||||
a.delete(2)
|
||||
println(a == [3.75, 4.25, 2.25, 6.0])
|
||||
println(c == [3.75, 4.25, -1.5])
|
||||
}
|
||||
{
|
||||
// test delete many
|
||||
mut a := [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
b := a[2..6]
|
||||
a.delete_many(4, 3)
|
||||
println(a == [1, 2, 3, 4, 8, 9])
|
||||
println(b == [3, 4, 5, 6])
|
||||
|
||||
c := a[..a.len]
|
||||
a.delete_many(2, 0) // this should just clone
|
||||
a[1] = 17
|
||||
|
||||
println(a == [1, 17, 3, 4, 8, 9])
|
||||
println(c == [1, 2, 3, 4, 8, 9])
|
||||
a.delete_many(0, a.len)
|
||||
println(a == []int{})
|
||||
}
|
||||
{
|
||||
// test short
|
||||
a := [1, 2, 3]
|
||||
println(a.len == 3)
|
||||
println(a.cap == 3)
|
||||
println(a[0])
|
||||
println(a[1])
|
||||
println(a[2])
|
||||
}
|
||||
{
|
||||
// test large
|
||||
mut a := [0].repeat(0)
|
||||
for i in 0 .. 10000 {
|
||||
a << i
|
||||
}
|
||||
println(a.len)
|
||||
println(a[234])
|
||||
}
|
||||
{
|
||||
// test empty
|
||||
mut chunks := []Chunk{}
|
||||
a := Chunk{}
|
||||
println(chunks.len)
|
||||
chunks << a
|
||||
println(chunks.len)
|
||||
chunks = []
|
||||
println(chunks.len)
|
||||
chunks << a
|
||||
println(chunks.len)
|
||||
}
|
||||
{
|
||||
// test push
|
||||
mut a := []int{}
|
||||
a << 1
|
||||
a << 3
|
||||
println(a[1])
|
||||
println(a.str())
|
||||
}
|
||||
{
|
||||
// test insert
|
||||
mut a := [1, 2]
|
||||
a.insert(0, 3)
|
||||
println(a[0])
|
||||
println(a[2])
|
||||
println(a.len)
|
||||
a.insert(1, 4)
|
||||
println(a[1])
|
||||
println(a[2])
|
||||
println(a.len)
|
||||
a.insert(4, 5)
|
||||
println(a[4])
|
||||
println(a[3])
|
||||
println(a.len)
|
||||
mut b := []f64{}
|
||||
println(b.len)
|
||||
b.insert(0, f64(1.1))
|
||||
println(b.len)
|
||||
println(b[0])
|
||||
}
|
||||
{
|
||||
// test insert many
|
||||
mut a := [3, 4]
|
||||
a.insert(0, [1, 2])
|
||||
println(a)
|
||||
|
||||
b := [5, 6]
|
||||
a.insert(1, b)
|
||||
println(a)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue