private void CGBinOpExp(FuncInfo funcInfo, DoubleOperationExpNode node, int a) { switch (node.OpType) { case TokenType.And: case TokenType.Or: { int b = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp1, b, 1); funcInfo.FreeReg(); if (node.OpType == TokenType.And) { funcInfo.EmitTestSet(a, b, 0); } else { funcInfo.EmitTestSet(a, b, 1); } int jmpPC = funcInfo.EmitJMP(0, 0); int c = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp2, c, 1); funcInfo.FreeReg(); funcInfo.EmitMove(a, c); funcInfo.FixSBX(jmpPC, funcInfo.PC() - jmpPC); break; } default: { int b = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp1, b, 1); int c = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp2, c, 1); funcInfo.EmitDoubleOperator(a, b, c, node.OpType); funcInfo.FreeRegs(2); break; } } }