Skip to content

Commit

Permalink
[java] if (!number.TryParse(str)).
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Feb 28, 2024
1 parent fdadd22 commit f9cbcd8
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 0 deletions.
41 changes: 41 additions & 0 deletions GenJava.fu
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
44 changes: 44 additions & 0 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
39 changes: 39 additions & 0 deletions libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19080,6 +19080,45 @@ internal override void VisitForeach(FuForeach statement)
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);
Expand Down
2 changes: 2 additions & 0 deletions libfut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2521,6 +2521,7 @@ class GenJava : public GenTyped
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;
Expand All @@ -2540,6 +2541,7 @@ class GenJava : public GenTyped
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);
Expand Down
44 changes: 44 additions & 0 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit f9cbcd8

Please sign in to comment.