Commit 1b3210488e83a5db401110253d18b3c6c13ec8ec
1 parent
c189b2afe2
Exists in
master
hope this works still got some syntax
Showing 4 changed files with 274 additions and 1 deletions Inline Diff
ast_expr.cc
View file @
1b32104
/* 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 | |||
string Operator::getToken() const { | 144 | 145 | string Operator::getToken() const { | |
return tokenString; | 145 | 146 | return tokenString; | |
} | 146 | 147 | } | |
147 | 148 | |||
llvm::Value* IntConstant::Emit() { | 148 | 149 | llvm::Value* IntConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | 149 | 150 | return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | |
} | 150 | 151 | } | |
151 | 152 | |||
llvm::Value* FloatConstant::Emit() { | 152 | 153 | llvm::Value* FloatConstant::Emit() { | |
return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); | 153 | 154 | return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); | |
} | 154 | 155 | } | |
155 | 156 | |||
llvm::Value* BoolConstant::Emit() { | 156 | 157 | llvm::Value* BoolConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | 157 | 158 | return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | |
} | 158 | 159 | } | |
159 | 160 | |||
llvm::Value* Call::Emit() { | 160 | 161 | llvm::Value* Call::Emit() { | |
vector<llvm::Value*> args; | 161 | 162 | vector<llvm::Value*> args; | |
for(int i = 0; i < actuals->NumElements(); i++) { | 162 | 163 | for(int i = 0; i < actuals->NumElements(); i++) { | |
args.push_back(actuals->Nth(i)->Emit()); | 163 | 164 | args.push_back(actuals->Nth(i)->Emit()); | |
} | 164 | 165 | } | |
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | 165 | 166 | return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | |
} | 166 | 167 | } | |
167 | 168 | |||
llvm::Value* CompoundExpr::Emit() { | 168 | 169 | llvm::Value* CompoundExpr::Emit() { | |
llvm::Value* l = left ? left->Emit() : NULL; | 169 | 170 | llvm::Value* l = left ? left->Emit() : NULL; | |
llvm::Value* r = right ? right->Emit() : NULL; | 170 | 171 | llvm::Value* r = right ? right->Emit() : NULL; | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 171 | 172 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
//austins additional value | 172 | 173 | //austins additional value | |
llvm::Value *val; | 173 | 174 | llvm::Value *val; | |
if(!l || !r) { | 174 | 175 | if(!l || !r) { | |
VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); | 175 | 176 | VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); | |
llvm::Value* ret; | 176 | 177 | llvm::Value* ret; | |
llvm::Value* var = l ? l : r; | 177 | 178 | llvm::Value* var = l ? l : r; | |
178 | 179 | |||
if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); | 179 | 180 | if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); | |
else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 180 | 181 | else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
181 | 182 | |||
if(op->getToken() == "++") { | 182 | 183 | if(op->getToken() == "++") { | |
ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); | 183 | 184 | ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); | |
} | 184 | 185 | } | |
else if(op->getToken() == "--") { | 185 | 186 | else if(op->getToken() == "--") { | |
ret = llvm::BinaryOperator::CreateSub(var, val, "", b); | 186 | 187 | ret = llvm::BinaryOperator::CreateSub(var, val, "", b); | |
} | 187 | 188 | } | |
new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); | 188 | 189 | new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); | |
189 | 190 | |||
if(!l) return ret; | 190 | 191 | if(!l) return ret; | |
else return var; | 191 | 192 | else return var; | |
} | 192 | 193 | } | |
if(l->getType()->isFPOrFPVectorTy()) { | 193 | 194 | if(l->getType()->isFPOrFPVectorTy()) { | |
if(op->getToken() == "+") | 194 | 195 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | 195 | 196 | return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | |
if(op->getToken() == "-") | 196 | 197 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | 197 | 198 | return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | |
if(op->getToken() == "*") | 198 | 199 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | 199 | 200 | return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | |
if(op->getToken() == "/") | 200 | 201 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | 201 | 202 | return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | |
if(op->getToken() == "==") | 202 | 203 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | 203 | 204 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | |
if(op->getToken() == "!=") | 204 | 205 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | 205 | 206 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | |
if(op->getToken() == "<=") | 206 | 207 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | 207 | 208 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | |
if(op->getToken() == ">=") | 208 | 209 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | 209 | 210 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | |
if(op->getToken() == "<") | 210 | 211 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | 211 | 212 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | |
if(op->getToken() == ">") | 212 | 213 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | 213 | 214 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | |
} | 214 | 215 | } | |
if(l->getType()->isIntOrIntVectorTy()) { | 215 | 216 | if(l->getType()->isIntOrIntVectorTy()) { | |
if(op->getToken() == "+") | 216 | 217 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | 217 | 218 | return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | |
if(op->getToken() == "-") | 218 | 219 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | 219 | 220 | return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | |
if(op->getToken() == "*") | 220 | 221 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | 221 | 222 | return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | |
if(op->getToken() == "/") | 222 | 223 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | 223 | 224 | return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | |
if(op->getToken() == "==") | 224 | 225 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | 225 | 226 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | |
if(op->getToken() == "!=") | 226 | 227 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | 227 | 228 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | |
if(op->getToken() == "<=") | 228 | 229 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | 229 | 230 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | |
if(op->getToken() == ">=") | 230 | 231 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | 231 | 232 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | |
if(op->getToken() == "<") | 232 | 233 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | 233 | 234 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | |
if(op->getToken() == ">") | 234 | 235 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | 235 | 236 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | |
} | 236 | 237 | } | |
if(op->getToken() == "&&") { | 237 | 238 | if(op->getToken() == "&&") { | |
return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); | 238 | 239 | return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); | |
} | 239 | 240 | } | |
if(op->getToken() == "||") { | 240 | 241 | if(op->getToken() == "||") { | |
return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); | 241 | 242 | return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); | |
} | 242 | 243 | } | |
return NULL; | 243 | 244 | return NULL; | |
245 | } | |||
246 | ||||
247 | //---------------------------------------------------------------------------------------- | |||
248 | //---------------------------------------------------------------------------------------- | |||
249 | llvm::Value * AssignExpr::AssignField(){ | |||
250 | FieldAccess * f = (FieldAccess *) left; | |||
251 | llvm::Value * rightval = right->Emit(); | |||
252 | string operationStr(op->getToken()); | |||
253 | bool isFloat = rightval->getType()->isFloatingPointTy(); | |||
254 | llvm::Type * intTyp = irgen.GetIntType(); | |||
255 | char * ptr = f->getField()->GetName();; | |||
256 | ||||
257 | std::vector<llvm::Constant *> maskI; | |||
258 | for(; *ptr; ptr++){ | |||
259 | switch(*ptr){ | |||
260 | case 'x': | |||
261 | maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); | |||
262 | break; | |||
263 | case 'y': | |||
264 | maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); | |||
265 | break; | |||
266 | case 'z': | |||
267 | maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); | |||
268 | break; | |||
269 | case 'w': | |||
270 | maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); | |||
271 | break; | |||
272 | default: | |||
273 | break; | |||
274 | } | |||
275 | } | |||
276 | llvm::Value * element; | |||
277 | llvm::Value * rightop = rightval; | |||
278 | llvm::Value * base_field = f->getBase()->Emit(); | |||
279 | llvm::Value * storeInst = f->getBase()->Emit(); | |||
280 | ||||
281 | ||||
282 | for (int i = 0; i < maskI.size(); i++){ | |||
283 | element = llvm::ExtractElementInst::Create (base_field, maskI[i], "", irgen.GetBasicBlock()); | |||
284 | if (rightval->getType()->isVectorTy()){ | |||
285 | rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); | |||
286 | } | |||
287 | if (!operationStr.compare("=")){ | |||
288 | storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); | |||
289 | } | |||
290 | if (!operationStr.compare("+=")){ | |||
291 | element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); | |||
292 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
293 | } | |||
294 | if (!operationStr.compare("-=")){ | |||
295 | element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); | |||
296 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
297 | } | |||
298 | if (!operationStr.compare("*=")){ | |||
299 | element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); | |||
300 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
301 | } | |||
302 | if (!operationStr.compare("/=")){ | |||
303 | element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock()); | |||
304 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |||
305 | } | |||
306 | } | |||
307 | VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase()); | |||
308 | ve->AddressStore(storeInst); | |||
309 | if (isFloat){ | |||
310 | return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock()); | |||
311 | } | |||
312 | return storeInst; | |||
313 | } | |||
314 | ||||
315 | llvm::Value * AssignExpr::Emit(){ | |||
316 | llvm::Value * leftval; | |||
317 | llvm::Value * rightval; | |||
318 | ||||
319 | FieldAccess * f = dynamic_cast<FieldAccess *>(left); | |||
320 | if (f){ | |||
321 | return this->AssignField(); | |||
322 | } | |||
323 | leftval = left->Emit(); | |||
324 | rightval = right->Emit(); | |||
325 | ||||
326 | string operationStr(op->getToken()); | |||
327 | ||||
328 | VarExpr * vd = dynamic_cast<VarExpr *>(left); | |||
329 | ||||
330 | llvm::Value * storeInst = NULL; | |||
331 | if ( operationStr.compare("=") == 0 ){ | |||
332 | if (vd){ | |||
333 | vd->AddressStore(rightval); | |||
334 | return rightval; | |||
335 | } | |||
336 | return ((VarExpr *) left)->AddressStore(rightval); | |||
337 | } | |||
338 | else if ( operationStr.compare("+=") == 0 ){ | |||
339 | if (leftval->getType()->isIntegerTy()){ | |||
340 | storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); | |||
341 | if (vd){ | |||
342 | vd->AddressStore(storeInst); | |||
343 | return storeInst; | |||
344 | } | |||
345 | } | |||
346 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |||
347 | storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); | |||
348 | if (vd){ | |||
349 | vd->AddressStore(storeInst); | |||
350 | return storeInst; | |||
351 | } | |||
352 | } | |||
353 | else{ | |||
354 | storeInst = convert(leftval, rightval, 0); | |||
355 | if (vd){ | |||
356 | vd->AddressStore(storeInst); | |||
357 | return storeInst; | |||
358 | } | |||
359 | } | |||
360 | } | |||
361 | else if ( operationStr.compare("-=") == 0 ){ | |||
362 | if (leftval->getType()->isIntegerTy()){ | |||
363 | storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); | |||
364 | if (vd){ | |||
365 | vd->AddressStore(storeInst); | |||
366 | return storeInst; | |||
367 | } | |||
368 | } | |||
369 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |||
370 | storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); | |||
371 | if (vd){ | |||
372 | vd->AddressStore(storeInst); | |||
373 | return storeInst; | |||
374 | } | |||
375 | } | |||
376 | else{ | |||
377 | storeInst = convert(leftval, rightval, 1); | |||
378 | if (vd){ | |||
379 | vd->AddressStore(storeInst); | |||
380 | return storeInst; | |||
381 | } | |||
382 | } | |||
383 | } | |||
384 | else if ( operationStr.compare("*=") == 0 ){ | |||
385 | if (leftval->getType()->isIntegerTy()){ | |||
386 | storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); | |||
387 | if (vd){ | |||
388 | vd->AddressStore(storeInst); | |||
389 | return storeInst; | |||
390 | } | |||
391 | } | |||
392 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |||
393 | storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); | |||
394 | if (vd){ | |||
395 | vd->AddressStore(storeInst); | |||
396 | return storeInst; | |||
397 | } | |||
398 | } | |||
399 | else{ | |||
400 | storeInst = convert(leftval, rightval, 3); | |||
401 | if (vd){ | |||
402 | vd->AddressStore(storeInst); | |||
403 | return storeInst; | |||
404 | } | |||
405 | } | |||
406 | } | |||
407 | else if ( operationStr.compare("/=") == 0 ){ | |||
408 | if (leftval->getType()->isIntegerTy()){ | |||
409 | storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); | |||
410 | if (vd){ | |||
411 | vd->AddressStore(storeInst); | |||
412 | return storeInst; | |||
413 | } | |||
414 | } | |||
415 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |||
416 | storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); | |||
417 | if (vd){ | |||
418 | vd->AddressStore(storeInst); | |||
419 | return storeInst; | |||
420 | } | |||
421 | } | |||
422 | else{ | |||
423 | storeInst = convert(leftval, rightval, 2); | |||
424 | if (vd){ | |||
425 | vd->AddressStore(storeInst); | |||
426 | return storeInst; | |||
427 | } | |||
428 | } | |||
429 | } | |||
430 | return NULL; | |||
431 | } | |||
432 | ||||
433 | llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ | |||
434 | llvm::Type * intTyp = irgen.GetIntType(); | |||
435 | llvm::Type * fltTyp = irgen.GetFloatType(); | |||
436 | llvm::Value *idVal; | |||
437 | llvm::Value * element; | |||
438 | llvm::Value * retVal = vec; | |||
439 | ||||
440 | //get vector size | |||
441 | int numElements=-1; | |||
442 | if(vec->getType()==irgen.GetVec2Type()){ | |||
443 | numElements=2; | |||
444 | } | |||
445 | else if(vec->getType()==irgen.GetVec3Type()){ | |||
446 | numElements=3; | |||
447 | } | |||
448 | else if(vec->getType()==irgen.GetVec4Type()){ |
ast_expr.h
View file @
1b32104
/* 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(); | |
97 | llvm::Value * AddressStore(llvm::Value* store); | |||
}; | 97 | 98 | }; | |
98 | 99 | |||
class Operator : public Node | 99 | 100 | class Operator : public Node | |
{ | 100 | 101 | { | |
protected: | 101 | 102 | protected: | |
char tokenString[4]; | 102 | 103 | char tokenString[4]; | |
103 | 104 | |||
public: | 104 | 105 | public: | |
string getToken() const; | 105 | 106 | string getToken() const; | |
Operator(yyltype loc, const char *tok); | 106 | 107 | Operator(yyltype loc, const char *tok); | |
const char *GetPrintNameForNode() { return "Operator"; } | 107 | 108 | const char *GetPrintNameForNode() { return "Operator"; } | |
void PrintChildren(int indentLevel); | 108 | 109 | void PrintChildren(int indentLevel); | |
friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } | 109 | 110 | friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } | |
bool IsOp(const char *op) const; | 110 | 111 | bool IsOp(const char *op) const; | |
}; | 111 | 112 | }; | |
112 | 113 | |||
class CompoundExpr : public Expr | 113 | 114 | class CompoundExpr : public Expr | |
{ | 114 | 115 | { | |
protected: | 115 | 116 | protected: | |
Operator *op; | 116 | 117 | Operator *op; | |
Expr *left, *right; // left will be NULL if unary | 117 | 118 | Expr *left, *right; // left will be NULL if unary | |
118 | 119 | |||
public: | 119 | 120 | public: | |
CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary | 120 | 121 | CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary | |
CompoundExpr(Operator *op, Expr *rhs); // for unary | 121 | 122 | CompoundExpr(Operator *op, Expr *rhs); // for unary | |
CompoundExpr(Expr *lhs, Operator *op); // for unary | 122 | 123 | CompoundExpr(Expr *lhs, Operator *op); // for unary | |
void PrintChildren(int indentLevel); | 123 | 124 | void PrintChildren(int indentLevel); | |
virtual llvm::Value* Emit(); | 124 | 125 | virtual llvm::Value* Emit(); | |
}; | 125 | 126 | }; | |
126 | 127 | |||
class ArithmeticExpr : public CompoundExpr | 127 | 128 | class ArithmeticExpr : public CompoundExpr | |
{ | 128 | 129 | { | |
public: | 129 | 130 | public: | |
ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 130 | 131 | ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | 131 | 132 | ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | |
const char *GetPrintNameForNode() { return "ArithmeticExpr"; } | 132 | 133 | const char *GetPrintNameForNode() { return "ArithmeticExpr"; } | |
}; | 133 | 134 | }; | |
134 | 135 | |||
class RelationalExpr : public CompoundExpr | 135 | 136 | class RelationalExpr : public CompoundExpr | |
{ | 136 | 137 | { | |
public: | 137 | 138 | public: | |
RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 138 | 139 | RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
const char *GetPrintNameForNode() { return "RelationalExpr"; } | 139 | 140 | const char *GetPrintNameForNode() { return "RelationalExpr"; } | |
}; | 140 | 141 | }; | |
141 | 142 | |||
class EqualityExpr : public CompoundExpr | 142 | 143 | class EqualityExpr : public CompoundExpr | |
{ | 143 | 144 | { | |
public: | 144 | 145 | public: | |
EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 145 | 146 | EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
const char *GetPrintNameForNode() { return "EqualityExpr"; } | 146 | 147 | const char *GetPrintNameForNode() { return "EqualityExpr"; } | |
}; | 147 | 148 | }; | |
148 | 149 | |||
class LogicalExpr : public CompoundExpr | 149 | 150 | class LogicalExpr : public CompoundExpr | |
{ | 150 | 151 | { | |
public: | 151 | 152 | public: | |
LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 152 | 153 | LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | 153 | 154 | LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} | |
const char *GetPrintNameForNode() { return "LogicalExpr"; } | 154 | 155 | const char *GetPrintNameForNode() { return "LogicalExpr"; } | |
}; | 155 | 156 | }; | |
156 | 157 | |||
class AssignExpr : public CompoundExpr | 157 | 158 | class AssignExpr : public CompoundExpr | |
{ | 158 | 159 | { | |
public: | 159 | 160 | public: | |
AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | 160 | 161 | AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} | |
const char *GetPrintNameForNode() { return "AssignExpr"; } | 161 | 162 | const char *GetPrintNameForNode() { return "AssignExpr"; } | |
llvm::Value* Emit(); | 162 | 163 | llvm::Value* Emit(); | |
164 | llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status ); | |||
165 | llvm::Value *AssignField(); | |||
}; | 163 | 166 | }; | |
164 | 167 | |||
class PostfixExpr : public CompoundExpr | 165 | 168 | class PostfixExpr : public CompoundExpr | |
{ | 166 | 169 | { | |
public: | 167 | 170 | public: | |
PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} | 168 | 171 | PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} | |
const char *GetPrintNameForNode() { return "PostfixExpr"; } | 169 | 172 | const char *GetPrintNameForNode() { return "PostfixExpr"; } | |
170 | 173 | |||
}; | 171 | 174 | }; | |
172 | 175 | |||
class ConditionalExpr : public Expr | 173 | 176 | class ConditionalExpr : public Expr | |
{ | 174 | 177 | { | |
protected: | 175 | 178 | protected: | |
Expr *cond, *trueExpr, *falseExpr; | 176 | 179 | Expr *cond, *trueExpr, *falseExpr; | |
public: | 177 | 180 | public: | |
ConditionalExpr(Expr *c, Expr *t, Expr *f); | 178 | 181 | ConditionalExpr(Expr *c, Expr *t, Expr *f); | |
void PrintChildren(int indentLevel); | 179 | 182 | void PrintChildren(int indentLevel); | |
const char *GetPrintNameForNode() { return "ConditionalExpr"; } | 180 | 183 | const char *GetPrintNameForNode() { return "ConditionalExpr"; } | |
}; | 181 | 184 | }; | |
182 | 185 | |||
class LValue : public Expr | 183 | 186 | class LValue : public Expr | |
{ | 184 | 187 | { | |
public: | 185 | 188 | public: | |
LValue(yyltype loc) : Expr(loc) {} | 186 | 189 | LValue(yyltype loc) : Expr(loc) {} | |
}; | 187 | 190 | }; | |
188 | 191 | |||
class ArrayAccess : public LValue | 189 | 192 | class ArrayAccess : public LValue | |
{ | 190 | 193 | { | |
protected: | 191 | 194 | protected: | |
Expr *base, *subscript; | 192 | 195 | Expr *base, *subscript; | |
193 | 196 | |||
public: | 194 | 197 | public: | |
ArrayAccess(yyltype loc, Expr *base, Expr *subscript); | 195 | 198 | ArrayAccess(yyltype loc, Expr *base, Expr *subscript); | |
const char *GetPrintNameForNode() { return "ArrayAccess"; } | 196 | 199 | const char *GetPrintNameForNode() { return "ArrayAccess"; } | |
void PrintChildren(int indentLevel); | 197 | 200 | void PrintChildren(int indentLevel); | |
}; | 198 | 201 | }; | |
199 | 202 | |||
/* Note that field access is used both for qualified names | 200 | 203 | /* Note that field access is used both for qualified names | |
* base.field and just field without qualification. We don't | 201 | 204 | * base.field and just field without qualification. We don't | |
* know for sure whether there is an implicit "this." in | 202 | 205 | * know for sure whether there is an implicit "this." in | |
* front until later on, so we use one node type for either | 203 | 206 | * front until later on, so we use one node type for either | |
* and sort it out later. */ | 204 | 207 | * and sort it out later. */ | |
class FieldAccess : public LValue | 205 | 208 | class FieldAccess : public LValue | |
{ | 206 | 209 | { | |
protected: | 207 | 210 | protected: | |
Expr *base; // will be NULL if no explicit base | 208 | 211 | Expr *base; // will be NULL if no explicit base |
irgen.cc
View file @
1b32104
/* irgen.cc - LLVM IR generator | 1 | 1 | /* irgen.cc - LLVM IR generator | |
* | 2 | 2 | * | |
* You can implement any LLVM related functions here. | 3 | 3 | * You can implement any LLVM related functions here. | |
*/ | 4 | 4 | */ | |
5 | 5 | |||
#include "irgen.h" | 6 | 6 | #include "irgen.h" | |
7 | 7 | |||
IRGenerator irgen; | 8 | 8 | IRGenerator irgen; | |
9 | 9 | |||
IRGenerator::IRGenerator() : | 10 | 10 | IRGenerator::IRGenerator() : | |
context(NULL), | 11 | 11 | context(NULL), | |
module(NULL), | 12 | 12 | module(NULL), | |
currentFunc(NULL), | 13 | 13 | currentFunc(NULL), | |
currentBB(NULL), | 14 | 14 | currentBB(NULL), | |
currentFooter(NULL), | 15 | 15 | currentFooter(NULL), | |
currentHeader(NULL) | 16 | 16 | currentHeader(NULL) | |
{ | 17 | 17 | { | |
} | 18 | 18 | } | |
19 | 19 | |||
IRGenerator::~IRGenerator() { | 20 | 20 | IRGenerator::~IRGenerator() { | |
} | 21 | 21 | } | |
22 | 22 | |||
llvm::Module *IRGenerator::GetOrCreateModule(const char *moduleID) | 23 | 23 | llvm::Module *IRGenerator::GetOrCreateModule(const char *moduleID) | |
{ | 24 | 24 | { | |
if ( module == NULL ) { | 25 | 25 | if ( module == NULL ) { | |
context = new llvm::LLVMContext(); | 26 | 26 | context = new llvm::LLVMContext(); | |
module = new llvm::Module(moduleID, *context); | 27 | 27 | module = new llvm::Module(moduleID, *context); | |
module->setTargetTriple(TargetTriple); | 28 | 28 | module->setTargetTriple(TargetTriple); | |
module->setDataLayout(TargetLayout); | 29 | 29 | module->setDataLayout(TargetLayout); | |
} | 30 | 30 | } | |
return module; | 31 | 31 | return module; | |
} | 32 | 32 | } | |
33 | 33 | |||
void IRGenerator::SetFunction(llvm::Function *func) { | 34 | 34 | void IRGenerator::SetFunction(llvm::Function *func) { | |
currentFunc = func; | 35 | 35 | currentFunc = func; | |
} | 36 | 36 | } | |
37 | 37 | |||
llvm::Function *IRGenerator::GetFunction() const { | 38 | 38 | llvm::Function *IRGenerator::GetFunction() const { | |
return currentFunc; | 39 | 39 | return currentFunc; | |
} | 40 | 40 | } | |
41 | 41 | |||
void IRGenerator::SetBasicBlock(llvm::BasicBlock *bb) { | 42 | 42 | void IRGenerator::SetBasicBlock(llvm::BasicBlock *bb) { | |
currentBB = bb; | 43 | 43 | currentBB = bb; | |
} | 44 | 44 | } | |
45 | 45 | |||
llvm::BasicBlock *IRGenerator::GetBasicBlock() const { | 46 | 46 | llvm::BasicBlock *IRGenerator::GetBasicBlock() const { | |
return currentBB; | 47 | 47 | return currentBB; | |
} | 48 | 48 | } | |
49 | 49 | |||
llvm::Type *IRGenerator::GetIntType() const { | 50 | 50 | llvm::Type *IRGenerator::GetIntType() const { | |
llvm::Type *ty = llvm::Type::getInt32Ty(*context); | 51 | 51 | llvm::Type *ty = llvm::Type::getInt32Ty(*context); | |
return ty; | 52 | 52 | return ty; | |
} | 53 | 53 | } | |
54 | 54 | |||
llvm::Type *IRGenerator::GetBoolType() const { | 55 | 55 | llvm::Type *IRGenerator::GetBoolType() const { | |
llvm::Type *ty = llvm::Type::getInt1Ty(*context); | 56 | 56 | llvm::Type *ty = llvm::Type::getInt1Ty(*context); | |
return ty; | 57 | 57 | return ty; | |
} | 58 | 58 | } | |
59 | 59 | |||
llvm::Type *IRGenerator::GetFloatType() const { | 60 | 60 | llvm::Type *IRGenerator::GetFloatType() const { | |
llvm::Type *ty = llvm::Type::getFloatTy(*context); | 61 | 61 | llvm::Type *ty = llvm::Type::getFloatTy(*context); | |
return ty; | 62 | 62 | return ty; | |
} | 63 | 63 | } | |
64 | 64 | |||
void IRGenerator::SetFooterBlock(llvm::BasicBlock *bb) { | 65 | 65 | void IRGenerator::SetFooterBlock(llvm::BasicBlock *bb) { | |
currentFooter = bb; | 66 | 66 | currentFooter = bb; | |
} | 67 | 67 | } | |
68 | 68 | |||
llvm::BasicBlock *IRGenerator::GetFooterBlock() const { | 69 | 69 | llvm::BasicBlock *IRGenerator::GetFooterBlock() const { | |
return currentFooter; | 70 | 70 | return currentFooter; | |
} | 71 | 71 | } | |
72 | 72 | |||
void IRGenerator::SetHeaderBlock(llvm::BasicBlock *bb){ | 73 | 73 | void IRGenerator::SetHeaderBlock(llvm::BasicBlock *bb){ | |
currentHeader = bb; | 74 | 74 | currentHeader = bb; | |
} | 75 | 75 | } | |
76 | 76 | |||
llvm::BasicBlock *IRGenerator::GetHeaderBlock() const { | 77 | 77 | llvm::BasicBlock *IRGenerator::GetHeaderBlock() const { | |
return currentHeader; | 78 | 78 | return currentHeader; | |
} | 79 | 79 | } | |
80 | 80 | |||
const char *IRGenerator::TargetLayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"; | 81 | 81 | const char *IRGenerator::TargetLayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"; | |
82 | 82 | |||
const char *IRGenerator::TargetTriple = "x86_64-redhat-linux-gnu"; | 83 | 83 | const char *IRGenerator::TargetTriple = "x86_64-redhat-linux-gnu"; | |
84 | ||||
85 | llvm::Type *IRGenerator::GetVec2Type() const{ | |||
86 | return llvm::VectorType::get(llvm::Type::getFloatTy(*context), 2); | |||
87 | } |
irgen.h
View file @
1b32104
/** | 1 | 1 | /** | |
* File: irgen.h | 2 | 2 | * File: irgen.h | |
* ----------- | 3 | 3 | * ----------- | |
* This file defines a class for LLVM IR Generation. | 4 | 4 | * This file defines a class for LLVM IR Generation. | |
* | 5 | 5 | * | |
* All LLVM instruction related functions or utilities can be implemented | 6 | 6 | * All LLVM instruction related functions or utilities can be implemented | |
* here. You'll need to customize this class heavily to provide any helpers | 7 | 7 | * here. You'll need to customize this class heavily to provide any helpers | |
* or untility as you need. | 8 | 8 | * or untility as you need. | |
*/ | 9 | 9 | */ | |
10 | 10 | |||
#ifndef _H_IRGen | 11 | 11 | #ifndef _H_IRGen | |
#define _H_IRGen | 12 | 12 | #define _H_IRGen | |
13 | 13 | |||
// LLVM headers | 14 | 14 | // LLVM headers | |
#include "llvm/IR/Module.h" | 15 | 15 | #include "llvm/IR/Module.h" | |
#include "llvm/IR/LLVMContext.h" | 16 | 16 | #include "llvm/IR/LLVMContext.h" | |
#include "llvm/IR/Instructions.h" | 17 | 17 | #include "llvm/IR/Instructions.h" | |
#include "llvm/IR/Constants.h" | 18 | 18 | #include "llvm/IR/Constants.h" | |
19 | 19 | |||
class IRGenerator { | 20 | 20 | class IRGenerator { | |
public: | 21 | 21 | public: | |
IRGenerator(); | 22 | 22 | IRGenerator(); | |
~IRGenerator(); | 23 | 23 | ~IRGenerator(); | |
24 | 24 | |||
llvm::Module *GetOrCreateModule(const char *moduleID); | 25 | 25 | llvm::Module *GetOrCreateModule(const char *moduleID); | |
llvm::LLVMContext *GetContext() const { return context; } | 26 | 26 | llvm::LLVMContext *GetContext() const { return context; } | |
27 | 27 | |||
// Add your helper functions here | 28 | 28 | // Add your helper functions here | |
llvm::Function *GetFunction() const; | 29 | 29 | llvm::Function *GetFunction() const; | |
void SetFunction(llvm::Function *func); | 30 | 30 | void SetFunction(llvm::Function *func); | |
31 | 31 | |||
llvm::BasicBlock *GetBasicBlock() const; | 32 | 32 | llvm::BasicBlock *GetBasicBlock() const; | |
void SetBasicBlock(llvm::BasicBlock *bb); | 33 | 33 | void SetBasicBlock(llvm::BasicBlock *bb); | |
34 | 34 | |||
llvm::BasicBlock *GetFooterBlock() const; | 35 | 35 | llvm::BasicBlock *GetFooterBlock() const; | |
void SetFooterBlock(llvm::BasicBlock *bb); | 36 | 36 | void SetFooterBlock(llvm::BasicBlock *bb); | |
37 | 37 | |||
llvm::BasicBlock *GetHeaderBlock() const; | 38 | 38 | llvm::BasicBlock *GetHeaderBlock() const; | |
void SetHeaderBlock(llvm::BasicBlock *bb); | 39 | 39 | void SetHeaderBlock(llvm::BasicBlock *bb); | |
40 | 40 | |||
llvm::Type *GetIntType() const; | 41 | 41 | llvm::Type *GetIntType() const; | |
llvm::Type *GetBoolType() const; | 42 | 42 | llvm::Type *GetBoolType() const; | |
llvm::Type *GetFloatType() const; | 43 | 43 | llvm::Type *GetFloatType() const; | |
44 | 44 | |||
45 | llvm::Type *GetVec2Type() const; | |||
46 | ||||
47 | llvm::Type *GetVec3Type() const; | |||
48 | ||||
49 | llvm::Type *GetVec4Type() const; | |||
50 | ||||
51 | llvm::Type *GetMat2Type() const; | |||
52 | ||||
53 | llvm::Type *GetMat3Type() const; | |||
54 | ||||
55 | llvm::Type *GetMat4Type() const; | |||
56 | ||||
private: | 45 | 57 | private: | |
llvm::LLVMContext *context; | 46 | 58 | llvm::LLVMContext *context; | |
llvm::Module *module; | 47 | 59 | llvm::Module *module; | |
48 | 60 |