Browse Source

Everywhere: Split REPL from main(), put settings in environment

master
Riyyi 1 year ago
parent
commit
705e80ad6b
  1. 9
      src/ast.cpp
  2. 15
      src/env/environment.cpp
  3. 6
      src/env/environment.h
  4. 5
      src/env/functions/collection-modify.cpp
  5. 3
      src/env/functions/mutable.cpp
  6. 7
      src/env/functions/repl.cpp
  7. 2
      src/eval-special-form.cpp
  8. 3
      src/eval.h
  9. 10
      src/forward.h
  10. 84
      src/main.cpp
  11. 2
      src/printer.cpp
  12. 8
      src/reader.cpp
  13. 89
      src/repl.cpp
  14. 29
      src/repl.h
  15. 13
      src/settings.cpp
  16. 8
      src/settings.h

9
src/ast.cpp

@ -226,7 +226,8 @@ Callable::Callable(ValuePtr meta)
// -----------------------------------------
Function::Function(std::string_view name, std::string_view bindings, std::string_view documentation, FunctionType function)
: m_name(name)
: Callable()
, m_name(name)
, m_bindings(bindings)
, m_documentation(documentation)
, m_function(function)
@ -243,14 +244,16 @@ Function::Function(const Function& that, ValuePtr meta)
// -----------------------------------------
Lambda::Lambda(const std::vector<std::string>& bindings, ValuePtr body, EnvironmentPtr env)
: m_bindings(bindings)
: Callable()
, m_bindings(bindings)
, m_body(body)
, m_env(env)
{
}
Lambda::Lambda(const Lambda& that)
: m_bindings(that.m_bindings)
: Callable()
, m_bindings(that.m_bindings)
, m_body(that.m_body)
, m_env(that.m_env)
{

15
src/env/environment.cpp vendored

@ -15,6 +15,7 @@
#include "env/environment.h"
#include "error.h"
#include "forward.h"
#include "repl.h"
namespace blaze {
@ -135,21 +136,21 @@ void Environment::installFunctions(EnvironmentPtr env)
}
for (const auto& lambda : s_lambdas) {
// Ensure all s-exprs are run with (do)
eval(read("(do " + lambda + ")"), env);
Repl::eval(Repl::read("(do " + lambda + ")"), env);
}
}
// -----------------------------------------
bool Environment::exists(const std::string& symbol)
bool Environment::exists(std::string_view symbol)
{
return m_values.find(symbol) != m_values.end();
return m_values.find(std::string(symbol)) != m_values.end();
}
ValuePtr Environment::set(const std::string& symbol, ValuePtr value)
ValuePtr Environment::set(std::string_view symbol, ValuePtr value)
{
if (exists(symbol)) {
m_values.erase(symbol);
m_values.erase(std::string(symbol));
}
m_values.emplace(symbol, value);
@ -157,10 +158,10 @@ ValuePtr Environment::set(const std::string& symbol, ValuePtr value)
return value;
}
ValuePtr Environment::get(const std::string& symbol)
ValuePtr Environment::get(std::string_view symbol)
{
if (exists(symbol)) {
return m_values[symbol];
return m_values[std::string(symbol)];
}
if (m_outer) {

6
src/env/environment.h vendored

@ -37,9 +37,9 @@ public:
static void registerFunction(FunctionParts function_parts);
static void installFunctions(EnvironmentPtr env);
bool exists(const std::string& symbol);
ValuePtr set(const std::string& symbol, ValuePtr value);
ValuePtr get(const std::string& symbol);
bool exists(std::string_view symbol);
ValuePtr set(std::string_view symbol, ValuePtr value);
ValuePtr get(std::string_view symbol);
private:
Environment() {}

5
src/env/functions/collection-modify.cpp vendored

@ -12,6 +12,7 @@
#include "env/environment.h"
#include "env/macro.h"
#include "forward.h"
#include "repl.h"
#include "util.h"
namespace blaze {
@ -47,7 +48,7 @@ void Environment::loadCollectionModify()
}
else {
auto lambda = std::static_pointer_cast<Lambda>(callable);
value = eval(lambda->body(), Environment::create(lambda, std::move(arguments)));
value = Repl::eval(lambda->body(), Environment::create(lambda, std::move(arguments)));
}
return value;
@ -152,7 +153,7 @@ void Environment::loadCollectionModify()
auto lambda = std::static_pointer_cast<Lambda>(callable);
auto collection_nodes = collection->nodesRead();
for (size_t i = 0; i < count; ++i) {
nodes.at(i) = (eval(lambda->body(), Environment::create(lambda, { collection_nodes[i] })));
nodes.at(i) = (Repl::eval(lambda->body(), Environment::create(lambda, { collection_nodes[i] })));
}
}

3
src/env/functions/mutable.cpp vendored

@ -11,6 +11,7 @@
#include "env/environment.h"
#include "env/macro.h"
#include "forward.h"
#include "repl.h"
#include "util.h"
namespace blaze {
@ -82,7 +83,7 @@ void Environment::loadMutable()
}
else {
auto lambda = std::static_pointer_cast<Lambda>(callable);
value = eval(lambda->body(), Environment::create(lambda, std::move(arguments)));
value = Repl::eval(lambda->body(), Environment::create(lambda, std::move(arguments)));
}
return atom->reset(value);

7
src/env/functions/repl.cpp vendored

@ -10,6 +10,7 @@
#include "ast.h"
#include "env/macro.h"
#include "repl.h"
#include "util.h"
namespace blaze {
@ -27,7 +28,7 @@ void Environment::loadRepl()
VALUE_CAST(node, String, (*begin));
std::string input = node->data();
return read(input);
return Repl::read(input);
});
// Read file contents
@ -56,7 +57,7 @@ void Environment::loadRepl()
VALUE_CAST(prompt, String, (*begin));
return readline(prompt->data());
return Repl::readline(prompt->data());
});
// REPL eval
@ -67,7 +68,7 @@ void Environment::loadRepl()
{
CHECK_ARG_COUNT_IS("eval", SIZE(), 1);
return eval(*begin, nullptr);
return Repl::eval(*begin, nullptr);
});
}

2
src/eval-special-form.cpp

@ -96,7 +96,7 @@ ValuePtr Eval::evalDescribe(const ValueVector& nodes, EnvironmentPtr env)
std::string documentation;
std::string value_string;
bool pretty_print = Settings::the().get("pretty-print") == "1";
bool pretty_print = Settings::the().getEnvBool("*PRETTY-PRINT*");
auto bold = fg(ruc::format::TerminalColor::None) | ruc::format::Emphasis::Bold;
auto describe = [&]() {

3
src/eval.h

@ -8,8 +8,7 @@
#include <vector>
#include "env/environment.h"
#include "forward.h"
#include "forward.h" // EnvironmentPtr
namespace blaze {

10
src/forward.h

@ -25,11 +25,15 @@ typedef ValueVector::const_reverse_iterator ValueVectorConstReverseIt;
class Environment;
typedef std::shared_ptr<Environment> EnvironmentPtr;
class Readline;
// -----------------------------------------
// Functions
extern ValuePtr readline(const std::string& prompt);
extern ValuePtr read(std::string_view input);
extern ValuePtr eval(ValuePtr ast, EnvironmentPtr env);
// -----------------------------------------
// Variables
extern Readline g_readline;
extern EnvironmentPtr g_outer_env;
} // namespace blaze

84
src/main.cpp

@ -0,0 +1,84 @@
/*
* Copyright (C) 2023 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#include <csignal> // std::signal
#include <string>
#include <string_view>
#include <vector>
#include "ruc/argparser.h"
#include "ruc/format/color.h"
#include "ruc/format/print.h"
#include "ast.h"
#include "env/environment.h"
#include "forward.h"
#include "repl.h"
#include "settings.h"
namespace blaze {
auto main(int argc, char* argv[]) -> int
{
bool dump_lexer = false;
bool dump_reader = false;
bool pretty_print = false;
std::string_view history_path = "~/.blaze-history";
std::vector<std::string> arguments;
// CLI arguments
ruc::ArgParser arg_parser;
arg_parser.addOption(dump_lexer, 'l', "dump-lexer", nullptr, nullptr);
arg_parser.addOption(dump_reader, 'r', "dump-reader", nullptr, nullptr);
arg_parser.addOption(pretty_print, 'c', "color", nullptr, nullptr);
arg_parser.addOption(history_path, 'h', "history-path", nullptr, nullptr, nullptr, ruc::ArgParser::Required::Yes);
// TODO: Add overload for addArgument(std::vector<std::string_view>)
arg_parser.addArgument(arguments, "arguments", nullptr, nullptr, ruc::ArgParser::Required::No);
arg_parser.parse(argc, argv);
// Set settings
g_outer_env->set("*DUMP-LEXER*", makePtr<Constant>(dump_lexer));
g_outer_env->set("*DUMP-READER*", makePtr<Constant>(dump_reader));
g_outer_env->set("*PRETTY-PRINT*", makePtr<Constant>(pretty_print));
// Signal callbacks
std::signal(SIGINT, Repl::cleanup);
std::signal(SIGTERM, Repl::cleanup);
Environment::loadFunctions();
Environment::installFunctions(g_outer_env);
Repl::makeArgv(g_outer_env, arguments);
if (arguments.size() > 0) {
Repl::rep(format("(load-file \"{}\")", arguments.front()), g_outer_env);
return 0;
}
Repl::rep("(println (str \"Blaze [\" *host-language* \"]\"))", g_outer_env);
g_readline = Readline(pretty_print, history_path);
std::string input;
while (g_readline.get(input)) {
std::string output = Repl::rep(input, g_outer_env);
if (output.length() > 0) {
print("{}\n", output);
}
}
if (pretty_print) {
print("\033[0m");
}
return 0;
}
} // namespace blaze
auto main(int argc, char* argv[]) -> int
{
return blaze::main(argc, argv);
}

2
src/printer.cpp

@ -66,7 +66,7 @@ void Printer::init()
void Printer::printImpl(ValuePtr value, bool print_readably)
{
bool pretty_print = Settings::the().get("pretty-print") == "1";
bool pretty_print = Settings::the().getEnvBool("*PRETTY-PRINT*");
auto printSpacing = [this]() -> void {
if (!m_first_node && !m_previous_node_is_list) {

8
src/reader.cpp

@ -147,7 +147,7 @@ ValuePtr Reader::readList()
nodes.push_back(node);
}
if (!consumeSpecific(Token { .type = Token::Type::ParenClose })) { // )
if (!consumeSpecific(Token { .type = Token::Type::ParenClose, .symbol = "" })) { // )
Error::the().add("expected ')', got EOF");
return nullptr;
}
@ -168,7 +168,7 @@ ValuePtr Reader::readVector()
nodes.push_back(node);
}
if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ]
if (!consumeSpecific(Token { .type = Token::Type::BracketClose, .symbol = "" })) { // ]
Error::the().add("expected ']', got EOF");
}
@ -201,7 +201,7 @@ ValuePtr Reader::readHashMap()
elements.insert_or_assign(HashMap::getKeyString(key), value);
}
if (!consumeSpecific(Token { .type = Token::Type::BraceClose })) { // }
if (!consumeSpecific(Token { .type = Token::Type::BraceClose, .symbol = "" })) { // }
Error::the().add("expected '}', got EOF");
return nullptr;
}
@ -378,7 +378,7 @@ void Reader::dumpImpl(ValuePtr node)
std::string indentation = std::string(m_indentation * INDENTATION_WIDTH, ' ');
print("{}", indentation);
bool pretty_print = Settings::the().get("pretty-print") == "1";
bool pretty_print = Settings::the().getEnvBool("*PRETTY-PRINT*");
auto blue = fg(ruc::format::TerminalColor::BrightBlue);
auto yellow = fg(ruc::format::TerminalColor::Yellow);

89
src/repl.cpp

@ -4,16 +4,13 @@
* SPDX-License-Identifier: MIT
*/
#include <csignal> // std::signal
#include <cstdlib> // std::exit
#include <string>
#include <string_view>
#include <vector>
#include "ruc/argparser.h"
#include "ruc/format/color.h"
#include "ruc/format/print.h"
#include "ast.h"
#include "env/environment.h"
#include "error.h"
#include "eval.h"
@ -22,50 +19,51 @@
#include "printer.h"
#include "reader.h"
#include "readline.h"
#include "repl.h"
#include "settings.h"
namespace blaze {
static blaze::Readline s_readline;
static EnvironmentPtr s_outer_env = Environment::create();
Readline g_readline;
EnvironmentPtr g_outer_env = Environment::create();
static auto cleanup(int signal) -> void
auto Repl::cleanup(int signal) -> void
{
print("\033[0m\n");
::print("\033[0m\n");
std::exit(signal);
}
auto readline(const std::string& prompt) -> ValuePtr
auto Repl::readline(const std::string& prompt) -> ValuePtr
{
std::string input;
if (s_readline.get(input, s_readline.createPrompt(prompt))) {
if (g_readline.get(input, g_readline.createPrompt(prompt))) {
return makePtr<String>(input);
}
return makePtr<Constant>();
}
auto read(std::string_view input) -> ValuePtr
auto Repl::read(std::string_view input) -> ValuePtr
{
Lexer lexer(input);
lexer.tokenize();
if (Settings::the().get("dump-lexer") == "1") {
if (Settings::the().getEnvBool("*DUMP-LEXER*")) {
lexer.dump();
}
Reader reader(std::move(lexer.tokens()));
reader.read();
if (Settings::the().get("dump-reader") == "1") {
if (Settings::the().getEnvBool("*DUMP-READER*")) {
reader.dump();
}
return reader.node();
}
auto eval(ValuePtr ast, EnvironmentPtr env) -> ValuePtr
auto Repl::eval(ValuePtr ast, EnvironmentPtr env) -> ValuePtr
{
if (env == nullptr) {
env = s_outer_env;
env = g_outer_env;
}
Eval eval(ast, env);
@ -74,14 +72,14 @@ auto eval(ValuePtr ast, EnvironmentPtr env) -> ValuePtr
return eval.ast();
}
static auto print(ValuePtr value) -> std::string
auto Repl::print(ValuePtr value) -> std::string
{
Printer printer;
return printer.print(value, true);
}
static auto rep(std::string_view input, EnvironmentPtr env) -> std::string
auto Repl::rep(std::string_view input, EnvironmentPtr env) -> std::string
{
Error::the().clearErrors();
Error::the().setInput(input);
@ -89,7 +87,7 @@ static auto rep(std::string_view input, EnvironmentPtr env) -> std::string
return print(eval(read(input), env));
}
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
auto Repl::makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
{
size_t count = arguments.size();
auto nodes = ValueVector();
@ -100,58 +98,3 @@ static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) ->
}
} // namespace blaze
auto main(int argc, char* argv[]) -> int
{
bool dump_lexer = false;
bool dump_reader = false;
bool pretty_print = false;
std::string_view history_path = "~/.blaze-history";
std::vector<std::string> arguments;
// CLI arguments
ruc::ArgParser arg_parser;
arg_parser.addOption(dump_lexer, 'l', "dump-lexer", nullptr, nullptr);
arg_parser.addOption(dump_reader, 'r', "dump-reader", nullptr, nullptr);
arg_parser.addOption(pretty_print, 'c', "color", nullptr, nullptr);
arg_parser.addOption(history_path, 'h', "history-path", nullptr, nullptr, nullptr, ruc::ArgParser::Required::Yes);
// TODO: Add overload for addArgument(std::vector<std::string_view>)
arg_parser.addArgument(arguments, "arguments", nullptr, nullptr, ruc::ArgParser::Required::No);
arg_parser.parse(argc, argv);
// Set settings
blaze::Settings::the().set("dump-lexer", dump_lexer ? "1" : "0");
blaze::Settings::the().set("dump-reader", dump_reader ? "1" : "0");
blaze::Settings::the().set("pretty-print", pretty_print ? "1" : "0");
// Signal callbacks
std::signal(SIGINT, blaze::cleanup);
std::signal(SIGTERM, blaze::cleanup);
blaze::Environment::loadFunctions();
blaze::Environment::installFunctions(blaze::s_outer_env);
makeArgv(blaze::s_outer_env, arguments);
if (arguments.size() > 0) {
rep(format("(load-file \"{}\")", arguments.front()), blaze::s_outer_env);
return 0;
}
rep("(println (str \"Blaze [\" *host-language* \"]\"))", blaze::s_outer_env);
blaze::s_readline = blaze::Readline(pretty_print, history_path);
std::string input;
while (blaze::s_readline.get(input)) {
std::string output = rep(input, blaze::s_outer_env);
if (output.length() > 0) {
print("{}\n", output);
}
}
if (pretty_print) {
print("\033[0m");
}
return 0;
}

29
src/repl.h

@ -0,0 +1,29 @@
/*
* Copyright (C) 2023 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <string>
#include <string_view>
#include <vector>
#include "forward.h"
#include "readline.h"
namespace blaze {
class Repl {
public:
static auto cleanup(int signal) -> void;
static auto eval(ValuePtr ast, EnvironmentPtr env) -> ValuePtr;
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void;
static auto print(ValuePtr value) -> std::string;
static auto read(std::string_view input) -> ValuePtr;
static auto readline(const std::string& prompt) -> ValuePtr;
static auto rep(std::string_view input, EnvironmentPtr env) -> std::string;
};
} // namespace blaze

13
src/settings.cpp

@ -4,7 +4,14 @@
* SPDX-License-Identifier: MIT
*/
#include <memory> // std::static_pointer_cast
#include "ruc/meta/assert.h"
#include "env/environment.h"
#include "forward.h"
#include "settings.h"
#include "types.h"
namespace blaze {
@ -14,4 +21,10 @@ std::string_view Settings::get(std::string_view key) const
return m_settings.at(key);
};
bool Settings::getEnvBool(std::string_view key) const
{
auto env = g_outer_env->get(key);
return is<Constant>(env.get()) && std::static_pointer_cast<Constant>(env)->state() == Constant::State::True;
}
} // namespace blaze

8
src/settings.h

@ -6,12 +6,10 @@
#pragma once
#include "ruc/meta/assert.h"
#include "ruc/singleton.h"
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "ruc/singleton.h"
namespace blaze {
@ -23,6 +21,8 @@ public:
std::string_view get(std::string_view key) const;
void set(std::string_view key, std::string_view value) { m_settings[key] = value; };
bool getEnvBool(std::string_view key) const;
private:
std::unordered_map<std::string_view, std::string_view> m_settings;
};

Loading…
Cancel
Save