diff --git a/README.md b/README.md index de9e307..f803590 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ hmmm - gdb (debug) - valgrind (debug) +# TODO +- function types + # Flex and Bison stuff - http://flex.sourceforge.net/manual/ - http://flex.sourceforge.net/manual/Reentrant.html diff --git a/sayaka/src/ast_node_block.cpp b/sayaka/src/ast_node_block.cpp index 95c5a67..32e46d0 100644 --- a/sayaka/src/ast_node_block.cpp +++ b/sayaka/src/ast_node_block.cpp @@ -17,22 +17,18 @@ void ASTNodeBlock::push(ASTNode* node) { } ASTNodeBlock* ASTNodeBlock::pass_types(CodeGenContext* code_gen_context, ASTType* type) { - code_gen_context->scope.push(); for (std::vector::iterator it = this->statements.begin(); it != this->statements.end(); it++) { (*it) = (*it)->pass_types(code_gen_context, type); } - code_gen_context->scope.pop(); this->type = this->statements.back()->type; return this; } llvm::Value* ASTNodeBlock::gen_code(CodeGenContext* code_gen_context) { std::cout << "Generating block" << std::endl; - code_gen_context->push_scope(); llvm::Value* last = NULL; for (std::vector::iterator it = this->statements.begin(); it != this->statements.end(); it++) { last = (*it)->gen_code(code_gen_context); } - code_gen_context->pop_scope(); return last; } diff --git a/sayaka/src/ast_node_function.cpp b/sayaka/src/ast_node_function.cpp index 70ea32f..390d8c9 100644 --- a/sayaka/src/ast_node_function.cpp +++ b/sayaka/src/ast_node_function.cpp @@ -14,8 +14,12 @@ ASTNodeFunction::~ASTNodeFunction() { ASTNodeFunction* ASTNodeFunction::pass_types(CodeGenContext* code_gen_context, ASTType* ignore) { this->type = NULL; // TODO; + code_gen_context->push_scope(); this->prototype = this->prototype->pass_types(code_gen_context, NULL); - this->body = this->body->pass_types(code_gen_context, code_gen_context->ast_types_resolver.get(this->prototype->return_type)); + if (this->body != NULL) { + this->body = this->body->pass_types(code_gen_context, code_gen_context->ast_types_resolver.get(this->prototype->return_type)); + } + code_gen_context->pop_scope(); return this; } @@ -26,19 +30,19 @@ llvm::Value* ASTNodeFunction::gen_code(CodeGenContext* code_gen_context) { if (type == NULL) { throw std::runtime_error("Unknown type"); } + code_gen_context->push_scope(); llvm::Function* fn = (llvm::Function*) this->prototype->gen_code(code_gen_context); - - llvm::BasicBlock* basic_block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", fn); - code_gen_context->push_block(basic_block); - llvm::Value* ret_val = this->body->gen_code(code_gen_context); - if (ret_val != NULL) { + if (this->body != NULL) { + llvm::BasicBlock* basic_block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", fn); + code_gen_context->push_block(basic_block); + + llvm::Value* ret_val = this->body->gen_code(code_gen_context); code_gen_context->builder.CreateRet(ret_val); llvm::verifyFunction(*fn); code_gen_context->pop_block(); fn->dump(); - return fn; } - code_gen_context->pop_block(); - throw std::runtime_error("Error generating function"); + code_gen_context->pop_scope(); + return fn; } diff --git a/sayaka/src/ast_types_resolver.cpp b/sayaka/src/ast_types_resolver.cpp index 9bb056e..f7f3af1 100644 --- a/sayaka/src/ast_types_resolver.cpp +++ b/sayaka/src/ast_types_resolver.cpp @@ -1,17 +1,17 @@ #include "ast_types_resolver.h" -ASTTypesResolver::ASTTypesResolver() { - this->put(this->bit_ty()); - this->put(this->byte_ty()); - this->put(this->short_ty()); - this->put(this->int_ty()); - this->put(this->long_ty()); - this->put(this->ubyte_ty()); - this->put(this->ushort_ty()); - this->put(this->uint_ty()); - this->put(this->ulong_ty()); - this->put(this->float_ty()); - this->put(this->double_ty()); +ASTTypesResolver::ASTTypesResolver(llvm::LLVMContext& llvm_context) : llvm_context(llvm_context) { + this->put(this->bit_ty(true)); + this->put(this->byte_ty(true)); + this->put(this->short_ty(true)); + this->put(this->int_ty(true)); + this->put(this->long_ty(true)); + this->put(this->ubyte_ty(true)); + this->put(this->ushort_ty(true)); + this->put(this->uint_ty(true)); + this->put(this->ulong_ty(true)); + this->put(this->float_ty(true)); + this->put(this->double_ty(true)); } ASTTypesResolver::~ASTTypesResolver() { @@ -28,112 +28,112 @@ void ASTTypesResolver::put(ASTType* type) { this->types_map[type->name] = type; } -ASTType* ASTTypesResolver::bit_ty() { - if (this->get("Bit") != NULL) { +ASTType* ASTTypesResolver::bit_ty(bool create) { + if (!create) { return this->get("Bit"); } ASTType* instance = new ASTType("Bit"); - instance->llvm_type = llvm::Type::getInt1Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt1Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::byte_ty() { - if (this->get("Byte") != NULL) { +ASTType* ASTTypesResolver::byte_ty(bool create) { + if (!create) { return this->get("Byte"); } ASTType* instance = new ASTType("Byte"); - instance->llvm_type = llvm::Type::getInt8Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt8Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::ubyte_ty() { - if (this->get("UByte") != NULL) { +ASTType* ASTTypesResolver::ubyte_ty(bool create) { + if (!create) { return this->get("UByte"); } ASTType* instance = new ASTType("UByte"); - instance->llvm_type = llvm::Type::getInt8Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt8Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::short_ty() { - if (this->get("Short") != NULL) { +ASTType* ASTTypesResolver::short_ty(bool create) { + if (!create) { return this->get("Short"); } ASTType* instance = new ASTType("Short"); - instance->llvm_type = llvm::Type::getInt16Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt16Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::ushort_ty() { - if (this->get("UShort") != NULL) { +ASTType* ASTTypesResolver::ushort_ty(bool create) { + if (!create) { return this->get("UShort"); } ASTType* instance = new ASTType("UShort"); - instance->llvm_type = llvm::Type::getInt16Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt16Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::int_ty() { - if (this->get("Int") != NULL) { +ASTType* ASTTypesResolver::int_ty(bool create) { + if (!create) { return this->get("Int"); } ASTType* instance = new ASTType("Int"); - instance->llvm_type = llvm::Type::getInt32Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt32Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::uint_ty() { - if (this->get("UInt") != NULL) { +ASTType* ASTTypesResolver::uint_ty(bool create) { + if (!create) { return this->get("UInt"); } ASTType* instance = new ASTType("UInt"); - instance->llvm_type = llvm::Type::getInt32Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt32Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::long_ty() { - if (this->get("Long") != NULL) { +ASTType* ASTTypesResolver::long_ty(bool create) { + if (!create) { return this->get("Long"); } ASTType* instance = new ASTType("Long"); - instance->llvm_type = llvm::Type::getInt64Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt64Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::ulong_ty() { - if (this->get("ULong") != NULL) { +ASTType* ASTTypesResolver::ulong_ty(bool create) { + if (!create) { return this->get("ULong"); } ASTType* instance = new ASTType("ULong"); - instance->llvm_type = llvm::Type::getInt64Ty(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getInt64Ty(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::float_ty() { - if (this->get("Float") != NULL) { +ASTType* ASTTypesResolver::float_ty(bool create) { + if (!create) { return this->get("Float"); } ASTType* instance = new ASTType("Float"); - instance->llvm_type = llvm::Type::getFloatTy(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getFloatTy(this->llvm_context); instance->primitive = true; return instance; } -ASTType* ASTTypesResolver::double_ty() { - if (this->get("Double") != NULL) { +ASTType* ASTTypesResolver::double_ty(bool create) { + if (!create) { return this->get("Double"); } ASTType* instance = new ASTType("Double"); - instance->llvm_type = llvm::Type::getDoubleTy(llvm::getGlobalContext()); + instance->llvm_type = llvm::Type::getDoubleTy(this->llvm_context); instance->primitive = true; return instance; } diff --git a/sayaka/src/ast_types_resolver.h b/sayaka/src/ast_types_resolver.h index 15a67ca..300155e 100644 --- a/sayaka/src/ast_types_resolver.h +++ b/sayaka/src/ast_types_resolver.h @@ -6,20 +6,22 @@ class ASTTypesResolver { public: - ASTTypesResolver(); + llvm::LLVMContext& llvm_context; + + ASTTypesResolver(llvm::LLVMContext& llvm_context); ASTType* get(std::string); - ASTType* bit_ty(); - ASTType* byte_ty(); - ASTType* ubyte_ty(); - ASTType* short_ty(); - ASTType* ushort_ty(); - ASTType* int_ty(); - ASTType* uint_ty(); - ASTType* long_ty(); - ASTType* ulong_ty(); - ASTType* float_ty(); - ASTType* double_ty(); + ASTType* bit_ty(bool = false); + ASTType* byte_ty(bool = false); + ASTType* ubyte_ty(bool = false); + ASTType* short_ty(bool = false); + ASTType* ushort_ty(bool = false); + ASTType* int_ty(bool = false); + ASTType* uint_ty(bool = false); + ASTType* long_ty(bool = false); + ASTType* ulong_ty(bool = false); + ASTType* float_ty(bool = false); + ASTType* double_ty(bool = false); ~ASTTypesResolver(); private: diff --git a/sayaka/src/code_gen_context.cpp b/sayaka/src/code_gen_context.cpp index b7383f8..592af59 100644 --- a/sayaka/src/code_gen_context.cpp +++ b/sayaka/src/code_gen_context.cpp @@ -1,7 +1,7 @@ #include "code_gen_context.h" #include -CodeGenContext::CodeGenContext(llvm::LLVMContext& llvm_context) : builder(llvm_context), llvm_context(llvm_context) { +CodeGenContext::CodeGenContext(llvm::LLVMContext& llvm_context) : builder(llvm_context), llvm_context(llvm_context), ast_types_resolver(llvm_context) { this->module = new llvm::Module("top", this->llvm_context); } diff --git a/sayaka/src/code_gen_context.h b/sayaka/src/code_gen_context.h index e4be908..c53034f 100644 --- a/sayaka/src/code_gen_context.h +++ b/sayaka/src/code_gen_context.h @@ -3,22 +3,18 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include #include +#include #include +#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include #include "identifier_scope.h" #include "ast_types_resolver.h" diff --git a/sayaka/src/lexer.l b/sayaka/src/lexer.l index d3b7185..acb6107 100644 --- a/sayaka/src/lexer.l +++ b/sayaka/src/lexer.l @@ -13,6 +13,7 @@ %option noyywrap %option never-interactive %option nounistd +%option yylineno %option bison-bridge %option bison-locations diff --git a/sayaka/src/main.cpp b/sayaka/src/main.cpp index aa7efbb..d7c6687 100644 --- a/sayaka/src/main.cpp +++ b/sayaka/src/main.cpp @@ -13,7 +13,7 @@ namespace boost { extern "C" { int32_t test_fn(int32_t x) { - std::cout << (char) x << std::endl; + std::cout << x << std::endl; return x * 2; } } diff --git a/sayaka/src/parser.y b/sayaka/src/parser.y index 4c00ac6..52940a4 100644 --- a/sayaka/src/parser.y +++ b/sayaka/src/parser.y @@ -21,6 +21,7 @@ class ASTNode; class ASTNodeBlock; class ASTNodeIdentifier; class ASTNodeDeclaration; +class ASTNodeFunctionPrototype; #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T @@ -41,6 +42,8 @@ typedef void* yyscan_t; ASTNode* node; ASTNodeBlock* block; ASTNodeIdentifier* identifier; + ASTNodeFunctionPrototype* function_prototype; + ASTNodeDeclaration* declaration; std::vector* typed_args_list; std::vector* args_list; std::string* str; @@ -58,9 +61,11 @@ typedef void* yyscan_t; %token TOKEN_COMMA TOKEN_IF TOKEN_ELSE %token TOKEN_NUMBER TOKEN_IDENTIFIER TOKEN_TYPE_NAME -%type program expr number binary_operator_expr assignment_expr declaration_expr cast_expr function_call_expr function_prototype_expr function_expr if_else_expr +%type program expr number binary_operator_expr assignment_expr cast_expr function_call_expr function_expr if_else_expr %type stmts %type identifier +%type function_prototype_expr +%type declaration_expr %type typed_args_list %type args_list @@ -89,9 +94,16 @@ expr | cast_expr { $$ = $1; } | if_else_expr { $$ = $1; } | function_expr { $$ = $1; } - | function_prototype_expr { $$ = $1; } + | function_prototype_expr { $$ = new ASTNodeFunction($1, NULL); } | function_call_expr { $$ = $1; } | binary_operator_expr { $$ = $1; } + | declaration_expr TOKEN_ASSIGN expr { + std::cout << "here" << std::endl; + ASTNodeBlock* block = new ASTNodeBlock(); + block->push($1); + block->push(new ASTNodeAssignment(new ASTNodeIdentifier($1->var_name), $3)); + $$ = block; + } ; identifier @@ -157,7 +169,7 @@ function_prototype_expr function_expr : function_prototype_expr TOKEN_LBRACE stmts TOKEN_RBRACE { - $$ = new ASTNodeFunction((ASTNodeFunctionPrototype*) $1, $3); + $$ = new ASTNodeFunction($1, $3); } ; @@ -171,10 +183,10 @@ function_call_expr typed_args_list : declaration_expr { $$ = new std::vector(); - $$->push_back((ASTNodeDeclaration*) $1); + $$->push_back($1); } | typed_args_list TOKEN_COMMA declaration_expr { - $$->push_back((ASTNodeDeclaration*) $3); + $$->push_back($3); } ; diff --git a/sayaka/test_script.txt b/sayaka/test_script.txt index bc4d70b..0c02d90 100644 --- a/sayaka/test_script.txt +++ b/sayaka/test_script.txt @@ -1,12 +1,10 @@ +Int test_fn(Int x); + Int fib(Int x) { - Int zero; - zero = 0; - Int one; - one = 1; - if (x <= zero) { + if (x <= 0) { 0; } else { - if (x == one) { + if (x == 1) { 1; } else { fib(x - 1) + fib(x - 2); @@ -14,6 +12,14 @@ Int fib(Int x) { }; }; -Int n; -n = 10; -fib(n); +Int loop(Int x) { + if (x == 0) { + 0; + } else { + test_fn(x); + loop(x - 1); + }; +}; + +Int n = 10; +fib(n) + loop(n);