Commit 2cead1f5e8bfb78b7f54257f4f50b9c22bf79ffc

Authored by Austin Sun
1 parent ebc2ecde2e
Exists in master

minor fixes arrays still dont work

Showing 6 changed files with 53 additions and 5 deletions Inline Diff

/* File: ast_decl.cc 1 1 /* File: ast_decl.cc
* ----------------- 2 2 * -----------------
* Implementation of Decl node classes. 3 3 * Implementation of Decl node classes.
*/ 4 4 */
#include "ast_decl.h" 5 5 #include "ast_decl.h"
#include "ast_type.h" 6 6 #include "ast_type.h"
#include "ast_stmt.h" 7 7 #include "ast_stmt.h"
#include "symtable.h" 8 8 #include "symtable.h"
9 9
Decl::Decl(Identifier *n) : Node(*n->GetLocation()) { 10 10 Decl::Decl(Identifier *n) : Node(*n->GetLocation()) {
Assert(n != NULL); 11 11 Assert(n != NULL);
(id=n)->SetParent(this); 12 12 (id=n)->SetParent(this);
} 13 13 }
14 14
VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) { 15 15 VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) {
Assert(n != NULL && t != NULL); 16 16 Assert(n != NULL && t != NULL);
(type=t)->SetParent(this); 17 17 (type=t)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 18 18 if (e) (assignTo=e)->SetParent(this);
typeq = NULL; 19 19 typeq = NULL;
} 20 20 }
21 21
VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) { 22 22 VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) {
Assert(n != NULL && tq != NULL); 23 23 Assert(n != NULL && tq != NULL);
(typeq=tq)->SetParent(this); 24 24 (typeq=tq)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 25 25 if (e) (assignTo=e)->SetParent(this);
type = NULL; 26 26 type = NULL;
} 27 27 }
28 28
VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) { 29 29 VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) {
Assert(n != NULL && t != NULL && tq != NULL); 30 30 Assert(n != NULL && t != NULL && tq != NULL);
(type=t)->SetParent(this); 31 31 (type=t)->SetParent(this);
(typeq=tq)->SetParent(this); 32 32 (typeq=tq)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 33 33 if (e) (assignTo=e)->SetParent(this);
} 34 34 }
35 35
void VarDecl::PrintChildren(int indentLevel) { 36 36 void VarDecl::PrintChildren(int indentLevel) {
if (typeq) typeq->Print(indentLevel+1); 37 37 if (typeq) typeq->Print(indentLevel+1);
if (type) type->Print(indentLevel+1); 38 38 if (type) type->Print(indentLevel+1);
if (id) id->Print(indentLevel+1); 39 39 if (id) id->Print(indentLevel+1);
if (assignTo) assignTo->Print(indentLevel+1, "(initializer) "); 40 40 if (assignTo) assignTo->Print(indentLevel+1, "(initializer) ");
} 41 41 }
42 42
FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) { 43 43 FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) {
Assert(n != NULL && r!= NULL && d != NULL); 44 44 Assert(n != NULL && r!= NULL && d != NULL);
(returnType=r)->SetParent(this); 45 45 (returnType=r)->SetParent(this);
(formals=d)->SetParentAll(this); 46 46 (formals=d)->SetParentAll(this);
body = NULL; 47 47 body = NULL;
returnTypeq = NULL; 48 48 returnTypeq = NULL;
} 49 49 }
50 50
FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) { 51 51 FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) {
Assert(n != NULL && r != NULL && rq != NULL&& d != NULL); 52 52 Assert(n != NULL && r != NULL && rq != NULL&& d != NULL);
(returnType=r)->SetParent(this); 53 53 (returnType=r)->SetParent(this);
(returnTypeq=rq)->SetParent(this); 54 54 (returnTypeq=rq)->SetParent(this);
(formals=d)->SetParentAll(this); 55 55 (formals=d)->SetParentAll(this);
body = NULL; 56 56 body = NULL;
} 57 57 }
58 58
void FnDecl::SetFunctionBody(Stmt *b) { 59 59 void FnDecl::SetFunctionBody(Stmt *b) {
(body=b)->SetParent(this); 60 60 (body=b)->SetParent(this);
} 61 61 }
62 62
void FnDecl::PrintChildren(int indentLevel) { 63 63 void FnDecl::PrintChildren(int indentLevel) {
if (returnType) returnType->Print(indentLevel+1, "(return type) "); 64 64 if (returnType) returnType->Print(indentLevel+1, "(return type) ");
if (id) id->Print(indentLevel+1); 65 65 if (id) id->Print(indentLevel+1);
if (formals) formals->PrintAll(indentLevel+1, "(formals) "); 66 66 if (formals) formals->PrintAll(indentLevel+1, "(formals) ");
if (body) body->Print(indentLevel+1, "(body) "); 67 67 if (body) body->Print(indentLevel+1, "(body) ");
} 68 68 }
69 69
llvm::Value* VarDecl::Emit() { 70 70 llvm::Value* VarDecl::Emit() {
llvm::BasicBlock* b = irgen.GetBasicBlock(); 71 71 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::Value* val; 72 72 llvm::Value* val;
73 //locals
if(b) { 73 74 if(b) {
val = new llvm::AllocaInst(convertType(type), id->GetName(), b); 74 75 if(dynamic_cast<ArrayType *>(type) !=NULL){
76 llvm::Value* val2 = llvm::ConstantInt::get(irgen.GetIntType(), dynamic_cast<ArrayType*>(type)->GetElemCount());
77 llvm::Type* thisType = convertType(dynamic_cast<ArrayType*>(type)->GetElemType());
78 llvm::ArrayType* arrType = llvm::ArrayType::get(thisType, dynamic_cast<ArrayType*>(type)->GetElemCount());
79 val = new llvm::AllocaInst(arrType, val2, id->GetName(), irgen.GetBasicBlock());
80 }
81 else{
82 val = new llvm::AllocaInst(convertType(type), id->GetName(), b);
83 }
if(assignTo) new llvm::StoreInst(assignTo->Emit(), val, false, irgen.GetBasicBlock()); 75 84 if(assignTo) new llvm::StoreInst(assignTo->Emit(), val, false, irgen.GetBasicBlock());
} 76 85 }
else { 77 86 else {
llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type)); 78 87 llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type));
val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, llvm::Twine(id->GetName())); 79 88 val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, llvm::Twine(id->GetName()));
} 80 89 }
addToScope(id->GetName(), this, val); 81 90 addToScope(id->GetName(), this, val);
return val; 82 91 return val;
} 83 92 }
84 93
85 94
llvm::Value * FnDecl::Emit(){ 86 95 llvm::Value * FnDecl::Emit(){
llvm::Module *mod = irgen.GetOrCreateModule("program"); 87 96 llvm::Module *mod = irgen.GetOrCreateModule("program");
llvm::Type *rt = convertType(this->returnType); 88 97 llvm::Type *rt = convertType(this->returnType);
89 98
std::vector<llvm::Type *> ref; 90 99 std::vector<llvm::Type *> ref;
for (int i = 0; i < formals->NumElements(); i++){ 91 100 for (int i = 0; i < formals->NumElements(); i++){
ref.push_back(convertType(formals->Nth(i)->GetType())); 92 101 ref.push_back(convertType(formals->Nth(i)->GetType()));
} 93 102 }
llvm::ArrayRef<llvm::Type *> ar(ref); 94 103 llvm::ArrayRef<llvm::Type *> ar(ref);
llvm::FunctionType * ft = llvm::FunctionType::get(rt, ar, false); 95 104 llvm::FunctionType * ft = llvm::FunctionType::get(rt, ar, false);
96 105
llvm::Value * funcval = mod->getOrInsertFunction(this->GetIdentifier()->GetName(), ft); 97 106 llvm::Value * funcval = mod->getOrInsertFunction(this->GetIdentifier()->GetName(), ft);
llvm::Function * fp = llvm::cast<llvm::Function>(funcval); 98 107 llvm::Function * fp = llvm::cast<llvm::Function>(funcval);
99 108
addToScope(id->GetName(), this, funcval); 100 109 addToScope(id->GetName(), this, funcval);
irgen.SetFunction(fp); 101 110 irgen.SetFunction(fp);
102 111
//SetName 103 112 //SetName
pushScope(); 104 113 pushScope();
llvm::Function::arg_iterator args = fp->arg_begin(); 105 114 llvm::Function::arg_iterator args = fp->arg_begin();
106 115
llvm::LLVMContext *context = irgen.GetContext(); 107 116 llvm::LLVMContext *context = irgen.GetContext();
llvm::BasicBlock * varbb = llvm::BasicBlock::Create(*context, "entry", fp); 108 117 llvm::BasicBlock * varbb = llvm::BasicBlock::Create(*context, "entry", fp);
irgen.SetBasicBlock(varbb); 109 118 irgen.SetBasicBlock(varbb);
for (int i = 0; i < formals->NumElements(); args++, i++){ 110 119 for (int i = 0; i < formals->NumElements(); args++, i++){
VarDecl * currvd = formals->Nth(i); 111 120 VarDecl * currvd = formals->Nth(i);
string currname = string(currvd->GetIdentifier()->GetName()); 112 121 string currname = string(currvd->GetIdentifier()->GetName());
args->setName(currname); 113 122 args->setName(currname);
llvm::Value * currargv = currvd->Emit(); 114 123 llvm::Value * currargv = currvd->Emit();
llvm::StoreInst * si = new llvm::StoreInst(&*args, currargv, varbb); 115 124 llvm::StoreInst * si = new llvm::StoreInst(&*args, currargv, varbb);
/* 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
12
IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { 12 13 IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) {
value = val; 13 14 value = val;
} 14 15 }
void IntConstant::PrintChildren(int indentLevel) { 15 16 void IntConstant::PrintChildren(int indentLevel) {
printf("%d", value); 16 17 printf("%d", value);
} 17 18 }
18 19
FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { 19 20 FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) {
value = val; 20 21 value = val;
} 21 22 }
void FloatConstant::PrintChildren(int indentLevel) { 22 23 void FloatConstant::PrintChildren(int indentLevel) {
printf("%g", value); 23 24 printf("%g", value);
} 24 25 }
25 26
BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { 26 27 BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) {
value = val; 27 28 value = val;
} 28 29 }
void BoolConstant::PrintChildren(int indentLevel) { 29 30 void BoolConstant::PrintChildren(int indentLevel) {
printf("%s", value ? "true" : "false"); 30 31 printf("%s", value ? "true" : "false");
} 31 32 }
32 33
VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { 33 34 VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) {
Assert(ident != NULL); 34 35 Assert(ident != NULL);
this->id = ident; 35 36 this->id = ident;
} 36 37 }
37 38
void VarExpr::PrintChildren(int indentLevel) { 38 39 void VarExpr::PrintChildren(int indentLevel) {
id->Print(indentLevel+1); 39 40 id->Print(indentLevel+1);
} 40 41 }
41 42
Operator::Operator(yyltype loc, const char *tok) : Node(loc) { 42 43 Operator::Operator(yyltype loc, const char *tok) : Node(loc) {
Assert(tok != NULL); 43 44 Assert(tok != NULL);
strncpy(tokenString, tok, sizeof(tokenString)); 44 45 strncpy(tokenString, tok, sizeof(tokenString));
} 45 46 }
46 47
void Operator::PrintChildren(int indentLevel) { 47 48 void Operator::PrintChildren(int indentLevel) {
printf("%s",tokenString); 48 49 printf("%s",tokenString);
} 49 50 }
50 51
bool Operator::IsOp(const char *op) const { 51 52 bool Operator::IsOp(const char *op) const {
return strcmp(tokenString, op) == 0; 52 53 return strcmp(tokenString, op) == 0;
} 53 54 }
54 55
CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) 55 56 CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r)
: Expr(Join(l->GetLocation(), r->GetLocation())) { 56 57 : Expr(Join(l->GetLocation(), r->GetLocation())) {
Assert(l != NULL && o != NULL && r != NULL); 57 58 Assert(l != NULL && o != NULL && r != NULL);
(op=o)->SetParent(this); 58 59 (op=o)->SetParent(this);
(left=l)->SetParent(this); 59 60 (left=l)->SetParent(this);
(right=r)->SetParent(this); 60 61 (right=r)->SetParent(this);
} 61 62 }
62 63
CompoundExpr::CompoundExpr(Operator *o, Expr *r) 63 64 CompoundExpr::CompoundExpr(Operator *o, Expr *r)
: Expr(Join(o->GetLocation(), r->GetLocation())) { 64 65 : Expr(Join(o->GetLocation(), r->GetLocation())) {
Assert(o != NULL && r != NULL); 65 66 Assert(o != NULL && r != NULL);
left = NULL; 66 67 left = NULL;
(op=o)->SetParent(this); 67 68 (op=o)->SetParent(this);
(right=r)->SetParent(this); 68 69 (right=r)->SetParent(this);
} 69 70 }
70 71
CompoundExpr::CompoundExpr(Expr *l, Operator *o) 71 72 CompoundExpr::CompoundExpr(Expr *l, Operator *o)
: Expr(Join(l->GetLocation(), o->GetLocation())) { 72 73 : Expr(Join(l->GetLocation(), o->GetLocation())) {
Assert(l != NULL && o != NULL); 73 74 Assert(l != NULL && o != NULL);
(left=l)->SetParent(this); 74 75 (left=l)->SetParent(this);
(op=o)->SetParent(this); 75 76 (op=o)->SetParent(this);
} 76 77 }
77 78
void CompoundExpr::PrintChildren(int indentLevel) { 78 79 void CompoundExpr::PrintChildren(int indentLevel) {
if (left) left->Print(indentLevel+1); 79 80 if (left) left->Print(indentLevel+1);
op->Print(indentLevel+1); 80 81 op->Print(indentLevel+1);
if (right) right->Print(indentLevel+1); 81 82 if (right) right->Print(indentLevel+1);
} 82 83 }
83 84
ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) 84 85 ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f)
: Expr(Join(c->GetLocation(), f->GetLocation())) { 85 86 : Expr(Join(c->GetLocation(), f->GetLocation())) {
Assert(c != NULL && t != NULL && f != NULL); 86 87 Assert(c != NULL && t != NULL && f != NULL);
(cond=c)->SetParent(this); 87 88 (cond=c)->SetParent(this);
(trueExpr=t)->SetParent(this); 88 89 (trueExpr=t)->SetParent(this);
(falseExpr=f)->SetParent(this); 89 90 (falseExpr=f)->SetParent(this);
} 90 91 }
91 92
void ConditionalExpr::PrintChildren(int indentLevel) { 92 93 void ConditionalExpr::PrintChildren(int indentLevel) {
cond->Print(indentLevel+1, "(cond) "); 93 94 cond->Print(indentLevel+1, "(cond) ");
trueExpr->Print(indentLevel+1, "(true) "); 94 95 trueExpr->Print(indentLevel+1, "(true) ");
falseExpr->Print(indentLevel+1, "(false) "); 95 96 falseExpr->Print(indentLevel+1, "(false) ");
} 96 97 }
ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { 97 98 ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) {
(base=b)->SetParent(this); 98 99 (base=b)->SetParent(this);
(subscript=s)->SetParent(this); 99 100 (subscript=s)->SetParent(this);
} 100 101 }
101 102
void ArrayAccess::PrintChildren(int indentLevel) { 102 103 void ArrayAccess::PrintChildren(int indentLevel) {
base->Print(indentLevel+1); 103 104 base->Print(indentLevel+1);
subscript->Print(indentLevel+1, "(subscript) "); 104 105 subscript->Print(indentLevel+1, "(subscript) ");
} 105 106 }
106 107
FieldAccess::FieldAccess(Expr *b, Identifier *f) 107 108 FieldAccess::FieldAccess(Expr *b, Identifier *f)
: LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { 108 109 : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) {
Assert(f != NULL); // b can be be NULL (just means no explicit base) 109 110 Assert(f != NULL); // b can be be NULL (just means no explicit base)
base = b; 110 111 base = b;
if (base) base->SetParent(this); 111 112 if (base) base->SetParent(this);
(field=f)->SetParent(this); 112 113 (field=f)->SetParent(this);
} 113 114 }
114 115
115 116
void FieldAccess::PrintChildren(int indentLevel) { 116 117 void FieldAccess::PrintChildren(int indentLevel) {
if (base) base->Print(indentLevel+1); 117 118 if (base) base->Print(indentLevel+1);
field->Print(indentLevel+1); 118 119 field->Print(indentLevel+1);
} 119 120 }
120 121
Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { 121 122 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 123 Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base)
base = b; 123 124 base = b;
if (base) base->SetParent(this); 124 125 if (base) base->SetParent(this);
(field=f)->SetParent(this); 125 126 (field=f)->SetParent(this);
(actuals=a)->SetParentAll(this); 126 127 (actuals=a)->SetParentAll(this);
} 127 128 }
128 129
void Call::PrintChildren(int indentLevel) { 129 130 void Call::PrintChildren(int indentLevel) {
if (base) base->Print(indentLevel+1); 130 131 if (base) base->Print(indentLevel+1);
if (field) field->Print(indentLevel+1); 131 132 if (field) field->Print(indentLevel+1);
if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); 132 133 if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) ");
} 133 134 }
134 135
llvm::Value* VarExpr::Emit() { 135 136 llvm::Value* VarExpr::Emit() {
return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock()); 136 137 return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock());
} 137 138 }
/* 138 139 /*
llvm::Value* AssignExpr::Emit() { 139 140 llvm::Value* AssignExpr::Emit() {
VarExpr* ve = dynamic_cast<VarExpr*>(left); 140 141 VarExpr* ve = dynamic_cast<VarExpr*>(left);
return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock()); 141 142 return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock());
} 142 143 }
*/ 143 144 */
144 145
string Operator::getToken() const { 145 146 string Operator::getToken() const {
return tokenString; 146 147 return tokenString;
} 147 148 }
148 149
llvm::Value* IntConstant::Emit() { 149 150 llvm::Value* IntConstant::Emit() {
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); 150 151 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true);
} 151 152 }
152 153
llvm::Value* FloatConstant::Emit() { 153 154 llvm::Value* FloatConstant::Emit() {
return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); 154 155 return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value);
} 155 156 }
156 157
llvm::Value* BoolConstant::Emit() { 157 158 llvm::Value* BoolConstant::Emit() {
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value); 158 159 return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value);
} 159 160 }
160 161
llvm::Value* Call::Emit() { 161 162 llvm::Value* Call::Emit() {
vector<llvm::Value*> args; 162 163 vector<llvm::Value*> args;
for(int i = 0; i < actuals->NumElements(); i++) { 163 164 for(int i = 0; i < actuals->NumElements(); i++) {
args.push_back(actuals->Nth(i)->Emit()); 164 165 args.push_back(actuals->Nth(i)->Emit());
} 165 166 }
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, "", irgen.GetBasicBlock()); 166 167 return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, "", irgen.GetBasicBlock());
} 167 168 }
168 169
llvm::Value* ConditionalExpr::Emit() { 169 170 llvm::Value* ConditionalExpr::Emit() {
llvm::LLVMContext * context = irgen.GetContext(); 170 171 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * func = irgen.GetFunction(); 171 172 llvm::Function * func = irgen.GetFunction();
llvm::BasicBlock* b = irgen.GetBasicBlock(); 172 173 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func); 173 174 llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func);
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); 174 175 llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func);
llvm::BasicBlock * elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func); 175 176 llvm::BasicBlock * elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func);
llvm::Value * condition = cond->Emit(); 176 177 llvm::Value * condition = cond->Emit();
177 178
irgen.SetBasicBlock(thenBlock); 178 179 irgen.SetBasicBlock(thenBlock);
llvm::Value* tVal = trueExpr->Emit(); 179 180 llvm::Value* tVal = trueExpr->Emit();
llvm::Value* val = new llvm::AllocaInst(tVal->getType(), "", b); 180 181 llvm::Value* val = new llvm::AllocaInst(tVal->getType(), "", b);
new llvm::StoreInst(tVal, val, false, irgen.GetBasicBlock()); 181 182 new llvm::StoreInst(tVal, val, false, irgen.GetBasicBlock());
llvm::BranchInst::Create(thenBlock, elseBlock, condition, b); 182 183 llvm::BranchInst::Create(thenBlock, elseBlock, condition, b);
183 184
llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); 184 185 llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock());
185 186
irgen.SetBasicBlock(elseBlock); 186 187 irgen.SetBasicBlock(elseBlock);
llvm::Value* fVal = falseExpr->Emit(); 187 188 llvm::Value* fVal = falseExpr->Emit();
new llvm::StoreInst(fVal, val, false, irgen.GetBasicBlock()); 188 189 new llvm::StoreInst(fVal, val, false, irgen.GetBasicBlock());
189 190
llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); 190 191 llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock());
irgen.SetBasicBlock(footBlock); 191 192 irgen.SetBasicBlock(footBlock);
return new llvm::LoadInst(val, "", footBlock); 192 193 return new llvm::LoadInst(val, "", footBlock);
} 193 194 }
194 195
static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) { 195 196 static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) {
if(val->getType() == target->getType()) return val; 196 197 if(val->getType() == target->getType()) return val;
llvm::BasicBlock* b = irgen.GetBasicBlock(); 197 198 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::Value* ret = new llvm::AllocaInst(target->getType(), "", b); 198 199 llvm::Value* ret = new llvm::AllocaInst(target->getType(), "", b);
ret = new llvm::LoadInst(ret, "", b); 199 200 ret = new llvm::LoadInst(ret, "", b);
200 201
for(int i = 0; i < target->getType()->getVectorNumElements(); i++) { 201 202 for(int i = 0; i < target->getType()->getVectorNumElements(); i++) {
ret = llvm::InsertElementInst::Create(ret, val, llvm::ConstantInt::get(irgen.GetIntType(), i), "", b); 202 203 ret = llvm::InsertElementInst::Create(ret, val, llvm::ConstantInt::get(irgen.GetIntType(), i), "", b);
} 203 204 }
return ret; 204 205 return ret;
} 205 206 }
206 207
llvm::Value* CompoundExpr::Emit() { 207 208 llvm::Value* CompoundExpr::Emit() {
llvm::BasicBlock* b = irgen.GetBasicBlock(); 208 209 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::Function * func = irgen.GetFunction(); 209 210 llvm::Function * func = irgen.GetFunction();
llvm::LLVMContext* context = irgen.GetContext(); 210 211 llvm::LLVMContext* context = irgen.GetContext();
//weird bc of short circuting 211 212 //weird bc of short circuting
if(op->getToken() == "&&" || op->getToken() == "||") { 212 213 if(op->getToken() == "&&" || op->getToken() == "||") {
llvm::Value* val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*context), "", b); 213 214 llvm::Value* val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*context), "", b);
llvm::BasicBlock * otherBlock = llvm::BasicBlock::Create(*context, "otherBlock", func); 214 215 llvm::BasicBlock * otherBlock = llvm::BasicBlock::Create(*context, "otherBlock", func);
llvm::BasicBlock * falseBlock = llvm::BasicBlock::Create(*context, "falseBlock", func); 215 216 llvm::BasicBlock * falseBlock = llvm::BasicBlock::Create(*context, "falseBlock", func);
llvm::BasicBlock * trueBlock = llvm::BasicBlock::Create(*context, "trueBlock", func); 216 217 llvm::BasicBlock * trueBlock = llvm::BasicBlock::Create(*context, "trueBlock", func);
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); 217 218 llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func);
llvm::Value* l = left->Emit(); 218 219 llvm::Value* l = left->Emit();
b = irgen.GetBasicBlock(); 219 220 b = irgen.GetBasicBlock();
if(op->getToken() == "&&") llvm::BranchInst::Create(otherBlock, falseBlock, l, b); 220 221 if(op->getToken() == "&&") llvm::BranchInst::Create(otherBlock, falseBlock, l, b);
if(op->getToken() == "||") llvm::BranchInst::Create(trueBlock, otherBlock, l, b); 221 222 if(op->getToken() == "||") llvm::BranchInst::Create(trueBlock, otherBlock, l, b);
irgen.SetBasicBlock(otherBlock); 222 223 irgen.SetBasicBlock(otherBlock);
llvm::Value* r = right->Emit(); 223 224 llvm::Value* r = right->Emit();
b = irgen.GetBasicBlock(); 224 225 b = irgen.GetBasicBlock();
llvm::BranchInst::Create(trueBlock, falseBlock, r, b); 225 226 llvm::BranchInst::Create(trueBlock, falseBlock, r, b);
new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), true), val, false, trueBlock); 226 227 new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), true), val, false, trueBlock);
llvm::BranchInst::Create(footBlock, trueBlock); 227 228 llvm::BranchInst::Create(footBlock, trueBlock);
new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), false), val, false, falseBlock); 228 229 new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), false), val, false, falseBlock);
llvm::BranchInst::Create(footBlock, falseBlock); 229 230 llvm::BranchInst::Create(footBlock, falseBlock);
irgen.SetBasicBlock(footBlock); 230 231 irgen.SetBasicBlock(footBlock);
return new llvm::LoadInst(val, "", footBlock); 231 232 return new llvm::LoadInst(val, "", footBlock);
} 232 233 }
llvm::Value* l = left ? left->Emit() : NULL; 233 234 llvm::Value* l = left ? left->Emit() : NULL;
llvm::Value* r = right ? right->Emit() : NULL; 234 235 llvm::Value* r = right ? right->Emit() : NULL;
b = irgen.GetBasicBlock(); 235 236 b = irgen.GetBasicBlock();
//austins additional value 236 237 //austins additional value
llvm::Value *val; 237 238 llvm::Value *val;
if(!l || !r) { 238 239 if(!l || !r) {
if(op->getToken() == "-" && (l ? l->getType()->isFPOrFPVectorTy() : r->getType()->isFPOrFPVectorTy())) { 239 240 if(op->getToken() == "-" && (l ? l->getType()->isFPOrFPVectorTy() : r->getType()->isFPOrFPVectorTy())) {
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, typeConvert(llvm::ConstantFP::get(irgen.GetFloatType(), 0.0), (l?l:r)), l ? l : r, "", b); 240 241 return llvm::BinaryOperator::Create(llvm::Instruction::FSub, typeConvert(llvm::ConstantFP::get(irgen.GetFloatType(), 0.0), (l?l:r)), l ? l : r, "", b);
} 241 242 }
else if(op->getToken() == "-") { 242 243 else if(op->getToken() == "-") {
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, typeConvert(llvm::ConstantInt::get(irgen.GetIntType(), 0), (l?l:r)), l ? l : r, "", b); 243 244 return llvm::BinaryOperator::Create(llvm::Instruction::Sub, typeConvert(llvm::ConstantInt::get(irgen.GetIntType(), 0), (l?l:r)), l ? l : r, "", b);
} 244 245 }
else if(op->getToken() == "+") return l ? l : r; 245 246 else if(op->getToken() == "+") return l ? l : r;
VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); 246 247 VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right);
llvm::Value* ret; 247 248 llvm::Value* ret;
llvm::Value* var = l ? l : r; 248 249 llvm::Value* var = l ? l : r;
249 250
if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); 250 251 if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0);
else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); 251 252 else val = llvm::ConstantInt::get(irgen.GetIntType(), 1);
val = typeConvert(val, var); 252 253 val = typeConvert(val, var);
253 254
if(op->getToken() == "++") { 254 255 if(op->getToken() == "++") {
ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); 255 256 ret = llvm::BinaryOperator::CreateAdd(var, val, "", b);
} 256 257 }
else if(op->getToken() == "--") { 257 258 else if(op->getToken() == "--") {
ret = llvm::BinaryOperator::CreateSub(var, val, "", b); 258 259 ret = llvm::BinaryOperator::CreateSub(var, val, "", b);
} 259 260 }
new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); 260 261 new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b);
261 262
if(!l) return ret; 262 263 if(!l) return ret;
else return var; 263 264 else return var;
} 264 265 }
if(l->getType()->isVectorTy() && !r->getType()->isVectorTy()) r = typeConvert(r, l); 265 266 if(l->getType()->isVectorTy() && !r->getType()->isVectorTy()) r = typeConvert(r, l);
if(!l->getType()->isVectorTy() && r->getType()->isVectorTy()) l = typeConvert(l, r); 266 267 if(!l->getType()->isVectorTy() && r->getType()->isVectorTy()) l = typeConvert(l, r);
if(l->getType()->isFPOrFPVectorTy()) { 267 268 if(l->getType()->isFPOrFPVectorTy()) {
if(op->getToken() == "+") 268 269 if(op->getToken() == "+")
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); 269 270 return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b);
if(op->getToken() == "-") 270 271 if(op->getToken() == "-")
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); 271 272 return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b);
if(op->getToken() == "*") 272 273 if(op->getToken() == "*")
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); 273 274 return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b);
if(op->getToken() == "/") 274 275 if(op->getToken() == "/")
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); 275 276 return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b);
if(op->getToken() == "==") 276 277 if(op->getToken() == "==")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); 277 278 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b);
if(op->getToken() == "!=") 278 279 if(op->getToken() == "!=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); 279 280 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b);
if(op->getToken() == "<=") 280 281 if(op->getToken() == "<=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); 281 282 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b);
if(op->getToken() == ">=") 282 283 if(op->getToken() == ">=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); 283 284 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b);
if(op->getToken() == "<") 284 285 if(op->getToken() == "<")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); 285 286 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b);
if(op->getToken() == ">") 286 287 if(op->getToken() == ">")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); 287 288 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b);
} 288 289 }
if(l->getType()->isIntOrIntVectorTy()) { 289 290 if(l->getType()->isIntOrIntVectorTy()) {
if(op->getToken() == "+") 290 291 if(op->getToken() == "+")
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); 291 292 return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b);
if(op->getToken() == "-") 292 293 if(op->getToken() == "-")
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); 293 294 return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b);
if(op->getToken() == "*") 294 295 if(op->getToken() == "*")
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); 295 296 return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b);
if(op->getToken() == "/") 296 297 if(op->getToken() == "/")
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); 297 298 return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b);
if(op->getToken() == "==") 298 299 if(op->getToken() == "==")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); 299 300 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b);
if(op->getToken() == "!=") 300 301 if(op->getToken() == "!=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); 301 302 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b);
if(op->getToken() == "<=") 302 303 if(op->getToken() == "<=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); 303 304 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b);
if(op->getToken() == ">=") 304 305 if(op->getToken() == ">=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); 305 306 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b);
if(op->getToken() == "<") 306 307 if(op->getToken() == "<")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); 307 308 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b);
if(op->getToken() == ">") 308 309 if(op->getToken() == ">")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); 309 310 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b);
} 310 311 }
return NULL; 311 312 return NULL;
} 312 313 }
313 314
//---------------------------------------------------------------------------------------- 314 315 //----------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------- 315 316 //----------------------------------------------------------------------------------------
316 317
llvm::Value * AssignExpr::Emit(){ 317 318 llvm::Value * AssignExpr::Emit(){
llvm::Value * leftval; 318 319 llvm::Value * leftval;
llvm::Value * rightval; 319 320 llvm::Value * rightval;
320 321
FieldAccess * f = dynamic_cast<FieldAccess *>(left); 321 322 FieldAccess * f = dynamic_cast<FieldAccess *>(left);
if (f){ 322 323 if (f){
324 //std::cerr<< "fuck this assignment"<<"/n";
return this->AssignField(); 323 325 return this->AssignField();
} 324 326 }
leftval = left->Emit(); 325 327 leftval = left->Emit();
rightval = right->Emit(); 326 328 rightval = right->Emit();
327 329
string operationStr(op->getToken()); 328 330 string operationStr(op->getToken());
329 331
VarExpr * vd = dynamic_cast<VarExpr *>(left); 330 332 VarExpr * vd = dynamic_cast<VarExpr *>(left);
331 333
llvm::Value * storeInst = NULL; 332 334 llvm::Value * storeInst = NULL;
if ( operationStr.compare("+=") == 0 ){ 333 335 if ( operationStr.compare("+=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 334 336 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); 335 337 storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 336 338 if (vd){
vd->AddressStore(storeInst); 337 339 vd->AddressStore(storeInst);
return storeInst; 338 340 return storeInst;
} 339 341 }
} 340 342 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 341 343 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); 342 344 storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 343 345 if (vd){
vd->AddressStore(storeInst); 344 346 vd->AddressStore(storeInst);
return storeInst; 345 347 return storeInst;
} 346 348 }
} 347 349 }
else{ 348 350 else{
storeInst = convert(leftval, rightval, 0); 349 351 storeInst = convert(leftval, rightval, 0);
if (vd){ 350 352 if (vd){
vd->AddressStore(storeInst); 351 353 vd->AddressStore(storeInst);
return storeInst; 352 354 return storeInst;
} 353 355 }
} 354 356 }
} 355 357 }
else if ( operationStr.compare("=") == 0 ){ 356 358 else if ( operationStr.compare("=") == 0 ){
if (vd){ 357 359 if (vd){
360 std::cerr<<"--------------------------------------------"<<"\n";
361 std::cerr<< vd->GetIdentifier()->GetName()<<"\n";
vd->AddressStore(rightval); 358 362 vd->AddressStore(rightval);
363 std::cerr<<"AFTER STOREING" << endl;
return rightval; 359 364 return rightval;
} 360 365 }
return ((VarExpr *) left)->AddressStore(rightval); 361 366 return ((VarExpr *) left)->AddressStore(rightval);
} 362 367 }
else if ( operationStr.compare("-=") == 0 ){ 363 368 else if ( operationStr.compare("-=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 364 369 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); 365 370 storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 366 371 if (vd){
vd->AddressStore(storeInst); 367 372 vd->AddressStore(storeInst);
return storeInst; 368 373 return storeInst;
} 369 374 }
} 370 375 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 371 376 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); 372 377 storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 373 378 if (vd){
vd->AddressStore(storeInst); 374 379 vd->AddressStore(storeInst);
return storeInst; 375 380 return storeInst;
} 376 381 }
} 377 382 }
else{ 378 383 else{
storeInst = convert(leftval, rightval, 1); 379 384 storeInst = convert(leftval, rightval, 1);
if (vd){ 380 385 if (vd){
vd->AddressStore(storeInst); 381 386 vd->AddressStore(storeInst);
return storeInst; 382 387 return storeInst;
} 383 388 }
} 384 389 }
} 385 390 }
else if ( operationStr.compare("/=") == 0 ){ 386 391 else if ( operationStr.compare("/=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 387 392 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); 388 393 storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 389 394 if (vd){
vd->AddressStore(storeInst); 390 395 vd->AddressStore(storeInst);
return storeInst; 391 396 return storeInst;
} 392 397 }
} 393 398 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 394 399 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); 395 400 storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 396 401 if (vd){
vd->AddressStore(storeInst); 397 402 vd->AddressStore(storeInst);
return storeInst; 398 403 return storeInst;
} 399 404 }
} 400 405 }
else{ 401 406 else{
storeInst = convert(leftval, rightval, 2); 402 407 storeInst = convert(leftval, rightval, 2);
if (vd){ 403 408 if (vd){
vd->AddressStore(storeInst); 404 409 vd->AddressStore(storeInst);
return storeInst; 405 410 return storeInst;
} 406 411 }
} 407 412 }
} 408 413 }
else if ( operationStr.compare("*=") == 0 ){ 409 414 else if ( operationStr.compare("*=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 410 415 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); 411 416 storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 412 417 if (vd){
vd->AddressStore(storeInst); 413 418 vd->AddressStore(storeInst);
return storeInst; 414 419 return storeInst;
} 415 420 }
} 416 421 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 417 422 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); 418 423 storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 419 424 if (vd){
vd->AddressStore(storeInst); 420 425 vd->AddressStore(storeInst);
return storeInst; 421 426 return storeInst;
} 422 427 }
} 423 428 }
else{ 424 429 else{
storeInst = convert(leftval, rightval, 3); 425 430 storeInst = convert(leftval, rightval, 3);
if (vd){ 426 431 if (vd){
vd->AddressStore(storeInst); 427 432 vd->AddressStore(storeInst);
return storeInst; 428 433 return storeInst;
} 429 434 }
} 430 435 }
} 431 436 }
return NULL; 432 437 return NULL;
} 433 438 }
434 439
llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ 435 440 llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){
llvm::Type * intTyp = irgen.GetIntType(); 436 441 llvm::Type * intTyp = irgen.GetIntType();
llvm::Type * fltTyp = irgen.GetFloatType(); 437 442 llvm::Type * fltTyp = irgen.GetFloatType();
llvm::Value *idVal; 438 443 llvm::Value *idVal;
llvm::Value * element; 439 444 llvm::Value * element;
llvm::Value * retVal = vec; 440 445 llvm::Value * retVal = vec;
441 446
//get vector size 442 447 //get vector size
int numElements=-1; 443 448 int numElements=-1;
if(vec->getType()==irgen.GetVec2Type()){ 444 449 if(vec->getType()==irgen.GetVec2Type()){
numElements=2; 445 450 numElements=2;
} 446 451 }
else if(vec->getType()==irgen.GetVec3Type()){ 447 452 else if(vec->getType()==irgen.GetVec3Type()){
numElements=3; 448 453 numElements=3;
} 449 454 }
else if(vec->getType()==irgen.GetVec4Type()){ 450 455 else if(vec->getType()==irgen.GetVec4Type()){
numElements=4; 451 456 numElements=4;
} 452 457 }
453 458
for (int i = 0; i < numElements; i++){ 454 459 for (int i = 0; i < numElements; i++){
idVal = llvm::ConstantInt::get(intTyp, i); 455 460 idVal = llvm::ConstantInt::get(intTyp, i);
element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); 456 461 element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock());
if (status == 0){ 457 462 if (status == 0){
element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); 458 463 element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock());
} 459 464 }
else if (status == 1){ 460 465 else if (status == 1){
element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); 461 466 element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock());
} 462 467 }
else if (status == 2){ 463 468 else if (status == 2){
element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); 464 469 element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock());
} 465 470 }
else{ 466 471 else{
element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); 467 472 element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock());
} 468 473 }
retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); 469 474 retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock());
} 470 475 }
return retVal; 471 476 return retVal;
} 472 477 }
473 478
llvm::Value* VarExpr::AddressStore(llvm::Value *store){ 474 479 llvm::Value* VarExpr::AddressStore(llvm::Value *store){
char * varname = GetIdentifier()->GetName(); 475 480 char * varname = GetIdentifier()->GetName();
476 481
pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); 477 482 pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname));
//value of symbol 478 483 //value of symbol
llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, false, irgen.GetBasicBlock()); 479 484 llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, false, irgen.GetBasicBlock());
return storeInst; 480 485 return storeInst;
} 481 486 }
482 487
llvm::Value * AssignExpr::AssignField(){ 483 488 llvm::Value * AssignExpr::AssignField(){
FieldAccess * f = (FieldAccess *) left; 484 489 FieldAccess * f = (FieldAccess *) left;
llvm::Value * rightval = right->Emit(); 485 490 llvm::Value * rightval = right->Emit();
string operationStr(op->getToken()); 486 491 string operationStr(op->getToken());
bool isFloat = rightval->getType()->isFloatingPointTy(); 487 492 bool isFloat = rightval->getType()->isFloatingPointTy();
llvm::Type * intTyp = irgen.GetIntType(); 488 493 llvm::Type * intTyp = irgen.GetIntType();
char * ptr = f->getField()->GetName();; 489 494 char * ptr = f->getField()->GetName();;
490 495
std::vector<llvm::Constant *> maskI; 491 496 std::vector<llvm::Constant *> maskI;
for(; *ptr; ptr++){ 492 497 for(; *ptr; ptr++){
if(*ptr =='x'){ 493 498 if(*ptr =='x'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); 494 499 maskI.push_back(llvm::ConstantInt::get(intTyp, 0));
} 495 500 }
else if(*ptr='y'){ 496 501 else if(*ptr='y'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); 497 502 maskI.push_back(llvm::ConstantInt::get(intTyp, 1));
} 498 503 }
else if(*ptr='z'){ 499 504 else if(*ptr='z'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); 500 505 maskI.push_back(llvm::ConstantInt::get(intTyp, 2));
} 501 506 }
else if(*ptr='w'){ 502 507 else if(*ptr='w'){
maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); 503 508 maskI.push_back(llvm::ConstantInt::get(intTyp, 3));
} 504 509 }
} 505 510 }
506 511
llvm::Value * element; 507 512 llvm::Value * element;
llvm::Value * rightop = rightval; 508 513 llvm::Value * rightop = rightval;
llvm::Value * baseF = f->getBase()->Emit(); 509 514 llvm::Value * baseF = f->getBase()->Emit();
llvm::Value * storeInst = f->getBase()->Emit(); 510 515 llvm::Value * storeInst = f->getBase()->Emit();
511 516
512 517
for (int i = 0; i < maskI.size(); i++){ 513 518 for (int i = 0; i < maskI.size(); i++){
element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock()); 514 519 element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock());
if (rightval->getType()->isVectorTy()){ 515 520 if (rightval->getType()->isVectorTy()){
rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); 516 521 rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock());
} 517 522 }
if (!operationStr.compare("=")){ 518 523 if (!operationStr.compare("=")){
storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); 519 524 storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock());
} 520 525 }
if (!operationStr.compare("+=")){ 521 526 if (!operationStr.compare("+=")){
element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); 522 527 element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock());
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 523 528 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
} 524 529 }
if (!operationStr.compare("-=")){ 525 530 if (!operationStr.compare("-=")){
element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); 526 531 element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock());
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 527 532 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
} 528 533 }
if (!operationStr.compare("*=")){ 529 534 if (!operationStr.compare("*=")){
element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); 530 535 element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock());
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 531 536 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
} 532 537 }
if (!operationStr.compare("/=")){ 533 538 if (!operationStr.compare("/=")){
element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock()); 534 539 element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock());
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 535 540 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
} 536 541 }
} 537 542 }
VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase()); 538 543 VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase());
ve->AddressStore(storeInst); 539 544 ve->AddressStore(storeInst);
if (isFloat){ 540 545 if (isFloat){
return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock()); 541 546 return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock());
} 542 547 }
return storeInst; 543 548 return storeInst;
} 544 549 }
545 550
546 551
llvm::Value * FieldAccess::Emit(){ 547 552 llvm::Value * FieldAccess::Emit(){
char * mask = this->getField()->GetName(); 548 553 char * mask = this->getField()->GetName();
char * ptr = mask; 549 554 char * ptr = mask;
550 555
llvm::Type * intTyp = irgen.GetIntType(); 551 556 llvm::Type * intTyp = irgen.GetIntType();
std::vector<llvm::Constant *> maskI; 552 557 std::vector<llvm::Constant *> maskI;
/* File: ast_expr.h 1 1 /* File: ast_expr.h
* ---------------- 2 2 * ----------------
* The Expr class and its subclasses are used to represent 3 3 * The Expr class and its subclasses are used to represent
* expressions in the parse tree. For each expression in the 4 4 * expressions in the parse tree. For each expression in the
* language (add, call, New, etc.) there is a corresponding 5 5 * language (add, call, New, etc.) there is a corresponding
* node class for that construct. 6 6 * node class for that construct.
* 7 7 *
* pp3: You will need to extend the Expr classes to implement 8 8 * pp3: You will need to extend the Expr classes to implement
* semantic analysis for rules pertaining to expressions. 9 9 * semantic analysis for rules pertaining to expressions.
*/ 10 10 */
11 11
12 12
#ifndef _H_ast_expr 13 13 #ifndef _H_ast_expr
#define _H_ast_expr 14 14 #define _H_ast_expr
15 15
#include "ast.h" 16 16 #include "ast.h"
#include "ast_stmt.h" 17 17 #include "ast_stmt.h"
#include "list.h" 18 18 #include "list.h"
#include "ast_type.h" 19 19 #include "ast_type.h"
20 20
void yyerror(const char *msg); 21 21 void yyerror(const char *msg);
22 22
class Expr : public Stmt 23 23 class Expr : public Stmt
{ 24 24 {
public: 25 25 public:
Expr(yyltype loc) : Stmt(loc) {} 26 26 Expr(yyltype loc) : Stmt(loc) {}
Expr() : Stmt() {} 27 27 Expr() : Stmt() {}
28 28
friend std::ostream& operator<< (std::ostream& stream, Expr * expr) { 29 29 friend std::ostream& operator<< (std::ostream& stream, Expr * expr) {
return stream << expr->GetPrintNameForNode(); 30 30 return stream << expr->GetPrintNameForNode();
} 31 31 }
}; 32 32 };
33 33
class ExprError : public Expr 34 34 class ExprError : public Expr
{ 35 35 {
public: 36 36 public:
ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); } 37 37 ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); }
const char *GetPrintNameForNode() { return "ExprError"; } 38 38 const char *GetPrintNameForNode() { return "ExprError"; }
}; 39 39 };
40 40
/* This node type is used for those places where an expression is optional. 41 41 /* This node type is used for those places where an expression is optional.
* We could use a NULL pointer, but then it adds a lot of checking for 42 42 * We could use a NULL pointer, but then it adds a lot of checking for
* NULL. By using a valid, but no-op, node, we save that trouble */ 43 43 * NULL. By using a valid, but no-op, node, we save that trouble */
class EmptyExpr : public Expr 44 44 class EmptyExpr : public Expr
{ 45 45 {
public: 46 46 public:
const char *GetPrintNameForNode() { return "Empty"; } 47 47 const char *GetPrintNameForNode() { return "Empty"; }
}; 48 48 };
49 49
class IntConstant : public Expr 50 50 class IntConstant : public Expr
{ 51 51 {
protected: 52 52 protected:
int value; 53 53 int value;
54 54
public: 55 55 public:
IntConstant(yyltype loc, int val); 56 56 IntConstant(yyltype loc, int val);
const char *GetPrintNameForNode() { return "IntConstant"; } 57 57 const char *GetPrintNameForNode() { return "IntConstant"; }
void PrintChildren(int indentLevel); 58 58 void PrintChildren(int indentLevel);
llvm::Value* Emit(); 59 59 llvm::Value* Emit();
}; 60 60 };
61 61
class FloatConstant: public Expr 62 62 class FloatConstant: public Expr
{ 63 63 {
protected: 64 64 protected:
double value; 65 65 double value;
66 66
public: 67 67 public:
FloatConstant(yyltype loc, double val); 68 68 FloatConstant(yyltype loc, double val);
const char *GetPrintNameForNode() { return "FloatConstant"; } 69 69 const char *GetPrintNameForNode() { return "FloatConstant"; }
void PrintChildren(int indentLevel); 70 70 void PrintChildren(int indentLevel);
llvm::Value* Emit(); 71 71 llvm::Value* Emit();
}; 72 72 };
73 73
class BoolConstant : public Expr 74 74 class BoolConstant : public Expr
{ 75 75 {
protected: 76 76 protected:
bool value; 77 77 bool value;
78 78
public: 79 79 public:
BoolConstant(yyltype loc, bool val); 80 80 BoolConstant(yyltype loc, bool val);
const char *GetPrintNameForNode() { return "BoolConstant"; } 81 81 const char *GetPrintNameForNode() { return "BoolConstant"; }
void PrintChildren(int indentLevel); 82 82 void PrintChildren(int indentLevel);
llvm::Value* Emit(); 83 83 llvm::Value* Emit();
}; 84 84 };
85 85
class VarExpr : public Expr 86 86 class VarExpr : public Expr
{ 87 87 {
protected: 88 88 protected:
Identifier *id; 89 89 Identifier *id;
90 90
public: 91 91 public:
VarExpr(yyltype loc, Identifier *id); 92 92 VarExpr(yyltype loc, Identifier *id);
const char *GetPrintNameForNode() { return "VarExpr"; } 93 93 const char *GetPrintNameForNode() { return "VarExpr"; }
void PrintChildren(int indentLevel); 94 94 void PrintChildren(int indentLevel);
Identifier *GetIdentifier() {return id;} 95 95 Identifier *GetIdentifier() {return id;}
llvm::Value* Emit(); 96 96 llvm::Value* Emit();
llvm::Value * AddressStore(llvm::Value* store); 97 97 llvm::Value * AddressStore(llvm::Value* store);
}; 98 98 };
99 99
class Operator : public Node 100 100 class Operator : public Node
{ 101 101 {
protected: 102 102 protected:
char tokenString[4]; 103 103 char tokenString[4];
104 104
public: 105 105 public:
string getToken() const; 106 106 string getToken() const;
Operator(yyltype loc, const char *tok); 107 107 Operator(yyltype loc, const char *tok);
const char *GetPrintNameForNode() { return "Operator"; } 108 108 const char *GetPrintNameForNode() { return "Operator"; }
void PrintChildren(int indentLevel); 109 109 void PrintChildren(int indentLevel);
friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } 110 110 friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; }
bool IsOp(const char *op) const; 111 111 bool IsOp(const char *op) const;
}; 112 112 };
113 113
class CompoundExpr : public Expr 114 114 class CompoundExpr : public Expr
{ 115 115 {
protected: 116 116 protected:
Operator *op; 117 117 Operator *op;
Expr *left, *right; // left will be NULL if unary 118 118 Expr *left, *right; // left will be NULL if unary
119 119
public: 120 120 public:
CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary 121 121 CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary
CompoundExpr(Operator *op, Expr *rhs); // for unary 122 122 CompoundExpr(Operator *op, Expr *rhs); // for unary
CompoundExpr(Expr *lhs, Operator *op); // for unary 123 123 CompoundExpr(Expr *lhs, Operator *op); // for unary
void PrintChildren(int indentLevel); 124 124 void PrintChildren(int indentLevel);
virtual llvm::Value* Emit(); 125 125 virtual llvm::Value* Emit();
}; 126 126 };
127 127
class ArithmeticExpr : public CompoundExpr 128 128 class ArithmeticExpr : public CompoundExpr
{ 129 129 {
public: 130 130 public:
ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 131 131 ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} 132 132 ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {}
const char *GetPrintNameForNode() { return "ArithmeticExpr"; } 133 133 const char *GetPrintNameForNode() { return "ArithmeticExpr"; }
}; 134 134 };
135 135
class RelationalExpr : public CompoundExpr 136 136 class RelationalExpr : public CompoundExpr
{ 137 137 {
public: 138 138 public:
RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 139 139 RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "RelationalExpr"; } 140 140 const char *GetPrintNameForNode() { return "RelationalExpr"; }
}; 141 141 };
142 142
class EqualityExpr : public CompoundExpr 143 143 class EqualityExpr : public CompoundExpr
{ 144 144 {
public: 145 145 public:
EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 146 146 EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "EqualityExpr"; } 147 147 const char *GetPrintNameForNode() { return "EqualityExpr"; }
}; 148 148 };
149 149
class LogicalExpr : public CompoundExpr 150 150 class LogicalExpr : public CompoundExpr
{ 151 151 {
public: 152 152 public:
LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 153 153 LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} 154 154 LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {}
const char *GetPrintNameForNode() { return "LogicalExpr"; } 155 155 const char *GetPrintNameForNode() { return "LogicalExpr"; }
}; 156 156 };
157 157
class AssignExpr : public CompoundExpr 158 158 class AssignExpr : public CompoundExpr
{ 159 159 {
public: 160 160 public:
AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 161 161 AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "AssignExpr"; } 162 162 const char *GetPrintNameForNode() { return "AssignExpr"; }
llvm::Value* Emit(); 163 163 llvm::Value* Emit();
llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status ); 164 164 llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status );
llvm::Value *AssignField(); 165 165 llvm::Value *AssignField();
}; 166 166 };
167 167
class PostfixExpr : public CompoundExpr 168 168 class PostfixExpr : public CompoundExpr
{ 169 169 {
public: 170 170 public:
PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} 171 171 PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {}
const char *GetPrintNameForNode() { return "PostfixExpr"; } 172 172 const char *GetPrintNameForNode() { return "PostfixExpr"; }
173 173
}; 174 174 };
175 175
class ConditionalExpr : public Expr 176 176 class ConditionalExpr : public Expr
{ 177 177 {
protected: 178 178 protected:
Expr *cond, *trueExpr, *falseExpr; 179 179 Expr *cond, *trueExpr, *falseExpr;
public: 180 180 public:
ConditionalExpr(Expr *c, Expr *t, Expr *f); 181 181 ConditionalExpr(Expr *c, Expr *t, Expr *f);
void PrintChildren(int indentLevel); 182 182 void PrintChildren(int indentLevel);
const char *GetPrintNameForNode() { return "ConditionalExpr"; } 183 183 const char *GetPrintNameForNode() { return "ConditionalExpr"; }
llvm::Value* Emit(); 184 184 llvm::Value* Emit();
}; 185 185 };
186 186
class LValue : public Expr 187 187 class LValue : public Expr
{ 188 188 {
public: 189 189 public:
LValue(yyltype loc) : Expr(loc) {} 190 190 LValue(yyltype loc) : Expr(loc) {}
}; 191 191 };
192 192
class ArrayAccess : public LValue 193 193 class ArrayAccess : public LValue
{ 194 194 {
protected: 195 195 protected:
Expr *base, *subscript; 196 196 Expr *base, *subscript;
197 197
public: 198 198 public:
ArrayAccess(yyltype loc, Expr *base, Expr *subscript); 199 199 ArrayAccess(yyltype loc, Expr *base, Expr *subscript);
const char *GetPrintNameForNode() { return "ArrayAccess"; } 200 200 const char *GetPrintNameForNode() { return "ArrayAccess"; }
void PrintChildren(int indentLevel); 201 201 void PrintChildren(int indentLevel);
202 Expr *GetBase(){ return base; }
203 Expr *GetSubScript(){ return subscript;}
204 llvm::Value *Emit();
205
206 llvm::Value *EmitHelper(llvm::Value* rightH);
}; 202 207 };
203 208
/* Note that field access is used both for qualified names 204 209 /* Note that field access is used both for qualified names
* base.field and just field without qualification. We don't 205 210 * base.field and just field without qualification. We don't
* know for sure whether there is an implicit "this." in 206 211 * know for sure whether there is an implicit "this." in
* front until later on, so we use one node type for either 207 212 * front until later on, so we use one node type for either
* and sort it out later. */ 208 213 * and sort it out later. */
class FieldAccess : public LValue 209 214 class FieldAccess : public LValue
{ 210 215 {
protected: 211 216 protected:
Expr *base; // will be NULL if no explicit base 212 217 Expr *base; // will be NULL if no explicit base
Identifier *field; 213 218 Identifier *field;
/* File: ast_stmt.cc 1 1 /* File: ast_stmt.cc
* ----------------- 2 2 * -----------------
* Implementation of statement node classes. 3 3 * Implementation of statement node classes.
*/ 4 4 */
#include "ast_stmt.h" 5 5 #include "ast_stmt.h"
#include "ast_type.h" 6 6 #include "ast_type.h"
#include "ast_decl.h" 7 7 #include "ast_decl.h"
#include "ast_expr.h" 8 8 #include "ast_expr.h"
#include "symtable.h" 9 9 #include "symtable.h"
10 10
#include "irgen.h" 11 11 #include "irgen.h"
#include "llvm/Bitcode/ReaderWriter.h" 12 12 #include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/raw_ostream.h" 13 13 #include "llvm/Support/raw_ostream.h"
14 14
15 15
Program::Program(List<Decl*> *d) { 16 16 Program::Program(List<Decl*> *d) {
Assert(d != NULL); 17 17 Assert(d != NULL);
(decls=d)->SetParentAll(this); 18 18 (decls=d)->SetParentAll(this);
} 19 19 }
20 20
void Program::PrintChildren(int indentLevel) { 21 21 void Program::PrintChildren(int indentLevel) {
decls->PrintAll(indentLevel+1); 22 22 decls->PrintAll(indentLevel+1);
printf("\n"); 23 23 printf("\n");
} 24 24 }
//pls work 25 25 //pls work
llvm::Value* Program::Emit() { 26 26 llvm::Value* Program::Emit() {
llvm::Module *module = irgen.GetOrCreateModule("program"); 27 27 llvm::Module *module = irgen.GetOrCreateModule("program");
pushScope(); 28 28 pushScope();
for (int i = 0; i < decls->NumElements(); i++){ 29 29 for (int i = 0; i < decls->NumElements(); i++){
decls->Nth(i)->Emit(); 30 30 decls->Nth(i)->Emit();
} 31 31 }
popScope(); 32 32 popScope();
33 33
//module->dump(); 34 34 //module->dump();
llvm::WriteBitcodeToFile(module, llvm::outs()); 35 35 llvm::WriteBitcodeToFile(module, llvm::outs());
return NULL; 36 36 return NULL;
} 37 37 }
38 38
StmtBlock::StmtBlock(List<VarDecl*> *d, List<Stmt*> *s) { 39 39 StmtBlock::StmtBlock(List<VarDecl*> *d, List<Stmt*> *s) {
Assert(d != NULL && s != NULL); 40 40 Assert(d != NULL && s != NULL);
(decls=d)->SetParentAll(this); 41 41 (decls=d)->SetParentAll(this);
(stmts=s)->SetParentAll(this); 42 42 (stmts=s)->SetParentAll(this);
} 43 43 }
44 44
void StmtBlock::PrintChildren(int indentLevel) { 45 45 void StmtBlock::PrintChildren(int indentLevel) {
decls->PrintAll(indentLevel+1); 46 46 decls->PrintAll(indentLevel+1);
stmts->PrintAll(indentLevel+1); 47 47 stmts->PrintAll(indentLevel+1);
} 48 48 }
49 49
DeclStmt::DeclStmt(Decl *d) { 50 50 DeclStmt::DeclStmt(Decl *d) {
Assert(d != NULL); 51 51 Assert(d != NULL);
(decl=d)->SetParent(this); 52 52 (decl=d)->SetParent(this);
} 53 53 }
54 54
void DeclStmt::PrintChildren(int indentLevel) { 55 55 void DeclStmt::PrintChildren(int indentLevel) {
decl->Print(indentLevel+1); 56 56 decl->Print(indentLevel+1);
} 57 57 }
58 58
ConditionalStmt::ConditionalStmt(Expr *t, Stmt *b) { 59 59 ConditionalStmt::ConditionalStmt(Expr *t, Stmt *b) {
Assert(t != NULL && b != NULL); 60 60 Assert(t != NULL && b != NULL);
(test=t)->SetParent(this); 61 61 (test=t)->SetParent(this);
(body=b)->SetParent(this); 62 62 (body=b)->SetParent(this);
} 63 63 }
64 64
ForStmt::ForStmt(Expr *i, Expr *t, Expr *s, Stmt *b): LoopStmt(t, b) { 65 65 ForStmt::ForStmt(Expr *i, Expr *t, Expr *s, Stmt *b): LoopStmt(t, b) {
Assert(i != NULL && t != NULL && b != NULL); 66 66 Assert(i != NULL && t != NULL && b != NULL);
(init=i)->SetParent(this); 67 67 (init=i)->SetParent(this);
step = s; 68 68 step = s;
if ( s ) 69 69 if ( s )
(step=s)->SetParent(this); 70 70 (step=s)->SetParent(this);
} 71 71 }
72 72
void ForStmt::PrintChildren(int indentLevel) { 73 73 void ForStmt::PrintChildren(int indentLevel) {
init->Print(indentLevel+1, "(init) "); 74 74 init->Print(indentLevel+1, "(init) ");
test->Print(indentLevel+1, "(test) "); 75 75 test->Print(indentLevel+1, "(test) ");
if ( step ) 76 76 if ( step )
step->Print(indentLevel+1, "(step) "); 77 77 step->Print(indentLevel+1, "(step) ");
body->Print(indentLevel+1, "(body) "); 78 78 body->Print(indentLevel+1, "(body) ");
} 79 79 }
80 80
void WhileStmt::PrintChildren(int indentLevel) { 81 81 void WhileStmt::PrintChildren(int indentLevel) {
test->Print(indentLevel+1, "(test) "); 82 82 test->Print(indentLevel+1, "(test) ");
body->Print(indentLevel+1, "(body) "); 83 83 body->Print(indentLevel+1, "(body) ");
} 84 84 }
85 85
IfStmt::IfStmt(Expr *t, Stmt *tb, Stmt *eb): ConditionalStmt(t, tb) { 86 86 IfStmt::IfStmt(Expr *t, Stmt *tb, Stmt *eb): ConditionalStmt(t, tb) {
Assert(t != NULL && tb != NULL); // else can be NULL 87 87 Assert(t != NULL && tb != NULL); // else can be NULL
elseBody = eb; 88 88 elseBody = eb;
if (elseBody) elseBody->SetParent(this); 89 89 if (elseBody) elseBody->SetParent(this);
} 90 90 }
91 91
void IfStmt::PrintChildren(int indentLevel) { 92 92 void IfStmt::PrintChildren(int indentLevel) {
if (test) test->Print(indentLevel+1, "(test) "); 93 93 if (test) test->Print(indentLevel+1, "(test) ");
if (body) body->Print(indentLevel+1, "(then) "); 94 94 if (body) body->Print(indentLevel+1, "(then) ");
if (elseBody) elseBody->Print(indentLevel+1, "(else) "); 95 95 if (elseBody) elseBody->Print(indentLevel+1, "(else) ");
} 96 96 }
97 97
98 98
ReturnStmt::ReturnStmt(yyltype loc, Expr *e) : Stmt(loc) { 99 99 ReturnStmt::ReturnStmt(yyltype loc, Expr *e) : Stmt(loc) {
expr = e; 100 100 expr = e;
if (e != NULL) expr->SetParent(this); 101 101 if (e != NULL) expr->SetParent(this);
} 102 102 }
103 103
void ReturnStmt::PrintChildren(int indentLevel) { 104 104 void ReturnStmt::PrintChildren(int indentLevel) {
if ( expr ) 105 105 if ( expr )
expr->Print(indentLevel+1); 106 106 expr->Print(indentLevel+1);
} 107 107 }
108 108
SwitchLabel::SwitchLabel(Expr *l, Stmt *s) { 109 109 SwitchLabel::SwitchLabel(Expr *l, Stmt *s) {
Assert(l != NULL && s != NULL); 110 110 Assert(l != NULL && s != NULL);
(label=l)->SetParent(this); 111 111 (label=l)->SetParent(this);
(stmt=s)->SetParent(this); 112 112 (stmt=s)->SetParent(this);
} 113 113 }
114 114
SwitchLabel::SwitchLabel(Stmt *s) { 115 115 SwitchLabel::SwitchLabel(Stmt *s) {
Assert(s != NULL); 116 116 Assert(s != NULL);
label = NULL; 117 117 label = NULL;
(stmt=s)->SetParent(this); 118 118 (stmt=s)->SetParent(this);
} 119 119 }
120 120
void SwitchLabel::PrintChildren(int indentLevel) { 121 121 void SwitchLabel::PrintChildren(int indentLevel) {
if (label) label->Print(indentLevel+1); 122 122 if (label) label->Print(indentLevel+1);
if (stmt) stmt->Print(indentLevel+1); 123 123 if (stmt) stmt->Print(indentLevel+1);
} 124 124 }
125 125
SwitchStmt::SwitchStmt(Expr *e, List<Stmt *> *c, Default *d) { 126 126 SwitchStmt::SwitchStmt(Expr *e, List<Stmt *> *c, Default *d) {
Assert(e != NULL && c != NULL && c->NumElements() != 0 ); 127 127 Assert(e != NULL && c != NULL && c->NumElements() != 0 );
(expr=e)->SetParent(this); 128 128 (expr=e)->SetParent(this);
(cases=c)->SetParentAll(this); 129 129 (cases=c)->SetParentAll(this);
def = d; 130 130 def = d;
if (def) def->SetParent(this); 131 131 if (def) def->SetParent(this);
} 132 132 }
133 133
void SwitchStmt::PrintChildren(int indentLevel) { 134 134 void SwitchStmt::PrintChildren(int indentLevel) {
if (expr) expr->Print(indentLevel+1); 135 135 if (expr) expr->Print(indentLevel+1);
if (cases) cases->PrintAll(indentLevel+1); 136 136 if (cases) cases->PrintAll(indentLevel+1);
if (def) def->Print(indentLevel+1); 137 137 if (def) def->Print(indentLevel+1);
} 138 138 }
//----------------------------------------------------------------------- 139 139 //-----------------------------------------------------------------------
//rest of the emits 140 140 //rest of the emits
//----------------------------------------------------------------------- 141 141 //-----------------------------------------------------------------------
llvm::Value * StmtBlock::Emit(){ 142 142 llvm::Value * StmtBlock::Emit(){
pushScope(); 143 143 pushScope();
for (int i = 0; i < decls->NumElements(); i++){ 144 144 for (int i = 0; i < decls->NumElements(); i++){
decls->Nth(i)->Emit(); 145 145 decls->Nth(i)->Emit();
} 146 146 }
for (int i = 0; i < stmts->NumElements(); i++){ 147 147 for (int i = 0; i < stmts->NumElements(); i++){
stmts->Nth(i)->Emit(); 148 148 stmts->Nth(i)->Emit();
if(irgen.GetBasicBlock()->getTerminator()) return NULL; 149 149 if(irgen.GetBasicBlock()->getTerminator()) return NULL;
} 150 150 }
151 151
popScope(); 152 152 popScope();
return NULL; 153 153 return NULL;
} 154 154 }
155 155
llvm::Value * DeclStmt::Emit(){ 156 156 llvm::Value * DeclStmt::Emit(){
llvm::Value * val; 157 157 llvm::Value * val;
if (VarDecl * vd = dynamic_cast<VarDecl*>(this->decl)){ 158 158 if (VarDecl * vd = dynamic_cast<VarDecl*>(this->decl)){
val = vd->Emit(); 159 159 val = vd->Emit();
} 160 160 }
else if (FnDecl * fd = dynamic_cast<FnDecl*>(this->decl)){ 161 161 else if (FnDecl * fd = dynamic_cast<FnDecl*>(this->decl)){
val = fd->Emit(); 162 162 val = fd->Emit();
} 163 163 }
else{ 164 164 else{
val = NULL; 165 165 val = NULL;
} 166 166 }
return val; 167 167 return val;
} 168 168 }
169 169
llvm::Value * ConditionalStmt::Emit(){ 170 170 llvm::Value * ConditionalStmt::Emit(){
return NULL; 171 171 return NULL;
} 172 172 }
173 173
llvm::Value * ForStmt::Emit() 174 174 llvm::Value * ForStmt::Emit()
{ 175 175 {
pushScope(); 176 176 pushScope();
llvm::LLVMContext * context = irgen.GetContext(); 177 177 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * f = irgen.GetFunction(); 178 178 llvm::Function * f = irgen.GetFunction();
llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", f); 179 179 llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", f);
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", f); 180 180 llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", f);
llvm::BasicBlock * stepBlock = llvm::BasicBlock::Create(*context, "stepBlock", f); 181 181 llvm::BasicBlock * stepBlock = llvm::BasicBlock::Create(*context, "stepBlock", f);
llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", f); 182 182 llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", f);
llvm::Value * cond; 183 183 llvm::Value * cond;
184 184
// init and branch to head 185 185 // init and branch to head
init->Emit(); 186 186 init->Emit();
187 187
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides 188 188 llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides
llvm::BasicBlock * oldHeader = irgen.GetHeaderBlock(); 189 189 llvm::BasicBlock * oldHeader = irgen.GetHeaderBlock();
llvm::BasicBlock * oldFooter = irgen.GetFooterBlock(); 190 190 llvm::BasicBlock * oldFooter = irgen.GetFooterBlock();
irgen.SetHeaderBlock(stepBlock); 191 191 irgen.SetHeaderBlock(stepBlock);
irgen.SetFooterBlock(footBlock); 192 192 irgen.SetFooterBlock(footBlock);
193 193
// head 194 194 // head
irgen.SetBasicBlock(headBlock); 195 195 irgen.SetBasicBlock(headBlock);
cond = test->Emit(); 196 196 cond = test->Emit();
if(!irgen.GetBasicBlock()->getTerminator()) 197 197 if(!irgen.GetBasicBlock()->getTerminator())
{ 198 198 {
llvm::BranchInst::Create(bodyBlock, footBlock, cond, irgen.GetBasicBlock()); // given in the slides 199 199 llvm::BranchInst::Create(bodyBlock, footBlock, cond, irgen.GetBasicBlock()); // given in the slides
} 200 200 }
// body 201 201 // body
irgen.SetBasicBlock(bodyBlock); 202 202 irgen.SetBasicBlock(bodyBlock);
body->Emit(); 203 203 body->Emit();
if(!irgen.GetBasicBlock()->getTerminator()) 204 204 if(!irgen.GetBasicBlock()->getTerminator())
{ 205 205 {
llvm::BranchInst::Create(stepBlock, irgen.GetBasicBlock()); // given in the slides 206 206 llvm::BranchInst::Create(stepBlock, irgen.GetBasicBlock()); // given in the slides
} 207 207 }
// step 208 208 // step
irgen.SetBasicBlock(stepBlock); 209 209 irgen.SetBasicBlock(stepBlock);
step->Emit(); 210 210 step->Emit();
if(!irgen.GetBasicBlock()->getTerminator()) 211 211 if(!irgen.GetBasicBlock()->getTerminator())
{ 212 212 {
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides 213 213 llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides
} 214 214 }
irgen.SetBasicBlock(footBlock); 215 215 irgen.SetBasicBlock(footBlock);
irgen.SetHeaderBlock(oldHeader); 216 216 irgen.SetHeaderBlock(oldHeader);
irgen.SetFooterBlock(oldFooter); 217 217 irgen.SetFooterBlock(oldFooter);
popScope(); 218 218 popScope();
return NULL; 219 219 return NULL;
} 220 220 }
221 221
//while statement 222 222 //while statement
llvm::Value * WhileStmt::Emit(){ 223 223 llvm::Value * WhileStmt::Emit(){
pushScope(); 224 224 pushScope();
llvm::LLVMContext * context = irgen.GetContext(); 225 225 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * f = irgen.GetFunction(); 226 226 llvm::Function * f = irgen.GetFunction();
llvm::Value * cond; 227 227 llvm::Value * cond;
228 228
llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", f); 229 229 llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", f);
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", f); 230 230 llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", f);
llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", f); 231 231 llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", f);
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); 232 232 llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock());
llvm::BasicBlock * oldHeader = irgen.GetHeaderBlock(); 233 233 llvm::BasicBlock * oldHeader = irgen.GetHeaderBlock();
llvm::BasicBlock * oldFooter = irgen.GetFooterBlock(); 234 234 llvm::BasicBlock * oldFooter = irgen.GetFooterBlock();
irgen.SetHeaderBlock(headBlock); 235 235 irgen.SetHeaderBlock(headBlock);
irgen.SetFooterBlock(footBlock); 236 236 irgen.SetFooterBlock(footBlock);
237 237
irgen.SetBasicBlock(headBlock); 238 238 irgen.SetBasicBlock(headBlock);
cond = test->Emit(); 239 239 cond = test->Emit();
if(!irgen.GetBasicBlock()->getTerminator()) 240 240 if(!irgen.GetBasicBlock()->getTerminator())
{ 241 241 {
llvm::BranchInst::Create(bodyBlock, footBlock, cond, irgen.GetBasicBlock()); // given in the slides 242 242 llvm::BranchInst::Create(bodyBlock, footBlock, cond, irgen.GetBasicBlock()); // given in the slides
} 243 243 }
244 244
irgen.SetBasicBlock(bodyBlock); 245 245 irgen.SetBasicBlock(bodyBlock);
body->Emit(); 246 246 body->Emit();
if(!irgen.GetBasicBlock()->getTerminator()) 247 247 if(!irgen.GetBasicBlock()->getTerminator())
{ 248 248 {
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides 249 249 llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides
} 250 250 }
251 251
irgen.SetBasicBlock(footBlock); 252 252 irgen.SetBasicBlock(footBlock);
irgen.SetHeaderBlock(oldHeader); 253 253 irgen.SetHeaderBlock(oldHeader);
irgen.SetFooterBlock(oldFooter); 254 254 irgen.SetFooterBlock(oldFooter);
popScope(); 255 255 popScope();
return NULL; 256 256 return NULL;
} 257 257 }
258 258
259 259
//if statement 260 260 //if statement
llvm::Value * IfStmt::Emit(){ 261 261 llvm::Value * IfStmt::Emit(){
262
llvm::LLVMContext * context = irgen.GetContext(); 262 263 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * func = irgen.GetFunction(); 263 264 llvm::Function * func = irgen.GetFunction();
llvm::BasicBlock * elseBlock = NULL; 264 265 llvm::BasicBlock * elseBlock = NULL;
llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func); 265 266 llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func);
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); 266 267 llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func);
llvm::Value * val; 267 268 llvm::Value * val;
llvm::Value * condition = test->Emit(); 268 269 llvm::Value * condition = test->Emit();
270
if(elseBody) 269 271 if(elseBody)
{ 270 272 {
elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func); 271 273 elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func);
} 272 274 }
273 275
val = llvm::BranchInst::Create(thenBlock, elseBody ? elseBlock : footBlock, condition, irgen.GetBasicBlock()); 274 276 val = llvm::BranchInst::Create(thenBlock, elseBody ? elseBlock : footBlock, condition, irgen.GetBasicBlock());
pushScope(); 275 277 pushScope();
irgen.SetBasicBlock(thenBlock); 276 278 irgen.SetBasicBlock(thenBlock);
body->Emit(); 277 279 body->Emit();
278 280
if(!irgen.GetBasicBlock()->getTerminator()) 279 281 if(!irgen.GetBasicBlock()->getTerminator())
{ 280 282 {
val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); 281 283 val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock());
} 282 284 }
285
popScope(); 283 286 popScope();
284 287
if(elseBody) 285 288 if(elseBody)
{ 286 289 {
pushScope(); 287 290 pushScope();
irgen.SetBasicBlock(elseBlock); 288 291 irgen.SetBasicBlock(elseBlock);
elseBody->Emit(); 289 292 elseBody->Emit();
290 293
if(!irgen.GetBasicBlock()->getTerminator()) 291 294 if(!irgen.GetBasicBlock()->getTerminator())
{ 292 295 {
val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); 293 296 val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock());
} 294 297 }
popScope(); 295 298 popScope();
} 296 299 }
irgen.SetBasicBlock(footBlock); 297 300 irgen.SetBasicBlock(footBlock);
return val; 298 301 return val;
} 299 302 }
300 303
llvm::Value * BreakStmt::Emit(){ 301 304 llvm::Value * BreakStmt::Emit(){
//goes to footer 302 305 //goes to footer
llvm::Value * val; 303 306 llvm::Value * val;
llvm::LLVMContext * context = irgen.GetContext(); 304 307 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * func = irgen.GetFunction(); 305 308 llvm::Function * func = irgen.GetFunction();
val=llvm::BranchInst::Create (irgen.GetFooterBlock(), irgen.GetBasicBlock()); 306 309 val=llvm::BranchInst::Create (irgen.GetFooterBlock(), irgen.GetBasicBlock());
return val; 307 310 return val;
} 308 311 }
309 312
llvm::Value * ContinueStmt::Emit(){ 310 313 llvm::Value * ContinueStmt::Emit(){
llvm::Value * val; 311 314 llvm::Value * val;
llvm::LLVMContext * context = irgen.GetContext(); 312 315 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * func = irgen.GetFunction(); 313 316 llvm::Function * func = irgen.GetFunction();
val=llvm::BranchInst::Create (irgen.GetHeaderBlock(), irgen.GetBasicBlock()); 314 317 val=llvm::BranchInst::Create (irgen.GetHeaderBlock(), irgen.GetBasicBlock());
return val; 315 318 return val;
} 316 319 }
317 320
//Not sure 318 321 //Not sure
llvm::Value * ReturnStmt::Emit(){ 319 322 llvm::Value * ReturnStmt::Emit(){
llvm::Value * val; 320 323 llvm::Value * val;
llvm::LLVMContext * context = irgen.GetContext(); 321 324 llvm::LLVMContext * context = irgen.GetContext();
if (expr){ 322 325 if (expr){
llvm::Value * retVal = expr->Emit(); 323 326 llvm::Value * retVal = expr->Emit();
retVal = llvm::ReturnInst::Create(*context, retVal, irgen.GetBasicBlock()); 324 327 retVal = llvm::ReturnInst::Create(*context, retVal, irgen.GetBasicBlock());
return retVal; 325 328 return retVal;
} 326 329 }
val = llvm::ReturnInst::Create(*context, irgen.GetBasicBlock()); 327 330 val = llvm::ReturnInst::Create(*context, irgen.GetBasicBlock());
return val; 328 331 return val;
} 329 332 }
//stack for both 330 333 //stack for both
331 334
llvm::SwitchInst * curSwitch = NULL; 332 335 llvm::SwitchInst * curSwitch = NULL;
llvm::Value * SwitchStmt::Emit(){ 333 336 llvm::Value * SwitchStmt::Emit(){
llvm::SwitchInst * val; 334 337 llvm::SwitchInst * val;
llvm::LLVMContext * context = irgen.GetContext(); 335 338 llvm::LLVMContext * context = irgen.GetContext();
llvm::Function * func = irgen.GetFunction(); 336 339 llvm::Function * func = irgen.GetFunction();
vector<llvm::BasicBlock *> blockArr; 337 340 vector<llvm::BasicBlock *> blockArr;
int defaultIndex = -1; 338 341 int defaultIndex = -1;
//find all cases and create a basic block for all of them 339 342 //find all cases and create a basic block for all of them
for (int i = 0; i < cases->NumElements(); i++){ 340 343 for (int i = 0; i < cases->NumElements(); i++){
blockArr.push_back(llvm::BasicBlock::Create(*context, "switchBlock", func)); 341 344 blockArr.push_back(llvm::BasicBlock::Create(*context, "switchBlock", func));
if(dynamic_cast<Default*>(cases->Nth(i))) defaultIndex = i; 342 345 if(dynamic_cast<Default*>(cases->Nth(i))) defaultIndex = i;
} 343 346 }
/* File: ast_type.h 1 1 /* File: ast_type.h
* ---------------- 2 2 * ----------------
* In our parse tree, Type nodes are used to represent and 3 3 * In our parse tree, Type nodes are used to represent and
* store type information. The base Type class is used 4 4 * store type information. The base Type class is used
* for built-in types, the NamedType for classes and interfaces, 5 5 * for built-in types, the NamedType for classes and interfaces,
* and the ArrayType for arrays of other types. 6 6 * and the ArrayType for arrays of other types.
* 7 7 *
* pp3: You will need to extend the Type classes to implement 8 8 * pp3: You will need to extend the Type classes to implement
* the type system and rules for type equivalency and compatibility. 9 9 * the type system and rules for type equivalency and compatibility.
*/ 10 10 */
11 11
#ifndef _H_ast_type 12 12 #ifndef _H_ast_type
#define _H_ast_type 13 13 #define _H_ast_type
14 14
#include "ast.h" 15 15 #include "ast.h"
#include "list.h" 16 16 #include "list.h"
#include <iostream> 17 17 #include <iostream>
18 18
using namespace std; 19 19 using namespace std;
20 20
class TypeQualifier : public Node 21 21 class TypeQualifier : public Node
{ 22 22 {
protected: 23 23 protected:
char *typeQualifierName; 24 24 char *typeQualifierName;
25 25
public : 26 26 public :
static TypeQualifier *inTypeQualifier, *outTypeQualifier, *constTypeQualifier, *uniformTypeQualifier; 27 27 static TypeQualifier *inTypeQualifier, *outTypeQualifier, *constTypeQualifier, *uniformTypeQualifier;
28 28
TypeQualifier(yyltype loc) : Node(loc) {} 29 29 TypeQualifier(yyltype loc) : Node(loc) {}
TypeQualifier(const char *str); 30 30 TypeQualifier(const char *str);
31 31
const char *GetPrintNameForNode() { return "TypeQualifier"; } 32 32 const char *GetPrintNameForNode() { return "TypeQualifier"; }
void PrintChildren(int indentLevel); 33 33 void PrintChildren(int indentLevel);
}; 34 34 };
35 35
class Type : public Node 36 36 class Type : public Node
{ 37 37 {
protected: 38 38 protected:
char *typeName; 39 39 char *typeName;
40 40
public : 41 41 public :
static Type *intType, *uintType,*floatType, *boolType, *voidType, 42 42 static Type *intType, *uintType,*floatType, *boolType, *voidType,
*vec2Type, *vec3Type, *vec4Type, 43 43 *vec2Type, *vec3Type, *vec4Type,
*mat2Type, *mat3Type, *mat4Type, 44 44 *mat2Type, *mat3Type, *mat4Type,
*ivec2Type, *ivec3Type, *ivec4Type, 45 45 *ivec2Type, *ivec3Type, *ivec4Type,
*bvec2Type, *bvec3Type, *bvec4Type, 46 46 *bvec2Type, *bvec3Type, *bvec4Type,
*uvec2Type, *uvec3Type,*uvec4Type, 47 47 *uvec2Type, *uvec3Type,*uvec4Type,
*errorType; 48 48 *errorType;
49 49
Type(yyltype loc) : Node(loc) {} 50 50 Type(yyltype loc) : Node(loc) {}
Type(const char *str); 51 51 Type(const char *str);
52 52
const char *GetPrintNameForNode() { return "Type"; } 53 53 const char *GetPrintNameForNode() { return "Type"; }
void PrintChildren(int indentLevel); 54 54 void PrintChildren(int indentLevel);
55 55
virtual void PrintToStream(ostream& out) { out << typeName; } 56 56 virtual void PrintToStream(ostream& out) { out << typeName; }
friend ostream& operator<<(ostream& out, Type *t) { t->PrintToStream(out); return out; } 57 57 friend ostream& operator<<(ostream& out, Type *t) { t->PrintToStream(out); return out; }
virtual bool IsEquivalentTo(Type *other) { return (this == other); } 58 58 virtual bool IsEquivalentTo(Type *other) { return (this == other); }
virtual bool IsConvertibleTo(Type *other) { return (this == other || this == errorType); } 59 59 virtual bool IsConvertibleTo(Type *other) { return (this == other || this == errorType); }
bool IsNumeric(); 60 60 bool IsNumeric();
bool IsVector(); 61 61 bool IsVector();
bool IsMatrix(); 62 62 bool IsMatrix();
bool IsError(); 63 63 bool IsError();
}; 64 64 };
65 65
66 66
class NamedType : public Type 67 67 class NamedType : public Type
{ 68 68 {
protected: 69 69 protected:
Identifier *id; 70 70 Identifier *id;
71 71
public: 72 72 public:
NamedType(Identifier *i); 73 73 NamedType(Identifier *i);
74 74
const char *GetPrintNameForNode() { return "NamedType"; } 75 75 const char *GetPrintNameForNode() { return "NamedType"; }
void PrintChildren(int indentLevel); 76 76 void PrintChildren(int indentLevel);
void PrintToStream(ostream& out) { out << id; } 77 77 void PrintToStream(ostream& out) { out << id; }
/** 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
llvm::Type *GetVec2Type() const; 45 45 llvm::Type *GetVec2Type() const;
46 46
llvm::Type *GetVec3Type() const; 47 47 llvm::Type *GetVec3Type() const;
48 48
llvm::Type *GetVec4Type() const; 49 49 llvm::Type *GetVec4Type() const;
50 50
llvm::Type *GetMat2Type() const; 51 51 llvm::Type *GetMat2Type() const;
52 52
llvm::Type *GetMat3Type() const; 53 53 llvm::Type *GetMat3Type() const;
54 54