Commit e3f7f8a769534ba879c06192a44f65b245112578

Authored by Austin Sun
Exists in master

Merge branch 'master' of git.ucsd.edu:acs008/cse131-pa4

Showing 5 changed files Inline Diff

/* 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);
/* File: ast_expr.h 1 1 /* File: ast_expr.h
* ---------------- 2 2 * ----------------
* The Expr class and its subclasses are used to represent 3 3 * The Expr class and its subclasses are used to represent
* expressions in the parse tree. For each expression in the 4 4 * expressions in the parse tree. For each expression in the
* language (add, call, New, etc.) there is a corresponding 5 5 * language (add, call, New, etc.) there is a corresponding
* node class for that construct. 6 6 * node class for that construct.
* 7 7 *
* pp3: You will need to extend the Expr classes to implement 8 8 * pp3: You will need to extend the Expr classes to implement
* semantic analysis for rules pertaining to expressions. 9 9 * semantic analysis for rules pertaining to expressions.
*/ 10 10 */
11 11
12 12
#ifndef _H_ast_expr 13 13 #ifndef _H_ast_expr
#define _H_ast_expr 14 14 #define _H_ast_expr
15 15
#include "ast.h" 16 16 #include "ast.h"
#include "ast_stmt.h" 17 17 #include "ast_stmt.h"
#include "list.h" 18 18 #include "list.h"
#include "ast_type.h" 19 19 #include "ast_type.h"
20 20
void yyerror(const char *msg); 21 21 void yyerror(const char *msg);
22 22
class Expr : public Stmt 23 23 class Expr : public Stmt
{ 24 24 {
public: 25 25 public:
Expr(yyltype loc) : Stmt(loc) {} 26 26 Expr(yyltype loc) : Stmt(loc) {}
Expr() : Stmt() {} 27 27 Expr() : Stmt() {}
28 28
friend std::ostream& operator<< (std::ostream& stream, Expr * expr) { 29 29 friend std::ostream& operator<< (std::ostream& stream, Expr * expr) {
return stream << expr->GetPrintNameForNode(); 30 30 return stream << expr->GetPrintNameForNode();
} 31 31 }
}; 32 32 };
33 33
class ExprError : public Expr 34 34 class ExprError : public Expr
{ 35 35 {
public: 36 36 public:
ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); } 37 37 ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); }
const char *GetPrintNameForNode() { return "ExprError"; } 38 38 const char *GetPrintNameForNode() { return "ExprError"; }
}; 39 39 };
40 40
/* This node type is used for those places where an expression is optional. 41 41 /* This node type is used for those places where an expression is optional.
* We could use a NULL pointer, but then it adds a lot of checking for 42 42 * We could use a NULL pointer, but then it adds a lot of checking for
* NULL. By using a valid, but no-op, node, we save that trouble */ 43 43 * NULL. By using a valid, but no-op, node, we save that trouble */
class EmptyExpr : public Expr 44 44 class EmptyExpr : public Expr
{ 45 45 {
public: 46 46 public:
const char *GetPrintNameForNode() { return "Empty"; } 47 47 const char *GetPrintNameForNode() { return "Empty"; }
}; 48 48 };
49 49
class IntConstant : public Expr 50 50 class IntConstant : public Expr
{ 51 51 {
protected: 52 52 protected:
int value; 53 53 int value;
54 54
public: 55 55 public:
IntConstant(yyltype loc, int val); 56 56 IntConstant(yyltype loc, int val);
const char *GetPrintNameForNode() { return "IntConstant"; } 57 57 const char *GetPrintNameForNode() { return "IntConstant"; }
void PrintChildren(int indentLevel); 58 58 void PrintChildren(int indentLevel);
59 llvm::Value* Emit();
}; 59 60 };
60 61
class FloatConstant: public Expr 61 62 class FloatConstant: public Expr
{ 62 63 {
protected: 63 64 protected:
double value; 64 65 double value;
65 66
public: 66 67 public:
FloatConstant(yyltype loc, double val); 67 68 FloatConstant(yyltype loc, double val);
const char *GetPrintNameForNode() { return "FloatConstant"; } 68 69 const char *GetPrintNameForNode() { return "FloatConstant"; }
void PrintChildren(int indentLevel); 69 70 void PrintChildren(int indentLevel);
71 llvm::Value* Emit();
}; 70 72 };
71 73
class BoolConstant : public Expr 72 74 class BoolConstant : public Expr
{ 73 75 {
protected: 74 76 protected:
bool value; 75 77 bool value;
76 78
public: 77 79 public:
BoolConstant(yyltype loc, bool val); 78 80 BoolConstant(yyltype loc, bool val);
const char *GetPrintNameForNode() { return "BoolConstant"; } 79 81 const char *GetPrintNameForNode() { return "BoolConstant"; }
void PrintChildren(int indentLevel); 80 82 void PrintChildren(int indentLevel);
83 llvm::Value* Emit();
}; 81 84 };
82 85
class VarExpr : public Expr 83 86 class VarExpr : public Expr
{ 84 87 {
protected: 85 88 protected:
Identifier *id; 86 89 Identifier *id;
87 90
public: 88 91 public:
VarExpr(yyltype loc, Identifier *id); 89 92 VarExpr(yyltype loc, Identifier *id);
const char *GetPrintNameForNode() { return "VarExpr"; } 90 93 const char *GetPrintNameForNode() { return "VarExpr"; }
void PrintChildren(int indentLevel); 91 94 void PrintChildren(int indentLevel);
Identifier *GetIdentifier() {return id;} 92 95 Identifier *GetIdentifier() {return id;}
}; 93 96 };
94 97
class Operator : public Node 95 98 class Operator : public Node
{ 96 99 {
protected: 97 100 protected:
char tokenString[4]; 98 101 char tokenString[4];
99 102
public: 100 103 public:
Operator(yyltype loc, const char *tok); 101 104 Operator(yyltype loc, const char *tok);
const char *GetPrintNameForNode() { return "Operator"; } 102 105 const char *GetPrintNameForNode() { return "Operator"; }
void PrintChildren(int indentLevel); 103 106 void PrintChildren(int indentLevel);
friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } 104 107 friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; }
bool IsOp(const char *op) const; 105 108 bool IsOp(const char *op) const;
}; 106 109 };
107 110
class CompoundExpr : public Expr 108 111 class CompoundExpr : public Expr
{ 109 112 {
protected: 110 113 protected:
Operator *op; 111 114 Operator *op;
Expr *left, *right; // left will be NULL if unary 112 115 Expr *left, *right; // left will be NULL if unary
113 116
public: 114 117 public:
CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary 115 118 CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary
CompoundExpr(Operator *op, Expr *rhs); // for unary 116 119 CompoundExpr(Operator *op, Expr *rhs); // for unary
CompoundExpr(Expr *lhs, Operator *op); // for unary 117 120 CompoundExpr(Expr *lhs, Operator *op); // for unary
void PrintChildren(int indentLevel); 118 121 void PrintChildren(int indentLevel);
}; 119 122 };
120 123
class ArithmeticExpr : public CompoundExpr 121 124 class ArithmeticExpr : public CompoundExpr
{ 122 125 {
public: 123 126 public:
ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 124 127 ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} 125 128 ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {}
const char *GetPrintNameForNode() { return "ArithmeticExpr"; } 126 129 const char *GetPrintNameForNode() { return "ArithmeticExpr"; }
}; 127 130 };
128 131
class RelationalExpr : public CompoundExpr 129 132 class RelationalExpr : public CompoundExpr
{ 130 133 {
public: 131 134 public:
RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 132 135 RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "RelationalExpr"; } 133 136 const char *GetPrintNameForNode() { return "RelationalExpr"; }
}; 134 137 };
135 138
class EqualityExpr : public CompoundExpr 136 139 class EqualityExpr : public CompoundExpr
{ 137 140 {
public: 138 141 public:
EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 139 142 EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "EqualityExpr"; } 140 143 const char *GetPrintNameForNode() { return "EqualityExpr"; }
}; 141 144 };
142 145
class LogicalExpr : public CompoundExpr 143 146 class LogicalExpr : public CompoundExpr
{ 144 147 {
public: 145 148 public:
LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 146 149 LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} 147 150 LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {}
const char *GetPrintNameForNode() { return "LogicalExpr"; } 148 151 const char *GetPrintNameForNode() { return "LogicalExpr"; }
}; 149 152 };
150 153
class AssignExpr : public CompoundExpr 151 154 class AssignExpr : public CompoundExpr
{ 152 155 {
public: 153 156 public:
AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 154 157 AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "AssignExpr"; } 155 158 const char *GetPrintNameForNode() { return "AssignExpr"; }
}; 156 159 };
157 160
class PostfixExpr : public CompoundExpr 158 161 class PostfixExpr : public CompoundExpr
{ 159 162 {
public: 160 163 public:
PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} 161 164 PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {}
const char *GetPrintNameForNode() { return "PostfixExpr"; } 162 165 const char *GetPrintNameForNode() { return "PostfixExpr"; }
163 166
}; 164 167 };
165 168
class ConditionalExpr : public Expr 166 169 class ConditionalExpr : public Expr
{ 167 170 {
protected: 168 171 protected:
Expr *cond, *trueExpr, *falseExpr; 169 172 Expr *cond, *trueExpr, *falseExpr;
public: 170 173 public:
ConditionalExpr(Expr *c, Expr *t, Expr *f); 171 174 ConditionalExpr(Expr *c, Expr *t, Expr *f);
void PrintChildren(int indentLevel); 172 175 void PrintChildren(int indentLevel);
const char *GetPrintNameForNode() { return "ConditionalExpr"; } 173 176 const char *GetPrintNameForNode() { return "ConditionalExpr"; }
}; 174 177 };
175 178
class LValue : public Expr 176 179 class LValue : public Expr
{ 177 180 {
public: 178 181 public:
LValue(yyltype loc) : Expr(loc) {} 179 182 LValue(yyltype loc) : Expr(loc) {}
}; 180 183 };
181 184
class ArrayAccess : public LValue 182 185 class ArrayAccess : public LValue
{ 183 186 {
protected: 184 187 protected:
Expr *base, *subscript; 185 188 Expr *base, *subscript;
186 189
public: 187 190 public:
ArrayAccess(yyltype loc, Expr *base, Expr *subscript); 188 191 ArrayAccess(yyltype loc, Expr *base, Expr *subscript);
const char *GetPrintNameForNode() { return "ArrayAccess"; } 189 192 const char *GetPrintNameForNode() { return "ArrayAccess"; }
void PrintChildren(int indentLevel); 190 193 void PrintChildren(int indentLevel);
}; 191 194 };
192 195
/* Note that field access is used both for qualified names 193 196 /* Note that field access is used both for qualified names
* base.field and just field without qualification. We don't 194 197 * base.field and just field without qualification. We don't
* know for sure whether there is an implicit "this." in 195 198 * know for sure whether there is an implicit "this." in
* front until later on, so we use one node type for either 196 199 * front until later on, so we use one node type for either
* and sort it out later. */ 197 200 * and sort it out later. */
class FieldAccess : public LValue 198 201 class FieldAccess : public LValue
/* 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
llvm::Value* Program::Emit() { 26 26 llvm::Value* Program::Emit() {
// TODO: 27 27 // TODO:
// This is just a reference for you to get started 28 28 // This is just a reference for you to get started
// 29 29 //
// You can use this as a template and create Emit() function 30 30 // You can use this as a template and create Emit() function
// for individual node to fill in the module structure and instructions. 31 31 // for individual node to fill in the module structure and instructions.
// 32 32 //
IRGenerator irgen; 33 33 //IRGenerator irgen;
llvm::Module *mod = irgen.GetOrCreateModule("Name_the_Module.bc"); 34 34 llvm::Module *mod = irgen.GetOrCreateModule("Name_the_Module.bc");
35 35
// create a function signature 36 36 // create a function signature
std::vector<llvm::Type *> argTypes; 37 37 std::vector<llvm::Type *> argTypes;
llvm::Type *intTy = irgen.GetIntType(); 38 38 llvm::Type *intTy = irgen.GetIntType();
argTypes.push_back(intTy); 39 39 argTypes.push_back(intTy);
llvm::ArrayRef<llvm::Type *> argArray(argTypes); 40 40 llvm::ArrayRef<llvm::Type *> argArray(argTypes);
llvm::FunctionType *funcTy = llvm::FunctionType::get(intTy, argArray, false); 41 41 llvm::FunctionType *funcTy = llvm::FunctionType::get(intTy, argArray, false);
42 42
// llvm::Function *f = llvm::cast<llvm::Function>(mod->getOrInsertFunction("foo", intTy, intTy, (Type *)0)); 43 43 // llvm::Function *f = llvm::cast<llvm::Function>(mod->getOrInsertFunction("foo", intTy, intTy, (Type *)0));
llvm::Function *f = llvm::cast<llvm::Function>(mod->getOrInsertFunction("Name_the_function", funcTy)); 44 44 llvm::Function *f = llvm::cast<llvm::Function>(mod->getOrInsertFunction("Name_the_function", funcTy));
llvm::Argument *arg = f->arg_begin(); 45 45 llvm::Argument *arg = f->arg_begin();
arg->setName("x"); 46 46 arg->setName("x");
47 47
// insert a block into the runction 48 48 // insert a block into the runction
llvm::LLVMContext *context = irgen.GetContext(); 49 49 llvm::LLVMContext *context = irgen.GetContext();
llvm::BasicBlock *bb = llvm::BasicBlock::Create(*context, "entry", f); 50 50 llvm::BasicBlock *bb = llvm::BasicBlock::Create(*context, "entry", f);
51 51
// create a return instruction 52 52 // create a return instruction
llvm::Value *val = llvm::ConstantInt::get(intTy, 1); 53 53 llvm::Value *val = llvm::ConstantInt::get(intTy, 1);
llvm::Value *sum = llvm::BinaryOperator::CreateAdd(arg, val, "", bb); 54 54 llvm::Value *sum = llvm::BinaryOperator::CreateAdd(arg, val, "", bb);
llvm::ReturnInst::Create(*context, sum, bb); 55 55 llvm::ReturnInst::Create(*context, sum, bb);
56 56
// write the BC into standard output 57 57 // write the BC into standard output
llvm::WriteBitcodeToFile(mod, llvm::outs()); 58 58 llvm::WriteBitcodeToFile(mod, llvm::outs());
} 59 59 }
60 60
StmtBlock::StmtBlock(List<VarDecl*> *d, List<Stmt*> *s) { 61 61 StmtBlock::StmtBlock(List<VarDecl*> *d, List<Stmt*> *s) {
Assert(d != NULL && s != NULL); 62 62 Assert(d != NULL && s != NULL);
(decls=d)->SetParentAll(this); 63 63 (decls=d)->SetParentAll(this);
(stmts=s)->SetParentAll(this); 64 64 (stmts=s)->SetParentAll(this);
} 65 65 }
66 66
void StmtBlock::PrintChildren(int indentLevel) { 67 67 void StmtBlock::PrintChildren(int indentLevel) {
decls->PrintAll(indentLevel+1); 68 68 decls->PrintAll(indentLevel+1);
stmts->PrintAll(indentLevel+1); 69 69 stmts->PrintAll(indentLevel+1);
} 70 70 }
71 71
DeclStmt::DeclStmt(Decl *d) { 72 72 DeclStmt::DeclStmt(Decl *d) {
Assert(d != NULL); 73 73 Assert(d != NULL);
(decl=d)->SetParent(this); 74 74 (decl=d)->SetParent(this);
} 75 75 }
76 76
void DeclStmt::PrintChildren(int indentLevel) { 77 77 void DeclStmt::PrintChildren(int indentLevel) {
decl->Print(indentLevel+1); 78 78 decl->Print(indentLevel+1);
} 79 79 }
80 80
ConditionalStmt::ConditionalStmt(Expr *t, Stmt *b) { 81 81 ConditionalStmt::ConditionalStmt(Expr *t, Stmt *b) {
Assert(t != NULL && b != NULL); 82 82 Assert(t != NULL && b != NULL);
(test=t)->SetParent(this); 83 83 (test=t)->SetParent(this);
(body=b)->SetParent(this); 84 84 (body=b)->SetParent(this);
} 85 85 }
86 86
ForStmt::ForStmt(Expr *i, Expr *t, Expr *s, Stmt *b): LoopStmt(t, b) { 87 87 ForStmt::ForStmt(Expr *i, Expr *t, Expr *s, Stmt *b): LoopStmt(t, b) {
Assert(i != NULL && t != NULL && b != NULL); 88 88 Assert(i != NULL && t != NULL && b != NULL);
(init=i)->SetParent(this); 89 89 (init=i)->SetParent(this);
step = s; 90 90 step = s;
if ( s ) 91 91 if ( s )
(step=s)->SetParent(this); 92 92 (step=s)->SetParent(this);
} 93 93 }
94 94
void ForStmt::PrintChildren(int indentLevel) { 95 95 void ForStmt::PrintChildren(int indentLevel) {
init->Print(indentLevel+1, "(init) "); 96 96 init->Print(indentLevel+1, "(init) ");
test->Print(indentLevel+1, "(test) "); 97 97 test->Print(indentLevel+1, "(test) ");
if ( step ) 98 98 if ( step )
step->Print(indentLevel+1, "(step) "); 99 99 step->Print(indentLevel+1, "(step) ");
body->Print(indentLevel+1, "(body) "); 100 100 body->Print(indentLevel+1, "(body) ");
} 101 101 }
102 102
void WhileStmt::PrintChildren(int indentLevel) { 103 103 void WhileStmt::PrintChildren(int indentLevel) {
test->Print(indentLevel+1, "(test) "); 104 104 test->Print(indentLevel+1, "(test) ");
body->Print(indentLevel+1, "(body) "); 105 105 body->Print(indentLevel+1, "(body) ");
} 106 106 }
107 107
IfStmt::IfStmt(Expr *t, Stmt *tb, Stmt *eb): ConditionalStmt(t, tb) { 108 108 IfStmt::IfStmt(Expr *t, Stmt *tb, Stmt *eb): ConditionalStmt(t, tb) {
Assert(t != NULL && tb != NULL); // else can be NULL 109 109 Assert(t != NULL && tb != NULL); // else can be NULL
elseBody = eb; 110 110 elseBody = eb;
if (elseBody) elseBody->SetParent(this); 111 111 if (elseBody) elseBody->SetParent(this);
} 112 112 }
113 113
void IfStmt::PrintChildren(int indentLevel) { 114 114 void IfStmt::PrintChildren(int indentLevel) {
if (test) test->Print(indentLevel+1, "(test) "); 115 115 if (test) test->Print(indentLevel+1, "(test) ");
if (body) body->Print(indentLevel+1, "(then) "); 116 116 if (body) body->Print(indentLevel+1, "(then) ");
if (elseBody) elseBody->Print(indentLevel+1, "(else) "); 117 117 if (elseBody) elseBody->Print(indentLevel+1, "(else) ");
} 118 118 }
119 119
120 120
ReturnStmt::ReturnStmt(yyltype loc, Expr *e) : Stmt(loc) { 121 121 ReturnStmt::ReturnStmt(yyltype loc, Expr *e) : Stmt(loc) {
expr = e; 122 122 expr = e;
if (e != NULL) expr->SetParent(this); 123 123 if (e != NULL) expr->SetParent(this);
} 124 124 }
125 125
void ReturnStmt::PrintChildren(int indentLevel) { 126 126 void ReturnStmt::PrintChildren(int indentLevel) {
if ( expr ) 127 127 if ( expr )
expr->Print(indentLevel+1); 128 128 expr->Print(indentLevel+1);
} 129 129 }
130 130
SwitchLabel::SwitchLabel(Expr *l, Stmt *s) { 131 131 SwitchLabel::SwitchLabel(Expr *l, Stmt *s) {
Assert(l != NULL && s != NULL); 132 132 Assert(l != NULL && s != NULL);
(label=l)->SetParent(this); 133 133 (label=l)->SetParent(this);
/* irgen.cc - LLVM IR generator 1 1 /* irgen.cc - LLVM IR generator
* 2 2 *
* You can implement any LLVM related functions here. 3 3 * You can implement any LLVM related functions here.
*/ 4 4 */
5 5
#include "irgen.h" 6 6 #include "irgen.h"
7 7
8 IRGenerator irgen;
9
IRGenerator::IRGenerator() : 8 10 IRGenerator::IRGenerator() :
context(NULL), 9 11 context(NULL),
module(NULL), 10 12 module(NULL),
currentFunc(NULL), 11 13 currentFunc(NULL),
currentBB(NULL) 12 14 currentBB(NULL)
{ 13 15 {
} 14 16 }
15 17
IRGenerator::~IRGenerator() { 16 18 IRGenerator::~IRGenerator() {
} 17 19 }
18 20
llvm::Module *IRGenerator::GetOrCreateModule(const char *moduleID) 19 21 llvm::Module *IRGenerator::GetOrCreateModule(const char *moduleID)
{ 20 22 {
if ( module == NULL ) { 21 23 if ( module == NULL ) {
context = new llvm::LLVMContext(); 22 24 context = new llvm::LLVMContext();
module = new llvm::Module(moduleID, *context); 23 25 module = new llvm::Module(moduleID, *context);
module->setTargetTriple(TargetTriple); 24 26 module->setTargetTriple(TargetTriple);
module->setDataLayout(TargetLayout); 25 27 module->setDataLayout(TargetLayout);
} 26 28 }
return module; 27 29 return module;
} 28 30 }
29 31
void IRGenerator::SetFunction(llvm::Function *func) { 30 32 void IRGenerator::SetFunction(llvm::Function *func) {
currentFunc = func; 31 33 currentFunc = func;
} 32 34 }
33 35
llvm::Function *IRGenerator::GetFunction() const { 34 36 llvm::Function *IRGenerator::GetFunction() const {
return currentFunc; 35 37 return currentFunc;
} 36 38 }
37 39
void IRGenerator::SetBasicBlock(llvm::BasicBlock *bb) { 38 40 void IRGenerator::SetBasicBlock(llvm::BasicBlock *bb) {
currentBB = bb; 39 41 currentBB = bb;
} 40 42 }
41 43
llvm::BasicBlock *IRGenerator::GetBasicBlock() const { 42 44 llvm::BasicBlock *IRGenerator::GetBasicBlock() const {
return currentBB; 43 45 return currentBB;
} 44 46 }
45 47
llvm::Type *IRGenerator::GetIntType() const { 46 48 llvm::Type *IRGenerator::GetIntType() const {
llvm::Type *ty = llvm::Type::getInt32Ty(*context); 47 49 llvm::Type *ty = llvm::Type::getInt32Ty(*context);
return ty; 48 50 return ty;
} 49 51 }
50 52
/** 1 1 /**
* File: irgen.h 2 2 * File: irgen.h
* ----------- 3 3 * -----------
* This file defines a class for LLVM IR Generation. 4 4 * This file defines a class for LLVM IR Generation.
* 5 5 *
* All LLVM instruction related functions or utilities can be implemented 6 6 * All LLVM instruction related functions or utilities can be implemented
* here. You'll need to customize this class heavily to provide any helpers 7 7 * here. You'll need to customize this class heavily to provide any helpers
* or untility as you need. 8 8 * or untility as you need.
*/ 9 9 */
10 10
#ifndef _H_IRGen 11 11 #ifndef _H_IRGen
#define _H_IRGen 12 12 #define _H_IRGen
13 13
// LLVM headers 14 14 // LLVM headers
#include "llvm/IR/Module.h" 15 15 #include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h" 16 16 #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Instructions.h" 17 17 #include "llvm/IR/Instructions.h"
#include "llvm/IR/Constants.h" 18 18 #include "llvm/IR/Constants.h"
19 19
class IRGenerator { 20 20 class IRGenerator {
public: 21 21 public:
IRGenerator(); 22 22 IRGenerator();
~IRGenerator(); 23 23 ~IRGenerator();
24 24
llvm::Module *GetOrCreateModule(const char *moduleID); 25 25 llvm::Module *GetOrCreateModule(const char *moduleID);
llvm::LLVMContext *GetContext() const { return context; } 26 26 llvm::LLVMContext *GetContext() const { return context; }
27 27
// Add your helper functions here 28 28 // Add your helper functions here
llvm::Function *GetFunction() const; 29 29 llvm::Function *GetFunction() const;
void SetFunction(llvm::Function *func); 30 30 void SetFunction(llvm::Function *func);
31 31
llvm::BasicBlock *GetBasicBlock() const; 32 32 llvm::BasicBlock *GetBasicBlock() const;
void SetBasicBlock(llvm::BasicBlock *bb); 33 33 void SetBasicBlock(llvm::BasicBlock *bb);
34 34
llvm::Type *GetIntType() const; 35 35 llvm::Type *GetIntType() const;
llvm::Type *GetBoolType() const; 36 36 llvm::Type *GetBoolType() const;
llvm::Type *GetFloatType() const; 37 37 llvm::Type *GetFloatType() const;
38 38
private: 39 39 private:
llvm::LLVMContext *context; 40 40 llvm::LLVMContext *context;
llvm::Module *module; 41 41 llvm::Module *module;
42 42