Files
jak-project/goalc/compiler/Compiler.cpp
T
2020-09-06 12:45:31 -04:00

129 lines
3.8 KiB
C++

#include "Compiler.h"
#include "goalc/logger/Logger.h"
#include "common/link_types.h"
using namespace goos;
Compiler::Compiler() {
init_logger();
m_ts.add_builtin_types();
m_global_env = std::make_unique<GlobalEnv>();
m_none = std::make_unique<None>(m_ts.make_typespec("none"));
// todo - compile library
}
void Compiler::execute_repl() {
while (!m_want_exit) {
try {
// 1). get a line from the user (READ)
std::string prompt;
if (m_listener.is_connected()) {
prompt = "gc";
} else {
prompt = "g";
}
Object code = m_goos.reader.read_from_stdin(prompt);
// 2). compile
auto obj_file = compile_object_file("repl", code, m_listener.is_connected());
obj_file->debug_print_tl();
// // 3). color
// color_object_file(obj_file);
//
// // 4). codegen
// auto data = codegen_object_file(obj_file);
//
// // 4). send!
// if(m_listener.is_connected()) {
// m_listener.send_code(data);
// if(!m_listener.most_recent_send_was_acked()) {
// gLogger.log(MSG_ERR, "Runtime is not responding. Did it crash?\n");
// }
// }
} catch (std::exception& e) {
gLogger.log(MSG_WARN, "REPL Error: %s\n", e.what());
}
}
m_listener.disconnect();
}
Compiler::~Compiler() {
gLogger.close();
}
void Compiler::init_logger() {
gLogger.set_file("compiler.txt"); // todo, a better file than this...
gLogger.config[MSG_COLOR].kind = LOG_FILE;
gLogger.config[MSG_DEBUG].kind = LOG_IGNORE;
gLogger.config[MSG_TGT].color = COLOR_GREEN;
gLogger.config[MSG_TGT_INFO].color = COLOR_BLUE;
gLogger.config[MSG_WARN].color = COLOR_RED;
gLogger.config[MSG_ICE].color = COLOR_RED;
gLogger.config[MSG_ERR].color = COLOR_RED;
}
FileEnv* Compiler::compile_object_file(const std::string& name,
goos::Object code,
bool allow_emit) {
auto file_env = m_global_env->add_file(name);
Env* compilation_env = file_env;
if (!allow_emit) {
compilation_env = file_env->add_no_emit_env();
}
file_env->add_top_level_function(
compile_top_level_function("top-level", std::move(code), compilation_env));
return file_env;
}
std::unique_ptr<FunctionEnv> Compiler::compile_top_level_function(const std::string& name,
const goos::Object& code,
Env* env) {
auto fe = std::make_unique<FunctionEnv>(env, name);
fe->set_segment(TOP_LEVEL_SEGMENT);
auto result = compile_error_guard(code, fe.get());
// only move to return register if we actually got a result
if (!dynamic_cast<const None*>(result)) {
fe->emit(std::make_unique<IR_Return>(fe->make_gpr(result->type()), result->to_gpr(fe.get())));
}
fe->finish();
return fe;
}
Val* Compiler::compile_error_guard(const goos::Object& code, Env* env) {
try {
return compile(code, env);
} catch (std::runtime_error& e) {
printf(
"------------------------------------------------------------------------------------------"
"-\n");
auto obj_print = code.print();
if (obj_print.length() > 80) {
obj_print = obj_print.substr(0, 80);
obj_print += "...";
}
printf("object: %s\nfrom : %s\n", obj_print.c_str(),
m_goos.reader.db.get_info_for(code).c_str());
throw e;
}
}
void Compiler::throw_compile_error(const goos::Object& o, const std::string& err) {
gLogger.log(MSG_ERR, "[Error] Could not compile %s!\nReason: %s\n", o.print().c_str(),
err.c_str());
throw std::runtime_error(err);
}
void Compiler::ice(const std::string& error) {
gLogger.log(MSG_ICE, "[ICE] %s\n", error.c_str());
throw std::runtime_error("ICE");
}