This commit is contained in:
nub31
2025-06-10 17:49:44 +02:00
parent d10c2e3b3a
commit 722e1ff6ba
5 changed files with 167 additions and 85 deletions

View File

@@ -0,0 +1,103 @@
using Nub.Lang.Frontend.Parsing.Definitions;
namespace Nub.Lang.Frontend.Generation;
public class SymbolTable
{
private readonly List<Func> _functions = [];
private readonly Stack<Variable> _variables = [];
private readonly Stack<int> _scopes = [];
public SymbolTable(IEnumerable<IFuncSignature> functions)
{
foreach (var func in functions)
{
string name;
switch (func)
{
case ExternFuncDefinitionNode externFuncDefinitionNode:
{
name = "$" + externFuncDefinitionNode.CallName;
break;
}
case LocalFuncDefinitionNode localFuncDefinitionNode:
{
if (localFuncDefinitionNode.Exported)
{
name = "$" + localFuncDefinitionNode.Name;
}
else
{
name = "$" + localFuncDefinitionNode.Namespace + "_" + localFuncDefinitionNode.Name;
}
break;
}
default:
{
throw new ArgumentOutOfRangeException(nameof(func));
}
}
_functions.Add(new Func(func.Namespace, func.Name, name));
}
}
public void Reset()
{
_variables.Clear();
}
public void StartScope()
{
_scopes.Push(_variables.Count);
}
public void EndScope()
{
var count = _scopes.Pop();
while (count > _variables.Count)
{
_variables.Pop();
}
}
public Symbol Lookup(string? @namespace, string name)
{
if (@namespace == null)
{
return LookupVariable(name);
}
return LookupFunc(@namespace, name);
}
public Func LookupFunc(string @namespace, string name)
{
return _functions.Single(x => x.Name == name);
}
public Variable LookupVariable(string name)
{
return _variables.Single(x => x.Name == name);
}
public void DeclareVariable(string name, string pointer)
{
_variables.Push(new Variable(name, pointer));
}
public abstract class Symbol(string name)
{
public string Name { get; } = name;
}
public class Variable(string name, string pointer) : Symbol(name)
{
public string Pointer { get; set; } = pointer;
}
public class Func(string @namespace, string name, string generatedName) : Symbol(name)
{
public string Namespace { get; } = @namespace;
public string GeneratedName { get; } = generatedName;
}
}