From 6107b4124c73d5b359ca4f92ca968d7da8614bf9 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Tue, 26 Apr 2022 23:32:43 -0400 Subject: [PATCH] goalc: debug issues, nrepl is working again --- game/system/Deci2Server.cpp | 2 + goalc/compiler/Compiler.cpp | 60 +++++++++++++---------------- goalc/compiler/Compiler.h | 7 +++- goalc/compiler/nrepl/ReplServer.cpp | 20 +++++----- goalc/compiler/nrepl/ReplServer.h | 1 + goalc/main.cpp | 10 ++++- scripts/nrepl-test.py | 12 +++++- 7 files changed, 65 insertions(+), 47 deletions(-) diff --git a/game/system/Deci2Server.cpp b/game/system/Deci2Server.cpp index 82143d7426..d073e4e9cd 100644 --- a/game/system/Deci2Server.cpp +++ b/game/system/Deci2Server.cpp @@ -16,7 +16,9 @@ void Deci2Server::write_on_accept() { u32 versions[2] = {versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR}; + lock(); write_to_socket(accepted_socket, (char*)&versions, 8); + unlock(); } /*! diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index b828976811..f9663f0220 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -72,16 +72,35 @@ void Compiler::unlock() { compiler_mutex.unlock(); } -ReplStatus Compiler::execute_repl(bool auto_listen, bool auto_debug) { - if (auto_debug || auto_listen) { - read_eval_print("(lt)"); +std::optional Compiler::read_from_stdin() { + std::string prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::cyan), "g > "); + if (m_listener.is_connected()) { + prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::lime_green), "gc> "); } - if (auto_debug) { - read_eval_print("(dbg) (:cont)"); + if (m_debugger.is_halted()) { + prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::magenta), "gs> "); + } else if (m_debugger.is_attached()) { + prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "gr> "); } + // 1). get a line from the user (READ) + std::optional code = m_goos.reader.read_from_stdin(prompt, *m_repl); + if (!code) { + return std::nullopt; + } + return code; +} + +goos::Object Compiler::read_from_string(const std::string& input) { + return m_goos.reader.read_from_string(input); +} + +ReplStatus Compiler::execute_repl() { while (!m_want_exit && !m_want_reload) { - read_eval_print(); + auto code = read_from_stdin(); + if (code) { + eval_and_print(code.value()); + } } if (m_listener.is_connected()) { @@ -100,35 +119,10 @@ ReplStatus Compiler::execute_repl(bool auto_listen, bool auto_debug) { return ReplStatus::OK; } -void Compiler::read_eval_print(std::string input) { +void Compiler::eval_and_print(goos::Object code) { try { - std::optional code; - - // Explicitly specified input - if (!input.empty()) { - code = m_goos.reader.read_from_string(input); - } else { - // if this is pulled out into a function....illegal instruction on checking the debugger? - // strange - std::string prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::cyan), "g > "); - if (m_listener.is_connected()) { - prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::lime_green), "gc> "); - } - if (m_debugger.is_halted()) { - prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::magenta), "gs> "); - } else if (m_debugger.is_attached()) { - prompt = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "gr> "); - } - // 1). get a line from the user (READ) - code = m_goos.reader.read_from_stdin(prompt, *m_repl); - } - - if (!code) { - return; - } - // 2). compile - auto obj_file = compile_object_file("repl", *code, m_listener.is_connected()); + auto obj_file = compile_object_file("repl", code, m_listener.is_connected()); if (m_settings.debug_print_ir) { obj_file->debug_print_tl(); } diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index a974936529..d2e4b5b8d1 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -29,8 +29,10 @@ enum class ReplStatus { OK, WANT_EXIT, WANT_RELOAD }; class Compiler { public: Compiler(const std::string& user_profile = "#f", std::unique_ptr repl = nullptr); - void read_eval_print(std::string input = ""); - ReplStatus execute_repl(bool auto_listen = false, bool auto_debug = false); + goos::Object read_from_string(const std::string& input); + void eval_and_print(goos::Object code); + + ReplStatus execute_repl(); goos::Interpreter& get_goos() { return m_goos; } FileEnv* compile_object_file(const std::string& name, goos::Object code, bool allow_emit); std::unique_ptr compile_top_level_function(const std::string& name, @@ -103,6 +105,7 @@ class Compiler { } m_debug_stats; void setup_goos_forms(); + std::optional read_from_stdin(); std::set lookup_symbol_infos_starting_with(const std::string& prefix) const; std::vector* lookup_exact_name_info(const std::string& name) const; bool get_true_or_false(const goos::Object& form, const goos::Object& boolean); diff --git a/goalc/compiler/nrepl/ReplServer.cpp b/goalc/compiler/nrepl/ReplServer.cpp index b5e80cc90f..e7762736d3 100644 --- a/goalc/compiler/nrepl/ReplServer.cpp +++ b/goalc/compiler/nrepl/ReplServer.cpp @@ -19,20 +19,20 @@ void ReplServer::write_on_accept() { } void ReplServer::read_data() { - int desired_size = 1; + int desired_size = (int)sizeof(ReplServerHeader); int got = 0; while (got < desired_size) { ASSERT(got + desired_size < buffer_size); int sock = accepted_socket; - auto x = read_from_socket(sock, buffer + got, desired_size - got); + auto x = read_from_socket(sock, header_buffer + got, desired_size - got); if (want_exit_callback()) { return; } got += x > 0 ? x : 0; } - auto* header = (ReplServerHeader*)(buffer); + auto* header = (ReplServerHeader*)(header_buffer); lock(); @@ -48,14 +48,14 @@ void ReplServer::read_data() { got += x > 0 ? x : 0; } - auto* body = (char*)(buffer); - switch (header->type) { case ReplServerMessageType::PING: ping_response(); break; case ReplServerMessageType::EVAL: - compile_msg("(repl-help)"); + std::string msg; + msg.assign(buffer, got); + compile_msg(msg); break; } @@ -83,10 +83,10 @@ void ReplServer::set_compiler(std::shared_ptr _compiler) { } void ReplServer::ping_response() { - u32 versions[2] = {versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR}; - char* ye = "sanity"; + std::string ping = fmt::format("Connected to OpenGOAL v{}.{} nREPL!", + versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR); lock(); - write_to_socket(accepted_socket, (char*)&ye, 6); + auto bytes_written = write_to_socket(accepted_socket, ping.c_str(), ping.size()); unlock(); } @@ -95,6 +95,6 @@ void ReplServer::compile_msg(const std::string_view& msg) { return; } compiler->lock(); - compiler->read_eval_print(msg.data()); + compiler->eval_and_print(compiler->read_from_string(msg.data())); compiler->unlock(); } diff --git a/goalc/compiler/nrepl/ReplServer.h b/goalc/compiler/nrepl/ReplServer.h index 2aae8cc2fb..5877e8c303 100644 --- a/goalc/compiler/nrepl/ReplServer.h +++ b/goalc/compiler/nrepl/ReplServer.h @@ -23,6 +23,7 @@ class ReplServer : public XSocketServer { private: std::shared_ptr compiler = nullptr; + char* header_buffer = new char[(int)sizeof(ReplServerHeader)]; void ping_response(); void compile_msg(const std::string_view& msg); diff --git a/goalc/main.cpp b/goalc/main.cpp index e0cf627213..0eb04c3e57 100644 --- a/goalc/main.cpp +++ b/goalc/main.cpp @@ -102,6 +102,7 @@ int main(int argc, char** argv) { } // Otherwise, run the REPL and such compiler = std::make_shared(username, std::make_unique()); + repl_server.set_compiler(compiler); // Start nREPL Server if (repl_server_ok) { nrepl_thread = std::thread([&]() { @@ -114,9 +115,16 @@ int main(int argc, char** argv) { } }); } + // Run automatic forms if applicable + if (auto_debug || auto_listen) { + compiler->eval_and_print(compiler->read_from_string("(lt)")); + } + if (auto_debug) { + compiler->eval_and_print(compiler->read_from_string("(dbg) (:cont)")); + } // Poll Terminal while (status == ReplStatus::WANT_RELOAD) { - status = compiler->execute_repl(auto_listen, auto_debug); + status = compiler->execute_repl(); if (status == ReplStatus::WANT_RELOAD) { fmt::print("Reloading compiler...\n"); } diff --git a/scripts/nrepl-test.py b/scripts/nrepl-test.py index 4fa431c640..a0d1a58ac1 100644 --- a/scripts/nrepl-test.py +++ b/scripts/nrepl-test.py @@ -1,6 +1,16 @@ import socket +import time clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM); clientSocket.connect(("127.0.0.1", 8181)) print(clientSocket) -num_sent = clientSocket.send(b'\x01\x02\x03\x04') +data = clientSocket.recv(1024) +print(data.decode()) + +form = "(repl-help)" + +num_sent = clientSocket.send(b'\x0B\x00\x00\x00\x0A\x00\x00\x00' + form.encode()) print("Sent {} bytes".format(num_sent)) + +# this shouldn't be necessary but...this is just a test script +# might imply something is wrong in the C++ code! +time.sleep(1000000)