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