Add the mapping for builtins special forms to namespace
This commit is contained in:
parent
dfa64e8f26
commit
a8557125c4
|
@ -44,7 +44,7 @@ public:
|
|||
void cons(ast_node f);
|
||||
void append(ast_node t);
|
||||
|
||||
std::optional<ast_node> at(uint index);
|
||||
std::optional<ast_node> at(uint index) const;
|
||||
|
||||
llvm::Value *codegen(Compiler &compiler, State &state) override;
|
||||
};
|
||||
|
|
|
@ -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<std::shared_ptr<AExpr>(Compiler &, State &, const List *)>;
|
||||
using BuiltinMap = std::map<std::string, MakerFn>;
|
||||
std::unique_ptr<llvm::Module> module;
|
||||
std::map<std::string, llvm::Value *> scope;
|
||||
static BuiltinMap builtins;
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace llvm;
|
|||
|
||||
namespace serene {
|
||||
|
||||
std::optional<ast_node> List::at(uint index) {
|
||||
std::optional<ast_node> List::at(uint index) const {
|
||||
if (index >= nodes_.size()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "serene/expr.hpp"
|
||||
#include "serene/llvm/IR/Value.h"
|
||||
#include "serene/special_forms/def.hpp"
|
||||
#include <fmt/core.h>
|
||||
#include <string>
|
||||
|
||||
|
@ -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; }
|
||||
|
|
|
@ -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<Symbol *>(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<Def>(static_cast<Symbol *>(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 {
|
||||
|
|
Loading…
Reference in New Issue