Compare View

switch
from
...
to
 
Commits (4)

Diff

Showing 3 changed files Inline Diff

/* 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 54 SymbolTable symbols;
pair<Decl*,llvm::Value *> findSymbol(string s) { 55 55 pair<Decl*,llvm::Value *> findSymbol(string s) {
for(int i = symbols.size() - 1; i >= 0; i--) { 56 56 for(int i = symbols.size() - 1; i >= 0; i--) {
if(symbols[i].count(s) > 0) return symbols[i][s]; 57 57 if(symbols[i].count(s) > 0) return symbols[i][s];
} 58 58 }
return make_pair<Decl*,llvm::Value *>(NULL,NULL); 59 59 return make_pair<Decl*,llvm::Value *>(NULL,NULL);
} 60 60 }
61 61
pair<Decl*,llvm::Value *> findSymbol(Decl* d) { 62 62 pair<Decl*,llvm::Value *> findSymbol(Decl* d) {
string s(d->GetIdentifier()->GetName()); 63 63 string s(d->GetIdentifier()->GetName());
return findSymbol(s); 64 64 return findSymbol(s);
} 65 65 }
66 66
bool isInCurrentScope(string s) { 67 67 bool isInCurrentScope(string s) {
if(symbols.size() == 0) return false; 68 68 if(symbols.size() == 0) return false;
return symbols[symbols.size()-1].count(s); 69 69 return symbols[symbols.size()-1].count(s);
} 70 70 }
71 71
bool isInCurrentScope(Decl* d) { 72 72 bool isInCurrentScope(Decl* d) {
string s(d->GetIdentifier()->GetName()); 73 73 string s(d->GetIdentifier()->GetName());
return isInCurrentScope(s); 74 74 return isInCurrentScope(s);
} 75 75 }
76 76
bool isInScope(string s) { 77 77 bool isInScope(string s) {
pair<Decl*, llvm::Value *> tmp = findSymbol(s); 78 78 pair<Decl*, llvm::Value *> tmp = findSymbol(s);
return tmp.first != NULL; 79 79 return tmp.first != NULL;
} 80 80 }
81 81
bool isInScope(Decl* d) { 82 82 bool isInScope(Decl* d) {
string s(d->GetIdentifier()->GetName()); 83 83 string s(d->GetIdentifier()->GetName());
return isInScope(s); 84 84 return isInScope(s);
} 85 85 }
86 86
void pushScope() { 87 87 void pushScope() {
symbols.push_back(map<string,pair<Decl*,llvm::Value *> >()); 88 88 symbols.push_back(map<string,pair<Decl*,llvm::Value *> >());
/** 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
//#pragma clang diagnostic push 37 37 //#pragma clang diagnostic push
//#pragma ide diagnostic ignored "CannotResolve" 38 38 //#pragma ide diagnostic ignored "CannotResolve"
#ifndef _H_ast 39 39 #ifndef _H_ast
#define _H_ast 40 40 #define _H_ast
41 41
#include <stdlib.h> // for NULL 42 42 #include <stdlib.h> // for NULL
#include "irgen.h" 43 43 #include "irgen.h"
#include "location.h" 44 44 #include "location.h"
#include <iostream> 45 45 #include <iostream>
#include <vector> 46 46 #include <vector>
#include <map> 47 47 #include <map>
#include <algorithm> 48 48 #include <algorithm>
//LLVM STUFF 49 49 //LLVM STUFF
#include "llvm/IR/Module.h" 50 50 #include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h" 51 51 #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Instructions.h" 52 52 #include "llvm/IR/Instructions.h"
#include "llvm/IR/Constants.h" 53 53 #include "llvm/IR/Constants.h"
54 54
using namespace std; 55 55 using namespace std;
56 56
class MyStack; 57 57 class MyStack;
class FnDecl; 58 58 class FnDecl;
class Decl; 59 59 class Decl;
60 60
class Node { 61 61 class Node {
protected: 62 62 protected:
yyltype *location; 63 63 yyltype *location;
Node *parent; 64 64 Node *parent;
65 65
public: 66 66 public:
Node(yyltype loc); 67 67 Node(yyltype loc);
Node(); 68 68 Node();
virtual ~Node() {} 69 69 virtual ~Node() {}
70 70
yyltype *GetLocation() { return location; } 71 71 yyltype *GetLocation() { return location; }
void SetParent(Node *p) { parent = p; } 72 72 void SetParent(Node *p) { parent = p; }
Node *GetParent() { return parent; } 73 73 Node *GetParent() { return parent; }
74 74
virtual const char *GetPrintNameForNode() = 0; 75 75 virtual const char *GetPrintNameForNode() = 0;
76 76
// Print() is deliberately _not_ virtual 77 77 // Print() is deliberately _not_ virtual
// subclasses should override PrintChildren() instead 78 78 // subclasses should override PrintChildren() instead
void Print(int indentLevel, const char *label = NULL); 79 79 void Print(int indentLevel, const char *label = NULL);
virtual void PrintChildren(int indentLevel) {} 80 80 virtual void PrintChildren(int indentLevel) {}
81 81
virtual llvm::Value* Emit() { return NULL; } 82 82 virtual llvm::Value* Emit() { return NULL; }
}; 83 83 };
84 84
85 85
class Identifier : public Node 86 86 class Identifier : public Node
{ 87 87 {
protected: 88 88 protected:
char *name; 89 89 char *name;
90 90
public: 91 91 public:
Identifier(yyltype loc, const char *name); 92 92 Identifier(yyltype loc, const char *name);
const char *GetPrintNameForNode() { return "Identifier"; } 93 93 const char *GetPrintNameForNode() { return "Identifier"; }
char *GetName() const { return name; } 94 94 char *GetName() const { return name; }
void PrintChildren(int indentLevel); 95 95 void PrintChildren(int indentLevel);
friend ostream& operator<<(ostream& out, Identifier *id) { return out << id->name; } 96 96 friend ostream& operator<<(ostream& out, Identifier *id) { return out << id->name; }
}; 97 97 };
98 98
99 99
// This node class is designed to represent a portion of the tree that 100 100 // This node class is designed to represent a portion of the tree that
// encountered syntax errors during parsing. The partial completed tree 101 101 // encountered syntax errors during parsing. The partial completed tree
// is discarded along with the states being popped, and an instance of 102 102 // 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 103 103 // the Error class can stand in as the placeholder in the parse tree
// when your parser can continue after an error. 104 104 // when your parser can continue after an error.
class Error : public Node 105 105 class Error : public Node
{ 106 106 {
public: 107 107 public:
Error() : Node() {} 108 108 Error() : Node() {}
const char *GetPrintNameForNode() { return "Error"; } 109 109 const char *GetPrintNameForNode() { return "Error"; }
}; 110 110 };
/*------------------------------------------------------------------------------------ 111 111 /*------------------------------------------------------------------------------------
/* File: ast_decl.cc 1 1 /* File: ast_decl.cc
* ----------------- 2 2 * -----------------
* Implementation of Decl node classes. 3 3 * Implementation of Decl node classes.
*/ 4 4 */
#include "ast_decl.h" 5 5 #include "ast_decl.h"
#include "ast_type.h" 6 6 #include "ast_type.h"
#include "ast_stmt.h" 7 7 #include "ast_stmt.h"
#include "symtable.h" 8 8 #include "symtable.h"
9 9
Decl::Decl(Identifier *n) : Node(*n->GetLocation()) { 10 10 Decl::Decl(Identifier *n) : Node(*n->GetLocation()) {
Assert(n != NULL); 11 11 Assert(n != NULL);
(id=n)->SetParent(this); 12 12 (id=n)->SetParent(this);
} 13 13 }
14 14
VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) { 15 15 VarDecl::VarDecl(Identifier *n, Type *t, Expr *e) : Decl(n) {
Assert(n != NULL && t != NULL); 16 16 Assert(n != NULL && t != NULL);
(type=t)->SetParent(this); 17 17 (type=t)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 18 18 if (e) (assignTo=e)->SetParent(this);
typeq = NULL; 19 19 typeq = NULL;
} 20 20 }
21 21
VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) { 22 22 VarDecl::VarDecl(Identifier *n, TypeQualifier *tq, Expr *e) : Decl(n) {
Assert(n != NULL && tq != NULL); 23 23 Assert(n != NULL && tq != NULL);
(typeq=tq)->SetParent(this); 24 24 (typeq=tq)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 25 25 if (e) (assignTo=e)->SetParent(this);
type = NULL; 26 26 type = NULL;
} 27 27 }
28 28
VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) { 29 29 VarDecl::VarDecl(Identifier *n, Type *t, TypeQualifier *tq, Expr *e) : Decl(n) {
Assert(n != NULL && t != NULL && tq != NULL); 30 30 Assert(n != NULL && t != NULL && tq != NULL);
(type=t)->SetParent(this); 31 31 (type=t)->SetParent(this);
(typeq=tq)->SetParent(this); 32 32 (typeq=tq)->SetParent(this);
if (e) (assignTo=e)->SetParent(this); 33 33 if (e) (assignTo=e)->SetParent(this);
} 34 34 }
35 35
void VarDecl::PrintChildren(int indentLevel) { 36 36 void VarDecl::PrintChildren(int indentLevel) {
if (typeq) typeq->Print(indentLevel+1); 37 37 if (typeq) typeq->Print(indentLevel+1);
if (type) type->Print(indentLevel+1); 38 38 if (type) type->Print(indentLevel+1);
if (id) id->Print(indentLevel+1); 39 39 if (id) id->Print(indentLevel+1);
if (assignTo) assignTo->Print(indentLevel+1, "(initializer) "); 40 40 if (assignTo) assignTo->Print(indentLevel+1, "(initializer) ");
} 41 41 }
42 42
FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) { 43 43 FnDecl::FnDecl(Identifier *n, Type *r, List<VarDecl*> *d) : Decl(n) {
Assert(n != NULL && r!= NULL && d != NULL); 44 44 Assert(n != NULL && r!= NULL && d != NULL);
(returnType=r)->SetParent(this); 45 45 (returnType=r)->SetParent(this);
(formals=d)->SetParentAll(this); 46 46 (formals=d)->SetParentAll(this);
body = NULL; 47 47 body = NULL;
returnTypeq = NULL; 48 48 returnTypeq = NULL;
} 49 49 }
50 50
FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) { 51 51 FnDecl::FnDecl(Identifier *n, Type *r, TypeQualifier *rq, List<VarDecl*> *d) : Decl(n) {
Assert(n != NULL && r != NULL && rq != NULL&& d != NULL); 52 52 Assert(n != NULL && r != NULL && rq != NULL&& d != NULL);
(returnType=r)->SetParent(this); 53 53 (returnType=r)->SetParent(this);
(returnTypeq=rq)->SetParent(this); 54 54 (returnTypeq=rq)->SetParent(this);
(formals=d)->SetParentAll(this); 55 55 (formals=d)->SetParentAll(this);
body = NULL; 56 56 body = NULL;
} 57 57 }
58 58
void FnDecl::SetFunctionBody(Stmt *b) { 59 59 void FnDecl::SetFunctionBody(Stmt *b) {
(body=b)->SetParent(this); 60 60 (body=b)->SetParent(this);
} 61 61 }
62 62
void FnDecl::PrintChildren(int indentLevel) { 63 63 void FnDecl::PrintChildren(int indentLevel) {
if (returnType) returnType->Print(indentLevel+1, "(return type) "); 64 64 if (returnType) returnType->Print(indentLevel+1, "(return type) ");
if (id) id->Print(indentLevel+1); 65 65 if (id) id->Print(indentLevel+1);
if (formals) formals->PrintAll(indentLevel+1, "(formals) "); 66 66 if (formals) formals->PrintAll(indentLevel+1, "(formals) ");
if (body) body->Print(indentLevel+1, "(body) "); 67 67 if (body) body->Print(indentLevel+1, "(body) ");
} 68 68 }
/* 69 69
70 /*
llvm::Value* VarDecl::Emit() { 70 71 llvm::Value* VarDecl::Emit() {
llvm::BasicBlock* b = irgen.GetBasicBlock(); 71 72 llvm::BasicBlock* b = irgen.GetBasicBlock();
llvm::Value* val; 72 73 llvm::Value* val;
if(b) val = new llvm::AllocaInst(convertType(type), id->GetName(), b); 73 74 if(b) val = new llvm::AllocaInst(convertType(type), id->GetName(), b);
else { 74 75 else {
llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type)); 75 76 llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type));
val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, ""); 76 77 val = new llvm::GlobalVariable(*irgen.GetOrCreateModule("program"), convertType(type), false, llvm::GlobalValue::ExternalLinkage, e, "");
} 77 78 }
if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), "", b); 78 79 if(assignTo) val = new llvm::StoreInst(val, assignTo->Emit(), "", b);
addToScope(id->GetName(), this, val); 79 80 addToScope(id->GetName(), this, val);
return val; 80 81 return val;
} 81 82 }
83 */
84 llvm::Value * VarDecl::Emit(){
85 Type * t = type;
86 llvm::Type * ltyp=convertType(t);
87 llvm::Value * val;
88 llvm::Module *mod = irgen.GetOrCreateModule("program");
89 if (global()){
90 val = new llvm::GlobalVariable(*mod, ltyp, false, llvm::GlobalValue::ExternalLinkage, llvm::Constant::getNullValue(ltyp), llvm::Twine(id->GetName()));
91 addToScope(id->GetName(),this, val);
92 }
93 else{
94 val = new llvm::AllocaInst(ltyp, llvm::Twine(id->GetName()), irgen.GetBasicBlock());
95 addToScope(id->GetName(),this, val);
96 }
97 return val;
98 }
99
*/ 82 100
101 /*
llvm::Value * VarDecl::Emit(){ 83 102 llvm::Value* FnDecl::Emit() {
Type * t = type; 84 103 llvm::BasicBlock* oldBlock = irgen.GetBasicBlock();
llvm::Type * ltyp=convertType(t); 85 104 llvm::LLVMContext* context = irgen.GetContext();
llvm::Value * val; 86 105 pushScope();
llvm::Module *mod = irgen.GetOrCreateModule("program"); 87 106 vector<llvm::Type*> types;
if (global()){ 88 107 for(int i = 0; i < formals->NumElements(); i++) {
val = new llvm::GlobalVariable(*mod, ltyp, false, llvm::GlobalValue::ExternalLinkage, llvm::Constant::getNullValue(ltyp), llvm::Twine(id->GetName())); 89 108 types.push_back(convertType(formals->Nth(i)->GetType()));
addToScope(id->GetName(),this, val); 90 109 }
} 91 110 llvm::FunctionType* ft = llvm::FunctionType::get(convertType(returnType), types, false);
else{ 92 111 popScope();
val = new llvm::AllocaInst(ltyp, llvm::Twine(id->GetName()), irgen.GetBasicBlock()); 93 112 llvm::Function* func = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, id->GetName(), irgen.GetOrCreateModule("program"));
addToScope(id->GetName(),this, val); 94 113 llvm::BasicBlock * block = llvm::BasicBlock::Create(*context, "funcBlock", func);
} 95 114 irgen.SetBasicBlock(block);
return val; 96 115 irgen.SetFunction(func);
} 97 116 for(int i = 0; i < formals->NumElements(); i++) {
98 117 formals->Nth(i)->Emit();
99 118 }
/* 100 119 body->Emit();
llvm::Value* FnDecl::Emit() { 101 120 if(!block->getTerminator()) {
llvm::BasicBlock* oldBlock = irgen.GetBasicBlock(); 102 121 llvm::Value* retVar = new llvm::AllocaInst(convertType(returnType), "", block);
llvm::LLVMContext* context = irgen.GetContext(); 103 122 llvm::Value* ret = new llvm::LoadInst(retVar, "", block);
pushScope(); 104 123 llvm::ReturnInst::Create(*context, ret, block);
vector<llvm::Type*> types; 105 124 }
for(int i = 0; i < formals->NumElements(); i++) { 106 125 irgen.SetBasicBlock(oldBlock);
types.push_back(convertType(formals->Nth(i)->GetType())); 107 126 return func;
} 108 127 }
128 */
129 llvm::Value * FnDecl::Emit(){
130 llvm::Module *mod = irgen.GetOrCreateModule("program");
131 llvm::Type *rt = convertType(this->returnType);
132
133 std::vector<llvm::Type *> ref;
134 for (int i = 0; i < formals->NumElements(); i++){
135 ref.push_back(convertType(formals->Nth(i)->GetType()));
136 }
137 llvm::ArrayRef<llvm::Type *> ar(ref);
138 llvm::FunctionType * ft = llvm::FunctionType::get(rt, ar, false);
llvm::FunctionType* ft = llvm::FunctionType::get(convertType(returnType), types, false); 109 139
140 llvm::Value * funcval = mod->getOrInsertFunction(llvm::StringRef(this->GetIdentifier()->GetName()), ft);
141 llvm::Function * fp = llvm::cast<llvm::Function>(funcval);
142
143 addToScope(id->GetName(),this, funcval);
144 //TODO is this how you set it?
145 irgen.SetFunction(fp);
146
147 //SetName
148 pushScope();
149 llvm::Function::arg_iterator args = fp->arg_begin();
150
151 llvm::LLVMContext *context = irgen.GetContext();
152 llvm::BasicBlock * varbb = llvm::BasicBlock::Create(*context, "entry", fp);
153 irgen.SetBasicBlock(varbb);
154 for (int i = 0; i < formals->NumElements(); args++, i++){
155 VarDecl * currvd = formals->Nth(i);
156 string currname = string(currvd->GetIdentifier()->GetName());
157 args->setName(currname);
158 llvm::Value * currargv = currvd->Emit();
159 llvm::StoreInst * si = new llvm::StoreInst(&*args, currargv, varbb);
160 }
161 //Emit StmtBlock
162 if ( StmtBlock * sb = dynamic_cast<StmtBlock *>(body) ){
163 sb->Emit();
164 }
165 popScope();
166 irgen.SetFunction(NULL);
167 return funcval;
168 }
popScope(); 110 169
llvm::Function* func = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, id->GetName(), irgen.GetOrCreateModule("program")); 111
llvm::BasicBlock * block = llvm::BasicBlock::Create(*context, "funcBlock", func); 112
irgen.SetBasicBlock(block); 113
irgen.SetFunction(func); 114
for(int i = 0; i < formals->NumElements(); i++) { 115
formals->Nth(i)->Emit(); 116
} 117
body->Emit(); 118
if(!block->getTerminator()) { 119
llvm::Value* retVar = new llvm::AllocaInst(convertType(returnType), "", block); 120
llvm::Value* ret = new llvm::LoadInst(retVar, "", block); 121
llvm::ReturnInst::Create(*context, ret, block); 122
} 123
irgen.SetBasicBlock(oldBlock); 124
return func; 125
} 126
*/ 127
llvm::Value * FnDecl::Emit(){ 128
llvm::Module *mod = irgen.GetOrCreateModule("program"); 129
llvm::Type *rt = convertType(this->returnType); 130
131
std::vector<llvm::Type *> ref; 132
for (int i = 0; i < formals->NumElements(); i++){ 133
ref.push_back(convertType(formals->Nth(i)->GetType())); 134
} 135
llvm::ArrayRef<llvm::Type *> ar(ref); 136
llvm::FunctionType * ft = llvm::FunctionType::get(rt, ar, false); 137
138
llvm::Value * funcval = mod->getOrInsertFunction(llvm::StringRef(this->GetIdentifier()->GetName()), ft); 139
llvm::Function * fp = llvm::cast<llvm::Function>(funcval); 140
141
addToScope(id->GetName(),this, funcval); 142
//TODO is this how you set it? 143
irgen.SetFunction(fp); 144
145
//SetName 146
pushScope(); 147
llvm::Function::arg_iterator args = fp->arg_begin(); 148
149
llvm::LLVMContext *context = irgen.GetContext(); 150
llvm::BasicBlock * varbb = llvm::BasicBlock::Create(*context, "entry", fp); 151