Create a very basic compiler setup to wire everything in the most basic way
This commit is contained in:
parent
6e36ce1711
commit
b27611d5ba
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "serene/serene.hpp"
|
#include "serene/serene.hpp"
|
||||||
#include "serene/reader.hpp"
|
#include "serene/compiler.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -33,13 +33,10 @@ int main(int argc, char *argv[]) {
|
||||||
UNUSED(argc);
|
UNUSED(argc);
|
||||||
cout << "Serene >>" << endl;
|
cout << "Serene >>" << endl;
|
||||||
|
|
||||||
char *input_file = argv[1];
|
string input_file(argv[1]);
|
||||||
Reader *r = new Reader(input_file);
|
|
||||||
ast_tree &ast = r->read();
|
|
||||||
|
|
||||||
for (const ast_node &x : ast) {
|
Compiler *c{new Compiler()};
|
||||||
cout << x->string_repr() << " ";
|
c->compile(input_file);
|
||||||
}
|
delete c;
|
||||||
delete r;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,9 @@ private:
|
||||||
std::map<std::string, llvm::Value *> scope;
|
std::map<std::string, llvm::Value *> scope;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Namespace();
|
std::string name;
|
||||||
|
|
||||||
|
Namespace(std::string &n) : name(n){};
|
||||||
llvm::Value *lookup(std::string &name);
|
llvm::Value *lookup(std::string &name);
|
||||||
~Namespace();
|
~Namespace();
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,14 +31,25 @@
|
||||||
#include <llvm/IR/Module.h>
|
#include <llvm/IR/Module.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#if defined(ENABLE_LOG) || defined(ENABLE_STATE_LOG)
|
||||||
|
#define STATE_LOG(...) __LOG("STATE", __VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define STATE_LOG(...) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace serene {
|
namespace serene {
|
||||||
class State {
|
class State {
|
||||||
public:
|
public:
|
||||||
std::map<std::string, Namespace *> namespaces;
|
std::map<std::string, Namespace *> namespaces;
|
||||||
Namespace *current_ns;
|
Namespace *current_ns;
|
||||||
|
|
||||||
State() : namespaces(), current_ns(nullptr){};
|
State();
|
||||||
void set_current_ns(Namespace *ns);
|
|
||||||
|
void add_namespace(Namespace *ns, bool set_current, bool overwrite);
|
||||||
|
bool set_current_ns(Namespace *ns);
|
||||||
|
llvm::Value *lookup_in_current_scope(std::string &name);
|
||||||
|
|
||||||
|
~State();
|
||||||
};
|
};
|
||||||
} // namespace serene
|
} // namespace serene
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "serene/compiler.hpp"
|
#include "serene/compiler.hpp"
|
||||||
#include "serene/llvm/IR/Value.h"
|
#include "serene/llvm/IR/Value.h"
|
||||||
|
#include "serene/namespace.hpp"
|
||||||
#include "serene/reader.hpp"
|
#include "serene/reader.hpp"
|
||||||
#include "serene/state.hpp"
|
#include "serene/state.hpp"
|
||||||
#include <llvm/IR/IRBuilder.h>
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
@ -36,10 +37,18 @@ using namespace llvm;
|
||||||
|
|
||||||
namespace serene {
|
namespace serene {
|
||||||
|
|
||||||
Compiler::Compiler() { builder = new IRBuilder(this->context); };
|
Compiler::Compiler() {
|
||||||
|
string default_ns_name("user");
|
||||||
|
Namespace *default_ns = new Namespace(default_ns_name);
|
||||||
|
|
||||||
|
builder = new IRBuilder(this->context);
|
||||||
|
state = new State();
|
||||||
|
|
||||||
|
state->add_namespace(default_ns, true, true);
|
||||||
|
};
|
||||||
|
|
||||||
Value *Compiler::log_error(const char *s) {
|
Value *Compiler::log_error(const char *s) {
|
||||||
fmt::print("[Error]: {}", s);
|
fmt::print("[Error]: {}\n", s);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,8 +56,10 @@ void Compiler::compile(string &input) {
|
||||||
Reader *r = new Reader(input);
|
Reader *r = new Reader(input);
|
||||||
ast_tree &ast = r->read();
|
ast_tree &ast = r->read();
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
@ -56,10 +67,19 @@ void Compiler::compile(string &input) {
|
||||||
IR->print(errs());
|
IR->print(errs());
|
||||||
fmt::print("\n");
|
fmt::print("\n");
|
||||||
} else {
|
} else {
|
||||||
|
fmt::print("No gen\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete r;
|
||||||
|
COMPILER_LOG("Done!")
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
Compiler::~Compiler() { delete this->builder; }
|
Compiler::~Compiler() {
|
||||||
|
COMPILER_LOG("Deleting state...");
|
||||||
|
delete state;
|
||||||
|
COMPILER_LOG("Deleting builder...");
|
||||||
|
delete builder;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace serene
|
} // namespace serene
|
||||||
|
|
|
@ -32,5 +32,62 @@ using namespace std;
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace serene {
|
namespace serene {
|
||||||
void State::set_current_ns(Namespace *ns) { current_ns = ns; };
|
State::State() { current_ns = nullptr; };
|
||||||
|
|
||||||
|
void State::add_namespace(Namespace *ns, bool set_current, bool overwrite) {
|
||||||
|
if (ns->name.empty()) {
|
||||||
|
// TODO: Better error handling
|
||||||
|
fmt::print("Error: namespace name is missing\n.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Namespace *already_exist_ns = namespaces[ns->name];
|
||||||
|
|
||||||
|
if (already_exist_ns && !overwrite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (already_exist_ns) {
|
||||||
|
delete namespaces[ns->name];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespaces[ns->name] = ns;
|
||||||
|
|
||||||
|
if (set_current) {
|
||||||
|
set_current_ns(ns);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool State::set_current_ns(Namespace *ns) {
|
||||||
|
Namespace *already_exist_ns = namespaces[ns->name];
|
||||||
|
if (already_exist_ns) {
|
||||||
|
current_ns = ns;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Value *State::lookup_in_current_scope(string &name) {
|
||||||
|
if (this->current_ns) {
|
||||||
|
return current_ns->lookup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt::print("FATAL ERROR: Current ns is not set.");
|
||||||
|
// TODO: Come up with the ERRNO table and return the proper ERRNO
|
||||||
|
exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
State::~State() {
|
||||||
|
STATE_LOG("Deleting namespaces...")
|
||||||
|
std::map<string, Namespace *>::iterator it = namespaces.begin();
|
||||||
|
while (it != namespaces.end()) {
|
||||||
|
STATE_LOG("DELETING {}", it->first);
|
||||||
|
Namespace *tmp = it->second;
|
||||||
|
namespaces[it->first] = nullptr;
|
||||||
|
delete tmp;
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
STATE_LOG("Clearing namespaces...");
|
||||||
|
namespaces.clear();
|
||||||
|
};
|
||||||
} // namespace serene
|
} // namespace serene
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "serene/llvm/IR/Value.h"
|
#include "serene/llvm/IR/Value.h"
|
||||||
#include "serene/namespace.hpp"
|
#include "serene/namespace.hpp"
|
||||||
#include "serene/state.hpp"
|
#include "serene/state.hpp"
|
||||||
|
#include <assert.h>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -38,10 +39,11 @@ namespace serene {
|
||||||
string Symbol::string_repr() { return name; };
|
string Symbol::string_repr() { return name; };
|
||||||
|
|
||||||
Value *Symbol::codegen(Compiler &compiler, State &state) {
|
Value *Symbol::codegen(Compiler &compiler, State &state) {
|
||||||
Value *V = state.current_ns->lookup(name);
|
Value *V = state.lookup_in_current_scope(name);
|
||||||
|
|
||||||
if (!V) {
|
if (!V) {
|
||||||
return compiler.log_error("Unknown symbol name");
|
return compiler.log_error(
|
||||||
|
fmt::format("Unable to resolve symbol '{}'.", name).c_str());
|
||||||
}
|
}
|
||||||
return V;
|
return V;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue