Commit 5d9d0bcccc933b0df7085169997768ea94a64aeb
1 parent
2d15c0427d
Exists in
master
Bug fixes
Showing 2 changed files with 28 additions and 18 deletions Inline Diff
ast_decl.cc
View file @
5d9d0bc
/* 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::Value* val = new llvm::AllocaInst(convertType(type), id->GetName(), irgen.GetBasicBlock()); | 71 | 71 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), NULL, irgen.GetBasicBlock()); | 72 | 72 | llvm::Value* val; | |
73 | if(b) val = new llvm::AllocaInst(convertType(type), id->GetName(), b); | |||
74 | else { | |||
75 | llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type)); | |||
76 | val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, ""); | |||
77 | } | |||
78 | if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), "", b); | |||
addToScope(id->GetName(), this, val); | 73 | 79 | addToScope(id->GetName(), this, val); | |
return val; | 74 | 80 | return val; | |
} | 75 | 81 | } | |
76 | 82 | |||
llvm::Value* FnDecl::Emit() { | 77 | 83 | llvm::Value* FnDecl::Emit() { | |
llvm::BasicBlock* oldBlock = irgen.GetBasicBlock(); | 78 | 84 | llvm::BasicBlock* oldBlock = irgen.GetBasicBlock(); | |
llvm::LLVMContext* context = irgen.GetContext(); | 79 | 85 | llvm::LLVMContext* context = irgen.GetContext(); | |
pushScope(); | 80 | 86 | pushScope(); | |
vector<llvm::Type*> types; | 81 | 87 | vector<llvm::Type*> types; | |
for(int i = 0; i < formals->NumElements(); i++) { | 82 | 88 | for(int i = 0; i < formals->NumElements(); i++) { | |
types.push_back(convertType(formals->Nth(i)->GetType())); | 83 | 89 | types.push_back(convertType(formals->Nth(i)->GetType())); | |
} | 84 | 90 | } | |
llvm::FunctionType* ft = llvm::FunctionType::get(convertType(returnType), types, false); | 85 | 91 | llvm::FunctionType* ft = llvm::FunctionType::get(convertType(returnType), types, false); | |
popScope(); | 86 | 92 | popScope(); | |
llvm::Function* func = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, id->GetName(), irgen.GetOrCreateModule("program")); | 87 | 93 | llvm::Function* func = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, id->GetName(), irgen.GetOrCreateModule("program")); | |
llvm::BasicBlock * block = llvm::BasicBlock::Create(*context, "funcBlock", func); | 88 | 94 | llvm::BasicBlock * block = llvm::BasicBlock::Create(*context, "funcBlock", func); | |
irgen.SetBasicBlock(block); | 89 | 95 | irgen.SetBasicBlock(block); | |
for(int i = 0; i < formals->NumElements(); i++) { | 90 | 96 | for(int i = 0; i < formals->NumElements(); i++) { | |
formals->Nth(i)->Emit(); | 91 | 97 | formals->Nth(i)->Emit(); | |
} | 92 | 98 | } | |
llvm::Value* ret = body->Emit(); | 93 | 99 | body->Emit(); | |
llvm::ReturnInst::Create(*context, ret, block); | 94 | 100 | if(!block->getTerminator()) { |
ast_expr.cc
View file @
5d9d0bc
/* 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, NULL, 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() { | |
return new llvm::StoreInst(left->Emit(), right->Emit(), NULL, irgen.GetBasicBlock()); | 140 | 140 | return new llvm::StoreInst(left->Emit(), right->Emit(), "", irgen.GetBasicBlock()); | |
} | 141 | 141 | } | |
142 | 142 | |||
string Operator::getToken() const { | 143 | 143 | string Operator::getToken() const { | |
return tokenString; | 144 | 144 | return tokenString; | |
} | 145 | 145 | } | |
146 | 146 | |||
llvm::Value* IntConstant::Emit() { | 147 | 147 | llvm::Value* IntConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | 148 | 148 | return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | |
} | 149 | 149 | } | |
150 | 150 | |||
llvm::Value* FloatConstant::Emit() { | 151 | 151 | llvm::Value* FloatConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getFloatTy(*irgen.GetContext()), value, true); | 152 | 152 | return llvm::ConstantInt::get(llvm::Type::getFloatTy(*irgen.GetContext()), value, true); | |
} | 153 | 153 | } | |
154 | 154 | |||
llvm::Value* BoolConstant::Emit() { | 155 | 155 | llvm::Value* BoolConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | 156 | 156 | return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | |
} | 157 | 157 | } | |
158 | 158 | |||
llvm::Value* Call::Emit() { | 159 | 159 | llvm::Value* Call::Emit() { | |
vector<llvm::Value*> args; | 160 | 160 | vector<llvm::Value*> args; | |
for(int i = 0; i < actuals->NumElements(); i++) { | 161 | 161 | for(int i = 0; i < actuals->NumElements(); i++) { | |
args.push_back(actuals->Nth(i)->Emit()); | 162 | 162 | args.push_back(actuals->Nth(i)->Emit()); | |
} | 163 | 163 | } | |
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | 164 | 164 | return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | |
} | 165 | 165 | } | |
166 | 166 | |||
llvm::Value* CompoundExpr::Emit() { | 167 | 167 | llvm::Value* CompoundExpr::Emit() { | |
llvm::Value* l = left->Emit(); | 168 | 168 | llvm::Value* l = left->Emit(); | |
llvm::Value* r = right->Emit(); | 169 | 169 | llvm::Value* r = right->Emit(); | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 170 | 170 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
//austins additional value | 171 | 171 | //austins additional value | |
llvm::Value *val; | 172 | 172 | llvm::Value *val; | |
if(!l) { | 173 | 173 | if(!l) { | |
if(op->getToken() == "++") | 174 | 174 | if(op->getToken() == "++") | |
val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 175 | 175 | val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
return llvm::BinaryOperator::CreateAdd(l, val, "", irgen.GetBasicBlock()); | 176 | 176 | return llvm::BinaryOperator::CreateAdd(l, val, "", irgen.GetBasicBlock()); | |
if(op->getToken() == "--") | 177 | 177 | if(op->getToken() == "--") | |
val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 178 | 178 | val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
return llvm::BinaryOperator::CreateSub(l, val, "", irgen.GetBasicBlock()); | 179 | 179 | return llvm::BinaryOperator::CreateSub(l, val, "", irgen.GetBasicBlock()); | |
} | 180 | 180 | } | |
if(l->getType()->isFPOrFPVectorTy()) { | 181 | 181 | if(l->getType()->isFPOrFPVectorTy()) { | |
if(op->getToken() == "+") | 182 | 182 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | 183 | 183 | return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | |
if(op->getToken() == "-") | 184 | 184 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | 185 | 185 | return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | |
if(op->getToken() == "*") | 186 | 186 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | 187 | 187 | return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | |
if(op->getToken() == "/") | 188 | 188 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | 189 | 189 | return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | |
if(op->getToken() == "==") | 190 | 190 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | 191 | 191 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | |
if(op->getToken() == "!=") | 192 | 192 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | 193 | 193 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | |
if(op->getToken() == "<=") | 194 | 194 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | 195 | 195 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | |
if(op->getToken() == ">=") | 196 | 196 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | 197 | 197 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | |
if(op->getToken() == "<") | 198 | 198 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | 199 | 199 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | |
if(op->getToken() == ">") | 200 | 200 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | 201 | 201 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | |
} | 202 | 202 | } | |
if(l->getType()->isIntOrIntVectorTy()) { | 203 | 203 | if(l->getType()->isIntOrIntVectorTy()) { | |
if(op->getToken() == "+") | 204 | 204 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | 205 | 205 | return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | |
if(op->getToken() == "-") | 206 | 206 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | 207 | 207 | return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | |
if(op->getToken() == "*") | 208 | 208 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | 209 | 209 | return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | |
if(op->getToken() == "/") | 210 | 210 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | 211 | 211 | return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | |
if(op->getToken() == "==") | 212 | 212 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | 213 | 213 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | |
if(op->getToken() == "!=") | 214 | 214 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | 215 | 215 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | |
if(op->getToken() == "<=") | 216 | 216 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | 217 | 217 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); |