ExprNode* Parser :: ParseMember(ExprNode* left){ SymbolType *type = left->getType(); if ( dynamic_cast<TypedefSymbol*>(type)) type = type->getType(); StructSymbol *struct_type = 0; if(dynamic_cast<PointerSymbol*>(type)) struct_type = dynamic_cast<StructSymbol*>(dynamic_cast<PointerSymbol*>(type)->pointer); else struct_type = dynamic_cast<StructSymbol*>(type); errorIf(!struct_type, "Left operand of . or -> must be a structure", scan.Get()); Token* opTok = scan.Get(); Token* token =scan.GetNext(); errorIf(token->Type != _IDENTIFIER , "Right operand of . or -> must be a identifier", token); string fieldName = token->Value; if (!struct_type->m_fields->exists(fieldName)) fieldName = '%' + fieldName; errorIf(!struct_type->m_fields->exists(fieldName), "Undefined field in structure",token); scan.Next(); ExprNode* right = new IdentifierNode(token, dynamic_cast<VarSymbol*>(struct_type->m_fields->find_symbol(fieldName))); return new BinOpNode(opTok, left, right); }
void BinOpNode::generate(AsmCode & code) { SymbolType * leftType = left->getType(); SymbolType * rightType = right->getType(); ArraySymbol* leftTypeArray = dynamic_cast<ArraySymbol *>(leftType); ArraySymbol* rightTypeArray = dynamic_cast<ArraySymbol *>(rightType); PointerSymbol* leftTypePointer = dynamic_cast<PointerSymbol *>(leftType); PointerSymbol* rightTypePointer = dynamic_cast<PointerSymbol *>(rightType); if (isAssing(token)) { left->generateLvalue(code); right->generate(code); } else { left->generate(code); right->generate(code); } if (token->Value == "+"){ if (leftTypePointer || rightTypeArray || leftTypeArray || rightTypePointer) { int shift; if (leftTypeArray) shift = leftTypeArray->getType()->offset; if (rightTypeArray) shift = rightTypeArray->getType()->offset; if (leftTypePointer) shift = leftTypePointer->getType()->offset; if (rightTypePointer) shift = rightTypePointer->getType()->offset; if (leftTypePointer) generateOperationPointer(code, _ADD, shift, false); else generateOperationPointer(code, _ADD, shift, true); } generateOperation(code, _ADD); } else if (token->Value == "-"){ if (leftTypePointer || rightTypeArray || leftTypeArray || rightTypePointer) { int shift; if (leftTypeArray) shift = leftTypeArray->getType()->offset; if (rightTypeArray) shift = rightTypeArray->getType()->offset; if (leftTypePointer) shift = leftTypePointer->getType()->offset; if (rightTypePointer) shift = rightTypePointer->getType()->offset; if (leftTypePointer && !rightTypePointer) generateOperationPointer(code, _SUB, shift, false); } generateOperation(code, _SUB); } else if (token->Value == "*"){ generateOperation(code, _IMUL); } else if (token->Value == "/"){ generateOperation(code, _IDIV); } else if (token->Value == "%"){ generateOperation(code, _IDIV, _EDX); } else if (token->Value == "&"){ generateOperation(code, _AND); } else if (token->Value == "|"){ generateOperation(code, _OR); } else if (token->Value == "^"){ generateOperation(code, _XOR); } else if (token->Value == "<<"){ generateOperationShift(code, _SHL); } else if (token->Value == ">>"){ generateOperationShift(code, _SHR); } else if (token->Value == "=="){ generateCmp(code, _SETE); } else if (token->Value == ">="){ generateCmp(code, _SETGE); } else if (token->Value == "<="){ generateCmp(code, _SETLE); } else if (token->Value == "!="){ generateCmp(code, _SETNE); } else if (token->Value == ">"){ generateCmp(code, _SETG); } else if (token->Value == "<"){ generateCmp(code, _SETL); } else if (token->Value == "&&"){ generateOperationLogic(code, _AND); } else if (token->Value == "||"){ generateOperationLogic(code, _OR); } else if (token->Value == "="){ code.add(_POP, _EBX) .add(_POP, _EAX); if (!(leftTypePointer || leftTypeArray) && leftType->getType() == CharType) { code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_BL)) .add(_XOR, _EBX, _EBX) .add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX)) .add(_PUSH, new AsmRegArg(_EAX)); } else { code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_EBX)); } code.add(_PUSH, _EBX); } else if (token->Value == "+="){ if ((leftTypePointer || leftTypeArray)) { int shift; if (leftTypeArray) shift = leftTypeArray->getType()->offset; if (rightTypeArray) shift = rightTypeArray->getType()->offset; if (leftTypePointer) shift = leftTypePointer->getType()->offset; if (rightTypePointer) shift = rightTypePointer->getType()->offset; generateOperationPointer(code, _ADD, shift, false); } generateOperationAssing(leftType, code, _ADD); } else if (token->Value == "-="){ generateOperationAssing(leftType, code, _SUB); } else if (token->Value == "*="){ generateOperationAssing(leftType, code, _IMUL); } else if (token->Value == "/="){ generateOperationAssing(leftType, code, _IDIV); } else if (token->Value == "%="){ generateOperationAssing(leftType, code, _IDIV, _EDX); } else if (token->Value == "&="){ generateOperationAssing(leftType, code, _AND); } else if (token->Value == "|="){ generateOperationAssing(leftType, code, _OR); } else if (token->Value == "^="){ generateOperationAssing(leftType, code, _XOR); } else if (token->Value == ","){ code.add(_POP, _EAX) .add(_POP, _EBX) .add(_PUSH, _EAX); } }