namespace
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
module c_interop
|
namespace c
|
||||||
|
|
||||||
extern func printf(fmt: string, ...args: any)
|
extern func printf(fmt: string, ...args: any)
|
||||||
extern func getchar(): i32
|
extern func getchar(): i32
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import c_interop
|
namespace main
|
||||||
|
|
||||||
module main
|
|
||||||
|
|
||||||
/// # Documentation
|
/// # Documentation
|
||||||
/// ## Documentation subtitle
|
/// ## Documentation subtitle
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ public class Lexer
|
|||||||
{
|
{
|
||||||
private static readonly Dictionary<string, Symbol> Keywords = new()
|
private static readonly Dictionary<string, Symbol> Keywords = new()
|
||||||
{
|
{
|
||||||
|
["namespace"] = Symbol.Namespace,
|
||||||
["func"] = Symbol.Func,
|
["func"] = Symbol.Func,
|
||||||
["import"] = Symbol.Import,
|
|
||||||
["module"] = Symbol.Module,
|
|
||||||
["if"] = Symbol.If,
|
["if"] = Symbol.If,
|
||||||
["else"] = Symbol.Else,
|
["else"] = Symbol.Else,
|
||||||
["while"] = Symbol.While,
|
["while"] = Symbol.While,
|
||||||
@@ -31,6 +30,7 @@ public class Lexer
|
|||||||
[['!', '=']] = Symbol.NotEqual,
|
[['!', '=']] = Symbol.NotEqual,
|
||||||
[['<', '=']] = Symbol.LessThanOrEqual,
|
[['<', '=']] = Symbol.LessThanOrEqual,
|
||||||
[['>', '=']] = Symbol.GreaterThanOrEqual,
|
[['>', '=']] = Symbol.GreaterThanOrEqual,
|
||||||
|
[[':', ':']] = Symbol.DoubleColon,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<char, Symbol> Chars = new()
|
private static readonly Dictionary<char, Symbol> Chars = new()
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ public class SymbolToken(SourceText sourceText, int startIndex, int endIndex, Sy
|
|||||||
|
|
||||||
public enum Symbol
|
public enum Symbol
|
||||||
{
|
{
|
||||||
Import,
|
|
||||||
Module,
|
|
||||||
Func,
|
Func,
|
||||||
Return,
|
Return,
|
||||||
If,
|
If,
|
||||||
@@ -44,4 +42,6 @@ public enum Symbol
|
|||||||
Struct,
|
Struct,
|
||||||
Caret,
|
Caret,
|
||||||
Ampersand,
|
Ampersand,
|
||||||
|
DoubleColon,
|
||||||
|
Namespace,
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
namespace Nub.Lang.Frontend.Parsing;
|
namespace Nub.Lang.Frontend.Parsing;
|
||||||
|
|
||||||
public class FuncCall(string name, List<ExpressionNode> parameters)
|
public class FuncCall(string @namespace, string name, List<ExpressionNode> parameters)
|
||||||
{
|
{
|
||||||
|
public string Namespace { get; } = @namespace;
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
public List<ExpressionNode> Parameters { get; } = parameters;
|
public List<ExpressionNode> Parameters { get; } = parameters;
|
||||||
|
|
||||||
|
|||||||
@@ -9,24 +9,19 @@ public class Parser
|
|||||||
private List<Diagnostic> _diagnostics = [];
|
private List<Diagnostic> _diagnostics = [];
|
||||||
private List<Token> _tokens = [];
|
private List<Token> _tokens = [];
|
||||||
private int _index;
|
private int _index;
|
||||||
|
private string _namespace = string.Empty;
|
||||||
|
|
||||||
public DiagnosticsResult<SourceFile?> ParseModule(List<Token> tokens)
|
public DiagnosticsResult<SourceFile?> ParseModule(List<Token> tokens)
|
||||||
{
|
{
|
||||||
_diagnostics = [];
|
_diagnostics = [];
|
||||||
_tokens = tokens;
|
_tokens = tokens;
|
||||||
_index = 0;
|
_index = 0;
|
||||||
|
_namespace = string.Empty;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<string> imports = [];
|
ExpectSymbol(Symbol.Namespace);
|
||||||
while (TryExpectSymbol(Symbol.Import))
|
_namespace = ExpectIdentifier().Value;
|
||||||
{
|
|
||||||
var name = ExpectIdentifier();
|
|
||||||
imports.Add(name.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpectSymbol(Symbol.Module);
|
|
||||||
var module = ExpectIdentifier().Value;
|
|
||||||
|
|
||||||
List<DefinitionNode> definitions = [];
|
List<DefinitionNode> definitions = [];
|
||||||
|
|
||||||
@@ -34,8 +29,8 @@ public class Parser
|
|||||||
{
|
{
|
||||||
definitions.Add(ParseDefinition());
|
definitions.Add(ParseDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DiagnosticsResult<SourceFile?>(_diagnostics, new SourceFile(module, imports, definitions));
|
return new DiagnosticsResult<SourceFile?>(_diagnostics, new SourceFile(_namespace, definitions));
|
||||||
}
|
}
|
||||||
catch (ParseException ex)
|
catch (ParseException ex)
|
||||||
{
|
{
|
||||||
@@ -187,41 +182,7 @@ public class Parser
|
|||||||
{
|
{
|
||||||
case IdentifierToken identifier:
|
case IdentifierToken identifier:
|
||||||
{
|
{
|
||||||
var symbol = ExpectSymbol();
|
return ParseStatementIdentifier(startIndex, identifier);
|
||||||
switch (symbol.Symbol)
|
|
||||||
{
|
|
||||||
case Symbol.OpenParen:
|
|
||||||
{
|
|
||||||
var parameters = new List<ExpressionNode>();
|
|
||||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
|
||||||
{
|
|
||||||
parameters.Add(ParseExpression());
|
|
||||||
TryExpectSymbol(Symbol.Comma);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FuncCallStatementNode(GetTokensForNode(startIndex), new FuncCall(identifier.Value, parameters));
|
|
||||||
}
|
|
||||||
case Symbol.Assign:
|
|
||||||
{
|
|
||||||
var value = ParseExpression();
|
|
||||||
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier.Value, Optional<NubType>.Empty(), value);
|
|
||||||
}
|
|
||||||
case Symbol.Colon:
|
|
||||||
{
|
|
||||||
var type = ParseType();
|
|
||||||
ExpectSymbol(Symbol.Assign);
|
|
||||||
var value = ParseExpression();
|
|
||||||
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier.Value, type, value);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw new ParseException(Diagnostic
|
|
||||||
.Error($"Unexpected symbol '{symbol.Symbol}' after identifier")
|
|
||||||
.WithHelp("Expected '(', '=', or ':' after identifier")
|
|
||||||
.At(symbol)
|
|
||||||
.Build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case SymbolToken symbol:
|
case SymbolToken symbol:
|
||||||
{
|
{
|
||||||
@@ -250,6 +211,72 @@ public class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StatementNode ParseStatementIdentifier(int startIndex, IdentifierToken identifier)
|
||||||
|
{
|
||||||
|
var symbol = ExpectSymbol();
|
||||||
|
switch (symbol.Symbol)
|
||||||
|
{
|
||||||
|
case Symbol.DoubleColon:
|
||||||
|
{
|
||||||
|
var name = ExpectIdentifier();
|
||||||
|
ExpectSymbol(Symbol.OpenParen);
|
||||||
|
var parameters = new List<ExpressionNode>();
|
||||||
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
|
{
|
||||||
|
parameters.Add(ParseExpression());
|
||||||
|
if (!TryExpectSymbol(Symbol.Comma) && Peek().TryGetValue(out var nextToken) && nextToken is not SymbolToken { Symbol: Symbol.CloseParen })
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic
|
||||||
|
.Warning("Missing comma between function arguments")
|
||||||
|
.WithHelp("Add a ',' to separate arguments")
|
||||||
|
.At(nextToken)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FuncCallStatementNode(GetTokensForNode(startIndex), new FuncCall(identifier.Value, name.Value, parameters));
|
||||||
|
}
|
||||||
|
case Symbol.OpenParen:
|
||||||
|
{
|
||||||
|
var parameters = new List<ExpressionNode>();
|
||||||
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
|
{
|
||||||
|
parameters.Add(ParseExpression());
|
||||||
|
if (!TryExpectSymbol(Symbol.Comma) && Peek().TryGetValue(out var nextToken) && nextToken is not SymbolToken { Symbol: Symbol.CloseParen })
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic
|
||||||
|
.Warning("Missing comma between function arguments")
|
||||||
|
.WithHelp("Add a ',' to separate arguments")
|
||||||
|
.At(nextToken)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FuncCallStatementNode(GetTokensForNode(startIndex), new FuncCall(_namespace, identifier.Value, parameters));
|
||||||
|
}
|
||||||
|
case Symbol.Assign:
|
||||||
|
{
|
||||||
|
var value = ParseExpression();
|
||||||
|
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier.Value, Optional<NubType>.Empty(), value);
|
||||||
|
}
|
||||||
|
case Symbol.Colon:
|
||||||
|
{
|
||||||
|
var type = ParseType();
|
||||||
|
ExpectSymbol(Symbol.Assign);
|
||||||
|
var value = ParseExpression();
|
||||||
|
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier.Value, type, value);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new ParseException(Diagnostic
|
||||||
|
.Error($"Unexpected symbol '{symbol.Symbol}' after identifier")
|
||||||
|
.WithHelp("Expected '(', '=', or ':' after identifier")
|
||||||
|
.At(symbol)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ReturnNode ParseReturn(int startIndex)
|
private ReturnNode ParseReturn(int startIndex)
|
||||||
{
|
{
|
||||||
var value = Optional<ExpressionNode>.Empty();
|
var value = Optional<ExpressionNode>.Empty();
|
||||||
@@ -384,10 +411,11 @@ public class Parser
|
|||||||
var next = Peek();
|
var next = Peek();
|
||||||
switch (next.Value)
|
switch (next.Value)
|
||||||
{
|
{
|
||||||
case SymbolToken { Symbol: Symbol.OpenParen }:
|
case SymbolToken { Symbol: Symbol.DoubleColon }:
|
||||||
{
|
{
|
||||||
Next();
|
var name = ExpectIdentifier();
|
||||||
List<ExpressionNode> parameters = [];
|
ExpectSymbol(Symbol.OpenParen);
|
||||||
|
var parameters = new List<ExpressionNode>();
|
||||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
{
|
{
|
||||||
parameters.Add(ParseExpression());
|
parameters.Add(ParseExpression());
|
||||||
@@ -401,7 +429,26 @@ public class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = new FuncCallExpressionNode(GetTokensForNode(startIndex), new FuncCall(identifier.Value, parameters));
|
expr = new FuncCallExpressionNode(GetTokensForNode(startIndex), new FuncCall(identifier.Value, name.Value, parameters));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SymbolToken { Symbol: Symbol.OpenParen }:
|
||||||
|
{
|
||||||
|
var parameters = new List<ExpressionNode>();
|
||||||
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
|
{
|
||||||
|
parameters.Add(ParseExpression());
|
||||||
|
if (!TryExpectSymbol(Symbol.Comma) && Peek().TryGetValue(out var nextToken) && nextToken is not SymbolToken { Symbol: Symbol.CloseParen })
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic
|
||||||
|
.Warning("Missing comma between function arguments")
|
||||||
|
.WithHelp("Add a ',' to separate arguments")
|
||||||
|
.At(nextToken)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expr = new FuncCallExpressionNode(GetTokensForNode(startIndex), new FuncCall(_namespace, identifier.Value, parameters));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace Nub.Lang.Frontend.Parsing;
|
namespace Nub.Lang.Frontend.Parsing;
|
||||||
|
|
||||||
public class SourceFile(string module, List<string> imports, List<DefinitionNode> definitions)
|
public class SourceFile(string @namespace, List<DefinitionNode> definitions)
|
||||||
{
|
{
|
||||||
public string Module { get; } = module;
|
public string Namespace { get; } = @namespace;
|
||||||
public List<string> Imports { get; } = imports;
|
|
||||||
public List<DefinitionNode> Definitions { get; } = definitions;
|
public List<DefinitionNode> Definitions { get; } = definitions;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user