Skip to content

Commit

Permalink
- conditionals work (e.g. recursive functions can work)
Browse files Browse the repository at this point in the history
- fix memory leak in function prototype
- fix lexer bug for token_pow
- fix parser bug with token_equals associativity and precedence
  • Loading branch information
Raekye committed Nov 11, 2014
1 parent 3d4d5da commit f39baf9
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 12 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ hmmm
- http://flex.sourceforge.net/manual/Reentrant.html
- http://flex.sourceforge.net/manual/Scanner-Options.html
- http://flex.sourceforge.net/manual/Index-of-Scanner-Options.html
- https://www.gnu.org/software/bison/manual/html\_node/index.html
- https://www.gnu.org/software/bison/manual/html\_node/Grammar-File.html
- https://www.gnu.org/software/bison/manual/html\_node/Declarations.html (see "%define Summary", "%define api.pure")
- https://www.gnu.org/software/bison/manual/html\_node/Pure-Decl.html
- https://www.gnu.org/software/bison/manual/html\_node/Pure-Calling.html
- https://www.gnu.org/software/bison/manual/html\_node/Error-Reporting.html
- https://www.gnu.org/software/bison/manual/html\_node/Interface.html
- https://www.gnu.org/software/bison/manual/html_node/index.html
- https://www.gnu.org/software/bison/manual/html_node/Grammar-File.html
- https://www.gnu.org/software/bison/manual/html_node/Declarations.html (see "%define Summary", "%define api.pure")
- https://www.gnu.org/software/bison/manual/html_node/Pure-Decl.html
- https://www.gnu.org/software/bison/manual/html_node/Pure-Calling.html
- https://www.gnu.org/software/bison/manual/html_node/Error-Reporting.html
- https://www.gnu.org/software/bison/manual/html_node/Interface.html

### Resources
- http://stackoverflow.com/questions/3104389/can-i-bind-an-existing-method-to-a-llvm-function-and-use-it-from-jit-compiled-c
Expand Down
13 changes: 13 additions & 0 deletions sayaka/src/ast_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,17 @@ class ASTNodeFunctionCall : public ASTNode {
virtual ASTNodeFunctionCall* pass_types(CodeGenContext*, ASTType*) override;
};

class ASTNodeIfElse : public ASTNode {
public:
ASTNode* cond;
ASTNode* if_true;
ASTNode* if_false;

ASTNodeIfElse(ASTNode* cond, ASTNode* if_true, ASTNode* if_false);

virtual ~ASTNodeIfElse();
virtual llvm::Value* gen_code(CodeGenContext*) override;
virtual ASTNodeIfElse* pass_types(CodeGenContext*, ASTType*) override;
};

#endif /* __AST_NODE_H_ */
3 changes: 3 additions & 0 deletions sayaka/src/ast_node_functionprototype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ ASTNodeFunctionPrototype::ASTNodeFunctionPrototype(std::string return_type, std:
}

ASTNodeFunctionPrototype::~ASTNodeFunctionPrototype() {
for (std::vector<ASTNodeDeclaration*>::iterator it = this->args->begin(); it != this->args->end(); it++) {
delete *it;
}
delete this->args;
}

Expand Down
50 changes: 50 additions & 0 deletions sayaka/src/ast_node_ifelse.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "ast_node.h"

ASTNodeIfElse::ASTNodeIfElse(ASTNode* cond, ASTNode* if_true, ASTNode* if_false) {
this->cond = cond;
this->if_true = if_true;
this->if_false = if_false;
}

ASTNodeIfElse::~ASTNodeIfElse() {
delete this->cond;
delete this->if_true;
delete this->if_false;
}

ASTNodeIfElse* ASTNodeIfElse::pass_types(CodeGenContext* code_gen_context, ASTType* type) {
this->cond = this->cond->pass_types(code_gen_context, code_gen_context->ast_types_resolver.int_ty());
this->if_true = this->if_true->pass_types(code_gen_context, type);
this->if_false = this->if_false->pass_types(code_gen_context, type);
this->type = type;
return this;
}

llvm::Value* ASTNodeIfElse::gen_code(CodeGenContext* code_gen_context) {
llvm::Value* cond_val = code_gen_context->builder.CreateICmpNE(this->cond->gen_code(code_gen_context), llvm::ConstantInt::get(llvm::Type::getInt32Ty(code_gen_context->llvm_context), 0, true), "ifcond");

llvm::Function* fn = code_gen_context->builder.GetInsertBlock()->getParent();
llvm::BasicBlock* if_true_block = llvm::BasicBlock::Create(code_gen_context->llvm_context, "if_true", fn);
llvm::BasicBlock* if_false_block = llvm::BasicBlock::Create(code_gen_context->llvm_context, "if_false");
llvm::BasicBlock* merge_block = llvm::BasicBlock::Create(code_gen_context->llvm_context, "if_merge");
code_gen_context->builder.CreateCondBr(cond_val, if_true_block, if_false_block);

code_gen_context->builder.SetInsertPoint(if_true_block);
llvm::Value* if_true_val = this->if_true->gen_code(code_gen_context);
code_gen_context->builder.CreateBr(merge_block);
if_true_block = code_gen_context->builder.GetInsertBlock();

fn->getBasicBlockList().push_back(if_false_block);
code_gen_context->builder.SetInsertPoint(if_false_block);
llvm::Value* if_false_val = this->if_false->gen_code(code_gen_context);
code_gen_context->builder.CreateBr(merge_block);
if_false_block = code_gen_context->builder.GetInsertBlock();

fn->getBasicBlockList().push_back(merge_block);
code_gen_context->builder.SetInsertPoint(merge_block);

llvm::PHINode* pn = code_gen_context->builder.CreatePHI(this->type->llvm_type, 2, "iftmp");
pn->addIncoming(if_true_val, if_true_block);
pn->addIncoming(if_false_val, if_false_block);
return pn;
}
4 changes: 3 additions & 1 deletion sayaka/src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ADD "+"
MULTIPLY "*"
SUBTRACT "-"
DIVIDE "/"
POW "*\\*"
POW "\\*\\*"
EQUALS "="
COMMA ","

Expand Down Expand Up @@ -55,6 +55,8 @@ WS [ \r\n\t]+
{SEMICOLON} { return TOKEN_SEMICOLON; }
{EQUALS} { return TOKEN_EQUALS; }
{COMMA} { return TOKEN_COMMA; }
if { return TOKEN_IF; }
else { return TOKEN_ELSE; }

{NUMBER} { SAVE_TOKEN; return TOKEN_NUMBER; }
{IDENTIFIER} { SAVE_TOKEN; return TOKEN_IDENTIFIER; }
Expand Down
1 change: 1 addition & 0 deletions sayaka/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace boost {

extern "C" {
int32_t test_fn(int32_t x) {
std::cout << (char) x << std::endl;
return x * 2;
}
}
Expand Down
15 changes: 11 additions & 4 deletions sayaka/src/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ void yyerror(YYLTYPE* llocp, ASTNode**, yyscan_t scanner, const char *s) {
%code requires {

#include <vector>
#include <tuple>

class ASTNode;
class ASTNodeBlock;
Expand Down Expand Up @@ -47,17 +46,18 @@ typedef void* yyscan_t;
std::string* str;
}

%right TOKEN_EQUALS
%left TOKEN_ADD TOKEN_SUBTRACT
%left TOKEN_MULTIPLY TOKEN_DIVIDE
%left TOKEN_POW
%left TOKEN_EQUALS TOKEN_RPAREN
%left TOKEN_RPAREN

%token TOKEN_LPAREN TOKEN_RPAREN TOKEN_SEMICOLON TOKEN_EQUALS TOKEN_LBRACE TOKEN_RBRACE TOKEN_LBRACKET TOKEN_RBRACKET
%token TOKEN_ADD TOKEN_MULTIPLY TOKEN_DIVIDE TOKEN_SUBTRACT TOKEN_POW
%token TOKEN_COMMA
%token TOKEN_COMMA TOKEN_IF TOKEN_ELSE
%token <str> TOKEN_NUMBER TOKEN_IDENTIFIER TOKEN_TYPE_NAME

%type <node> program expr number binary_operator_expr assignment_expr variable_declaration_expr cast_expr function_call_expr function_prototype_expr function_expr
%type <node> program expr number binary_operator_expr assignment_expr variable_declaration_expr cast_expr function_call_expr function_prototype_expr function_expr if_else_expr
%type <block> stmts
%type <identifier> identifier
%type <typed_args_list> typed_args_list
Expand Down Expand Up @@ -86,6 +86,7 @@ expr
| variable_declaration_expr { $$ = $1; }
| assignment_expr { $$ = $1; }
| cast_expr { $$ = $1; }
| if_else_expr { $$ = $1; }
| function_expr { $$ = $1; }
| function_prototype_expr { $$ = $1; }
| function_call_expr { $$ = $1; }
Expand Down Expand Up @@ -125,6 +126,12 @@ cast_expr
}
;

if_else_expr
: TOKEN_IF TOKEN_LPAREN expr[cond] TOKEN_RPAREN TOKEN_LBRACE stmts[if_true] TOKEN_RBRACE TOKEN_ELSE TOKEN_LBRACE stmts[if_false] TOKEN_RBRACE {
$$ = new ASTNodeIfElse($cond, $if_true, $if_false);
}
;

binary_operator_expr
: expr TOKEN_ADD expr { $$ = new ASTNodeBinaryOperator(eADD, $1, $3); }
| expr TOKEN_SUBTRACT expr { $$ = new ASTNodeBinaryOperator(eSUBTRACT, $1, $3); }
Expand Down
7 changes: 7 additions & 0 deletions sayaka/src/playground.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include <sstream>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>

void test_map_nonexisting_key() {
std::cout << "Testing map non-existing key" << std::endl;
Expand Down Expand Up @@ -61,6 +64,10 @@ void test_virtual_destructors() {

void test_llvm_memory() {
llvm::InitializeNativeTarget();
llvm::ExecutionEngine* a = llvm::EngineBuilder(new llvm::Module("a", llvm::getGlobalContext())).setEngineKind(llvm::EngineKind::JIT).create();
llvm::ExecutionEngine* b = llvm::EngineBuilder(new llvm::Module("b", llvm::getGlobalContext())).setEngineKind(llvm::EngineKind::JIT).create();
delete a;
delete b;
llvm::llvm_shutdown();
}

Expand Down
17 changes: 17 additions & 0 deletions sayaka/test_script.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Int n;

Int fib(Int x) {
Int a;
a = x - 1;
if (x) {
if (a) {
fib(x - 1) + fib(x - 2);
} else {
1;
};
} else {
0;
};
};

fib(10);

0 comments on commit f39baf9

Please sign in to comment.