Fix some of the hints from the 1on1 session on the refactoring the code

This commit is contained in:
Sameer Rahmani 2020-08-03 12:39:20 +01:00
parent 18910a4a2c
commit dfa64e8f26
12 changed files with 62 additions and 68 deletions

View File

@ -35,8 +35,7 @@ int main(int argc, char *argv[]) {
string input_file(argv[1]); string input_file(argv[1]);
Compiler *c{new Compiler()}; Compiler c;
c->compile(input_file); c.compile(input_file);
delete c;
return 0; return 0;
} }

View File

@ -27,6 +27,7 @@
#include "serene/llvm/IR/Value.h" #include "serene/llvm/IR/Value.h"
#include "serene/logger.hpp" #include "serene/logger.hpp"
#include "serene/state.hpp"
#include <llvm/IR/IRBuilder.h> #include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h> #include <llvm/IR/LLVMContext.h>
#include <string> #include <string>
@ -38,18 +39,16 @@
#endif #endif
namespace serene { namespace serene {
// Forward declaration of State. The actual declaration is in state.hpp
class State;
class Compiler { class Compiler {
public: public:
llvm::LLVMContext context; llvm::LLVMContext context;
llvm::IRBuilder<> *builder; llvm::IRBuilder<> builder;
Compiler(); Compiler();
State *state; State state;
llvm::Value *log_error(const char *s); llvm::Value *log_error(const char *s);
void compile(std::string &input); void compile(std::string &input);

View File

@ -25,7 +25,6 @@
#ifndef NAMESPACE_H #ifndef NAMESPACE_H
#define NAMESPACE_H #define NAMESPACE_H
#include "serene/compiler.hpp"
#include "serene/llvm/IR/Value.h" #include "serene/llvm/IR/Value.h"
#include "serene/logger.hpp" #include "serene/logger.hpp"
#include <llvm/IR/Module.h> #include <llvm/IR/Module.h>
@ -47,8 +46,8 @@ public:
std::string name; std::string name;
Namespace(std::string &n) : name(n){}; Namespace(std::string &n) : name(n){};
llvm::Value *lookup(std::string &name); llvm::Value *lookup(const std::string &name);
void insert_symbol(std::string &name, llvm::Value *v); void insert_symbol(const std::string &name, llvm::Value *v);
void print_scope(); void print_scope();
~Namespace(); ~Namespace();

View File

@ -60,15 +60,15 @@ class Reader {
private: private:
std::stringstream input_stream; std::stringstream input_stream;
char get_char(bool); char get_char(bool skip_whitespace);
void unget_char(); void unget_char();
bool is_valid_for_identifier(char); bool is_valid_for_identifier(char c);
// The property to store the ast tree // The property to store the ast tree
ast_tree ast; ast_tree ast;
ast_node read_symbol(); ast_node read_symbol();
ast_list_node read_list(List *); ast_list_node read_list(List *list);
ast_node read_expr(); ast_node read_expr();
public: public:

View File

@ -27,10 +27,10 @@
#include "serene/compiler.hpp" #include "serene/compiler.hpp"
#include "serene/expr.hpp" #include "serene/expr.hpp"
#include "serene/list.hpp"
#include "serene/llvm/IR/Value.h" #include "serene/llvm/IR/Value.h"
#include "serene/logger.hpp" #include "serene/logger.hpp"
#include "serene/state.hpp" #include "serene/state.hpp"
#include "serene/symbol.hpp"
#include <string> #include <string>
#if defined(ENABLE_LOG) || defined(ENABLE_DEF_LOG) #if defined(ENABLE_LOG) || defined(ENABLE_DEF_LOG)
@ -44,13 +44,13 @@ namespace special_forms {
class Def : public AExpr { class Def : public AExpr {
private: private:
AExpr *sym; Symbol *m_sym;
AExpr *value; AExpr *m_value;
public: public:
ExprId id() const override { return def; }; ExprId id() const override { return def; }
Def(AExpr *s, AExpr *v); Def(serene::Symbol *symbol_, AExpr *value_);
std::string string_repr() const override; std::string string_repr() const override;
llvm::Value *codegen(Compiler &compiler, State &state) override; llvm::Value *codegen(Compiler &compiler, State &state) override;
~Def(); ~Def();

View File

@ -47,7 +47,7 @@ public:
void add_namespace(Namespace *ns, bool set_current, bool overwrite); void add_namespace(Namespace *ns, bool set_current, bool overwrite);
bool set_current_ns(Namespace *ns); bool set_current_ns(Namespace *ns);
llvm::Value *lookup_in_current_scope(std::string &name); llvm::Value *lookup_in_current_scope(const std::string &name);
void set_in_current_ns_root_scope(std::string name, llvm::Value *v); void set_in_current_ns_root_scope(std::string name, llvm::Value *v);
~State(); ~State();
}; };

View File

@ -37,14 +37,11 @@ using namespace llvm;
namespace serene { namespace serene {
Compiler::Compiler() { Compiler::Compiler() : builder(context) {
string default_ns_name("user"); string default_ns_name("user");
Namespace *default_ns = new Namespace(default_ns_name); Namespace *default_ns = new Namespace(default_ns_name);
builder = new IRBuilder(this->context); state.add_namespace(default_ns, true, true);
state = new State();
state->add_namespace(default_ns, true, true);
}; };
Value *Compiler::log_error(const char *s) { Value *Compiler::log_error(const char *s) {
@ -58,7 +55,7 @@ void Compiler::compile(string &input) {
COMPILER_LOG("Parsing the input has been done.") COMPILER_LOG("Parsing the input has been done.")
for (const ast_node &x : ast) { for (const ast_node &x : ast) {
auto *IR{x->codegen(*this, *this->state)}; auto *IR{x->codegen(*this, this->state)};
if (IR) { if (IR) {
fmt::print("'{}' generates: \n", x->string_repr() fmt::print("'{}' generates: \n", x->string_repr()
@ -70,17 +67,12 @@ void Compiler::compile(string &input) {
fmt::print("No gen\n"); fmt::print("No gen\n");
} }
} }
state->current_ns->print_scope(); state.current_ns->print_scope();
delete r; delete r;
COMPILER_LOG("Done!") COMPILER_LOG("Done!")
return; return;
}; };
Compiler::~Compiler() { Compiler::~Compiler() { COMPILER_LOG("destroying"); }
COMPILER_LOG("Deleting state...");
delete state;
COMPILER_LOG("Deleting builder...");
delete builder;
}
} // namespace serene } // namespace serene

View File

@ -36,22 +36,26 @@ using namespace llvm;
namespace serene { namespace serene {
std::optional<ast_node> List::at(uint index) { std::optional<ast_node> List::at(uint index) {
if (index >= nodes_.size()) if (index >= nodes_.size()) {
return std::nullopt; return std::nullopt;
}
auto itr = cbegin(nodes_); auto itr = cbegin(nodes_);
std::advance(itr, index); std::advance(itr, index);
return std::make_optional(*itr); return std::make_optional(*itr);
} }
void List::cons(ast_node f) { nodes_.push_back(std::move(f)); } void List::cons(ast_node node) { nodes_.push_front(std::move(node)); }
void List::append(ast_node t) { nodes_.push_front(std::move(t)); } void List::append(ast_node node) { nodes_.push_back(std::move(node)); }
std::string List::string_repr() const { std::string List::string_repr() const {
std::string s; std::string s;
for (auto &n : nodes_) for (auto &n : nodes_) {
s += n->string_repr(); // TODO: Fix the tailing space for the last element
s = s + n->string_repr() + " ";
}
return fmt::format("({})", s); return fmt::format("({})", s);
} }
@ -68,16 +72,23 @@ Value *List::codegen(Compiler &compiler, State &state) {
auto name_ptr = at(1).value_or(nullptr); auto name_ptr = at(1).value_or(nullptr);
auto body_ptr = at(2).value_or(nullptr); auto body_ptr = at(2).value_or(nullptr);
if (!def_ptr && def_ptr->id() != symbol && static_cast<Symbol*>(def_ptr.get())->name() != "def") if (def_ptr && def_ptr->id() == symbol &&
return nullptr; static_cast<Symbol *>(def_ptr.get())->name() == "def") {
if (!name_ptr && def_ptr->id() != symbol) if (!name_ptr && def_ptr->id() != symbol) {
return nullptr; return compiler.log_error("First argument of 'def' has to be a symbol.");
}
if (!body_ptr) if (!body_ptr) {
return nullptr; return compiler.log_error("'def' needs 3 arguments, two has been given.");
}
special_forms::Def def(name_ptr.get(), body_ptr.get()); special_forms::Def def(static_cast<Symbol *>(name_ptr.get()),
body_ptr.get());
return def.codegen(compiler, state); return def.codegen(compiler, state);
}
EXPR_LOG("Not implemented in list.");
return nullptr;
} }
} // namespace serene } // namespace serene

View File

@ -32,8 +32,10 @@ using namespace llvm;
namespace serene { namespace serene {
Value *Namespace::lookup(string &name) { return scope[name]; }; Value *Namespace::lookup(const string &name) { return scope[name]; };
void Namespace::insert_symbol(string &name, Value *v) { scope[name] = v; }
void Namespace::insert_symbol(const string &name, Value *v) { scope[name] = v; }
void Namespace::print_scope() { void Namespace::print_scope() {
typedef map<string, Value *>::const_iterator Iter; typedef map<string, Value *>::const_iterator Iter;

View File

@ -38,27 +38,21 @@ using namespace llvm;
namespace serene { namespace serene {
namespace special_forms { namespace special_forms {
Def::Def(Symbol *symbol_, AExpr *value_) : m_sym(symbol_), m_value(value_) {}
Def::Def(AExpr *s, AExpr *v)
: sym(s), value(v) {
}
string Def::string_repr() const { string Def::string_repr() const {
// this method is not going to get called. // this method is not going to get called.
return "Def"; return "Def";
}; }
Value *Def::codegen(Compiler &compiler, State &state) { Value *Def::codegen(Compiler &compiler, State &state) {
state.set_in_current_ns_root_scope(m_sym->name(),
m_value->codegen(compiler, state));
auto symobj = dynamic_cast<Symbol *>(this->sym); // TODO: Do we need to return the codegen of the symbol instead
// of the symbol itself?
if (symobj->id() != symbol) { return m_sym->codegen(compiler, state);
return compiler.log_error("First argument of 'def' should be a symbol."); }
}
state.set_in_current_ns_root_scope(symobj->name(), value->codegen(compiler, state));
return symobj->codegen(compiler, state);
};
Def::~Def() { EXPR_LOG("Destroying def"); }; Def::~Def() { EXPR_LOG("Destroying def"); };
} // namespace special_forms } // namespace special_forms

View File

@ -67,7 +67,7 @@ bool State::set_current_ns(Namespace *ns) {
return false; return false;
}; };
Value *State::lookup_in_current_scope(string &name) { Value *State::lookup_in_current_scope(const string &name) {
if (current_ns) { if (current_ns) {
return current_ns->lookup(name); return current_ns->lookup(name);
} }

View File

@ -46,21 +46,19 @@ const string &Symbol::name() const { return name_; }
Symbol::Symbol(const string &name) : name_(name) {} Symbol::Symbol(const string &name) : name_(name) {}
Value *Symbol::codegen(Compiler &compiler, State &state) { Value *Symbol::codegen(Compiler &compiler, State &state) {
auto name = this->name_; if (name() == "false") {
if (name == "false") {
return ConstantInt::get(Type::getInt1Ty(compiler.context), 0); return ConstantInt::get(Type::getInt1Ty(compiler.context), 0);
} }
if (name == "true") { if (name() == "true") {
return ConstantInt::get(Type::getInt1Ty(compiler.context), 1); return ConstantInt::get(Type::getInt1Ty(compiler.context), 1);
} }
Value *V = state.lookup_in_current_scope(name); Value *V = state.lookup_in_current_scope(name());
if (!V) { if (!V) {
return compiler.log_error( return compiler.log_error(
fmt::format("Unable to resolve symbol '{}'.", name).c_str()); fmt::format("Unable to resolve symbol '{}'.", name()).c_str());
} }
return V; return V;
} }