This commit is contained in:
nub31
2025-10-20 18:31:43 +02:00
parent 6671fced57
commit 78441549c7
12 changed files with 313 additions and 724 deletions

View File

@@ -5,7 +5,6 @@ namespace NubLang.Syntax;
public sealed class Parser
{
private readonly HashSet<string> _templateArguments = [];
private List<Token> _tokens = [];
private int _tokenIndex;
private string _moduleName = string.Empty;
@@ -21,16 +20,7 @@ public sealed class Parser
_tokens = tokens;
_tokenIndex = 0;
_moduleName = string.Empty;
_templateArguments.Clear();
var metadata = ParseMetadata();
var definitions = ParseDefinitions();
return new SyntaxTree(definitions, metadata);
}
private SyntaxTreeMetadata ParseMetadata()
{
var imports = new List<string>();
try
@@ -57,11 +47,6 @@ public sealed class Parser
}
}
return new SyntaxTreeMetadata(_moduleName, imports);
}
private List<DefinitionSyntax> ParseDefinitions()
{
var definitions = new List<DefinitionSyntax>();
while (HasToken)
@@ -80,7 +65,7 @@ public sealed class Parser
}
var keyword = ExpectSymbol();
var definition = keyword.Symbol switch
DefinitionSyntax definition = keyword.Symbol switch
{
Symbol.Func => ParseFunc(startIndex, exported, null),
Symbol.Struct => ParseStruct(startIndex, exported),
@@ -108,12 +93,22 @@ public sealed class Parser
}
}
return definitions;
return new SyntaxTree(definitions, _moduleName, imports);
}
private FuncSignatureSyntax ParseFuncSignature()
private FuncParameterSyntax ParseFuncParameter()
{
var startIndex = _tokenIndex;
var name = ExpectIdentifier();
ExpectSymbol(Symbol.Colon);
var type = ParseType();
return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type);
}
private FuncSyntax ParseFunc(int startIndex, bool exported, string? externSymbol)
{
var name = ExpectIdentifier();
List<FuncParameterSyntax> parameters = [];
ExpectSymbol(Symbol.OpenParen);
@@ -131,23 +126,7 @@ public sealed class Parser
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax([]);
return new FuncSignatureSyntax(GetTokens(startIndex), parameters, returnType);
}
private FuncParameterSyntax ParseFuncParameter()
{
var startIndex = _tokenIndex;
var name = ExpectIdentifier();
ExpectSymbol(Symbol.Colon);
var type = ParseType();
return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type);
}
private FuncSyntax ParseFunc(int startIndex, bool exported, string? externSymbol)
{
var name = ExpectIdentifier();
var signature = ParseFuncSignature();
var prototype = new FuncPrototypeSyntax(GetTokens(startIndex), name.Value, exported, externSymbol, parameters, returnType);
BlockSyntax? body = null;
var bodyStartIndex = _tokenIndex;
@@ -156,64 +135,36 @@ public sealed class Parser
body = ParseBlock(bodyStartIndex);
}
return new FuncSyntax(GetTokens(startIndex), name.Value, exported, externSymbol, signature, body);
return new FuncSyntax(GetTokens(startIndex), prototype, body);
}
private DefinitionSyntax ParseStruct(int startIndex, bool exported)
private StructSyntax ParseStruct(int startIndex, bool exported)
{
var name = ExpectIdentifier();
if (TryExpectSymbol(Symbol.LessThan))
{
while (!TryExpectSymbol(Symbol.GreaterThan))
{
_templateArguments.Add(ExpectIdentifier().Value);
TryExpectSymbol(Symbol.Comma);
}
}
ExpectSymbol(Symbol.OpenBrace);
List<StructFieldSyntax> fields = [];
List<StructFuncSyntax> funcs = [];
while (!TryExpectSymbol(Symbol.CloseBrace))
{
var memberStartIndex = _tokenIndex;
if (TryExpectSymbol(Symbol.Func))
var fieldName = ExpectIdentifier().Value;
ExpectSymbol(Symbol.Colon);
var fieldType = ParseType();
ExpressionSyntax? fieldValue = null;
if (TryExpectSymbol(Symbol.Assign))
{
var funcName = ExpectIdentifier().Value;
var funcSignature = ParseFuncSignature();
var funcBody = ParseBlock();
funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody));
fieldValue = ParseExpression();
}
else
{
var fieldName = ExpectIdentifier().Value;
ExpectSymbol(Symbol.Colon);
var fieldType = ParseType();
ExpressionSyntax? fieldValue = null;
if (TryExpectSymbol(Symbol.Assign))
{
fieldValue = ParseExpression();
}
fields.Add(new StructFieldSyntax(GetTokens(memberStartIndex), fieldName, fieldType, fieldValue));
}
fields.Add(new StructFieldSyntax(GetTokens(memberStartIndex), fieldName, fieldType, fieldValue));
}
if (_templateArguments.Count > 0)
{
var templateArguments = _templateArguments.ToList();
_templateArguments.Clear();
return new StructTemplateSyntax(GetTokens(startIndex), templateArguments, name.Value, exported, fields, funcs);
}
return new StructSyntax(GetTokens(startIndex), name.Value, exported, fields, funcs);
return new StructSyntax(GetTokens(startIndex), name.Value, exported, fields);
}
private StatementSyntax ParseStatement()
@@ -543,24 +494,6 @@ public sealed class Parser
if (TryExpectSymbol(Symbol.Period))
{
var member = ExpectIdentifier().Value;
if (TryExpectSymbol(Symbol.OpenParen))
{
var parameters = new List<ExpressionSyntax>();
while (!TryExpectSymbol(Symbol.CloseParen))
{
parameters.Add(ParseExpression());
if (!TryExpectSymbol(Symbol.Comma))
{
ExpectSymbol(Symbol.CloseParen);
break;
}
}
expr = new MemberFuncCallSyntax(GetTokens(startIndex), member, expr, parameters);
continue;
}
expr = new MemberAccessSyntax(GetTokens(startIndex), expr, member);
continue;
}
@@ -672,11 +605,6 @@ public sealed class Parser
var startIndex = _tokenIndex;
if (TryExpectIdentifier(out var name))
{
if (_templateArguments.Contains(name.Value))
{
return new SubstitutionTypeSyntax(GetTokens(startIndex), name.Value);
}
if (name.Value[0] == 'u' && int.TryParse(name.Value[1..], out var size))
{
if (size is not 8 and not 16 and not 32 and not 64)
@@ -740,21 +668,6 @@ public sealed class Parser
name = customTypeName;
}
var templateParameters = new List<TypeSyntax>();
if (TryExpectSymbol(Symbol.LessThan))
{
while (!TryExpectSymbol(Symbol.GreaterThan))
{
templateParameters.Add(ParseType());
TryExpectSymbol(Symbol.Comma);
}
}
if (templateParameters.Count > 0)
{
return new StructTemplateTypeSyntax(GetTokens(startIndex), templateParameters, module, name.Value);
}
return new CustomTypeSyntax(GetTokens(startIndex), module, name.Value);
}
}
@@ -946,9 +859,7 @@ public sealed class Parser
}
}
public record SyntaxTreeMetadata(string ModuleName, List<string> Imports);
public record SyntaxTree(List<DefinitionSyntax> Definitions, SyntaxTreeMetadata Metadata);
public record SyntaxTree(List<DefinitionSyntax> Definitions, string ModuleName, List<string> Imports);
public class ParseException : Exception
{