using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using System.Text;
using Sunweaver.DataPrototypes;
namespace Sunweaver.Commands.Abstracts
{
public abstract class BinaryBooleanLogic : BasePair
{
protected VirtualMachine VM = null;
public override void Implementation(VirtualMachine VM)
{
if (VM.BoolStack.Count() < 2)
return;
bool b = VM.BoolStack.Pop();
bool a = VM.BoolStack.Pop();
this.VM = VM;
Operation(a, b);
}
internal override void Compile(ILGenerator il, Locals locals)
{
var cont = il.DefineLabel();
il.Emit(OpCodes.Ldloc, locals[typeof(VirtualMachine)]);
il.Emit(OpCodes.Ldfld, typeof(VirtualMachine).GetField("BoolStack"));
il.Emit(OpCodes.Call, typeof(BoolStack).GetMethod("Count"));
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Conv_I8);
il.Emit(OpCodes.Blt_S, cont); // We dont return, just go the end of this method
il.Emit(OpCodes.Ldloc, locals[typeof(VirtualMachine)]);
il.Emit(OpCodes.Ldfld, typeof(VirtualMachine).GetField("BoolStack"));
il.Emit(OpCodes.Call, typeof(BoolStack).GetMethod("Pop"));
il.Emit(OpCodes.Stloc, locals[typeof(bool), 1]);
il.Emit(OpCodes.Ldloc, locals[typeof(VirtualMachine)]);
il.Emit(OpCodes.Ldfld, typeof(VirtualMachine).GetField("BoolStack"));
il.Emit(OpCodes.Call, typeof(BoolStack).GetMethod("Pop"));
il.Emit(OpCodes.Stloc, locals[typeof(bool), 0]);
CompileOperation(il, locals);
il.MarkLabel(cont);
}
///
/// Abstract interface that child classes implement
///
/// Top value from the bool stack
/// Second to top value on the bool stack
public abstract void Operation(bool a, bool b);
///
/// Abstract interface that child classes implement
///
///
/// The boolean variables for the operation are stored in bool0 and bool1 of locals.
///
public abstract void CompileOperation(ILGenerator il, Locals locals);
}
}