This commit is contained in:
nub31
2025-09-16 16:02:08 +02:00
parent 46432d2f8e
commit c9e34ae7e2
8 changed files with 130 additions and 36 deletions

View File

@@ -528,6 +528,9 @@ public class QBEGenerator
case WhileNode whileStatement:
EmitWhile(whileStatement);
break;
case ForArrayNode forArray:
EmitForArray(forArray);
break;
default:
throw new ArgumentOutOfRangeException(nameof(statement));
}
@@ -615,6 +618,54 @@ public class QBEGenerator
_breakLabels.Pop();
}
// todo(nub31): Implement index ident
private void EmitForArray(ForArrayNode forArray)
{
var target = EmitExpression(forArray.Target);
var arrayStart = TmpName();
_writer.Indented($"{arrayStart} =l add {target}, 8");
var size = TmpName();
_writer.Indented($"{size} =l loadl {target}");
var count = TmpName();
_writer.Indented($"{count} =l copy 0");
var loopLabel = LabelName();
_writer.WriteLine(loopLabel);
var condition = TmpName();
_writer.Indented($"{condition} =w cultl {count}, {size}");
var continueLabel = LabelName();
var endLabel = LabelName();
_writer.Indented($"jnz {condition}, {continueLabel}, {endLabel}");
_writer.WriteLine(continueLabel);
var arrayOffset = TmpName();
_writer.Indented($"{arrayOffset} =l mul {count}, {SizeOf(forArray.ArrayType.ElementType)}");
var elementAddress = TmpName();
_writer.Indented($"{elementAddress} =l add {arrayStart}, {arrayOffset}");
if (forArray.ArrayType.ElementType is StructTypeNode)
{
_writer.Indented($"%{forArray.ElementIdent} =l copy {elementAddress}");
}
else
{
var element = EmitLoad(forArray.ArrayType.ElementType, elementAddress);
_writer.Indented($"%{forArray.ElementIdent} {QBEAssign(forArray.ArrayType.ElementType)} copy {element}");
}
EmitBlock(forArray.Body);
_writer.Indented($"{count} =l add {count}, 1");
_writer.Indented($"jmp {loopLabel}");
_writer.WriteLine(endLabel);
}
private string EmitExpression(ExpressionNode expression)
{
return expression switch
@@ -647,10 +698,12 @@ public class QBEGenerator
private string EmitVariableIdentifier(VariableIdentifierNode variableIdent)
{
var address = EmitAddressOfVariableIdent(variableIdent);
if (variableIdent.Type is StructTypeNode)
{
return address;
}
return variableIdent.Type.IsSimpleType(out _, out _)
? EmitLoad(variableIdent.Type, address)
: address;
return EmitLoad(variableIdent.Type, address);
}
private string EmitParameterFuncIdentifier(FuncParameterIdentifierNode funcParameterIdent)