...
This commit is contained in:
@@ -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^)
|
||||||
}
|
}
|
||||||
@@ -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,24 +1342,9 @@ 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
|
|
||||||
if (unaryExpression.Type is NubPrimitiveType primitiveType)
|
|
||||||
{
|
|
||||||
_builder.AppendLine($" %{outputLabel} ={SQT(primitiveType)} load{SQT(primitiveType)} {operand}");
|
|
||||||
return $"%{outputLabel}";
|
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:
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
@@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user