Commit 43abbf64217a7ff4de3f1cb28bcbc511e0a9e9e0

Authored by Jeffrey Johnson
1 parent 9399459476
Exists in master

Short circuit && and ||

Showing 1 changed file with 26 additions and 8 deletions Inline Diff

/* File: ast_expr.cc 1 1 /* File: ast_expr.cc
* ----------------- 2 2 * -----------------
* Implementation of expression node classes. 3 3 * Implementation of expression node classes.
*/ 4 4 */
5 5
#include <string.h> 6 6 #include <string.h>
#include "ast_expr.h" 7 7 #include "ast_expr.h"
#include "ast_type.h" 8 8 #include "ast_type.h"
#include "ast_decl.h" 9 9 #include "ast_decl.h"
#include "symtable.h" 10 10 #include "symtable.h"
11 11
IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { 12 12 IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) {
value = val; 13 13 value = val;
} 14 14 }
void IntConstant::PrintChildren(int indentLevel) { 15 15 void IntConstant::PrintChildren(int indentLevel) {
printf("%d", value); 16 16 printf("%d", value);
} 17 17 }
18 18
FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { 19 19 FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) {
value = val; 20 20 value = val;
} 21 21 }
void FloatConstant::PrintChildren(int indentLevel) { 22 22 void FloatConstant::PrintChildren(int indentLevel) {
printf("%g", value); 23 23 printf("%g", value);
} 24 24 }
25 25
BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { 26 26 BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) {
value = val; 27 27 value = val;
} 28 28 }
void BoolConstant::PrintChildren(int indentLevel) { 29 29 void BoolConstant::PrintChildren(int indentLevel) {
printf("%s", value ? "true" : "false"); 30 30 printf("%s", value ? "true" : "false");
} 31 31 }
32 32
VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { 33 33 VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) {
Assert(ident != NULL); 34 34 Assert(ident != NULL);
this->id = ident; 35 35 this->id = ident;
} 36 36 }
37 37
void VarExpr::PrintChildren(int indentLevel) { 38 38 void VarExpr::PrintChildren(int indentLevel) {
id->Print(indentLevel+1); 39 39 id->Print(indentLevel+1);
} 40 40 }
41 41
Operator::Operator(yyltype loc, const char *tok) : Node(loc) { 42 42 Operator::Operator(yyltype loc, const char *tok) : Node(loc) {
Assert(tok != NULL); 43 43 Assert(tok != NULL);
strncpy(tokenString, tok, sizeof(tokenString)); 44 44 strncpy(tokenString, tok, sizeof(tokenString));
} 45 45 }
46 46
void Operator::PrintChildren(int indentLevel) { 47 47 void Operator::PrintChildren(int indentLevel) {
printf("%s",tokenString); 48 48 printf("%s",tokenString);
} 49 49 }
50 50
bool Operator::IsOp(const char *op) const { 51 51 bool Operator::IsOp(const char *op) const {
return strcmp(tokenString, op) == 0; 52 52 return strcmp(tokenString, op) == 0;
} 53 53 }
54 54
CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) 55 55 CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r)
: Expr(Join(l->GetLocation(), r->GetLocation())) { 56 56 : Expr(Join(l->GetLocation(), r->GetLocation())) {
Assert(l != NULL && o != NULL && r != NULL); 57 57 Assert(l != NULL && o != NULL && r != NULL);
(op=o)->SetParent(this); 58 58 (op=o)->SetParent(this);
(left=l)->SetParent(this); 59 59 (left=l)->SetParent(this);
(right=r)->SetParent(this); 60 60 (right=r)->SetParent(this);
} 61 61 }
62 62
CompoundExpr::CompoundExpr(Operator *o, Expr *r) 63 63 CompoundExpr::CompoundExpr(Operator *o, Expr *r)
: Expr(Join(o->GetLocation(), r->GetLocation())) { 64 64 : Expr(Join(o->GetLocation(), r->GetLocation())) {
Assert(o != NULL && r != NULL); 65 65 Assert(o != NULL && r != NULL);
left = NULL; 66 66 left = NULL;
(op=o)->SetParent(this); 67 67 (op=o)->SetParent(this);
(right=r)->SetParent(this); 68 68 (right=r)->SetParent(this);
} 69 69 }
70 70
CompoundExpr::CompoundExpr(Expr *l, Operator *o) 71 71 CompoundExpr::CompoundExpr(Expr *l, Operator *o)
: Expr(Join(l->GetLocation(), o->GetLocation())) { 72 72 : Expr(Join(l->GetLocation(), o->GetLocation())) {
Assert(l != NULL && o != NULL); 73 73 Assert(l != NULL && o != NULL);
(left=l)->SetParent(this); 74 74 (left=l)->SetParent(this);
(op=o)->SetParent(this); 75 75 (op=o)->SetParent(this);
} 76 76 }
77 77
void CompoundExpr::PrintChildren(int indentLevel) { 78 78 void CompoundExpr::PrintChildren(int indentLevel) {
if (left) left->Print(indentLevel+1); 79 79 if (left) left->Print(indentLevel+1);
op->Print(indentLevel+1); 80 80 op->Print(indentLevel+1);
if (right) right->Print(indentLevel+1); 81 81 if (right) right->Print(indentLevel+1);
} 82 82 }
83 83
ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) 84 84 ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f)
: Expr(Join(c->GetLocation(), f->GetLocation())) { 85 85 : Expr(Join(c->GetLocation(), f->GetLocation())) {
Assert(c != NULL && t != NULL && f != NULL); 86 86 Assert(c != NULL && t != NULL && f != NULL);
(cond=c)->SetParent(this); 87 87 (cond=c)->SetParent(this);
(trueExpr=t)->SetParent(this); 88 88 (trueExpr=t)->SetParent(this);
(falseExpr=f)->SetParent(this); 89 89 (falseExpr=f)->SetParent(this);
} 90 90 }
91 91
void ConditionalExpr::PrintChildren(int indentLevel) { 92 92 void ConditionalExpr::PrintChildren(int indentLevel) {
cond->Print(indentLevel+1, "(cond) "); 93 93 cond->Print(indentLevel+1, "(cond) ");
trueExpr->Print(indentLevel+1, "(true) "); 94 94 trueExpr->Print(indentLevel+1, "(true) ");
falseExpr->Print(indentLevel+1, "(false) "); 95 95 falseExpr->Print(indentLevel+1, "(false) ");
} 96 96 }
ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { 97 97 ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) {
(base=b)->SetParent(this); 98 98 (base=b)->SetParent(this);
(subscript=s)->SetParent(this); 99 99 (subscript=s)->SetParent(this);
} 100 100 }
101 101
void ArrayAccess::PrintChildren(int indentLevel) { 102 102 void ArrayAccess::PrintChildren(int indentLevel) {
base->Print(indentLevel+1); 103 103 base->Print(indentLevel+1);
subscript->Print(indentLevel+1, "(subscript) "); 104 104 subscript->Print(indentLevel+1, "(subscript) ");
} 105 105 }
106 106
FieldAccess::FieldAccess(Expr *b, Identifier *f) 107 107 FieldAccess::FieldAccess(Expr *b, Identifier *f)
: LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { 108 108 : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) {
Assert(f != NULL); // b can be be NULL (just means no explicit base) 109 109 Assert(f != NULL); // b can be be NULL (just means no explicit base)
base = b; 110 110 base = b;
if (base) base->SetParent(this); 111 111 if (base) base->SetParent(this);
(field=f)->SetParent(this); 112 112 (field=f)->SetParent(this);
} 113 113 }
114 114
115 115
void FieldAccess::PrintChildren(int indentLevel) { 116 116 void FieldAccess::PrintChildren(int indentLevel) {
if (base) base->Print(indentLevel+1); 117 117 if (base) base->Print(indentLevel+1);
field->Print(indentLevel+1); 118 118 field->Print(indentLevel+1);
} 119 119 }
120 120
Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { 121 121 Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) {
Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) 122 122 Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base)
base = b; 123 123 base = b;
if (base) base->SetParent(this); 124 124 if (base) base->SetParent(this);
(field=f)->SetParent(this); 125 125 (field=f)->SetParent(this);
(actuals=a)->SetParentAll(this); 126 126 (actuals=a)->SetParentAll(this);
} 127 127 }
128 128
void Call::PrintChildren(int indentLevel) { 129 129 void Call::PrintChildren(int indentLevel) {
if (base) base->Print(indentLevel+1); 130 130 if (base) base->Print(indentLevel+1);
if (field) field->Print(indentLevel+1); 131 131 if (field) field->Print(indentLevel+1);
if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); 132 132 if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) ");
} 133 133 }
134 134
llvm::Value* VarExpr::Emit() { 135 135 llvm::Value* VarExpr::Emit() {
return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock()); 136 136 return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock());
} 137 137 }
/* 138 138 /*
llvm::Value* AssignExpr::Emit() { 139 139 llvm::Value* AssignExpr::Emit() {
VarExpr* ve = dynamic_cast<VarExpr*>(left); 140 140 VarExpr* ve = dynamic_cast<VarExpr*>(left);
return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock()); 141 141 return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock());
} 142 142 }
*/ 143 143 */
144 144
string Operator::getToken() const { 145 145 string Operator::getToken() const {
return tokenString; 146 146 return tokenString;
} 147 147 }
148 148
llvm::Value* IntConstant::Emit() { 149 149 llvm::Value* IntConstant::Emit() {
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); 150 150 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true);
} 151 151 }
152 152
llvm::Value* FloatConstant::Emit() { 153 153 llvm::Value* FloatConstant::Emit() {
return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); 154 154 return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value);
} 155 155 }
156 156
llvm::Value* BoolConstant::Emit() { 157 157 llvm::Value* BoolConstant::Emit() {
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value); 158 158 return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value);
} 159 159 }
160 160
llvm::Value* Call::Emit() { 161 161 llvm::Value* Call::Emit() {
vector<llvm::Value*> args; 162 162 vector<llvm::Value*> args;
for(int i = 0; i < actuals->NumElements(); i++) { 163 163 for(int i = 0; i < actuals->NumElements(); i++) {
args.push_back(actuals->Nth(i)->Emit()); 164 164 args.push_back(actuals->Nth(i)->Emit());
} 165 165 }
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, "", irgen.GetBasicBlock()); 166 166 return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, "", irgen.GetBasicBlock());
} 167 167 }
168 168
llvm::Value* ConditionalExpr::Emit() { 169 169 llvm::Value* ConditionalExpr::Emit() {
llvm::BasicBlock* b = irgen.GetBasicBlock(); 170 170 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::Value* t = trueExpr->Emit(); 171 171 llvm::Value* t = trueExpr->Emit();
llvm::Value* f = falseExpr->Emit(); 172 172 llvm::Value* f = falseExpr->Emit();
llvm::Value* c = cond->Emit(); 173 173 llvm::Value* c = cond->Emit();
174 174
return llvm::SelectInst::Create(c, t, f, "", b); 175 175 return llvm::SelectInst::Create(c, t, f, "", b);
} 176 176 }
177 177
static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) { 178 178 static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) {
if(val->getType() == target->getType()) return val; 179 179 if(val->getType() == target->getType()) return val;
llvm::BasicBlock* b = irgen.GetBasicBlock(); 180 180 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::Value* ret = new llvm::AllocaInst(target->getType(), "", b); 181 181 llvm::Value* ret = new llvm::AllocaInst(target->getType(), "", b);
ret = new llvm::LoadInst(ret, "", b); 182 182 ret = new llvm::LoadInst(ret, "", b);
183 183
for(int i = 0; i < target->getType()->getVectorNumElements(); i++) { 184 184 for(int i = 0; i < target->getType()->getVectorNumElements(); i++) {
ret = llvm::InsertElementInst::Create(ret, val, llvm::ConstantInt::get(irgen.GetIntType(), i), "", b); 185 185 ret = llvm::InsertElementInst::Create(ret, val, llvm::ConstantInt::get(irgen.GetIntType(), i), "", b);
} 186 186 }
return ret; 187 187 return ret;
} 188 188 }
189 189
// TODO ++ and -- on vectors? 190
llvm::Value* CompoundExpr::Emit() { 191 190 llvm::Value* CompoundExpr::Emit() {
191 llvm::BasicBlock* b = irgen.GetBasicBlock();
192 llvm::Function * func = irgen.GetFunction();
193 llvm::LLVMContext* context = irgen.GetContext();
194 //weird bc of short circuting
195 if(op->getToken() == "&&" || op->getToken() == "||") {
196 llvm::Value* val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*context), "", b);
197 llvm::BasicBlock * otherBlock = llvm::BasicBlock::Create(*context, "otherBlock", func);
198 llvm::BasicBlock * falseBlock = llvm::BasicBlock::Create(*context, "falseBlock", func);
199 llvm::BasicBlock * trueBlock = llvm::BasicBlock::Create(*context, "trueBlock", func);
200 llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func);
201 llvm::Value* l = left->Emit();
202 b = irgen.GetBasicBlock();
203 if(op->getToken() == "&&") llvm::BranchInst::Create(otherBlock, falseBlock, l, b);
204 if(op->getToken() == "||") llvm::BranchInst::Create(trueBlock, otherBlock, l, b);
205 irgen.SetBasicBlock(otherBlock);
206 llvm::Value* r = right->Emit();
207 b = irgen.GetBasicBlock();
208 llvm::BranchInst::Create(trueBlock, falseBlock, r, b);
209 new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), true), val, false, trueBlock);
210 llvm::BranchInst::Create(footBlock, trueBlock);
211 new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), false), val, false, falseBlock);
212 llvm::BranchInst::Create(footBlock, falseBlock);
213 irgen.SetBasicBlock(footBlock);
214 return new llvm::LoadInst(val, "", footBlock);
215 }
llvm::Value* l = left ? left->Emit() : NULL; 192 216 llvm::Value* l = left ? left->Emit() : NULL;
llvm::Value* r = right ? right->Emit() : NULL; 193 217 llvm::Value* r = right ? right->Emit() : NULL;
llvm::BasicBlock* b = irgen.GetBasicBlock(); 194 218 b = irgen.GetBasicBlock();
//austins additional value 195 219 //austins additional value
llvm::Value *val; 196 220 llvm::Value *val;
if(!l || !r) { 197 221 if(!l || !r) {
if(op->getToken() == "-" && (l ? l->getType()->isFPOrFPVectorTy() : r->getType()->isFPOrFPVectorTy())) { 198 222 if(op->getToken() == "-" && (l ? l->getType()->isFPOrFPVectorTy() : r->getType()->isFPOrFPVectorTy())) {
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, typeConvert(llvm::ConstantFP::get(irgen.GetFloatType(), 0.0), (l?l:r)), l ? l : r, "", b); 199 223 return llvm::BinaryOperator::Create(llvm::Instruction::FSub, typeConvert(llvm::ConstantFP::get(irgen.GetFloatType(), 0.0), (l?l:r)), l ? l : r, "", b);
} 200 224 }
else if(op->getToken() == "-") { 201 225 else if(op->getToken() == "-") {
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, typeConvert(llvm::ConstantInt::get(irgen.GetIntType(), 0), (l?l:r)), l ? l : r, "", b); 202 226 return llvm::BinaryOperator::Create(llvm::Instruction::Sub, typeConvert(llvm::ConstantInt::get(irgen.GetIntType(), 0), (l?l:r)), l ? l : r, "", b);
} 203 227 }
else if(op->getToken() == "+") return l ? l : r; 204 228 else if(op->getToken() == "+") return l ? l : r;
VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); 205 229 VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right);
llvm::Value* ret; 206 230 llvm::Value* ret;
llvm::Value* var = l ? l : r; 207 231 llvm::Value* var = l ? l : r;
208 232
if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); 209 233 if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0);
else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); 210 234 else val = llvm::ConstantInt::get(irgen.GetIntType(), 1);
val = typeConvert(val, var); 211 235 val = typeConvert(val, var);
212 236
if(op->getToken() == "++") { 213 237 if(op->getToken() == "++") {
ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); 214 238 ret = llvm::BinaryOperator::CreateAdd(var, val, "", b);
} 215 239 }
else if(op->getToken() == "--") { 216 240 else if(op->getToken() == "--") {
ret = llvm::BinaryOperator::CreateSub(var, val, "", b); 217 241 ret = llvm::BinaryOperator::CreateSub(var, val, "", b);
} 218 242 }
new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); 219 243 new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b);
220 244
if(!l) return ret; 221 245 if(!l) return ret;
else return var; 222 246 else return var;
} 223 247 }
if(l->getType()->isVectorTy() && !r->getType()->isVectorTy()) r = typeConvert(r, l); 224 248 if(l->getType()->isVectorTy() && !r->getType()->isVectorTy()) r = typeConvert(r, l);
if(!l->getType()->isVectorTy() && r->getType()->isVectorTy()) l = typeConvert(l, r); 225 249 if(!l->getType()->isVectorTy() && r->getType()->isVectorTy()) l = typeConvert(l, r);
if(l->getType()->isFPOrFPVectorTy()) { 226 250 if(l->getType()->isFPOrFPVectorTy()) {
if(op->getToken() == "+") 227 251 if(op->getToken() == "+")
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); 228 252 return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b);
if(op->getToken() == "-") 229 253 if(op->getToken() == "-")
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); 230 254 return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b);
if(op->getToken() == "*") 231 255 if(op->getToken() == "*")
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); 232 256 return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b);
if(op->getToken() == "/") 233 257 if(op->getToken() == "/")
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); 234 258 return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b);
if(op->getToken() == "==") 235 259 if(op->getToken() == "==")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); 236 260 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b);
if(op->getToken() == "!=") 237 261 if(op->getToken() == "!=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); 238 262 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b);
if(op->getToken() == "<=") 239 263 if(op->getToken() == "<=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); 240 264 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b);
if(op->getToken() == ">=") 241 265 if(op->getToken() == ">=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); 242 266 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b);
if(op->getToken() == "<") 243 267 if(op->getToken() == "<")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); 244 268 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b);
if(op->getToken() == ">") 245 269 if(op->getToken() == ">")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); 246 270 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b);
} 247 271 }
if(l->getType()->isIntOrIntVectorTy()) { 248 272 if(l->getType()->isIntOrIntVectorTy()) {
if(op->getToken() == "+") 249 273 if(op->getToken() == "+")
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); 250 274 return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b);
if(op->getToken() == "-") 251 275 if(op->getToken() == "-")
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); 252 276 return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b);
if(op->getToken() == "*") 253 277 if(op->getToken() == "*")
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); 254 278 return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b);
if(op->getToken() == "/") 255 279 if(op->getToken() == "/")
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); 256 280 return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b);
if(op->getToken() == "==") 257 281 if(op->getToken() == "==")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); 258 282 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b);
if(op->getToken() == "!=") 259 283 if(op->getToken() == "!=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); 260 284 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b);
if(op->getToken() == "<=") 261 285 if(op->getToken() == "<=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); 262 286 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b);
if(op->getToken() == ">=") 263 287 if(op->getToken() == ">=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); 264 288 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b);
if(op->getToken() == "<") 265 289 if(op->getToken() == "<")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); 266 290 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b);
if(op->getToken() == ">") 267 291 if(op->getToken() == ">")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); 268 292 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b);
} 269
if(op->getToken() == "&&") { 270
return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); 271
} 272
if(op->getToken() == "||") { 273
return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); 274
} 275 293 }
return NULL; 276 294 return NULL;
} 277 295 }
278 296
//---------------------------------------------------------------------------------------- 279 297 //----------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------- 280 298 //----------------------------------------------------------------------------------------
281 299
llvm::Value * AssignExpr::Emit(){ 282 300 llvm::Value * AssignExpr::Emit(){
llvm::Value * leftval; 283 301 llvm::Value * leftval;
llvm::Value * rightval; 284 302 llvm::Value * rightval;
285 303
FieldAccess * f = dynamic_cast<FieldAccess *>(left); 286 304 FieldAccess * f = dynamic_cast<FieldAccess *>(left);
if (f){ 287 305 if (f){
return this->AssignField(); 288 306 return this->AssignField();
} 289 307 }
leftval = left->Emit(); 290 308 leftval = left->Emit();
rightval = right->Emit(); 291 309 rightval = right->Emit();
292 310
string operationStr(op->getToken()); 293 311 string operationStr(op->getToken());
294 312
VarExpr * vd = dynamic_cast<VarExpr *>(left); 295 313 VarExpr * vd = dynamic_cast<VarExpr *>(left);
296 314
llvm::Value * storeInst = NULL; 297 315 llvm::Value * storeInst = NULL;
if ( operationStr.compare("+=") == 0 ){ 298 316 if ( operationStr.compare("+=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 299 317 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); 300 318 storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 301 319 if (vd){
vd->AddressStore(storeInst); 302 320 vd->AddressStore(storeInst);
return storeInst; 303 321 return storeInst;
} 304 322 }
} 305 323 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 306 324 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); 307 325 storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 308 326 if (vd){
vd->AddressStore(storeInst); 309 327 vd->AddressStore(storeInst);
return storeInst; 310 328 return storeInst;
} 311 329 }
} 312 330 }
else{ 313 331 else{
storeInst = convert(leftval, rightval, 0); 314 332 storeInst = convert(leftval, rightval, 0);
if (vd){ 315 333 if (vd){
vd->AddressStore(storeInst); 316 334 vd->AddressStore(storeInst);
return storeInst; 317 335 return storeInst;
} 318 336 }
} 319 337 }
} 320 338 }
else if ( operationStr.compare("=") == 0 ){ 321 339 else if ( operationStr.compare("=") == 0 ){
if (vd){ 322 340 if (vd){
vd->AddressStore(rightval); 323 341 vd->AddressStore(rightval);
return rightval; 324 342 return rightval;
} 325 343 }
return ((VarExpr *) left)->AddressStore(rightval); 326 344 return ((VarExpr *) left)->AddressStore(rightval);
} 327 345 }
else if ( operationStr.compare("-=") == 0 ){ 328 346 else if ( operationStr.compare("-=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 329 347 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); 330 348 storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 331 349 if (vd){
vd->AddressStore(storeInst); 332 350 vd->AddressStore(storeInst);
return storeInst; 333 351 return storeInst;
} 334 352 }
} 335 353 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 336 354 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); 337 355 storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 338 356 if (vd){
vd->AddressStore(storeInst); 339 357 vd->AddressStore(storeInst);
return storeInst; 340 358 return storeInst;
} 341 359 }
} 342 360 }
else{ 343 361 else{
storeInst = convert(leftval, rightval, 1); 344 362 storeInst = convert(leftval, rightval, 1);
if (vd){ 345 363 if (vd){
vd->AddressStore(storeInst); 346 364 vd->AddressStore(storeInst);
return storeInst; 347 365 return storeInst;
} 348 366 }
} 349 367 }
} 350 368 }
else if ( operationStr.compare("/=") == 0 ){ 351 369 else if ( operationStr.compare("/=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 352 370 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); 353 371 storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 354 372 if (vd){
vd->AddressStore(storeInst); 355 373 vd->AddressStore(storeInst);
return storeInst; 356 374 return storeInst;
} 357 375 }
} 358 376 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 359 377 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); 360 378 storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 361 379 if (vd){
vd->AddressStore(storeInst); 362 380 vd->AddressStore(storeInst);
return storeInst; 363 381 return storeInst;
} 364 382 }
} 365 383 }
else{ 366 384 else{
storeInst = convert(leftval, rightval, 2); 367 385 storeInst = convert(leftval, rightval, 2);
if (vd){ 368 386 if (vd){
vd->AddressStore(storeInst); 369 387 vd->AddressStore(storeInst);
return storeInst; 370 388 return storeInst;
} 371 389 }
} 372 390 }
} 373 391 }
else if ( operationStr.compare("*=") == 0 ){ 374 392 else if ( operationStr.compare("*=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 375 393 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); 376 394 storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 377 395 if (vd){
vd->AddressStore(storeInst); 378 396 vd->AddressStore(storeInst);
return storeInst; 379 397 return storeInst;
} 380 398 }
} 381 399 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 382 400 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); 383 401 storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 384 402 if (vd){
vd->AddressStore(storeInst); 385 403 vd->AddressStore(storeInst);
return storeInst; 386 404 return storeInst;
} 387 405 }
} 388 406 }
else{ 389 407 else{
storeInst = convert(leftval, rightval, 3); 390 408 storeInst = convert(leftval, rightval, 3);
if (vd){ 391 409 if (vd){
vd->AddressStore(storeInst); 392 410 vd->AddressStore(storeInst);
return storeInst; 393 411 return storeInst;
} 394 412 }
} 395 413 }
} 396 414 }
return NULL; 397 415 return NULL;
} 398 416 }
399 417
llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ 400 418 llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){
llvm::Type * intTyp = irgen.GetIntType(); 401 419 llvm::Type * intTyp = irgen.GetIntType();
llvm::Type * fltTyp = irgen.GetFloatType(); 402 420 llvm::Type * fltTyp = irgen.GetFloatType();
llvm::Value *idVal; 403 421 llvm::Value *idVal;
llvm::Value * element; 404 422 llvm::Value * element;
llvm::Value * retVal = vec; 405 423 llvm::Value * retVal = vec;
406 424
//get vector size 407 425 //get vector size
int numElements=-1; 408 426 int numElements=-1;
if(vec->getType()==irgen.GetVec2Type()){ 409 427 if(vec->getType()==irgen.GetVec2Type()){
numElements=2; 410 428 numElements=2;
} 411 429 }
else if(vec->getType()==irgen.GetVec3Type()){ 412 430 else if(vec->getType()==irgen.GetVec3Type()){
numElements=3; 413 431 numElements=3;
} 414 432 }
else if(vec->getType()==irgen.GetVec4Type()){ 415 433 else if(vec->getType()==irgen.GetVec4Type()){
numElements=4; 416 434 numElements=4;
} 417 435 }
418 436
for (int i = 0; i < numElements; i++){ 419 437 for (int i = 0; i < numElements; i++){
idVal = llvm::ConstantInt::get(intTyp, i); 420 438 idVal = llvm::ConstantInt::get(intTyp, i);
element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); 421 439 element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock());
if (status == 0){ 422 440 if (status == 0){
element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); 423 441 element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock());
} 424 442 }
else if (status == 1){ 425 443 else if (status == 1){
element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); 426 444 element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock());
} 427 445 }
else if (status == 2){ 428 446 else if (status == 2){
element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); 429 447 element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock());
} 430 448 }
else{ 431 449 else{
element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); 432 450 element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock());
} 433 451 }
retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); 434 452 retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock());
} 435 453 }
return retVal; 436 454 return retVal;
} 437 455 }
438 456
llvm::Value* VarExpr::AddressStore(llvm::Value *store){ 439 457 llvm::Value* VarExpr::AddressStore(llvm::Value *store){
char * varname = GetIdentifier()->GetName(); 440 458 char * varname = GetIdentifier()->GetName();
441 459
pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); 442 460 pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname));
//value of symbol 443 461 //value of symbol
llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, false, irgen.GetBasicBlock()); 444 462 llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, false, irgen.GetBasicBlock());
return storeInst; 445 463 return storeInst;
} 446 464 }
447 465
llvm::Value * AssignExpr::AssignField(){ 448 466 llvm::Value * AssignExpr::AssignField(){
FieldAccess * f = (FieldAccess *) left; 449 467 FieldAccess * f = (FieldAccess *) left;
llvm::Value * rightval = right->Emit(); 450 468 llvm::Value * rightval = right->Emit();
string operationStr(op->getToken()); 451 469 string operationStr(op->getToken());
bool isFloat = rightval->getType()->isFloatingPointTy(); 452 470 bool isFloat = rightval->getType()->isFloatingPointTy();
llvm::Type * intTyp = irgen.GetIntType(); 453 471 llvm::Type * intTyp = irgen.GetIntType();
char * ptr = f->getField()->GetName();; 454 472 char * ptr = f->getField()->GetName();;
455 473
std::vector<llvm::Constant *> maskI; 456 474 std::vector<llvm::Constant *> maskI;
for(; *ptr; ptr++){ 457 475 for(; *ptr; ptr++){
if(*ptr =='x'){ 458 476 if(*ptr =='x'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); 459 477 maskI.push_back(llvm::ConstantInt::get(intTyp, 0));
} 460 478 }
else if(*ptr='y'){ 461 479 else if(*ptr='y'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); 462 480 maskI.push_back(llvm::ConstantInt::get(intTyp, 1));
} 463 481 }
else if(*ptr='z'){ 464 482 else if(*ptr='z'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); 465 483 maskI.push_back(llvm::ConstantInt::get(intTyp, 2));
} 466 484 }
else if(*ptr='w'){ 467 485 else if(*ptr='w'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); 468 486 maskI.push_back(llvm::ConstantInt::get(intTyp, 3));
} 469 487 }
} 470 488 }
471 489
llvm::Value * element; 472 490 llvm::Value * element;
llvm::Value * rightop = rightval; 473 491 llvm::Value * rightop = rightval;
llvm::Value * baseF = f->getBase()->Emit(); 474 492 llvm::Value * baseF = f->getBase()->Emit();
llvm::Value * storeInst = f->getBase()->Emit(); 475 493 llvm::Value * storeInst = f->getBase()->Emit();
476 494
477 495
for (int i = 0; i < maskI.size(); i++){ 478 496 for (int i = 0; i < maskI.size(); i++){
element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock()); 479 497 element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock());
if (rightval->getType()->isVectorTy()){ 480 498 if (rightval->getType()->isVectorTy()){
rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); 481 499 rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock());
} 482 500 }
if (!operationStr.compare("=")){ 483 501 if (!operationStr.compare("=")){
storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); 484 502 storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock());
} 485 503 }
if (!operationStr.compare("+=")){ 486 504 if (!operationStr.compare("+=")){
element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); 487 505 element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock());
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 488 506 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
} 489 507 }
if (!operationStr.compare("-=")){ 490 508 if (!operationStr.compare("-=")){
element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); 491 509 element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock());
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 492 510 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
} 493 511 }
if (!operationStr.compare("*=")){ 494 512 if (!operationStr.compare("*=")){
element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); 495 513 element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock());