Array type works with args
This commit is contained in:
@@ -74,6 +74,7 @@ public class Generator
|
||||
}
|
||||
case NubStructType:
|
||||
case NubPointerType:
|
||||
case NubArrayType:
|
||||
{
|
||||
return "l";
|
||||
}
|
||||
@@ -120,6 +121,7 @@ public class Generator
|
||||
return ":" + nubCustomType.Name;
|
||||
}
|
||||
case NubPointerType:
|
||||
case NubArrayType:
|
||||
{
|
||||
return "l";
|
||||
}
|
||||
@@ -169,6 +171,7 @@ public class Generator
|
||||
return ":" + nubCustomType.Name;
|
||||
}
|
||||
case NubPointerType:
|
||||
case NubArrayType:
|
||||
{
|
||||
return "l";
|
||||
}
|
||||
@@ -221,6 +224,7 @@ public class Generator
|
||||
return definition.Fields.Sum(f => QbeTypeSize(f.Type));
|
||||
}
|
||||
case NubPointerType:
|
||||
case NubArrayType:
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
@@ -259,7 +263,7 @@ public class Generator
|
||||
_builder.AppendLine("@start");
|
||||
|
||||
_builder.AppendLine(" # Variable allocation");
|
||||
|
||||
|
||||
foreach (var parameter in node.Parameters)
|
||||
{
|
||||
var parameterName = parameter.Name;
|
||||
@@ -287,8 +291,8 @@ public class Generator
|
||||
var pointerLabel = GenName();
|
||||
_builder.AppendLine($" %{pointerLabel} ={SQT(parameter.Type)} alloc8 {QbeTypeSize(parameter.Type)}");
|
||||
_builder.AppendLine($" storel %{parameterName}, %{pointerLabel}");
|
||||
|
||||
|
||||
|
||||
|
||||
_variables[parameter.Name] = new Variable
|
||||
{
|
||||
Pointer = $"%{pointerLabel}",
|
||||
@@ -474,15 +478,23 @@ public class Generator
|
||||
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
|
||||
{
|
||||
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
|
||||
if (_variables.TryGetValue(variableAssignment.Name, out var existingVariable))
|
||||
{
|
||||
Pointer = $"%{pointerLabel}",
|
||||
Type = variableAssignment.Value.Type
|
||||
};
|
||||
_builder.AppendLine($" storel {result}, {existingVariable.Pointer}");
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
Pointer = $"%{pointerLabel}",
|
||||
Type = variableAssignment.Value.Type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateWhile(WhileNode whileStatement)
|
||||
@@ -511,6 +523,7 @@ public class Generator
|
||||
return expression switch
|
||||
{
|
||||
AddressOfNode addressOf => GenerateAddressOf(addressOf),
|
||||
ArrayIndexNode arrayIndex => GenerateArrayIndex(arrayIndex),
|
||||
BinaryExpressionNode binaryExpression => GenerateBinaryExpression(binaryExpression),
|
||||
CastNode cast => GenerateCast(cast),
|
||||
DereferenceNode dereference => GenerateDereference(dereference),
|
||||
@@ -519,11 +532,29 @@ public class Generator
|
||||
LiteralNode literal => GenerateLiteral(literal),
|
||||
StructInitializerNode structInitializer => GenerateStructInitializer(structInitializer),
|
||||
UnaryExpressionNode unaryExpression => GenerateUnaryExpression(unaryExpression),
|
||||
StructFieldAccessorNode structMemberAccessor => GenerateStructFieldAccessor(structMemberAccessor),
|
||||
MemberAccessNode memberAccess => GenerateMemberAccess(memberAccess),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(expression))
|
||||
};
|
||||
}
|
||||
|
||||
private string GenerateArrayIndex(ArrayIndexNode arrayIndex)
|
||||
{
|
||||
var array = GenerateExpression(arrayIndex.Expression);
|
||||
var index = GenerateExpression(arrayIndex.Index);
|
||||
|
||||
var arrayBaseType = ((NubArrayType)arrayIndex.Expression.Type).BaseType;
|
||||
|
||||
var firstItem = GenName();
|
||||
_builder.AppendLine($" %{firstItem} =l add {array}, 8");
|
||||
var adjustedIndex = GenName();
|
||||
_builder.AppendLine($" %{adjustedIndex} =l mul {index}, {QbeTypeSize(arrayBaseType)}");
|
||||
var indexLabel = GenName();
|
||||
_builder.AppendLine($" %{indexLabel} ={SQT(arrayIndex.Type)} add %{firstItem}, %{adjustedIndex}");
|
||||
var outputLabel = GenName();
|
||||
_builder.AppendLine($" %{outputLabel} =l load{SQT(arrayBaseType)} %{indexLabel}");
|
||||
return $"%{outputLabel}";
|
||||
}
|
||||
|
||||
private string GenerateDereference(DereferenceNode dereference)
|
||||
{
|
||||
var result = GenerateExpression(dereference.Expression);
|
||||
@@ -1331,7 +1362,7 @@ public class Generator
|
||||
_builder.AppendLine($" %{outputLabel} =s neg {operand}");
|
||||
return $"%{outputLabel}";
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case UnaryExpressionOperator.Invert:
|
||||
@@ -1354,42 +1385,60 @@ public class Generator
|
||||
throw new NotSupportedException($"Unary operator {unaryExpression.Operator} for type {unaryExpression.Operand.Type} not supported");
|
||||
}
|
||||
|
||||
private string GenerateStructFieldAccessor(StructFieldAccessorNode structFieldAccessor)
|
||||
private string GenerateMemberAccess(MemberAccessNode memberAccess)
|
||||
{
|
||||
var structType = structFieldAccessor.Struct.Type;
|
||||
var structDefinition = _definitions
|
||||
.OfType<StructDefinitionNode>()
|
||||
.FirstOrDefault(s => s.Name == structType.Name);
|
||||
var expression = GenerateExpression(memberAccess.Expression);
|
||||
|
||||
if (structDefinition == null)
|
||||
switch (memberAccess.Expression.Type)
|
||||
{
|
||||
throw new Exception($"Struct {structType.Name} is not defined");
|
||||
}
|
||||
|
||||
var @struct = GenerateExpression(structFieldAccessor.Struct);
|
||||
|
||||
var fieldIndex = -1;
|
||||
for (var i = 0; i < structDefinition.Fields.Count; i++)
|
||||
{
|
||||
if (structDefinition.Fields[i].Name == structFieldAccessor.Field)
|
||||
case NubArrayType:
|
||||
{
|
||||
fieldIndex = i;
|
||||
if (memberAccess.Member == "count")
|
||||
{
|
||||
var outputLabel = GenName();
|
||||
_builder.AppendLine($" %{outputLabel} =l loadl {expression}");
|
||||
return $"%{outputLabel}";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NubStructType structType:
|
||||
{
|
||||
var structDefinition = _definitions
|
||||
.OfType<StructDefinitionNode>()
|
||||
.FirstOrDefault(s => s.Name == structType.Name);
|
||||
|
||||
if (structDefinition == null)
|
||||
{
|
||||
throw new Exception($"Struct {structType.Name} is not defined");
|
||||
}
|
||||
|
||||
var fieldIndex = -1;
|
||||
for (var i = 0; i < structDefinition.Fields.Count; i++)
|
||||
{
|
||||
if (structDefinition.Fields[i].Name == memberAccess.Member)
|
||||
{
|
||||
fieldIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldIndex == -1)
|
||||
{
|
||||
throw new Exception($"Field {memberAccess.Member} is not defined in struct {structType.Name}");
|
||||
}
|
||||
|
||||
var offsetLabel = GenName();
|
||||
_builder.AppendLine($" %{offsetLabel} =l add {expression}, {fieldIndex * QbeTypeSize(memberAccess.Type)}");
|
||||
|
||||
var outputLabel = GenName();
|
||||
_builder.AppendLine($" %{outputLabel} ={SQT(memberAccess.Type)} load{SQT(memberAccess.Type)} %{offsetLabel}");
|
||||
|
||||
return $"%{outputLabel}";
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldIndex == -1)
|
||||
{
|
||||
throw new Exception($"Field {structFieldAccessor.Field} is not defined in struct {structType.Name}");
|
||||
}
|
||||
|
||||
var offsetLabel = GenName();
|
||||
_builder.AppendLine($" %{offsetLabel} =l add {@struct}, {fieldIndex * QbeTypeSize(structFieldAccessor.Type)}");
|
||||
|
||||
var outputLabel = GenName();
|
||||
_builder.AppendLine($" %{outputLabel} ={SQT(structFieldAccessor.Type)} load{SQT(structFieldAccessor.Type)} %{offsetLabel}");
|
||||
|
||||
return $"%{outputLabel}";
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(memberAccess.Expression.Type));
|
||||
}
|
||||
|
||||
private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall)
|
||||
|
||||
Reference in New Issue
Block a user