v.gen.js: support operator overloading (#11171)
parent
083a90148d
commit
aa14fd1b05
|
@ -428,6 +428,9 @@ fn (mut g JsGen) js_name(name_ string) string {
|
||||||
'*' {
|
'*' {
|
||||||
'\$mul'
|
'\$mul'
|
||||||
}
|
}
|
||||||
|
'%' {
|
||||||
|
'\$mod'
|
||||||
|
}
|
||||||
'==' {
|
'==' {
|
||||||
'eq'
|
'eq'
|
||||||
}
|
}
|
||||||
|
@ -1769,8 +1772,14 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if it.op == .eq || it.op == .ne {
|
if it.op == .eq || it.op == .ne {
|
||||||
|
has_operator_overloading := g.table.type_has_method(l_sym, '==')
|
||||||
|
if has_operator_overloading {
|
||||||
|
g.expr(it.left)
|
||||||
|
g.write('.eq(')
|
||||||
|
g.expr(it.right)
|
||||||
|
g.write(')')
|
||||||
// Shallow equatables
|
// Shallow equatables
|
||||||
if l_sym.kind in js.shallow_equatables && r_sym.kind in js.shallow_equatables {
|
} else if l_sym.kind in js.shallow_equatables && r_sym.kind in js.shallow_equatables {
|
||||||
// wrap left expr in parens so binary operations will work correctly.
|
// wrap left expr in parens so binary operations will work correctly.
|
||||||
g.write('(')
|
g.write('(')
|
||||||
g.expr(it.left)
|
g.expr(it.left)
|
||||||
|
@ -1816,9 +1825,52 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||||
g.expr(it.left)
|
g.expr(it.left)
|
||||||
g.write(' instanceof ')
|
g.write(' instanceof ')
|
||||||
g.write(g.typ(it.right_type))
|
g.write(g.typ(it.right_type))
|
||||||
|
} else if it.op in [.lt, .gt, .ge, .le] && g.table.type_has_method(l_sym, '<')
|
||||||
|
&& l_sym.kind == r_sym.kind {
|
||||||
|
if it.op in [.le, .ge] {
|
||||||
|
g.write('!')
|
||||||
|
}
|
||||||
|
if it.op in [.lt, .ge] {
|
||||||
|
g.expr(it.left)
|
||||||
|
g.write('.\$lt (')
|
||||||
|
g.expr(it.right)
|
||||||
|
g.write(')')
|
||||||
|
} else {
|
||||||
|
g.expr(it.right)
|
||||||
|
g.write('.\$lt (')
|
||||||
|
g.expr(it.left)
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod]
|
is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod]
|
||||||
|
has_operator_overloading := g.table.type_has_method(l_sym, it.op.str())
|
||||||
|
if has_operator_overloading {
|
||||||
|
g.expr(it.left)
|
||||||
|
name := match it.op.str() {
|
||||||
|
'+' {
|
||||||
|
'\$add'
|
||||||
|
}
|
||||||
|
'-' {
|
||||||
|
'\$sub'
|
||||||
|
}
|
||||||
|
'/' {
|
||||||
|
'\$div'
|
||||||
|
}
|
||||||
|
'*' {
|
||||||
|
'\$mul'
|
||||||
|
}
|
||||||
|
'%' {
|
||||||
|
'\$mod'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic('unreachable')
|
||||||
|
''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write('.$name (')
|
||||||
|
g.expr(it.right)
|
||||||
|
g.write(')')
|
||||||
|
} else {
|
||||||
mut greater_typ := 0
|
mut greater_typ := 0
|
||||||
// todo(playX): looks like this cast is always required to perform .eq operation on types.
|
// todo(playX): looks like this cast is always required to perform .eq operation on types.
|
||||||
if is_arithmetic {
|
if is_arithmetic {
|
||||||
|
@ -1847,6 +1899,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if is_not {
|
if is_not {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Foo { x: 5 , y: 5 }
|
||||||
|
true
|
||||||
|
true
|
|
@ -0,0 +1,24 @@
|
||||||
|
struct Foo {
|
||||||
|
x f32
|
||||||
|
y f32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (x Foo) == (y Foo) bool {
|
||||||
|
return x.x == y.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (x Foo) < (y Foo) bool {
|
||||||
|
return x.x < y.x && x.y < y.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (a Foo) + (b Foo) Foo {
|
||||||
|
return Foo{a.x + b.x, a.y + b.y}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
x := Foo{4.0, 3.0}
|
||||||
|
y := Foo{1.0, 2.0}
|
||||||
|
println(x + y)
|
||||||
|
println(Foo{42.42, 0.0} == Foo{0.0, 42.42})
|
||||||
|
println(x > y)
|
||||||
|
}
|
Loading…
Reference in New Issue