directory scoped imports

This commit is contained in:
nub31
2025-01-29 20:51:38 +01:00
parent 0c807d765c
commit 88aa2375ef
10 changed files with 69 additions and 68 deletions

View File

@@ -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)
{

View File

@@ -8,7 +8,7 @@ public class SymbolToken(Symbol symbol) : Token
public enum Symbol
{
Whitespace,
Include,
Import,
Extern,
Func,
Return,

View File

@@ -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;
}

View 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;
}

View File

@@ -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();