Skip to content

Commit

Permalink
[ctfe] Fix forward-referenced methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Mar 25, 2024
1 parent d615551 commit c83b061
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 6 deletions.
2 changes: 1 addition & 1 deletion AST.fu
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ public class FuMethodBase : FuMember
{
internal FuParameters() Parameters;
internal List<FuThrowsDeclaration#>() Throws;
internal FuStatement#? Body;
internal FuScope#? Body;
internal bool IsLive = false;
internal HashSet<FuMethod!>() Calls;
public override bool IsStatic() => false; // constructor
Expand Down
6 changes: 5 additions & 1 deletion Sema.fu
Original file line number Diff line number Diff line change
Expand Up @@ -1357,7 +1357,7 @@ public class FuSema
symbol.Symbol = method;

if (method.CallType == FuCallType.Static
&& method.Body is FuReturn ret
&& method.Body is FuReturn! ret
&& arguments.All(arg => arg is FuLiteral)
&& !this.CurrentPureMethods.Contains(method)) {
this.CurrentPureMethods.Add(method);
Expand All @@ -1368,7 +1368,11 @@ public class FuSema
else
this.CurrentPureArguments[param] = param.Value;
}
FuScope! callSite = this.CurrentScope;
ret.Parent = method.Parameters;
this.CurrentScope = ret;
FuExpr# result = VisitExpr(ret.Value);
this.CurrentScope = callSite;
for (FuVar? param = method.FirstParameter(); param != null; param = param.NextVar())
this.CurrentPureArguments.Remove(param);
this.CurrentPureMethods.Remove(method);
Expand Down
8 changes: 6 additions & 2 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5730,8 +5730,8 @@ std::shared_ptr<FuExpr> FuSema::resolveCallWithArguments(std::shared_ptr<FuCallE
reportError(expr.get(), std::format("Method marked 'throws {}' called from a method without it", exception->name));
}
symbol->symbol = method;
const FuReturn * ret;
if (method->callType == FuCallType::static_ && (ret = dynamic_cast<const FuReturn *>(method->body.get())) && std::all_of(arguments->begin(), arguments->end(), [](const std::shared_ptr<FuExpr> &arg) { return dynamic_cast<const FuLiteral *>(arg.get()); }) && !this->currentPureMethods.contains(method)) {
FuReturn * ret;
if (method->callType == FuCallType::static_ && (ret = dynamic_cast<FuReturn *>(method->body.get())) && std::all_of(arguments->begin(), arguments->end(), [](const std::shared_ptr<FuExpr> &arg) { return dynamic_cast<const FuLiteral *>(arg.get()); }) && !this->currentPureMethods.contains(method)) {
this->currentPureMethods.insert(method);
i = 0;
for (const FuVar * param = method->firstParameter(); param != nullptr; param = param->nextVar()) {
Expand All @@ -5740,7 +5740,11 @@ std::shared_ptr<FuExpr> FuSema::resolveCallWithArguments(std::shared_ptr<FuCallE
else
this->currentPureArguments[param] = param->value;
}
FuScope * callSite = this->currentScope;
ret->parent = &method->parameters;
this->currentScope = ret;
std::shared_ptr<FuExpr> result = visitExpr(ret->value);
this->currentScope = callSite;
for (const FuVar * param = method->firstParameter(); param != nullptr; param = param->nextVar())
this->currentPureArguments.erase(param);
this->currentPureMethods.erase(method);
Expand Down
6 changes: 5 additions & 1 deletion libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2738,7 +2738,7 @@ public class FuMethodBase : FuMember

internal readonly List<FuThrowsDeclaration> Throws = new List<FuThrowsDeclaration>();

internal FuStatement Body;
internal FuScope Body;

internal bool IsLive = false;

Expand Down Expand Up @@ -5852,7 +5852,11 @@ FuExpr ResolveCallWithArguments(FuCallExpr expr, List<FuExpr> arguments)
else
this.CurrentPureArguments[param] = param.Value;
}
FuScope callSite = this.CurrentScope;
ret.Parent = method.Parameters;
this.CurrentScope = ret;
FuExpr result = VisitExpr(ret.Value);
this.CurrentScope = callSite;
for (FuVar param = method.FirstParameter(); param != null; param = param.NextVar())
this.CurrentPureArguments.Remove(param);
this.CurrentPureMethods.Remove(method);
Expand Down
2 changes: 1 addition & 1 deletion libfut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,7 @@ class FuMethodBase : public FuMember
public:
FuParameters parameters;
std::vector<std::shared_ptr<FuThrowsDeclaration>> throws;
std::shared_ptr<FuStatement> body;
std::shared_ptr<FuScope> body;
bool isLive = false;
std::unordered_set<FuMethod *> calls;
};
Expand Down
4 changes: 4 additions & 0 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -6153,7 +6153,11 @@ export class FuSema
else
this.#currentPureArguments[param] = param.value;
}
let callSite = this.#currentScope;
ret.parent = method.parameters;
this.#currentScope = ret;
let result = this.#visitExpr(ret.value);
this.#currentScope = callSite;
for (let param = method.firstParameter(); param != null; param = param.nextVar())
delete this.#currentPureArguments[param];
this.#currentPureMethods.delete(method);
Expand Down
9 changes: 9 additions & 0 deletions test/ConstForwardMethod.fu
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public static class Test
{
public static bool Run()
{
return Foo(42);
}

static bool Foo(int answer) => answer == 42;
}

0 comments on commit c83b061

Please sign in to comment.