directory scoped imports
This commit is contained in:
@@ -9,7 +9,7 @@ public class Lexer
|
||||
["func"] = Symbol.Func,
|
||||
["extern"] = Symbol.Extern,
|
||||
["return"] = Symbol.Return,
|
||||
["include"] = Symbol.Include,
|
||||
["import"] = Symbol.Import,
|
||||
["let"] = Symbol.Let,
|
||||
["if"] = Symbol.If,
|
||||
["else"] = Symbol.Else,
|
||||
@@ -45,17 +45,14 @@ public class Lexer
|
||||
['!'] = Symbol.Bang,
|
||||
};
|
||||
|
||||
private readonly string _src;
|
||||
private string _src = string.Empty;
|
||||
private int _index;
|
||||
|
||||
public Lexer(string src)
|
||||
public IReadOnlyCollection<Token> Lex(string src)
|
||||
{
|
||||
_src = src;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<Token> Lex()
|
||||
{
|
||||
_index = 0;
|
||||
|
||||
List<Token> tokens = [];
|
||||
while (Peek().HasValue)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ public class SymbolToken(Symbol symbol) : Token
|
||||
public enum Symbol
|
||||
{
|
||||
Whitespace,
|
||||
Include,
|
||||
Import,
|
||||
Extern,
|
||||
Func,
|
||||
Return,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Nub.Lang.Frontend.Parsing;
|
||||
|
||||
public class FileNode(IReadOnlyCollection<string> includes, IReadOnlyCollection<DefinitionNode> definitions) : Node
|
||||
{
|
||||
public IReadOnlyCollection<string> Includes { get; } = includes;
|
||||
public IReadOnlyCollection<DefinitionNode> Definitions { get; } = definitions;
|
||||
}
|
||||
8
Nub.Lang/Nub.Lang/Frontend/Parsing/ModuleNode.cs
Normal file
8
Nub.Lang/Nub.Lang/Frontend/Parsing/ModuleNode.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Nub.Lang.Frontend.Parsing;
|
||||
|
||||
public class ModuleNode(string path, IReadOnlyCollection<string> imports, IReadOnlyCollection<DefinitionNode> definitions) : Node
|
||||
{
|
||||
public string Path { get; } = path;
|
||||
public IReadOnlyCollection<string> Imports { get; } = imports;
|
||||
public IReadOnlyCollection<DefinitionNode> Definitions { get; } = definitions;
|
||||
}
|
||||
@@ -6,38 +6,37 @@ namespace Nub.Lang.Frontend.Parsing;
|
||||
|
||||
public class Parser
|
||||
{
|
||||
private readonly Token[] _tokens;
|
||||
private IReadOnlyCollection<Token> _tokens = [];
|
||||
private int _index;
|
||||
|
||||
public Parser(IReadOnlyCollection<Token> tokens)
|
||||
{
|
||||
_tokens = tokens.ToArray();
|
||||
}
|
||||
|
||||
public FileNode ParseFile(string relativePath)
|
||||
|
||||
public ModuleNode ParseModule(IReadOnlyCollection<Token> tokens, string path)
|
||||
{
|
||||
_index = 0;
|
||||
_tokens = tokens;
|
||||
|
||||
List<DefinitionNode> definitions = [];
|
||||
List<string> includes = [];
|
||||
|
||||
while (TryExpectSymbol(Symbol.Include))
|
||||
{
|
||||
var name = ExpectLiteral();
|
||||
if (name.Type is not StringType)
|
||||
{
|
||||
throw new Exception("Using statements must have a string literal value");
|
||||
}
|
||||
|
||||
TryExpectSymbol(Symbol.Semicolon);
|
||||
includes.Add(name.Value);
|
||||
}
|
||||
List<string> imports = [];
|
||||
|
||||
while (Peek().HasValue)
|
||||
{
|
||||
definitions.Add(ParseDefinition());
|
||||
if (TryExpectSymbol(Symbol.Import))
|
||||
{
|
||||
var name = ExpectLiteral();
|
||||
if (name.Type is not StringType)
|
||||
{
|
||||
throw new Exception("Import statements must have a string literal value");
|
||||
}
|
||||
|
||||
TryExpectSymbol(Symbol.Semicolon);
|
||||
imports.Add(name.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
definitions.Add(ParseDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
return new FileNode(includes, definitions);
|
||||
return new ModuleNode(path, imports, definitions);
|
||||
}
|
||||
|
||||
private DefinitionNode ParseDefinition()
|
||||
@@ -450,14 +449,14 @@ public class Parser
|
||||
|
||||
private Optional<Token> Peek()
|
||||
{
|
||||
while (_index < _tokens.Length && _tokens[_index] is SymbolToken { Symbol: Symbol.Whitespace })
|
||||
while (_index < _tokens.Count && _tokens.ElementAt(_index) is SymbolToken { Symbol: Symbol.Whitespace })
|
||||
{
|
||||
Next();
|
||||
}
|
||||
|
||||
if (_index < _tokens.Length)
|
||||
if (_index < _tokens.Count)
|
||||
{
|
||||
return _tokens[_index];
|
||||
return _tokens.ElementAt(_index);
|
||||
}
|
||||
|
||||
return Optional<Token>.Empty();
|
||||
|
||||
Reference in New Issue
Block a user