Compare View
Commits (3)
Diff
Showing 3 changed files Inline Diff
ast_expr.cc
View file @
eefa7b6
/* File: ast_expr.cc | 1 | 1 | /* File: ast_expr.cc | |
* ----------------- | 2 | 2 | * ----------------- | |
* Implementation of expression node classes. | 3 | 3 | * Implementation of expression node classes. | |
*/ | 4 | 4 | */ | |
5 | 5 | |||
#include <string.h> | 6 | 6 | #include <string.h> | |
#include "ast_expr.h" | 7 | 7 | #include "ast_expr.h" | |
#include "ast_type.h" | 8 | 8 | #include "ast_type.h" | |
#include "ast_decl.h" | 9 | 9 | #include "ast_decl.h" | |
#include "symtable.h" | 10 | 10 | #include "symtable.h" | |
11 | 11 | |||
IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { | 12 | 12 | IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { | |
value = val; | 13 | 13 | value = val; | |
} | 14 | 14 | } | |
void IntConstant::PrintChildren(int indentLevel) { | 15 | 15 | void IntConstant::PrintChildren(int indentLevel) { | |
printf("%d", value); | 16 | 16 | printf("%d", value); | |
} | 17 | 17 | } | |
18 | 18 | |||
FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { | 19 | 19 | FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { | |
value = val; | 20 | 20 | value = val; | |
} | 21 | 21 | } | |
void FloatConstant::PrintChildren(int indentLevel) { | 22 | 22 | void FloatConstant::PrintChildren(int indentLevel) { | |
printf("%g", value); | 23 | 23 | printf("%g", value); | |
} | 24 | 24 | } | |
25 | 25 | |||
BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { | 26 | 26 | BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { | |
value = val; | 27 | 27 | value = val; | |
} | 28 | 28 | } | |
void BoolConstant::PrintChildren(int indentLevel) { | 29 | 29 | void BoolConstant::PrintChildren(int indentLevel) { | |
printf("%s", value ? "true" : "false"); | 30 | 30 | printf("%s", value ? "true" : "false"); | |
} | 31 | 31 | } | |
32 | 32 | |||
VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { | 33 | 33 | VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { | |
Assert(ident != NULL); | 34 | 34 | Assert(ident != NULL); | |
this->id = ident; | 35 | 35 | this->id = ident; | |
} | 36 | 36 | } | |
37 | 37 | |||
void VarExpr::PrintChildren(int indentLevel) { | 38 | 38 | void VarExpr::PrintChildren(int indentLevel) { | |
id->Print(indentLevel+1); | 39 | 39 | id->Print(indentLevel+1); | |
} | 40 | 40 | } | |
41 | 41 | |||
Operator::Operator(yyltype loc, const char *tok) : Node(loc) { | 42 | 42 | Operator::Operator(yyltype loc, const char *tok) : Node(loc) { | |
Assert(tok != NULL); | 43 | 43 | Assert(tok != NULL); | |
strncpy(tokenString, tok, sizeof(tokenString)); | 44 | 44 | strncpy(tokenString, tok, sizeof(tokenString)); | |
} | 45 | 45 | } | |
46 | 46 | |||
void Operator::PrintChildren(int indentLevel) { | 47 | 47 | void Operator::PrintChildren(int indentLevel) { | |
printf("%s",tokenString); | 48 | 48 | printf("%s",tokenString); | |
} | 49 | 49 | } | |
50 | 50 | |||
bool Operator::IsOp(const char *op) const { | 51 | 51 | bool Operator::IsOp(const char *op) const { | |
return strcmp(tokenString, op) == 0; | 52 | 52 | return strcmp(tokenString, op) == 0; | |
} | 53 | 53 | } | |
54 | 54 | |||
CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) | 55 | 55 | CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) | |
: Expr(Join(l->GetLocation(), r->GetLocation())) { | 56 | 56 | : Expr(Join(l->GetLocation(), r->GetLocation())) { | |
Assert(l != NULL && o != NULL && r != NULL); | 57 | 57 | Assert(l != NULL && o != NULL && r != NULL); | |
(op=o)->SetParent(this); | 58 | 58 | (op=o)->SetParent(this); | |
(left=l)->SetParent(this); | 59 | 59 | (left=l)->SetParent(this); | |
(right=r)->SetParent(this); | 60 | 60 | (right=r)->SetParent(this); | |
} | 61 | 61 | } | |
62 | 62 | |||
CompoundExpr::CompoundExpr(Operator *o, Expr *r) | 63 | 63 | CompoundExpr::CompoundExpr(Operator *o, Expr *r) | |
: Expr(Join(o->GetLocation(), r->GetLocation())) { | 64 | 64 | : Expr(Join(o->GetLocation(), r->GetLocation())) { | |
Assert(o != NULL && r != NULL); | 65 | 65 | Assert(o != NULL && r != NULL); | |
left = NULL; | 66 | 66 | left = NULL; | |
(op=o)->SetParent(this); | 67 | 67 | (op=o)->SetParent(this); | |
(right=r)->SetParent(this); | 68 | 68 | (right=r)->SetParent(this); | |
} | 69 | 69 | } | |
70 | 70 | |||
CompoundExpr::CompoundExpr(Expr *l, Operator *o) | 71 | 71 | CompoundExpr::CompoundExpr(Expr *l, Operator *o) | |
: Expr(Join(l->GetLocation(), o->GetLocation())) { | 72 | 72 | : Expr(Join(l->GetLocation(), o->GetLocation())) { | |
Assert(l != NULL && o != NULL); | 73 | 73 | Assert(l != NULL && o != NULL); | |
(left=l)->SetParent(this); | 74 | 74 | (left=l)->SetParent(this); | |
(op=o)->SetParent(this); | 75 | 75 | (op=o)->SetParent(this); | |
} | 76 | 76 | } | |
77 | 77 | |||
void CompoundExpr::PrintChildren(int indentLevel) { | 78 | 78 | void CompoundExpr::PrintChildren(int indentLevel) { | |
if (left) left->Print(indentLevel+1); | 79 | 79 | if (left) left->Print(indentLevel+1); | |
op->Print(indentLevel+1); | 80 | 80 | op->Print(indentLevel+1); | |
if (right) right->Print(indentLevel+1); | 81 | 81 | if (right) right->Print(indentLevel+1); | |
} | 82 | 82 | } | |
83 | 83 | |||
ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) | 84 | 84 | ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) | |
: Expr(Join(c->GetLocation(), f->GetLocation())) { | 85 | 85 | : Expr(Join(c->GetLocation(), f->GetLocation())) { | |
Assert(c != NULL && t != NULL && f != NULL); | 86 | 86 | Assert(c != NULL && t != NULL && f != NULL); | |
(cond=c)->SetParent(this); | 87 | 87 | (cond=c)->SetParent(this); | |
(trueExpr=t)->SetParent(this); | 88 | 88 | (trueExpr=t)->SetParent(this); | |
(falseExpr=f)->SetParent(this); | 89 | 89 | (falseExpr=f)->SetParent(this); | |
} | 90 | 90 | } | |
91 | 91 | |||
void ConditionalExpr::PrintChildren(int indentLevel) { | 92 | 92 | void ConditionalExpr::PrintChildren(int indentLevel) { | |
cond->Print(indentLevel+1, "(cond) "); | 93 | 93 | cond->Print(indentLevel+1, "(cond) "); | |
trueExpr->Print(indentLevel+1, "(true) "); | 94 | 94 | trueExpr->Print(indentLevel+1, "(true) "); | |
falseExpr->Print(indentLevel+1, "(false) "); | 95 | 95 | falseExpr->Print(indentLevel+1, "(false) "); | |
} | 96 | 96 | } | |
ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { | 97 | 97 | ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { | |
(base=b)->SetParent(this); | 98 | 98 | (base=b)->SetParent(this); | |
(subscript=s)->SetParent(this); | 99 | 99 | (subscript=s)->SetParent(this); | |
} | 100 | 100 | } | |
101 | 101 | |||
void ArrayAccess::PrintChildren(int indentLevel) { | 102 | 102 | void ArrayAccess::PrintChildren(int indentLevel) { | |
base->Print(indentLevel+1); | 103 | 103 | base->Print(indentLevel+1); | |
subscript->Print(indentLevel+1, "(subscript) "); | 104 | 104 | subscript->Print(indentLevel+1, "(subscript) "); | |
} | 105 | 105 | } | |
106 | 106 | |||
FieldAccess::FieldAccess(Expr *b, Identifier *f) | 107 | 107 | FieldAccess::FieldAccess(Expr *b, Identifier *f) | |
: LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { | 108 | 108 | : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { | |
Assert(f != NULL); // b can be be NULL (just means no explicit base) | 109 | 109 | Assert(f != NULL); // b can be be NULL (just means no explicit base) | |
base = b; | 110 | 110 | base = b; | |
if (base) base->SetParent(this); | 111 | 111 | if (base) base->SetParent(this); | |
(field=f)->SetParent(this); | 112 | 112 | (field=f)->SetParent(this); | |
} | 113 | 113 | } | |
114 | 114 | |||
115 | 115 | |||
void FieldAccess::PrintChildren(int indentLevel) { | 116 | 116 | void FieldAccess::PrintChildren(int indentLevel) { | |
if (base) base->Print(indentLevel+1); | 117 | 117 | if (base) base->Print(indentLevel+1); | |
field->Print(indentLevel+1); | 118 | 118 | field->Print(indentLevel+1); | |
} | 119 | 119 | } | |
120 | 120 | |||
Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { | 121 | 121 | Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { | |
Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) | 122 | 122 | Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) | |
base = b; | 123 | 123 | base = b; | |
if (base) base->SetParent(this); | 124 | 124 | if (base) base->SetParent(this); | |
(field=f)->SetParent(this); | 125 | 125 | (field=f)->SetParent(this); | |
(actuals=a)->SetParentAll(this); | 126 | 126 | (actuals=a)->SetParentAll(this); | |
} | 127 | 127 | } | |
128 | 128 | |||
void Call::PrintChildren(int indentLevel) { | 129 | 129 | void Call::PrintChildren(int indentLevel) { | |
if (base) base->Print(indentLevel+1); | 130 | 130 | if (base) base->Print(indentLevel+1); | |
if (field) field->Print(indentLevel+1); | 131 | 131 | if (field) field->Print(indentLevel+1); | |
if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); | 132 | 132 | if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); | |
} | 133 | 133 | } | |
134 | 134 | |||
llvm::Value* VarExpr::Emit() { | 135 | 135 | llvm::Value* VarExpr::Emit() { | |
return new llvm::LoadInst(findSymbol(id->GetName()).second, NULL, irgen.GetBasicBlock()); | 136 | 136 | return new llvm::LoadInst(findSymbol(id->GetName()).second, NULL, irgen.GetBasicBlock()); | |
} | 137 | 137 | } | |
138 | 138 | |||
llvm::Value* AssignExpr::Emit() { | 139 | 139 | llvm::Value* AssignExpr::Emit() { | |
return new llvm::StoreInst(left->Emit(), right->Emit(), NULL, irgen.GetBasicBlock()); | 140 | 140 | return new llvm::StoreInst(left->Emit(), right->Emit(), NULL, irgen.GetBasicBlock()); | |
} | 141 | 141 | } | |
142 | 142 | |||
string Operator::getToken() const { | 143 | 143 | string Operator::getToken() const { | |
return tokenString; | 144 | 144 | return tokenString; | |
} | 145 | 145 | } | |
146 | 146 | |||
llvm::Value* IntConstant::Emit() { | 147 | 147 | llvm::Value* IntConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | 148 | 148 | return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | |
} | 149 | 149 | } | |
150 | 150 | |||
llvm::Value* FloatConstant::Emit() { | 151 | 151 | llvm::Value* FloatConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getFloatTy(*irgen.GetContext()), value, true); | 152 | 152 | return llvm::ConstantInt::get(llvm::Type::getFloatTy(*irgen.GetContext()), value, true); | |
} | 153 | 153 | } | |
154 | 154 | |||
llvm::Value* BoolConstant::Emit() { | 155 | 155 | llvm::Value* BoolConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | 156 | 156 | return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); | |
} | 157 | 157 | } | |
158 | 158 | |||
llvm::Value* Call::Emit() { | 159 | 159 | llvm::Value* Call::Emit() { | |
vector<llvm::Value*> args; | 160 | 160 | vector<llvm::Value*> args; | |
for(int i = 0; i < actuals->NumElements(); i++) { | 161 | 161 | for(int i = 0; i < actuals->NumElements(); i++) { | |
args.push_back(actuals->Nth(i)->Emit()); | 162 | 162 | args.push_back(actuals->Nth(i)->Emit()); | |
} | 163 | 163 | } | |
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | 164 | 164 | return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); | |
} | 165 | 165 | } | |
166 | 166 | |||
llvm::Value* CompoundExpr::Emit() { | 167 | 167 | llvm::Value* CompoundExpr::Emit() { | |
llvm::Value* l = l ? left->Emit() : NULL; | 168 | 168 | llvm::Value* l = l ? left->Emit() : NULL; | |
llvm::Value* r = r ? right->Emit() : NULL; | 169 | 169 | llvm::Value* r = r ? right->Emit() : NULL; | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 170 | 170 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
//austins additional value | 171 | 171 | //austins additional value | |
172 | llvm::Value *val; | |||
173 | if(!l) { | |||
llvm::Value *val; | 172 | 174 | if(op->getToken() == "++") | |
if(!l) { | 173 | 175 | val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
176 | return llvm::BinaryOperator::CreateAdd(l, val, "", irgen.GetBasicBlock()); | |||
if(op->getToken() == "++") | 174 | 177 | if(op->getToken() == "--") | |
val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 175 | 178 | val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
179 | return llvm::BinaryOperator::CreateSub(l, val, "", irgen.GetBasicBlock()); | |||
return llvm::BinaryOperator::CreateAdd(l, val, "", irgen.GetBasicBlock()); | 176 | 180 | } | |
if(op->getToken() == "--") | 177 | 181 | if(l->getType()->isFPOrFPVectorTy()) { | |
val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 178 | 182 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::CreateSub(l, val, "", irgen.GetBasicBlock()); | 179 | 183 | return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, NULL, b); | |
} | 180 | 184 | if(op->getToken() == "-") | |
if(l->getType()->isFPOrFPVectorTy()) { | 181 | 185 | return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, NULL, b); | |
if(op->getToken() == "+") | 182 | 186 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, NULL, b); | 183 | 187 | return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, NULL, b); | |
if(op->getToken() == "-") | 184 | 188 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, NULL, b); | 185 | 189 | return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, NULL, b); | |
if(op->getToken() == "*") | 186 | 190 | if(op->getToken() == "==") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, NULL, b); | 187 | 191 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, NULL, b); | |
if(op->getToken() == "/") | 188 | 192 | if(op->getToken() == "!=") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, NULL, b); | 189 | 193 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, NULL, b); | |
if(op->getToken() == "==") | 190 | 194 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, NULL, b); | 191 | 195 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, NULL, b); | |
if(op->getToken() == "!=") | 192 | 196 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, NULL, b); | 193 | 197 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, NULL, b); | |
if(op->getToken() == "<=") | 194 | 198 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, NULL, b); | 195 | 199 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, NULL, b); | |
if(op->getToken() == ">=") | 196 | 200 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, NULL, b); | 197 | 201 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, NULL, b); | |
if(op->getToken() == "<") | 198 | 202 | } | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, NULL, b); | 199 | 203 | if(l->getType()->isIntOrIntVectorTy()) { | |
if(op->getToken() == ">") | 200 | 204 | if(op->getToken() == "+") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, NULL, b); | 201 | 205 | return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, NULL, b); | |
} | 202 | 206 | if(op->getToken() == "-") | |
if(l->getType()->isIntOrIntVectorTy()) { | 203 | 207 | return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, NULL, b); | |
if(op->getToken() == "+") | 204 | 208 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, NULL, b); | 205 | 209 | return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, NULL, b); | |
if(op->getToken() == "-") | 206 | 210 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, NULL, b); | 207 | 211 | return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, NULL, b); |
ast_stmt.cc
View file @
eefa7b6
/* 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(); | |
} | 149 | 149 | } | |
150 | 150 | |||
popScope(); | 151 | 151 | popScope(); | |
return NULL; | 152 | 152 | return NULL; | |
} | 153 | 153 | } | |
154 | 154 | |||
llvm::Value * DeclStmt::Emit(){ | 155 | 155 | llvm::Value * DeclStmt::Emit(){ | |
llvm::Value * val; | 156 | 156 | llvm::Value * val; | |
if (VarDecl * vd = dynamic_cast<VarDecl*>(this->decl)){ | 157 | 157 | if (VarDecl * vd = dynamic_cast<VarDecl*>(this->decl)){ | |
val = vd->Emit(); | 158 | 158 | val = vd->Emit(); | |
} | 159 | 159 | } | |
else if (FnDecl * fd = dynamic_cast<FnDecl*>(this->decl)){ | 160 | 160 | else if (FnDecl * fd = dynamic_cast<FnDecl*>(this->decl)){ | |
val = fd->Emit(); | 161 | 161 | val = fd->Emit(); | |
} | 162 | 162 | } | |
else{ | 163 | 163 | else{ | |
val = NULL; | 164 | 164 | val = NULL; | |
} | 165 | 165 | } | |
return val; | 166 | 166 | return val; | |
} | 167 | 167 | } | |
168 | 168 | |||
llvm::Value * ConditionalStmt::Emit(){ | 169 | 169 | llvm::Value * ConditionalStmt::Emit(){ | |
return NULL; | 170 | 170 | return NULL; | |
} | 171 | 171 | } | |
//for statement | 172 | 172 | //for statement | |
llvm::Value * ForStmt::Emit() | 173 | 173 | llvm::Value * ForStmt::Emit() | |
{ | 174 | 174 | { | |
pushScope(); | 175 | 175 | pushScope(); | |
llvm::LLVMContext * context = irgen.GetContext(); | 176 | 176 | llvm::LLVMContext * context = irgen.GetContext(); | |
llvm::Function * func = irgen.GetFunction(); | 177 | 177 | llvm::Function * func = irgen.GetFunction(); | |
llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", func); | 178 | 178 | llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", func); | |
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | 179 | 179 | llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | |
llvm::BasicBlock * incBlock = llvm::BasicBlock::Create(*context, "incBlock", func); | 180 | 180 | llvm::BasicBlock * incBlock = llvm::BasicBlock::Create(*context, "incBlock", func); | |
llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", func); | 181 | 181 | llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", func); | |
llvm::Value * condition; | 182 | 182 | llvm::Value * condition; | |
183 | 183 | |||
// init and branch to head | 184 | |||
init->Emit(); | 185 | 184 | // init and branch to head | |
186 | 185 | init->Emit(); | ||
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | 187 | 186 | ||
188 | 187 | llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | ||
// head | 189 | 188 | ||
irgen.SetBasicBlock(headBlock); | 190 | 189 | // head | |
condition = test->Emit(); | 191 | 190 | irgen.SetBasicBlock(headBlock); | |
if(!irgen.GetBasicBlock()->getTerminator()) | 192 | 191 | condition = test->Emit(); | |
{ | 193 | 192 | if(!irgen.GetBasicBlock()->getTerminator()) | |
llvm::BranchInst::Create(bodyBlock, footBlock, condition, irgen.GetBasicBlock()); | 194 | 193 | { | |
} | 195 | 194 | llvm::BranchInst::Create(bodyBlock, footBlock, condition, irgen.GetBasicBlock()); | |
196 | 195 | } | ||
// body | 197 | 196 | ||
irgen.SetBasicBlock(bodyBlock); | 198 | 197 | // body | |
body->Emit(); | 199 | 198 | irgen.SetBasicBlock(bodyBlock); | |
if(!irgen.GetBasicBlock()->getTerminator()) | 200 | 199 | body->Emit(); | |
{ | 201 | 200 | if(!irgen.GetBasicBlock()->getTerminator()) | |
llvm::BranchInst::Create(incBlock, irgen.GetBasicBlock()); | 202 | 201 | { | |
} | 203 | 202 | llvm::BranchInst::Create(incBlock, irgen.GetBasicBlock()); | |
204 | 203 | } | ||
// step | 205 | 204 | ||
irgen.SetBasicBlock(incBlock); | 206 | 205 | // step | |
step->Emit(); | 207 | 206 | irgen.SetBasicBlock(incBlock); | |
if(!irgen.GetBasicBlock()->getTerminator()) | 208 | 207 | step->Emit(); | |
{ | 209 | 208 | if(!irgen.GetBasicBlock()->getTerminator()) | |
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | 210 | 209 | { | |
} | 211 | 210 | llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | |
212 | 211 | } | ||
irgen.SetBasicBlock(footBlock); | 213 | 212 | ||
popScope(); | 214 | 213 | irgen.SetBasicBlock(footBlock); | |
return NULL; | 215 | 214 | popScope(); | |
} | 216 | 215 | return NULL; | |
//while statement | 217 | 216 | } | |
218 | 217 | //while statement | ||
218 | llvm::Value * WhileStmt::Emit(){ | |||
219 | pushScope(); | |||
220 | llvm::LLVMContext * context = irgen.GetContext(); | |||
221 | llvm::Function * f = irgen.GetFunction(); | |||
222 | llvm::Value * cond; | |||
223 | ||||
224 | llvm::BasicBlock * headBlock = llvm::BasicBlock::Create(*context, "headBlock", f); | |||
225 | llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", f); | |||
226 | llvm::BasicBlock * bodyBlock = llvm::BasicBlock::Create(*context, "bodyBlock", f); | |||
227 | llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | |||
228 | ||||
229 | irgen.SetBasicBlock(headBlock); | |||
230 | cond = test->Emit(); | |||
231 | if(!irgen.GetBasicBlock()->getTerminator()) | |||
232 | { | |||
233 | llvm::BranchInst::Create(bodyBlock, footBlock, cond, irgen.GetBasicBlock()); // given in the slides | |||
234 | } | |||
235 | ||||
236 | irgen.SetBasicBlock(bodyBlock); | |||
237 | body->Emit(); | |||
238 | if(!irgen.GetBasicBlock()->getTerminator()) | |||
239 | { | |||
240 | llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); // given in the slides | |||
241 | } | |||
242 | ||||
243 | ||||
244 | irgen.SetBasicBlock(footBlock); | |||
245 | popScope(); | |||
246 | return NULL; | |||
247 | } | |||
248 | ||||
//if statement | 219 | 249 | ||
llvm::Value * IfStmt::Emit(){ | 220 | 250 | //if statement | |
llvm::LLVMContext * context = irgen.GetContext(); | 221 | 251 | llvm::Value * IfStmt::Emit(){ | |
llvm::Function * func = irgen.GetFunction(); | 222 | 252 | llvm::LLVMContext * context = irgen.GetContext(); | |
llvm::BasicBlock * elseBlock = NULL; | 223 | 253 | llvm::Function * func = irgen.GetFunction(); | |
llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func); | 224 | 254 | llvm::BasicBlock * elseBlock = NULL; | |
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | 225 | 255 | llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func); | |
llvm::Value * val; | 226 | 256 | llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | |
llvm::Value * condition = test->Emit(); | 227 | 257 | llvm::Value * val; | |
if(elseBody) | 228 | 258 | llvm::Value * condition = test->Emit(); | |
{ | 229 | 259 | if(elseBody) | |
elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func); | 230 | 260 | { | |
} | 231 | 261 | elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func); | |
232 | 262 | } | ||
val = llvm::BranchInst::Create(thenBlock, elseBody ? elseBlock : footBlock, condition, irgen.GetBasicBlock()); | 233 | 263 | ||
pushScope(); | 234 | 264 | val = llvm::BranchInst::Create(thenBlock, elseBody ? elseBlock : footBlock, condition, irgen.GetBasicBlock()); | |
irgen.SetBasicBlock(thenBlock); | 235 | 265 | pushScope(); | |
body->Emit(); | 236 | 266 | irgen.SetBasicBlock(thenBlock); | |
237 | 267 | body->Emit(); | ||
if(!irgen.GetBasicBlock()->getTerminator()) | 238 | 268 | ||
{ | 239 | 269 | if(!irgen.GetBasicBlock()->getTerminator()) | |
val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | 240 | 270 | { | |
} | 241 | 271 | val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | |
popScope(); | 242 | 272 | } | |
243 | 273 | popScope(); | ||
if(elseBody) | 244 | 274 | ||
{ | 245 | 275 | if(elseBody) | |
pushScope(); | 246 | 276 | { | |
irgen.SetBasicBlock(elseBlock); | 247 | 277 | pushScope(); | |
elseBody->Emit(); | 248 | 278 | irgen.SetBasicBlock(elseBlock); | |
249 | 279 | elseBody->Emit(); | ||
if(!irgen.GetBasicBlock()->getTerminator()) | 250 | 280 | ||
{ | 251 | 281 | if(!irgen.GetBasicBlock()->getTerminator()) | |
val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | 252 | 282 | { | |
} | 253 | 283 | val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | |
popScope(); | 254 | 284 | } | |
} | 255 | 285 | popScope(); | |
irgen.SetBasicBlock(footBlock); | 256 | 286 | } | |
return val; | 257 | 287 | irgen.SetBasicBlock(footBlock); | |
} | 258 | 288 | return val; | |
259 | 289 | } | ||
llvm::Value * BreakStmt::Emit(){ | 260 | 290 | ||
return NULL; | 261 | 291 | llvm::Value * BreakStmt::Emit(){ | |
} | 262 | 292 | llvm::Value * val; | |
293 | llvm::LLVMContext * context = irgen.GetContext(); | |||
294 | llvm::Function * func = irgen.GetFunction(); | |||
295 | llvm::BasicBlock * breakBlock = llvm::BasicBlock::Create(*context, "breakBlock", func); | |||
296 | val=llvm::Create (breakBlock, irgen.GetBasicBlock()); | |||
263 | 297 | } | ||
llvm::Value * ContinueStmt::Emit(){ | 264 | 298 | ||
return NULL; | 265 | 299 | llvm::Value * ContinueStmt::Emit(){ | |
} | 266 | 300 | llvm::Value * val; | |
301 | llvm::LLVMContext * context = irgen.GetContext(); | |||
302 | llvm::Function * func = irgen.GetFunction(); | |||
303 | llvm::BasicBlock * contBlock = llvm::BasicBlock::Create(*context, "contBlock", func); | |||
304 | val=llvm::Create (breakBlock, irgen.GetBasicBlock()); | |||
267 | 305 | } | ||
//Not sure | 268 | 306 | ||
llvm::Value * ReturnStmt::Emit(){ | 269 | 307 | //Not sure | |
llvm::Value * val; | 270 | 308 | llvm::Value * ReturnStmt::Emit(){ | |
llvm::LLVMContext * context = irgen.GetContext(); | 271 | 309 | llvm::Value * val; | |
if (expr){ | 272 | 310 | llvm::LLVMContext * context = irgen.GetContext(); | |
llvm::Value * retVal = expr->Emit(); | 273 | 311 | if (expr){ | |
retVal = llvm::ReturnInst::Create(*context, retVal, irgen.GetBasicBlock()); | 274 | 312 | llvm::Value * retVal = expr->Emit(); | |
return retVal; | 275 | 313 | retVal = llvm::ReturnInst::Create(*context, retVal, irgen.GetBasicBlock()); | |
} | 276 | 314 | return retVal; | |
val = llvm::ReturnInst::Create(*context, irgen.GetBasicBlock()); | 277 | 315 | } | |
return val; | 278 | 316 | val = llvm::ReturnInst::Create(*context, irgen.GetBasicBlock()); | |
} | 279 | 317 | return val; | |
280 | 318 | } |
ast_stmt.h
View file @
eefa7b6
/* File: ast_stmt.h | 1 | 1 | /* File: ast_stmt.h | |
* ---------------- | 2 | 2 | * ---------------- | |
* The Stmt class and its subclasses are used to represent | 3 | 3 | * The Stmt class and its subclasses are used to represent | |
* statements in the parse tree. For each statment in the | 4 | 4 | * statements in the parse tree. For each statment in the | |
* language (for, if, return, etc.) there is a corresponding | 5 | 5 | * language (for, if, return, 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 Stmt classes to generate | 8 | 8 | * pp3: You will need to extend the Stmt classes to generate | |
* LLVM IR instructions. | 9 | 9 | * LLVM IR instructions. | |
*/ | 10 | 10 | */ | |
11 | 11 | |||
12 | 12 | |||
#ifndef _H_ast_stmt | 13 | 13 | #ifndef _H_ast_stmt | |
#define _H_ast_stmt | 14 | 14 | #define _H_ast_stmt | |
15 | 15 | |||
#include "list.h" | 16 | 16 | #include "list.h" | |
#include "ast.h" | 17 | 17 | #include "ast.h" | |
18 | 18 | |||
class Decl; | 19 | 19 | class Decl; | |
class VarDecl; | 20 | 20 | class VarDecl; | |
class Expr; | 21 | 21 | class Expr; | |
class IntConstant; | 22 | 22 | class IntConstant; | |
23 | 23 | |||
void yyerror(const char *msg); | 24 | 24 | void yyerror(const char *msg); | |
25 | 25 | |||
class Program : public Node | 26 | 26 | class Program : public Node | |
{ | 27 | 27 | { | |
protected: | 28 | 28 | protected: | |
List<Decl*> *decls; | 29 | 29 | List<Decl*> *decls; | |
30 | 30 | |||
public: | 31 | 31 | public: | |
Program(List<Decl*> *declList); | 32 | 32 | Program(List<Decl*> *declList); | |
const char *GetPrintNameForNode() { return "Program"; } | 33 | 33 | const char *GetPrintNameForNode() { return "Program"; } | |
void PrintChildren(int indentLevel); | 34 | 34 | void PrintChildren(int indentLevel); | |
virtual llvm::Value* Emit(); | 35 | 35 | virtual llvm::Value* Emit(); | |
}; | 36 | 36 | }; | |
37 | 37 | |||
class Stmt : public Node | 38 | 38 | class Stmt : public Node | |
{ | 39 | 39 | { | |
public: | 40 | 40 | public: | |
Stmt() : Node() {} | 41 | 41 | Stmt() : Node() {} | |
Stmt(yyltype loc) : Node(loc) {} | 42 | 42 | Stmt(yyltype loc) : Node(loc) {} | |
}; | 43 | 43 | }; | |
44 | 44 | |||
class StmtBlock : public Stmt | 45 | 45 | class StmtBlock : public Stmt | |
{ | 46 | 46 | { | |
protected: | 47 | 47 | protected: | |
List<VarDecl*> *decls; | 48 | 48 | List<VarDecl*> *decls; | |
List<Stmt*> *stmts; | 49 | 49 | List<Stmt*> *stmts; | |
50 | 50 | |||
public: | 51 | 51 | public: | |
StmtBlock(List<VarDecl*> *variableDeclarations, List<Stmt*> *statements); | 52 | 52 | StmtBlock(List<VarDecl*> *variableDeclarations, List<Stmt*> *statements); | |
const char *GetPrintNameForNode() { return "StmtBlock"; } | 53 | 53 | const char *GetPrintNameForNode() { return "StmtBlock"; } | |
void PrintChildren(int indentLevel); | 54 | 54 | void PrintChildren(int indentLevel); | |
llvm::Value *Emit(); | 55 | 55 | llvm::Value *Emit(); | |
}; | 56 | 56 | }; | |
57 | 57 | |||
class DeclStmt: public Stmt | 58 | 58 | class DeclStmt: public Stmt | |
{ | 59 | 59 | { | |
protected: | 60 | 60 | protected: | |
Decl* decl; | 61 | 61 | Decl* decl; | |
62 | 62 | |||
public: | 63 | 63 | public: | |
DeclStmt(Decl *d); | 64 | 64 | DeclStmt(Decl *d); | |
const char *GetPrintNameForNode() { return "DeclStmt"; } | 65 | 65 | const char *GetPrintNameForNode() { return "DeclStmt"; } | |
void PrintChildren(int indentLevel); | 66 | 66 | void PrintChildren(int indentLevel); | |
67 | 67 | |||
llvm::Value *Emit(); | 68 | 68 | llvm::Value *Emit(); | |
}; | 69 | 69 | }; | |
70 | 70 | |||
class ConditionalStmt : public Stmt | 71 | 71 | class ConditionalStmt : public Stmt | |
{ | 72 | 72 | { | |
protected: | 73 | 73 | protected: | |
Expr *test; | 74 | 74 | Expr *test; | |
Stmt *body; | 75 | 75 | Stmt *body; | |
76 | 76 | |||
public: | 77 | 77 | public: | |
ConditionalStmt() : Stmt(), test(NULL), body(NULL) {} | 78 | 78 | ConditionalStmt() : Stmt(), test(NULL), body(NULL) {} | |
ConditionalStmt(Expr *testExpr, Stmt *body); | 79 | 79 | ConditionalStmt(Expr *testExpr, Stmt *body); | |
80 | 80 | |||
llvm::Value *Emit(); | 81 | 81 | llvm::Value *Emit(); | |
}; | 82 | 82 | }; | |
83 | 83 | |||
class LoopStmt : public ConditionalStmt | 84 | 84 | class LoopStmt : public ConditionalStmt | |
{ | 85 | 85 | { | |
public: | 86 | 86 | public: | |
LoopStmt(Expr *testExpr, Stmt *body) | 87 | 87 | LoopStmt(Expr *testExpr, Stmt *body) | |
: ConditionalStmt(testExpr, body) {} | 88 | 88 | : ConditionalStmt(testExpr, body) {} | |
}; | 89 | 89 | }; | |
90 | 90 | |||
class ForStmt : public LoopStmt | 91 | 91 | class ForStmt : public LoopStmt | |
{ | 92 | 92 | { | |
protected: | 93 | 93 | protected: | |
Expr *init, *step; | 94 | 94 | Expr *init, *step; | |
95 | 95 | |||
public: | 96 | 96 | public: | |
ForStmt(Expr *init, Expr *test, Expr *step, Stmt *body); | 97 | 97 | ForStmt(Expr *init, Expr *test, Expr *step, Stmt *body); | |
const char *GetPrintNameForNode() { return "ForStmt"; } | 98 | 98 | const char *GetPrintNameForNode() { return "ForStmt"; } | |
void PrintChildren(int indentLevel); | 99 | 99 | void PrintChildren(int indentLevel); | |
100 | 100 | |||
llvm::Value *Emit(); | 101 | 101 | llvm::Value *Emit(); | |
}; | 102 | 102 | }; | |
103 | 103 | |||
class WhileStmt : public LoopStmt | 104 | 104 | class WhileStmt : public LoopStmt | |
{ | 105 | 105 | { | |
public: | 106 | 106 | public: | |
WhileStmt(Expr *test, Stmt *body) : LoopStmt(test, body) {} | 107 | 107 | WhileStmt(Expr *test, Stmt *body) : LoopStmt(test, body) {} | |
const char *GetPrintNameForNode() { return "WhileStmt"; } | 108 | 108 | const char *GetPrintNameForNode() { return "WhileStmt"; } | |
void PrintChildren(int indentLevel); | 109 | 109 | void PrintChildren(int indentLevel); | |
110 | 110 | |||
111 | llvm::Value *Emit(); | |||
}; | 111 | 112 | }; | |
112 | 113 | |||
class IfStmt : public ConditionalStmt | 113 | 114 | class IfStmt : public ConditionalStmt | |
{ | 114 | 115 | { | |
protected: | 115 | 116 | protected: | |
Stmt *elseBody; | 116 | 117 | Stmt *elseBody; | |
117 | 118 | |||
public: | 118 | 119 | public: | |
IfStmt() : ConditionalStmt(), elseBody(NULL) {} | 119 | 120 | IfStmt() : ConditionalStmt(), elseBody(NULL) {} | |
IfStmt(Expr *test, Stmt *thenBody, Stmt *elseBody); | 120 | 121 | IfStmt(Expr *test, Stmt *thenBody, Stmt *elseBody); | |
const char *GetPrintNameForNode() { return "IfStmt"; } | 121 | 122 | const char *GetPrintNameForNode() { return "IfStmt"; } | |
void PrintChildren(int indentLevel); | 122 | 123 | void PrintChildren(int indentLevel); | |
123 | 124 | |||
llvm::Value *Emit(); | 124 | 125 | llvm::Value *Emit(); | |
}; | 125 | 126 | }; | |
126 | 127 | |||
class IfStmtExprError : public IfStmt | 127 | 128 | class IfStmtExprError : public IfStmt | |
{ | 128 | 129 | { | |
public: | 129 | 130 | public: | |
IfStmtExprError() : IfStmt() { yyerror(this->GetPrintNameForNode()); } | 130 | 131 | IfStmtExprError() : IfStmt() { yyerror(this->GetPrintNameForNode()); } | |
const char *GetPrintNameForNode() { return "IfStmtExprError"; } | 131 | 132 | const char *GetPrintNameForNode() { return "IfStmtExprError"; } | |
}; | 132 | 133 | }; | |
133 | 134 | |||
class BreakStmt : public Stmt | 134 | 135 | class BreakStmt : public Stmt | |
{ | 135 | 136 | { | |
public: | 136 | 137 | public: | |
BreakStmt(yyltype loc) : Stmt(loc) {} | 137 | 138 | BreakStmt(yyltype loc) : Stmt(loc) {} | |
const char *GetPrintNameForNode() { return "BreakStmt"; } | 138 | 139 | const char *GetPrintNameForNode() { return "BreakStmt"; } | |
139 | 140 | |||
llvm::Value *Emit(); | 140 | 141 | llvm::Value *Emit(); | |
}; | 141 | 142 | }; | |
142 | 143 | |||
class ContinueStmt : public Stmt | 143 | 144 | class ContinueStmt : public Stmt | |
{ | 144 | 145 | { | |
public: | 145 | 146 | public: | |
ContinueStmt(yyltype loc) : Stmt(loc) {} | 146 | 147 | ContinueStmt(yyltype loc) : Stmt(loc) {} | |
const char *GetPrintNameForNode() { return "ContinueStmt"; } | 147 | 148 | const char *GetPrintNameForNode() { return "ContinueStmt"; } | |
148 | 149 | |||
llvm::Value *Emit(); | 149 | 150 | llvm::Value *Emit(); | |
}; | 150 | 151 | }; | |
151 | 152 | |||
class ReturnStmt : public Stmt | 152 | 153 | class ReturnStmt : public Stmt | |
{ | 153 | 154 | { | |
protected: | 154 | 155 | protected: | |
Expr *expr; | 155 | 156 | Expr *expr; | |
156 | 157 | |||
public: | 157 | 158 | public: | |
ReturnStmt(yyltype loc, Expr *expr = NULL); | 158 | 159 | ReturnStmt(yyltype loc, Expr *expr = NULL); | |
const char *GetPrintNameForNode() { return "ReturnStmt"; } | 159 | 160 | const char *GetPrintNameForNode() { return "ReturnStmt"; } | |
void PrintChildren(int indentLevel); | 160 | 161 | void PrintChildren(int indentLevel); | |
161 | 162 | |||
llvm::Value *Emit(); | 162 | 163 | llvm::Value *Emit(); | |
}; | 163 | 164 | }; | |
164 | 165 | |||
class SwitchLabel : public Stmt | 165 | 166 | class SwitchLabel : public Stmt | |
{ | 166 | 167 | { | |
protected: | 167 | 168 | protected: | |
Expr *label; | 168 | 169 | Expr *label; | |
Stmt *stmt; | 169 | 170 | Stmt *stmt; | |
170 | 171 | |||
public: | 171 | 172 | public: | |
SwitchLabel() { label = NULL; stmt = NULL; } | 172 | 173 | SwitchLabel() { label = NULL; stmt = NULL; } | |
SwitchLabel(Expr *label, Stmt *stmt); | 173 | 174 | SwitchLabel(Expr *label, Stmt *stmt); | |
SwitchLabel(Stmt *stmt); | 174 | 175 | SwitchLabel(Stmt *stmt); | |
void PrintChildren(int indentLevel); | 175 | 176 | void PrintChildren(int indentLevel); | |
176 | 177 | |||
llvm::Value *Emit(); | 177 | 178 | llvm::Value *Emit(); |