Main+Env+Printer: Remove the GlobalEnvironment subclass
This commit is contained in:
+3
-2
@@ -65,8 +65,9 @@ Value::Value(State state)
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
Function::Function(FunctionType function)
|
Function::Function(const std::string& name, FunctionType function)
|
||||||
: m_function(function)
|
: m_name(name)
|
||||||
|
, m_function(function)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -202,14 +202,16 @@ using FunctionType = std::function<ASTNodePtr(std::list<ASTNodePtr>)>;
|
|||||||
|
|
||||||
class Function final : public ASTNode {
|
class Function final : public ASTNode {
|
||||||
public:
|
public:
|
||||||
explicit Function(FunctionType function);
|
explicit Function(const std::string& name, FunctionType function);
|
||||||
virtual ~Function() = default;
|
virtual ~Function() = default;
|
||||||
|
|
||||||
virtual bool isFunction() const override { return true; }
|
virtual bool isFunction() const override { return true; }
|
||||||
|
|
||||||
|
const std::string& name() const { return m_name; }
|
||||||
FunctionType function() const { return m_function; }
|
FunctionType function() const { return m_function; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const std::string m_name;
|
||||||
FunctionType m_function;
|
FunctionType m_function;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-30
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <memory> // std::static_pointer_cast
|
#include <memory> // std::static_pointer_cast
|
||||||
|
|
||||||
#include "ruc/format/print.h"
|
#include "ruc/format/format.h"
|
||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
@@ -88,8 +88,6 @@ ASTNodePtr Environment::set(const std::string& symbol, ASTNodePtr value)
|
|||||||
|
|
||||||
ASTNodePtr Environment::get(const std::string& symbol)
|
ASTNodePtr Environment::get(const std::string& symbol)
|
||||||
{
|
{
|
||||||
m_current_key = symbol;
|
|
||||||
|
|
||||||
if (exists(symbol)) {
|
if (exists(symbol)) {
|
||||||
return m_values[symbol];
|
return m_values[symbol];
|
||||||
}
|
}
|
||||||
@@ -101,31 +99,4 @@ ASTNodePtr Environment::get(const std::string& symbol)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
|
|
||||||
GlobalEnvironment::GlobalEnvironment()
|
|
||||||
{
|
|
||||||
add();
|
|
||||||
sub();
|
|
||||||
mul();
|
|
||||||
div();
|
|
||||||
|
|
||||||
lt();
|
|
||||||
lte();
|
|
||||||
gt();
|
|
||||||
gte();
|
|
||||||
|
|
||||||
list();
|
|
||||||
isList();
|
|
||||||
isEmpty();
|
|
||||||
count();
|
|
||||||
|
|
||||||
str();
|
|
||||||
prStr();
|
|
||||||
prn();
|
|
||||||
println();
|
|
||||||
|
|
||||||
equal();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
+1
-33
@@ -9,9 +9,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "badge.h"
|
|
||||||
#include "forward.h"
|
#include "forward.h"
|
||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
@@ -32,38 +30,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
Environment() {}
|
Environment() {}
|
||||||
|
|
||||||
std::string m_current_key;
|
|
||||||
std::unordered_map<std::string, ASTNodePtr> m_values;
|
|
||||||
EnvironmentPtr m_outer { nullptr };
|
EnvironmentPtr m_outer { nullptr };
|
||||||
};
|
std::unordered_map<std::string, ASTNodePtr> m_values;
|
||||||
|
|
||||||
class GlobalEnvironment final : public Environment {
|
|
||||||
public:
|
|
||||||
GlobalEnvironment();
|
|
||||||
virtual ~GlobalEnvironment() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void add(); // +
|
|
||||||
void sub(); // -
|
|
||||||
void mul(); // *
|
|
||||||
void div(); // /
|
|
||||||
|
|
||||||
void lt(); // <
|
|
||||||
void lte(); // <=
|
|
||||||
void gt(); // >
|
|
||||||
void gte(); // >=
|
|
||||||
|
|
||||||
void list(); // list
|
|
||||||
void isList(); // list?
|
|
||||||
void isEmpty(); // empty?
|
|
||||||
void count(); // count
|
|
||||||
|
|
||||||
void str(); // str
|
|
||||||
void prStr(); // pr-str
|
|
||||||
void prn(); // prn
|
|
||||||
void println(); // println
|
|
||||||
|
|
||||||
void equal(); // =
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
@@ -10,10 +10,18 @@
|
|||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
// Types
|
||||||
|
|
||||||
class ASTNode;
|
class ASTNode;
|
||||||
typedef std::shared_ptr<ASTNode> ASTNodePtr;
|
typedef std::shared_ptr<ASTNode> ASTNodePtr;
|
||||||
|
|
||||||
class Environment;
|
class Environment;
|
||||||
typedef std::shared_ptr<Environment> EnvironmentPtr;
|
typedef std::shared_ptr<Environment> EnvironmentPtr;
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
extern void installFunctions(EnvironmentPtr env);
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
+75
-108
@@ -7,7 +7,6 @@
|
|||||||
#include <memory> // std::static_pointer_cast
|
#include <memory> // std::static_pointer_cast
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ruc/format/color.h"
|
|
||||||
#include "ruc/format/format.h"
|
#include "ruc/format/format.h"
|
||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
@@ -18,11 +17,34 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
// At the top-level you cant invoke any function, but you can create variables.
|
||||||
|
// Using a struct's constructor you can work around this limitation.
|
||||||
|
// Also the line number in the file is used to make the struct names unique.
|
||||||
|
|
||||||
|
#define FUNCTION_STRUCT_NAME(unique) __functionStruct##unique
|
||||||
|
|
||||||
|
#define ADD_FUNCTION_IMPL(unique, symbol, lambda) \
|
||||||
|
struct FUNCTION_STRUCT_NAME(unique) { \
|
||||||
|
FUNCTION_STRUCT_NAME(unique) \
|
||||||
|
(std::string __symbol, FunctionType __lambda) \
|
||||||
|
{ \
|
||||||
|
s_functions.emplace(__symbol, __lambda); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
static struct FUNCTION_STRUCT_NAME(unique) \
|
||||||
|
FUNCTION_STRUCT_NAME(unique)( \
|
||||||
|
symbol, \
|
||||||
|
[](std::list<ASTNodePtr> nodes) -> ASTNodePtr lambda);
|
||||||
|
|
||||||
|
#define ADD_FUNCTION(symbol, lambda) ADD_FUNCTION_IMPL(__LINE__, symbol, lambda);
|
||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
void GlobalEnvironment::add()
|
static std::unordered_map<std::string, FunctionType> s_functions;
|
||||||
|
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"+",
|
||||||
{
|
{
|
||||||
auto add = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
int64_t result = 0;
|
int64_t result = 0;
|
||||||
|
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
@@ -35,14 +57,11 @@ void GlobalEnvironment::add()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Number>(result);
|
return makePtr<Number>(result);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("+", makePtr<Function>(add));
|
ADD_FUNCTION(
|
||||||
}
|
"-",
|
||||||
|
|
||||||
void GlobalEnvironment::sub()
|
|
||||||
{
|
{
|
||||||
auto sub = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
if (nodes.size() == 0) {
|
if (nodes.size() == 0) {
|
||||||
return makePtr<Number>(0);
|
return makePtr<Number>(0);
|
||||||
}
|
}
|
||||||
@@ -63,14 +82,11 @@ void GlobalEnvironment::sub()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Number>(result);
|
return makePtr<Number>(result);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("-", makePtr<Function>(sub));
|
ADD_FUNCTION(
|
||||||
}
|
"*",
|
||||||
|
|
||||||
void GlobalEnvironment::mul()
|
|
||||||
{
|
{
|
||||||
auto mul = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
int64_t result = 1;
|
int64_t result = 1;
|
||||||
|
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
@@ -83,16 +99,13 @@ void GlobalEnvironment::mul()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Number>(result);
|
return makePtr<Number>(result);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("*", makePtr<Function>(mul));
|
ADD_FUNCTION(
|
||||||
}
|
"/",
|
||||||
|
|
||||||
void GlobalEnvironment::div()
|
|
||||||
{
|
{
|
||||||
auto div = [this](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
if (nodes.size() == 0) {
|
if (nodes.size() == 0) {
|
||||||
Error::the().add(format("wrong number of arguments: {}, 0", m_current_key));
|
Error::the().add(format("wrong number of arguments: /, 0"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,19 +125,16 @@ void GlobalEnvironment::div()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Number>((int64_t)result);
|
return makePtr<Number>((int64_t)result);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("/", makePtr<Function>(div));
|
// // -----------------------------------------
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------
|
#define NUMBER_COMPARE(operator) \
|
||||||
|
{ \
|
||||||
#define NUMBER_COMPARE(symbol, comparison_symbol) \
|
|
||||||
auto lambda = [this](std::list<ASTNodePtr> nodes) -> ASTNodePtr { \
|
|
||||||
bool result = true; \
|
bool result = true; \
|
||||||
\
|
\
|
||||||
if (nodes.size() < 2) { \
|
if (nodes.size() < 2) { \
|
||||||
Error::the().add(format("wrong number of arguments: {}, {}", m_current_key, nodes.size() - 1)); \
|
Error::the().add(format("wrong number of arguments: {}, {}", #operator, nodes.size() - 1)); \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -141,7 +151,7 @@ void GlobalEnvironment::div()
|
|||||||
/* Skip the first node */ \
|
/* Skip the first node */ \
|
||||||
for (auto it = std::next(nodes.begin()); it != nodes.end(); ++it) { \
|
for (auto it = std::next(nodes.begin()); it != nodes.end(); ++it) { \
|
||||||
int64_t current_number = std::static_pointer_cast<Number>(*it)->number(); \
|
int64_t current_number = std::static_pointer_cast<Number>(*it)->number(); \
|
||||||
if (number comparison_symbol current_number) { \
|
if (!(number operator current_number)) { \
|
||||||
result = false; \
|
result = false; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
@@ -149,35 +159,18 @@ void GlobalEnvironment::div()
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return makePtr<Value>((result) ? Value::True : Value::False); \
|
return makePtr<Value>((result) ? Value::True : Value::False); \
|
||||||
}; \
|
|
||||||
\
|
|
||||||
m_values.emplace(symbol, makePtr<Function>(lambda));
|
|
||||||
|
|
||||||
void GlobalEnvironment::lt()
|
|
||||||
{
|
|
||||||
NUMBER_COMPARE("<", >=);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalEnvironment::lte()
|
ADD_FUNCTION("<", NUMBER_COMPARE(<));
|
||||||
{
|
ADD_FUNCTION("<=", NUMBER_COMPARE(<=));
|
||||||
NUMBER_COMPARE("<=", >);
|
ADD_FUNCTION(">", NUMBER_COMPARE(>));
|
||||||
}
|
ADD_FUNCTION(">=", NUMBER_COMPARE(>=));
|
||||||
|
|
||||||
void GlobalEnvironment::gt()
|
|
||||||
{
|
|
||||||
NUMBER_COMPARE(">", <=);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlobalEnvironment::gte()
|
|
||||||
{
|
|
||||||
NUMBER_COMPARE(">=", <);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
void GlobalEnvironment::list()
|
ADD_FUNCTION(
|
||||||
|
"list",
|
||||||
{
|
{
|
||||||
auto list = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
auto list = makePtr<List>();
|
auto list = makePtr<List>();
|
||||||
|
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
@@ -185,14 +178,11 @@ void GlobalEnvironment::list()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("list", makePtr<Function>(list));
|
ADD_FUNCTION(
|
||||||
}
|
"list?",
|
||||||
|
|
||||||
void GlobalEnvironment::isList()
|
|
||||||
{
|
{
|
||||||
auto is_list = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
@@ -203,14 +193,11 @@ void GlobalEnvironment::isList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Value>((result) ? Value::True : Value::False);
|
return makePtr<Value>((result) ? Value::True : Value::False);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("list?", makePtr<Function>(is_list));
|
ADD_FUNCTION(
|
||||||
}
|
"empty?",
|
||||||
|
|
||||||
void GlobalEnvironment::isEmpty()
|
|
||||||
{
|
{
|
||||||
auto is_empty = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
@@ -226,16 +213,13 @@ void GlobalEnvironment::isEmpty()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Value>((result) ? Value::True : Value::False);
|
return makePtr<Value>((result) ? Value::True : Value::False);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("empty?", makePtr<Function>(is_empty));
|
ADD_FUNCTION(
|
||||||
}
|
"count",
|
||||||
|
|
||||||
void GlobalEnvironment::count()
|
|
||||||
{
|
{
|
||||||
auto count = [this](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
if (nodes.size() != 1) {
|
if (nodes.size() != 1) {
|
||||||
Error::the().add(format("wrong number of arguments: {}, {}", m_current_key, nodes.size() - 1));
|
Error::the().add(format("wrong number of arguments: count, {}", nodes.size() - 1));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,15 +239,12 @@ void GlobalEnvironment::count()
|
|||||||
|
|
||||||
// FIXME: Add numeric_limits check for implicit cast: size_t > int64_t
|
// FIXME: Add numeric_limits check for implicit cast: size_t > int64_t
|
||||||
return makePtr<Number>((int64_t)result);
|
return makePtr<Number>((int64_t)result);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("count", makePtr<Function>(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
#define PRINTER_STRING(symbol, concatenation, print_readably) \
|
#define PRINTER_STRING(print_readably, concatenation) \
|
||||||
auto lambda = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr { \
|
{ \
|
||||||
std::string result; \
|
std::string result; \
|
||||||
\
|
\
|
||||||
Printer printer; \
|
Printer printer; \
|
||||||
@@ -276,22 +257,13 @@ void GlobalEnvironment::count()
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return makePtr<String>(result); \
|
return makePtr<String>(result); \
|
||||||
}; \
|
|
||||||
\
|
|
||||||
m_values.emplace(symbol, makePtr<Function>(lambda));
|
|
||||||
|
|
||||||
void GlobalEnvironment::str()
|
|
||||||
{
|
|
||||||
PRINTER_STRING("str", "", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalEnvironment::prStr()
|
ADD_FUNCTION("str", PRINTER_STRING(false, ""));
|
||||||
{
|
ADD_FUNCTION("pr-str", PRINTER_STRING(true, " "));
|
||||||
PRINTER_STRING("pr-str", " ", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PRINTER_PRINT(symbol, print_readably) \
|
#define PRINTER_PRINT(print_readably) \
|
||||||
auto lambda = [](std::list<ASTNodePtr> nodes) -> ASTNodePtr { \
|
{ \
|
||||||
Printer printer; \
|
Printer printer; \
|
||||||
for (auto it = nodes.begin(); it != nodes.end(); ++it) { \
|
for (auto it = nodes.begin(); it != nodes.end(); ++it) { \
|
||||||
print("{}", printer.printNoErrorCheck(*it, print_readably)); \
|
print("{}", printer.printNoErrorCheck(*it, print_readably)); \
|
||||||
@@ -303,27 +275,18 @@ void GlobalEnvironment::prStr()
|
|||||||
print("\n"); \
|
print("\n"); \
|
||||||
\
|
\
|
||||||
return makePtr<Value>(Value::Nil); \
|
return makePtr<Value>(Value::Nil); \
|
||||||
}; \
|
|
||||||
\
|
|
||||||
m_values.emplace(symbol, makePtr<Function>(lambda));
|
|
||||||
|
|
||||||
void GlobalEnvironment::prn()
|
|
||||||
{
|
|
||||||
PRINTER_PRINT("prn", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalEnvironment::println()
|
ADD_FUNCTION("prn", PRINTER_PRINT(true));
|
||||||
{
|
ADD_FUNCTION("println", PRINTER_PRINT(false));
|
||||||
PRINTER_PRINT("println", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
void GlobalEnvironment::equal()
|
ADD_FUNCTION(
|
||||||
|
"=",
|
||||||
{
|
{
|
||||||
auto lambda = [this](std::list<ASTNodePtr> nodes) -> ASTNodePtr {
|
|
||||||
if (nodes.size() < 2) {
|
if (nodes.size() < 2) {
|
||||||
Error::the().add(format("wrong number of arguments: {}, {}", m_current_key, nodes.size() - 1));
|
Error::the().add(format("wrong number of arguments: =, {}", nodes.size() - 1));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,9 +365,13 @@ void GlobalEnvironment::equal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return makePtr<Value>((result) ? Value::True : Value::False);
|
return makePtr<Value>((result) ? Value::True : Value::False);
|
||||||
};
|
});
|
||||||
|
|
||||||
m_values.emplace("=", makePtr<Function>(lambda));
|
void installFunctions(EnvironmentPtr env)
|
||||||
|
{
|
||||||
|
for (const auto& [name, lambda] : s_functions) {
|
||||||
|
env->set(name, makePtr<Function>(name, lambda));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
+2
-2
@@ -135,11 +135,11 @@ void Printer::printImpl(ASTNodePtr node, bool print_readably)
|
|||||||
}
|
}
|
||||||
else if (is<Function>(node_raw_ptr)) {
|
else if (is<Function>(node_raw_ptr)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
m_print += format("#<builtin-function>");
|
m_print += format("#<builtin-function>({})", std::static_pointer_cast<Function>(node)->name());
|
||||||
}
|
}
|
||||||
else if (is<Lambda>(node_raw_ptr)) {
|
else if (is<Lambda>(node_raw_ptr)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
m_print += format("#<user-function>");
|
m_print += format("#<user-function>({:p})", node_raw_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+68
-47
@@ -18,53 +18,14 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
static blaze::EnvironmentPtr env = blaze::makePtr<blaze::GlobalEnvironment>();
|
static blaze::EnvironmentPtr s_outer_env = blaze::Environment::create();
|
||||||
|
|
||||||
auto read(std::string_view input) -> blaze::ASTNodePtr
|
static auto cleanup(int signal) -> void;
|
||||||
{
|
static auto installLambdas(blaze::EnvironmentPtr env) -> void;
|
||||||
blaze::Lexer lexer(input);
|
static auto rep(std::string_view input, blaze::EnvironmentPtr env) -> std::string;
|
||||||
lexer.tokenize();
|
static auto read(std::string_view input) -> blaze::ASTNodePtr;
|
||||||
if (blaze::Settings::the().get("dump-lexer") == "1") {
|
static auto eval(blaze::ASTNodePtr ast, blaze::EnvironmentPtr env) -> blaze::ASTNodePtr;
|
||||||
lexer.dump();
|
static auto print(blaze::ASTNodePtr exp) -> std::string;
|
||||||
}
|
|
||||||
|
|
||||||
blaze::Reader reader(std::move(lexer.tokens()));
|
|
||||||
reader.read();
|
|
||||||
if (blaze::Settings::the().get("dump-reader") == "1") {
|
|
||||||
reader.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
return reader.node();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto eval(blaze::ASTNodePtr ast) -> blaze::ASTNodePtr
|
|
||||||
{
|
|
||||||
blaze::Eval eval(ast, env);
|
|
||||||
eval.eval();
|
|
||||||
|
|
||||||
return eval.ast();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto print(blaze::ASTNodePtr exp) -> std::string
|
|
||||||
{
|
|
||||||
blaze::Printer printer;
|
|
||||||
|
|
||||||
return printer.print(exp, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rep(std::string_view input) -> std::string
|
|
||||||
{
|
|
||||||
blaze::Error::the().clearErrors();
|
|
||||||
blaze::Error::the().setInput(input);
|
|
||||||
|
|
||||||
return print(eval(read(input)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto cleanup(int signal) -> void
|
|
||||||
{
|
|
||||||
print("\033[0m\n");
|
|
||||||
std::exit(signal);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto main(int argc, char* argv[]) -> int
|
auto main(int argc, char* argv[]) -> int
|
||||||
{
|
{
|
||||||
@@ -90,6 +51,9 @@ auto main(int argc, char* argv[]) -> int
|
|||||||
std::signal(SIGINT, cleanup);
|
std::signal(SIGINT, cleanup);
|
||||||
std::signal(SIGTERM, cleanup);
|
std::signal(SIGTERM, cleanup);
|
||||||
|
|
||||||
|
installFunctions(s_outer_env);
|
||||||
|
installLambdas(s_outer_env);
|
||||||
|
|
||||||
blaze::Readline readline(pretty_print, history_path);
|
blaze::Readline readline(pretty_print, history_path);
|
||||||
|
|
||||||
std::string input;
|
std::string input;
|
||||||
@@ -97,7 +61,7 @@ auto main(int argc, char* argv[]) -> int
|
|||||||
if (pretty_print) {
|
if (pretty_print) {
|
||||||
print("\033[0m");
|
print("\033[0m");
|
||||||
}
|
}
|
||||||
print("{}\n", rep(input));
|
print("{}\n", rep(input, s_outer_env));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print) {
|
if (pretty_print) {
|
||||||
@@ -106,4 +70,61 @@ auto main(int argc, char* argv[]) -> int
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto cleanup(int signal) -> void
|
||||||
|
{
|
||||||
|
print("\033[0m\n");
|
||||||
|
std::exit(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string_view lambdaTable[] = {
|
||||||
|
"(def! not (fn* (cond) (if cond false true)))",
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto installLambdas(blaze::EnvironmentPtr env) -> void
|
||||||
|
{
|
||||||
|
for (auto function : lambdaTable) {
|
||||||
|
rep(function, env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto rep(std::string_view input, blaze::EnvironmentPtr env) -> std::string
|
||||||
|
{
|
||||||
|
blaze::Error::the().clearErrors();
|
||||||
|
blaze::Error::the().setInput(input);
|
||||||
|
|
||||||
|
return print(eval(read(input), env));
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto read(std::string_view input) -> blaze::ASTNodePtr
|
||||||
|
{
|
||||||
|
blaze::Lexer lexer(input);
|
||||||
|
lexer.tokenize();
|
||||||
|
if (blaze::Settings::the().get("dump-lexer") == "1") {
|
||||||
|
lexer.dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
blaze::Reader reader(std::move(lexer.tokens()));
|
||||||
|
reader.read();
|
||||||
|
if (blaze::Settings::the().get("dump-reader") == "1") {
|
||||||
|
reader.dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader.node();
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto eval(blaze::ASTNodePtr ast, blaze::EnvironmentPtr env) -> blaze::ASTNodePtr
|
||||||
|
{
|
||||||
|
blaze::Eval eval(ast, env);
|
||||||
|
eval.eval();
|
||||||
|
|
||||||
|
return eval.ast();
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto print(blaze::ASTNodePtr exp) -> std::string
|
||||||
|
{
|
||||||
|
blaze::Printer printer;
|
||||||
|
|
||||||
|
return printer.print(exp, true);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user