diff --git a/compiler/Compiler/Parser.cs b/compiler/Compiler/Parser.cs index 8c537ad..83870a9 100644 --- a/compiler/Compiler/Parser.cs +++ b/compiler/Compiler/Parser.cs @@ -4,23 +4,35 @@ namespace Compiler; public sealed class Parser(string fileName, List tokens) { - public static List Parse(string fileName, List tokens, out List diagnostics) + public static Ast Parse(string fileName, List tokens, out List diagnostics) { return new Parser(fileName, tokens).Parse(out diagnostics); } private int index; - private List Parse(out List diagnostics) + private Ast Parse(out List diagnostics) { - var nodes = new List(); + var functionDefinitions = new List(); + var structDefinitions = new List(); diagnostics = []; try { while (Peek() != null) { - nodes.Add(ParseDefinition()); + var definition = ParseDefinition(); + switch (definition) + { + case NodeDefinitionFunc def: + functionDefinitions.Add(def); + break; + case NodeDefinitionStruct def: + structDefinitions.Add(def); + break; + default: + throw new ArgumentOutOfRangeException(nameof(definition)); + } } } catch (CompileException e) @@ -28,7 +40,7 @@ public sealed class Parser(string fileName, List tokens) diagnostics.Add(e.Diagnostic); } - return nodes; + return new Ast(structDefinitions, functionDefinitions); } private NodeDefinition ParseDefinition() @@ -504,6 +516,12 @@ public sealed class Parser(string fileName, List tokens) } } +public sealed class Ast(List structs, List functions) +{ + public readonly List Structs = structs; + public readonly List Functions = functions; +} + public abstract class Node(List tokens) { public readonly List Tokens = tokens; diff --git a/compiler/Compiler/Program.cs b/compiler/Compiler/Program.cs index 794682f..8a4a407 100644 --- a/compiler/Compiler/Program.cs +++ b/compiler/Compiler/Program.cs @@ -16,7 +16,7 @@ if (tokenizerDiagnostics.Any(x => x.Severity == DiagnosticSeverity.Error)) return 1; } -var nodes = Parser.Parse(fileName, tokens, out var parserDiagnostics); +var ast = Parser.Parse(fileName, tokens, out var parserDiagnostics); foreach (var diagnostic in parserDiagnostics) { @@ -28,7 +28,7 @@ if (parserDiagnostics.Any(x => x.Severity == DiagnosticSeverity.Error)) return 1; } -var typedNodes = TypeChecker.Check(fileName, nodes, out var typeCheckerDiagnostics); +var typedAst = TypeChecker.Check(fileName, ast, out var typeCheckerDiagnostics); foreach (var diagnostic in typeCheckerDiagnostics) { @@ -40,7 +40,7 @@ if (typeCheckerDiagnostics.Any(x => x.Severity == DiagnosticSeverity.Error)) return 1; } -var output = Generator.Emit(typedNodes); +var output = Generator.Emit(typedAst); File.WriteAllText("C:/Users/oliste/repos/nub-lang/compiler/Compiler/out.c", output); diff --git a/compiler/Compiler/TypeChecker.cs b/compiler/Compiler/TypeChecker.cs index 0408c65..ad565ff 100644 --- a/compiler/Compiler/TypeChecker.cs +++ b/compiler/Compiler/TypeChecker.cs @@ -1,10 +1,10 @@ namespace Compiler; -public sealed class TypeChecker(string fileName, List definitions) +public sealed class TypeChecker(string fileName, Ast ast) { - public static TypedAst Check(string fileName, List nodes, out List diagnostics) + public static TypedAst Check(string fileName, Ast ast, out List diagnostics) { - return new TypeChecker(fileName, nodes).Check(out diagnostics); + return new TypeChecker(fileName, ast).Check(out diagnostics); } private Scope scope = new(null); @@ -16,19 +16,19 @@ public sealed class TypeChecker(string fileName, List definition diagnostics = []; // todo(nub31): Types must be resolved better to prevent circular dependencies and independent ordering - foreach (var structDef in definitions.OfType()) + foreach (var structDef in ast.Structs) { var fields = structDef.Fields.Select(x => new NubTypeStruct.Field(x.Name.Ident, CheckType(x.Type))).ToList(); structTypes.Add(structDef.Name.Ident, new NubTypeStruct(fields)); } - foreach (var funcDef in definitions.OfType()) + foreach (var funcDef in ast.Functions) { var type = new NubTypeFunc(funcDef.Parameters.Select(x => CheckType(x.Type)).ToList(), CheckType(funcDef.ReturnType)); scope.DeclareIdentifier(funcDef.Name.Ident, type); } - foreach (var funcDef in definitions.OfType()) + foreach (var funcDef in ast.Functions) { try { @@ -40,7 +40,7 @@ public sealed class TypeChecker(string fileName, List definition } } - return new TypedAst(functions, structTypes.Values.ToList()); + return new TypedAst(structTypes.Values.ToList(), functions); } private TypedNodeDefinitionFunc CheckDefinitionFunc(NodeDefinitionFunc definition) @@ -363,10 +363,10 @@ public sealed class TypeChecker(string fileName, List definition } } -public sealed class TypedAst(List functions, List structTypes) +public sealed class TypedAst(List structTypes, List functions) { - public List Functions = functions; - public List StructTypes = structTypes; + public readonly List StructTypes = structTypes; + public readonly List Functions = functions; } public abstract class TypedNode(List tokens)