WIP: dev #1
@@ -4,23 +4,35 @@ namespace Compiler;
|
|||||||
|
|
||||||
public sealed class Parser(string fileName, List<Token> tokens)
|
public sealed class Parser(string fileName, List<Token> tokens)
|
||||||
{
|
{
|
||||||
public static List<NodeDefinition> Parse(string fileName, List<Token> tokens, out List<Diagnostic> diagnostics)
|
public static Ast Parse(string fileName, List<Token> tokens, out List<Diagnostic> diagnostics)
|
||||||
{
|
{
|
||||||
return new Parser(fileName, tokens).Parse(out diagnostics);
|
return new Parser(fileName, tokens).Parse(out diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
private List<NodeDefinition> Parse(out List<Diagnostic> diagnostics)
|
private Ast Parse(out List<Diagnostic> diagnostics)
|
||||||
{
|
{
|
||||||
var nodes = new List<NodeDefinition>();
|
var functionDefinitions = new List<NodeDefinitionFunc>();
|
||||||
|
var structDefinitions = new List<NodeDefinitionStruct>();
|
||||||
diagnostics = [];
|
diagnostics = [];
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (Peek() != null)
|
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)
|
catch (CompileException e)
|
||||||
@@ -28,7 +40,7 @@ public sealed class Parser(string fileName, List<Token> tokens)
|
|||||||
diagnostics.Add(e.Diagnostic);
|
diagnostics.Add(e.Diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes;
|
return new Ast(structDefinitions, functionDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NodeDefinition ParseDefinition()
|
private NodeDefinition ParseDefinition()
|
||||||
@@ -504,6 +516,12 @@ public sealed class Parser(string fileName, List<Token> tokens)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class Ast(List<NodeDefinitionStruct> structs, List<NodeDefinitionFunc> functions)
|
||||||
|
{
|
||||||
|
public readonly List<NodeDefinitionStruct> Structs = structs;
|
||||||
|
public readonly List<NodeDefinitionFunc> Functions = functions;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class Node(List<Token> tokens)
|
public abstract class Node(List<Token> tokens)
|
||||||
{
|
{
|
||||||
public readonly List<Token> Tokens = tokens;
|
public readonly List<Token> Tokens = tokens;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ if (tokenizerDiagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
|
|||||||
return 1;
|
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)
|
foreach (var diagnostic in parserDiagnostics)
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,7 @@ if (parserDiagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
|
|||||||
return 1;
|
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)
|
foreach (var diagnostic in typeCheckerDiagnostics)
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ if (typeCheckerDiagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
|
|||||||
return 1;
|
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);
|
File.WriteAllText("C:/Users/oliste/repos/nub-lang/compiler/Compiler/out.c", output);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
namespace Compiler;
|
namespace Compiler;
|
||||||
|
|
||||||
public sealed class TypeChecker(string fileName, List<NodeDefinition> definitions)
|
public sealed class TypeChecker(string fileName, Ast ast)
|
||||||
{
|
{
|
||||||
public static TypedAst Check(string fileName, List<NodeDefinition> nodes, out List<Diagnostic> diagnostics)
|
public static TypedAst Check(string fileName, Ast ast, out List<Diagnostic> diagnostics)
|
||||||
{
|
{
|
||||||
return new TypeChecker(fileName, nodes).Check(out diagnostics);
|
return new TypeChecker(fileName, ast).Check(out diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Scope scope = new(null);
|
private Scope scope = new(null);
|
||||||
@@ -16,19 +16,19 @@ public sealed class TypeChecker(string fileName, List<NodeDefinition> definition
|
|||||||
diagnostics = [];
|
diagnostics = [];
|
||||||
|
|
||||||
// todo(nub31): Types must be resolved better to prevent circular dependencies and independent ordering
|
// todo(nub31): Types must be resolved better to prevent circular dependencies and independent ordering
|
||||||
foreach (var structDef in definitions.OfType<NodeDefinitionStruct>())
|
foreach (var structDef in ast.Structs)
|
||||||
{
|
{
|
||||||
var fields = structDef.Fields.Select(x => new NubTypeStruct.Field(x.Name.Ident, CheckType(x.Type))).ToList();
|
var fields = structDef.Fields.Select(x => new NubTypeStruct.Field(x.Name.Ident, CheckType(x.Type))).ToList();
|
||||||
structTypes.Add(structDef.Name.Ident, new NubTypeStruct(fields));
|
structTypes.Add(structDef.Name.Ident, new NubTypeStruct(fields));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var funcDef in definitions.OfType<NodeDefinitionFunc>())
|
foreach (var funcDef in ast.Functions)
|
||||||
{
|
{
|
||||||
var type = new NubTypeFunc(funcDef.Parameters.Select(x => CheckType(x.Type)).ToList(), CheckType(funcDef.ReturnType));
|
var type = new NubTypeFunc(funcDef.Parameters.Select(x => CheckType(x.Type)).ToList(), CheckType(funcDef.ReturnType));
|
||||||
scope.DeclareIdentifier(funcDef.Name.Ident, type);
|
scope.DeclareIdentifier(funcDef.Name.Ident, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var funcDef in definitions.OfType<NodeDefinitionFunc>())
|
foreach (var funcDef in ast.Functions)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ public sealed class TypeChecker(string fileName, List<NodeDefinition> definition
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TypedAst(functions, structTypes.Values.ToList());
|
return new TypedAst(structTypes.Values.ToList(), functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypedNodeDefinitionFunc CheckDefinitionFunc(NodeDefinitionFunc definition)
|
private TypedNodeDefinitionFunc CheckDefinitionFunc(NodeDefinitionFunc definition)
|
||||||
@@ -363,10 +363,10 @@ public sealed class TypeChecker(string fileName, List<NodeDefinition> definition
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TypedAst(List<TypedNodeDefinitionFunc> functions, List<NubTypeStruct> structTypes)
|
public sealed class TypedAst(List<NubTypeStruct> structTypes, List<TypedNodeDefinitionFunc> functions)
|
||||||
{
|
{
|
||||||
public List<TypedNodeDefinitionFunc> Functions = functions;
|
public readonly List<NubTypeStruct> StructTypes = structTypes;
|
||||||
public List<NubTypeStruct> StructTypes = structTypes;
|
public readonly List<TypedNodeDefinitionFunc> Functions = functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class TypedNode(List<Token> tokens)
|
public abstract class TypedNode(List<Token> tokens)
|
||||||
|
|||||||
Reference in New Issue
Block a user