...
This commit is contained in:
@@ -1,5 +1,27 @@
|
|||||||
|
interface Printable
|
||||||
|
{
|
||||||
|
func print()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Human : Printable {
|
||||||
|
name: cstring
|
||||||
|
|
||||||
|
func print_name()
|
||||||
|
{
|
||||||
|
puts(this^.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func print()
|
||||||
|
{
|
||||||
|
puts("example")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main(args: []cstring): i64
|
func main(args: []cstring): i64
|
||||||
{
|
{
|
||||||
puts("test")
|
let human: Human = alloc Human {
|
||||||
|
name = "oliver"
|
||||||
|
}
|
||||||
|
human.print()
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,14 @@ public partial class QBEGenerator
|
|||||||
ArrowFuncNode arrowFunc => EmitArrowFunc(arrowFunc),
|
ArrowFuncNode arrowFunc => EmitArrowFunc(arrowFunc),
|
||||||
BinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression),
|
BinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression),
|
||||||
FuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression),
|
FuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression),
|
||||||
|
InterfaceFuncAccessNode interfaceFuncAccess => EmitInterfaceFuncAccess(interfaceFuncAccess),
|
||||||
ExternFuncIdentNode externFuncIdent => EmitExternFuncIdent(externFuncIdent),
|
ExternFuncIdentNode externFuncIdent => EmitExternFuncIdent(externFuncIdent),
|
||||||
LocalFuncIdentNode localFuncIdent => EmitLocalFuncIdent(localFuncIdent),
|
LocalFuncIdentNode localFuncIdent => EmitLocalFuncIdent(localFuncIdent),
|
||||||
VariableIdentNode variableIdent => EmitVariableIdent(variableIdent),
|
VariableIdentNode variableIdent => EmitVariableIdent(variableIdent),
|
||||||
LiteralNode literal => EmitLiteral(literal),
|
LiteralNode literal => EmitLiteral(literal),
|
||||||
UnaryExpressionNode unaryExpression => EmitUnaryExpression(unaryExpression),
|
UnaryExpressionNode unaryExpression => EmitUnaryExpression(unaryExpression),
|
||||||
StructFieldAccessNode structFieldAccess => EmitStructFieldAccess(structFieldAccess),
|
StructFieldAccessNode structFieldAccess => EmitStructFieldAccess(structFieldAccess),
|
||||||
|
StructFuncAccessNode structFuncAccess => EmitStructFuncAccess(structFuncAccess),
|
||||||
ArrayIndexAccessNode arrayIndex => EmitArrayIndexAccess(arrayIndex),
|
ArrayIndexAccessNode arrayIndex => EmitArrayIndexAccess(arrayIndex),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(expression))
|
_ => throw new ArgumentOutOfRangeException(nameof(expression))
|
||||||
};
|
};
|
||||||
@@ -321,16 +323,22 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
private Val EmitStructInitializer(StructInitializerNode structInitializer, string? destination = null)
|
private Val EmitStructInitializer(StructInitializerNode structInitializer, string? destination = null)
|
||||||
{
|
{
|
||||||
var @struct = _definitionTable.LookupStruct(structInitializer.StructType.Name);
|
var structDef = _definitionTable.LookupStruct(structInitializer.StructType.Name);
|
||||||
|
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
{
|
{
|
||||||
destination = TmpName();
|
destination = TmpName();
|
||||||
var size = structInitializer.StructType.Size(_definitionTable);
|
var size = structInitializer.StructType.Size(_definitionTable);
|
||||||
|
|
||||||
|
if (structDef.InterfaceImplementations.Any())
|
||||||
|
{
|
||||||
|
size += 8;
|
||||||
|
}
|
||||||
|
|
||||||
_writer.Indented($"{destination} =l alloc8 {size}");
|
_writer.Indented($"{destination} =l alloc8 {size}");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var field in @struct.Fields)
|
foreach (var field in structDef.Fields)
|
||||||
{
|
{
|
||||||
if (!structInitializer.Initializers.TryGetValue(field.Name, out var valueExpression))
|
if (!structInitializer.Initializers.TryGetValue(field.Name, out var valueExpression))
|
||||||
{
|
{
|
||||||
@@ -340,7 +348,7 @@ public partial class QBEGenerator
|
|||||||
Debug.Assert(valueExpression != null);
|
Debug.Assert(valueExpression != null);
|
||||||
|
|
||||||
var offset = TmpName();
|
var offset = TmpName();
|
||||||
_writer.Indented($"{offset} =l add {destination}, {OffsetOf(@struct, field.Name)}");
|
_writer.Indented($"{offset} =l add {destination}, {OffsetOf(structDef, field.Name)}");
|
||||||
EmitCopyIntoOrInitialize(valueExpression, offset);
|
EmitCopyIntoOrInitialize(valueExpression, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +421,20 @@ public partial class QBEGenerator
|
|||||||
return new Val(output, structFieldAccess.Type, ValKind.Pointer);
|
return new Val(output, structFieldAccess.Type, ValKind.Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Val EmitStructFuncAccess(StructFuncAccessNode structFuncAccess)
|
||||||
|
{
|
||||||
|
var target = EmitExpression(structFuncAccess.Target);
|
||||||
|
var structDef = _definitionTable.LookupStruct(structFuncAccess.StructType.Name);
|
||||||
|
var func = StructFuncName(structDef.Name, structFuncAccess.Func);
|
||||||
|
|
||||||
|
return new Val(func, structFuncAccess.Type, ValKind.Direct, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Val EmitInterfaceFuncAccess(InterfaceFuncAccessNode interfaceFuncAccess)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
private Val EmitFuncCall(FuncCallNode funcCall)
|
private Val EmitFuncCall(FuncCallNode funcCall)
|
||||||
{
|
{
|
||||||
var expression = EmitExpression(funcCall.Expression);
|
var expression = EmitExpression(funcCall.Expression);
|
||||||
@@ -420,6 +442,12 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
var parameterStrings = new List<string>();
|
var parameterStrings = new List<string>();
|
||||||
|
|
||||||
|
if (expression.ThisArg != null)
|
||||||
|
{
|
||||||
|
Debug.Assert(expression.ThisArg.Kind == ValKind.Pointer);
|
||||||
|
parameterStrings.Add($"l {expression.ThisArg.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var parameter in funcCall.Parameters)
|
foreach (var parameter in funcCall.Parameters)
|
||||||
{
|
{
|
||||||
var copy = EmitCreateCopyOrInitialize(parameter);
|
var copy = EmitCreateCopyOrInitialize(parameter);
|
||||||
|
|||||||
@@ -51,10 +51,20 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
foreach (var structDef in _definitionTable.GetStructs())
|
foreach (var structDef in _definitionTable.GetStructs())
|
||||||
{
|
{
|
||||||
EmitStructDefinition(structDef);
|
EmitStructTypeDefinition(structDef);
|
||||||
_writer.NewLine();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var structDef in _syntaxTree.Definitions.OfType<StructNode>())
|
||||||
|
{
|
||||||
|
foreach (var func in structDef.Functions)
|
||||||
|
{
|
||||||
|
var funcName = StructFuncName(structDef.Name, func.Name);
|
||||||
|
EmitFuncDefinition(funcName, func.Signature.Parameters, func.Signature.ReturnType, func.Body);
|
||||||
|
_writer.NewLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<LocalFuncNode>())
|
foreach (var funcDef in _syntaxTree.Definitions.OfType<LocalFuncNode>())
|
||||||
{
|
{
|
||||||
EmitFuncDefinition(LocalFuncName(funcDef), funcDef.Signature.Parameters, funcDef.Signature.ReturnType, funcDef.Body);
|
EmitFuncDefinition(LocalFuncName(funcDef), funcDef.Signature.Parameters, funcDef.Signature.ReturnType, funcDef.Body);
|
||||||
@@ -67,6 +77,22 @@ public partial class QBEGenerator
|
|||||||
_writer.NewLine();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var structDef in _syntaxTree.Definitions.OfType<StructNode>().Where(x => x.InterfaceImplementations.Count > 0))
|
||||||
|
{
|
||||||
|
_writer.Write($"data {StructVtableName(structDef.Name)} = {{ ");
|
||||||
|
|
||||||
|
foreach (var interfaceImplementation in structDef.InterfaceImplementations)
|
||||||
|
{
|
||||||
|
var interfaceDef = _definitionTable.LookupInterface(interfaceImplementation.Name);
|
||||||
|
foreach (var func in interfaceDef.Functions)
|
||||||
|
{
|
||||||
|
_writer.Write($"l {StructFuncName(structDef.Name, func.Name)}, ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_writer.WriteLine("}");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var cStringLiteral in _cStringLiterals)
|
foreach (var cStringLiteral in _cStringLiterals)
|
||||||
{
|
{
|
||||||
_writer.WriteLine($"data {cStringLiteral.Name} = {{ b \"{cStringLiteral.Value}\", b 0 }}");
|
_writer.WriteLine($"data {cStringLiteral.Name} = {{ b \"{cStringLiteral.Value}\", b 0 }}");
|
||||||
@@ -315,7 +341,7 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
if (complexType is CustomTypeNode customType)
|
if (complexType is CustomTypeNode customType)
|
||||||
{
|
{
|
||||||
return CustomTypeName(customType);
|
return CustomTypeName(customType.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "l";
|
return "l";
|
||||||
@@ -359,7 +385,7 @@ public partial class QBEGenerator
|
|||||||
_writer.WriteLine("}");
|
_writer.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmitStructDefinition(StructNode structDef)
|
private void EmitStructTypeDefinition(StructNode structDef)
|
||||||
{
|
{
|
||||||
_writer.WriteLine($"type {CustomTypeName(structDef.Name)} = {{ ");
|
_writer.WriteLine($"type {CustomTypeName(structDef.Name)} = {{ ");
|
||||||
|
|
||||||
@@ -398,7 +424,7 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
if (complexType is CustomTypeNode customType)
|
if (complexType is CustomTypeNode customType)
|
||||||
{
|
{
|
||||||
return CustomTypeName(customType);
|
return CustomTypeName(customType.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "l";
|
return "l";
|
||||||
@@ -432,11 +458,16 @@ public partial class QBEGenerator
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private int OffsetOf(StructNode structDefinition, string member)
|
private int OffsetOf(StructNode structDef, string member)
|
||||||
{
|
{
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
|
|
||||||
foreach (var field in structDefinition.Fields)
|
if (structDef.InterfaceImplementations.Any())
|
||||||
|
{
|
||||||
|
offset = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var field in structDef.Fields)
|
||||||
{
|
{
|
||||||
if (field.Name == member)
|
if (field.Name == member)
|
||||||
{
|
{
|
||||||
@@ -484,16 +515,21 @@ public partial class QBEGenerator
|
|||||||
return $"${funcDef.CallName}";
|
return $"${funcDef.CallName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CustomTypeName(CustomTypeNode customType)
|
|
||||||
{
|
|
||||||
return CustomTypeName(customType.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string CustomTypeName(string name)
|
private string CustomTypeName(string name)
|
||||||
{
|
{
|
||||||
return $":{name}";
|
return $":{name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string StructFuncName(string structName, string funcName)
|
||||||
|
{
|
||||||
|
return $"${structName}_{funcName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string StructVtableName(string structName)
|
||||||
|
{
|
||||||
|
return $"${structName}_vtable";
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,7 +545,7 @@ public class CStringLiteral(string value, string name)
|
|||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Val(string Name, TypeNode Type, ValKind Kind);
|
public record Val(string Name, TypeNode Type, ValKind Kind, Val? ThisArg = null);
|
||||||
|
|
||||||
public class Scope(Scope? parent = null)
|
public class Scope(Scope? parent = null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ public sealed class TypedDefinitionTable
|
|||||||
.First(x => x.Name == name);
|
.First(x => x.Name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InterfaceNode LookupInterface(string name)
|
||||||
|
{
|
||||||
|
return _definitions
|
||||||
|
.OfType<InterfaceNode>()
|
||||||
|
.First(x => x.Name == name);
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<StructNode> GetStructs()
|
public IEnumerable<StructNode> GetStructs()
|
||||||
{
|
{
|
||||||
return _definitions.OfType<StructNode>();
|
return _definitions.OfType<StructNode>();
|
||||||
|
|||||||
@@ -66,14 +66,14 @@ public sealed class Parser
|
|||||||
return new SyntaxTree(GetTokens(_tokenIndex), definitions);
|
return new SyntaxTree(GetTokens(_tokenIndex), definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null)
|
private FuncSignatureSyntax ParseFuncSignature(TypeSyntax? thisArg = null)
|
||||||
{
|
{
|
||||||
var startIndex = _tokenIndex;
|
var startIndex = _tokenIndex;
|
||||||
List<FuncParameterSyntax> parameters = [];
|
List<FuncParameterSyntax> parameters = [];
|
||||||
|
|
||||||
if (thisArg != null)
|
if (thisArg != null)
|
||||||
{
|
{
|
||||||
parameters.Add(thisArg);
|
parameters.Add(new FuncParameterSyntax([], "this", new PointerTypeSyntax([], thisArg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpectSymbol(Symbol.OpenParen);
|
ExpectSymbol(Symbol.OpenParen);
|
||||||
@@ -150,6 +150,16 @@ public sealed class Parser
|
|||||||
private DefinitionSyntax ParseStruct(int startIndex)
|
private DefinitionSyntax ParseStruct(int startIndex)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
@@ -165,8 +175,7 @@ public sealed class Parser
|
|||||||
if (TryExpectSymbol(Symbol.Func))
|
if (TryExpectSymbol(Symbol.Func))
|
||||||
{
|
{
|
||||||
var funcName = ExpectIdentifier().Value;
|
var funcName = ExpectIdentifier().Value;
|
||||||
var thisArg = new FuncParameterSyntax([], "this", new CustomTypeSyntax([], name.Value));
|
var funcSignature = ParseFuncSignature(new CustomTypeSyntax([], name.Value));
|
||||||
var funcSignature = ParseFuncSignature(thisArg);
|
|
||||||
var funcBody = ParseBlock();
|
var funcBody = ParseBlock();
|
||||||
|
|
||||||
funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody));
|
funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody));
|
||||||
@@ -188,7 +197,7 @@ public sealed class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StructSyntax(GetTokens(startIndex), name.Value, fields, funcs);
|
return new StructSyntax(GetTokens(startIndex), name.Value, fields, funcs, interfaceImplementations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InterfaceSyntax ParseInterface(int startIndex)
|
private InterfaceSyntax ParseInterface(int startIndex)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public record StructFuncSyntax(IEnumerable<Token> Tokens, string Name, FuncSigna
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record StructSyntax(IEnumerable<Token> Tokens, string Name, IReadOnlyList<StructFieldSyntax> Fields, IReadOnlyList<StructFuncSyntax> Functions) : DefinitionSyntax(Tokens)
|
public record StructSyntax(IEnumerable<Token> Tokens, string Name, IReadOnlyList<StructFieldSyntax> Fields, IReadOnlyList<StructFuncSyntax> Functions, IReadOnlyList<TypeSyntax> InterfaceImplementations) : DefinitionSyntax(Tokens)
|
||||||
{
|
{
|
||||||
public override IEnumerable<SyntaxNode> GetChildren()
|
public override IEnumerable<SyntaxNode> GetChildren()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,9 +33,14 @@ public class DefinitionTable
|
|||||||
.Where(x => x.Name == type.Name);
|
.Where(x => x.Name == type.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<StructFieldSyntax> LookupStructField(StructSyntax structNode, string field)
|
public IEnumerable<StructFieldSyntax> LookupStructField(StructSyntax @struct, string field)
|
||||||
{
|
{
|
||||||
return structNode.Fields.Where(x => x.Name == field);
|
return @struct.Fields.Where(x => x.Name == field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<StructFuncSyntax> LookupStructFunc(StructSyntax @struct, string func)
|
||||||
|
{
|
||||||
|
return @struct.Functions.Where(x => x.Name == func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<InterfaceSyntax> LookupInterface(CustomTypeNode type)
|
public IEnumerable<InterfaceSyntax> LookupInterface(CustomTypeNode type)
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ public record ExternFuncNode(string Name, string CallName, FuncSignatureNode Sig
|
|||||||
|
|
||||||
public record StructFieldNode(int Index, string Name, TypeNode Type, Optional<ExpressionNode> Value) : Node;
|
public record StructFieldNode(int Index, string Name, TypeNode Type, Optional<ExpressionNode> Value) : Node;
|
||||||
|
|
||||||
public record StructNode(string Name, IReadOnlyList<StructFieldNode> Fields) : DefinitionNode;
|
public record StructFuncNode(string Name, FuncSignatureNode Signature, BlockNode Body) : Node;
|
||||||
|
|
||||||
public record InterfacenFuncNode(string Name, FuncSignatureNode Signature) : Node;
|
public record StructNode(string Name, IReadOnlyList<StructFieldNode> Fields, IReadOnlyList<StructFuncNode> Functions, IReadOnlyList<CustomTypeNode> InterfaceImplementations) : DefinitionNode;
|
||||||
|
|
||||||
public record InterfaceNode(string Name, IReadOnlyList<InterfacenFuncNode> Functions) : DefinitionNode;
|
public record InterfaceFuncNode(string Name, FuncSignatureNode Signature) : Node;
|
||||||
|
|
||||||
|
public record InterfaceNode(string Name, IReadOnlyList<InterfaceFuncNode> Functions) : DefinitionNode;
|
||||||
@@ -48,6 +48,8 @@ public record LiteralNode(TypeNode Type, string Value, LiteralKind Kind) : Expre
|
|||||||
|
|
||||||
public record StructFieldAccessNode(TypeNode Type, CustomTypeNode StructType, ExpressionNode Target, string Field) : ExpressionNode(Type);
|
public record StructFieldAccessNode(TypeNode Type, CustomTypeNode StructType, ExpressionNode Target, string Field) : ExpressionNode(Type);
|
||||||
|
|
||||||
|
public record StructFuncAccessNode(TypeNode Type, CustomTypeNode StructType, ExpressionNode Target, string Func) : ExpressionNode(Type);
|
||||||
|
|
||||||
public record InterfaceFuncAccessNode(TypeNode Type, CustomTypeNode InterfaceType, ExpressionNode Target, string FuncName) : ExpressionNode(Type);
|
public record InterfaceFuncAccessNode(TypeNode Type, CustomTypeNode InterfaceType, ExpressionNode Target, string FuncName) : ExpressionNode(Type);
|
||||||
|
|
||||||
public record StructInitializerNode(CustomTypeNode StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(StructType);
|
public record StructInitializerNode(CustomTypeNode StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(StructType);
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ public sealed class TypeChecker
|
|||||||
|
|
||||||
private InterfaceNode CheckInterfaceDefinition(InterfaceSyntax node)
|
private InterfaceNode CheckInterfaceDefinition(InterfaceSyntax node)
|
||||||
{
|
{
|
||||||
var functions = new List<InterfacenFuncNode>();
|
var functions = new List<InterfaceFuncNode>();
|
||||||
|
|
||||||
foreach (var function in node.Functions)
|
foreach (var function in node.Functions)
|
||||||
{
|
{
|
||||||
functions.Add(new InterfacenFuncNode(function.Name, CheckFuncSignature(function.Signature)));
|
functions.Add(new InterfaceFuncNode(function.Name, CheckFuncSignature(function.Signature)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InterfaceNode(node.Name, functions);
|
return new InterfaceNode(node.Name, functions);
|
||||||
@@ -87,7 +87,48 @@ public sealed class TypeChecker
|
|||||||
structFields.Add(new StructFieldNode(field.Index, field.Name, CheckType(field.Type), value));
|
structFields.Add(new StructFieldNode(field.Index, field.Name, CheckType(field.Type), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StructNode(node.Name, structFields);
|
var funcs = new List<StructFuncNode>();
|
||||||
|
|
||||||
|
foreach (var func in node.Functions)
|
||||||
|
{
|
||||||
|
var parameters = new List<FuncParameterNode>();
|
||||||
|
foreach (var parameter in func.Signature.Parameters)
|
||||||
|
{
|
||||||
|
parameters.Add(new FuncParameterNode(parameter.Name, CheckType(parameter.Type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
funcs.Add(new StructFuncNode(func.Name, CheckFuncSignature(func.Signature), CheckFuncBody(func.Body, CheckType(func.Signature.ReturnType), parameters)));
|
||||||
|
}
|
||||||
|
|
||||||
|
var interfaceImplementations = new List<CustomTypeNode>();
|
||||||
|
|
||||||
|
foreach (var interfaceImplementation in node.InterfaceImplementations)
|
||||||
|
{
|
||||||
|
var interfaceType = CheckType(interfaceImplementation);
|
||||||
|
if (interfaceType is not CustomTypeNode customType)
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic.Error("Interface implementation is not a custom type").Build());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var interfaceDefs = _definitionTable.LookupInterface(customType).ToArray();
|
||||||
|
|
||||||
|
if (interfaceDefs.Length == 0)
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic.Error($"Interface {customType.Name} is not defined").Build());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceDefs.Length > 1)
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic.Error($"Interface {customType.Name} has multiple definitions").Build());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaceImplementations.Add(customType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StructNode(node.Name, structFields, funcs, interfaceImplementations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExternFuncNode CheckExternFuncDefinition(ExternFuncSyntax node)
|
private ExternFuncNode CheckExternFuncDefinition(ExternFuncSyntax node)
|
||||||
@@ -163,11 +204,6 @@ public sealed class TypeChecker
|
|||||||
{
|
{
|
||||||
TypeNode? type = null;
|
TypeNode? type = null;
|
||||||
|
|
||||||
if (statement.ExplicitType.HasValue)
|
|
||||||
{
|
|
||||||
type = CheckType(statement.ExplicitType.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
var assignment = Optional<ExpressionNode>.Empty();
|
var assignment = Optional<ExpressionNode>.Empty();
|
||||||
if (statement.Assignment.HasValue)
|
if (statement.Assignment.HasValue)
|
||||||
{
|
{
|
||||||
@@ -176,6 +212,11 @@ public sealed class TypeChecker
|
|||||||
type = boundValue.Type;
|
type = boundValue.Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (statement.ExplicitType.HasValue)
|
||||||
|
{
|
||||||
|
type = CheckType(statement.ExplicitType.Value);
|
||||||
|
}
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Diagnostics not implemented");
|
throw new NotImplementedException("Diagnostics not implemented");
|
||||||
@@ -373,9 +414,9 @@ public sealed class TypeChecker
|
|||||||
var @interface = interfaces[0];
|
var @interface = interfaces[0];
|
||||||
|
|
||||||
var interfaceFuncs = _definitionTable.LookupInterfaceFunc(@interface, expression.Member).ToArray();
|
var interfaceFuncs = _definitionTable.LookupInterfaceFunc(@interface, expression.Member).ToArray();
|
||||||
if (interfaces.Length > 0)
|
if (interfaceFuncs.Length > 0)
|
||||||
{
|
{
|
||||||
if (interfaces.Length > 1)
|
if (interfaceFuncs.Length > 1)
|
||||||
{
|
{
|
||||||
throw new CheckException(Diagnostic.Error($"Interface {customType} has multiple functions with the name {expression.Member}").Build());
|
throw new CheckException(Diagnostic.Error($"Interface {customType} has multiple functions with the name {expression.Member}").Build());
|
||||||
}
|
}
|
||||||
@@ -411,6 +452,21 @@ public sealed class TypeChecker
|
|||||||
|
|
||||||
return new StructFieldAccessNode(CheckType(field.Type), customType, boundExpression, expression.Member);
|
return new StructFieldAccessNode(CheckType(field.Type), customType, boundExpression, expression.Member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var funcs = _definitionTable.LookupStructFunc(@struct, expression.Member).ToArray();
|
||||||
|
if (funcs.Length > 0)
|
||||||
|
{
|
||||||
|
if (funcs.Length > 1)
|
||||||
|
{
|
||||||
|
throw new CheckException(Diagnostic.Error($"Struct {customType} has multiple functions with the name {expression.Member}").Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
var func = funcs[0];
|
||||||
|
|
||||||
|
var parameters = func.Signature.Parameters.Select(x => CheckType(x.Type)).ToList();
|
||||||
|
var returnType = CheckType(func.Signature.ReturnType);
|
||||||
|
return new StructFuncAccessNode(new FuncTypeNode(parameters, returnType), customType, boundExpression, expression.Member);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user