Commit 521d50fcc059a8c7793f8535f7e88a0cfb7b2009
1 parent
1b3210488e
Exists in
master
wol
Showing 2 changed files with 124 additions and 85 deletions Inline Diff
ast_expr.cc
View file @
521d50f
/* 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, false); | 158 | 158 | return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | |
} | 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, NULL, irgen.GetBasicBlock()); | 166 | 166 | return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | |
} | 167 | 167 | } | |
168 | 168 | |||
llvm::Value* CompoundExpr::Emit() { | 169 | 169 | llvm::Value* CompoundExpr::Emit() { | |
llvm::Value* l = left ? left->Emit() : NULL; | 170 | 170 | llvm::Value* l = left ? left->Emit() : NULL; | |
llvm::Value* r = right ? right->Emit() : NULL; | 171 | 171 | llvm::Value* r = right ? right->Emit() : NULL; | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 172 | 172 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
//austins additional value | 173 | 173 | //austins additional value | |
llvm::Value *val; | 174 | 174 | llvm::Value *val; | |
if(!l || !r) { | 175 | 175 | if(!l || !r) { | |
VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); | 176 | 176 | VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); | |
llvm::Value* ret; | 177 | 177 | llvm::Value* ret; | |
llvm::Value* var = l ? l : r; | 178 | 178 | llvm::Value* var = l ? l : r; | |
179 | 179 | |||
if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); | 180 | 180 | if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); | |
else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 181 | 181 | else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
182 | 182 | |||
if(op->getToken() == "++") { | 183 | 183 | if(op->getToken() == "++") { | |
ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); | 184 | 184 | ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); | |
} | 185 | 185 | } | |
else if(op->getToken() == "--") { | 186 | 186 | else if(op->getToken() == "--") { | |
ret = llvm::BinaryOperator::CreateSub(var, val, "", b); | 187 | 187 | ret = llvm::BinaryOperator::CreateSub(var, val, "", b); | |
} | 188 | 188 | } | |
new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); | 189 | 189 | new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); | |
190 | 190 | |||
if(!l) return ret; | 191 | 191 | if(!l) return ret; | |
else return var; | 192 | 192 | else return var; | |
} | 193 | 193 | } | |
if(l->getType()->isFPOrFPVectorTy()) { | 194 | 194 | if(l->getType()->isFPOrFPVectorTy()) { | |
if(op->getToken() == "+") | 195 | 195 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | 196 | 196 | return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | |
if(op->getToken() == "-") | 197 | 197 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | 198 | 198 | return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | |
if(op->getToken() == "*") | 199 | 199 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | 200 | 200 | return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | |
if(op->getToken() == "/") | 201 | 201 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | 202 | 202 | return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | |
if(op->getToken() == "==") | 203 | 203 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | 204 | 204 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | |
if(op->getToken() == "!=") | 205 | 205 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | 206 | 206 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | |
if(op->getToken() == "<=") | 207 | 207 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | 208 | 208 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | |
if(op->getToken() == ">=") | 209 | 209 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | 210 | 210 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | |
if(op->getToken() == "<") | 211 | 211 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | 212 | 212 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | |
if(op->getToken() == ">") | 213 | 213 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | 214 | 214 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | |
} | 215 | 215 | } | |
if(l->getType()->isIntOrIntVectorTy()) { | 216 | 216 | if(l->getType()->isIntOrIntVectorTy()) { | |
if(op->getToken() == "+") | 217 | 217 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | 218 | 218 | return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | |
if(op->getToken() == "-") | 219 | 219 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | 220 | 220 | return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | |
if(op->getToken() == "*") | 221 | 221 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | 222 | 222 | return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | |
if(op->getToken() == "/") | 223 | 223 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | 224 | 224 | return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | |
if(op->getToken() == "==") | 225 | 225 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | 226 | 226 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | |
if(op->getToken() == "!=") | 227 | 227 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | 228 | 228 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | |
if(op->getToken() == "<=") | 229 | 229 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | 230 | 230 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | |
if(op->getToken() == ">=") | 231 | 231 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | 232 | 232 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | |
if(op->getToken() == "<") | 233 | 233 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | 234 | 234 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | |
if(op->getToken() == ">") | 235 | 235 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | 236 | 236 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | |
} | 237 | 237 | } | |
if(op->getToken() == "&&") { | 238 | 238 | if(op->getToken() == "&&") { | |
return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); | 239 | 239 | return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); | |
} | 240 | 240 | } | |
if(op->getToken() == "||") { | 241 | 241 | if(op->getToken() == "||") { | |
return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); | 242 | 242 | return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); | |
} | 243 | 243 | } | |
return NULL; | 244 | 244 | return NULL; | |
} | 245 | 245 | } | |
246 | 246 | |||
//---------------------------------------------------------------------------------------- | 247 | 247 | //---------------------------------------------------------------------------------------- | |
//---------------------------------------------------------------------------------------- | 248 | 248 | //---------------------------------------------------------------------------------------- | |
llvm::Value * AssignExpr::AssignField(){ | 249 | |||
FieldAccess * f = (FieldAccess *) left; | 250 | |||
llvm::Value * rightval = right->Emit(); | 251 | |||
string operationStr(op->getToken()); | 252 | |||
bool isFloat = rightval->getType()->isFloatingPointTy(); | 253 | |||
llvm::Type * intTyp = irgen.GetIntType(); | 254 | |||
char * ptr = f->getField()->GetName();; | 255 | |||
256 | 249 | |||
std::vector<llvm::Constant *> maskI; | 257 | |||
for(; *ptr; ptr++){ | 258 | |||
switch(*ptr){ | 259 | |||
case 'x': | 260 | |||
maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); | 261 | |||
break; | 262 | |||
case 'y': | 263 | |||
maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); | 264 | |||
break; | 265 | |||
case 'z': | 266 | |||
maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); | 267 | |||
break; | 268 | |||
case 'w': | 269 | |||
maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); | 270 | |||
break; | 271 | |||
default: | 272 | |||
break; | 273 | |||
} | 274 | |||
} | 275 | |||
llvm::Value * element; | 276 | |||
llvm::Value * rightop = rightval; | 277 | |||
llvm::Value * base_field = f->getBase()->Emit(); | 278 | |||
llvm::Value * storeInst = f->getBase()->Emit(); | 279 | |||
280 | ||||
281 | ||||
for (int i = 0; i < maskI.size(); i++){ | 282 | |||
element = llvm::ExtractElementInst::Create (base_field, maskI[i], "", irgen.GetBasicBlock()); | 283 | |||
if (rightval->getType()->isVectorTy()){ | 284 | |||
rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); | 285 | |||
} | 286 | |||
if (!operationStr.compare("=")){ | 287 | |||
storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); | 288 | |||
} | 289 | |||
if (!operationStr.compare("+=")){ | 290 | |||
element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); | 291 | |||
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | 292 | |||
} | 293 | |||
if (!operationStr.compare("-=")){ | 294 | |||
element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); | 295 | |||
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | 296 | |||
} | 297 | |||
if (!operationStr.compare("*=")){ | 298 | |||
element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); | 299 | |||
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | 300 | |||
} | 301 | |||
if (!operationStr.compare("/=")){ | 302 | |||
element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock()); | 303 | |||
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | 304 | |||
} | 305 | |||
} | 306 | |||
VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase()); | 307 | |||
ve->AddressStore(storeInst); | 308 | |||
if (isFloat){ | 309 | |||
return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock()); | 310 | |||
} | 311 | |||
return storeInst; | 312 | |||
} | 313 | |||
314 | ||||
llvm::Value * AssignExpr::Emit(){ | 315 | 250 | llvm::Value * AssignExpr::Emit(){ | |
llvm::Value * leftval; | 316 | 251 | llvm::Value * leftval; | |
llvm::Value * rightval; | 317 | 252 | llvm::Value * rightval; | |
318 | 253 | |||
FieldAccess * f = dynamic_cast<FieldAccess *>(left); | 319 | 254 | FieldAccess * f = dynamic_cast<FieldAccess *>(left); | |
if (f){ | 320 | 255 | if (f){ | |
return this->AssignField(); | 321 | 256 | return this->AssignField(); | |
} | 322 | 257 | } | |
leftval = left->Emit(); | 323 | 258 | leftval = left->Emit(); | |
rightval = right->Emit(); | 324 | 259 | rightval = right->Emit(); | |
325 | 260 | |||
string operationStr(op->getToken()); | 326 | 261 | string operationStr(op->getToken()); | |
327 | 262 | |||
VarExpr * vd = dynamic_cast<VarExpr *>(left); | 328 | 263 | VarExpr * vd = dynamic_cast<VarExpr *>(left); | |
329 | 264 | |||
llvm::Value * storeInst = NULL; | 330 | 265 | llvm::Value * storeInst = NULL; | |
if ( operationStr.compare("=") == 0 ){ | 331 | 266 | if ( operationStr.compare("+=") == 0 ){ | |
if (vd){ | 332 | |||
vd->AddressStore(rightval); | 333 | |||
return rightval; | 334 | |||
} | 335 | |||
return ((VarExpr *) left)->AddressStore(rightval); | 336 | |||
} | 337 | |||
else if ( operationStr.compare("+=") == 0 ){ | 338 | |||
if (leftval->getType()->isIntegerTy()){ | 339 | 267 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); | 340 | 268 | storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 341 | 269 | if (vd){ | |
vd->AddressStore(storeInst); | 342 | 270 | vd->AddressStore(storeInst); | |
return storeInst; | 343 | 271 | return storeInst; | |
} | 344 | 272 | } | |
} | 345 | 273 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 346 | 274 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); | 347 | 275 | storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 348 | 276 | if (vd){ | |
vd->AddressStore(storeInst); | 349 | 277 | vd->AddressStore(storeInst); | |
return storeInst; | 350 | 278 | return storeInst; | |
} | 351 | 279 | } | |
} | 352 | 280 | } | |
else{ | 353 | 281 | else{ | |
storeInst = convert(leftval, rightval, 0); | 354 | 282 | storeInst = convert(leftval, rightval, 0); | |
if (vd){ | 355 | 283 | if (vd){ | |
vd->AddressStore(storeInst); | 356 | 284 | vd->AddressStore(storeInst); | |
return storeInst; | 357 | 285 | return storeInst; | |
} | 358 | 286 | } | |
} | 359 | 287 | } | |
} | 360 | 288 | } | |
289 | else if ( operationStr.compare("=") == 0 ){ | |||
290 | if (vd){ | |||
291 | vd->AddressStore(rightval); | |||
292 | return rightval; | |||
293 | } | |||
294 | return ((VarExpr *) left)->AddressStore(rightval); | |||
295 | } | |||
else if ( operationStr.compare("-=") == 0 ){ | 361 | 296 | else if ( operationStr.compare("-=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 362 | 297 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); | 363 | 298 | storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 364 | 299 | if (vd){ | |
vd->AddressStore(storeInst); | 365 | 300 | vd->AddressStore(storeInst); | |
return storeInst; | 366 | 301 | return storeInst; | |
} | 367 | 302 | } | |
} | 368 | 303 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 369 | 304 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); | 370 | 305 | storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 371 | 306 | if (vd){ | |
vd->AddressStore(storeInst); | 372 | 307 | vd->AddressStore(storeInst); | |
return storeInst; | 373 | 308 | return storeInst; | |
} | 374 | 309 | } | |
} | 375 | 310 | } | |
else{ | 376 | 311 | else{ | |
storeInst = convert(leftval, rightval, 1); | 377 | 312 | storeInst = convert(leftval, rightval, 1); | |
if (vd){ | 378 | 313 | if (vd){ | |
vd->AddressStore(storeInst); | 379 | 314 | vd->AddressStore(storeInst); | |
return storeInst; | 380 | 315 | return storeInst; | |
} | 381 | 316 | } | |
} | 382 | 317 | } | |
} | 383 | 318 | } | |
else if ( operationStr.compare("*=") == 0 ){ | 384 | 319 | else if ( operationStr.compare("/=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 385 | 320 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); | 386 | 321 | storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 387 | 322 | if (vd){ | |
vd->AddressStore(storeInst); | 388 | 323 | vd->AddressStore(storeInst); | |
return storeInst; | 389 | 324 | return storeInst; | |
} | 390 | 325 | } | |
} | 391 | 326 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 392 | 327 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); | 393 | 328 | storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 394 | 329 | if (vd){ | |
vd->AddressStore(storeInst); | 395 | 330 | vd->AddressStore(storeInst); | |
return storeInst; | 396 | 331 | return storeInst; | |
} | 397 | 332 | } | |
} | 398 | 333 | } | |
else{ | 399 | 334 | else{ | |
storeInst = convert(leftval, rightval, 3); | 400 | 335 | storeInst = convert(leftval, rightval, 2); | |
if (vd){ | 401 | 336 | if (vd){ | |
vd->AddressStore(storeInst); | 402 | 337 | vd->AddressStore(storeInst); | |
return storeInst; | 403 | 338 | return storeInst; | |
} | 404 | 339 | } | |
} | 405 | 340 | } | |
} | 406 | 341 | } | |
else if ( operationStr.compare("/=") == 0 ){ | 407 | 342 | else if ( operationStr.compare("*=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 408 | 343 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); | 409 | 344 | storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 410 | 345 | if (vd){ | |
vd->AddressStore(storeInst); | 411 | 346 | vd->AddressStore(storeInst); | |
return storeInst; | 412 | 347 | return storeInst; | |
} | 413 | 348 | } | |
} | 414 | 349 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 415 | 350 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); | 416 | 351 | storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 417 | 352 | if (vd){ | |
vd->AddressStore(storeInst); | 418 | 353 | vd->AddressStore(storeInst); | |
return storeInst; | 419 | 354 | return storeInst; | |
} | 420 | 355 | } | |
} | 421 | 356 | } | |
else{ | 422 | 357 | else{ | |
storeInst = convert(leftval, rightval, 2); | 423 | 358 | storeInst = convert(leftval, rightval, 3); | |
if (vd){ | 424 | 359 | if (vd){ | |
vd->AddressStore(storeInst); | 425 | 360 | vd->AddressStore(storeInst); | |
return storeInst; | 426 | 361 | return storeInst; | |
} | 427 | 362 | } | |
} | 428 | 363 | } | |
} | 429 | 364 | } | |
return NULL; | 430 | 365 | return NULL; | |
} | 431 | 366 | } | |
432 | 367 | |||
llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ | 433 | 368 | llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ | |
llvm::Type * intTyp = irgen.GetIntType(); | 434 | 369 | llvm::Type * intTyp = irgen.GetIntType(); | |
llvm::Type * fltTyp = irgen.GetFloatType(); | 435 | 370 | llvm::Type * fltTyp = irgen.GetFloatType(); | |
llvm::Value *idVal; | 436 | 371 | llvm::Value *idVal; | |
llvm::Value * element; | 437 | 372 | llvm::Value * element; | |
llvm::Value * retVal = vec; | 438 | 373 | llvm::Value * retVal = vec; | |
439 | 374 | |||
//get vector size | 440 | 375 | //get vector size | |
int numElements=-1; | 441 | 376 | int numElements=-1; | |
if(vec->getType()==irgen.GetVec2Type()){ | 442 | 377 | if(vec->getType()==irgen.GetVec2Type()){ | |
numElements=2; | 443 | 378 | numElements=2; | |
} | 444 | 379 | } | |
else if(vec->getType()==irgen.GetVec3Type()){ | 445 | 380 | else if(vec->getType()==irgen.GetVec3Type()){ | |
numElements=3; | 446 | 381 | numElements=3; | |
} | 447 | 382 | } | |
else if(vec->getType()==irgen.GetVec4Type()){ | 448 | 383 | else if(vec->getType()==irgen.GetVec4Type()){ | |
numElements=4; | 449 | 384 | numElements=4; | |
} | 450 | 385 | } | |
451 | 386 | |||
for (int i = 0; i < numElements; i++){ | 452 | 387 | for (int i = 0; i < numElements; i++){ | |
idVal = llvm::ConstantInt::get(intTyp, i); | 453 | 388 | idVal = llvm::ConstantInt::get(intTyp, i); | |
element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); | 454 | 389 | element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); | |
if (status == 0){ | 455 | 390 | if (status == 0){ | |
element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); | 456 | 391 | element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); | |
} | 457 | 392 | } | |
else if (status == 1){ | 458 | 393 | else if (status == 1){ | |
element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); | 459 | 394 | element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); | |
} | 460 | 395 | } | |
else if (status == 2){ | 461 | 396 | else if (status == 2){ | |
element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); | 462 | 397 | element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); | |
} | 463 | 398 | } | |
else{ | 464 | 399 | else{ | |
element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); | 465 | 400 | element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); | |
} | 466 | 401 | } | |
retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); | 467 | 402 | retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); | |
} | 468 | 403 | } | |
return retVal; | 469 | 404 | return retVal; | |
} | 470 | 405 | } | |
471 | 406 | |||
llvm::Value* VarExpr::AddressStore(llvm::Value *store){ | 472 | 407 | llvm::Value* VarExpr::AddressStore(llvm::Value *store){ | |
char * varname = GetIdentifier()->GetName(); | 473 | 408 | char * varname = GetIdentifier()->GetName(); | |
474 | 409 | |||
pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); | 475 | 410 | pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); | |
//value of symbol | 476 | 411 | //value of symbol | |
llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, "",irgen.GetBasicBlock()); | 477 | 412 | llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, "",irgen.GetBasicBlock()); | |
return storeInst; | 478 | 413 | return storeInst; | |
414 | } | |||
415 | ||||
416 | llvm::Value * AssignExpr::AssignField(){ | |||
417 | FieldAccess * f = (FieldAccess *) left; | |||
418 | llvm::Value * rightval = right->Emit(); | |||
419 | string operationStr(op->getToken()); | |||
420 | bool isFloat = rightval->getType()->isFloatingPointTy(); | |||
421 | llvm::Type * intTyp = irgen.GetIntType(); | |||
422 | char * ptr = f->getField()->GetName();; | |||
423 | ||||
424 | std::vector<llvm::Constant *> maskI; | |||
425 | for(; *ptr; ptr++){ | |||
426 | if(*ptr =='x'){ | |||
427 | maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); | |||
428 | } | |||
429 | else if(*ptr='y'){ | |||
430 | maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); | |||
431 | } | |||
432 | else if(*ptr='z'){ | |||
433 | maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); | |||
434 | } | |||
435 | else if(*ptr='w'){ | |||
436 | maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); | |||
437 | } | |||
438 | } | |||
439 | ||||
440 | llvm::Value * element; | |||
441 | llvm::Value * rightop = rightval; | |||
442 | llvm::Value * baseF = f->getBase()->Emit(); | |||
443 | llvm::Value * storeInst = f->getBase()->Emit(); | |||
444 | ||||
445 | ||||
446 | for (int i = 0; i < maskI.size(); i++){ | |||
447 | element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock()); | |||
448 | if (rightval->getType()->isVectorTy()){ | |||
449 | rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); | |||
450 | } | |||
451 | if (!operationStr.compare("=")){ | |||
452 | storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); | |||
453 | } | |||
454 | if (!operationStr.compare("+=")){ | |||
455 | element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); | |||
456 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
457 | } | |||
458 | if (!operationStr.compare("-=")){ | |||
459 | element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); | |||
460 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
461 | } | |||
462 | if (!operationStr.compare("*=")){ | |||
463 | element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); | |||
464 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
465 | } | |||
466 | if (!operationStr.compare("/=")){ | |||
467 | element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock()); | |||
468 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
469 | } | |||
470 | } | |||
471 | VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase()); | |||
472 | ve->AddressStore(storeInst); | |||
473 | if (isFloat){ | |||
474 | return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock()); | |||
475 | } | |||
476 | return storeInst; | |||
477 | } | |||
478 | ||||
479 | ||||
480 | llvm::Value * FieldAccess::Emit(){ | |||
481 | char * mask = this->getField()->GetName(); | |||
482 | char * ptr = mask; | |||
483 | ||||
484 | llvm::Type * intTyp = irgen.GetIntType(); | |||
485 | std::vector<llvm::Constant *> maskI; |
ast_expr.h
View file @
521d50f
/* File: ast_expr.h | 1 | 1 | /* File: ast_expr.h | |
* ---------------- | 2 | 2 | * ---------------- | |
* The Expr class and its subclasses are used to represent | 3 | 3 | * The Expr class and its subclasses are used to represent | |
* expressions in the parse tree. For each expression in the | 4 | 4 | * expressions in the parse tree. For each expression in the | |
* language (add, call, New, etc.) there is a corresponding | 5 | 5 | * language (add, call, New, etc.) there is a corresponding | |
* node class for that construct. | 6 | 6 | * node class for that construct. | |
* | 7 | 7 | * | |
* pp3: You will need to extend the Expr classes to implement | 8 | 8 | * pp3: You will need to extend the Expr classes to implement | |
* semantic analysis for rules pertaining to expressions. | 9 | 9 | * semantic analysis for rules pertaining to expressions. | |
*/ | 10 | 10 | */ | |
11 | 11 | |||
12 | 12 | |||
#ifndef _H_ast_expr | 13 | 13 | #ifndef _H_ast_expr | |
#define _H_ast_expr | 14 | 14 | #define _H_ast_expr | |
15 | 15 | |||
#include "ast.h" | 16 | 16 | #include "ast.h" | |
#include "ast_stmt.h" | 17 | 17 | #include "ast_stmt.h" | |
#include "list.h" | 18 | 18 | #include "list.h" | |
#include "ast_type.h" | 19 | 19 | #include "ast_type.h" | |
20 | 20 | |||
void yyerror(const char *msg); | 21 | 21 | void yyerror(const char *msg); | |
22 | 22 | |||
class Expr : public Stmt | 23 | 23 | class Expr : public Stmt | |
{ | 24 | 24 | { | |
public: | 25 | 25 | public: | |
Expr(yyltype loc) : Stmt(loc) {} | 26 | 26 | Expr(yyltype loc) : Stmt(loc) {} | |
Expr() : Stmt() {} | 27 | 27 | Expr() : Stmt() {} | |
28 | 28 | |||
friend std::ostream& operator<< (std::ostream& stream, Expr * expr) { | 29 | 29 | friend std::ostream& operator<< (std::ostream& stream, Expr * expr) { | |
return stream << expr->GetPrintNameForNode(); | 30 | 30 | return stream << expr->GetPrintNameForNode(); | |
} | 31 | 31 | } | |
}; | 32 | 32 | }; | |
33 | 33 | |||
class ExprError : public Expr | 34 | 34 | class ExprError : public Expr | |
{ | 35 | 35 | { | |
public: | 36 | 36 | public: | |
ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); } | 37 | 37 | ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); } | |
const char *GetPrintNameForNode() { return "ExprError"; } | 38 | 38 | const char *GetPrintNameForNode() { return "ExprError"; } | |
}; | 39 | 39 | }; | |
40 | 40 | |||
/* This node type is used for those places where an expression is optional. | 41 | 41 | /* This node type is used for those places where an expression is optional. | |
* We could use a NULL pointer, but then it adds a lot of checking for | 42 | 42 | * We could use a NULL pointer, but then it adds a lot of checking for | |
* NULL. By using a valid, but no-op, node, we save that trouble */ | 43 | 43 | * NULL. By using a valid, but no-op, node, we save that trouble */ | |
class EmptyExpr : public Expr | 44 | 44 | class EmptyExpr : public Expr | |
{ | 45 | 45 | { | |
public: | 46 | 46 | public: | |
const char *GetPrintNameForNode() { return "Empty"; } | 47 | 47 | const char *GetPrintNameForNode() { return "Empty"; } | |
}; | 48 | 48 | }; | |
49 | 49 | |||
class IntConstant : public Expr | 50 | 50 | class IntConstant : public Expr | |
{ | 51 | 51 | { | |
protected: | 52 | 52 | protected: | |
int value; | 53 | 53 | int value; | |
54 | 54 | |||
public: | 55 | 55 | public: | |
IntConstant(yyltype loc, int val); | 56 | 56 | IntConstant(yyltype loc, int val); | |
const char *GetPrintNameForNode() { return "IntConstant"; } | 57 | 57 | const char *GetPrintNameForNode() { return "IntConstant"; } | |
void PrintChildren(int indentLevel); | 58 | 58 | void PrintChildren(int indentLevel); | |
llvm::Value* Emit(); | 59 | 59 | llvm::Value* Emit(); | |
}; | 60 | 60 | }; | |
61 | 61 | |||
class FloatConstant: public Expr | 62 | 62 | class FloatConstant: public Expr | |
{ | 63 | 63 | { | |
protected: | 64 | 64 | protected: | |
double value; | 65 | 65 | double value; | |
66 | 66 | |||
public: | 67 | 67 | public: | |
FloatConstant(yyltype loc, double val); | 68 | 68 | FloatConstant(yyltype loc, double val); | |
const char *GetPrintNameForNode() { return "FloatConstant"; } | 69 | 69 | const char *GetPrintNameForNode() { return "FloatConstant"; } | |
void PrintChildren(int indentLevel); | 70 | 70 | void PrintChildren(int indentLevel); | |
llvm::Value* Emit(); | 71 | 71 | llvm::Value* Emit(); | |
}; | 72 | 72 | }; | |
73 | 73 | |||
class BoolConstant : public Expr | 74 | 74 | class BoolConstant : public Expr | |
{ | 75 | 75 | { | |
protected: | 76 | 76 | protected: | |
bool value; | 77 | 77 | bool value; | |
78 | 78 | |||
public: | 79 | 79 | public: | |
BoolConstant(yyltype loc, bool val); | 80 | 80 | BoolConstant(yyltype loc, bool val); | |
const char *GetPrintNameForNode() { return "BoolConstant"; } | 81 | 81 | const char *GetPrintNameForNode() { return "BoolConstant"; } | |
void PrintChildren(int indentLevel); | 82 | 82 | void PrintChildren(int indentLevel); | |
llvm::Value* Emit(); | 83 | 83 | llvm::Value* Emit(); | |
}; | 84 | 84 | }; | |
85 | 85 | |||
class VarExpr : public Expr | 86 | 86 | class VarExpr : public Expr | |
{ | 87 | 87 | { | |
protected: | 88 | 88 | protected: | |
Identifier *id; | 89 | 89 | Identifier *id; | |
90 | 90 | |||
public: | 91 | 91 | public: | |
VarExpr(yyltype loc, Identifier *id); | 92 | 92 | VarExpr(yyltype loc, Identifier *id); | |
const char *GetPrintNameForNode() { return "VarExpr"; } | 93 | 93 | const char *GetPrintNameForNode() { return "VarExpr"; } | |
void PrintChildren(int indentLevel); | 94 | 94 | void PrintChildren(int indentLevel); | |
Identifier *GetIdentifier() {return id;} | 95 | 95 | Identifier *GetIdentifier() {return id;} | |
llvm::Value* Emit(); | 96 | 96 | llvm::Value* Emit(); | |
llvm::Value * AddressStore(llvm::Value* store); | 97 | 97 | llvm::Value * AddressStore(llvm::Value* store); | |
}; | 98 | 98 | }; | |
99 | 99 | |||
class Operator : public Node | 100 | 100 | class Operator : public Node | |
{ | 101 | 101 | { | |
protected: | 102 | 102 | protected: | |
char tokenString[4]; | 103 | 103 | char tokenString[4]; | |
104 | 104 | |||
public: | 105 | 105 | public: | |
string getToken() const; | 106 | 106 | string getToken() const; | |
Operator(yyltype loc, const char *tok); | 107 | 107 | Operator(yyltype loc, const char *tok); | |
const char *GetPrintNameForNode() { return "Operator"; } | 108 | 108 | const char *GetPrintNameForNode() { return "Operator"; } | |
void PrintChildren(int indentLevel); | 109 | 109 | void PrintChildren(int indentLevel); | |
friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } | 110 | 110 | friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } | |
bool IsOp(const char *op) const; | 111 | 111 | bool IsOp(const char *op) const; | |
}; | 112 | 112 | }; | |
113 | 113 | |||
class CompoundExpr : public Expr | 114 | 114 | class CompoundExpr : public Expr | |
{ | 115 | 115 | { | |
protected: | 116 | 116 | protected: | |
Operator *op; | 117 | 117 | Operator *op; | |
Expr *left, *right; // left will be NULL if unary | 118 | 118 | Expr *left, *right; // left will be NULL if unary | |
119 | 119 | |||
public: | 120 | 120 | public: | |
CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary | 121 | 121 | CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary | |
CompoundExpr(Operator *op, Expr *rhs); // for unary | 122 | 122 | CompoundExpr(Operator *op, Expr *rhs); // for unary | |
CompoundExpr(Expr *lhs, Operator *op); // for unary | 123 | 123 | CompoundExpr(Expr *lhs, Operator *op); // for unary | |
void PrintChildren(int indentLevel); | 124 | 124 | void PrintChildren(int indentLevel); | |
virtual llvm::Value* Emit(); | 125 | 125 | virtual llvm::Value* Emit(); | |
}; | 126 | 126 | }; | |
127 | 127 | |||
class ArithmeticExpr : public CompoundExpr | 128 | 128 | class ArithmeticExpr : public CompoundExpr | |
{ | 129 | 129 | { | |
public: | 130 | 130 | public: | |
ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 131 | 131 | ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | 132 | 132 | ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | |
const char *GetPrintNameForNode() { return "ArithmeticExpr"; } | 133 | 133 | const char *GetPrintNameForNode() { return "ArithmeticExpr"; } | |
}; | 134 | 134 | }; | |
135 | 135 | |||
class RelationalExpr : public CompoundExpr | 136 | 136 | class RelationalExpr : public CompoundExpr | |
{ | 137 | 137 | { | |
public: | 138 | 138 | public: | |
RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 139 | 139 | RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
const char *GetPrintNameForNode() { return "RelationalExpr"; } | 140 | 140 | const char *GetPrintNameForNode() { return "RelationalExpr"; } | |
}; | 141 | 141 | }; | |
142 | 142 | |||
class EqualityExpr : public CompoundExpr | 143 | 143 | class EqualityExpr : public CompoundExpr | |
{ | 144 | 144 | { | |
public: | 145 | 145 | public: | |
EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 146 | 146 | EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
const char *GetPrintNameForNode() { return "EqualityExpr"; } | 147 | 147 | const char *GetPrintNameForNode() { return "EqualityExpr"; } | |
}; | 148 | 148 | }; | |
149 | 149 | |||
class LogicalExpr : public CompoundExpr | 150 | 150 | class LogicalExpr : public CompoundExpr | |
{ | 151 | 151 | { | |
public: | 152 | 152 | public: | |
LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 153 | 153 | LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | 154 | 154 | LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | |
const char *GetPrintNameForNode() { return "LogicalExpr"; } | 155 | 155 | const char *GetPrintNameForNode() { return "LogicalExpr"; } | |
}; | 156 | 156 | }; | |
157 | 157 | |||
class AssignExpr : public CompoundExpr | 158 | 158 | class AssignExpr : public CompoundExpr | |
{ | 159 | 159 | { | |
public: | 160 | 160 | public: | |
AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 161 | 161 | AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
const char *GetPrintNameForNode() { return "AssignExpr"; } | 162 | 162 | const char *GetPrintNameForNode() { return "AssignExpr"; } | |
llvm::Value* Emit(); | 163 | 163 | llvm::Value* Emit(); | |
llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status ); | 164 | 164 | llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status ); | |
llvm::Value *AssignField(); | 165 | 165 | llvm::Value *AssignField(); | |
}; | 166 | 166 | }; | |
167 | 167 | |||
class PostfixExpr : public CompoundExpr | 168 | 168 | class PostfixExpr : public CompoundExpr | |
{ | 169 | 169 | { | |
public: | 170 | 170 | public: | |
PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} | 171 | 171 | PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} | |
const char *GetPrintNameForNode() { return "PostfixExpr"; } | 172 | 172 | const char *GetPrintNameForNode() { return "PostfixExpr"; } | |
173 | 173 | |||
}; | 174 | 174 | }; | |
175 | 175 | |||
class ConditionalExpr : public Expr | 176 | 176 | class ConditionalExpr : public Expr | |
{ | 177 | 177 | { | |
protected: | 178 | 178 | protected: | |
Expr *cond, *trueExpr, *falseExpr; | 179 | 179 | Expr *cond, *trueExpr, *falseExpr; | |
public: | 180 | 180 | public: | |
ConditionalExpr(Expr *c, Expr *t, Expr *f); | 181 | 181 | ConditionalExpr(Expr *c, Expr *t, Expr *f); | |
void PrintChildren(int indentLevel); | 182 | 182 | void PrintChildren(int indentLevel); | |
const char *GetPrintNameForNode() { return "ConditionalExpr"; } | 183 | 183 | const char *GetPrintNameForNode() { return "ConditionalExpr"; } | |
}; | 184 | 184 | }; | |
185 | 185 | |||
class LValue : public Expr | 186 | 186 | class LValue : public Expr | |
{ | 187 | 187 | { | |
public: | 188 | 188 | public: | |
LValue(yyltype loc) : Expr(loc) {} | 189 | 189 | LValue(yyltype loc) : Expr(loc) {} | |
}; | 190 | 190 | }; | |
191 | 191 | |||
class ArrayAccess : public LValue | 192 | 192 | class ArrayAccess : public LValue | |
{ | 193 | 193 | { | |
protected: | 194 | 194 | protected: | |
Expr *base, *subscript; | 195 | 195 | Expr *base, *subscript; | |
196 | 196 | |||
public: | 197 | 197 | public: | |
ArrayAccess(yyltype loc, Expr *base, Expr *subscript); | 198 | 198 | ArrayAccess(yyltype loc, Expr *base, Expr *subscript); | |
const char *GetPrintNameForNode() { return "ArrayAccess"; } | 199 | 199 | const char *GetPrintNameForNode() { return "ArrayAccess"; } | |
void PrintChildren(int indentLevel); | 200 | 200 | void PrintChildren(int indentLevel); | |
}; | 201 | 201 | }; | |
202 | 202 | |||
/* Note that field access is used both for qualified names | 203 | 203 | /* Note that field access is used both for qualified names | |
* base.field and just field without qualification. We don't | 204 | 204 | * base.field and just field without qualification. We don't | |
* know for sure whether there is an implicit "this." in | 205 | 205 | * know for sure whether there is an implicit "this." in | |
* front until later on, so we use one node type for either | 206 | 206 | * front until later on, so we use one node type for either | |
* and sort it out later. */ | 207 | 207 | * and sort it out later. */ | |
class FieldAccess : public LValue | 208 | 208 | class FieldAccess : public LValue | |
{ | 209 | 209 | { | |
protected: | 210 | 210 | protected: | |
Expr *base; // will be NULL if no explicit base | 211 | 211 | Expr *base; // will be NULL if no explicit base | |
Identifier *field; | 212 | 212 | Identifier *field; |