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); } }