This repository has been archived on 2025-10-23. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nub-lang-archive/src/lang/Nub.Lang/Frontend/Generation/SymbolTable.cs
2025-06-11 10:46:41 +02:00

109 lines
2.9 KiB
C#

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 && x.Namespace == @namespace);
}
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;
}
public class Struct(string @namespace, string name) : Symbol(name)
{
public string Namespace { get; } = @namespace;
public string GeneratedName => $"{Namespace}_{Name}";
}
}