...
This commit is contained in:
103
src/lang/Nub.Lang/Frontend/Generation/SymbolTable.cs
Normal file
103
src/lang/Nub.Lang/Frontend/Generation/SymbolTable.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user