Commit 98c5b35993332c80acfbb1f877deecb93afb3091

Authored by Austin Sun
1 parent e3f7f8a769
Exists in master

added irgen to node and the basic emit messages in stmt, only missing for,while,if

Showing 5 changed files with 146 additions and 41 deletions Inline Diff

CMakeLists.txt View file @ 98c5b35
File was created 1 cmake_minimum_required(VERSION 3.5)
2 project(cse_131pa4)
3
4 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
5
6 set(SOURCE_FILES
7 ast.cc
8 ast.h
9 ast_decl.cc
10 ast_decl.h
11 ast_expr.cc
12 ast_expr.h
13 ast_stmt.cc
14 ast_stmt.h
15 ast_type.cc
16 ast_type.h
17 errors.cc
18 errors.h
19 irgen.cc
20 irgen.h
21 list.h
22 location.h
23 main.cc
24 parser.h
25 scanner.h
26 symtable.cc
27 symtable.h
28 utility.cc
/* File: ast.cc 1 1 /* File: ast.cc
* ------------ 2 2 * ------------
*/ 3 3 */
4 4
#include "ast.h" 5 5 #include "ast.h"
#include "ast_type.h" 6 6 #include "ast_type.h"
#include "ast_decl.h" 7 7 #include "ast_decl.h"
#include "symtable.h" 8 8 #include "symtable.h"
#include <string.h> // strdup 9 9 #include <string.h> // strdup
#include <stdio.h> // printf 10 10 #include <stdio.h> // printf
11 11
12 12
Node::Node(yyltype loc) { 13 13 Node::Node(yyltype loc) {
location = new yyltype(loc); 14 14 location = new yyltype(loc);
parent = NULL; 15 15 parent = NULL;
} 16 16 }
17 17
Node::Node() { 18 18 Node::Node() {
location = NULL; 19 19 location = NULL;
parent = NULL; 20 20 parent = NULL;
} 21 21 }
22 22
/* The Print method is used to print the parse tree nodes. 23 23 /* The Print method is used to print the parse tree nodes.
* If this node has a location (most nodes do, but some do not), it 24 24 * If this node has a location (most nodes do, but some do not), it
* will first print the line number to help you match the parse tree 25 25 * will first print the line number to help you match the parse tree
* back to the source text. It then indents the proper number of levels 26 26 * back to the source text. It then indents the proper number of levels
* and prints the "print name" of the node. It then will invoke the 27 27 * and prints the "print name" of the node. It then will invoke the
* virtual function PrintChildren which is expected to print the 28 28 * virtual function PrintChildren which is expected to print the
* internals of the node (itself & children) as appropriate. 29 29 * internals of the node (itself & children) as appropriate.
*/ 30 30 */
void Node::Print(int indentLevel, const char *label) { 31 31 void Node::Print(int indentLevel, const char *label) {
const int numSpaces = 3; 32 32 const int numSpaces = 3;
printf("\n"); 33 33 printf("\n");
if (GetLocation()) 34 34 if (GetLocation())
printf("%*d", numSpaces, GetLocation()->first_line); 35 35 printf("%*d", numSpaces, GetLocation()->first_line);
else 36 36 else
printf("%*s", numSpaces, ""); 37 37 printf("%*s", numSpaces, "");
printf("%*s%s%s: ", indentLevel*numSpaces, "", 38 38 printf("%*s%s%s: ", indentLevel*numSpaces, "",
label? label : "", GetPrintNameForNode()); 39 39 label? label : "", GetPrintNameForNode());
PrintChildren(indentLevel); 40 40 PrintChildren(indentLevel);
} 41 41 }
42 42
Identifier::Identifier(yyltype loc, const char *n) : Node(loc) { 43 43 Identifier::Identifier(yyltype loc, const char *n) : Node(loc) {
name = strdup(n); 44 44 name = strdup(n);
} 45 45 }
46 46
void Identifier::PrintChildren(int indentLevel) { 47 47 void Identifier::PrintChildren(int indentLevel) {
printf("%s", name); 48 48 printf("%s", name);
} 49 49 }
50 50
/*------------------------------------------------------------------------------------ 51 51 /*------------------------------------------------------------------------------------
* Symbol Table Information 52 52 * Symbol Table Information
*----------------------------------------------------------------------------------*/ 53 53 *----------------------------------------------------------------------------------*/
SymbolTable symbols; 54
55
pair<Decl*,llvm::Value *> findSymbol(string s) { 56 54 pair<Decl*,llvm::Value *> findSymbol(string s) {
for(int i = symbols.size() - 1; i >= 0; i--) { 57 55 for(int i = symbols.size() - 1; i >= 0; i--) {
if(symbols[i].count(s) > 0) return symbols[i][s]; 58 56 if(symbols[i].count(s) > 0) return symbols[i][s];
} 59 57 }
return make_pair<Decl*,llvm::Value *>(NULL,NULL); 60 58 return make_pair<Decl*,llvm::Value *>(NULL,NULL);
} 61 59 }
62 60
pair<Decl*,llvm::Value *> findSymbol(Decl* d) { 63 61 pair<Decl*,llvm::Value *> findSymbol(Decl* d) {
string s(d->GetIdentifier()->GetName()); 64 62 string s(d->GetIdentifier()->GetName());
return findSymbol(s); 65 63 return findSymbol(s);
} 66 64 }
67 65
bool isInCurrentScope(string s) { 68 66 bool isInCurrentScope(string s) {
if(symbols.size() == 0) return false; 69 67 if(symbols.size() == 0) return false;
return symbols[symbols.size()-1].count(s); 70 68 return symbols[symbols.size()-1].count(s);
} 71 69 }
72 70
bool isInCurrentScope(Decl* d) { 73 71 bool isInCurrentScope(Decl* d) {
string s(d->GetIdentifier()->GetName()); 74 72 string s(d->GetIdentifier()->GetName());
return isInCurrentScope(s); 75 73 return isInCurrentScope(s);
} 76 74 }
77 75
bool isInScope(string s) { 78 76 bool isInScope(string s) {
pair<Decl*,llvm::Value *> tmp = findSymbol(s); 79 77 pair<Decl*, llvm::Value *> tmp = findSymbol(s);
return tmp.first != NULL; 80 78 return tmp.first != NULL;
} 81 79 }
82 80
bool isInScope(Decl* d) { 83 81 bool isInScope(Decl* d) {
string s(d->GetIdentifier()->GetName()); 84 82 string s(d->GetIdentifier()->GetName());
/** 1 1 /**
* File: ast.h 2 2 * File: ast.h
* ----------- 3 3 * -----------
* This file defines the abstract base class Node and the concrete 4 4 * This file defines the abstract base class Node and the concrete
* Identifier and Error node subclasses that are used through the tree as 5 5 * Identifier and Error node subclasses that are used through the tree as
* leaf nodes. A parse tree is a hierarchical collection of ast nodes (or, 6 6 * leaf nodes. A parse tree is a hierarchical collection of ast nodes (or,
* more correctly, of instances of concrete subclassses such as VarDecl, 7 7 * more correctly, of instances of concrete subclassses such as VarDecl,
* ForStmt, and AssignExpr). 8 8 * ForStmt, and AssignExpr).
* 9 9 *
* Location: Each node maintains its lexical location (line and columns in 10 10 * Location: Each node maintains its lexical location (line and columns in
* file), that location can be NULL for those nodes that don't care/use 11 11 * file), that location can be NULL for those nodes that don't care/use
* locations. The location is typcially set by the node constructor. The 12 12 * locations. The location is typcially set by the node constructor. The
* location is used to provide the context when reporting semantic errors. 13 13 * location is used to provide the context when reporting semantic errors.
* 14 14 *
* Parent: Each node has a pointer to its parent. For a Program node, the 15 15 * Parent: Each node has a pointer to its parent. For a Program node, the
* parent is NULL, for all other nodes it is the pointer to the node one level 16 16 * parent is NULL, for all other nodes it is the pointer to the node one level
* up in the parse tree. The parent is not set in the constructor (during a 17 17 * up in the parse tree. The parent is not set in the constructor (during a
* bottom-up parse we don't know the parent at the time of construction) but 18 18 * bottom-up parse we don't know the parent at the time of construction) but
* instead we wait until assigning the children into the parent node and then 19 19 * instead we wait until assigning the children into the parent node and then
* set up links in both directions. The parent link is typically not used 20 20 * set up links in both directions. The parent link is typically not used
* during parsing, but is more important in later phases. 21 21 * during parsing, but is more important in later phases.
* 22 22 *
* Printing: This functionaility is saved from pp2 of the node classes to 23 23 * Printing: This functionaility is saved from pp2 of the node classes to
* print out the AST tree for debugging purpose. Each node class is 24 24 * print out the AST tree for debugging purpose. Each node class is
* responsible for printing itself/children by overriding the virtual 25 25 * responsible for printing itself/children by overriding the virtual
* PrintChildren() and GetPrintNameForNode() methods. All the classes we 26 26 * PrintChildren() and GetPrintNameForNode() methods. All the classes we
* provide already implement these methods, so your job is to construct the 27 27 * provide already implement these methods, so your job is to construct the
* nodes and wire them up during parsing. Once that's done, printing is a snap! 28 28 * nodes and wire them up during parsing. Once that's done, printing is a snap!
29 29
* Semantic analysis: For pp3 you are adding "Check" behavior to the ast 30 30 * Semantic analysis: For pp3 you are adding "Check" behavior to the ast
* node classes. Your semantic analyzer should do an inorder walk on the 31 31 * node classes. Your semantic analyzer should do an inorder walk on the
* parse tree, and when visiting each node, verify the particular 32 32 * parse tree, and when visiting each node, verify the particular
* semantic rules that apply to that construct. 33 33 * semantic rules that apply to that construct.
34 34
*/ 35 35 */
36 36
37 #pragma clang diagnostic push
38 #pragma ide diagnostic ignored "CannotResolve"
#ifndef _H_ast 37 39 #ifndef _H_ast
#define _H_ast 38 40 #define _H_ast
39 41
#include <stdlib.h> // for NULL 40 42 #include <stdlib.h> // for NULL
#include "irgen.h" 41 43 #include "irgen.h"
#include "location.h" 42 44 #include "location.h"
#include <iostream> 43 45 #include <iostream>
#include <vector> 44 46 #include <vector>
#include <map> 45 47 #include <map>
#include <algorithm> 46 48 #include <algorithm>
49 //LLVM STUFF
50 #include "llvm/IR/Module.h"
51 #include "llvm/IR/LLVMContext.h"
52 #include "llvm/IR/Instructions.h"
53 #include "llvm/IR/Constants.h"
47 54
using namespace std; 48 55 using namespace std;
49 56
class SymbolTable; 50 57 class SymbolTable;
class MyStack; 51 58 class MyStack;
class FnDecl; 52 59 class FnDecl;
class Decl; 53 60 class Decl;
54 61
class Node { 55 62 class Node {
protected: 56 63 protected:
yyltype *location; 57 64 yyltype *location;
Node *parent; 58 65 Node *parent;
59 66
public: 60 67 public:
Node(yyltype loc); 61 68 Node(yyltype loc);
Node(); 62 69 Node();
70 static IRGenerator * irGen;
71 SymbolTable symbols;
virtual ~Node() {} 63 72 virtual ~Node() {}
64 73
yyltype *GetLocation() { return location; } 65 74 yyltype *GetLocation() { return location; }
void SetParent(Node *p) { parent = p; } 66 75 void SetParent(Node *p) { parent = p; }
Node *GetParent() { return parent; } 67 76 Node *GetParent() { return parent; }
68 77
virtual const char *GetPrintNameForNode() = 0; 69 78 virtual const char *GetPrintNameForNode() = 0;
70 79
// Print() is deliberately _not_ virtual 71 80 // Print() is deliberately _not_ virtual
// subclasses should override PrintChildren() instead 72 81 // subclasses should override PrintChildren() instead
void Print(int indentLevel, const char *label = NULL); 73 82 void Print(int indentLevel, const char *label = NULL);
virtual void PrintChildren(int indentLevel) {} 74 83 virtual void PrintChildren(int indentLevel) {}
75 84
virtual llvm::Value* Emit() { return NULL; } 76 85 virtual llvm::Value* Emit() { return NULL; }
}; 77 86 };
78 87
79 88
class Identifier : public Node 80 89 class Identifier : public Node
{ 81 90 {
protected: 82 91 protected:
char *name; 83 92 char *name;
84 93
public: 85 94 public:
Identifier(yyltype loc, const char *name); 86 95 Identifier(yyltype loc, const char *name);
const char *GetPrintNameForNode() { return "Identifier"; } 87 96 const char *GetPrintNameForNode() { return "Identifier"; }
char *GetName() const { return name; } 88 97 char *GetName() const { return name; }
void PrintChildren(int indentLevel); 89 98 void PrintChildren(int indentLevel);
friend ostream& operator<<(ostream& out, Identifier *id) { return out << id->name; } 90 99 friend ostream& operator<<(ostream& out, Identifier *id) { return out << id->name; }
}; 91 100 };
92 101
93 102
// This node class is designed to represent a portion of the tree that 94 103 // This node class is designed to represent a portion of the tree that
// encountered syntax errors during parsing. The partial completed tree 95 104 // encountered syntax errors during parsing. The partial completed tree
// is discarded along with the states being popped, and an instance of 96 105 // is discarded along with the states being popped, and an instance of
// the Error class can stand in as the placeholder in the parse tree 97 106 // the Error class can stand in as the placeholder in the parse tree
// when your parser can continue after an error. 98 107 // when your parser can continue after an error.
class Error : public Node 99 108 class Error : public Node
{ 100 109 {
public: 101 110 public:
Error() : Node() {} 102 111 Error() : Node() {}
const char *GetPrintNameForNode() { return "Error"; } 103 112 const char *GetPrintNameForNode() { return "Error"; }
}; 104 113 };
/*------------------------------------------------------------------------------------ 105 114 /*------------------------------------------------------------------------------------
* Symbol Table Information 106 115 * Symbol Table Information
*----------------------------------------------------------------------------------*/ 107 116 *----------------------------------------------------------------------------------*/
/* 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 }
25 25 //pls work
llvm::Value* Program::Emit() { 26 26 llvm::Value* Program::Emit() {
// TODO: 27 27 llvm::Module *module = irGen->GetOrCreateModule("swag");
// This is just a reference for you to get started 28 28 pushScope();
// 29 29 for (int i = 0; i < decls->NumElements(); i++){
// You can use this as a template and create Emit() function 30 30 decls->Nth(i)->Emit();
// for individual node to fill in the module structure and instructions. 31 31 }
// 32 32 popScope();
//IRGenerator irgen; 33
llvm::Module *mod = irgen.GetOrCreateModule("Name_the_Module.bc"); 34
35 33
// create a function signature 36 34 module->dump();
std::vector<llvm::Type *> argTypes; 37 35 llvm::WriteBitcodeToFile(module, llvm::outs());
llvm::Type *intTy = irgen.GetIntType(); 38 36 return NULL;
argTypes.push_back(intTy); 39
llvm::ArrayRef<llvm::Type *> argArray(argTypes); 40
llvm::FunctionType *funcTy = llvm::FunctionType::get(intTy, argArray, false); 41
42
// llvm::Function *f = llvm::cast<llvm::Function>(mod->getOrInsertFunction("foo", intTy, intTy, (Type *)0)); 43
llvm::Function *f = llvm::cast<llvm::Function>(mod->getOrInsertFunction("Name_the_function", funcTy)); 44
llvm::Argument *arg = f->arg_begin(); 45
arg->setName("x"); 46
47
// insert a block into the runction 48
llvm::LLVMContext *context = irgen.GetContext(); 49
llvm::BasicBlock *bb = llvm::BasicBlock::Create(*context, "entry", f); 50
51
// create a return instruction 52
llvm::Value *val = llvm::ConstantInt::get(intTy, 1); 53
llvm::Value *sum = llvm::BinaryOperator::CreateAdd(arg, val, "", bb); 54
llvm::ReturnInst::Create(*context, sum, bb); 55
56
// write the BC into standard output 57
llvm::WriteBitcodeToFile(mod, llvm::outs()); 58
} 59 37 }
60 38
StmtBlock::StmtBlock(List<VarDecl*> *d, List<Stmt*> *s) { 61 39 StmtBlock::StmtBlock(List<VarDecl*> *d, List<Stmt*> *s) {
Assert(d != NULL && s != NULL); 62 40 Assert(d != NULL && s != NULL);
(decls=d)->SetParentAll(this); 63 41 (decls=d)->SetParentAll(this);
(stmts=s)->SetParentAll(this); 64 42 (stmts=s)->SetParentAll(this);
} 65 43 }
66 44
void StmtBlock::PrintChildren(int indentLevel) { 67 45 void StmtBlock::PrintChildren(int indentLevel) {
decls->PrintAll(indentLevel+1); 68 46 decls->PrintAll(indentLevel+1);
stmts->PrintAll(indentLevel+1); 69 47 stmts->PrintAll(indentLevel+1);
} 70 48 }
71 49
DeclStmt::DeclStmt(Decl *d) { 72 50 DeclStmt::DeclStmt(Decl *d) {
Assert(d != NULL); 73 51 Assert(d != NULL);
(decl=d)->SetParent(this); 74 52 (decl=d)->SetParent(this);
} 75 53 }
76 54
void DeclStmt::PrintChildren(int indentLevel) { 77 55 void DeclStmt::PrintChildren(int indentLevel) {
decl->Print(indentLevel+1); 78 56 decl->Print(indentLevel+1);
} 79 57 }
80 58
ConditionalStmt::ConditionalStmt(Expr *t, Stmt *b) { 81 59 ConditionalStmt::ConditionalStmt(Expr *t, Stmt *b) {
Assert(t != NULL && b != NULL); 82 60 Assert(t != NULL && b != NULL);
(test=t)->SetParent(this); 83 61 (test=t)->SetParent(this);
(body=b)->SetParent(this); 84 62 (body=b)->SetParent(this);
} 85 63 }
86 64
ForStmt::ForStmt(Expr *i, Expr *t, Expr *s, Stmt *b): LoopStmt(t, b) { 87 65 ForStmt::ForStmt(Expr *i, Expr *t, Expr *s, Stmt *b): LoopStmt(t, b) {
Assert(i != NULL && t != NULL && b != NULL); 88 66 Assert(i != NULL && t != NULL && b != NULL);
(init=i)->SetParent(this); 89 67 (init=i)->SetParent(this);
step = s; 90 68 step = s;
if ( s ) 91 69 if ( s )
(step=s)->SetParent(this); 92 70 (step=s)->SetParent(this);
} 93 71 }
94 72
void ForStmt::PrintChildren(int indentLevel) { 95 73 void ForStmt::PrintChildren(int indentLevel) {
init->Print(indentLevel+1, "(init) "); 96 74 init->Print(indentLevel+1, "(init) ");
test->Print(indentLevel+1, "(test) "); 97 75 test->Print(indentLevel+1, "(test) ");
if ( step ) 98 76 if ( step )
step->Print(indentLevel+1, "(step) "); 99 77 step->Print(indentLevel+1, "(step) ");
body->Print(indentLevel+1, "(body) "); 100 78 body->Print(indentLevel+1, "(body) ");
} 101 79 }
102 80
void WhileStmt::PrintChildren(int indentLevel) { 103 81 void WhileStmt::PrintChildren(int indentLevel) {
test->Print(indentLevel+1, "(test) "); 104 82 test->Print(indentLevel+1, "(test) ");
body->Print(indentLevel+1, "(body) "); 105 83 body->Print(indentLevel+1, "(body) ");
} 106 84 }
107 85
IfStmt::IfStmt(Expr *t, Stmt *tb, Stmt *eb): ConditionalStmt(t, tb) { 108 86 IfStmt::IfStmt(Expr *t, Stmt *tb, Stmt *eb): ConditionalStmt(t, tb) {
Assert(t != NULL && tb != NULL); // else can be NULL 109 87 Assert(t != NULL && tb != NULL); // else can be NULL
elseBody = eb; 110 88 elseBody = eb;
if (elseBody) elseBody->SetParent(this); 111 89 if (elseBody) elseBody->SetParent(this);
} 112 90 }
113 91
void IfStmt::PrintChildren(int indentLevel) { 114 92 void IfStmt::PrintChildren(int indentLevel) {
if (test) test->Print(indentLevel+1, "(test) "); 115 93 if (test) test->Print(indentLevel+1, "(test) ");
if (body) body->Print(indentLevel+1, "(then) "); 116 94 if (body) body->Print(indentLevel+1, "(then) ");
if (elseBody) elseBody->Print(indentLevel+1, "(else) "); 117 95 if (elseBody) elseBody->Print(indentLevel+1, "(else) ");
} 118 96 }
119 97
120 98
ReturnStmt::ReturnStmt(yyltype loc, Expr *e) : Stmt(loc) { 121 99 ReturnStmt::ReturnStmt(yyltype loc, Expr *e) : Stmt(loc) {
expr = e; 122 100 expr = e;
if (e != NULL) expr->SetParent(this); 123 101 if (e != NULL) expr->SetParent(this);
} 124 102 }
125 103
void ReturnStmt::PrintChildren(int indentLevel) { 126 104 void ReturnStmt::PrintChildren(int indentLevel) {
if ( expr ) 127 105 if ( expr )
expr->Print(indentLevel+1); 128 106 expr->Print(indentLevel+1);
} 129 107 }
130 108
SwitchLabel::SwitchLabel(Expr *l, Stmt *s) { 131 109 SwitchLabel::SwitchLabel(Expr *l, Stmt *s) {
Assert(l != NULL && s != NULL); 132 110 Assert(l != NULL && s != NULL);
(label=l)->SetParent(this); 133 111 (label=l)->SetParent(this);
(stmt=s)->SetParent(this); 134 112 (stmt=s)->SetParent(this);
} 135 113 }
136 114
SwitchLabel::SwitchLabel(Stmt *s) { 137 115 SwitchLabel::SwitchLabel(Stmt *s) {
Assert(s != NULL); 138 116 Assert(s != NULL);
label = NULL; 139 117 label = NULL;
(stmt=s)->SetParent(this); 140 118 (stmt=s)->SetParent(this);
} 141 119 }
142 120
void SwitchLabel::PrintChildren(int indentLevel) { 143 121 void SwitchLabel::PrintChildren(int indentLevel) {
if (label) label->Print(indentLevel+1); 144 122 if (label) label->Print(indentLevel+1);
if (stmt) stmt->Print(indentLevel+1); 145 123 if (stmt) stmt->Print(indentLevel+1);
} 146 124 }
147 125
SwitchStmt::SwitchStmt(Expr *e, List<Stmt *> *c, Default *d) { 148 126 SwitchStmt::SwitchStmt(Expr *e, List<Stmt *> *c, Default *d) {
Assert(e != NULL && c != NULL && c->NumElements() != 0 ); 149 127 Assert(e != NULL && c != NULL && c->NumElements() != 0 );
(expr=e)->SetParent(this); 150 128 (expr=e)->SetParent(this);
(cases=c)->SetParentAll(this); 151 129 (cases=c)->SetParentAll(this);
def = d; 152 130 def = d;
if (def) def->SetParent(this); 153 131 if (def) def->SetParent(this);
} 154 132 }
155 133
void SwitchStmt::PrintChildren(int indentLevel) { 156 134 void SwitchStmt::PrintChildren(int indentLevel) {
if (expr) expr->Print(indentLevel+1); 157 135 if (expr) expr->Print(indentLevel+1);
if (cases) cases->PrintAll(indentLevel+1); 158 136 if (cases) cases->PrintAll(indentLevel+1);
if (def) def->Print(indentLevel+1); 159 137 if (def) def->Print(indentLevel+1);
138 }
139
140 //rest of the emits
141 llvm::Value * StmtBlock::Emit(){
142 pushScope();
143 for (int i = 0; i < decls->NumElements(); i++){
144 decls->Nth(i)->Emit();
145 }
146 for (int i = 0; i < stmts->NumElements(); i++){
147 stmts->Nth(i)->Emit();
148 }
149
150 //TODO
151
152 popScope();
153 return NULL;
154 }
155
156 llvm::Value * DeclStmt::Emit(){
157 llvm::Value * val;
158 if (VarDecl * vd = dynamic_cast<VarDecl*>(this->decl)){
159 val = vd->Emit();
160 }
161 else if (FnDecl * fd = dynamic_cast<FnDecl*>(this->decl)){
162 val = fd->Emit();
163 }
164 else{
165 val = NULL;
166 }
167 return val;
168 }
169
170 llvm::Value * ConditionalStmt::Emit(){
171 return NULL;
172 }
173 //for statement
174 //while statement
175 //if statement
176
177 llvm::Value * BreakStmt::Emit(){
178 return NULL;
179 }
180
181 llvm::Value * ContinueStmt::Emit(){
182 return NULL;
183 }
184
185 //Not sure
186 llvm::Value * ReturnStmt::Emit(){
187 llvm::Value * val;
188 llvm::LLVMContext * context = irGen->GetContext();
189 if (expr){
190 llvm::Value * retVal = expr->Emit();
191 retVal = llvm::ReturnInst::Create(*context, retVal, irGen->GetBasicBlock());
192 return retVal;
193 }
194 val = llvm::ReturnInst::Create(*context, irGen->GetBasicBlock());
/* 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);
55
56 llvm::Value *Emit();
}; 55 57 };
56 58
class DeclStmt: public Stmt 57 59 class DeclStmt: public Stmt
{ 58 60 {
protected: 59 61 protected:
Decl* decl; 60 62 Decl* decl;
61 63
public: 62 64 public:
DeclStmt(Decl *d); 63 65 DeclStmt(Decl *d);
const char *GetPrintNameForNode() { return "DeclStmt"; } 64 66 const char *GetPrintNameForNode() { return "DeclStmt"; }
void PrintChildren(int indentLevel); 65 67 void PrintChildren(int indentLevel);
66 68
69 llvm::Value *Emit();
}; 67 70 };
68 71
class ConditionalStmt : public Stmt 69 72 class ConditionalStmt : public Stmt
{ 70 73 {
protected: 71 74 protected:
Expr *test; 72 75 Expr *test;
Stmt *body; 73 76 Stmt *body;
74 77
public: 75 78 public:
ConditionalStmt() : Stmt(), test(NULL), body(NULL) {} 76 79 ConditionalStmt() : Stmt(), test(NULL), body(NULL) {}
ConditionalStmt(Expr *testExpr, Stmt *body); 77 80 ConditionalStmt(Expr *testExpr, Stmt *body);
78 81
82 llvm::Value *Emit();
}; 79 83 };
80 84
class LoopStmt : public ConditionalStmt 81 85 class LoopStmt : public ConditionalStmt
{ 82 86 {
public: 83 87 public:
LoopStmt(Expr *testExpr, Stmt *body) 84 88 LoopStmt(Expr *testExpr, Stmt *body)
: ConditionalStmt(testExpr, body) {} 85 89 : ConditionalStmt(testExpr, body) {}
}; 86 90 };
87 91
class ForStmt : public LoopStmt 88 92 class ForStmt : public LoopStmt
{ 89 93 {
protected: 90 94 protected:
Expr *init, *step; 91 95 Expr *init, *step;
92 96
public: 93 97 public:
ForStmt(Expr *init, Expr *test, Expr *step, Stmt *body); 94 98 ForStmt(Expr *init, Expr *test, Expr *step, Stmt *body);
const char *GetPrintNameForNode() { return "ForStmt"; } 95 99 const char *GetPrintNameForNode() { return "ForStmt"; }
void PrintChildren(int indentLevel); 96 100 void PrintChildren(int indentLevel);
97 101
}; 98 102 };
99 103
class WhileStmt : public LoopStmt 100 104 class WhileStmt : public LoopStmt
{ 101 105 {
public: 102 106 public:
WhileStmt(Expr *test, Stmt *body) : LoopStmt(test, body) {} 103 107 WhileStmt(Expr *test, Stmt *body) : LoopStmt(test, body) {}
const char *GetPrintNameForNode() { return "WhileStmt"; } 104 108 const char *GetPrintNameForNode() { return "WhileStmt"; }
void PrintChildren(int indentLevel); 105 109 void PrintChildren(int indentLevel);
106 110
}; 107 111 };
108 112
class IfStmt : public ConditionalStmt 109 113 class IfStmt : public ConditionalStmt
{ 110 114 {
protected: 111 115 protected:
Stmt *elseBody; 112 116 Stmt *elseBody;
113 117
public: 114 118 public:
IfStmt() : ConditionalStmt(), elseBody(NULL) {} 115 119 IfStmt() : ConditionalStmt(), elseBody(NULL) {}
IfStmt(Expr *test, Stmt *thenBody, Stmt *elseBody); 116 120 IfStmt(Expr *test, Stmt *thenBody, Stmt *elseBody);
const char *GetPrintNameForNode() { return "IfStmt"; } 117 121 const char *GetPrintNameForNode() { return "IfStmt"; }
void PrintChildren(int indentLevel); 118 122 void PrintChildren(int indentLevel);
119 123
}; 120 124 };
121 125
class IfStmtExprError : public IfStmt 122 126 class IfStmtExprError : public IfStmt
{ 123 127 {
public: 124 128 public:
IfStmtExprError() : IfStmt() { yyerror(this->GetPrintNameForNode()); } 125 129 IfStmtExprError() : IfStmt() { yyerror(this->GetPrintNameForNode()); }
const char *GetPrintNameForNode() { return "IfStmtExprError"; } 126 130 const char *GetPrintNameForNode() { return "IfStmtExprError"; }
}; 127 131 };
128 132
class BreakStmt : public Stmt 129 133 class BreakStmt : public Stmt
{ 130 134 {
public: 131 135 public:
BreakStmt(yyltype loc) : Stmt(loc) {} 132 136 BreakStmt(yyltype loc) : Stmt(loc) {}
const char *GetPrintNameForNode() { return "BreakStmt"; } 133 137 const char *GetPrintNameForNode() { return "BreakStmt"; }
134 138
139 llvm::Value *Emit();
}; 135 140 };
136 141
class ContinueStmt : public Stmt 137 142 class ContinueStmt : public Stmt
{ 138 143 {
public: 139 144 public:
ContinueStmt(yyltype loc) : Stmt(loc) {} 140 145 ContinueStmt(yyltype loc) : Stmt(loc) {}
const char *GetPrintNameForNode() { return "ContinueStmt"; } 141 146 const char *GetPrintNameForNode() { return "ContinueStmt"; }
142 147
148 llvm::Value *Emit();
}; 143 149 };
144 150
class ReturnStmt : public Stmt 145 151 class ReturnStmt : public Stmt
{ 146 152 {
protected: 147 153 protected:
Expr *expr; 148 154 Expr *expr;
149 155
public: 150 156 public:
ReturnStmt(yyltype loc, Expr *expr = NULL); 151 157 ReturnStmt(yyltype loc, Expr *expr = NULL);
const char *GetPrintNameForNode() { return "ReturnStmt"; } 152 158 const char *GetPrintNameForNode() { return "ReturnStmt"; }
void PrintChildren(int indentLevel); 153 159 void PrintChildren(int indentLevel);
154 160
161 llvm::Value *Emit();
}; 155 162 };
156 163
class SwitchLabel : public Stmt 157 164 class SwitchLabel : public Stmt
{ 158 165 {
protected: 159 166 protected:
Expr *label; 160 167 Expr *label;
Stmt *stmt; 161 168 Stmt *stmt;
162 169
public: 163 170 public:
SwitchLabel() { label = NULL; stmt = NULL; } 164 171 SwitchLabel() { label = NULL; stmt = NULL; }
SwitchLabel(Expr *label, Stmt *stmt); 165 172 SwitchLabel(Expr *label, Stmt *stmt);
SwitchLabel(Stmt *stmt); 166 173 SwitchLabel(Stmt *stmt);
void PrintChildren(int indentLevel); 167 174 void PrintChildren(int indentLevel);
168 175
176 llvm::Value *Emit();
}; 169 177 };
170 178