diff --git a/vlib/builtin/float.v b/vlib/builtin/float.v new file mode 100644 index 0000000000..adcc189c05 --- /dev/null +++ b/vlib/builtin/float.v @@ -0,0 +1,113 @@ +// Copyright (c) 2019 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + +module builtin + +#include + +pub fn (d f64) str() string { + buf := malloc(sizeof(double) * 5 + 1)// TODO + C.sprintf(*char(buf), '%f', d) + return tos(buf, vstrlen(buf)) +} + +pub fn (d f32) str() string { + buf := malloc(sizeof(double) * 5 + 1)// TODO + C.sprintf(*char(buf), '%f', d) + return tos(buf, vstrlen(buf)) +} + +fn f32_abs(a f32) f32 { return if a < 0 { -a } else { a } } +fn f64_abs(a f64) f64 { return if a < 0 { -a } else { a } } + +// compare floats using C epsilon +// == +pub fn (a f64) eq(b f64) bool { + return f64_abs(a - b) <= C.DBL_EPSILON +} +pub fn (a f32) eq(b f32) bool { + return f32_abs(a - b) <= C.FLT_EPSILON +} + +pub fn (a f64) eqbit(b f64) bool { + return C.DEFAULT_EQUAL(a, b) +} + +pub fn (a f32) eqbit(b f32) bool { + return C.DEFAULT_EQUAL(a, b) +} + +// != +fn (a f64) ne(b f64) bool { + return !a.eq(b) +} +fn (a f32) ne(b f32) bool { + return !a.eq(b) +} +pub fn (a f64) nebit(b f64) bool { + return C.DEFAULT_NOT_EQUAL(a, b) +} +pub fn (a f32) nebit(b f32) bool { + return C.DEFAULT_NOT_EQUAL(a, b) +} + +// a < b +fn (a f64) lt(b f64) bool { + return a.ne(b) && a.ltbit(b) +} +fn (a f32) lt(b f32) bool { + return a.ne(b) && a.ltbit(b) +} +fn (a f64) ltbit(b f64) bool { + return C.DEFAULT_LT(a, b) +} +fn (a f32) ltbit(b f32) bool { + return C.DEFAULT_LT(a, b) +} + +// a <= b +fn (a f64) le(b f64) bool { + return !a.gt(b) +} +fn (a f32) le(b f32) bool { + return !a.gt(b) +} +fn (a f64) lebit(b f64) bool { + return C.DEFAULT_LE(a, b) +} +fn (a f32) lebit(b f32) bool { + return C.DEFAULT_LE(a, b) +} + +// a > b +fn (a f64) gt(b f64) bool { + return a.ne(b) && a.gtbit(b) +} +fn (a f32) gt(b f32) bool { + return a.ne(b) && a.gtbit(b) +} +fn (a f64) gtbit(b f64) bool { + return C.DEFAULT_GT(a, b) +} +fn (a f32) gtbit(b f32) bool { + return C.DEFAULT_GT(a, b) +} + +// a >= b +fn (a f64) ge(b f64) bool { + return !a.lt(b) +} +fn (a f32) ge(b f32) bool { + return !a.lt(b) +} +fn (a f64) gebit(b f64) bool { + return C.DEFAULT_GE(a, b) +} +fn (a f32) gebit(b f32) bool { + return C.DEFAULT_GE(a, b) +} + + + + diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index f3a0f8980b..d5e56d245c 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -4,130 +4,12 @@ module builtin -#include -#include - -pub fn (d f64) str() string { - buf := malloc(sizeof(double) * 5 + 1)// TODO - C.sprintf(*char(buf), '%f', d) - return tos(buf, vstrlen(buf)) -} - -pub fn (d f32) str() string { - buf := malloc(sizeof(double) * 5 + 1)// TODO - C.sprintf(*char(buf), '%f', d) - return tos(buf, vstrlen(buf)) -} - pub fn ptr_str(ptr voidptr) string { buf := malloc(sizeof(double) * 5 + 1)// TODO C.sprintf(*char(buf), '%p', ptr) return tos(buf, vstrlen(buf)) } -// compare floats using C epsilon -// == -pub fn (a f64) eq(b f64) bool { - $if windows { - $if tinyc { - return a -b <= 0.01 - } $else { - return C.fabs(a - b) <= C.DBL_EPSILON - } - } $else { - return C.fabs(a - b) <= C.DBL_EPSILON - } -} -pub fn (a f32) eq(b f32) bool { - $if windows { - $if tinyc { - return a -b <= 0.01 - } $else { - return C.fabsf(a - b) <= C.FLT_EPSILON - } - } $else { - return C.fabsf(a - b) <= C.FLT_EPSILON - } -} -pub fn (a f64) eqbit(b f64) bool { - return C.DEFAULT_EQUAL(a, b) -} -pub fn (a f32) eqbit(b f32) bool { - return C.DEFAULT_EQUAL(a, b) -} - -// != -fn (a f64) ne(b f64) bool { - return !a.eq(b) -} -fn (a f32) ne(b f32) bool { - return !a.eq(b) -} -pub fn (a f64) nebit(b f64) bool { - return C.DEFAULT_NOT_EQUAL(a, b) -} -pub fn (a f32) nebit(b f32) bool { - return C.DEFAULT_NOT_EQUAL(a, b) -} - -// a < b -fn (a f64) lt(b f64) bool { - return a.ne(b) && a.ltbit(b) -} -fn (a f32) lt(b f32) bool { - return a.ne(b) && a.ltbit(b) -} -fn (a f64) ltbit(b f64) bool { - return C.DEFAULT_LT(a, b) -} -fn (a f32) ltbit(b f32) bool { - return C.DEFAULT_LT(a, b) -} - -// a <= b -fn (a f64) le(b f64) bool { - return !a.gt(b) -} -fn (a f32) le(b f32) bool { - return !a.gt(b) -} -fn (a f64) lebit(b f64) bool { - return C.DEFAULT_LE(a, b) -} -fn (a f32) lebit(b f32) bool { - return C.DEFAULT_LE(a, b) -} - -// a > b -fn (a f64) gt(b f64) bool { - return a.ne(b) && a.gtbit(b) -} -fn (a f32) gt(b f32) bool { - return a.ne(b) && a.gtbit(b) -} -fn (a f64) gtbit(b f64) bool { - return C.DEFAULT_GT(a, b) -} -fn (a f32) gtbit(b f32) bool { - return C.DEFAULT_GT(a, b) -} - -// a >= b -fn (a f64) ge(b f64) bool { - return !a.lt(b) -} -fn (a f32) ge(b f32) bool { - return !a.lt(b) -} -fn (a f64) gebit(b f64) bool { - return C.DEFAULT_GE(a, b) -} -fn (a f32) gebit(b f32) bool { - return C.DEFAULT_GE(a, b) -} - - - // fn (nn i32) str() string { // return i // } diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index f0ea6d281c..017f47fe53 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -266,7 +266,7 @@ fn (p mut Parser) parse(pass Pass) { p.can_chash = p.mod=='ui' || p.mod == 'darwin'// TODO tmp remove // Import pass - the first and the smallest pass that only analyzes imports // if we are a building module get the full module name from v.mod - fq_mod := if p.pref.build_mode == .build_module && p.v.mod.ends_with(p.mod) { + fq_mod := if p.pref.build_mode == .build_module && p.v.mod.ends_with(p.mod) { p.v.mod } // fully qualify the module name, eg base64 to encoding.base64 @@ -1627,10 +1627,12 @@ fn (p mut Parser) bterm() string { p.expected_type = typ is_str := typ=='string' && !p.is_sql is_ustr := typ=='ustring' - is_float := typ=='f64' || typ=='f32' + is_float := typ[0] == `f` && (typ in ['f64', 'f32']) && + !(p.cur_fn.name in ['f64_abs', 'f32_abs']) && + !(p.cur_fn.name == 'eq') expr_type := typ tok := p.tok - if tok in [ .eq, .gt, .lt, .le, .ge, .ne] { + if tok in [.eq, .gt, .lt, .le, .ge, .ne] { p.fgen(' ${p.tok.str()} ') if (is_float || is_str || is_ustr) && !p.is_js { p.gen(',') @@ -1686,7 +1688,7 @@ fn (p mut Parser) bterm() string { case TokenKind.lt: p.cgen.set_placeholder(ph, 'ustring_lt(') } } - if is_float { + if is_float && p.cur_fn.name != 'f32_abs' && p.cur_fn.name != 'f64_abs' { p.gen(')') switch tok { case TokenKind.eq: p.cgen.set_placeholder(ph, '${expr_type}_eq(') diff --git a/vlib/math/math.v b/vlib/math/math.v index 6839b7db38..3088ef6af4 100644 --- a/vlib/math/math.v +++ b/vlib/math/math.v @@ -4,6 +4,8 @@ module math +#include + // NOTE // When adding a new function, please make sure it's in the right place. // All functions are sorted alphabetically.