Commit eefa7b6f6111c27ae104e69c08ecdba654c9a55f
1 parent
1ff8269e79
Exists in
master
well
Showing 2 changed files with 44 additions and 2 deletions Inline Diff
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 | 184 | // init and branch to head | |
init->Emit(); | 185 | 185 | init->Emit(); | |
186 | 186 | |||
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | 187 | 187 | llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | |
188 | 188 | |||
// head | 189 | 189 | // head | |
irgen.SetBasicBlock(headBlock); | 190 | 190 | irgen.SetBasicBlock(headBlock); | |
condition = test->Emit(); | 191 | 191 | condition = test->Emit(); | |
if(!irgen.GetBasicBlock()->getTerminator()) | 192 | 192 | if(!irgen.GetBasicBlock()->getTerminator()) | |
{ | 193 | 193 | { | |
llvm::BranchInst::Create(bodyBlock, footBlock, condition, irgen.GetBasicBlock()); | 194 | 194 | llvm::BranchInst::Create(bodyBlock, footBlock, condition, irgen.GetBasicBlock()); | |
} | 195 | 195 | } | |
196 | 196 | |||
// body | 197 | 197 | // body | |
irgen.SetBasicBlock(bodyBlock); | 198 | 198 | irgen.SetBasicBlock(bodyBlock); | |
body->Emit(); | 199 | 199 | body->Emit(); | |
if(!irgen.GetBasicBlock()->getTerminator()) | 200 | 200 | if(!irgen.GetBasicBlock()->getTerminator()) | |
{ | 201 | 201 | { | |
llvm::BranchInst::Create(incBlock, irgen.GetBasicBlock()); | 202 | 202 | llvm::BranchInst::Create(incBlock, irgen.GetBasicBlock()); | |
} | 203 | 203 | } | |
204 | 204 | |||
// step | 205 | 205 | // step | |
irgen.SetBasicBlock(incBlock); | 206 | 206 | irgen.SetBasicBlock(incBlock); | |
step->Emit(); | 207 | 207 | step->Emit(); | |
if(!irgen.GetBasicBlock()->getTerminator()) | 208 | 208 | if(!irgen.GetBasicBlock()->getTerminator()) | |
{ | 209 | 209 | { | |
llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | 210 | 210 | llvm::BranchInst::Create(headBlock, irgen.GetBasicBlock()); | |
} | 211 | 211 | } | |
212 | 212 | |||
irgen.SetBasicBlock(footBlock); | 213 | 213 | irgen.SetBasicBlock(footBlock); | |
popScope(); | 214 | 214 | popScope(); | |
return NULL; | 215 | 215 | return NULL; | |
} | 216 | 216 | } | |
//while statement | 217 | 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; | |||
218 | 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 | ||||
249 | ||||
//if statement | 219 | 250 | //if statement | |
llvm::Value * IfStmt::Emit(){ | 220 | 251 | llvm::Value * IfStmt::Emit(){ | |
llvm::LLVMContext * context = irgen.GetContext(); | 221 | 252 | llvm::LLVMContext * context = irgen.GetContext(); | |
llvm::Function * func = irgen.GetFunction(); | 222 | 253 | llvm::Function * func = irgen.GetFunction(); | |
llvm::BasicBlock * elseBlock = NULL; | 223 | 254 | llvm::BasicBlock * elseBlock = NULL; | |
llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func); | 224 | 255 | llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func); | |
llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | 225 | 256 | llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | |
llvm::Value * val; | 226 | 257 | llvm::Value * val; | |
llvm::Value * condition = test->Emit(); | 227 | 258 | llvm::Value * condition = test->Emit(); | |
if(elseBody) | 228 | 259 | if(elseBody) | |
{ | 229 | 260 | { | |
elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func); | 230 | 261 | elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func); | |
} | 231 | 262 | } | |
232 | 263 | |||
val = llvm::BranchInst::Create(thenBlock, elseBody ? elseBlock : footBlock, condition, irgen.GetBasicBlock()); | 233 | 264 | val = llvm::BranchInst::Create(thenBlock, elseBody ? elseBlock : footBlock, condition, irgen.GetBasicBlock()); | |
pushScope(); | 234 | 265 | pushScope(); | |
irgen.SetBasicBlock(thenBlock); | 235 | 266 | irgen.SetBasicBlock(thenBlock); | |
body->Emit(); | 236 | 267 | body->Emit(); | |
237 | 268 | |||
if(!irgen.GetBasicBlock()->getTerminator()) | 238 | 269 | if(!irgen.GetBasicBlock()->getTerminator()) | |
{ | 239 | 270 | { | |
val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | 240 | 271 | val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | |
} | 241 | 272 | } | |
popScope(); | 242 | 273 | popScope(); | |
243 | 274 | |||
if(elseBody) | 244 | 275 | if(elseBody) | |
{ | 245 | 276 | { | |
pushScope(); | 246 | 277 | pushScope(); | |
irgen.SetBasicBlock(elseBlock); | 247 | 278 | irgen.SetBasicBlock(elseBlock); | |
elseBody->Emit(); | 248 | 279 | elseBody->Emit(); | |
249 | 280 | |||
if(!irgen.GetBasicBlock()->getTerminator()) | 250 | 281 | if(!irgen.GetBasicBlock()->getTerminator()) | |
{ | 251 | 282 | { | |
val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | 252 | 283 | val = llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock()); | |
} | 253 | 284 | } | |
popScope(); | 254 | 285 | popScope(); | |
} | 255 | 286 | } | |
irgen.SetBasicBlock(footBlock); | 256 | 287 | irgen.SetBasicBlock(footBlock); | |
return val; | 257 | 288 | return val; | |
} | 258 | 289 | } | |
259 | 290 | |||
llvm::Value * BreakStmt::Emit(){ | 260 | 291 | llvm::Value * BreakStmt::Emit(){ | |
return NULL; | 261 | 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()); | |||
} | 262 | 297 | } | |
263 | 298 | |||
llvm::Value * ContinueStmt::Emit(){ | 264 | 299 | llvm::Value * ContinueStmt::Emit(){ | |
return NULL; | 265 | 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()); | |||
} | 266 | 305 | } |
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(); |