void CCodeGenerationVisitor::Visit(CUnaryOp &AStmt) { ETokenType OpType = AStmt.GetType(); CExpression *Arg = AStmt.GetArgument(); if (OpType == TOKEN_TYPE_OPERATION_AMPERSAND) { Arg->Accept(Addr); } else if (OpType == TOKEN_TYPE_KEYWORD && AStmt.GetName() == "sizeof") { Asm.Add(PUSH, Arg->GetResultType()->GetSize()); } else { if (Arg->GetResultType()->IsFloat()) { Arg->Accept(*this); if (OpType == TOKEN_TYPE_OPERATION_MINUS) { Asm.Add(FLD, mem(ESP)); Asm.Add(FCHS); Asm.Add(FSTP, mem(ESP)); } else if (OpType == TOKEN_TYPE_OPERATION_INCREMENT || OpType == TOKEN_TYPE_OPERATION_DECREMENT) { Arg->Accept(Addr); Asm.Add(POP, EBX); Asm.Add(FLD1); if (OpType == TOKEN_TYPE_OPERATION_INCREMENT) { Asm.Add(FADD, mem(ESP)); } else { Asm.Add(FSUBR, mem(ESP)); } Asm.Add(FSTP, mem(ESP)); Asm.Add(MOV, mem(ESP), EAX); Asm.Add(MOV, EAX, mem(EBX)); } else if (OpType == TOKEN_TYPE_OPERATION_LOGIC_NOT) { string TrueLabel = Asm.GenerateLabel(); string EndLabel = Asm.GenerateLabel(); Asm.Add(FLD, mem(ESP)); Asm.Add(ADD, TypeSize::Float, ESP); Asm.Add(FTST); Asm.Add(FSTSW, AX); Asm.Add(SAHF); Asm.Add(JNE, TrueLabel); Asm.Add(MOV, 1, EAX); Asm.Add(JMP, EndLabel); Asm.Add(TrueLabel); Asm.Add(MOV, 0, EAX); Asm.Add(EndLabel); Asm.Add(PUSH, EAX); } } else { if (OpType == TOKEN_TYPE_OPERATION_INCREMENT || OpType == TOKEN_TYPE_OPERATION_DECREMENT) { Arg->Accept(Addr); Arg->Accept(*this); Asm.Add(POP, EAX); Asm.Add(POP, EBX); Asm.Add(IntOperationCmd[OpType], EAX); Asm.Add(MOV, EAX, mem(EBX)); } else { Arg->Accept(*this); Asm.Add(POP, EAX); if (OpType == TOKEN_TYPE_OPERATION_ASTERISK) { Asm.Add(MOV, mem(EAX), EAX); } else if (OpType == TOKEN_TYPE_OPERATION_MINUS) { Asm.Add(NEG, EAX); } else if (OpType == TOKEN_TYPE_OPERATION_BITWISE_NOT) { Asm.Add(NOT, EAX); } else if (OpType == TOKEN_TYPE_OPERATION_LOGIC_NOT) { string TrueLabel = Asm.GenerateLabel(); string EndLabel = Asm.GenerateLabel(); Asm.Add(CMP, 0, EAX); Asm.Add(JNE, TrueLabel); Asm.Add(MOV, 1, EAX); Asm.Add(JMP, EndLabel); Asm.Add(TrueLabel); Asm.Add(MOV, 0, EAX); Asm.Add(EndLabel); } } Asm.Add(PUSH, EAX); } } }