This commit is contained in:
nub31
2025-08-13 21:50:42 +02:00
parent c2a6afdbbd
commit 9ddac8edfe
4 changed files with 38 additions and 7 deletions

View File

@@ -1,6 +1,11 @@
extern func puts(text: cstring)
struct Human
interface Test
{
func print()
}
struct Human : Test
{
name: cstring
@@ -12,7 +17,7 @@ struct Human
func main(args: []cstring): i64
{
let human = alloc Human {
let human: Test = alloc Human {
name = "oliver"
}

View File

@@ -424,7 +424,7 @@ public partial class QBEGenerator
private Val EmitStructFuncCall(StructFuncCallNode structFuncCall)
{
var expression = EmitExpression(structFuncCall.Expression);
var thisParameter = EmitUnwrap(EmitExpression(structFuncCall.ThisParam));
var thisParameter = EmitUnwrap(EmitExpression(structFuncCall.StructExpression));
List<string> parameterStrings = [$"l {thisParameter}"];
@@ -470,7 +470,32 @@ public partial class QBEGenerator
private Val EmitInterfaceFuncCall(InterfaceFuncCallNode interfaceFuncCall)
{
throw new NotImplementedException();
var expression = EmitExpression(interfaceFuncCall.Expression);
var thisParameter = EmitUnwrap(EmitExpression(interfaceFuncCall.InterfaceExpression));
_writer.Indented($"{thisParameter} =l add {thisParameter}, 8");
_writer.Indented($"{thisParameter} =l loadl {thisParameter}");
List<string> parameterStrings = [$"l {thisParameter}"];
foreach (var parameter in interfaceFuncCall.Parameters)
{
var copy = EmitCreateCopyOrInitialize(parameter);
parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}");
}
var funcPointer = EmitUnwrap(expression);
if (interfaceFuncCall.Type is VoidTypeNode)
{
_writer.Indented($"call {funcPointer}({string.Join(", ", parameterStrings)})");
return new Val(string.Empty, interfaceFuncCall.Type, ValKind.Direct);
}
else
{
var outputName = TmpName();
_writer.Indented($"{outputName} {QBEAssign(interfaceFuncCall.Type)} call {funcPointer}({string.Join(", ", parameterStrings)})");
return new Val(outputName, interfaceFuncCall.Type, ValKind.Direct);
}
}
private Val EmitInterfaceInitializer(InterfaceInitializerNode interfaceInitializer, string? destination = null)

View File

@@ -269,6 +269,7 @@ public partial class QBEGenerator
{
case ArrayInitializerNode:
case StructInitializerNode:
case InterfaceInitializerNode:
case LiteralNode { Kind: LiteralKind.String }:
{
destination = EmitUnwrap(EmitExpression(source));
@@ -282,7 +283,7 @@ public partial class QBEGenerator
private string EmitCreateCopyOrInitialize(ExpressionNode source)
{
// If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying
// If the source is a value which is not used yet such as an array/struct/interface initializer or literal, we can skip copying
if (EmitTryCreateWithoutCopy(source, out var uncopiedValue))
{
return uncopiedValue;

View File

@@ -30,9 +30,9 @@ public record UnaryExpressionNode(TypeNode Type, UnaryOperator Operator, Express
public record FuncCallNode(TypeNode Type, ExpressionNode Expression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
public record StructFuncCallNode(TypeNode Type, ExpressionNode Expression, ExpressionNode ThisParam, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
public record StructFuncCallNode(TypeNode Type, ExpressionNode Expression, ExpressionNode StructExpression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
public record InterfaceFuncCallNode(TypeNode Type, ExpressionNode Expression, ExpressionNode ThisParam, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
public record InterfaceFuncCallNode(TypeNode Type, ExpressionNode Expression, ExpressionNode InterfaceExpression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
public record VariableIdentNode(TypeNode Type, string Name) : ExpressionNode(Type);