Remove interfaces
This commit is contained in:
@@ -66,7 +66,6 @@ var moduleRepository = new ModuleRepository(syntaxTrees);
|
|||||||
var definitions = new List<DefinitionNode>();
|
var definitions = new List<DefinitionNode>();
|
||||||
|
|
||||||
var referencedStructTypes = new HashSet<StructTypeNode>();
|
var referencedStructTypes = new HashSet<StructTypeNode>();
|
||||||
var referencedInterfaceTypes = new HashSet<InterfaceTypeNode>();
|
|
||||||
|
|
||||||
foreach (var syntaxTree in syntaxTrees)
|
foreach (var syntaxTree in syntaxTrees)
|
||||||
{
|
{
|
||||||
@@ -80,11 +79,6 @@ foreach (var syntaxTree in syntaxTrees)
|
|||||||
{
|
{
|
||||||
referencedStructTypes.Add(structType);
|
referencedStructTypes.Add(structType);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var interfaceType in typeChecker.ReferencedInterfaceTypes)
|
|
||||||
{
|
|
||||||
referencedInterfaceTypes.Add(interfaceType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var diagnostic in diagnostics)
|
foreach (var diagnostic in diagnostics)
|
||||||
@@ -99,7 +93,7 @@ if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Erro
|
|||||||
|
|
||||||
Directory.CreateDirectory(".build");
|
Directory.CreateDirectory(".build");
|
||||||
|
|
||||||
var generator = new QBEGenerator(definitions, referencedStructTypes, referencedInterfaceTypes);
|
var generator = new QBEGenerator(definitions, referencedStructTypes);
|
||||||
var ssa = generator.Emit();
|
var ssa = generator.Emit();
|
||||||
var ssaFilePath = Path.Combine(".build", "out.ssa");
|
var ssaFilePath = Path.Combine(".build", "out.ssa");
|
||||||
File.WriteAllText(ssaFilePath, ssa);
|
File.WriteAllText(ssaFilePath, ssa);
|
||||||
|
|||||||
@@ -271,7 +271,6 @@ public class Diagnostic
|
|||||||
case Symbol.Struct:
|
case Symbol.Struct:
|
||||||
case Symbol.Let:
|
case Symbol.Let:
|
||||||
case Symbol.Calls:
|
case Symbol.Calls:
|
||||||
case Symbol.Interface:
|
|
||||||
case Symbol.For:
|
case Symbol.For:
|
||||||
case Symbol.Extern:
|
case Symbol.Extern:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ public class QBEGenerator
|
|||||||
private readonly QBEWriter _writer;
|
private readonly QBEWriter _writer;
|
||||||
private readonly List<DefinitionNode> _definitions;
|
private readonly List<DefinitionNode> _definitions;
|
||||||
private readonly HashSet<StructTypeNode> _structTypes;
|
private readonly HashSet<StructTypeNode> _structTypes;
|
||||||
private readonly HashSet<InterfaceTypeNode> _interfaceTypes;
|
|
||||||
|
|
||||||
private readonly List<CStringLiteral> _cStringLiterals = [];
|
private readonly List<CStringLiteral> _cStringLiterals = [];
|
||||||
private readonly List<StringLiteral> _stringLiterals = [];
|
private readonly List<StringLiteral> _stringLiterals = [];
|
||||||
@@ -23,11 +22,10 @@ public class QBEGenerator
|
|||||||
private int _stringLiteralIndex;
|
private int _stringLiteralIndex;
|
||||||
private bool _codeIsReachable = true;
|
private bool _codeIsReachable = true;
|
||||||
|
|
||||||
public QBEGenerator(List<DefinitionNode> definitions, HashSet<StructTypeNode> structTypes, HashSet<InterfaceTypeNode> interfaceTypes)
|
public QBEGenerator(List<DefinitionNode> definitions, HashSet<StructTypeNode> structTypes)
|
||||||
{
|
{
|
||||||
_definitions = definitions;
|
_definitions = definitions;
|
||||||
_structTypes = structTypes;
|
_structTypes = structTypes;
|
||||||
_interfaceTypes = interfaceTypes;
|
|
||||||
_writer = new QBEWriter();
|
_writer = new QBEWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,8 +259,8 @@ public class QBEGenerator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structs and interfaces has known sizes at compile time
|
// Structs has known sizes at compile time
|
||||||
if (complexType is StructTypeNode or InterfaceTypeNode)
|
if (complexType is StructTypeNode)
|
||||||
{
|
{
|
||||||
var value = EmitExpression(source);
|
var value = EmitExpression(source);
|
||||||
_writer.Indented($"blit {value}, {destination}, {SizeOf(complexType)}");
|
_writer.Indented($"blit {value}, {destination}, {SizeOf(complexType)}");
|
||||||
@@ -289,7 +287,7 @@ public class QBEGenerator
|
|||||||
private string EmitCopy(ExpressionNode source)
|
private string EmitCopy(ExpressionNode source)
|
||||||
{
|
{
|
||||||
// Allowlist for types which are safe to not copy
|
// Allowlist for types which are safe to not copy
|
||||||
if (source is ArrayInitializerNode or StructInitializerNode or ConvertToInterfaceNode or LiteralNode)
|
if (source is ArrayInitializerNode or StructInitializerNode or LiteralNode)
|
||||||
{
|
{
|
||||||
return EmitExpression(source);
|
return EmitExpression(source);
|
||||||
}
|
}
|
||||||
@@ -304,8 +302,8 @@ public class QBEGenerator
|
|||||||
var value = EmitExpression(source);
|
var value = EmitExpression(source);
|
||||||
var destination = TmpName();
|
var destination = TmpName();
|
||||||
|
|
||||||
// Structs and interfaces has known sizes at compile time
|
// Structs has known sizes at compile time
|
||||||
if (complexType is StructTypeNode or InterfaceTypeNode)
|
if (complexType is StructTypeNode)
|
||||||
{
|
{
|
||||||
var size = SizeOf(complexType);
|
var size = SizeOf(complexType);
|
||||||
_writer.Indented($"{destination} =l alloc8 {size}");
|
_writer.Indented($"{destination} =l alloc8 {size}");
|
||||||
@@ -501,12 +499,6 @@ public class QBEGenerator
|
|||||||
|
|
||||||
private void EmitStatement(StatementNode statement)
|
private void EmitStatement(StatementNode statement)
|
||||||
{
|
{
|
||||||
// var tokens = statement.Tokens.ToArray();
|
|
||||||
// if (tokens.Length != 0)
|
|
||||||
// {
|
|
||||||
// _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}");
|
|
||||||
// }
|
|
||||||
|
|
||||||
switch (statement)
|
switch (statement)
|
||||||
{
|
{
|
||||||
case AssignmentNode assignment:
|
case AssignmentNode assignment:
|
||||||
@@ -622,12 +614,6 @@ public class QBEGenerator
|
|||||||
|
|
||||||
private string EmitExpression(ExpressionNode expression)
|
private string EmitExpression(ExpressionNode expression)
|
||||||
{
|
{
|
||||||
// var tokens = expression.Tokens.ToArray();
|
|
||||||
// if (tokens.Length != 0)
|
|
||||||
// {
|
|
||||||
// _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}");
|
|
||||||
// }
|
|
||||||
|
|
||||||
return expression switch
|
return expression switch
|
||||||
{
|
{
|
||||||
ArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
ArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
||||||
@@ -636,8 +622,6 @@ public class QBEGenerator
|
|||||||
DereferenceNode dereference => EmitDereference(dereference),
|
DereferenceNode dereference => EmitDereference(dereference),
|
||||||
BinaryExpressionNode binary => EmitBinaryExpression(binary),
|
BinaryExpressionNode binary => EmitBinaryExpression(binary),
|
||||||
FuncCallNode funcCall => EmitFuncCall(funcCall),
|
FuncCallNode funcCall => EmitFuncCall(funcCall),
|
||||||
InterfaceFuncCallNode interfaceFuncCall => EmitInterfaceFuncCall(interfaceFuncCall),
|
|
||||||
ConvertToInterfaceNode convertToInterface => EmitConvertToInterface(convertToInterface),
|
|
||||||
ConvertIntNode convertInt => EmitConvertInt(convertInt),
|
ConvertIntNode convertInt => EmitConvertInt(convertInt),
|
||||||
ConvertFloatNode convertFloat => EmitConvertFloat(convertFloat),
|
ConvertFloatNode convertFloat => EmitConvertFloat(convertFloat),
|
||||||
VariableIdentifierNode identifier => EmitVariableIdentifier(identifier),
|
VariableIdentifierNode identifier => EmitVariableIdentifier(identifier),
|
||||||
@@ -673,14 +657,13 @@ public class QBEGenerator
|
|||||||
|
|
||||||
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess)
|
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess)
|
||||||
{
|
{
|
||||||
// var address = EmitAddressOfArrayIndexAccess(arrayIndexAccess);
|
var address = EmitAddressOfArrayIndexAccess(arrayIndexAccess);
|
||||||
// if (arrayIndexAccess.Type is StructTypeNode)
|
if (arrayIndexAccess.Type is StructTypeNode)
|
||||||
// {
|
{
|
||||||
// return address;
|
return address;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// return EmitLoad(arrayIndexAccess.Type, address);
|
return EmitLoad(arrayIndexAccess.Type, address);
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializer)
|
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializer)
|
||||||
@@ -1114,76 +1097,6 @@ public class QBEGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitInterfaceFuncCall(InterfaceFuncCallNode interfaceFuncCall)
|
|
||||||
{
|
|
||||||
var target = EmitExpression(interfaceFuncCall.InterfaceExpression);
|
|
||||||
|
|
||||||
var functionIndex = interfaceFuncCall.InterfaceType.Functions.ToList().FindIndex(x => x.Name == interfaceFuncCall.Name);
|
|
||||||
var offset = functionIndex * 8;
|
|
||||||
|
|
||||||
var vtable = TmpName();
|
|
||||||
_writer.Indented($"{vtable} =l loadl {target}");
|
|
||||||
|
|
||||||
var funcOffset = TmpName();
|
|
||||||
_writer.Indented($"{funcOffset} =l add {vtable}, {offset}");
|
|
||||||
|
|
||||||
var func = TmpName();
|
|
||||||
_writer.Indented($"{func} =l loadl {funcOffset}");
|
|
||||||
|
|
||||||
var data = TmpName();
|
|
||||||
_writer.Indented($"{data} =l add {target}, 8");
|
|
||||||
_writer.Indented($"{data} =l loadl {data}");
|
|
||||||
|
|
||||||
List<string> parameterStrings = [$"l {data}"];
|
|
||||||
|
|
||||||
foreach (var parameter in interfaceFuncCall.Parameters)
|
|
||||||
{
|
|
||||||
var copy = EmitCopy(parameter);
|
|
||||||
parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceFuncCall.Type is VoidTypeNode)
|
|
||||||
{
|
|
||||||
_writer.Indented($"call {func}({string.Join(", ", parameterStrings)})");
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var outputName = TmpName();
|
|
||||||
_writer.Indented($"{outputName} {QBEAssign(interfaceFuncCall.Type)} call {func}({string.Join(", ", parameterStrings)})");
|
|
||||||
return outputName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EmitConvertToInterface(ConvertToInterfaceNode convertToInterface)
|
|
||||||
{
|
|
||||||
var implementation = EmitExpression(convertToInterface.Implementation);
|
|
||||||
|
|
||||||
var vtableOffset = 0;
|
|
||||||
foreach (var interfaceImplementation in convertToInterface.StructType.InterfaceImplementations)
|
|
||||||
{
|
|
||||||
if (interfaceImplementation == convertToInterface.InterfaceType)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vtableOffset += interfaceImplementation.Functions.Count * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
var destination = TmpName();
|
|
||||||
_writer.Indented($"{destination} =l alloc8 {SizeOf(convertToInterface.InterfaceType)}");
|
|
||||||
|
|
||||||
var interfaceVtablePointer = TmpName();
|
|
||||||
_writer.Indented($"{interfaceVtablePointer} =l add {StructVtableName(convertToInterface.StructType.Module, convertToInterface.StructType.Name)}, {vtableOffset}");
|
|
||||||
_writer.Indented($"storel {interfaceVtablePointer}, {destination}");
|
|
||||||
|
|
||||||
var objectPointer = TmpName();
|
|
||||||
_writer.Indented($"{objectPointer} =l add {destination}, 8");
|
|
||||||
_writer.Indented($"storel {implementation}, {objectPointer}");
|
|
||||||
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EmitConvertInt(ConvertIntNode convertInt)
|
private string EmitConvertInt(ConvertIntNode convertInt)
|
||||||
{
|
{
|
||||||
var value = EmitExpression(convertInt.Value);
|
var value = EmitExpression(convertInt.Value);
|
||||||
@@ -1279,7 +1192,6 @@ public class QBEGenerator
|
|||||||
StringTypeNode => 8,
|
StringTypeNode => 8,
|
||||||
ArrayTypeNode => 8,
|
ArrayTypeNode => 8,
|
||||||
StructTypeNode structType => CalculateStructSize(structType),
|
StructTypeNode structType => CalculateStructSize(structType),
|
||||||
InterfaceTypeNode => 16,
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type.GetType()}")
|
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type.GetType()}")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1288,8 +1200,6 @@ public class QBEGenerator
|
|||||||
{
|
{
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
|
|
||||||
var fields = new List<TypeNode>(structType.Fields.Count);
|
|
||||||
|
|
||||||
foreach (var field in structType.Fields)
|
foreach (var field in structType.Fields)
|
||||||
{
|
{
|
||||||
var fieldAlignment = AlignmentOf(field.Type);
|
var fieldAlignment = AlignmentOf(field.Type);
|
||||||
@@ -1318,7 +1228,6 @@ public class QBEGenerator
|
|||||||
StringTypeNode => 8,
|
StringTypeNode => 8,
|
||||||
ArrayTypeNode => 8,
|
ArrayTypeNode => 8,
|
||||||
StructTypeNode structType => CalculateStructAlignment(structType),
|
StructTypeNode structType => CalculateStructAlignment(structType),
|
||||||
InterfaceTypeNode => 8,
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type.GetType()}")
|
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type.GetType()}")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1327,11 +1236,6 @@ public class QBEGenerator
|
|||||||
{
|
{
|
||||||
var maxAlignment = 1;
|
var maxAlignment = 1;
|
||||||
|
|
||||||
if (structType.InterfaceImplementations.Any())
|
|
||||||
{
|
|
||||||
maxAlignment = Math.Max(maxAlignment, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var field in structType.Fields)
|
foreach (var field in structType.Fields)
|
||||||
{
|
{
|
||||||
var fieldAlignment = AlignmentOf(field.Type);
|
var fieldAlignment = AlignmentOf(field.Type);
|
||||||
@@ -1405,11 +1309,6 @@ public class QBEGenerator
|
|||||||
{
|
{
|
||||||
return $"$.{module}.{structName}.func.{funcName}";
|
return $"$.{module}.{structName}.func.{funcName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string StructVtableName(string module, string structName)
|
|
||||||
{
|
|
||||||
return $"${module}.{structName}.vtable";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StringLiteral(string value, string name)
|
public class StringLiteral(string value, string name)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace NubLang.Modules;
|
|||||||
public class Module
|
public class Module
|
||||||
{
|
{
|
||||||
private readonly List<ModuleStruct> _structs = [];
|
private readonly List<ModuleStruct> _structs = [];
|
||||||
private readonly List<ModuleInterface> _interfaces = [];
|
|
||||||
private readonly List<ModuleFunction> _functions = [];
|
private readonly List<ModuleFunction> _functions = [];
|
||||||
|
|
||||||
public void RegisterStruct(bool exported, string name, List<ModuleStructField> fields, List<ModuleStructFunction> functions)
|
public void RegisterStruct(bool exported, string name, List<ModuleStructField> fields, List<ModuleStructFunction> functions)
|
||||||
@@ -13,11 +12,6 @@ public class Module
|
|||||||
_structs.Add(new ModuleStruct(exported, name, fields, functions));
|
_structs.Add(new ModuleStruct(exported, name, fields, functions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterInterface(bool exported, string name, List<ModuleInterfaceFunction> functions)
|
|
||||||
{
|
|
||||||
_interfaces.Add(new ModuleInterface(exported, name, functions));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterFunction(bool exported, string name, string? externSymbol, List<ModuleFunctionParameter> parameters, TypeSyntax returnType)
|
public void RegisterFunction(bool exported, string name, string? externSymbol, List<ModuleFunctionParameter> parameters, TypeSyntax returnType)
|
||||||
{
|
{
|
||||||
_functions.Add(new ModuleFunction(exported, name, externSymbol, parameters, returnType));
|
_functions.Add(new ModuleFunction(exported, name, externSymbol, parameters, returnType));
|
||||||
@@ -28,11 +22,6 @@ public class Module
|
|||||||
return _structs.Where(x => x.Exported || includePrivate).ToList();
|
return _structs.Where(x => x.Exported || includePrivate).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ModuleInterface> InterfaceTypes(bool includePrivate)
|
|
||||||
{
|
|
||||||
return _interfaces.Where(x => x.Exported || includePrivate).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ModuleFunction> Functions(bool includePrivate)
|
public List<ModuleFunction> Functions(bool includePrivate)
|
||||||
{
|
{
|
||||||
return _functions.Where(x => x.Exported || includePrivate).ToList();
|
return _functions.Where(x => x.Exported || includePrivate).ToList();
|
||||||
@@ -47,12 +36,6 @@ public record ModuleStructFunction(string Name, List<ModuleStructFunctionParamet
|
|||||||
|
|
||||||
public record ModuleStruct(bool Exported, string Name, List<ModuleStructField> Fields, List<ModuleStructFunction> Functions);
|
public record ModuleStruct(bool Exported, string Name, List<ModuleStructField> Fields, List<ModuleStructFunction> Functions);
|
||||||
|
|
||||||
public record ModuleInterfaceFunctionParameter(string Name, TypeSyntax Type);
|
|
||||||
|
|
||||||
public record ModuleInterfaceFunction(string Name, List<ModuleInterfaceFunctionParameter> Parameters, TypeSyntax ReturnType);
|
|
||||||
|
|
||||||
public record ModuleInterface(bool Exported, string Name, List<ModuleInterfaceFunction> Functions);
|
|
||||||
|
|
||||||
public record ModuleFunctionParameter(string Name, TypeSyntax Type);
|
public record ModuleFunctionParameter(string Name, TypeSyntax Type);
|
||||||
|
|
||||||
public record ModuleFunction(bool Exported, string Name, string? ExternSymbol, List<ModuleFunctionParameter> Parameters, TypeSyntax ReturnType);
|
public record ModuleFunction(bool Exported, string Name, string? ExternSymbol, List<ModuleFunctionParameter> Parameters, TypeSyntax ReturnType);
|
||||||
@@ -42,18 +42,6 @@ public class ModuleRepository
|
|||||||
module.RegisterStruct(structDef.Exported, structDef.Name, fields, functions);
|
module.RegisterStruct(structDef.Exported, structDef.Name, fields, functions);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InterfaceSyntax interfaceDef:
|
|
||||||
{
|
|
||||||
var functions = new List<ModuleInterfaceFunction>();
|
|
||||||
foreach (var function in interfaceDef.Functions)
|
|
||||||
{
|
|
||||||
var parameters = function.Signature.Parameters.Select(x => new ModuleInterfaceFunctionParameter(x.Name, x.Type)).ToList();
|
|
||||||
functions.AddRange(new ModuleInterfaceFunction(function.Name, parameters, function.Signature.ReturnType));
|
|
||||||
}
|
|
||||||
|
|
||||||
module.RegisterInterface(interfaceDef.Exported, interfaceDef.Name, functions);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException(nameof(definition));
|
throw new ArgumentOutOfRangeException(nameof(definition));
|
||||||
|
|||||||
@@ -84,14 +84,13 @@ public sealed class Parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
var keyword = ExpectSymbol();
|
var keyword = ExpectSymbol();
|
||||||
var definition = keyword.Symbol switch
|
DefinitionSyntax definition = keyword.Symbol switch
|
||||||
{
|
{
|
||||||
Symbol.Func => ParseFunc(startIndex, exported, null),
|
Symbol.Func => ParseFunc(startIndex, exported, null),
|
||||||
Symbol.Struct => ParseStruct(startIndex, exported),
|
Symbol.Struct => ParseStruct(startIndex, exported),
|
||||||
Symbol.Interface => ParseInterface(startIndex, exported),
|
|
||||||
_ => throw new ParseException(Diagnostic
|
_ => throw new ParseException(Diagnostic
|
||||||
.Error($"Expected 'func', 'struct' or 'interface' but found '{keyword.Symbol}'")
|
.Error($"Expected 'func' or 'struct' but found '{keyword.Symbol}'")
|
||||||
.WithHelp("Valid definition keywords are 'func', 'struct' and 'interface'")
|
.WithHelp("Valid definition keywords are 'func' and 'struct'")
|
||||||
.At(keyword)
|
.At(keyword)
|
||||||
.Build())
|
.Build())
|
||||||
};
|
};
|
||||||
@@ -103,7 +102,7 @@ public sealed class Parser
|
|||||||
_diagnostics.Add(e.Diagnostic);
|
_diagnostics.Add(e.Diagnostic);
|
||||||
while (HasToken)
|
while (HasToken)
|
||||||
{
|
{
|
||||||
if (CurrentToken is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Interface })
|
if (CurrentToken is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct })
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -164,19 +163,9 @@ public sealed class Parser
|
|||||||
return new FuncSyntax(GetTokens(startIndex), name.Value, exported, externSymbol, signature, body);
|
return new FuncSyntax(GetTokens(startIndex), name.Value, exported, externSymbol, signature, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefinitionSyntax ParseStruct(int startIndex, bool exported)
|
private StructSyntax ParseStruct(int startIndex, bool exported)
|
||||||
{
|
{
|
||||||
var name = ExpectIdentifier();
|
var name = ExpectIdentifier();
|
||||||
var interfaceImplementations = new List<TypeSyntax>();
|
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.Colon))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
var interfaceType = ParseType();
|
|
||||||
interfaceImplementations.Add(interfaceType);
|
|
||||||
} while (TryExpectSymbol(Symbol.Comma));
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpectSymbol(Symbol.OpenBrace);
|
ExpectSymbol(Symbol.OpenBrace);
|
||||||
|
|
||||||
@@ -212,30 +201,7 @@ public sealed class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StructSyntax(GetTokens(startIndex), name.Value, exported, fields, funcs, interfaceImplementations);
|
return new StructSyntax(GetTokens(startIndex), name.Value, exported, fields, funcs);
|
||||||
}
|
|
||||||
|
|
||||||
private InterfaceSyntax ParseInterface(int startIndex, bool exported)
|
|
||||||
{
|
|
||||||
var name = ExpectIdentifier();
|
|
||||||
|
|
||||||
ExpectSymbol(Symbol.OpenBrace);
|
|
||||||
|
|
||||||
List<InterfaceFuncSyntax> functions = [];
|
|
||||||
|
|
||||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
|
||||||
{
|
|
||||||
var funcStartIndex = _tokenIndex;
|
|
||||||
|
|
||||||
ExpectSymbol(Symbol.Func);
|
|
||||||
|
|
||||||
var funcName = ExpectIdentifier().Value;
|
|
||||||
var signature = ParseFuncSignature();
|
|
||||||
|
|
||||||
functions.Add(new InterfaceFuncSyntax(GetTokens(funcStartIndex), funcName, signature));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new InterfaceSyntax(GetTokens(startIndex), name.Value, exported, functions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private StatementSyntax ParseStatement()
|
private StatementSyntax ParseStatement()
|
||||||
|
|||||||
@@ -14,8 +14,4 @@ public record StructFieldSyntax(IEnumerable<Token> Tokens, string Name, TypeSynt
|
|||||||
|
|
||||||
public record StructFuncSyntax(IEnumerable<Token> Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens);
|
public record StructFuncSyntax(IEnumerable<Token> Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record StructSyntax(IEnumerable<Token> Tokens, string Name, bool Exported, List<StructFieldSyntax> Fields, List<StructFuncSyntax> Functions, List<TypeSyntax> InterfaceImplementations) : DefinitionSyntax(Tokens, Name, Exported);
|
public record StructSyntax(IEnumerable<Token> Tokens, string Name, bool Exported, List<StructFieldSyntax> Fields, List<StructFuncSyntax> Functions) : DefinitionSyntax(Tokens, Name, Exported);
|
||||||
|
|
||||||
public record InterfaceFuncSyntax(IEnumerable<Token> Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens);
|
|
||||||
|
|
||||||
public record InterfaceSyntax(IEnumerable<Token> Tokens, string Name, bool Exported, List<InterfaceFuncSyntax> Functions) : DefinitionSyntax(Tokens, Name, Exported);
|
|
||||||
@@ -67,7 +67,6 @@ public enum Symbol
|
|||||||
Ampersand,
|
Ampersand,
|
||||||
Let,
|
Let,
|
||||||
Calls,
|
Calls,
|
||||||
Interface,
|
|
||||||
For,
|
For,
|
||||||
Extern,
|
Extern,
|
||||||
Semi,
|
Semi,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ public sealed class Tokenizer
|
|||||||
["struct"] = Symbol.Struct,
|
["struct"] = Symbol.Struct,
|
||||||
["let"] = Symbol.Let,
|
["let"] = Symbol.Let,
|
||||||
["calls"] = Symbol.Calls,
|
["calls"] = Symbol.Calls,
|
||||||
["interface"] = Symbol.Interface,
|
|
||||||
["for"] = Symbol.For,
|
["for"] = Symbol.For,
|
||||||
["extern"] = Symbol.Extern,
|
["extern"] = Symbol.Extern,
|
||||||
["module"] = Symbol.Module,
|
["module"] = Symbol.Module,
|
||||||
|
|||||||
@@ -12,8 +12,4 @@ public record StructFieldNode(string Name, TypeNode Type, Optional<ExpressionNod
|
|||||||
|
|
||||||
public record StructFuncNode(string Name, FuncSignatureNode Signature, BlockNode Body) : Node;
|
public record StructFuncNode(string Name, FuncSignatureNode Signature, BlockNode Body) : Node;
|
||||||
|
|
||||||
public record StructNode(StructTypeNode StructType, string Module, string Name, List<StructFieldNode> Fields, List<StructFuncNode> Functions, List<InterfaceTypeNode> InterfaceImplementations) : DefinitionNode(Module, Name);
|
public record StructNode(StructTypeNode StructType, string Module, string Name, List<StructFieldNode> Fields, List<StructFuncNode> Functions) : DefinitionNode(Module, Name);
|
||||||
|
|
||||||
public record InterfaceFuncNode(string Name, FuncSignatureNode Signature) : Node;
|
|
||||||
|
|
||||||
public record InterfaceNode(InterfaceTypeNode InterfaceType, string Module, string Name, List<InterfaceFuncNode> Functions) : DefinitionNode(Module, Name);
|
|
||||||
@@ -33,6 +33,7 @@ public enum BinaryOperator
|
|||||||
public abstract record ExpressionNode(TypeNode Type) : Node;
|
public abstract record ExpressionNode(TypeNode Type) : Node;
|
||||||
|
|
||||||
public abstract record LValueExpressionNode(TypeNode Type) : RValueExpressionNode(Type);
|
public abstract record LValueExpressionNode(TypeNode Type) : RValueExpressionNode(Type);
|
||||||
|
|
||||||
public abstract record RValueExpressionNode(TypeNode Type) : ExpressionNode(Type);
|
public abstract record RValueExpressionNode(TypeNode Type) : ExpressionNode(Type);
|
||||||
|
|
||||||
public record BinaryExpressionNode(TypeNode Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Type);
|
public record BinaryExpressionNode(TypeNode Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Type);
|
||||||
@@ -43,8 +44,6 @@ public record FuncCallNode(TypeNode Type, ExpressionNode Expression, List<Expres
|
|||||||
|
|
||||||
public record StructFuncCallNode(TypeNode Type, string Name, StructTypeNode StructType, ExpressionNode StructExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
|
public record StructFuncCallNode(TypeNode Type, string Name, StructTypeNode StructType, ExpressionNode StructExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
|
||||||
|
|
||||||
public record InterfaceFuncCallNode(TypeNode Type, string Name, InterfaceTypeNode InterfaceType, ExpressionNode InterfaceExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
|
|
||||||
|
|
||||||
public record VariableIdentifierNode(TypeNode Type, string Name) : LValueExpressionNode(Type);
|
public record VariableIdentifierNode(TypeNode Type, string Name) : LValueExpressionNode(Type);
|
||||||
|
|
||||||
public record FuncParameterIdentifierNode(TypeNode Type, string Name) : RValueExpressionNode(Type);
|
public record FuncParameterIdentifierNode(TypeNode Type, string Name) : RValueExpressionNode(Type);
|
||||||
@@ -65,8 +64,6 @@ public record StructInitializerNode(StructTypeNode StructType, Dictionary<string
|
|||||||
|
|
||||||
public record DereferenceNode(TypeNode Type, ExpressionNode Expression) : RValueExpressionNode(Type);
|
public record DereferenceNode(TypeNode Type, ExpressionNode Expression) : RValueExpressionNode(Type);
|
||||||
|
|
||||||
public record ConvertToInterfaceNode(TypeNode Type, InterfaceTypeNode InterfaceType, StructTypeNode StructType, ExpressionNode Implementation) : RValueExpressionNode(Type);
|
|
||||||
|
|
||||||
public record ConvertIntNode(TypeNode Type, ExpressionNode Value, IntTypeNode ValueType, IntTypeNode TargetType) : RValueExpressionNode(Type);
|
public record ConvertIntNode(TypeNode Type, ExpressionNode Value, IntTypeNode ValueType, IntTypeNode TargetType) : RValueExpressionNode(Type);
|
||||||
|
|
||||||
public record ConvertFloatNode(TypeNode Type, ExpressionNode Value, FloatTypeNode ValueType, FloatTypeNode TargetType) : RValueExpressionNode(Type);
|
public record ConvertFloatNode(TypeNode Type, ExpressionNode Value, FloatTypeNode ValueType, FloatTypeNode TargetType) : RValueExpressionNode(Type);
|
||||||
@@ -187,36 +187,18 @@ public class StructTypeFunc(string name, FuncTypeNode type)
|
|||||||
public FuncTypeNode Type { get; } = type;
|
public FuncTypeNode Type { get; } = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StructTypeNode(string module, string name, List<StructTypeField> fields, List<StructTypeFunc> functions, List<InterfaceTypeNode> interfaceImplementations) : ComplexTypeNode
|
public class StructTypeNode(string module, string name, List<StructTypeField> fields, List<StructTypeFunc> functions) : ComplexTypeNode
|
||||||
{
|
{
|
||||||
public string Module { get; } = module;
|
public string Module { get; } = module;
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
public List<StructTypeField> Fields { get; set; } = fields;
|
public List<StructTypeField> Fields { get; set; } = fields;
|
||||||
public List<StructTypeFunc> Functions { get; set; } = functions;
|
public List<StructTypeFunc> Functions { get; set; } = functions;
|
||||||
public List<InterfaceTypeNode> InterfaceImplementations { get; set; } = interfaceImplementations;
|
|
||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
public override bool Equals(TypeNode? other) => other is StructTypeNode structType && Name == structType.Name && Module == structType.Module;
|
public override bool Equals(TypeNode? other) => other is StructTypeNode structType && Name == structType.Name && Module == structType.Module;
|
||||||
public override int GetHashCode() => HashCode.Combine(typeof(StructTypeNode), Name);
|
public override int GetHashCode() => HashCode.Combine(typeof(StructTypeNode), Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InterfaceTypeFunc(string name, FuncTypeNode type)
|
|
||||||
{
|
|
||||||
public string Name { get; } = name;
|
|
||||||
public FuncTypeNode Type { get; } = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InterfaceTypeNode(string module, string name, List<InterfaceTypeFunc> functions) : ComplexTypeNode
|
|
||||||
{
|
|
||||||
public string Module { get; } = module;
|
|
||||||
public string Name { get; } = name;
|
|
||||||
public List<InterfaceTypeFunc> Functions { get; set; } = functions;
|
|
||||||
|
|
||||||
public override string ToString() => Name;
|
|
||||||
public override bool Equals(TypeNode? other) => other is InterfaceTypeNode interfaceType && Name == interfaceType.Name && Module == interfaceType.Module;
|
|
||||||
public override int GetHashCode() => HashCode.Combine(typeof(InterfaceTypeNode), Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ArrayTypeNode(TypeNode elementType) : ComplexTypeNode
|
public class ArrayTypeNode(TypeNode elementType) : ComplexTypeNode
|
||||||
{
|
{
|
||||||
public TypeNode ElementType { get; } = elementType;
|
public TypeNode ElementType { get; } = elementType;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public sealed class TypeChecker
|
|||||||
private readonly Stack<TypeNode> _funcReturnTypes = [];
|
private readonly Stack<TypeNode> _funcReturnTypes = [];
|
||||||
private readonly List<Diagnostic> _diagnostics = [];
|
private readonly List<Diagnostic> _diagnostics = [];
|
||||||
private readonly List<StructTypeNode> _referencedStructTypes = [];
|
private readonly List<StructTypeNode> _referencedStructTypes = [];
|
||||||
private readonly List<InterfaceTypeNode> _referencedInterfaceTypes = [];
|
|
||||||
private readonly List<DefinitionNode> _definitions = [];
|
private readonly List<DefinitionNode> _definitions = [];
|
||||||
|
|
||||||
private Scope Scope => _scopes.Peek();
|
private Scope Scope => _scopes.Peek();
|
||||||
@@ -33,7 +32,6 @@ public sealed class TypeChecker
|
|||||||
public List<DefinitionNode> Definitions => _definitions;
|
public List<DefinitionNode> Definitions => _definitions;
|
||||||
public List<Diagnostic> Diagnostics => _diagnostics;
|
public List<Diagnostic> Diagnostics => _diagnostics;
|
||||||
public List<StructTypeNode> ReferencedStructTypes => _referencedStructTypes;
|
public List<StructTypeNode> ReferencedStructTypes => _referencedStructTypes;
|
||||||
public List<InterfaceTypeNode> ReferencedInterfaceTypes => _referencedInterfaceTypes;
|
|
||||||
|
|
||||||
public void Check()
|
public void Check()
|
||||||
{
|
{
|
||||||
@@ -41,7 +39,6 @@ public sealed class TypeChecker
|
|||||||
_funcReturnTypes.Clear();
|
_funcReturnTypes.Clear();
|
||||||
_diagnostics.Clear();
|
_diagnostics.Clear();
|
||||||
_referencedStructTypes.Clear();
|
_referencedStructTypes.Clear();
|
||||||
_referencedInterfaceTypes.Clear();
|
|
||||||
_definitions.Clear();
|
_definitions.Clear();
|
||||||
|
|
||||||
foreach (var definition in _syntaxTree.Definitions)
|
foreach (var definition in _syntaxTree.Definitions)
|
||||||
@@ -61,32 +58,12 @@ public sealed class TypeChecker
|
|||||||
{
|
{
|
||||||
return node switch
|
return node switch
|
||||||
{
|
{
|
||||||
InterfaceSyntax definition => CheckInterfaceDefinition(definition),
|
|
||||||
FuncSyntax definition => CheckFuncDefinition(definition),
|
FuncSyntax definition => CheckFuncDefinition(definition),
|
||||||
StructSyntax definition => CheckStructDefinition(definition),
|
StructSyntax definition => CheckStructDefinition(definition),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private InterfaceNode CheckInterfaceDefinition(InterfaceSyntax node)
|
|
||||||
{
|
|
||||||
var functions = node.Functions
|
|
||||||
.Select(function => new InterfaceFuncNode(function.Name, CheckFuncSignature(function.Signature)))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var functionTypes = new List<InterfaceTypeFunc>();
|
|
||||||
foreach (var function in node.Functions)
|
|
||||||
{
|
|
||||||
var parameters = function.Signature.Parameters.Select(x => ResolveType(x.Type)).ToList();
|
|
||||||
var funcType = new FuncTypeNode(parameters, ResolveType(function.Signature.ReturnType));
|
|
||||||
functionTypes.Add(new InterfaceTypeFunc(function.Name, funcType));
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = new InterfaceTypeNode(_syntaxTree.Metadata.ModuleName, node.Name, functionTypes);
|
|
||||||
|
|
||||||
return new InterfaceNode(type, _syntaxTree.Metadata.ModuleName, node.Name, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private StructNode CheckStructDefinition(StructSyntax node)
|
private StructNode CheckStructDefinition(StructSyntax node)
|
||||||
{
|
{
|
||||||
var fields = new List<StructFieldNode>();
|
var fields = new List<StructFieldNode>();
|
||||||
@@ -117,19 +94,6 @@ public sealed class TypeChecker
|
|||||||
functions.Add(new StructFuncNode(function.Name, CheckFuncSignature(function.Signature), body));
|
functions.Add(new StructFuncNode(function.Name, CheckFuncSignature(function.Signature), body));
|
||||||
}
|
}
|
||||||
|
|
||||||
var interfaceImplementations = new List<InterfaceTypeNode>();
|
|
||||||
foreach (var interfaceImplementation in node.InterfaceImplementations)
|
|
||||||
{
|
|
||||||
var resolvedType = ResolveType(interfaceImplementation);
|
|
||||||
if (resolvedType is not InterfaceTypeNode interfaceType)
|
|
||||||
{
|
|
||||||
_diagnostics.Add(Diagnostic.Error($"Struct {node.Name} cannot implement non-struct type {interfaceImplementation}").At(interfaceImplementation).Build());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaceImplementations.Add(interfaceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fieldTypes = node.Fields
|
var fieldTypes = node.Fields
|
||||||
.Select(x => new StructTypeField(x.Name, ResolveType(x.Type), x.Value.HasValue))
|
.Select(x => new StructTypeField(x.Name, ResolveType(x.Type), x.Value.HasValue))
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -142,22 +106,9 @@ public sealed class TypeChecker
|
|||||||
functionTypes.Add(new StructTypeFunc(function.Name, funcType));
|
functionTypes.Add(new StructTypeFunc(function.Name, funcType));
|
||||||
}
|
}
|
||||||
|
|
||||||
var interfaceImplementationTypes = new List<InterfaceTypeNode>();
|
var type = new StructTypeNode(_syntaxTree.Metadata.ModuleName, node.Name, fieldTypes, functionTypes);
|
||||||
foreach (var interfaceImplementation in node.InterfaceImplementations)
|
|
||||||
{
|
|
||||||
var resolvedType = ResolveType(interfaceImplementation);
|
|
||||||
if (resolvedType is not InterfaceTypeNode interfaceType)
|
|
||||||
{
|
|
||||||
_diagnostics.Add(Diagnostic.Error($"Struct {node.Name} cannot implement non-struct type {interfaceImplementation}").At(interfaceImplementation).Build());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaceImplementationTypes.Add(interfaceType);
|
return new StructNode(type, _syntaxTree.Metadata.ModuleName, node.Name, fields, functions);
|
||||||
}
|
|
||||||
|
|
||||||
var type = new StructTypeNode(_syntaxTree.Metadata.ModuleName, node.Name, fieldTypes, functionTypes, interfaceImplementationTypes);
|
|
||||||
|
|
||||||
return new StructNode(type, _syntaxTree.Metadata.ModuleName, node.Name, fields, functions, interfaceImplementations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private FuncNode CheckFuncDefinition(FuncSyntax node)
|
private FuncNode CheckFuncDefinition(FuncSyntax node)
|
||||||
@@ -289,11 +240,6 @@ public sealed class TypeChecker
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Type is StructTypeNode structType && expectedType is InterfaceTypeNode interfaceType)
|
|
||||||
{
|
|
||||||
return new ConvertToInterfaceNode(interfaceType, interfaceType, structType, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.Type is IntTypeNode sourceIntType && expectedType is IntTypeNode targetIntType)
|
if (result.Type is IntTypeNode sourceIntType && expectedType is IntTypeNode targetIntType)
|
||||||
{
|
{
|
||||||
if (sourceIntType.Signed == targetIntType.Signed && sourceIntType.Width < targetIntType.Width)
|
if (sourceIntType.Signed == targetIntType.Signed && sourceIntType.Width < targetIntType.Width)
|
||||||
@@ -586,7 +532,7 @@ public sealed class TypeChecker
|
|||||||
|
|
||||||
if (!_resolvingTypes.Add(key))
|
if (!_resolvingTypes.Add(key))
|
||||||
{
|
{
|
||||||
var placeholder = new StructTypeNode(customType.Module, customType.Name, new List<StructTypeField>(), [], []);
|
var placeholder = new StructTypeNode(customType.Module, customType.Name, [], []);
|
||||||
_typeCache[key] = placeholder;
|
_typeCache[key] = placeholder;
|
||||||
return placeholder;
|
return placeholder;
|
||||||
}
|
}
|
||||||
@@ -603,30 +549,18 @@ public sealed class TypeChecker
|
|||||||
var structType = module.StructTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
var structType = module.StructTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
||||||
if (structType != null)
|
if (structType != null)
|
||||||
{
|
{
|
||||||
var result = new StructTypeNode(customType.Module, structType.Name, [], [], []);
|
var result = new StructTypeNode(customType.Module, structType.Name, [], []);
|
||||||
_typeCache[key] = result;
|
_typeCache[key] = result;
|
||||||
|
|
||||||
var fields = structType.Fields.Select(x => new StructTypeField(x.Name, ResolveType(x.Type), x.HasDefaultValue)).ToList();
|
var fields = structType.Fields.Select(x => new StructTypeField(x.Name, ResolveType(x.Type), x.HasDefaultValue)).ToList();
|
||||||
result.Fields.AddRange(fields);
|
result.Fields.AddRange(fields);
|
||||||
|
|
||||||
// todo(nub31): Functions and interface implementations
|
// todo(nub31): Function implementations
|
||||||
|
|
||||||
_referencedStructTypes.Add(result);
|
_referencedStructTypes.Add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var interfaceType = module.InterfaceTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
|
||||||
if (interfaceType != null)
|
|
||||||
{
|
|
||||||
var result = new InterfaceTypeNode(customType.Module, interfaceType.Name, []);
|
|
||||||
_typeCache[key] = result;
|
|
||||||
|
|
||||||
// todo(nub31): Put func resolution code here
|
|
||||||
|
|
||||||
_referencedInterfaceTypes.AddRange(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new TypeCheckerException(Diagnostic.Error($"Type {customType.Name} not found in module {customType.Module}").At(customType).Build());
|
throw new TypeCheckerException(Diagnostic.Error($"Type {customType.Name} not found in module {customType.Module}").At(customType).Build());
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ NUBC = ../compiler/NubLang.CLI/bin/Debug/net9.0/nubc
|
|||||||
out: .build/out.o
|
out: .build/out.o
|
||||||
gcc -nostartfiles -o out x86_64.s .build/out.o
|
gcc -nostartfiles -o out x86_64.s .build/out.o
|
||||||
|
|
||||||
.build/out.o: $(NUBC) src/main.nub src/test.nub
|
.build/out.o: $(NUBC) src/main.nub
|
||||||
$(NUBC) src/main.nub src/test.nub
|
$(NUBC) src/main.nub
|
||||||
|
|
||||||
.PHONY: $(NUBC)
|
.PHONY: $(NUBC)
|
||||||
$(NUBC):
|
$(NUBC):
|
||||||
|
|||||||
Reference in New Issue
Block a user