modifiers
This commit is contained in:
@@ -5,8 +5,6 @@ public class Lexer
|
||||
private static readonly Dictionary<string, Symbol> Keywords = new()
|
||||
{
|
||||
["func"] = Symbol.Func,
|
||||
["global"] = Symbol.Global,
|
||||
["extern"] = Symbol.Extern,
|
||||
["import"] = Symbol.Import,
|
||||
["if"] = Symbol.If,
|
||||
["else"] = Symbol.Else,
|
||||
@@ -18,6 +16,12 @@ public class Lexer
|
||||
["struct"] = Symbol.Struct,
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, Modifier> Modifers = new()
|
||||
{
|
||||
["global"] = Modifier.Global,
|
||||
["extern"] = Modifier.Extern,
|
||||
};
|
||||
|
||||
private static readonly Dictionary<char[], Symbol> Chians = new()
|
||||
{
|
||||
[['=', '=']] = Symbol.Equal,
|
||||
@@ -84,6 +88,11 @@ public class Lexer
|
||||
return new SymbolToken(keywordSymbol);
|
||||
}
|
||||
|
||||
if (Modifers.TryGetValue(buffer, out var modifer))
|
||||
{
|
||||
return new ModifierToken(modifer);
|
||||
}
|
||||
|
||||
if (buffer is "true" or "false")
|
||||
{
|
||||
return new LiteralToken(NubPrimitiveType.Bool, buffer);
|
||||
|
||||
12
src/compiler/Nub.Lang/Frontend/Lexing/ModifierToken.cs
Normal file
12
src/compiler/Nub.Lang/Frontend/Lexing/ModifierToken.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Nub.Lang.Frontend.Lexing;
|
||||
|
||||
public class ModifierToken(Modifier symbol) : Token
|
||||
{
|
||||
public Modifier Modifier { get; } = symbol;
|
||||
}
|
||||
|
||||
public enum Modifier
|
||||
{
|
||||
Extern,
|
||||
Global
|
||||
}
|
||||
@@ -9,8 +9,6 @@ public enum Symbol
|
||||
{
|
||||
Whitespace,
|
||||
Import,
|
||||
Extern,
|
||||
Global,
|
||||
Func,
|
||||
Return,
|
||||
If,
|
||||
|
||||
@@ -35,18 +35,23 @@ public class Parser
|
||||
|
||||
private DefinitionNode ParseDefinition()
|
||||
{
|
||||
List<Modifier> modifiers = [];
|
||||
|
||||
while (TryExpectModifier(out var modifier))
|
||||
{
|
||||
modifiers.Add(modifier);
|
||||
}
|
||||
|
||||
var keyword = ExpectSymbol();
|
||||
return keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseFuncDefinition(),
|
||||
Symbol.Global => ParseGlobalFuncDefinition(),
|
||||
Symbol.Extern => ParseExternFuncDefinition(),
|
||||
Symbol.Struct => ParseStruct(),
|
||||
Symbol.Func => ParseFuncDefinition(modifiers),
|
||||
Symbol.Struct => ParseStruct(modifiers),
|
||||
_ => throw new Exception("Unexpected symbol: " + keyword.Symbol)
|
||||
};
|
||||
}
|
||||
|
||||
private LocalFuncDefinitionNode ParseFuncDefinition()
|
||||
private DefinitionNode ParseFuncDefinition(List<Modifier> modifiers)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameter> parameters = [];
|
||||
@@ -66,64 +71,27 @@ public class Parser
|
||||
returnType = ParseType();
|
||||
}
|
||||
|
||||
if (modifiers.Remove(Modifier.Extern))
|
||||
{
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new Exception($"Modifiers: {string.Join(", ", modifiers)} is not valid for an extern function");
|
||||
}
|
||||
ExpectSymbol(Symbol.Semicolon);
|
||||
return new ExternFuncDefinitionNode(name.Value, parameters, returnType);
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
var global = modifiers.Remove(Modifier.Global);
|
||||
|
||||
return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType, false);
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new Exception($"Modifiers: {string.Join(", ", modifiers)} is not valid for a local function");
|
||||
}
|
||||
return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType, global);
|
||||
}
|
||||
|
||||
private LocalFuncDefinitionNode ParseGlobalFuncDefinition()
|
||||
{
|
||||
ExpectSymbol(Symbol.Func);
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameter> parameters = [];
|
||||
ExpectSymbol(Symbol.OpenParen);
|
||||
if (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
parameters.Add(ParseFuncParameter());
|
||||
TryExpectSymbol(Symbol.Comma);
|
||||
}
|
||||
}
|
||||
|
||||
var returnType = Optional<NubType>.Empty();
|
||||
if (TryExpectSymbol(Symbol.Colon))
|
||||
{
|
||||
returnType = ParseType();
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
|
||||
return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType, true);
|
||||
}
|
||||
|
||||
private ExternFuncDefinitionNode ParseExternFuncDefinition()
|
||||
{
|
||||
ExpectSymbol(Symbol.Func);
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameter> parameters = [];
|
||||
ExpectSymbol(Symbol.OpenParen);
|
||||
if (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
parameters.Add(ParseFuncParameter());
|
||||
TryExpectSymbol(Symbol.Comma);
|
||||
}
|
||||
}
|
||||
|
||||
var returnType = Optional<NubType>.Empty();
|
||||
if (TryExpectSymbol(Symbol.Colon))
|
||||
{
|
||||
returnType = ParseType();
|
||||
}
|
||||
|
||||
ExpectSymbol(Symbol.Semicolon);
|
||||
|
||||
return new ExternFuncDefinitionNode(name.Value, parameters, returnType);
|
||||
}
|
||||
|
||||
private StructDefinitionNode ParseStruct()
|
||||
private StructDefinitionNode ParseStruct(List<Modifier> modifiers)
|
||||
{
|
||||
var name = ExpectIdentifier().Value;
|
||||
|
||||
@@ -503,6 +471,19 @@ public class Parser
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool TryExpectModifier(out Modifier modifier)
|
||||
{
|
||||
if (Peek() is { HasValue: true, Value: ModifierToken modifierToken })
|
||||
{
|
||||
modifier = modifierToken.Modifier;
|
||||
Next();
|
||||
return true;
|
||||
}
|
||||
|
||||
modifier = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private IdentifierToken ExpectIdentifier()
|
||||
{
|
||||
var token = ExpectToken();
|
||||
|
||||
Reference in New Issue
Block a user