From a8557125c48965de525f68d081c9147a13c22fae Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Mon, 3 Aug 2020 20:21:46 +0100 Subject: [PATCH] Add the mapping for builtins special forms to namespace --- include/serene/list.hpp | 2 +- include/serene/namespace.hpp | 12 +++++++++++- include/serene/special_forms/def.hpp | 1 + src/list.cpp | 2 +- src/namespace.cpp | 10 ++++++++++ src/special_forms/def.cpp | 27 +++++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 3 deletions(-) diff --git a/include/serene/list.hpp b/include/serene/list.hpp index aaa72b3..546c866 100644 --- a/include/serene/list.hpp +++ b/include/serene/list.hpp @@ -44,7 +44,7 @@ public: void cons(ast_node f); void append(ast_node t); - std::optional at(uint index); + std::optional at(uint index) const; llvm::Value *codegen(Compiler &compiler, State &state) override; }; diff --git a/include/serene/namespace.hpp b/include/serene/namespace.hpp index 3d8e148..980a418 100644 --- a/include/serene/namespace.hpp +++ b/include/serene/namespace.hpp @@ -37,10 +37,20 @@ #endif namespace serene { +class AExpr; +class List; +class Compiler; +class State; + class Namespace { -private: + // 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/special_forms/def.hpp b/include/serene/special_forms/def.hpp index 8e15644..048ffb1 100644 --- a/include/serene/special_forms/def.hpp +++ b/include/serene/special_forms/def.hpp @@ -53,6 +53,7 @@ public: Def(serene::Symbol *symbol_, AExpr *value_); 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(); }; diff --git a/src/list.cpp b/src/list.cpp index 309cc53..db3f798 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -35,7 +35,7 @@ using namespace llvm; namespace serene { -std::optional List::at(uint index) { +std::optional List::at(uint index) const { if (index >= nodes_.size()) { return std::nullopt; } diff --git a/src/namespace.cpp b/src/namespace.cpp index a65b938..20c111f 100644 --- a/src/namespace.cpp +++ b/src/namespace.cpp @@ -24,6 +24,7 @@ #include "serene/expr.hpp" #include "serene/llvm/IR/Value.h" +#include "serene/special_forms/def.hpp" #include #include @@ -32,6 +33,15 @@ 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/special_forms/def.cpp b/src/special_forms/def.cpp index 654a099..572f12d 100644 --- a/src/special_forms/def.cpp +++ b/src/special_forms/def.cpp @@ -24,6 +24,7 @@ #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" @@ -38,6 +39,32 @@ 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 {