js: implement codegen for array.sort and implement .any,.all (#11100)
parent
1f3f7705a2
commit
7a67a08d2f
|
@ -87,19 +87,6 @@ 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($sortComparator)
|
||||
}
|
||||
|
@ -153,6 +140,23 @@ pub fn (a array) str() string {
|
|||
#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; } })
|
||||
#array.prototype.any = function (value) {
|
||||
#let val ;if (typeof value == 'function') { val = function (x) { return value(x); } } else { val = function (x) { return vEq(x,value); } }
|
||||
#for (let i = 0;i < this.arr.length;i++)
|
||||
#if (val(this.arr[i]))
|
||||
#return true;
|
||||
#
|
||||
#return false;
|
||||
#}
|
||||
|
||||
#array.prototype.all = function (value) {
|
||||
#let val ;if (typeof value == 'function') { val = function (x) { return value(x); } } else { val = function (x) { return vEq(x,value); } }
|
||||
#for (let i = 0;i < this.arr.length;i++)
|
||||
#if (!val(this.arr[i]))
|
||||
#return false;
|
||||
#
|
||||
#return true;
|
||||
#}
|
||||
// delete deletes array element at index `i`.
|
||||
pub fn (mut a array) delete(i int) {
|
||||
a.delete_many(i, 1)
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
module js
|
||||
|
||||
import v.ast
|
||||
|
||||
const (
|
||||
special_array_methods = [
|
||||
'sort',
|
||||
'insert',
|
||||
'prepend',
|
||||
]
|
||||
)
|
||||
|
||||
fn (mut g JsGen) gen_array_method_call(it ast.CallExpr) {
|
||||
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
|
||||
}
|
||||
'prepend' {
|
||||
arg_sym := g.table.get_type_symbol(node.args[0].typ)
|
||||
is_arg_array := arg_sym.kind == .array && node.args[0].typ == node.left_type
|
||||
if is_arg_array {
|
||||
g.write('prepend_many(')
|
||||
} else {
|
||||
g.write('prepend(')
|
||||
}
|
||||
|
||||
if is_arg_array {
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('.arr, ')
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('.len')
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
}
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
'sort' {
|
||||
rec_sym := g.table.get_type_symbol(node.receiver_type)
|
||||
if rec_sym.kind != .array {
|
||||
println(node.name)
|
||||
println(g.typ(node.receiver_type))
|
||||
// println(rec_sym.kind)
|
||||
verror('.sort() is an array method')
|
||||
}
|
||||
|
||||
// `users.sort(a.age > b.age)`
|
||||
|
||||
if node.args.len == 0 {
|
||||
g.write('sort()')
|
||||
return
|
||||
} else {
|
||||
infix_expr := node.args[0].expr as ast.InfixExpr
|
||||
left_name := infix_expr.left.str()
|
||||
is_reverse := (left_name.starts_with('a') && infix_expr.op == .gt)
|
||||
|| (left_name.starts_with('b') && infix_expr.op == .lt)
|
||||
if is_reverse {
|
||||
g.write('arr.sort(function (b,a) {')
|
||||
} else {
|
||||
g.write('arr.sort(function (a,b) {')
|
||||
}
|
||||
g.write('return ')
|
||||
g.write('\$sortComparator(a,b)')
|
||||
g.write('})')
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
|
@ -1516,50 +1516,9 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
|||
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
|
||||
}
|
||||
'prepend' {
|
||||
arg_sym := g.table.get_type_symbol(node.args[0].typ)
|
||||
is_arg_array := arg_sym.kind == .array && node.args[0].typ == node.left_type
|
||||
if is_arg_array {
|
||||
g.write('prepend_many(')
|
||||
} else {
|
||||
g.write('prepend(')
|
||||
}
|
||||
|
||||
if is_arg_array {
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('.arr, ')
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('.len')
|
||||
} else {
|
||||
g.expr(node.args[0].expr)
|
||||
}
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
else {}
|
||||
if node.name in special_array_methods {
|
||||
g.gen_array_method_call(it)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -74,5 +74,16 @@ function vEq(a, b) {
|
|||
// true if both NaN, false otherwise
|
||||
return a!==a && b!==b;
|
||||
};
|
||||
|
||||
function \$sortComparator(a, b)
|
||||
{
|
||||
a = a.\$toJS();
|
||||
b = b.\$toJS();
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue