This commit is contained in:
nub31
2025-05-27 09:18:31 +02:00
parent cae1c03ed5
commit 2b666f168b
9 changed files with 347 additions and 284 deletions

5
example/math/math.nub Normal file
View File

@@ -0,0 +1,5 @@
namespace math
func add(a: i64, b: i64): i64 {
return a + b
}

View File

@@ -2,9 +2,11 @@ namespace main
/// # Documentation /// # Documentation
/// ## Documentation subtitle /// ## Documentation subtitle
global func main(args: []string) { export func main(args: []string) {
i = 0 i = 0
x = math::add(1, 1)
c::printf("%d\n", args.count) c::printf("%d\n", args.count)
while i < args.count { while i < args.count {

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ public class Lexer
private static readonly Dictionary<string, Modifier> Modifiers = new() private static readonly Dictionary<string, Modifier> Modifiers = new()
{ {
["global"] = Modifier.Global, ["export"] = Modifier.Export,
["extern"] = Modifier.Extern, ["extern"] = Modifier.Extern,
}; };

View File

@@ -10,5 +10,5 @@ public class ModifierToken(SourceText sourceText, int startIndex, int endIndex,
public enum Modifier public enum Modifier
{ {
Extern, Extern,
Global Export
} }

View File

@@ -52,13 +52,13 @@ public interface IFuncSignature
public string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; public string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
} }
public class LocalFuncDefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation, string name, List<FuncParameter> parameters, BlockNode body, Optional<NubType> returnType, bool global) : DefinitionNode(tokens, documentation), IFuncSignature public class LocalFuncDefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation, string name, List<FuncParameter> parameters, BlockNode body, Optional<NubType> returnType, bool exported) : DefinitionNode(tokens, documentation), IFuncSignature
{ {
public string Name { get; } = name; public string Name { get; } = name;
public List<FuncParameter> Parameters { get; } = parameters; public List<FuncParameter> Parameters { get; } = parameters;
public BlockNode Body { get; } = body; public BlockNode Body { get; } = body;
public Optional<NubType> ReturnType { get; } = returnType; public Optional<NubType> ReturnType { get; } = returnType;
public bool Global { get; } = global; public bool Exported { get; } = exported;
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
} }

View File

@@ -117,7 +117,7 @@ public class Parser
} }
var body = ParseBlock(); var body = ParseBlock();
var isGlobal = modifiers.RemoveAll(x => x.Modifier == Modifier.Global) > 0; var exported = modifiers.RemoveAll(x => x.Modifier == Modifier.Export) > 0;
if (modifiers.Count != 0) if (modifiers.Count != 0)
{ {
@@ -128,7 +128,7 @@ public class Parser
.Build()); .Build());
} }
return new LocalFuncDefinitionNode(GetTokensForNode(startIndex), documentation, name.Value, parameters, body, returnType, isGlobal); return new LocalFuncDefinitionNode(GetTokensForNode(startIndex), documentation, name.Value, parameters, body, returnType, exported);
} }
private StructDefinitionNode ParseStruct(int startIndex, List<ModifierToken> _, Optional<string> documentation) private StructDefinitionNode ParseStruct(int startIndex, List<ModifierToken> _, Optional<string> documentation)
@@ -414,6 +414,7 @@ public class Parser
{ {
case SymbolToken { Symbol: Symbol.DoubleColon }: case SymbolToken { Symbol: Symbol.DoubleColon }:
{ {
Next();
var name = ExpectIdentifier(); var name = ExpectIdentifier();
ExpectSymbol(Symbol.OpenParen); ExpectSymbol(Symbol.OpenParen);
var parameters = new List<ExpressionNode>(); var parameters = new List<ExpressionNode>();
@@ -435,6 +436,7 @@ public class Parser
} }
case SymbolToken { Symbol: Symbol.OpenParen }: case SymbolToken { Symbol: Symbol.OpenParen }:
{ {
Next();
var parameters = new List<ExpressionNode>(); var parameters = new List<ExpressionNode>();
while (!TryExpectSymbol(Symbol.CloseParen)) while (!TryExpectSymbol(Symbol.CloseParen))
{ {

View File

@@ -19,16 +19,27 @@ public class TypeChecker
_hasReturnStatement = false; _hasReturnStatement = false;
_sourceFiles = sourceFiles; _sourceFiles = sourceFiles;
var externFunctionNames = _sourceFiles var externFuncDefinitions = _sourceFiles
.SelectMany(f => f.Definitions) .SelectMany(f => f.Definitions)
.OfType<ExternFuncDefinitionNode>() .OfType<ExternFuncDefinitionNode>()
.ToArray(); .ToArray();
foreach (var funcName in externFunctionNames.Where(x => externFunctionNames.Count(y => x.Name == y.Name) > 1)) foreach (var funcName in externFuncDefinitions.Where(x => externFuncDefinitions.Count(y => x.Name == y.Name) > 1))
{ {
ReportError($"Extern function '{funcName}' has been declared more than once", funcName); ReportError($"Extern function '{funcName}' has been declared more than once", funcName);
} }
var exportedLocalFuncDefinitions = _sourceFiles
.SelectMany(f => f.Definitions)
.OfType<LocalFuncDefinitionNode>()
.Where(f => f.Exported)
.ToArray();
foreach (var funcName in exportedLocalFuncDefinitions.Where(x => exportedLocalFuncDefinitions.Count(y => x.Name == y.Name) > 1))
{
ReportError($"Exported function '{funcName}' has been declared more than once", funcName);
}
foreach (var structDef in _sourceFiles.SelectMany(f => f.Definitions).OfType<StructDefinitionNode>()) foreach (var structDef in _sourceFiles.SelectMany(f => f.Definitions).OfType<StructDefinitionNode>())
{ {
TypeCheckStructDef(structDef); TypeCheckStructDef(structDef);

View File

@@ -58,11 +58,13 @@ internal static class Program
typeCheckResult.PrintAllDiagnostics(); typeCheckResult.PrintAllDiagnostics();
error = error || typeCheckResult.HasErrors; error = error || typeCheckResult.HasErrors;
if (error) return 1;
var generator = new Generator(); var generator = new Generator();
var result = generator.Generate(files); var result = generator.Generate(files);
Console.Out.Write(result); Console.Out.Write(result);
return error ? 1 : 0; return 0;
} }
} }