/* File: ast_expr.cc * ----------------- * Implementation of expression node classes. */ #include #include "ast_expr.h" #include "ast_type.h" #include "ast_decl.h" #include "symtable.h" IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { value = val; } void IntConstant::PrintChildren(int indentLevel) { printf("%d", value); } FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { value = val; } void FloatConstant::PrintChildren(int indentLevel) { printf("%g", value); } BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { value = val; } void BoolConstant::PrintChildren(int indentLevel) { printf("%s", value ? "true" : "false"); } VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { Assert(ident != NULL); this->id = ident; } void VarExpr::PrintChildren(int indentLevel) { id->Print(indentLevel+1); } Operator::Operator(yyltype loc, const char *tok) : Node(loc) { Assert(tok != NULL); strncpy(tokenString, tok, sizeof(tokenString)); } void Operator::PrintChildren(int indentLevel) { printf("%s",tokenString); } bool Operator::IsOp(const char *op) const { return strcmp(tokenString, op) == 0; } CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) : Expr(Join(l->GetLocation(), r->GetLocation())) { Assert(l != NULL && o != NULL && r != NULL); (op=o)->SetParent(this); (left=l)->SetParent(this); (right=r)->SetParent(this); } CompoundExpr::CompoundExpr(Operator *o, Expr *r) : Expr(Join(o->GetLocation(), r->GetLocation())) { Assert(o != NULL && r != NULL); left = NULL; (op=o)->SetParent(this); (right=r)->SetParent(this); } CompoundExpr::CompoundExpr(Expr *l, Operator *o) : Expr(Join(l->GetLocation(), o->GetLocation())) { Assert(l != NULL && o != NULL); (left=l)->SetParent(this); (op=o)->SetParent(this); } void CompoundExpr::PrintChildren(int indentLevel) { if (left) left->Print(indentLevel+1); op->Print(indentLevel+1); if (right) right->Print(indentLevel+1); } ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) : Expr(Join(c->GetLocation(), f->GetLocation())) { Assert(c != NULL && t != NULL && f != NULL); (cond=c)->SetParent(this); (trueExpr=t)->SetParent(this); (falseExpr=f)->SetParent(this); } void ConditionalExpr::PrintChildren(int indentLevel) { cond->Print(indentLevel+1, "(cond) "); trueExpr->Print(indentLevel+1, "(true) "); falseExpr->Print(indentLevel+1, "(false) "); } ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { (base=b)->SetParent(this); (subscript=s)->SetParent(this); } void ArrayAccess::PrintChildren(int indentLevel) { base->Print(indentLevel+1); subscript->Print(indentLevel+1, "(subscript) "); } FieldAccess::FieldAccess(Expr *b, Identifier *f) : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { Assert(f != NULL); // b can be be NULL (just means no explicit base) base = b; if (base) base->SetParent(this); (field=f)->SetParent(this); } void FieldAccess::PrintChildren(int indentLevel) { if (base) base->Print(indentLevel+1); field->Print(indentLevel+1); } Call::Call(yyltype loc, Expr *b, Identifier *f, List *a) : Expr(loc) { Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) base = b; if (base) base->SetParent(this); (field=f)->SetParent(this); (actuals=a)->SetParentAll(this); } void Call::PrintChildren(int indentLevel) { if (base) base->Print(indentLevel+1); if (field) field->Print(indentLevel+1); if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); } llvm::Value* VarExpr::Emit() { return new llvm::LoadInst(findSymbol(id->GetName()).second, NULL, irgen.GetBasicBlock()); } llvm::Value* AssignExpr::Emit() { return new llvm::StoreInst(left->Emit(), right->Emit(), NULL, irgen.GetBasicBlock()); } string Operator::getToken() const { return tokenString; } llvm::Value* IntConstant::Emit() { return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); } llvm::Value* FloatConstant::Emit() { return llvm::ConstantInt::get(llvm::Type::getFloatTy(*irgen.GetContext()), value, true); } llvm::Value* BoolConstant::Emit() { return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); } llvm::Value* Call::Emit() { vector args; for(int i = 0; i < actuals->NumElements(); i++) { args.push_back(actuals->Nth(i)->Emit()); } return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); } llvm::Value* CompoundExpr::Emit() { llvm::Value* l = l ? left->Emit() : NULL; llvm::Value* r = r ? right->Emit() : NULL; llvm::BasicBlock* b = irgen.GetBasicBlock(); //austins additional value llvm::Value *val; if(!l) { if(op->getToken() == "++") val = llvm::ConstantInt::get(irgen.GetIntType(), 1); return llvm::BinaryOperator::CreateAdd(l, val, "", irgen.GetBasicBlock()); if(op->getToken() == "--") val = llvm::ConstantInt::get(irgen.GetIntType(), 1); return llvm::BinaryOperator::CreateSub(l, val, "", irgen.GetBasicBlock()); } if(l->getType()->isFPOrFPVectorTy()) { if(op->getToken() == "+") return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, NULL, b); if(op->getToken() == "-") return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, NULL, b); if(op->getToken() == "*") return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, NULL, b); if(op->getToken() == "/") return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, NULL, b); if(op->getToken() == "==") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, NULL, b); if(op->getToken() == "!=") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, NULL, b); if(op->getToken() == "<=") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, NULL, b); if(op->getToken() == ">=") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, NULL, b); if(op->getToken() == "<") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, NULL, b); if(op->getToken() == ">") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, NULL, b); } if(l->getType()->isIntOrIntVectorTy()) { if(op->getToken() == "+") return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, NULL, b); if(op->getToken() == "-") return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, NULL, b); if(op->getToken() == "*") return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, NULL, b); if(op->getToken() == "/") return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, NULL, b); if(op->getToken() == "==") return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, NULL, b); if(op->getToken() == "!=") return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, NULL, b); if(op->getToken() == "<=") return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, NULL, b); if(op->getToken() == ">=") return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, NULL, b); if(op->getToken() == "<") return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, NULL, b); if(op->getToken() == ">") return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, NULL, b); } if(op->getToken() == "&&") { return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, NULL, b); } if(op->getToken() == "||") { return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, NULL, b); } return NULL; }