Skip to content

Commit

Permalink
- function prototypes
Browse files Browse the repository at this point in the history
- function calls
- link to c functions
  • Loading branch information
Raekye committed Nov 10, 2014
1 parent c6dedb7 commit 7e11a56
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 43 deletions.
24 changes: 12 additions & 12 deletions sayaka/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
CC = g++
CFLAGS = -c -g -std=c++11 -fexceptions
LDFLAGS = -g -rdynamic
LLVM_COMPILER_FLAGS = $(shell llvm-config --libs core jit native --cxxflags)
LLVM_LINKER_FLAGS = $(shell llvm-config --libs core jit native --ldflags)
LLVM_COMPILER_FLAGS = $(shell llvm-config --cxxflags)
LLVM_LINKER_FLAGS = $(shell llvm-config --ldflags --libs core jit native)
EXECUTABLE = sayaka
SRC_DIR = src
BIN_DIR = bin
Expand All @@ -13,23 +13,23 @@ OBJS = $(subst $(SRC_DIR),$(BIN_DIR),$(subst .cpp,.o,$(SOURCES)))

all: $(BIN_DIR) $(PARSER_SOURCE) $(LEXER_SOURCE) $(BIN_DIR)/$(EXECUTABLE)

debug: all
gdb $(BIN_DIR)/$(EXECUTABLE)

valgrind: all
valgrind --leak-check=yes $(BIN_DIR)/$(EXECUTABLE)

$(BIN_DIR)/$(EXECUTABLE): $(OBJS)
$(CC) $(OBJS) -o $(BIN_DIR)/$(EXECUTABLE) $(LLVM_LINKER_FLAGS) $(LDFLAGS)
$(CC) $(OBJS) -o $@ $(LLVM_LINKER_FLAGS) $(LDFLAGS)

$(BIN_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CC) $(LLVM_COMPILER_FLAGS) $(CFLAGS) $< -o $@

$(LEXER_SOURCE): $(SRC_DIR)/lexer.l
flex --outfile=$@ --header-file=$(SRC_DIR)/lexer.h $(SRC_DIR)/lexer.l

$(PARSER_SOURCE): $(SRC_DIR)/parser.y
bison --defines=$(SRC_DIR)/parser.h --output=$@ --verbose --report-file=$(BIN_DIR)/parser.log $(SRC_DIR)/parser.y

$(BIN_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CC) $(LLVM_COMPILER_FLAGS) $(CFLAGS) $< -o $@
debug: all
gdb $(BIN_DIR)/$(EXECUTABLE)

valgrind: all
valgrind --leak-check=yes $(BIN_DIR)/$(EXECUTABLE)

$(BIN_DIR):
mkdir -p $(BIN_DIR)
Expand All @@ -39,4 +39,4 @@ clean:
rm -f $(LEXER_SOURCE) $(SRC_DIR)/lexer.h $(PARSER_SOURCE) $(SRC_DIR)/parser.h

playground: $(BIN_DIR)
$(CC) $(SRC_DIR)/playground.cpp -o $(BIN_DIR)/playground.o
$(CC) $(SRC_DIR)/playground.cpp -o $(BIN_DIR)/playground.o $(shell llvm-config --libs core jit native --cxxflags --ldflags)
57 changes: 27 additions & 30 deletions sayaka/src/ast_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,12 @@
#define __AST_NODE_H_

#include <iostream>
#include <vector>
#include <tuple>
#include <llvm/IR/Value.h>
#include "ast_type.h"
#include "code_gen_context.h"

union tagUNumberValue {
int8_t b;
uint8_t ub;
int16_t s;
uint16_t us;
int32_t i;
uint32_t ui;
int64_t l;
uint64_t ul;
float f;
double d;
};


enum tagENumberType {
eBYTE = 0,
eUBYTE = 1,
eSHORT = (1 << 1),
eUSHORT = (1 << 1) | 1,
eINT = (1 << 2),
eUINT = (1 << 2) | 1,
eLONG = (1 << 3),
eULONG = (1 << 3) | 1,
eFLOAT = (1 << 4),
eDOUBLE = (1 << 5),
};

enum tagEBinaryOperationType {
eMULTIPLY,
eADD,
Expand All @@ -41,8 +16,6 @@ enum tagEBinaryOperationType {
ePOW,
};

typedef union tagUNumberValue UNumberValue;
typedef enum tagENumberType ENumberType;
typedef enum tagEBinaryOperationType EBinaryOperationType;

class ASTNode {
Expand All @@ -67,7 +40,6 @@ class ASTNodeIdentifier : public ASTNode {

class ASTNodePrimitive : public ASTNode {
public:
UNumberValue val;
std::string str;

ASTNodePrimitive(std::string);
Expand Down Expand Up @@ -150,4 +122,29 @@ class ASTNodeFunction : public ASTNode {
virtual ASTNodeFunction* pass_types(CodeGenContext*, ASTType*) override;
};

class ASTNodeFunctionPrototype : public ASTNode {
public:
std::string return_type;
std::string function_name;
std::vector<std::tuple<std::string, std::string>>* args;

ASTNodeFunctionPrototype(std::string, std::string, std::vector<std::tuple<std::string, std::string>>*);

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

class ASTNodeFunctionCall : public ASTNode {
public:
std::string function_name;
std::vector<ASTNode*>* args;

ASTNodeFunctionCall(std::string, std::vector<ASTNode*>*);

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

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

ASTNodeFunctionCall::ASTNodeFunctionCall(std::string function_name, std::vector<ASTNode*>* args) {
this->function_name = function_name;
this->args = args;
}

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

ASTNodeFunctionCall* ASTNodeFunctionCall::pass_types(CodeGenContext* code_gen_context, ASTType* type) {
this->type = code_gen_context->ast_types_resolver.double_ty();
for (std::vector<ASTNode*>::iterator it = this->args->begin(); it != this->args->end(); it++) {
*it = (*it)->pass_types(code_gen_context, type);
}
return this;
}

llvm::Value* ASTNodeFunctionCall::gen_code(CodeGenContext* code_gen_context) {
llvm::Function* callee = code_gen_context->module->getFunction(this->function_name);
if (callee == NULL) {
throw std::runtime_error("Unknown function called");
}
std::vector<llvm::Value*> argsv;
for (std::vector<ASTNode*>::iterator it = this->args->begin(); it != this->args->end(); it++) {
argsv.push_back((*it)->gen_code(code_gen_context));
}
return code_gen_context->builder.CreateCall(callee, argsv, "calltmp");
}
27 changes: 27 additions & 0 deletions sayaka/src/ast_node_functionprototype.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "ast_node.h"

ASTNodeFunctionPrototype::ASTNodeFunctionPrototype(std::string return_type, std::string function_name, std::vector<std::tuple<std::string, std::string>>* args) {
this->return_type = return_type;
this->function_name = function_name;
this->args = args;
}

ASTNodeFunctionPrototype::~ASTNodeFunctionPrototype() {
delete this->args;
}

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

llvm::Value* ASTNodeFunctionPrototype::gen_code(CodeGenContext* code_gen_context) {
std::vector<llvm::Type*> args_types_list;
for (std::vector<std::tuple<std::string, std::string>>::iterator it = this->args->begin(); it != this->args->end(); it++) {
args_types_list.push_back(code_gen_context->ast_types_resolver.get(std::get<0>(*it))->llvm_type);
}
llvm::FunctionType* ft = llvm::FunctionType::get(code_gen_context->ast_types_resolver.get(this->return_type)->llvm_type, args_types_list, false);
llvm::Function* fn = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, this->function_name, code_gen_context->module);
return llvm::ConstantInt::get(code_gen_context->ast_types_resolver.int_ty()->llvm_type, 0, true);
}

2 changes: 2 additions & 0 deletions sayaka/src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SUBTRACT "-"
DIVIDE "/"
POW "*\\*"
EQUALS "="
COMMA ","

IDENTIFIER [a-z_][a-zA-Z0-9_]*
TYPE_NAME [A-Z][a-zA-Z0-9_]*
Expand All @@ -53,6 +54,7 @@ WS [ \r\n\t]+
{RBRACKET} { return TOKEN_RBRACKET; }
{SEMICOLON} { return TOKEN_SEMICOLON; }
{EQUALS} { return TOKEN_EQUALS; }
{COMMA} { return TOKEN_COMMA; }

{NUMBER} { SAVE_TOKEN; return TOKEN_NUMBER; }
{IDENTIFIER} { SAVE_TOKEN; return TOKEN_IDENTIFIER; }
Expand Down
6 changes: 6 additions & 0 deletions sayaka/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ namespace boost {
}
#endif // BOOST_NO_EXCEPTIONS

extern "C" {
int32_t test_fn(int32_t x) {
return x * 2;
}
}

int main(int argc, char* argv[]) {
Compiler compiler;
compiler.llvm_initialize();
Expand Down
52 changes: 51 additions & 1 deletion sayaka/src/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ void yyerror(YYLTYPE* llocp, ASTNode**, yyscan_t scanner, const char *s) {

%code requires {

#include <vector>
#include <tuple>

class ASTNode;
class ASTNodeBlock;
class ASTNodeIdentifier;
Expand All @@ -38,6 +41,8 @@ typedef void* yyscan_t;
ASTNode* node;
ASTNodeBlock* block;
ASTNodeIdentifier* identifier;
std::vector<std::tuple<std::string, std::string>>* typed_args_list;
std::vector<ASTNode*>* args_list;
std::string* str;
}

Expand All @@ -48,11 +53,14 @@ typedef void* yyscan_t;

%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 <str> TOKEN_NUMBER TOKEN_IDENTIFIER TOKEN_TYPE_NAME

%type <node> program expr number binary_operator_expr assignment_expr variable_declaration_expr cast_expr
%type <node> program expr number binary_operator_expr assignment_expr variable_declaration_expr cast_expr function_call_expr function_prototype_expr
%type <block> stmts
%type <identifier> identifier
%type <typed_args_list> typed_args_list
%type <args_list> args_list

%start program

Expand All @@ -77,6 +85,8 @@ expr
| variable_declaration_expr { $$ = $1; }
| assignment_expr { $$ = $1; }
| cast_expr { $$ = $1; }
| function_prototype_expr { $$ = $1; }
| function_call_expr { $$ = $1; }
| binary_operator_expr { $$ = $1; }
;

Expand Down Expand Up @@ -120,3 +130,43 @@ binary_operator_expr
| expr TOKEN_MULTIPLY expr { $$ = new ASTNodeBinaryOperator(eMULTIPLY, $1, $3); }
| expr TOKEN_POW expr { $$ = new ASTNodeBinaryOperator(ePOW, $1, $3); }
;

function_prototype_expr
: TOKEN_TYPE_NAME TOKEN_IDENTIFIER TOKEN_LPAREN typed_args_list TOKEN_RPAREN {
$$ = new ASTNodeFunctionPrototype(*$1, *$2, $4);
delete $1;
delete $2;
}
;


typed_args_list
: TOKEN_TYPE_NAME TOKEN_IDENTIFIER {
$$ = new std::vector<std::tuple<std::string, std::string>>();
$$->push_back(std::make_tuple(*$1, *$2));
delete $1;
delete $2;
}
| typed_args_list TOKEN_COMMA TOKEN_TYPE_NAME TOKEN_IDENTIFIER {
$$->push_back(std::make_tuple(*$3, *$4));
delete $3;
delete $4;
}
;

args_list
: expr {
$$ = new std::vector<ASTNode*>();
$$->push_back($1);
}
| args_list TOKEN_COMMA expr {
$$->push_back($3);
}
;

function_call_expr
: TOKEN_IDENTIFIER TOKEN_LPAREN args_list TOKEN_RPAREN {
$$ = new ASTNodeFunctionCall(*$1, $3);
delete $1;
}
;
8 changes: 8 additions & 0 deletions sayaka/src/playground.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <iostream>
#include <map>
#include <sstream>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/ManagedStatic.h>

void test_map_nonexisting_key() {
std::cout << "Testing map non-existing key" << std::endl;
Expand Down Expand Up @@ -57,11 +59,17 @@ void test_virtual_destructors() {
std::cout << "---" << std::endl;
}

void test_llvm_memory() {
llvm::InitializeNativeTarget();
llvm::llvm_shutdown();
}

int main() {
test_map_nonexisting_key();
test_pointer_size();
test_string_concat();
test_string_stream();
test_virtual_destructors();
test_llvm_memory();
return 0;
}

0 comments on commit 7e11a56

Please sign in to comment.