diff --git a/bin/serene.cpp b/bin/serene.cpp index 87bb0ad..8dc8d04 100644 --- a/bin/serene.cpp +++ b/bin/serene.cpp @@ -23,7 +23,6 @@ */ #include "serene/serene.hpp" -#include "serene/compiler.hpp" #include "serene/reader.hpp" #include #include diff --git a/include/serene/compiler.hpp b/include/serene/compiler.hpp deleted file mode 100644 index c0daefe..0000000 --- a/include/serene/compiler.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef COMPILER_H -#define COMPILER_H - -#include "serene/llvm/IR/Value.h" -#include "serene/logger.hpp" -#include "serene/state.hpp" -#include -#include -#include - -#if defined(ENABLE_LOG) || defined(ENABLE_COMPILER_LOG) -#define COMPILER_LOG(...) __LOG("COMPILER", __VA_ARGS__); -#else -#define COMPILER_LOG(...) ; -#endif - -namespace serene { - -class Compiler { - -public: - llvm::LLVMContext context; - llvm::IRBuilder<> builder; - - Compiler(); - - State state; - llvm::Value *log_error(const char *s); - void compile(std::string &input); - - ~Compiler(); -}; - -} // namespace serene - -#endif diff --git a/include/serene/error.hpp b/include/serene/error.hpp index 467a4e0..2576c6a 100644 --- a/include/serene/error.hpp +++ b/include/serene/error.hpp @@ -25,7 +25,6 @@ #ifndef ERROR_H #define ERROR_H -#include "serene/compiler.hpp" #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" #include "serene/state.hpp" @@ -44,8 +43,6 @@ public: ExprId id() const override { return error; } std::string string_repr() const override; std::string dumpAST() const override; - - llvm::Value *codegen(Compiler &compiler, State &state) override; }; } // namespace serene diff --git a/include/serene/expr.hpp b/include/serene/expr.hpp index 0dff9c4..8de2d41 100644 --- a/include/serene/expr.hpp +++ b/include/serene/expr.hpp @@ -25,7 +25,6 @@ #ifndef EXPR_H #define EXPR_H -#include "serene/compiler.hpp" #include "serene/llvm/IR/Value.h" #include "serene/logger.hpp" #include "serene/state.hpp" @@ -48,7 +47,6 @@ public: virtual ExprId id() const = 0; virtual std::string string_repr() const = 0; - virtual llvm::Value *codegen(Compiler &compiler, State &state) = 0; virtual std::string dumpAST() const = 0; }; diff --git a/include/serene/list.hpp b/include/serene/list.hpp index 11001ca..9bbbc0b 100644 --- a/include/serene/list.hpp +++ b/include/serene/list.hpp @@ -46,8 +46,6 @@ public: void append(ast_node t); std::optional at(uint index) const; - - llvm::Value *codegen(Compiler &compiler, State &state) override; }; using ast_list_node = std::unique_ptr; diff --git a/include/serene/namespace.hpp b/include/serene/namespace.hpp index 980a418..8cbdf9d 100644 --- a/include/serene/namespace.hpp +++ b/include/serene/namespace.hpp @@ -39,18 +39,13 @@ namespace serene { class AExpr; class List; -class Compiler; class State; class Namespace { // Why not ast_node ? because i have to include expr.hpp which // causes a circular dependency - using MakerFn = - std::function(Compiler &, State &, const List *)>; - using BuiltinMap = std::map; std::unique_ptr module; std::map scope; - static BuiltinMap builtins; public: std::string name; diff --git a/include/serene/reader.hpp b/include/serene/reader.hpp index a2d3ef7..14a61cb 100644 --- a/include/serene/reader.hpp +++ b/include/serene/reader.hpp @@ -77,7 +77,7 @@ public: void setInput(const std::string); - ast_tree &read(); + std::unique_ptr read(); // Dumps the AST data to stdout void dumpAST(); @@ -95,7 +95,7 @@ public: // Dumps the AST data to stdout void dumpAST(); - ast_tree &read(); + std::unique_ptr read(); ~FileReader(); }; diff --git a/include/serene/special_forms/def.hpp b/include/serene/special_forms/def.hpp deleted file mode 100644 index 7be3ff0..0000000 --- a/include/serene/special_forms/def.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, DEFESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef DEF_H -#define DEF_H - -#include "serene/compiler.hpp" -#include "serene/expr.hpp" -#include "serene/llvm/IR/Value.h" -#include "serene/logger.hpp" -#include "serene/state.hpp" -#include "serene/symbol.hpp" -#include - -#if defined(ENABLE_LOG) || defined(ENABLE_DEF_LOG) -#define DEF_LOG(...) __LOG("DEF", __VA_ARGS__); -#else -#define DEF_LOG(...) ; -#endif - -namespace serene { -namespace special_forms { - -class Def : public AExpr { -private: - Symbol *m_sym; - AExpr *m_value; - -public: - ExprId id() const override { return def; } - - Def(serene::Symbol *symbol_, AExpr *value_); - std::string dumpAST() const override; - std::string string_repr() const override; - llvm::Value *codegen(Compiler &compiler, State &state) override; - static ast_node make(Compiler &compiler, State &state, const List *args); - ~Def(); -}; - -} // namespace special_forms -} // namespace serene - -#endif diff --git a/include/serene/symbol.hpp b/include/serene/symbol.hpp index de64f0e..9609418 100644 --- a/include/serene/symbol.hpp +++ b/include/serene/symbol.hpp @@ -25,7 +25,6 @@ #ifndef SYMBOL_H #define SYMBOL_H -#include "serene/compiler.hpp" #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" #include "serene/state.hpp" @@ -44,8 +43,6 @@ public: ExprId id() const override { return symbol; } std::string string_repr() const override; std::string dumpAST() const override; - - llvm::Value *codegen(Compiler &compiler, State &state) override; }; } // namespace serene diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 559c479..deda56a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,9 +5,8 @@ set(HEADER_LIST "${INCLUDE_DIR}/serene/expr.hpp" "${INCLUDE_DIR}/serene/serene.hpp" "${INCLUDE_DIR}/serene/state.hpp" - "${INCLUDE_DIR}/serene/compiler.hpp" - "${INCLUDE_DIR}/serene/namespace.hpp" - "${INCLUDE_DIR}/serene/special_forms/def.hpp") + "${INCLUDE_DIR}/serene/namespace.hpp") + # Make an automatic library - will be static or dynamic based on user setting add_library(lserene serene.cpp @@ -15,9 +14,7 @@ add_library(lserene symbol.cpp list.cpp namespace.cpp - compiler.cpp state.cpp - special_forms/def.cpp ${HEADER_LIST}) diff --git a/src/compiler.cpp b/src/compiler.cpp deleted file mode 100644 index ca91d46..0000000 --- a/src/compiler.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "serene/compiler.hpp" -#include "serene/llvm/IR/Value.h" -#include "serene/namespace.hpp" -#include "serene/reader.hpp" -#include "serene/state.hpp" -#include -#include -#include -#include - -using namespace std; -using namespace llvm; - -namespace serene { - -Compiler::Compiler() : builder(context) { - string default_ns_name("user"); - Namespace *default_ns = new Namespace(default_ns_name); - - state.add_namespace(default_ns, true, true); -}; - -Value *Compiler::log_error(const char *s) { - fmt::print("[Error]: {}\n", s); - return nullptr; -}; - -void Compiler::compile(string &input) { - Reader *r = new Reader(input); - ast_tree &ast = r->read(); - - COMPILER_LOG("Parsing the input has been done.") - for (const ast_node &x : ast) { - auto *IR{x->codegen(*this, this->state)}; - - if (IR) { - fmt::print("'{}' generates: \n", x->string_repr() - - ); - IR->print(errs()); - fmt::print("\n"); - } else { - fmt::print("No gen\n"); - } - } - state.current_ns->print_scope(); - delete r; - COMPILER_LOG("Done!") - return; -}; - -Compiler::~Compiler() { COMPILER_LOG("destroying"); } - -} // namespace serene diff --git a/src/error.cpp b/src/error.cpp index 14d00ce..56631e6 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -23,7 +23,6 @@ */ #include "serene/error.hpp" -#include "serene/compiler.hpp" #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" #include "serene/namespace.hpp" @@ -43,7 +42,5 @@ string Error::string_repr() const { return fmt::format("Error: {}", msg); } string Error::dumpAST() const { return fmt::format("", this->msg); } -Value *Error::codegen(Compiler &compiler, State &state) { return nullptr; } - Error::~Error() { EXPR_LOG("Destroying Error"); } } // namespace serene diff --git a/src/list.cpp b/src/list.cpp index b98e4ee..d84fa27 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -25,7 +25,6 @@ #include "serene/list.hpp" #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" -#include "serene/special_forms/def.hpp" #include "serene/symbol.hpp" #include #include @@ -72,5 +71,4 @@ std::string List::dumpAST() const { inline size_t List::length() const { return nodes_.size(); } -Value *List::codegen(Compiler &compiler, State &state) { return nullptr; } } // namespace serene diff --git a/src/namespace.cpp b/src/namespace.cpp index 20c111f..a65b938 100644 --- a/src/namespace.cpp +++ b/src/namespace.cpp @@ -24,7 +24,6 @@ #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" -#include "serene/special_forms/def.hpp" #include #include @@ -33,15 +32,6 @@ using namespace llvm; namespace serene { -Namespace::BuiltinMap Namespace::builtins = [] { - NAMESPACE_LOG("Initializing builtins map."); - BuiltinMap exprs_map; - // exprs_map.insert(std::make_pair("def", &special_forms::Def::make)); - // MakerFn def = ; - exprs_map["def"] = special_forms::Def::make; - return exprs_map; -}(); - Value *Namespace::lookup(const string &name) { return scope[name]; }; void Namespace::insert_symbol(const string &name, Value *v) { scope[name] = v; } diff --git a/src/reader.cpp b/src/reader.cpp index e1c81fd..06925ed 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -26,6 +26,8 @@ #include "serene/error.hpp" #include "serene/list.hpp" #include "serene/symbol.hpp" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" #include #include #include @@ -144,7 +146,7 @@ ast_node Reader::read_expr() { } } -ast_tree &Reader::read() { +std::unique_ptr Reader::read() { char c = get_char(true); while (c != EOF) { @@ -156,39 +158,38 @@ ast_tree &Reader::read() { c = get_char(true); } - return this->ast; + return std::make_unique(this->ast); } void Reader::dumpAST() { - ast_tree &ast = this->read(); + ast_tree ast = *this->read(); std::string result = ""; for (auto &node : ast) { result = fmt::format("{0} {1}", result, node->dumpAST()); } } -ast_tree &FileReader::read() { - std::string buffer; +std::unique_ptr FileReader::read() { + llvm::ErrorOr> fileOrErr = + llvm::MemoryBuffer::getFileOrSTDIN(file); - std::ifstream f(file.c_str()); - - if (f) { - f.seekg(0, std::ios::end); - buffer.resize(f.tellg()); - f.seekg(0); - f.read(buffer.data(), buffer.size()); - f.close(); - - reader->setInput(buffer); - - return reader->read(); + if (std::error_code EC = fileOrErr.getError()) { + llvm::errs() << "Could not open input file: " << EC.message() << "\n"; + return nullptr; } - throw ReadError((char *)fmt::format("Can't find file '{}'", file).c_str()); + reader->setInput(fileOrErr.get()->getBuffer().str()); + return reader->read(); } void FileReader::dumpAST() { - ast_tree &ast = this->read(); + auto maybeAst = this->read(); + ast_tree ast; + + if (maybeAst) { + ast = *maybeAst; + } + std::string result = ""; for (auto &node : ast) { result = fmt::format("{0} {1}", result, node->dumpAST()); diff --git a/src/special_forms/def.cpp b/src/special_forms/def.cpp deleted file mode 100644 index 0c16680..0000000 --- a/src/special_forms/def.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "serene/special_forms/def.hpp" -#include "serene/compiler.hpp" -#include "serene/list.hpp" -#include "serene/llvm/IR/Value.h" -#include "serene/namespace.hpp" -#include "serene/state.hpp" -#include "serene/symbol.hpp" -#include -#include -#include - -using namespace std; -using namespace llvm; - -namespace serene { -namespace special_forms { - -ast_node Def::make(Compiler &compiler, State &state, const List *args) { - auto def_ptr = args->at(0).value_or(nullptr); - auto name_ptr = args->at(1).value_or(nullptr); - auto body_ptr = args->at(2).value_or(nullptr); - - if (def_ptr && def_ptr->id() == symbol && - static_cast(def_ptr.get())->name() == "def") { - - if (!name_ptr && def_ptr->id() != symbol) { - compiler.log_error("First argument of 'def' has to be a symbol."); - return nullptr; - } - - if (!body_ptr) { - compiler.log_error("'def' needs 3 arguments, two has been given."); - return nullptr; - } - - return make_unique(static_cast(name_ptr.get()), - body_ptr.get()); - } - - compiler.log_error("Calling 'def' with wrong parameters"); - return nullptr; -}; - -Def::Def(Symbol *symbol_, AExpr *value_) : m_sym(symbol_), m_value(value_) {} - -string Def::string_repr() const { - // this method is not going to get called. - return "Def"; -} - -string Def::dumpAST() const { return ""; } - -Value *Def::codegen(Compiler &compiler, State &state) { - state.set_in_current_ns_root_scope(m_sym->name(), - m_value->codegen(compiler, state)); - - // TODO: Do we need to return the codegen of the symbol instead - // of the symbol itself? - return m_sym->codegen(compiler, state); -} - -Def::~Def() { EXPR_LOG("Destroying def"); }; -} // namespace special_forms -} // namespace serene diff --git a/src/symbol.cpp b/src/symbol.cpp index 8a169fa..2925817 100644 --- a/src/symbol.cpp +++ b/src/symbol.cpp @@ -23,7 +23,6 @@ */ #include "serene/symbol.hpp" -#include "serene/compiler.hpp" #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" #include "serene/namespace.hpp" @@ -49,23 +48,5 @@ const string &Symbol::name() const { return name_; } Symbol::Symbol(const string &name) : name_(name) {} -Value *Symbol::codegen(Compiler &compiler, State &state) { - if (name() == "false") { - return ConstantInt::get(Type::getInt1Ty(compiler.context), 0); - } - - if (name() == "true") { - return ConstantInt::get(Type::getInt1Ty(compiler.context), 1); - } - - Value *V = state.lookup_in_current_scope(name()); - - if (!V) { - return compiler.log_error( - fmt::format("Unable to resolve symbol '{}'.", name()).c_str()); - } - return V; -} - Symbol::~Symbol() { EXPR_LOG("Destroying symbol"); } } // namespace serene