Commit 2cead1f5e8bfb78b7f54257f4f50b9c22bf79ffc
1 parent
ebc2ecde2e
Exists in
master
minor fixes arrays still dont work
Showing 6 changed files with 53 additions and 5 deletions Inline Diff
ast_decl.cc
View file @
2cead1f
/* 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); |
ast_expr.cc
View file @
2cead1f
/* 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; |
ast_expr.h
View file @
2cead1f
/* 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; |
ast_stmt.cc
View file @
2cead1f
/* 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 | } |
ast_type.h
View file @
2cead1f
/* 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; } |
irgen.h
View file @
2cead1f
/** | 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 |