WhileStatement
using CLanguage.Compiler;
using CLanguage.Interpreter;
using System.Runtime.CompilerServices;
namespace CLanguage.Syntax
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class WhileStatement : Statement
{
public bool IsDo { get; set; }
public Expression Condition { get; set; }
public Block Loop { get; set; }
public override bool AlwaysReturns => false;
public WhileStatement(bool isDo, Expression condition, Block loop)
{
IsDo = isDo;
Condition = condition;
Loop = loop;
}
protected override void DoEmit(EmitContext parentContext)
{
Label label = parentContext.DefineLabel();
Label l = parentContext.DefineLabel();
Label label2 = parentContext.DefineLabel();
EmitContext emitContext = parentContext.PushLoop(label2, label);
if (IsDo) {
emitContext.EmitLabel(l);
Loop.Emit(emitContext);
emitContext.EmitLabel(label);
Condition.Emit(emitContext);
emitContext.EmitCastToBoolean(Condition.GetEvaluatedCType(emitContext));
emitContext.Emit(OpCode.BranchIfFalse, label2);
emitContext.Emit(OpCode.Jump, label);
} else {
emitContext.EmitLabel(label);
Condition.Emit(emitContext);
emitContext.EmitCastToBoolean(Condition.GetEvaluatedCType(emitContext));
emitContext.Emit(OpCode.BranchIfFalse, label2);
emitContext.EmitLabel(l);
parentContext.BeginBlock(Loop);
Loop.Emit(emitContext);
emitContext.Emit(OpCode.Jump, label);
}
emitContext.EmitLabel(label2);
}
public override string ToString()
{
if (IsDo)
return string.Format("do {1} while({0});", Condition, Loop);
return $"""{Condition}""{Loop}""";
}
public override void AddDeclarationToBlock(BlockContext context)
{
Loop.AddDeclarationToBlock(context);
}
}
}