cgen: operator overloading
parent
3521b7ff89
commit
a08e64f37f
|
@ -271,11 +271,11 @@ pub fn len_16(x u16) int {
|
||||||
pub fn len_32(x u32) int {
|
pub fn len_32(x u32) int {
|
||||||
mut y := x
|
mut y := x
|
||||||
mut n := 0
|
mut n := 0
|
||||||
if y >= 1<<16 {
|
if y >= (1<<16) {
|
||||||
y >>= 16
|
y >>= 16
|
||||||
n = 16
|
n = 16
|
||||||
}
|
}
|
||||||
if y >= 1<<8 {
|
if y >= (1<<8) {
|
||||||
y >>= 8
|
y >>= 8
|
||||||
n += 8
|
n += 8
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ fn test_bits(){
|
||||||
// 32 bit
|
// 32 bit
|
||||||
i = 1
|
i = 1
|
||||||
for x in 0..32 {
|
for x in 0..32 {
|
||||||
v0 := u32(i) << x
|
v0 := (u32(i) << x)
|
||||||
v1 := v0 - 1
|
v1 := v0 - 1
|
||||||
hi, lo := mul_32(v0, v1)
|
hi, lo := mul_32(v0, v1)
|
||||||
//C.printf("x:%08x [%llu,%llu] %llu\n", v0, hi, lo, u64(v0 * v1))
|
//C.printf("x:%08x [%llu,%llu] %llu\n", v0, hi, lo, u64(v0 * v1))
|
||||||
|
|
|
@ -366,7 +366,7 @@ pub fn (c Complex) asinh() Complex {
|
||||||
// Based on
|
// Based on
|
||||||
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
||||||
pub fn (c Complex) acosh() Complex {
|
pub fn (c Complex) acosh() Complex {
|
||||||
if(c.re > 1) {
|
if c.re > 1 {
|
||||||
return c.add(
|
return c.add(
|
||||||
c.pow(2)
|
c.pow(2)
|
||||||
.subtract(complex(1,0))
|
.subtract(complex(1,0))
|
||||||
|
@ -391,7 +391,7 @@ pub fn (c Complex) acosh() Complex {
|
||||||
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
||||||
pub fn (c Complex) atanh() Complex {
|
pub fn (c Complex) atanh() Complex {
|
||||||
one := complex(1,0)
|
one := complex(1,0)
|
||||||
if(c.re < 1) {
|
if c.re < 1 {
|
||||||
return complex(1.0/2,0).multiply(
|
return complex(1.0/2,0).multiply(
|
||||||
one
|
one
|
||||||
.add(c)
|
.add(c)
|
||||||
|
@ -421,7 +421,7 @@ pub fn (c Complex) atanh() Complex {
|
||||||
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
||||||
pub fn (c Complex) acoth() Complex {
|
pub fn (c Complex) acoth() Complex {
|
||||||
one := complex(1,0)
|
one := complex(1,0)
|
||||||
if(c.re < 0 || c.re > 1) {
|
if c.re < 0 || c.re > 1 {
|
||||||
return complex(1.0/2,0).multiply(
|
return complex(1.0/2,0).multiply(
|
||||||
c
|
c
|
||||||
.add(one)
|
.add(one)
|
||||||
|
@ -479,7 +479,7 @@ pub fn (c Complex) acoth() Complex {
|
||||||
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
|
||||||
pub fn (c Complex) acsch() Complex {
|
pub fn (c Complex) acsch() Complex {
|
||||||
one := complex(1,0)
|
one := complex(1,0)
|
||||||
if(c.re < 0) {
|
if c.re < 0 {
|
||||||
return one.subtract(
|
return one.subtract(
|
||||||
one.add(
|
one.add(
|
||||||
c.pow(2)
|
c.pow(2)
|
||||||
|
|
|
@ -168,6 +168,8 @@ fn test_complex_mulinv() {
|
||||||
mut c2 := cmplx.complex(0.067568,-0.094595)
|
mut c2 := cmplx.complex(0.067568,-0.094595)
|
||||||
mut result := c1.mulinv()
|
mut result := c1.mulinv()
|
||||||
// Some issue with precision comparison in f64 using == operator hence serializing to string
|
// Some issue with precision comparison in f64 using == operator hence serializing to string
|
||||||
|
println(c2.str())
|
||||||
|
println(result.str())
|
||||||
assert result.str().eq(c2.str())
|
assert result.str().eq(c2.str())
|
||||||
c1 = cmplx.complex(-3,4)
|
c1 = cmplx.complex(-3,4)
|
||||||
c2 = cmplx.complex(-0.12,-0.16)
|
c2 = cmplx.complex(-0.12,-0.16)
|
||||||
|
|
|
@ -788,6 +788,10 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mut name := it.name
|
mut name := it.name
|
||||||
|
c := name[0]
|
||||||
|
if c in [`+`, `-`, `*`, `/`] {
|
||||||
|
name = util.replace_op(name)
|
||||||
|
}
|
||||||
if it.is_method {
|
if it.is_method {
|
||||||
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
||||||
}
|
}
|
||||||
|
@ -796,9 +800,6 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
} else {
|
} else {
|
||||||
name = c_name(name)
|
name = c_name(name)
|
||||||
}
|
}
|
||||||
if name.starts_with('_op_') {
|
|
||||||
name = op_to_fn_name(name)
|
|
||||||
}
|
|
||||||
// type_name := g.table.Type_to_str(it.return_type)
|
// type_name := g.table.Type_to_str(it.return_type)
|
||||||
type_name := g.typ(it.return_type)
|
type_name := g.typ(it.return_type)
|
||||||
g.write('$type_name ${name}(')
|
g.write('$type_name ${name}(')
|
||||||
|
@ -1295,6 +1296,7 @@ fn (g mut Gen) assign_expr(node ast.AssignExpr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
|
left_sym := g.table.get_type_symbol(node.left_type)
|
||||||
// println('infix_expr() op="$node.op.str()" line_nr=$node.pos.line_nr')
|
// println('infix_expr() op="$node.op.str()" line_nr=$node.pos.line_nr')
|
||||||
// g.write('/*infix*/')
|
// g.write('/*infix*/')
|
||||||
// if it.left_type == table.string_type_idx {
|
// if it.left_type == table.string_type_idx {
|
||||||
|
@ -1412,6 +1414,15 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
g.write(',')
|
g.write(',')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
} else if node.op in [.plus, .minus, .mul, .div] && (left_sym.name[0].is_capital() || left_sym.name.contains('.')) {
|
||||||
|
g.write(g.typ(node.left_type))
|
||||||
|
g.write('_')
|
||||||
|
g.write(util.replace_op(node.op.str()))
|
||||||
|
g.write('(')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(', ')
|
||||||
|
g.expr(node.right)
|
||||||
|
g.write(')')
|
||||||
} else {
|
} else {
|
||||||
need_par := node.op in [.amp, .pipe, .xor] // `x & y == 0` => `(x & y) == 0` in C
|
need_par := node.op in [.amp, .pipe, .xor] // `x & y == 0` => `(x & y) == 0` in C
|
||||||
if need_par {
|
if need_par {
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module util
|
module util
|
||||||
|
|
||||||
import os
|
import (
|
||||||
import v.pref
|
os
|
||||||
|
v.pref
|
||||||
|
)
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
v_version = '0.1.26'
|
v_version = '0.1.26'
|
||||||
|
@ -50,7 +52,7 @@ pub fn githash(should_get_from_filesystem bool) string {
|
||||||
vroot := os.dir(vexe)
|
vroot := os.dir(vexe)
|
||||||
// .git/HEAD
|
// .git/HEAD
|
||||||
git_head_file := os.join_path(vroot, '.git', 'HEAD')
|
git_head_file := os.join_path(vroot, '.git', 'HEAD')
|
||||||
if !os.exists( git_head_file ) {
|
if !os.exists(git_head_file) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// 'ref: refs/heads/master' ... the current branch name
|
// 'ref: refs/heads/master' ... the current branch name
|
||||||
|
@ -60,11 +62,11 @@ pub fn githash(should_get_from_filesystem bool) string {
|
||||||
gcbranch_rel_path := head_content.replace('ref: ', '').trim_space()
|
gcbranch_rel_path := head_content.replace('ref: ', '').trim_space()
|
||||||
gcbranch_file := os.join_path(vroot, '.git', gcbranch_rel_path)
|
gcbranch_file := os.join_path(vroot, '.git', gcbranch_rel_path)
|
||||||
// .git/refs/heads/master
|
// .git/refs/heads/master
|
||||||
if !os.exists( gcbranch_file ) {
|
if !os.exists(gcbranch_file) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// get the full commit hash contained in the ref heads file
|
// get the full commit hash contained in the ref heads file
|
||||||
current_branch_hash := os.read_file( gcbranch_file ) or {
|
current_branch_hash := os.read_file(gcbranch_file) or {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
desired_hash_length := 7
|
desired_hash_length := 7
|
||||||
|
@ -81,20 +83,18 @@ pub fn githash(should_get_from_filesystem bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
fn set_vroot_folder(vroot_path string) {
|
fn set_vroot_folder(vroot_path string) {
|
||||||
// Preparation for the compiler module:
|
// Preparation for the compiler module:
|
||||||
// VEXE env variable is needed so that compiler.vexe_path()
|
// VEXE env variable is needed so that compiler.vexe_path()
|
||||||
// can return it later to whoever needs it:
|
// can return it later to whoever needs it:
|
||||||
vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
||||||
os.setenv('VEXE', os.real_path(os.join_path( vroot_path, vname)), true)
|
os.setenv('VEXE', os.real_path(os.join_path(vroot_path, vname)), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn launch_tool(is_verbose bool, tool_name string) {
|
pub fn launch_tool(is_verbose bool, tool_name string) {
|
||||||
vexe := pref.vexe_path()
|
vexe := pref.vexe_path()
|
||||||
vroot := os.dir(vexe)
|
vroot := os.dir(vexe)
|
||||||
set_vroot_folder(vroot)
|
set_vroot_folder(vroot)
|
||||||
|
|
||||||
tool_args := os.args[1..].join(' ')
|
tool_args := os.args[1..].join(' ')
|
||||||
tool_exe := path_of_executable(os.real_path('$vroot/cmd/tools/$tool_name'))
|
tool_exe := path_of_executable(os.real_path('$vroot/cmd/tools/$tool_name'))
|
||||||
tool_source := os.real_path('$vroot/cmd/tools/${tool_name}.v')
|
tool_source := os.real_path('$vroot/cmd/tools/${tool_name}.v')
|
||||||
|
@ -105,7 +105,6 @@ pub fn launch_tool(is_verbose bool, tool_name string) {
|
||||||
println('launch_tool tool_args : $tool_args')
|
println('launch_tool tool_args : $tool_args')
|
||||||
println('launch_tool tool_command: $tool_command')
|
println('launch_tool tool_command: $tool_command')
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Caching should be done on the `vlib/v` level.
|
// TODO Caching should be done on the `vlib/v` level.
|
||||||
mut should_compile := false
|
mut should_compile := false
|
||||||
if !os.exists(tool_exe) {
|
if !os.exists(tool_exe) {
|
||||||
|
@ -115,7 +114,6 @@ pub fn launch_tool(is_verbose bool, tool_name string) {
|
||||||
// v was recompiled, maybe after v up ...
|
// v was recompiled, maybe after v up ...
|
||||||
// rebuild the tool too just in case
|
// rebuild the tool too just in case
|
||||||
should_compile = true
|
should_compile = true
|
||||||
|
|
||||||
if tool_name == 'vself' || tool_name == 'vup' {
|
if tool_name == 'vself' || tool_name == 'vup' {
|
||||||
// The purpose of vself/up is to update and recompile v itself.
|
// The purpose of vself/up is to update and recompile v itself.
|
||||||
// After the first 'v self' execution, v will be modified, so
|
// After the first 'v self' execution, v will be modified, so
|
||||||
|
@ -133,14 +131,15 @@ pub fn launch_tool(is_verbose bool, tool_name string) {
|
||||||
if is_verbose {
|
if is_verbose {
|
||||||
println('launch_tool should_compile: $should_compile')
|
println('launch_tool should_compile: $should_compile')
|
||||||
}
|
}
|
||||||
|
|
||||||
if should_compile {
|
if should_compile {
|
||||||
mut compilation_command := '"$vexe" '
|
mut compilation_command := '"$vexe" '
|
||||||
compilation_command += '"$tool_source"'
|
compilation_command += '"$tool_source"'
|
||||||
if is_verbose {
|
if is_verbose {
|
||||||
println('Compiling $tool_name with: "$compilation_command"')
|
println('Compiling $tool_name with: "$compilation_command"')
|
||||||
}
|
}
|
||||||
tool_compilation := os.exec(compilation_command) or { panic(err) }
|
tool_compilation := os.exec(compilation_command) or {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
if tool_compilation.exit_code != 0 {
|
if tool_compilation.exit_code != 0 {
|
||||||
mut err := 'Permission denied'
|
mut err := 'Permission denied'
|
||||||
if !tool_compilation.output.contains('Permission denied') {
|
if !tool_compilation.output.contains('Permission denied') {
|
||||||
|
@ -153,7 +152,6 @@ pub fn launch_tool(is_verbose bool, tool_name string) {
|
||||||
if is_verbose {
|
if is_verbose {
|
||||||
println('launch_tool running tool command: $tool_command ...')
|
println('launch_tool running tool command: $tool_command ...')
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(os.system(tool_command))
|
exit(os.system(tool_command))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,13 +178,42 @@ pub fn read_file(file_path string) ?string {
|
||||||
return raw_text
|
return raw_text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn imin(a, b int) int {
|
fn imin(a, b int) int {
|
||||||
return if a < b { a } else { b }
|
return if a < b {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn imax(a, b int) int {
|
fn imax(a, b int) int {
|
||||||
return if a > b { a } else { b }
|
return if a > b {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn replace_op(s string) string {
|
||||||
|
last_char := s[s.len - 1]
|
||||||
|
suffix := match last_char {
|
||||||
|
`+` {
|
||||||
|
'_plus'
|
||||||
|
}
|
||||||
|
`-` {
|
||||||
|
'_minus'
|
||||||
|
}
|
||||||
|
`*` {
|
||||||
|
'_mult'
|
||||||
|
}
|
||||||
|
`/` {
|
||||||
|
'_div'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[..s.len - 1] + suffix
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue