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
|
arr JS.Array
|
||||||
pub:
|
pub:
|
||||||
len int
|
len int
|
||||||
|
cap int
|
||||||
}
|
}
|
||||||
|
|
||||||
#function flatIntoArray(target, source, sourceLength, targetIndex, depth) {
|
#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
|
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 {
|
fn (a array) get(ix int) voidptr {
|
||||||
mut result := voidptr(0)
|
mut result := voidptr(0)
|
||||||
#result = a.arr[ix]
|
#result = a.arr[ix]
|
||||||
|
@ -104,6 +113,10 @@ pub fn (mut a array) insert(i int, val voidptr) {
|
||||||
#a.arr.splice(i,0,val)
|
#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 {
|
pub fn (mut a array) join(separator string) string {
|
||||||
mut res := ''
|
mut res := ''
|
||||||
#res = new builtin.string(a.arr.join(separator +''));
|
#res = new builtin.string(a.arr.join(separator +''));
|
||||||
|
@ -115,7 +128,24 @@ fn (a array) push(val voidptr) {
|
||||||
#a.arr.push(val)
|
#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[Symbol.iterator] = function () { return this.arr[Symbol.iterator](); }
|
||||||
#array.prototype.entries = function () { return this.arr.entries(); }
|
#array.prototype.entries = function () { return this.arr.entries(); }
|
||||||
#array.prototype.map = function(callback) { return this.arr.map(callback); }
|
#array.prototype.map = function(callback) { return this.arr.map(callback); }
|
||||||
#array.prototype.filter = function(callback) { return this.arr.filter(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_ {
|
.struct_ {
|
||||||
styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})'
|
styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})'
|
||||||
}
|
}
|
||||||
|
.voidptr {
|
||||||
|
styp = 'null'
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// TODO
|
// TODO
|
||||||
styp = 'undefined'
|
styp = 'undefined'
|
||||||
|
@ -100,6 +103,9 @@ fn (mut g JsGen) sym_to_js_typ(sym ast.TypeSymbol) string {
|
||||||
.array {
|
.array {
|
||||||
styp = 'array'
|
styp = 'array'
|
||||||
}
|
}
|
||||||
|
.voidptr {
|
||||||
|
styp = 'any'
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// TODO
|
// TODO
|
||||||
styp = 'undefined'
|
styp = 'undefined'
|
||||||
|
@ -358,6 +364,17 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
||||||
eq: 'vEq(this, other)'
|
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 {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ function vEq(a, b) {
|
||||||
|
|
||||||
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
||||||
if (a.constructor !== b.constructor) return false;
|
if (a.constructor !== b.constructor) return false;
|
||||||
|
a = a.valueOf();
|
||||||
|
b = b.valueOf();
|
||||||
var length, i, keys;
|
var length, i, keys;
|
||||||
if (Array.isArray(a)) {
|
if (Array.isArray(a)) {
|
||||||
length = a.length;
|
length = a.length;
|
||||||
|
@ -62,5 +63,5 @@ function vEq(a, b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// true if both NaN, false otherwise
|
// true if both NaN, false otherwise
|
||||||
return a!==a && b!==b;
|
return a !== a && b !== b;
|
||||||
};
|
};
|
|
@ -25,7 +25,7 @@ const (
|
||||||
'Array', 'Map']
|
'Array', 'Map']
|
||||||
// used to generate type structs
|
// used to generate type structs
|
||||||
v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64',
|
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,
|
shallow_equatables = [ast.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64,
|
||||||
.int_literal, .float_literal, .size_t, .bool, .string]
|
.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] {
|
if node.op in [.amp, .mul] {
|
||||||
// C pointers/references: ignore them
|
// C pointers/references: ignore them
|
||||||
if node.op == .amp {
|
if node.op == .amp {
|
||||||
type_sym := g.table.get_type_symbol(node.right_type)
|
if !node.right_type.is_pointer() {
|
||||||
|
|
||||||
if !type_sym.is_primitive() && !node.right_type.is_pointer() {
|
|
||||||
// kind of weird way to handle references but it allows us to access type methods easily.
|
// kind of weird way to handle references but it allows us to access type methods easily.
|
||||||
g.write('(function(x) {')
|
g.write('(function(x) {')
|
||||||
g.write(' return { val: x, __proto__: Object.getPrototypeOf(x), valueOf: function() { return this.val; } }})( ')
|
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 {
|
} else {
|
||||||
g.write('(')
|
g.write('(')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(').val')
|
g.write(').valueOf()')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.write(node.op.str())
|
g.write(node.op.str())
|
||||||
|
g.write('(')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write('.valueOf()')
|
g.write('.valueOf()')
|
||||||
|
g.write(')')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.RangeExpr {
|
ast.RangeExpr {
|
||||||
|
@ -1103,7 +1103,7 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
||||||
g.expr(it.cond)
|
g.expr(it.cond)
|
||||||
g.write('; $i < ')
|
g.write('; $i < ')
|
||||||
g.expr(it.high)
|
g.expr(it.high)
|
||||||
g.writeln('; ++$i) {')
|
g.writeln('; $i = new builtin.int($i + 1)) {')
|
||||||
g.inside_loop = false
|
g.inside_loop = false
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
|
@ -1379,6 +1379,7 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
||||||
g.write('return builtin.unwrap(')
|
g.write('return builtin.unwrap(')
|
||||||
}
|
}
|
||||||
g.expr(it.left)
|
g.expr(it.left)
|
||||||
|
|
||||||
if it.is_method { // foo.bar.baz()
|
if it.is_method { // foo.bar.baz()
|
||||||
sym := g.table.get_type_symbol(it.receiver_type)
|
sym := g.table.get_type_symbol(it.receiver_type)
|
||||||
g.write('.')
|
g.write('.')
|
||||||
|
@ -1410,11 +1411,42 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
|
|
||||||
g.write('it => ')
|
g.write('it => ')
|
||||||
g.expr(node.args[0].expr)
|
g.expr(node.args[0].expr)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
return
|
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 {
|
} else {
|
||||||
if name in g.builtin_fns {
|
if name in g.builtin_fns {
|
||||||
g.write('builtin.')
|
g.write('builtin.')
|
||||||
|
@ -1647,8 +1679,9 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||||
g.write('Array.prototype.push.call(')
|
g.write('Array.prototype.push.call(')
|
||||||
g.expr(it.left)
|
g.expr(it.left)
|
||||||
g.write('.arr,')
|
g.write('.arr,')
|
||||||
|
array_info := l_sym.info as ast.Array
|
||||||
// arr << [1, 2]
|
// arr << [1, 2]
|
||||||
if r_sym.kind == .array {
|
if r_sym.kind == .array && array_info.elem_type != it.right_type {
|
||||||
g.write('...')
|
g.write('...')
|
||||||
}
|
}
|
||||||
g.expr(it.right)
|
g.expr(it.right)
|
||||||
|
|
|
@ -9,7 +9,8 @@ function vEq(a, b) {
|
||||||
|
|
||||||
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
||||||
if (a.constructor !== b.constructor) return false;
|
if (a.constructor !== b.constructor) return false;
|
||||||
|
a = a.valueOf();
|
||||||
|
b = b.valueOf();
|
||||||
var length, i, keys;
|
var length, i, keys;
|
||||||
if (Array.isArray(a)) {
|
if (Array.isArray(a)) {
|
||||||
length = a.length;
|
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