Make more of the builtins do promotion from int to double for convenience.

This commit is contained in:
Christoffer Lerno
2023-01-13 00:46:00 +01:00
committed by Christoffer Lerno
parent 50b0958fb6
commit 2123e81e8e
5 changed files with 83 additions and 33 deletions

View File

@@ -182,6 +182,18 @@ macro bool @has_same(#a, #b, ...)
return true; return true;
} }
macro bool is_promotable_to_floatlike($Type) = types::is_floatlike($Type) || types::is_int($Type);
macro bool is_same_vector_type($Type1, $Type2)
{
$if ($Type1.kindof != TypeKind.VECTOR):
return $Type2.kindof != TypeKind.VECTOR;
$else:
return $Type1.inner == $Type2.inner && $Type1.len == $Type2.len;
$endif;
}
macro bool is_equatable_value(value) macro bool is_equatable_value(value)
{ {
$if ($defined(value.less) || $defined(value.compare_to) || $defined(value.equals)): $if ($defined(value.less) || $defined(value.compare_to) || $defined(value.equals)):

View File

@@ -3,4 +3,15 @@ module std::core::values;
macro bool @is_int(#value) = types::is_int($typeof(#value)); macro bool @is_int(#value) = types::is_int($typeof(#value));
macro bool @convertable_to(#a, #b) = $checks($typeof(#b) x = #a); macro bool @convertable_to(#a, #b) = $checks($typeof(#b) x = #a);
macro bool @is_floatlike(#value) = types::is_floatlike($typeof(#value)); macro bool @is_floatlike(#value) = types::is_floatlike($typeof(#value));
macro bool @is_float(#value) = types::is_float($typeof(#value)); macro bool @is_float(#value) = types::is_float($typeof(#value));
macro bool @is_promotable_to_floatlike(#value) = types::is_promotable_to_floatlike($typeof(#value));
macro bool @is_same_vector_type(#value1, #value2) = types::is_same_vector_type($typeof(#value1), $typeof(#value2));
macro promote_int(x)
{
$if (values::@is_int(x)):
return (double)x;
$else:
return x;
$endif;
}

View File

@@ -133,70 +133,87 @@ macro ceil(x) = $$ceil(x);
macro clamp(x, lower, upper) = $$max(lower, $$min(x, upper)); macro clamp(x, lower, upper) = $$max(lower, $$min(x, upper));
/** /**
* @require values::@is_floatlike(mag) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(mag) `The input must be a number value or float vector`
* @require types::is_same($typeof(mag), $typeof(sgn)) `The input types must be equal` * @require values::@is_same_vector_type(mag, sgn) `The input types must match`
**/ **/
macro copysign(mag, sgn) = $$copysign(mag, sgn); macro copysign(mag, sgn) = $$copysign(mag, sgn);
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/ **/
macro cos(x) = $$cos(x); macro cos(x) = $$cos(x);
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/
macro cosec(x) = 1 / sin(x); macro cosec(x) = 1 / sin(x);
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/
macro cosech(x) = 2 / (exp(x) - exp(-x)); macro cosech(x) = 2 / (exp(x) - exp(-x));
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/ **/
macro cosh(x) = (exp(x) + exp(-x)) / 2.0; macro cosh(x) = (exp(x) + exp(-x)) / 2.0;
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/
macro cotan(x) = cos(x) / sin(x); macro cotan(x) = cos(x) / sin(x);
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/
macro cotanh(x) = (exp(2.0 * x) + 1.0) / (exp(2.0 * x) - 1.0); macro cotanh(x) = (exp(2.0 * x) + 1.0) / (exp(2.0 * x) - 1.0);
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/ **/
macro exp(x) = $$exp(x); macro exp(x) = $$exp(values::promote_int(x));
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/ **/
macro exp2(x) = $$exp2(x); macro exp2(x) = $$exp2(values::promote_int(x));
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number value or float vector`
**/ **/
macro floor(x) = $$floor(x); macro floor(x) = $$floor(values::promote_int(x));
/** /**
* @require values::@is_floatlike(a) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(a) `The input must be a number or float vector`
* @require types::@has_same(a, b, c) `The input types must be equal` * @require values::@is_promotable_to_floatlike(b) `The input must be a number or float vector`
* @require values::@is_promotable_to_floatlike(c) `The input must be a number or float vector`
* @require types::@is_same_vector_type(a, b) `The input types must be equal`
* @require types::@is_same_vector_type(a, c) `The input types must match`
**/ **/
macro fma(a, b, c) = $$fma(a, b, c); macro fma(a, b, c) = $$fma(a, b, c);
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
* @require values::@is_floatlike(y) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(y) `The input must be a number or a float vector`
* @require types::@is_same_vector_type(x, y) `The input types must match`
**/ **/
macro hypot(x, y) = sqrt(sqr(x) + sqr(y)); macro hypot(x, y) = sqrt(sqr(x) + sqr(y));
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro log(x) = $$log(x); macro log(x) = $$log(values::promote_int(x));
/** /**
* @require values::is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro log2(x) = $$log2(x); macro log2(x) = $$log2(values::promote_int(x));
/** /**
* @require values::is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro log10(x) = $$log10(x); macro log10(x) = $$log10(values::promote_int(x));
/** /**
* @require types::is_numerical($typeof(x)) `The input must be a floating point value or float vector` * @require types::is_numerical($typeof(x)) `The input must be a floating point value or float vector`
@@ -244,7 +261,7 @@ macro muladd(a, b, c) = $$fmuladd(a, b, c);
macro nearbyint(x) = $$nearbyint(x); macro nearbyint(x) = $$nearbyint(x);
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
* @require values::@convertable_to(exp, x) || values::@is_int(exp) `The input must be an integer, castable to the type of x` * @require values::@convertable_to(exp, x) || values::@is_int(exp) `The input must be an integer, castable to the type of x`
**/ **/
macro pow(x, exp) macro pow(x, exp)
@@ -257,7 +274,7 @@ macro pow(x, exp)
} }
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro rint(x) = $$rint(x); macro rint(x) = $$rint(x);
@@ -271,34 +288,43 @@ macro round(x) = $$round(x);
**/ **/
macro roundeven(x) = $$roundeven(x); macro roundeven(x) = $$roundeven(x);
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/
macro sec(x) = 1 / cos(x); macro sec(x) = 1 / cos(x);
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/
macro sech(x) = 2 / (exp(x) + exp(-x)); macro sech(x) = 2 / (exp(x) + exp(-x));
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro sin(x) = $$sin(x); macro sin(x) = $$sin(values::promote_int(x));
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro sinh(x) = (exp(x) - exp(-x)) / 2.0; macro sinh(x) = (exp(x) - exp(-x)) / 2.0;
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro sqr(x) = x * x; macro sqr(x) = values::promote_int(x) * values::promote_int(x);
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro sqrt(x) = $$sqrt(x); macro sqrt(x) = $$sqrt(values::promote_int(x));
/**
* @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/
macro tan(x) = sin(x) / cos(x); macro tan(x) = sin(x) / cos(x);
/** /**
* @require values::@is_floatlike(x) `The input must be a floating point value or float vector` * @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
**/ **/
macro tanh(x) = (exp(2.0 * x) - 1.0) / (exp(2.0 * x) + 1.0); macro tanh(x) = (exp(2.0 * x) - 1.0) / (exp(2.0 * x) + 1.0);

View File

@@ -13,7 +13,7 @@ fn void main()
fn VarString bin(int x) fn VarString bin(int x)
{ {
int bits = 1 + (int)(x == 0 ? 0 : math::log10((double)(x)) / math::log10(2)); int bits = x == 0 ? 1 : 1 + (int)math::log2(x);
VarString str; VarString str;
str.append_repeat('0', bits); str.append_repeat('0', bits);
for (int i = 0; i < bits; i++) for (int i = 0; i < bits; i++)

View File

@@ -98,7 +98,8 @@ static bool sema_check_builtin_args(Expr **args, BuiltinArg *arg_type, size_t ar
case BA_FLOATLIKE: case BA_FLOATLIKE:
if (!type_flat_is_floatlike(type)) if (!type_flat_is_floatlike(type))
{ {
SEMA_ERROR(args[i], "Expected a floating point or floating point vector."); SEMA_ERROR(args[i], "Expected a floating point or floating point vector, but was %s.",
type_quoted_error_string(type));
return false; return false;
} }
break; break;