Skip to content

Commit

Permalink
[cpp] Fix Math.Min/Max/Clamp with different types.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Jan 13, 2025
1 parent 85da13d commit 9cf5995
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 26 deletions.
27 changes: 21 additions & 6 deletions GenCpp.fu
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,24 @@ public class GenCpp : GenCCpp
}
}

void WriteMathClampMaxMin!(FuType type, string function, List<FuExpr#> args)
{
Include("algorithm");
Write(function);
WriteChar('(');
bool first = true;
foreach (FuExpr arg in args) {
if (!first)
Write(", ");
first = false;
if (arg.Type != type)
WriteStaticCast(type, arg);
else
arg.Accept(this, FuPriority.Argument);
}
WriteChar(')');
}

protected override void WriteCallExpr!(FuType type, FuExpr? obj, FuMethod method, List<FuExpr#> args, FuPriority parent)
{
switch (method.Id) {
Expand Down Expand Up @@ -1224,8 +1242,7 @@ public class GenCpp : GenCCpp
WriteCall("std::ceil", args[0]);
break;
case FuId.MathClamp:
Include("algorithm");
WriteCall("std::clamp", args[0], args[1], args[2]);
WriteMathClampMaxMin(type, "std::clamp", args);
break;
case FuId.MathFusedMultiplyAdd:
IncludeMath();
Expand All @@ -1236,12 +1253,10 @@ public class GenCpp : GenCCpp
WriteCall("std::isinf", args[0]);
break;
case FuId.MathMax: // TODO: <cmath> fmax ?
Include("algorithm");
WriteCall("(std::max)", args[0], args[1]);
WriteMathClampMaxMin(type, "(std::max)", args);
break;
case FuId.MathMin: // TODO: <cmath> fmin ?
Include("algorithm");
WriteCall("(std::min)", args[0], args[1]);
WriteMathClampMaxMin(type, "(std::min)", args);
break;
case FuId.MathTruncate:
IncludeMath();
Expand Down
27 changes: 21 additions & 6 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14424,6 +14424,24 @@ void GenCpp::writeRegexArgument(const FuExpr * expr)
}
}

void GenCpp::writeMathClampMaxMin(const FuType * type, std::string_view function, const std::vector<std::shared_ptr<FuExpr>> * args)
{
include("algorithm");
write(function);
writeChar('(');
bool first = true;
for (const std::shared_ptr<FuExpr> &arg : *args) {
if (!first)
write(", ");
first = false;
if (arg->type.get() != type)
writeStaticCast(type, arg.get());
else
arg->accept(this, FuPriority::argument);
}
writeChar(')');
}

void GenCpp::writeCallExpr(const FuType * type, const FuExpr * obj, const FuMethod * method, const std::vector<std::shared_ptr<FuExpr>> * args, FuPriority parent)
{
switch (method->id) {
Expand Down Expand Up @@ -14888,8 +14906,7 @@ void GenCpp::writeCallExpr(const FuType * type, const FuExpr * obj, const FuMeth
writeCall("std::ceil", (*args)[0].get());
break;
case FuId::mathClamp:
include("algorithm");
writeCall("std::clamp", (*args)[0].get(), (*args)[1].get(), (*args)[2].get());
writeMathClampMaxMin(type, "std::clamp", args);
break;
case FuId::mathFusedMultiplyAdd:
includeMath();
Expand All @@ -14900,12 +14917,10 @@ void GenCpp::writeCallExpr(const FuType * type, const FuExpr * obj, const FuMeth
writeCall("std::isinf", (*args)[0].get());
break;
case FuId::mathMax:
include("algorithm");
writeCall("(std::max)", (*args)[0].get(), (*args)[1].get());
writeMathClampMaxMin(type, "(std::max)", args);
break;
case FuId::mathMin:
include("algorithm");
writeCall("(std::min)", (*args)[0].get(), (*args)[1].get());
writeMathClampMaxMin(type, "(std::min)", args);
break;
case FuId::mathTruncate:
includeMath();
Expand Down
27 changes: 21 additions & 6 deletions libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14769,6 +14769,24 @@ void WriteRegexArgument(FuExpr expr)
}
}

void WriteMathClampMaxMin(FuType type, string function, List<FuExpr> args)
{
Include("algorithm");
Write(function);
WriteChar('(');
bool first = true;
foreach (FuExpr arg in args) {
if (!first)
Write(", ");
first = false;
if (arg.Type != type)
WriteStaticCast(type, arg);
else
arg.Accept(this, FuPriority.Argument);
}
WriteChar(')');
}

protected override void WriteCallExpr(FuType type, FuExpr obj, FuMethod method, List<FuExpr> args, FuPriority parent)
{
switch (method.Id) {
Expand Down Expand Up @@ -15227,8 +15245,7 @@ protected override void WriteCallExpr(FuType type, FuExpr obj, FuMethod method,
WriteCall("std::ceil", args[0]);
break;
case FuId.MathClamp:
Include("algorithm");
WriteCall("std::clamp", args[0], args[1], args[2]);
WriteMathClampMaxMin(type, "std::clamp", args);
break;
case FuId.MathFusedMultiplyAdd:
IncludeMath();
Expand All @@ -15239,12 +15256,10 @@ protected override void WriteCallExpr(FuType type, FuExpr obj, FuMethod method,
WriteCall("std::isinf", args[0]);
break;
case FuId.MathMax:
Include("algorithm");
WriteCall("(std::max)", args[0], args[1]);
WriteMathClampMaxMin(type, "(std::max)", args);
break;
case FuId.MathMin:
Include("algorithm");
WriteCall("(std::min)", args[0], args[1]);
WriteMathClampMaxMin(type, "(std::min)", args);
break;
case FuId.MathTruncate:
IncludeMath();
Expand Down
1 change: 1 addition & 0 deletions libfut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2458,6 +2458,7 @@ class GenCpp : public GenCCpp
void writeRegex(const std::vector<std::shared_ptr<FuExpr>> * args, int argIndex);
void writeWrite(const std::vector<std::shared_ptr<FuExpr>> * args, bool newLine);
void writeRegexArgument(const FuExpr * expr);
void writeMathClampMaxMin(const FuType * type, std::string_view function, const std::vector<std::shared_ptr<FuExpr>> * args);
void writeMatchProperty(const FuSymbolReference * expr, std::string_view name);
void writeGtRawPtr(const FuExpr * expr);
void writeIsVar(const FuExpr * expr, const FuVar * def, FuPriority parent);
Expand Down
27 changes: 21 additions & 6 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -15256,6 +15256,24 @@ export class GenCpp extends GenCCpp
}
}

#writeMathClampMaxMin(type, function_, args)
{
this.include("algorithm");
this.write(function_);
this.writeChar(40);
let first = true;
for (const arg of args) {
if (!first)
this.write(", ");
first = false;
if (arg.type != type)
this.writeStaticCast(type, arg);
else
arg.accept(this, FuPriority.ARGUMENT);
}
this.writeChar(41);
}

writeCallExpr(type, obj, method, args, parent)
{
switch (method.id) {
Expand Down Expand Up @@ -15716,8 +15734,7 @@ export class GenCpp extends GenCCpp
this.writeCall("std::ceil", args[0]);
break;
case FuId.MATH_CLAMP:
this.include("algorithm");
this.writeCall("std::clamp", args[0], args[1], args[2]);
this.#writeMathClampMaxMin(type, "std::clamp", args);
break;
case FuId.MATH_FUSED_MULTIPLY_ADD:
this.includeMath();
Expand All @@ -15728,12 +15745,10 @@ export class GenCpp extends GenCCpp
this.writeCall("std::isinf", args[0]);
break;
case FuId.MATH_MAX:
this.include("algorithm");
this.writeCall("(std::max)", args[0], args[1]);
this.#writeMathClampMaxMin(type, "(std::max)", args);
break;
case FuId.MATH_MIN:
this.include("algorithm");
this.writeCall("(std::min)", args[0], args[1]);
this.#writeMathClampMaxMin(type, "(std::min)", args);
break;
case FuId.MATH_TRUNCATE:
this.includeMath();
Expand Down
4 changes: 2 additions & 2 deletions test/MathMaxMin.fu
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public static class Test
nint n = 1024;
long l = 0x1000000;
l *= l;
return Math.Min(-5, 10) == -5 && Math.Max(-5, 10) == 10 && Math.Min(n, -n) == -n && Math.Max(n, -n) == n && Math.Max(l, l) == l //FAIL: cl TODO
&& Math.Min(-3.0, 10.5) == -3 && Math.Max(-3.0, 10.5) == 10.5; //FAIL: swift TODO https://github.com/swiftlang/swift/issues/76416
return Math.Min(-5, 10) == -5 && Math.Max(-5, 10) == 10 && Math.Min(n, -n) == -n && Math.Max(n, -n) == n && Math.Max(l, l) == l && Math.Min(0, l) == 0 //FAIL: cl TODO
&& Math.Min(-3, 10.5) == -3 && Math.Max(-3, 10.5) == 10.5; //FAIL: swift TODO https://github.com/swiftlang/swift/issues/76416
}
}

0 comments on commit 9cf5995

Please sign in to comment.