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)
|
#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() {
|
pub fn (mut a array) sort() {
|
||||||
#a.arr.sort($sortComparator)
|
#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.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; } )); }
|
#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; } })
|
#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`.
|
// delete deletes array element at index `i`.
|
||||||
pub fn (mut a array) delete(i int) {
|
pub fn (mut a array) delete(i int) {
|
||||||
a.delete_many(i, 1)
|
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)
|
left_sym := g.table.get_type_symbol(it.left_type)
|
||||||
if left_sym.kind == .array {
|
if left_sym.kind == .array {
|
||||||
node := it
|
node := it
|
||||||
match node.name {
|
if node.name in special_array_methods {
|
||||||
'insert' {
|
g.gen_array_method_call(it)
|
||||||
arg2_sym := g.table.get_type_symbol(node.args[1].typ)
|
return
|
||||||
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 {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -74,5 +74,16 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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