v.gen.js: port fully the array test suite & add fixes (#11073)
parent
c560d58f1e
commit
94c321c80d
|
@ -14,3 +14,13 @@ pub fn (mut m map) delete(key voidptr) {
|
|||
pub fn (m &map) free() {}
|
||||
|
||||
#map.prototype[Symbol.iterator] = function () { return this.map[Symbol.iterator](); }
|
||||
|
||||
#map.prototype.toString = function () {
|
||||
#function fmtKey(key) { return typeof key == 'string' ? '\'' + key + '\'' : key}
|
||||
#let res = '{'
|
||||
#for (const entry of this) {
|
||||
#res += fmtKey(entry[0]) + ': ' + entry[0];
|
||||
#}
|
||||
#res += '}'
|
||||
#return res;
|
||||
#}
|
||||
|
|
|
@ -94,7 +94,10 @@ pub fn (s string) count(substr string) int {
|
|||
}
|
||||
|
||||
pub fn (s string) ends_with(p string) bool {
|
||||
return s.str.endsWith(p.str)
|
||||
mut res := false
|
||||
#res.val = s.str.endsWith(p.str)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (s string) starts_with(p string) bool {
|
||||
|
@ -133,7 +136,7 @@ pub fn (s string) fields() []string {
|
|||
}
|
||||
|
||||
pub fn (s string) find_between(start string, end string) string {
|
||||
return string(s.str.slice(s.str.indexOf(start.str), s.str.indexOf(end.str) + 1))
|
||||
return string(s.str.slice(s.str.indexOf(start.str) + 1, s.str.indexOf(end.str)))
|
||||
}
|
||||
|
||||
// unnecessary in the JS backend, implemented for api parity.
|
||||
|
@ -464,3 +467,77 @@ pub fn (s string) strip_margin_custom(del byte) string {
|
|||
|
||||
return result
|
||||
}
|
||||
|
||||
// split_nth splits the string based on the passed `delim` substring.
|
||||
// It returns the first Nth parts. When N=0, return all the splits.
|
||||
// The last returned element has the remainder of the string, even if
|
||||
// the remainder contains more `delim` substrings.
|
||||
[direct_array_access]
|
||||
pub fn (s string) split_nth(delim string, nth int) []string {
|
||||
mut res := []string{}
|
||||
mut i := 0
|
||||
|
||||
match delim.len {
|
||||
0 {
|
||||
i = 1
|
||||
for ch in s {
|
||||
if nth > 0 && i >= nth {
|
||||
res << s[i..]
|
||||
break
|
||||
}
|
||||
res << ch.str()
|
||||
i++
|
||||
}
|
||||
return res
|
||||
}
|
||||
1 {
|
||||
mut start := 0
|
||||
delim_byte := delim[0]
|
||||
|
||||
for i < s.len {
|
||||
if s[i] == delim_byte {
|
||||
was_last := nth > 0 && res.len == nth - 1
|
||||
if was_last {
|
||||
break
|
||||
}
|
||||
val := s[start..i] //.substr(start, i)
|
||||
res << val
|
||||
start = i + delim.len
|
||||
i = start
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// Then the remaining right part of the string
|
||||
if nth < 1 || res.len < nth {
|
||||
res << s[start..]
|
||||
}
|
||||
return res
|
||||
}
|
||||
else {
|
||||
mut start := 0
|
||||
// Take the left part for each delimiter occurence
|
||||
for i <= s.len {
|
||||
is_delim := i + delim.len <= s.len && s[i..i + delim.len] == delim
|
||||
if is_delim {
|
||||
was_last := nth > 0 && res.len == nth - 1
|
||||
if was_last {
|
||||
break
|
||||
}
|
||||
val := s[start..i] // .substr(start, i)
|
||||
res << val
|
||||
start = i + delim.len
|
||||
i = start
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
}
|
||||
// Then the remaining right part of the string
|
||||
if nth < 1 || res.len < nth {
|
||||
res << s[start..]
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
|
|||
styp = '$prefix${g.sym_to_js_typ(sym)}("")'
|
||||
}
|
||||
.map {
|
||||
styp = 'new Map()'
|
||||
styp = 'new map(new Map())'
|
||||
}
|
||||
.array {
|
||||
styp = '$prefix${g.sym_to_js_typ(sym)}()'
|
||||
|
@ -335,6 +335,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
|||
typ_name: typ_name
|
||||
default_value: 'new Boolean(false)'
|
||||
to_jsval: '+this != 0'
|
||||
eq: 'this.val === other.valueOf()'
|
||||
)
|
||||
}
|
||||
'string' {
|
||||
|
@ -354,7 +355,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
|||
g.gen_builtin_prototype(
|
||||
typ_name: typ_name
|
||||
val_name: 'map'
|
||||
default_value: 'new Map()'
|
||||
default_value: 'new map(new Map())'
|
||||
constructor: 'this.map = map'
|
||||
value_of: 'this'
|
||||
to_string: 'this.map.toString()'
|
||||
|
|
|
@ -1831,17 +1831,16 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
} else {
|
||||
is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod]
|
||||
|
||||
mut needs_cast := is_arithmetic && it.left_type != it.right_type
|
||||
mut greater_typ := 0
|
||||
// todo(playX): looks like this cast is always required to perform .eq operation on types.
|
||||
if true || needs_cast {
|
||||
if is_arithmetic {
|
||||
greater_typ = g.greater_typ(it.left_type, it.right_type)
|
||||
if g.cast_stack.len > 0 {
|
||||
needs_cast = g.cast_stack.last() != greater_typ
|
||||
// needs_cast = g.cast_stack.last() != greater_typ
|
||||
}
|
||||
}
|
||||
|
||||
if true || needs_cast {
|
||||
if is_arithmetic {
|
||||
if g.ns.name == 'builtin' {
|
||||
g.write('new ')
|
||||
}
|
||||
|
@ -1855,7 +1854,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
|
||||
g.expr(it.right)
|
||||
|
||||
if true || needs_cast {
|
||||
if is_arithmetic {
|
||||
g.cast_stack.delete_last()
|
||||
g.write(')')
|
||||
}
|
||||
|
|
|
@ -195,6 +195,7 @@ true
|
|||
[2, 3, 4]
|
||||
[1, 2, 3]
|
||||
[1, 2, 3]
|
||||
[[1, 2, 3], [4, 5, 6]]
|
||||
true
|
||||
true
|
||||
true
|
||||
|
@ -292,5 +293,11 @@ true
|
|||
true
|
||||
true
|
||||
0
|
||||
`exists`: true and `not exists`: false
|
||||
[[], [], [], []]
|
||||
[[], [], [123], []]
|
||||
[{}, {}, {}, {}]
|
||||
[{}, {}, {'123': 123}, {}]
|
||||
Numbers { odds: [1, 3, 5] , evens: [2, 4] }
|
||||
Numbers { odds: [3, 5, 7] , evens: [2, 6, 10] }
|
||||
[[10, 10, 10], [10, 10, 10], [10, 10, 10]]
|
||||
|
|
|
@ -16,6 +16,11 @@ struct Coord {
|
|||
z int
|
||||
}
|
||||
|
||||
struct Numbers {
|
||||
odds []int
|
||||
evens []int
|
||||
}
|
||||
|
||||
struct Person {
|
||||
name string
|
||||
nums []int
|
||||
|
@ -672,15 +677,13 @@ fn main() {
|
|||
}
|
||||
{
|
||||
// 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
|
||||
|
@ -1110,8 +1113,7 @@ fn main() {
|
|||
}
|
||||
{
|
||||
// test array struct contains
|
||||
/*
|
||||
todo: does not work
|
||||
|
||||
mut coords := []Coord{}
|
||||
coord_1 := Coord{
|
||||
x: 1
|
||||
|
@ -1124,7 +1126,6 @@ fn main() {
|
|||
println('`exists`: $exists and `not exists`: $not_exists')
|
||||
assert exists == true
|
||||
assert not_exists == false
|
||||
*/
|
||||
}
|
||||
{
|
||||
// test array of array append
|
||||
|
@ -1133,4 +1134,47 @@ fn main() {
|
|||
x[2] << 123 // RTE
|
||||
println(x)
|
||||
}
|
||||
{
|
||||
// test array of map insert
|
||||
mut x := []map[string]int{len: 4}
|
||||
println(x) // OK
|
||||
x[2]['123'] = 123 // RTE
|
||||
println(x)
|
||||
}
|
||||
{
|
||||
// todo(playX): does not work
|
||||
/*
|
||||
// test multi fixed array init
|
||||
a := [3][3]int{}
|
||||
println(a)
|
||||
*/
|
||||
}
|
||||
{
|
||||
// test array of multi filter
|
||||
arr := [1, 2, 3, 4, 5]
|
||||
nums := Numbers{
|
||||
odds: arr.filter(it % 2 == 1)
|
||||
evens: arr.filter(it % 2 == 0)
|
||||
}
|
||||
println(nums)
|
||||
assert nums.odds == [1, 3, 5]
|
||||
assert nums.evens == [2, 4]
|
||||
}
|
||||
{
|
||||
// test array of multi map
|
||||
arr := [1, 3, 5]
|
||||
nums := Numbers{
|
||||
odds: arr.map(it + 2)
|
||||
evens: arr.map(it * 2)
|
||||
}
|
||||
println(nums)
|
||||
assert nums.odds == [3, 5, 7]
|
||||
assert nums.evens == [2, 6, 10]
|
||||
}
|
||||
{
|
||||
// test multi fixed array with default init
|
||||
a := [3][3]int{init: [3]int{init: 10}}
|
||||
println(a)
|
||||
assert a == [[10, 10, 10]!, [10, 10, 10]!, [10, 10, 10]!]!
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
ab
|
||||
1000
|
||||
true
|
||||
true
|
||||
true
|
||||
man
|
||||
true
|
|
@ -0,0 +1,200 @@
|
|||
struct Foo {
|
||||
bar int
|
||||
mut:
|
||||
str string
|
||||
}
|
||||
|
||||
fn main() {
|
||||
{
|
||||
// test add
|
||||
mut a := 'a'
|
||||
a += 'b'
|
||||
println(a)
|
||||
a = 'a'
|
||||
for i := 1; i < 1000; i++ {
|
||||
a += 'b'
|
||||
}
|
||||
println(a.len)
|
||||
println(a.ends_with('bbbbb'))
|
||||
a += '123'
|
||||
println(a.ends_with('3'))
|
||||
}
|
||||
{
|
||||
// test ends with
|
||||
a := 'browser.v'
|
||||
println(a.ends_with('.v'))
|
||||
|
||||
s := 'V Programming Language'
|
||||
assert s.ends_with('guage') == true
|
||||
assert s.ends_with('Language') == true
|
||||
assert s.ends_with('Programming Language') == true
|
||||
assert s.ends_with('V') == false
|
||||
}
|
||||
{
|
||||
// test between
|
||||
s := 'hello [man] how you doing'
|
||||
println(s.find_between('[', ']'))
|
||||
}
|
||||
{
|
||||
// test compare
|
||||
a := 'Music'
|
||||
b := 'src'
|
||||
println(b >= a)
|
||||
}
|
||||
{
|
||||
// test lt
|
||||
a := ''
|
||||
b := 'a'
|
||||
c := 'a'
|
||||
d := 'b'
|
||||
e := 'aa'
|
||||
f := 'ab'
|
||||
|
||||
assert a < b
|
||||
assert !(b < c)
|
||||
assert c < d
|
||||
assert !(d < e)
|
||||
assert c < e
|
||||
assert e < f
|
||||
}
|
||||
{
|
||||
// test ge
|
||||
a := 'aa'
|
||||
b := 'aa'
|
||||
c := 'ab'
|
||||
d := 'abc'
|
||||
e := 'aaa'
|
||||
assert b >= a
|
||||
assert c >= b
|
||||
assert d >= c
|
||||
assert !(c >= d)
|
||||
assert e >= a
|
||||
}
|
||||
{
|
||||
// test compare strings
|
||||
a := 'aa'
|
||||
b := 'aa'
|
||||
c := 'ab'
|
||||
d := 'abc'
|
||||
e := 'aaa'
|
||||
assert compare_strings(a, b) == 0
|
||||
assert compare_strings(b, c) == -1
|
||||
assert compare_strings(c, d) == -1
|
||||
assert compare_strings(d, e) == 1
|
||||
assert compare_strings(a, e) == -1
|
||||
assert compare_strings(e, a) == 1
|
||||
}
|
||||
{
|
||||
// test sort
|
||||
mut vals := [
|
||||
'arr',
|
||||
'an',
|
||||
'a',
|
||||
'any',
|
||||
]
|
||||
len := vals.len
|
||||
vals.sort()
|
||||
assert len == vals.len
|
||||
assert vals[0] == 'a'
|
||||
assert vals[1] == 'an'
|
||||
assert vals[2] == 'any'
|
||||
assert vals[3] == 'arr'
|
||||
}
|
||||
{
|
||||
// todo(playX): sort codegen
|
||||
/*// test sort reverse
|
||||
mut vals := [
|
||||
'arr',
|
||||
'an',
|
||||
'a',
|
||||
'any',
|
||||
]
|
||||
len := vals.len
|
||||
vals.sort(b > a)
|
||||
assert len == vals.len
|
||||
assert vals[0] == 'a'
|
||||
assert vals[1] == 'an'
|
||||
assert vals[2] == 'any'
|
||||
assert vals[3] == 'arr'*/
|
||||
}
|
||||
{
|
||||
// todo: split nth
|
||||
/*
|
||||
a := '1,2,3'
|
||||
assert a.split(',').len == 3
|
||||
assert a.split_nth(',', -1).len == 3
|
||||
assert a.split_nth(',', 0).len == 3
|
||||
assert a.split_nth(',', 1).len == 1
|
||||
assert a.split_nth(',', 2).len == 2
|
||||
assert a.split_nth(',', 10).len == 3
|
||||
b := '1::2::3'
|
||||
assert b.split('::').len == 3
|
||||
assert b.split_nth('::', -1).len == 3
|
||||
assert b.split_nth('::', 0).len == 3
|
||||
assert b.split_nth('::', 1).len == 1
|
||||
assert b.split_nth('::', 2).len == 2
|
||||
assert b.split_nth('::', 10).len == 3
|
||||
c := 'ABCDEF'
|
||||
println(c.split('').len)
|
||||
assert c.split('').len == 6
|
||||
assert c.split_nth('', 3).len == 3
|
||||
assert c.split_nth('BC', -1).len == 2
|
||||
d := ','
|
||||
assert d.split(',').len == 2
|
||||
assert d.split_nth('', 3).len == 1
|
||||
assert d.split_nth(',', -1).len == 2
|
||||
assert d.split_nth(',', 3).len == 2
|
||||
e := ',,,0,,,,,a,,b,'
|
||||
assert e.split(',,').len == 5
|
||||
assert e.split_nth(',,', 3).len == 3
|
||||
assert e.split_nth(',', -1).len == 12
|
||||
assert e.split_nth(',', 3).len == 3
|
||||
*/
|
||||
}
|
||||
{
|
||||
// test split
|
||||
mut s := 'volt/twitch.v:34'
|
||||
mut vals := s.split(':')
|
||||
assert vals.len == 2
|
||||
assert vals[0] == 'volt/twitch.v'
|
||||
assert vals[1] == '34'
|
||||
// /////////
|
||||
s = '2018-01-01z13:01:02'
|
||||
vals = s.split('z')
|
||||
assert vals.len == 2
|
||||
assert vals[0] == '2018-01-01'
|
||||
assert vals[1] == '13:01:02'
|
||||
// //////////
|
||||
s = '4627a862c3dec29fb3182a06b8965e0025759e18___1530207969___blue'
|
||||
vals = s.split('___')
|
||||
assert vals.len == 3
|
||||
assert vals[0] == '4627a862c3dec29fb3182a06b8965e0025759e18'
|
||||
assert vals[1] == '1530207969'
|
||||
assert vals[2] == 'blue'
|
||||
// /////////
|
||||
s = 'lalala'
|
||||
vals = s.split('a')
|
||||
assert vals.len == 4
|
||||
assert vals[0] == 'l'
|
||||
assert vals[1] == 'l'
|
||||
assert vals[2] == 'l'
|
||||
assert vals[3] == ''
|
||||
// /////////
|
||||
s = 'awesome'
|
||||
a := s.split('')
|
||||
assert a.len == 7
|
||||
assert a[0] == 'a'
|
||||
assert a[1] == 'w'
|
||||
assert a[2] == 'e'
|
||||
assert a[3] == 's'
|
||||
assert a[4] == 'o'
|
||||
assert a[5] == 'm'
|
||||
assert a[6] == 'e'
|
||||
// /////////
|
||||
s = 'wavy turquoise bags'
|
||||
vals = s.split(' bags')
|
||||
assert vals.len == 2
|
||||
assert vals[0] == 'wavy turquoise'
|
||||
assert vals[1] == ''
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue