js: implement codegen for array.sort and implement .any,.all (#11100)

pull/11112/head
playX 2021-08-09 01:46:40 +03:00 committed by GitHub
parent 1f3f7705a2
commit 7a67a08d2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 57 deletions

View File

@ -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)

View File

@ -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 {}
}
}

View File

@ -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 {

View File

@ -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;
}
"
)