////////////////////////////////////////////////////////////////////////// // // Class Relation // void Relation::Jumping( int t, int f ) { Expr* ap = m_pExpr1->Reduce(); Expr* bp = m_pExpr2->Reduce(); std::string test = ap->ToString() + " " + m_pTok->ToString() + " " + bp->ToString(); EmitJumps( test, t, f ); }
////////////////////////////////////////////////////////////////////////// // // Class ExprStmt // void ExprStmt::Gen( int b, int a, bool bASM ) { if ( bASM ) GenMovLineno( m_lineno ); Expr* pExpr = m_pExpr->Gen(); if ( pExpr && pExpr->ToString().find( "=" ) != std::string::npos ) { Emit( pExpr->ToString() ); delete pExpr; } }
////////////////////////////////////////////////////////////////////////// // // Class CallExpr // Expr* CallExpr::Reduce() { Emit( "push r0" ); for ( auto arg = m_params.rbegin(); arg != m_params.rend(); arg++ ) { Expr* pExpr = (*arg)->Gen(); Temp* temp = new Temp( (*arg)->m_pType ); Emit( temp->ToString() + " = " + pExpr->ToString() ); Emit( "arg " + temp->ToString() ); delete temp; delete pExpr; } Emit( "call " + m_id.ToString() ); for ( std::size_t i = 0; i < m_params.size(); i++ ) { Emit( "pop r0" ); } Temp* temp = new Temp( m_pType ); Emit( "pop " + temp->ToString() ); return temp; }
////////////////////////////////////////////////////////////////////////// // // Class ReadStmt // void ReadStmt::Gen( int b, int a, bool bASM ) { if ( bASM ) GenMovLineno( m_lineno ); Expr* pExpr = m_pExpr->Gen(); Temp temp( m_pExpr->m_pType ); Emit( temp.ToString() + " = " + pExpr->ToString() ); Emit( "read " + temp.ToString() ); delete pExpr; }
////////////////////////////////////////////////////////////////////////// // // Class ReturnStmt // void ReturnStmt::Gen( int b, int a, bool bASM ) { if ( bASM ) GenMovLineno( m_lineno ); Expr* pExpr = m_pExpr->Gen(); Temp* temp = new Temp( m_pExpr->m_pType ); Emit( temp->ToString() + " = " + pExpr->ToString() ); Emit( "leave " + temp->ToString() ); delete temp; delete pExpr; }
////////////////////////////////////////////////////////////////////////// // // Class Unary // Expr* Unary::Gen() { if ( m_pTok->m_Tag == Tag::TIMES ) { Expr* exp = m_pExpr->Reduce(); Temp temp( exp->m_pType ); Emit( temp.ToString() + " = " + exp->ToString() ); Temp* t = new Temp( exp->m_pType ); Emit( t->ToString() + " = " + m_pTok->ToString() + " " + temp.ToString() ); delete exp; return t; } return new Unary( m_pTok->Clone(), m_pExpr->Reduce() ); }
////////////////////////////////////////////////////////////////////////// // // Class WriteStmt // void WriteStmt::Gen( int b, int a, bool bASM ) { if ( bASM ) GenMovLineno( m_lineno ); if ( typeid( *m_pExpr ) == typeid( Constant ) ) { Emit( "write " + itoa( dynamic_cast<Num*>(dynamic_cast<Constant*>(m_pExpr)->m_pTok)->m_Val ) ); } else { Expr* pExpr = m_pExpr->Gen(); Temp temp( m_pExpr->m_pType ); Emit( temp.ToString() + " = " + pExpr->ToString() ); Emit( "write " + temp.ToString() ); delete pExpr; } }
Expr* Arith::Gen() { if ( typeid( *m_pExpr1 ) == typeid( ArrayAccess ) && m_pTok->m_Tag == Tag::ASSIGN ) { Expr* p1 = dynamic_cast<ArrayAccess*>( m_pExpr1 )->m_index->Reduce(); std::string s1 = p1->ToString(); Expr* p2 = m_pExpr2->Reduce(); std::string s2 = p2->ToString(); Emit( dynamic_cast<ArrayAccess*>( m_pExpr1 )->m_array.ToString() + "[" + s1 + "] = " + s2 ); Temp* temp = new Temp( m_pType ); Emit( temp->ToString() + " = " + dynamic_cast<ArrayAccess*>( m_pExpr1 )->m_array.ToString() + "[" + s1 + "]" ); delete p1; delete p2; return temp; } else if ( m_pTok->m_Tag == Tag::ASSIGN ) { Arith* exp = new Arith( m_pTok->Clone(), m_pExpr1->Reduce(), m_pExpr2->Reduce(), false ); Emit( exp->ToString() ); Temp* temp = new Temp( m_pType ); Emit( temp->ToString() + " " + m_pTok->ToString() + " " + m_pExpr1->ToString() ); delete exp; return temp; } else if ( m_pTok->m_Tag == Tag::POINT || m_pTok->m_Tag == Tag::ARROW ) { Arith* exp = new Arith( m_pTok->Clone(), m_pExpr1->Reduce(), m_pExpr2->Reduce(), false ); return exp; } else { Expr* exp = new Arith( m_pTok->Clone(), m_pExpr1->Reduce(), m_pExpr2->Reduce(), false ); Temp* temp = new Temp( m_pType ); Emit( temp->ToString() + " = " + exp->ToString() ); delete exp; return temp; } }
////////////////////////////////////////////////////////////////////////// // // Class CallStmt // void CallStmt::Gen( int b, int a, bool bASM ) { if ( bASM ) GenMovLineno( m_lineno ); for ( auto arg = m_args.rbegin(); arg != m_args.rend(); arg++ ) { Expr* pExpr = (*arg)->Gen(); Temp* temp = new Temp( (*arg)->m_pType ); Emit( temp->ToString() + " = " + pExpr->ToString() ); Emit( "arg " + temp->ToString() ); delete temp; delete pExpr; } Emit( "call " + m_id.ToString() ); for ( std::size_t i = 0; i < m_args.size(); i++ ) { Emit( "pop r0" ); } }