Skip to content

Commit

Permalink
fix: not being able to call function within itself
Browse files Browse the repository at this point in the history
fixes #5
  • Loading branch information
R-unic committed Jan 14, 2025
1 parent 0b91d7c commit 37f6807
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 23 deletions.
36 changes: 29 additions & 7 deletions Heir/Binder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,27 @@ public BoundStatement VisitFunctionDeclaration(FunctionDeclaration functionDecla
var parameterTypePairs = boundParameters.ConvertAll(parameter =>
new KeyValuePair<string, BaseType>(parameter.Symbol.Name.Text, parameter.Type));

var boundBody = (BoundBlock)Bind(functionDeclaration.Body);
var type = new FunctionType(
new Dictionary<string, BaseType>(parameterTypePairs),
var parameterTypes = new Dictionary<string, BaseType>(parameterTypePairs);
var placeholderType = new FunctionType(
parameterTypes,
functionDeclaration.ReturnType != null
? BaseType.FromTypeRef(functionDeclaration.ReturnType)
: boundBody.Type
: new AnyType()
);

var symbol = DefineSymbol(functionDeclaration.Name.Token, type, false);
var placeholderSymbol = DefineSymbol<BaseType>(functionDeclaration.Name.Token, placeholderType, false);
var boundBody = (BoundBlock)Bind(functionDeclaration.Body);
var returnType = functionDeclaration.ReturnType != null
? BaseType.FromTypeRef(functionDeclaration.ReturnType)
: boundBody.Type;

var finalType = new FunctionType(
new Dictionary<string, BaseType>(parameterTypePairs),
returnType
);

UndefineSymbol(placeholderSymbol);
var symbol = DefineSymbol(functionDeclaration.Name.Token, finalType, false);
return new BoundFunctionDeclaration(functionDeclaration.Keyword, symbol, boundParameters, boundBody);
}

Expand Down Expand Up @@ -220,6 +232,16 @@ private VariableSymbol<TType> DefineSymbol<TType>(Token name, TType type, bool i
return symbol;
}

private void UndefineSymbol(VariableSymbol<BaseType> variableSymbol)
{
if (!_variableScopes.TryPop(out var scope)) return;

var newScope = scope.ToList();
newScope.Remove(variableSymbol);
_variableScopes.Push(new Stack<VariableSymbol<BaseType>>(newScope));
}


private void BeginScope() => _variableScopes.Push([]);
private Stack<VariableSymbol<BaseType>> EndScope() => _variableScopes.Pop();

Expand Down Expand Up @@ -251,14 +273,14 @@ private BoundSyntaxNode Bind(SyntaxNode node)
private BoundStatement Bind(Statement statement)
{
var boundStatement = statement.Accept(this);
_boundNodes.Add(statement, boundStatement);
_boundNodes.TryAdd(statement, boundStatement);
return boundStatement;
}

private BoundExpression Bind(Expression expression)
{
var boundExpression = expression.Accept(this);
_boundNodes.Add(expression, boundExpression);
_boundNodes.TryAdd(expression, boundExpression);
return boundExpression;
}
}
4 changes: 4 additions & 0 deletions Heir/Heir.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@
<PackageReference Include="Spectre.Console" Version="0.49.1" />
</ItemGroup>

<ItemGroup>
<Folder Include="Runtime\Intrinsics\" />
</ItemGroup>

</Project>
12 changes: 6 additions & 6 deletions Heir/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
var testFile = SourceFile.FromPath("./Test.heir", isMainFile: true);
// Console.WriteLine(testFile.Tokenize().WithoutTrivia().ToString());
// Console.WriteLine();
var syntaxTree = testFile.Parse();
syntaxTree.Display();
Console.WriteLine();
// var syntaxTree = testFile.Parse();
// syntaxTree.Display();
// Console.WriteLine();
// testFile.Bind().GetBoundNode(syntaxTree).Display();
//Console.WriteLine();
//Console.WriteLine(testFile.GenerateBytecode().ToString());
//Console.WriteLine();
// Console.WriteLine();
// Console.WriteLine(testFile.GenerateBytecode().ToString());
// Console.WriteLine();
program.LoadFile(testFile);

var result = program.Evaluate();
Expand Down
14 changes: 10 additions & 4 deletions Heir/SourceFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,17 @@ public static SourceFile FromPath(string path, bool isMainFile = false)
return (null, vm);
}

var value = vm.Evaluate();
if (Diagnostics.Count <= 0)
return (IsMainFile ? value : null, vm);
try
{
var value = vm.Evaluate();
if (Diagnostics.Count <= 0)
return (IsMainFile ? value : null, vm);
}
catch (Exception e)

Check warning on line 50 in Heir/SourceFile.cs

View workflow job for this annotation

GitHub Actions / test

The variable 'e' is declared but never used
{
WriteDiagnostics();
}

WriteDiagnostics();
return (null, vm);
}

Expand Down
8 changes: 4 additions & 4 deletions Heir/VirtualMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public sealed class VirtualMachine
public Scope Scope { get; private set; }
public int RecursionDepth { get; private set; }

private const int _maxRecursionDepth = 1000;
private const int _maxRecursionDepth = 300; // can only handle about this much for now 💀
private readonly Stack<StackFrame> _stack = [];
private readonly Bytecode _bytecode;
private Scope _enclosingScope;
Expand Down Expand Up @@ -61,9 +61,9 @@ public VirtualMachine(Bytecode bytecode, Scope? scope = null, int recursionDepth
public void EndRecursion(int level = 1) => RecursionDepth -= level;
public void BeginRecursion(Token token)
{
RecursionDepth++;
if (RecursionDepth < _maxRecursionDepth) return;
Diagnostics.Error(DiagnosticCode.H017, $"Stack overflow: Recursion depth of ${_maxRecursionDepth} exceeded", token);
if (RecursionDepth++ < _maxRecursionDepth) return;
Diagnostics.Error(DiagnosticCode.H017, $"Stack overflow: Recursion depth of {_maxRecursionDepth} exceeded", token);
throw new Exception();
}

private StackFrame? EvaluateInstruction(Instruction instruction)
Expand Down
3 changes: 1 addition & 2 deletions Test.heir
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
let mut i = 0;
fn abc {
return;
abc();
}

abc();

0 comments on commit 37f6807

Please sign in to comment.