summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Fusik <piotr@fusion-lang.org>2024-02-28 20:46:10 +0100
committerPiotr Fusik <piotr@fusion-lang.org>2024-02-28 20:46:10 +0100
commitf9cbcd86f92e383796ad37543996dc87c1f788cc (patch)
tree92feecbf6239fec3bfd9e31e92be7935a03a359b
parentfdadd2203c27f37028fc9a69d1bee8ff6b785661 (diff)
[java] if (!number.TryParse(str)).
#140
-rw-r--r--GenJava.fu41
-rw-r--r--libfut.cpp44
-rw-r--r--libfut.cs39
-rw-r--r--libfut.hpp2
-rw-r--r--libfut.js44
5 files changed, 170 insertions, 0 deletions
diff --git a/GenJava.fu b/GenJava.fu
index c27db2d..9b4813b 100644
--- a/GenJava.fu
+++ b/GenJava.fu
@@ -1101,6 +1101,47 @@ public class GenJava : GenTyped
WriteChild(statement.Body);
}
+ static bool IsTryParse(FuId id) => id == FuId.IntTryParse || id == FuId.LongTryParse || id == FuId.DoubleTryParse;
+
+ internal override void VisitIf!(FuIf statement)
+ {
+ if (statement.OnFalse == null
+ && statement.Cond is FuPrefixExpr not && not.Op == FuToken.ExclamationMark
+ && not.Inner is FuCallExpr call && IsTryParse(call.Method.Symbol.Id)) {
+ Write("try ");
+ OpenBlock();
+ call.Method.Left.Accept(this, FuPriority.Assign);
+ Write(" = ");
+ switch (call.Method.Symbol.Id) {
+ case FuId.IntTryParse:
+ Write("Integer.parseInt");
+ break;
+ case FuId.LongTryParse:
+ Write("Long.parseLong");
+ break;
+ case FuId.DoubleTryParse:
+ Write("Double.parseDouble");
+ break;
+ default:
+ assert false;
+ }
+ WriteChar('(');
+ call.Arguments[0].Accept(this, FuPriority.Argument);
+ if (call.Arguments.Count == 2) {
+ Write(", ");
+ call.Arguments[1].Accept(this, FuPriority.Argument);
+ }
+ WriteLine(");");
+ CloseBlock();
+ Write("catch (NumberFormatException e) ");
+ OpenBlock();
+ statement.OnTrue.AcceptStatement(this);
+ CloseBlock();
+ }
+ else
+ base.VisitIf(statement);
+ }
+
internal override void VisitLock!(FuLock statement)
{
WriteCall("synchronized ", statement.Lock);
diff --git a/libfut.cpp b/libfut.cpp
index 517892d..cfefe31 100644
--- a/libfut.cpp
+++ b/libfut.cpp
@@ -18441,6 +18441,50 @@ void GenJava::visitForeach(const FuForeach * statement)
writeChild(statement->body.get());
}
+bool GenJava::isTryParse(FuId id)
+{
+ return id == FuId::intTryParse || id == FuId::longTryParse || id == FuId::doubleTryParse;
+}
+
+void GenJava::visitIf(const FuIf * statement)
+{
+ const FuPrefixExpr * not_;
+ const FuCallExpr * call;
+ if (statement->onFalse == nullptr && (not_ = dynamic_cast<const FuPrefixExpr *>(statement->cond.get())) && not_->op == FuToken::exclamationMark && (call = dynamic_cast<const FuCallExpr *>(not_->inner.get())) && isTryParse(call->method->symbol->id)) {
+ write("try ");
+ openBlock();
+ call->method->left->accept(this, FuPriority::assign);
+ write(" = ");
+ switch (call->method->symbol->id) {
+ case FuId::intTryParse:
+ write("Integer.parseInt");
+ break;
+ case FuId::longTryParse:
+ write("Long.parseLong");
+ break;
+ case FuId::doubleTryParse:
+ write("Double.parseDouble");
+ break;
+ default:
+ std::abort();
+ }
+ writeChar('(');
+ call->arguments[0]->accept(this, FuPriority::argument);
+ if (std::ssize(call->arguments) == 2) {
+ write(", ");
+ call->arguments[1]->accept(this, FuPriority::argument);
+ }
+ writeLine(");");
+ closeBlock();
+ write("catch (NumberFormatException e) ");
+ openBlock();
+ statement->onTrue->acceptStatement(this);
+ closeBlock();
+ }
+ else
+ GenBase::visitIf(statement);
+}
+
void GenJava::visitLock(const FuLock * statement)
{
writeCall("synchronized ", statement->lock.get());
diff --git a/libfut.cs b/libfut.cs
index 0f1311a..060b1d6 100644
--- a/libfut.cs
+++ b/libfut.cs
@@ -19080,6 +19080,45 @@ namespace Fusion
WriteChild(statement.Body);
}
+ static bool IsTryParse(FuId id) => id == FuId.IntTryParse || id == FuId.LongTryParse || id == FuId.DoubleTryParse;
+
+ internal override void VisitIf(FuIf statement)
+ {
+ if (statement.OnFalse == null && statement.Cond is FuPrefixExpr not && not.Op == FuToken.ExclamationMark && not.Inner is FuCallExpr call && IsTryParse(call.Method.Symbol.Id)) {
+ Write("try ");
+ OpenBlock();
+ call.Method.Left.Accept(this, FuPriority.Assign);
+ Write(" = ");
+ switch (call.Method.Symbol.Id) {
+ case FuId.IntTryParse:
+ Write("Integer.parseInt");
+ break;
+ case FuId.LongTryParse:
+ Write("Long.parseLong");
+ break;
+ case FuId.DoubleTryParse:
+ Write("Double.parseDouble");
+ break;
+ default:
+ throw new NotImplementedException();
+ }
+ WriteChar('(');
+ call.Arguments[0].Accept(this, FuPriority.Argument);
+ if (call.Arguments.Count == 2) {
+ Write(", ");
+ call.Arguments[1].Accept(this, FuPriority.Argument);
+ }
+ WriteLine(");");
+ CloseBlock();
+ Write("catch (NumberFormatException e) ");
+ OpenBlock();
+ statement.OnTrue.AcceptStatement(this);
+ CloseBlock();
+ }
+ else
+ base.VisitIf(statement);
+ }
+
internal override void VisitLock(FuLock statement)
{
WriteCall("synchronized ", statement.Lock);
diff --git a/libfut.hpp b/libfut.hpp
index 8c54e16..5486393 100644
--- a/libfut.hpp
+++ b/libfut.hpp
@@ -2521,6 +2521,7 @@ public:
void visitSymbolReference(const FuSymbolReference * expr, FuPriority parent) override;
void visitLambdaExpr(const FuLambdaExpr * expr) override;
void visitForeach(const FuForeach * statement) override;
+ void visitIf(const FuIf * statement) override;
void visitLock(const FuLock * statement) override;
void visitReturn(const FuReturn * statement) override;
void visitSwitch(const FuSwitch * statement) override;
@@ -2540,6 +2541,7 @@ private:
void writeArrayBinarySearchFill(const FuExpr * obj, std::string_view method, const std::vector<std::shared_ptr<FuExpr>> * args);
void writeWrite(const FuMethod * method, const std::vector<std::shared_ptr<FuExpr>> * args, bool newLine);
void writeCompileRegex(const std::vector<std::shared_ptr<FuExpr>> * args, int argIndex);
+ static bool isTryParse(FuId id);
void createJavaFile(std::string_view className);
void writeSignature(const FuMethod * method, int paramCount);
void writeOverloads(const FuMethod * method, int paramCount);
diff --git a/libfut.js b/libfut.js
index 2ebc804..39ae82b 100644
--- a/libfut.js
+++ b/libfut.js
@@ -19612,6 +19612,50 @@ export class GenJava extends GenTyped
this.writeChild(statement.body);
}
+ static #isTryParse(id)
+ {
+ return id == FuId.INT_TRY_PARSE || id == FuId.LONG_TRY_PARSE || id == FuId.DOUBLE_TRY_PARSE;
+ }
+
+ visitIf(statement)
+ {
+ let not;
+ let call;
+ if (statement.onFalse == null && (not = statement.cond) instanceof FuPrefixExpr && not.op == FuToken.EXCLAMATION_MARK && (call = not.inner) instanceof FuCallExpr && GenJava.#isTryParse(call.method.symbol.id)) {
+ this.write("try ");
+ this.openBlock();
+ call.method.left.accept(this, FuPriority.ASSIGN);
+ this.write(" = ");
+ switch (call.method.symbol.id) {
+ case FuId.INT_TRY_PARSE:
+ this.write("Integer.parseInt");
+ break;
+ case FuId.LONG_TRY_PARSE:
+ this.write("Long.parseLong");
+ break;
+ case FuId.DOUBLE_TRY_PARSE:
+ this.write("Double.parseDouble");
+ break;
+ default:
+ throw new Error();
+ }
+ this.writeChar(40);
+ call.arguments_[0].accept(this, FuPriority.ARGUMENT);
+ if (call.arguments_.length == 2) {
+ this.write(", ");
+ call.arguments_[1].accept(this, FuPriority.ARGUMENT);
+ }
+ this.writeLine(");");
+ this.closeBlock();
+ this.write("catch (NumberFormatException e) ");
+ this.openBlock();
+ statement.onTrue.acceptStatement(this);
+ this.closeBlock();
+ }
+ else
+ super.visitIf(statement);
+ }
+
visitLock(statement)
{
this.writeCall("synchronized ", statement.lock);