This commit is contained in:
nub31
2025-05-17 18:51:51 +02:00
parent 97611317f7
commit 007a4f03ac
3 changed files with 56 additions and 31 deletions

View File

@@ -1,6 +1,15 @@
import c import c
global func main(argc: i64, argv: i64) { struct Test {
x = "TEST" text: ^string
printf("%s\n", ^&x) }
global func main(argc: i64, argv: i64) {
text = "test"
x = new Test {
text = &text
}
printf("%s\n", x.text^)
} }

View File

@@ -220,6 +220,10 @@ public class Generator
return definition.Fields.Sum(f => QbeTypeSize(f.Type)); return definition.Fields.Sum(f => QbeTypeSize(f.Type));
} }
case NubPointerType:
{
return 8;
}
default: default:
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@@ -254,6 +258,8 @@ public class Generator
_builder.AppendLine($"({string.Join(", ", parameterStrings)}) {{"); _builder.AppendLine($"({string.Join(", ", parameterStrings)}) {{");
_builder.AppendLine("@start"); _builder.AppendLine("@start");
_builder.AppendLine(" # Variable allocation");
foreach (var parameter in node.Parameters) foreach (var parameter in node.Parameters)
{ {
var parameterName = parameter.Name; var parameterName = parameter.Name;
@@ -278,23 +284,35 @@ public class Generator
break; break;
} }
_variables.Add(parameter.Name, new Variable var pointerLabel = GenName();
_builder.AppendLine($" %{pointerLabel} ={SQT(parameter.Type)} alloc8 {QbeTypeSize(parameter.Type)}");
_builder.AppendLine($" storel %{parameterName}, %{pointerLabel}");
_variables[parameter.Name] = new Variable
{ {
Identifier = $"%{parameterName}", Pointer = $"%{pointerLabel}",
Type = parameter.Type Type = parameter.Type
}); };
} }
_builder.AppendLine(" # End variable allocation");
_builder.AppendLine();
GenerateBlock(node.Body); GenerateBlock(node.Body);
if (node.Body.Statements.Last() is not ReturnNode) if (node.Body.Statements.Last() is not ReturnNode)
{ {
if (!node.ReturnType.HasValue && node.Name == "main") if (!node.ReturnType.HasValue && node.Name == "main")
{ {
_builder.AppendLine();
_builder.AppendLine(" # Implicit return for main");
_builder.AppendLine(" ret 0"); _builder.AppendLine(" ret 0");
} }
else if (!node.ReturnType.HasValue) else if (!node.ReturnType.HasValue)
{ {
_builder.AppendLine();
_builder.AppendLine(" # Implicit return");
_builder.AppendLine(" ret"); _builder.AppendLine(" ret");
} }
} }
@@ -456,9 +474,13 @@ public class Generator
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment) private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
{ {
var result = GenerateExpression(variableAssignment.Value); var result = GenerateExpression(variableAssignment.Value);
var pointerLabel = GenName();
_builder.AppendLine($" %{pointerLabel} ={SQT(variableAssignment.Value.Type)} alloc8 {QbeTypeSize(variableAssignment.Value.Type)}");
_builder.AppendLine($" storel {result}, %{pointerLabel}");
_variables[variableAssignment.Name] = new Variable _variables[variableAssignment.Name] = new Variable
{ {
Identifier = result, Pointer = $"%{pointerLabel}",
Type = variableAssignment.Value.Type Type = variableAssignment.Value.Type
}; };
} }
@@ -1180,7 +1202,10 @@ public class Generator
private string GenerateIdentifier(IdentifierNode identifier) private string GenerateIdentifier(IdentifierNode identifier)
{ {
return _variables[identifier.Identifier].Identifier; var variable = _variables[identifier.Identifier];
var outputLabel = GenName();
_builder.AppendLine($" %{outputLabel} ={SQT(identifier.Type)} load{SQT(identifier.Type)} {variable.Pointer}");
return $"%{outputLabel}";
} }
private string GenerateLiteral(LiteralNode literal) private string GenerateLiteral(LiteralNode literal)
@@ -1317,23 +1342,8 @@ public class Generator
} }
case UnaryExpressionOperator.Dereference: case UnaryExpressionOperator.Dereference:
{ {
// Handle dereference operator (assuming operand is a pointer) _builder.AppendLine($" %{outputLabel} ={SQT(unaryExpression.Type)} load{SQT(unaryExpression.Type)} {operand}");
// This would load the value from the address stored in the operand return $"%{outputLabel}";
if (unaryExpression.Type is NubPrimitiveType primitiveType)
{
_builder.AppendLine($" %{outputLabel} ={SQT(primitiveType)} load{SQT(primitiveType)} {operand}");
return $"%{outputLabel}";
}
if (unaryExpression.Type is NubStructType structType)
{
// For struct types, we'd need to handle differently
// This is a simplified version
_builder.AppendLine($" %{outputLabel} =l copy {operand}");
return $"%{outputLabel}";
}
break;
} }
default: default:
{ {
@@ -1397,7 +1407,7 @@ public class Generator
private class Variable private class Variable
{ {
public required string Identifier { get; init; } public required string Pointer { get; init; }
public required NubType Type { get; init; } public required NubType Type { get; init; }
} }
} }

View File

@@ -359,11 +359,6 @@ public class Parser
return new StructInitializerNode(type, initializers); return new StructInitializerNode(type, initializers);
} }
case Symbol.Caret:
{
var expression = ParsePrimaryExpression();
return new UnaryExpressionNode(UnaryExpressionOperator.Dereference, expression);
}
case Symbol.Ampersand: case Symbol.Ampersand:
{ {
var expression = ParsePrimaryExpression(); var expression = ParsePrimaryExpression();
@@ -413,6 +408,10 @@ public class Parser
{ {
var field = ExpectIdentifier(); var field = ExpectIdentifier();
result = new StructFieldAccessorNode(result, field.Value); result = new StructFieldAccessorNode(result, field.Value);
if (TryExpectSymbol(Symbol.Caret))
{
result = new UnaryExpressionNode(UnaryExpressionOperator.Dereference, result);
}
} while (TryExpectSymbol(Symbol.Period)); } while (TryExpectSymbol(Symbol.Period));
return result; return result;
@@ -435,6 +434,11 @@ public class Parser
} }
} }
if (TryExpectSymbol(Symbol.Caret))
{
return new UnaryExpressionNode(UnaryExpressionOperator.Dereference, new IdentifierNode(identifier.Value));
}
return new IdentifierNode(identifier.Value); return new IdentifierNode(identifier.Value);
} }
@@ -452,8 +456,10 @@ public class Parser
private NubType ParseType() private NubType ParseType()
{ {
var pointer = TryExpectSymbol(Symbol.Caret);
var name = ExpectIdentifier().Value; var name = ExpectIdentifier().Value;
return NubType.Parse(name); var type = NubType.Parse(name);
return pointer ? new NubPointerType(type) : type;
} }
private Token ExpectToken() private Token ExpectToken()