...
This commit is contained in:
@@ -487,6 +487,9 @@ public class QBEGenerator
|
||||
case AssignmentNode assignment:
|
||||
EmitCopyInto(assignment.Value, EmitAddressOf(assignment.Target));
|
||||
break;
|
||||
case BlockNode block:
|
||||
EmitBlock(block);
|
||||
break;
|
||||
case BreakNode:
|
||||
EmitScopeCleanup();
|
||||
_writer.Indented($"jmp {_breakLabels.Peek()}");
|
||||
@@ -510,15 +513,9 @@ public class QBEGenerator
|
||||
case VariableDeclarationNode variableDeclaration:
|
||||
EmitVariableDeclaration(variableDeclaration);
|
||||
break;
|
||||
case DeferNode defer:
|
||||
Scope.DeferredStatements.Push(defer.Statement);
|
||||
break;
|
||||
case WhileNode whileStatement:
|
||||
EmitWhile(whileStatement);
|
||||
break;
|
||||
case ForArrayNode forArray:
|
||||
EmitForArray(forArray);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(statement));
|
||||
}
|
||||
@@ -526,11 +523,6 @@ public class QBEGenerator
|
||||
|
||||
private void EmitScopeCleanup()
|
||||
{
|
||||
while (Scope.DeferredStatements.TryPop(out var deferredStatement))
|
||||
{
|
||||
EmitStatement(deferredStatement);
|
||||
}
|
||||
|
||||
while (Scope.Variables.TryPop(out var variable))
|
||||
{
|
||||
if (variable.Type is NubStructType structType)
|
||||
@@ -613,54 +605,6 @@ 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 NubStructType)
|
||||
{
|
||||
_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 expr)
|
||||
{
|
||||
return expr switch
|
||||
@@ -1338,7 +1282,6 @@ public class QBEGenerator
|
||||
|
||||
public class Scope
|
||||
{
|
||||
public readonly Stack<StatementNode> DeferredStatements = [];
|
||||
public readonly Stack<Variable> Variables = [];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user