Skip to content

Commit

Permalink
[exceptions] Emit doc for magic return values in C.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Nov 16, 2023
1 parent 4f2f014 commit a275c35
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 53 deletions.
5 changes: 5 additions & 0 deletions GenBase.fu
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ public abstract class GenBase : FuVisitor
}
}

protected virtual void WriteReturnDoc!(FuMethod method)
{
}

protected void WriteMethodDoc!(FuMethod method)
{
if (method.Documentation == null)
Expand All @@ -445,6 +449,7 @@ public abstract class GenBase : FuVisitor
WriteContent(method.Documentation);
WriteSelfDoc(method);
WriteParametersDoc(method);
WriteReturnDoc(method);
WriteLine(" */");
}

Expand Down
40 changes: 27 additions & 13 deletions GenC.fu
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ public class GenC : GenCCpp
WriteLine("</code>.");
}

protected override void WriteReturnDoc!(FuMethod method)
{
if (method.Throws.Count == 0)
return;
Write(" * @return <code>");
WriteThrowReturnValue(method.Type, false);
WriteLine("</code> on error.");
}

protected override void IncludeStdInt!()
{
Include("stdint.h");
Expand Down Expand Up @@ -1275,27 +1284,32 @@ public class GenC : GenCCpp
VisitLiteralLong(range.Min - 1);
}

void WriteThrowReturnValue!()
void WriteThrowReturnValue!(FuType type, bool include)
{
if (this.CurrentMethod.Type is FuNumericType) {
if (this.CurrentMethod.Type is FuRangeType range)
WriteRangeThrowReturnValue(range);
else {
switch (type.Id) {
case FuId.VoidType:
Write("false");
break;
case FuId.FloatType:
case FuId.DoubleType:
if (include)
IncludeMath();
Write("NAN");
}
Write("NAN");
break;
default:
if (type is FuRangeType range)
WriteRangeThrowReturnValue(range);
else
Write("NULL");
break;
}
else if (this.CurrentMethod.Type.Id == FuId.VoidType)
Write("false");
else
Write("NULL");
}

void WriteThrow!()
{
WriteDestructAll();
Write("return ");
WriteThrowReturnValue();
WriteThrowReturnValue(this.CurrentMethod.Type, true);
WriteCharLine(';');
}

Expand Down Expand Up @@ -2862,7 +2876,7 @@ public class GenC : GenCCpp
Write(" ? ");
returnValue.Accept(this, FuPriority.Select);
Write(" : ");
WriteThrowReturnValue();
WriteThrowReturnValue(this.CurrentMethod.Type, true);
}
WriteCharLine(';');
return true;
Expand Down
45 changes: 32 additions & 13 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6792,6 +6792,10 @@ void GenBase::writeParametersDoc(const FuMethod * method)
}
}

void GenBase::writeReturnDoc(const FuMethod * method)
{
}

void GenBase::writeMethodDoc(const FuMethod * method)
{
if (method->documentation == nullptr)
Expand All @@ -6800,6 +6804,7 @@ void GenBase::writeMethodDoc(const FuMethod * method)
writeContent(method->documentation.get());
writeSelfDoc(method);
writeParametersDoc(method);
writeReturnDoc(method);
writeLine(" */");
}

Expand Down Expand Up @@ -8990,6 +8995,15 @@ void GenC::writeSelfDoc(const FuMethod * method)
writeLine("</code>.");
}

void GenC::writeReturnDoc(const FuMethod * method)
{
if (std::ssize(method->throws) == 0)
return;
write(" * @return <code>");
writeThrowReturnValue(method->type.get(), false);
writeLine("</code> on error.");
}

void GenC::includeStdInt()
{
include("stdint.h");
Expand Down Expand Up @@ -10121,27 +10135,32 @@ void GenC::writeRangeThrowReturnValue(const FuRangeType * range)
visitLiteralLong(range->min - 1);
}

void GenC::writeThrowReturnValue()
void GenC::writeThrowReturnValue(const FuType * type, bool include)
{
if (dynamic_cast<const FuNumericType *>(this->currentMethod->type.get())) {
if (const FuRangeType *range = dynamic_cast<const FuRangeType *>(this->currentMethod->type.get()))
writeRangeThrowReturnValue(range);
else {
switch (type->id) {
case FuId::voidType:
write("false");
break;
case FuId::floatType:
case FuId::doubleType:
if (include)
includeMath();
write("NAN");
}
write("NAN");
break;
default:
if (const FuRangeType *range = dynamic_cast<const FuRangeType *>(type))
writeRangeThrowReturnValue(range);
else
write("NULL");
break;
}
else if (this->currentMethod->type->id == FuId::voidType)
write("false");
else
write("NULL");
}

void GenC::writeThrow()
{
writeDestructAll();
write("return ");
writeThrowReturnValue();
writeThrowReturnValue(this->currentMethod->type.get(), true);
writeCharLine(';');
}

Expand Down Expand Up @@ -11725,7 +11744,7 @@ bool GenC::tryWriteCallAndReturn(const std::vector<std::shared_ptr<FuStatement>>
write(" ? ");
returnValue->accept(this, FuPriority::select);
write(" : ");
writeThrowReturnValue();
writeThrowReturnValue(this->currentMethod->type.get(), true);
}
writeCharLine(';');
return true;
Expand Down
45 changes: 32 additions & 13 deletions libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6956,6 +6956,10 @@ protected void WriteParametersDoc(FuMethod method)
}
}

protected virtual void WriteReturnDoc(FuMethod method)
{
}

protected void WriteMethodDoc(FuMethod method)
{
if (method.Documentation == null)
Expand All @@ -6964,6 +6968,7 @@ protected void WriteMethodDoc(FuMethod method)
WriteContent(method.Documentation);
WriteSelfDoc(method);
WriteParametersDoc(method);
WriteReturnDoc(method);
WriteLine(" */");
}

Expand Down Expand Up @@ -9208,6 +9213,15 @@ protected override void WriteSelfDoc(FuMethod method)
WriteLine("</code>.");
}

protected override void WriteReturnDoc(FuMethod method)
{
if (method.Throws.Count == 0)
return;
Write(" * @return <code>");
WriteThrowReturnValue(method.Type, false);
WriteLine("</code> on error.");
}

protected override void IncludeStdInt()
{
Include("stdint.h");
Expand Down Expand Up @@ -10404,27 +10418,32 @@ void WriteRangeThrowReturnValue(FuRangeType range)
VisitLiteralLong(range.Min - 1);
}

void WriteThrowReturnValue()
void WriteThrowReturnValue(FuType type, bool include)
{
if (this.CurrentMethod.Type is FuNumericType) {
if (this.CurrentMethod.Type is FuRangeType range)
WriteRangeThrowReturnValue(range);
else {
switch (type.Id) {
case FuId.VoidType:
Write("false");
break;
case FuId.FloatType:
case FuId.DoubleType:
if (include)
IncludeMath();
Write("NAN");
}
Write("NAN");
break;
default:
if (type is FuRangeType range)
WriteRangeThrowReturnValue(range);
else
Write("NULL");
break;
}
else if (this.CurrentMethod.Type.Id == FuId.VoidType)
Write("false");
else
Write("NULL");
}

void WriteThrow()
{
WriteDestructAll();
Write("return ");
WriteThrowReturnValue();
WriteThrowReturnValue(this.CurrentMethod.Type, true);
WriteCharLine(';');
}

Expand Down Expand Up @@ -11976,7 +11995,7 @@ bool TryWriteCallAndReturn(List<FuStatement> statements, int lastCallIndex, FuEx
Write(" ? ");
returnValue.Accept(this, FuPriority.Select);
Write(" : ");
WriteThrowReturnValue();
WriteThrowReturnValue(this.CurrentMethod.Type, true);
}
WriteCharLine(';');
return true;
Expand Down
4 changes: 3 additions & 1 deletion libfut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,7 @@ class GenBase : public FuVisitor
virtual void writeSelfDoc(const FuMethod * method);
virtual void writeParameterDoc(const FuVar * param, bool first);
void writeParametersDoc(const FuMethod * method);
virtual void writeReturnDoc(const FuMethod * method);
void writeMethodDoc(const FuMethod * method);
void writeTopLevelNatives(const FuProgram * program);
void openBlock();
Expand Down Expand Up @@ -2010,6 +2011,7 @@ class GenC : public GenCCpp
const FuContainerType * getCurrentContainer() const override;
std::string_view getTargetName() const override;
void writeSelfDoc(const FuMethod * method) override;
void writeReturnDoc(const FuMethod * method) override;
void includeStdInt() override;
void includeAssert() override;
void includeMath() override;
Expand Down Expand Up @@ -2146,7 +2148,7 @@ class GenC : public GenCCpp
void writeDestruct(const FuSymbol * symbol);
void writeDestructAll(const FuVar * exceptVar = nullptr);
void writeRangeThrowReturnValue(const FuRangeType * range);
void writeThrowReturnValue();
void writeThrowReturnValue(const FuType * type, bool include);
void writeThrow();
void endForwardThrow(const FuMethod * throwingMethod);
void writeMemberAccess(const FuType * leftType, const FuSymbol * symbolClass);
Expand Down
45 changes: 32 additions & 13 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -7251,6 +7251,10 @@ export class GenBase extends FuVisitor
}
}

writeReturnDoc(method)
{
}

writeMethodDoc(method)
{
if (method.documentation == null)
Expand All @@ -7259,6 +7263,7 @@ export class GenBase extends FuVisitor
this.writeContent(method.documentation);
this.writeSelfDoc(method);
this.writeParametersDoc(method);
this.writeReturnDoc(method);
this.writeLine(" */");
}

Expand Down Expand Up @@ -9550,6 +9555,15 @@ export class GenC extends GenCCpp
this.writeLine("</code>.");
}

writeReturnDoc(method)
{
if (method.throws.length == 0)
return;
this.write(" * @return <code>");
this.#writeThrowReturnValue(method.type, false);
this.writeLine("</code> on error.");
}

includeStdInt()
{
this.include("stdint.h");
Expand Down Expand Up @@ -10782,28 +10796,33 @@ export class GenC extends GenCCpp
this.visitLiteralLong(BigInt(range.min - 1));
}

#writeThrowReturnValue()
#writeThrowReturnValue(type, include)
{
if (this.currentMethod.type instanceof FuNumericType) {
switch (type.id) {
case FuId.VOID_TYPE:
this.write("false");
break;
case FuId.FLOAT_TYPE:
case FuId.DOUBLE_TYPE:
if (include)
this.includeMath();
this.write("NAN");
break;
default:
let range;
if ((range = this.currentMethod.type) instanceof FuRangeType)
if ((range = type) instanceof FuRangeType)
this.#writeRangeThrowReturnValue(range);
else {
this.includeMath();
this.write("NAN");
}
else
this.write("NULL");
break;
}
else if (this.currentMethod.type.id == FuId.VOID_TYPE)
this.write("false");
else
this.write("NULL");
}

#writeThrow()
{
this.#writeDestructAll();
this.write("return ");
this.#writeThrowReturnValue();
this.#writeThrowReturnValue(this.currentMethod.type, true);
this.writeCharLine(59);
}

Expand Down Expand Up @@ -12386,7 +12405,7 @@ export class GenC extends GenCCpp
this.write(" ? ");
returnValue.accept(this, FuPriority.SELECT);
this.write(" : ");
this.#writeThrowReturnValue();
this.#writeThrowReturnValue(this.currentMethod.type, true);
}
this.writeCharLine(59);
return true;
Expand Down

0 comments on commit a275c35

Please sign in to comment.