public override int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info) { loc = Term.GenerateCode(loc, vm, info); //Only execute RepTerm if no conditional BoolOpr or if the left hand side is not enough to determine result if (Operator != Operators.COR && Operator != Operators.CAND) { loc = RepTerm.GenerateCode(loc, vm, info); } var type = GetExpressionType(info); if (type == Type.BOOL) { switch (Operator) { case Operators.AND: //Can only work with int operations: //If both terms are true (=1), they result in 2 (1+1=2) vm.IntAdd(loc++); //Test if result == 2 vm.IntLoad(loc++, 2); vm.IntEQ(loc++); break; case Operators.OR: vm.IntAdd(loc++); vm.IntLoad(loc++, 1); vm.IntGE(loc++); //>=1 => only one term has to be true break; case Operators.CAND: //If true is on the top of the stack, the second condition has to be evaluated //1. Jump if left hand side was false int conditionalJump = loc++; //2. a. Evaluate right hand side if left hand side was true loc = RepTerm.GenerateCode(loc, vm, info); vm.CondJump(conditionalJump, loc + 1); //Step 1: Only now the jump destination is known! vm.UncondJump(loc, loc + 2); ++loc; //Leap over the load(0) instruction //2. b. Evaluate to false vm.IntLoad(loc++, 0); break; case Operators.COR: //If false is on the top of the stack, the second condition has to be evaluated //1. Invert top of stack: vm.IntLoad(loc++, 1); vm.IntNE(loc++); //2. Jump if left hand side was true int conditionalJump2 = loc++; //3. a. Evaluate right hand side if left hand side was false loc = RepTerm.GenerateCode(loc, vm, info); vm.CondJump(conditionalJump2, loc + 1); vm.UncondJump(loc, loc + 2); ++loc; //3. b. Evaluate to true (without evaluating right hand side) vm.IntLoad(loc++, 1); break; default: throw new IVirtualMachine.InternalError( "There's an invalid operator in ASTBoolOpr. Operator: " + Operator.ToString()); } } else { throw new IVirtualMachine.InternalError( "There's an invalid operand in ASTBoolOpr. Oprand: " + type.ToString()); } return(loc); }