Skip to content

Commit

Permalink
refactor and it compiles
Browse files Browse the repository at this point in the history
  • Loading branch information
Raekye committed Nov 2, 2014
1 parent 8be7711 commit 7d55bd3
Show file tree
Hide file tree
Showing 35 changed files with 723 additions and 639 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ hmmm
- flex
- bison

### Passes
- types (primitive literals)
- scope

# Flex and Bison stuff
- hmmmm

Expand Down
1 change: 1 addition & 0 deletions sayaka/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ lexer.cpp
parser.h
parser.cpp
parser.log
*.pyc
15 changes: 9 additions & 6 deletions sayaka/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ CFLAGS = -g -std=c++11 -fexceptions
EXECUTABLE = sayaka
SRC_DIR = src
BIN_DIR = bin
FILES = lexer.cpp parser.cpp main.cpp ntype.cpp node.cpp codegen.cpp codescope.cpp
SOURCES = $(FILES:%.cpp=$(SRC_DIR)/%.cpp)
SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
SOURCES := $(filter-out $(SRC_DIR)/playground.cpp, $(SOURCES))

lexer.cpp: $(SRC_DIR)/lexer.l
$(SRC_DIR)/lexer.cpp: $(SRC_DIR)/lexer.l
cd $(SRC_DIR) && flex --outfile=lexer.cpp --header-file=lexer.h lexer.l

parser.cpp: $(SRC_DIR)/parser.y
$(SRC_DIR)/parser.cpp: $(SRC_DIR)/parser.y
cd $(SRC_DIR) && bison --defines=parser.h --output=parser.cpp --verbose --report-file=parser.log parser.y

build: $(SOURCES)
Expand All @@ -20,9 +20,12 @@ prepare:

clean:
rm -rf $(BIN_DIR)/*
cd $(SRC_DIR) && rm -f lexer.cpp lexer.h parser.cpp parser.h
cd $(SRC_DIR) && rm -f lexer.cpp lexer.h parser.cpp parser.h parser.log

playground:
$(CC) $(SRC_DIR)/playground.cpp -o $(BIN_DIR)/playground.o

all: prepare clean lexer.cpp parser.cpp build
all: prepare clean build

debug: all
gdb $(BIN_DIR)/$(EXECUTABLE)
5 changes: 5 additions & 0 deletions sayaka/src/ast_node.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "ast_node.h"

ASTNode::~ASTNode() {
return;
}
18 changes: 18 additions & 0 deletions sayaka/src/ast_node.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef __AST_NODE_H_
#define __AST_NODE_H_

#include <iostream>
#include <llvm/IR/Value.h>
#include "ast_type.h"
#include "codegen.h"

class ASTNode {
public:
ASTType* type;
llvm::Value* value;

virtual ~ASTNode() = 0;
virtual llvm::Value* gen_code(CodeGen*) = 0;
};

#endif /* __AST_NODE_H_ */
29 changes: 29 additions & 0 deletions sayaka/src/ast_node_assignment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "ast_node_assignment.h"

#include <iostream>

ASTNodeAssignment::ASTNodeAssignment(ASTNodeIdentifier* lhs, ASTNode* rhs) {
this->lhs = lhs;
this->rhs = rhs;
this->type = lhs->type;
}

ASTNodeAssignment::~ASTNodeAssignment() {
delete this->lhs;
delete this->rhs;
}

llvm::Value* ASTNodeAssignment::gen_code(CodeGen* code_gen) {
std::cout << "Generating assignment to " << this->lhs->name << "..." << std::endl;
ASTNode* val = code_gen->scope.get(this->lhs->name);
if (val == NULL) {
std::cout << "Undeclared variable " << this->lhs->name << std::endl;
return NULL;
}
this->type = val->type;
this->rhs->type = val->type;
llvm::Value* rhs_val = this->rhs->gen_code(code_gen);
code_gen->builder.SetInsertPoint(code_gen->current_block());
code_gen->builder.CreateStore(rhs_val, val->value, false);
return rhs_val;
}
18 changes: 18 additions & 0 deletions sayaka/src/ast_node_assignment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef __AST_NODE_ASSIGNMENT_H_
#define __AST_NODE_ASSIGNMENT_H_

#include "ast_node.h"
#include "ast_node_identifier.h"

class ASTNodeAssignment : public ASTNode {
public:
ASTNodeIdentifier* lhs;
ASTNode* rhs;

ASTNodeAssignment(ASTNodeIdentifier*, ASTNode*);

virtual llvm::Value* gen_code(CodeGen*) override;
virtual ~ASTNodeAssignment();
};

#endif /* __AST_NODE_ASSIGNMENT_H_ */
37 changes: 37 additions & 0 deletions sayaka/src/ast_node_binaryoperator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "ast_node_binaryoperator.h"

#include <iostream>

ASTNodeBinaryOperator::ASTNodeBinaryOperator(EBinaryOperationType op, ASTNode* lhs, ASTNode* rhs) {
this->op = op;
this->lhs = lhs;
this->rhs = rhs;
}

ASTNodeBinaryOperator::~ASTNodeBinaryOperator() {
delete this->lhs;
delete this->rhs;
}

llvm::Value* ASTNodeBinaryOperator::gen_code(CodeGen* code_gen) {
std::cout << "Generating binary operator..." << std::endl;
this->lhs->type = this->type;
this->rhs->type = this->type;
llvm::Value* l = this->lhs->gen_code(code_gen);
llvm::Value* r = this->rhs->gen_code(code_gen);
if (this->lhs->type->is_primitive() && this->rhs->type->is_primitive()) {
switch (this->op) {
case eADD:
return code_gen->builder.CreateAdd(l, r, "addtmp");
case eSUBTRACT:
return code_gen->builder.CreateSub(l, r, "subtmp");
case eMULTIPLY:
return code_gen->builder.CreateMul(l, r, "multmp");
case eDIVIDE:
return code_gen->builder.CreateSDiv(l, r, "divtmp");
case ePOW:
return code_gen->builder.CreateAdd(l, r, "powtmp"); // TODO: library function
}
}
throw std::runtime_error("Unknown binary operation");
}
18 changes: 18 additions & 0 deletions sayaka/src/ast_node_binaryoperator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef __AST_NODE_BINARYOPERATOR_H_
#define __AST_NODE_BINARYOPERATOR_H_

#include "ast_node.h"

class ASTNodeBinaryOperator : public ASTNode {
public:
EBinaryOperationType op;
ASTNode* lhs;
ASTNode* rhs;

ASTNodeBinaryOperator(EBinaryOperationType, ASTNode*, ASTNode*);

virtual llvm::Value* gen_code(CodeGen*) override;
virtual ~ASTNodeBinaryOperator();
};

#endif /* __AST_NODE_BINARYOPERATOR_H_ */
25 changes: 25 additions & 0 deletions sayaka/src/ast_node_block.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "ast_node_block.h"

#include <iostream>

ASTNodeBlock::ASTNodeBlock() {
return;
}

void ASTNodeBlock::push(ASTNode* node) {
this->statements.push_back(node);
}

ASTNodeBlock::~ASTNodeBlock() {
return;
}

llvm::Value* ASTNodeBlock::gen_code(CodeGen* code_gen) {
std::cout << "Generating block..." << std::endl;
llvm::Value* last = NULL;
for (std::vector<ASTNode*>::iterator it = this->statements.begin(); it != this->statements.end(); it++) {
last = (*it)->gen_code(code_gen);
this->type = (*it)->type;
}
return last;
}
17 changes: 17 additions & 0 deletions sayaka/src/ast_node_block.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __AST_NODE_BLOCK_H_
#define __AST_NODE_BLOCK_H_

#include "ast_node.h"

class ASTNodeBlock : public ASTNode {
public:
std::vector<ASTNode*> statements;

ASTNodeBlock();
void push(ASTNode*);

virtual llvm::Value* gen_code(CodeGen*) override;
virtual ~ASTNodeBlock();
};

#endif /* __AST_NODE_BLOCK_H_ */
44 changes: 44 additions & 0 deletions sayaka/src/ast_node_cast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "ast_node_cast.h"

#include <iostream>

ASTNodeCast::ASTNodeCast(ASTNode* val, ASTType* target_type) {
this->val = val;
this->target_type = target_type;
this->type = this->target_type;
}

ASTNodeCast::~ASTNodeCast() {
return;
}

llvm::Value* ASTNodeCast::gen_code(CodeGen* code_gen) {
std::cout << "Generating cast..." << std::endl;
code_gen->builder.SetInsertPoint(code_gen->current_block());
if (this->val->type->is_primitive() && this->target_type->is_primitive()) {
llvm::Value* llvm_val = this->val->gen_code(code_gen);
if (this->val->type->is_integral()) {
if (this->target_type->is_integral()) {
return code_gen->builder.CreateIntCast(llvm_val, this->target_type->llvm_type, this->val->type->is_signed());
} else {
if (this->val->type->is_signed()) {
return code_gen->builder.CreateSIToFP(llvm_val, this->target_type->llvm_type);
} else {
return code_gen->builder.CreateUIToFP(llvm_val, this->target_type->llvm_type);
}
}
} else {
if (this->target_type->is_floating()) {
return code_gen->builder.CreateFPCast(llvm_val, this->target_type->llvm_type);
} else {
if (this->target_type->is_signed()) {
return code_gen->builder.CreateFPToSI(llvm_val, this->target_type->llvm_type);
} else {
return code_gen->builder.CreateFPToUI(llvm_val, this->target_type->llvm_type);
}
}
}
}
std::cout << "Badness!!!" << std::endl;
return NULL;
}
17 changes: 17 additions & 0 deletions sayaka/src/ast_node_cast.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __AST_NODE_CAST_H_
#define __AST_NODE_CAST_H_

#include "ast_node.h"

class ASTNodeCast : public ASTNode {
public:
ASTType* target_type;
ASTNode* val;

ASTNodeCast(ASTNode*, ASTType*);

virtual llvm::Value* gen_code(CodeGen*) override;
virtual ~ASTNodeCast();
};

#endif /* __AST_NODE_CAST_H_ */
26 changes: 26 additions & 0 deletions sayaka/src/ast_node_declaration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "ast_node_declaration.h"

#include <iostream>

ASTNodeDeclaration::ASTNodeDeclaration(ASTType* type, ASTNodeIdentifier* var_name) {
this->type = type;
this->var_name = var_name;
this->var_name->type = this->type;
}

ASTNodeDeclaration::~ASTNodeDeclaration() {
delete this->var_name;
}

llvm::Value* ASTNodeDeclaration::gen_code(CodeGen* code_gen) {
if (this->type == NULL || this->type->llvm_type == NULL) {
std::cout << "Unknown type " << this->type->name << std::endl;
return NULL;
}
std::cout << "Generating variable declaration for " << this->var_name->name << ", type " << this->type->name << "..." << std::endl;
code_gen->builder.SetInsertPoint(code_gen->current_block());
llvm::AllocaInst* alloc = new llvm::AllocaInst(this->type->llvm_type, this->var_name->name.c_str(), code_gen->current_block());
this->value = alloc;
code_gen->scope.put(this->var_name->name, this);
return alloc;
}
17 changes: 17 additions & 0 deletions sayaka/src/ast_node_declaration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __AST_NODE_DECLARATION_H_
#define __AST_NODE_DECLARATION_H_

#include "ast_node.h"
#include "ast_node_identifier.h"

class ASTNodeDeclaration : public ASTNode {
public:
ASTNodeIdentifier* var_name;

ASTNodeDeclaration(ASTType*, ASTNodeIdentifier*);

virtual llvm::Value* gen_code(CodeGen*) override;
virtual ~ASTNodeDeclaration();
};

#endif /* __AST_NODE_DECLARATION_H_ */
33 changes: 33 additions & 0 deletions sayaka/src/ast_node_function.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "ast_node_function.h"

#include <iostream>

ASTNodeFunction::ASTNodeFunction(ASTNode* body, ASTType* return_type) {
this->body = body;
this->return_type = return_type;
}

ASTNodeFunction::~ASTNodeFunction() {
delete this->body;
}

llvm::Value* ASTNodeFunction::gen_code(CodeGen* code_gen) {
std::cout << "Generating function..." << std::endl;
std::vector<llvm::Type*> arg_types;
llvm::FunctionType* fn_type = llvm::FunctionType::get(this->return_type->llvm_type, arg_types, false);
llvm::Function* fn = llvm::Function::Create(fn_type, llvm::Function::ExternalLinkage, "", code_gen->module);

llvm::BasicBlock* basic_block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", fn);
code_gen->push_block(basic_block);
code_gen->builder.SetInsertPoint(basic_block);

llvm::Value* ret_val = this->body->gen_code(code_gen);
if (ret_val != NULL) {
code_gen->builder.CreateRet(ret_val);
llvm::verifyFunction(*fn);
code_gen->pop_block();
return fn;
}
code_gen->pop_block();
throw std::runtime_error("Error generating function");
}
17 changes: 17 additions & 0 deletions sayaka/src/ast_node_function.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef __AST_NODE_FUNCTION_H_
#define __AST_NODE_FUNCTION_H_

#include "ast_node.h"

class ASTNodeFunction : public ASTNode {
public:
ASTNode* body;
ASTType* return_type;

ASTNodeFunction(ASTNode*, ASTType*);

virtual llvm::Value* gen_code(CodeGen*) override;
virtual ~ASTNodeFunction();
};

#endif /* __AST_NODE_FUNCTION_H_ */
Loading

0 comments on commit 7d55bd3

Please sign in to comment.