v.gen.js: add more array tests and fixes (#11014)

pull/10994/head
playX 2021-08-01 14:08:49 +03:00 committed by GitHub
parent 77e9ed417f
commit 836ac54d12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 356 additions and 15 deletions

View File

@ -87,8 +87,21 @@ pub fn (mut a array) sort_with_compare(compare voidptr) {
#a.arr.sort(compare)
}
#function $sortComparator(a, b)
#{
#"use strict";
#a = a.$toJS();
#b = b.$toJS();
#
#if (a > b) return 1;
#if (a < b) return -1;
#return 0;
#
#
#}
pub fn (mut a array) sort() {
#a.arr.sort()
#a.arr.sort($sortComparator)
}
pub fn (a array) index(v string) int {
@ -137,7 +150,7 @@ pub fn (a array) str() string {
#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.map = function(callback) { return new builtin.array(this.arr.map(callback)); }
#array.prototype.filter = function(callback) { return new array(this.arr.filter( function (it) { return (+callback(it)) != 0; } )); }
#Object.defineProperty(array.prototype,'cap',{ get: function () { return this.len; } })
// delete deletes array element at index `i`.

View File

@ -0,0 +1,8 @@
module builtin
pub fn (i int) str() string {
mut res := ''
#res = new builtin.string( i )
return res
}

View File

@ -3,7 +3,7 @@ module builtin
pub struct string {
pub:
str JS.String
len u32
len int
}
pub fn (s string) slice(a int, b int) string {

View File

@ -5,8 +5,13 @@ function vEq(a, b) {
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (a.constructor !== b.constructor) return false;
a = a.$toJS();
b = b.$toJS();
// we want to convert all V types to JS for comparison.
if ('$toJS' in a)
a = a.$toJS();
if ('$toJS' in b)
b = b.$toJS();
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;

View File

@ -619,7 +619,8 @@ fn (mut g JsGen) expr(node ast.Expr) {
g.gen_type_cast_expr(node)
}
ast.CharLiteral {
g.write("'$node.val'")
// todo(playX): char type?
g.write("new builtin.string('$node.val')")
}
ast.Comment {}
ast.ConcatExpr {
@ -1312,8 +1313,9 @@ fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
}
g.writeln('}`')
g.dec_indent()
g.writeln('}')
g.writeln('},')
}
g.writeln('\$toJS() { return this; }')
g.dec_indent()
g.writeln('};\n')
if node.is_pub {

View File

@ -9,8 +9,13 @@ function vEq(a, b) {
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (a.constructor !== b.constructor) return false;
a = a.\$toJS();
b = b.\$toJS();
// we want to convert all V types to JS for comparison.
if ('\$toJS' in a)
a = a.\$toJS();
if ('\$toJS' in b)
b = b.\$toJS();
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;

View File

@ -162,3 +162,70 @@ true
[2,3,4,6,8,9,10]
[4,5,6]
[5,10]
[2,4]
[2,4]
[1,2,3,4,5,6]
["v","is","awesome"]
[0,0,0,0,0,0]
0
[10,20,30,40,50,60]
[1,4,9,16,25,36]
["1","2","3","4","5","6"]
[false,true,false,true,false,true]
["V","IS","AWESOME"]
[false,false,true]
[true,true,false]
[7,7,7]
[1,4,9,16,25,36]
[3,4,5,6,7,8]
[3,9,4,6,12,7]
[]
[true,true,true,true,true,true]
["1a","2a","3a","4a","5a","6a"]
[2,3,4,5,6,7]
[2,3,8]
["1v","2is","3awesome"]
[1,4,9,16,25,36]
[1,25,100]
[1,2,3,4,5,6]
["v","is","awesome"]
[2,3,4]
[2,3,4]
[3,4,5]
[2,3,4]
["1","2","3"]
["1","2","3"]
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
["1","3","5","hi"]
[-3,7,42,67,108]
["a","b","c","d","e","f"]
0
1
79

View File

@ -10,6 +10,23 @@ const (
c_n = 5
)
struct User {
age int
name string
}
fn map_test_helper_1(i int) int {
return i * i
}
fn map_test_helper_2(i int, b string) int {
return i + b.len
}
fn map_test_helper_3(i int, b []string) int {
return i + b.map(it.len)[i % b.len]
}
fn filter_test_helper_1(a int) bool {
return a > 3
}
@ -510,21 +527,245 @@ fn main() {
println([1, 5, 10].filter(filter_test_helper_1))
}
{
// todo(playX): RUNTIME ERROR: Invalid memory access
/*
// test anon fn filter
filter_num := fn (i int) bool {
return i % 2 == 0
}
assert [1, 2, 3, 4, 5].filter(filter_num) == [2, 4]
*/
println([1, 2, 3, 4, 5].filter(filter_num))
}
{
/*
a := [1, 2, 3, 4].filter(fn (i int) bool {
return i % 2 == 0
})
assert a == [2, 4]
println(a)
}
{
// test map
nums := [1, 2, 3, 4, 5, 6]
strs := ['v', 'is', 'awesome']
// assert nums.map() == <error>
// assert nums.map(it, 'excessive') == <error>
// identity
println(nums.map(it))
println(strs.map(it))
println(nums.map(it - it))
println(nums.map(it - it)[0])
// type switch
println(nums.map(it * 10))
println(nums.map(it * it))
println(nums.map('$it'))
println(nums.map(it % 2 == 0))
println(strs.map(it.to_upper()))
println(strs.map(it == 'awesome'))
println(strs.map(it.len in nums))
println(strs.map(int(7)))
// external func
println(nums.map(map_test_helper_1(it)))
println(nums.map(map_test_helper_2(it, 'bb')))
println(nums.map(map_test_helper_3(it, strs)))
// empty array as input
println([]int{len: 0}.map(it * 2))
// nested maps (where it is of same type)
println(nums.map(strs.map(int(7)) == [7, 7, 7]))
println(nums.map('$it' + strs.map('a')[0]))
// assert nums.map(it + strs.map(int(7))[0]) == [8, 9, 10, 11, 12, 13]
println(nums.map(it + strs.map(it.len)[0]))
println(strs.map(it.len + strs.map(it.len)[0]))
// nested (different it types)
// todo(playX): this one produces invalid JS code.
// assert strs.map(it[nums.map(it - it)[0]]) == [byte(`v`), `i`, `a`]
println(nums[0..3].map('$it' + strs.map(it)[it - 1]))
println(nums.map(map_test_helper_1))
println([1, 5, 10].map(map_test_helper_1))
println(nums)
println(strs)
}
{
// test anon fn map
add_num := fn (i int) int {
return i + 1
}
println([1, 2, 3].map(add_num))
}
{
// test multi anon fn map
a := [1, 2, 3].map(fn (i int) int {
return i + 1
})
b := [1, 2, 3].map(fn (i int) int {
return i + 2
})
println(a)
println(b)
}
{
// test anon fn arg map
a := [1, 2, 3].map(fn (i int) int {
return i + 1
})
println(a)
}
{
// test anon fn arg different type map
i_to_str := fn (i int) string {
return i.str()
}
a := [1, 2, 3].map(i_to_str)
println(a)
}
{
// test anon fn inline different type map
a := [1, 2, 3].map(fn (i int) string {
return i.str()
})
println(a)
}
{
// test array str
// todo(playX): JS array formatting should match what default builtin impl has.
/*
numbers := [1, 2, 3]
assert numbers == [1, 2, 3]
numbers2 := [numbers, [4, 5, 6]] // dup str() bug
println(numbers2)
assert true
assert numbers.str() == '[1, 2, 3]'
*/
}
{
// test eq
println([5, 6, 7] != [6, 7])
println([`a`, `b`] == [`a`, `b`])
println([User{
age: 22
name: 'bob'
}] == [User{
age: 22
name: 'bob'
}])
// todo(playX): map cmp does not work yet
/*
assert [map{
'bob': 22
}, map{
'tom': 33
}] == [map{
'bob': 22
}, map{
'tom': 33
}]*/
println([[1, 2, 3], [4]] == [[1, 2, 3], [4]])
}
{
// test fixed array eq
a1 := [1, 2, 3]!
println(a1 == [1, 2, 3]!)
println(a1 != [2, 3, 4]!)
a2 := [[1, 2]!, [3, 4]!]!
println(a2 == [[1, 2]!, [3, 4]!]!)
println(a2 != [[3, 4]!, [1, 2]!]!)
a3 := [[1, 2], [3, 4]]!
println(a3 == [[1, 2], [3, 4]]!)
println(a3 != [[1, 1], [2, 2]]!)
a4 := [[`a`, `b`], [`c`, `d`]]!
println(a4 == [[`a`, `b`], [`c`, `d`]]!)
println(a4 != [[`c`, `a`], [`a`, `b`]]!)
a5 := [['aaa', 'bbb'], ['ccc', 'ddd']]!
println(a5 == [['aaa', 'bbb'], ['ccc', 'ddd']]!)
println(a5 != [['abc', 'def'], ['ccc', 'ddd']]!)
a6 := [['aaa', 'bbb']!, ['ccc', 'ddd']!]!
println(a6 == [['aaa', 'bbb']!, ['ccc', 'ddd']!]!)
println(a6 != [['aaa', 'bbb']!, ['aaa', 'ddd']!]!)
a7 := [[1, 2]!, [3, 4]!]
println(a7 == [[1, 2]!, [3, 4]!])
println(a7 != [[2, 3]!, [1, 2]!])
a8 := [['aaa', 'bbb']!, ['ccc', 'ddd']!]
println(a8 == [['aaa', 'bbb']!, ['ccc', 'ddd']!])
println(a8 != [['bbb', 'aaa']!, ['cccc', 'dddd']!])
}
{
// test fixed array literal eq
println([1, 2, 3]! == [1, 2, 3]!)
println([1, 1, 1]! != [1, 2, 3]!)
println([[1, 2], [3, 4]]! == [[1, 2], [3, 4]]!)
println([[1, 1], [2, 2]]! != [[1, 2], [3, 4]]!)
println([[1, 1]!, [2, 2]!]! == [[1, 1]!, [2, 2]!]!)
println([[1, 1]!, [2, 2]!]! != [[1, 2]!, [2, 3]!]!)
println([[1, 1]!, [2, 2]!] == [[1, 1]!, [2, 2]!])
println([[1, 1]!, [2, 2]!] != [[1, 2]!, [2, 3]!])
}
{
// test sort
mut a := ['hi', '1', '5', '3']
a.sort()
println(a)
mut nums := [67, -3, 108, 42, 7]
nums.sort()
println(nums)
assert nums[0] == -3
assert nums[1] == 7
assert nums[2] == 42
assert nums[3] == 67
assert nums[4] == 108
// todo(playX): add codegen for comparator fn passed
/*
nums.sort(a < b)
assert nums[0] == -3
assert nums[1] == 7
assert nums[2] == 42
assert nums[3] == 67
assert nums[4] == 108
mut users := [User{22, 'Peter'}, User{20, 'Bob'}, User{25, 'Alice'}]
users.sort(a.age < b.age)
assert users[0].age == 20
assert users[1].age == 22
assert users[2].age == 25
assert users[0].name == 'Bob'
assert users[1].name == 'Peter'
assert users[2].name == 'Alice'
users.sort(a.age > b.age)
assert users[0].age == 25
assert users[1].age == 22
assert users[2].age == 20
users.sort(a.name < b.name) // Test sorting by string fields
*/
}
{
// test rune sort
mut bs := [`f`, `e`, `d`, `b`, `c`, `a`]
bs.sort()
println(bs)
/*
bs.sort(a > b)
println(bs)
assert '$bs' == '[`f`, `e`, `d`, `c`, `b`, `a`]'
bs.sort(a < b)
println(bs)
assert '$bs' == '[`a`, `b`, `c`, `d`, `e`, `f`]'
*/
}
{
// test f32 sort
mut f := [f32(50.0), 15, 1, 79, 38, 0, 27]
f.sort()
println(f[0])
println(f[1])
println(f[6])
}
}