Commit 1b3210488e83a5db401110253d18b3c6c13ec8ec

Authored by Austin Sun
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

/* 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()){
/* 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 - 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 }
/** 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