Compare commits
3
Commits
cf8e5dfc66
...
3aa99d0045
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3aa99d0045 | ||
|
|
a099e955cf | ||
|
|
63a19170ef |
+32
-40
@@ -95,49 +95,41 @@ add_custom_target(run
|
|||||||
# ------------------------------------------
|
# ------------------------------------------
|
||||||
# Test targets
|
# Test targets
|
||||||
|
|
||||||
add_custom_target(test0
|
function(make_test_target target_name step_name)
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step0_repl.mal -- ./${PROJECT})
|
add_custom_target(${target_name}
|
||||||
add_dependencies(test0 ${PROJECT})
|
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/${step_name}.mal -- ./${step_name})
|
||||||
|
add_dependencies(${target_name} ${step_name})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
add_custom_target(test1
|
make_test_target("test0" "step0_repl")
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step1_read_print.mal -- ./${PROJECT})
|
make_test_target("test1" "step1_read_print")
|
||||||
add_dependencies(test1 ${PROJECT})
|
make_test_target("test2" "step2_eval")
|
||||||
|
make_test_target("test3" "step3_env")
|
||||||
|
make_test_target("test4" "step4_if_fn_do")
|
||||||
|
make_test_target("test5" "step5_tco")
|
||||||
|
make_test_target("test6" "step6_file")
|
||||||
|
make_test_target("test7" "step7_quote")
|
||||||
|
make_test_target("test8" "step8_macros")
|
||||||
|
make_test_target("test9" "step9_try")
|
||||||
|
make_test_target("testA" "stepA_mal")
|
||||||
|
|
||||||
add_custom_target(test2
|
function(make_host_test_target target_name step_name)
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step2_eval.mal -- ./${PROJECT})
|
add_custom_target(${target_name}
|
||||||
add_dependencies(test2 ${PROJECT})
|
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/${step_name}.mal -- ./${PROJECT} ../mal/${step_name}.mal)
|
||||||
|
add_dependencies(${target_name} ${PROJECT})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
add_custom_target(test3
|
make_host_test_target("host_test0" "step0_repl")
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step3_env.mal -- ./${PROJECT})
|
make_host_test_target("host_test1" "step1_read_print")
|
||||||
add_dependencies(test3 ${PROJECT})
|
make_host_test_target("host_test2" "step2_eval")
|
||||||
|
make_host_test_target("host_test3" "step3_env")
|
||||||
add_custom_target(test4
|
make_host_test_target("host_test4" "step4_if_fn_do")
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step4_if_fn_do.mal -- ./${PROJECT})
|
# make_host_test_target("host_test5" "step5_tco") # disabled
|
||||||
add_dependencies(test4 ${PROJECT})
|
make_host_test_target("host_test6" "step6_file")
|
||||||
|
make_host_test_target("host_test7" "step7_quote")
|
||||||
add_custom_target(test5
|
make_host_test_target("host_test8" "step8_macros")
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step5_tco.mal -- ./${PROJECT})
|
make_host_test_target("host_test9" "step9_try")
|
||||||
add_dependencies(test5 ${PROJECT})
|
make_host_test_target("host_testA" "stepA_mal")
|
||||||
|
|
||||||
add_custom_target(test6
|
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step6_file.mal -- ./${PROJECT})
|
|
||||||
add_dependencies(test6 ${PROJECT})
|
|
||||||
|
|
||||||
add_custom_target(test7
|
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step7_quote.mal -- ./${PROJECT})
|
|
||||||
add_dependencies(test7 ${PROJECT})
|
|
||||||
|
|
||||||
add_custom_target(test8
|
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step8_macros.mal -- ./${PROJECT})
|
|
||||||
add_dependencies(test8 ${PROJECT})
|
|
||||||
|
|
||||||
add_custom_target(test9
|
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/step9_try.mal -- ./${PROJECT})
|
|
||||||
add_dependencies(test9 ${PROJECT})
|
|
||||||
|
|
||||||
add_custom_target(testA
|
|
||||||
COMMAND ../vendor/mal/runtest.py --deferrable --optional ../tests/stepA_mal.mal -- ./${PROJECT})
|
|
||||||
add_dependencies(testA ${PROJECT})
|
|
||||||
|
|
||||||
add_custom_target(perf
|
add_custom_target(perf
|
||||||
COMMAND ./${PROJECT} ../tests/perf1.mal
|
COMMAND ./${PROJECT} ../tests/perf1.mal
|
||||||
|
|||||||
+69
-65
@@ -30,8 +30,8 @@ ValuePtr Eval::evalDef(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
VALUE_CAST(symbol, Symbol, nodes.front());
|
VALUE_CAST(symbol, Symbol, nodes.front());
|
||||||
|
|
||||||
// Eval second argument
|
// Eval second argument
|
||||||
m_ast_stack.push(*std::next(nodes.begin()));
|
m_ast = *std::next(nodes.begin());
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
ValuePtr value = evalImpl();
|
ValuePtr value = evalImpl();
|
||||||
|
|
||||||
// Dont overwrite symbols after an error
|
// Dont overwrite symbols after an error
|
||||||
@@ -52,8 +52,8 @@ ValuePtr Eval::evalDefMacro(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
VALUE_CAST(symbol, Symbol, nodes.front());
|
VALUE_CAST(symbol, Symbol, nodes.front());
|
||||||
|
|
||||||
// Eval second argument
|
// Eval second argument
|
||||||
m_ast_stack.push(*std::next(nodes.begin()));
|
m_ast = *std::next(nodes.begin());
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
ValuePtr value = evalImpl();
|
ValuePtr value = evalImpl();
|
||||||
VALUE_CAST(lambda, Lambda, value);
|
VALUE_CAST(lambda, Lambda, value);
|
||||||
|
|
||||||
@@ -111,6 +111,55 @@ ValuePtr Eval::evalQuote(const ValueVector& nodes)
|
|||||||
return nodes.front();
|
return nodes.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (try* x (catch* y z))
|
||||||
|
ValuePtr Eval::evalTry(const ValueVector& nodes, EnvironmentPtr env)
|
||||||
|
{
|
||||||
|
CHECK_ARG_COUNT_AT_LEAST("try*", nodes.size(), 1);
|
||||||
|
|
||||||
|
// Try 'x'
|
||||||
|
m_ast = nodes.front();
|
||||||
|
m_env = env;
|
||||||
|
auto result = evalImpl();
|
||||||
|
|
||||||
|
if (!Error::the().hasAnyError()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (nodes.size() == 1) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch
|
||||||
|
|
||||||
|
// Get the error message
|
||||||
|
auto error = (Error::the().hasOtherError())
|
||||||
|
? makePtr<String>(Error::the().otherError())
|
||||||
|
: Error::the().exception();
|
||||||
|
Error::the().clearErrors();
|
||||||
|
|
||||||
|
VALUE_CAST(catch_list, List, nodes.back());
|
||||||
|
const auto& catch_nodes = catch_list->nodes();
|
||||||
|
CHECK_ARG_COUNT_IS("catch*", catch_nodes.size() - 1, 2);
|
||||||
|
|
||||||
|
VALUE_CAST(catch_symbol, Symbol, catch_nodes.front());
|
||||||
|
if (catch_symbol->symbol() != "catch*") {
|
||||||
|
Error::the().add("catch block must begin with catch*");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE_CAST(catch_binding, Symbol, (*std::next(catch_nodes.begin())));
|
||||||
|
|
||||||
|
// Create new Environment that binds 'y' to the value of the exception
|
||||||
|
auto catch_env = Environment::create(env);
|
||||||
|
catch_env->set(catch_binding->symbol(), error);
|
||||||
|
|
||||||
|
// Evaluate 'z' using the new Environment
|
||||||
|
m_ast = catch_nodes.back();
|
||||||
|
m_env = catch_env;
|
||||||
|
return evalImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
// (do 1 2 3)
|
// (do 1 2 3)
|
||||||
void Eval::evalDo(const ValueVector& nodes, EnvironmentPtr env)
|
void Eval::evalDo(const ValueVector& nodes, EnvironmentPtr env)
|
||||||
{
|
{
|
||||||
@@ -118,14 +167,14 @@ void Eval::evalDo(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
|
|
||||||
// Evaluate all nodes except the last
|
// Evaluate all nodes except the last
|
||||||
for (auto it = nodes.begin(); it != std::prev(nodes.end(), 1); ++it) {
|
for (auto it = nodes.begin(); it != std::prev(nodes.end(), 1); ++it) {
|
||||||
m_ast_stack.push(*it);
|
m_ast = *it;
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
evalImpl();
|
evalImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eval last node
|
// Eval last node
|
||||||
m_ast_stack.push(nodes.back());
|
m_ast = nodes.back();
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
return; // TCO
|
return; // TCO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,18 +187,18 @@ void Eval::evalIf(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
auto second_argument = *std::next(nodes.begin());
|
auto second_argument = *std::next(nodes.begin());
|
||||||
auto third_argument = (nodes.size() == 3) ? *std::next(std::next(nodes.begin())) : makePtr<Constant>(Constant::Nil);
|
auto third_argument = (nodes.size() == 3) ? *std::next(std::next(nodes.begin())) : makePtr<Constant>(Constant::Nil);
|
||||||
|
|
||||||
m_ast_stack.push(first_argument);
|
m_ast = first_argument;
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
auto first_evaluated = evalImpl();
|
auto first_evaluated = evalImpl();
|
||||||
if (!is<Constant>(first_evaluated.get())
|
if (!is<Constant>(first_evaluated.get())
|
||||||
|| std::static_pointer_cast<Constant>(first_evaluated)->state() == Constant::True) {
|
|| std::static_pointer_cast<Constant>(first_evaluated)->state() == Constant::True) {
|
||||||
m_ast_stack.push(second_argument);
|
m_ast = second_argument;
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
return; // TCO
|
return; // TCO
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ast_stack.push(third_argument);
|
m_ast = third_argument;
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
return; // TCO
|
return; // TCO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,16 +222,16 @@ void Eval::evalLet(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
VALUE_CAST(elt, Symbol, (*it), void());
|
VALUE_CAST(elt, Symbol, (*it), void());
|
||||||
|
|
||||||
std::string key = elt->symbol();
|
std::string key = elt->symbol();
|
||||||
m_ast_stack.push(*std::next(it));
|
m_ast = *std::next(it);
|
||||||
m_env_stack.push(let_env);
|
m_env = let_env;
|
||||||
ValuePtr value = evalImpl();
|
ValuePtr value = evalImpl();
|
||||||
let_env->set(key, value);
|
let_env->set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove limitation of 3 arguments
|
// TODO: Remove limitation of 3 arguments
|
||||||
// Eval all arguments in this new env, return last sexp of the result
|
// Eval all arguments in this new env, return last sexp of the result
|
||||||
m_ast_stack.push(*std::next(nodes.begin()));
|
m_ast = *std::next(nodes.begin());
|
||||||
m_env_stack.push(let_env);
|
m_env = let_env;
|
||||||
return; // TCO
|
return; // TCO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,53 +326,8 @@ void Eval::evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
|
|
||||||
auto result = evalQuasiQuoteImpl(nodes.front());
|
auto result = evalQuasiQuoteImpl(nodes.front());
|
||||||
|
|
||||||
m_ast_stack.push(result);
|
m_ast = result;
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
return; // TCO
|
|
||||||
}
|
|
||||||
|
|
||||||
// (try* x (catch* y z))
|
|
||||||
void Eval::evalTry(const ValueVector& nodes, EnvironmentPtr env)
|
|
||||||
{
|
|
||||||
CHECK_ARG_COUNT_AT_LEAST("try*", nodes.size(), 1, void());
|
|
||||||
|
|
||||||
// Try 'x'
|
|
||||||
m_ast_stack.push(nodes.front());
|
|
||||||
m_env_stack.push(env);
|
|
||||||
auto result = evalImpl();
|
|
||||||
|
|
||||||
// Catch
|
|
||||||
if (nodes.size() == 2 && (Error::the().hasOtherError() || Error::the().hasException())) {
|
|
||||||
// Get the exception
|
|
||||||
auto error = (Error::the().hasOtherError())
|
|
||||||
? makePtr<String>(Error::the().otherError())
|
|
||||||
: Error::the().exception();
|
|
||||||
Error::the().clearErrors();
|
|
||||||
|
|
||||||
VALUE_CAST(catch_list, List, nodes.back(), void());
|
|
||||||
const auto& catch_nodes = catch_list->nodes();
|
|
||||||
CHECK_ARG_COUNT_IS("catch*", catch_nodes.size() - 1, 2, void());
|
|
||||||
|
|
||||||
VALUE_CAST(catch_symbol, Symbol, catch_nodes.front(), void());
|
|
||||||
if (catch_symbol->symbol() != "catch*") {
|
|
||||||
Error::the().add("catch block must begin with catch*");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VALUE_CAST(catch_binding, Symbol, (*std::next(catch_nodes.begin())), void());
|
|
||||||
|
|
||||||
// Create new Environment that binds 'y' to the value of the exception
|
|
||||||
auto catch_env = Environment::create(env);
|
|
||||||
catch_env->set(catch_binding->symbol(), error);
|
|
||||||
|
|
||||||
// Evaluate 'z' using the new Environment
|
|
||||||
m_ast_stack.push(catch_nodes.back());
|
|
||||||
m_env_stack.push(catch_env);
|
|
||||||
return; // TCO
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ast_stack.push(result);
|
|
||||||
m_env_stack.push(env);
|
|
||||||
return; // TCO
|
return; // TCO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-30
@@ -23,6 +23,7 @@ namespace blaze {
|
|||||||
Eval::Eval(ValuePtr ast, EnvironmentPtr env)
|
Eval::Eval(ValuePtr ast, EnvironmentPtr env)
|
||||||
: m_ast(ast)
|
: m_ast(ast)
|
||||||
, m_env(env)
|
, m_env(env)
|
||||||
|
, m_outer_env(env)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,11 +31,6 @@ Eval::Eval(ValuePtr ast, EnvironmentPtr env)
|
|||||||
|
|
||||||
void Eval::eval()
|
void Eval::eval()
|
||||||
{
|
{
|
||||||
m_ast_stack = std::stack<ValuePtr>();
|
|
||||||
m_env_stack = std::stack<EnvironmentPtr>();
|
|
||||||
m_ast_stack.push(m_ast);
|
|
||||||
m_env_stack.push(m_env);
|
|
||||||
|
|
||||||
m_ast = evalImpl();
|
m_ast = evalImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,20 +44,13 @@ ValuePtr Eval::evalImpl()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ast_stack.size() == 0) {
|
ast = m_ast;
|
||||||
return nullptr;
|
env = m_env;
|
||||||
|
|
||||||
|
if (env == nullptr) {
|
||||||
|
env = m_outer_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_env_stack.size() == 0) {
|
|
||||||
m_env_stack.push(m_env);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast = m_ast_stack.top();
|
|
||||||
env = m_env_stack.top();
|
|
||||||
|
|
||||||
m_ast_stack.pop();
|
|
||||||
m_env_stack.pop();
|
|
||||||
|
|
||||||
if (!is<List>(ast.get())) {
|
if (!is<List>(ast.get())) {
|
||||||
return evalAst(ast, env);
|
return evalAst(ast, env);
|
||||||
}
|
}
|
||||||
@@ -100,6 +89,9 @@ ValuePtr Eval::evalImpl()
|
|||||||
if (symbol == "quote") {
|
if (symbol == "quote") {
|
||||||
return evalQuote(nodes);
|
return evalQuote(nodes);
|
||||||
}
|
}
|
||||||
|
if (symbol == "try*") {
|
||||||
|
return evalTry(nodes, env);
|
||||||
|
}
|
||||||
// Tail call optimized functions
|
// Tail call optimized functions
|
||||||
if (symbol == "do") {
|
if (symbol == "do") {
|
||||||
evalDo(nodes, env);
|
evalDo(nodes, env);
|
||||||
@@ -117,10 +109,6 @@ ValuePtr Eval::evalImpl()
|
|||||||
evalQuasiQuote(nodes, env);
|
evalQuasiQuote(nodes, env);
|
||||||
continue; // TCO
|
continue; // TCO
|
||||||
}
|
}
|
||||||
if (symbol == "try*") {
|
|
||||||
evalTry(nodes, env);
|
|
||||||
continue; // TCO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evaluated_list = std::static_pointer_cast<List>(evalAst(ast, env));
|
auto evaluated_list = std::static_pointer_cast<List>(evalAst(ast, env));
|
||||||
@@ -133,8 +121,8 @@ ValuePtr Eval::evalImpl()
|
|||||||
if (is<Lambda>(evaluated_list->front().get())) {
|
if (is<Lambda>(evaluated_list->front().get())) {
|
||||||
auto lambda = std::static_pointer_cast<Lambda>(evaluated_list->front());
|
auto lambda = std::static_pointer_cast<Lambda>(evaluated_list->front());
|
||||||
|
|
||||||
m_ast_stack.push(lambda->body());
|
m_ast = lambda->body();
|
||||||
m_env_stack.push(Environment::create(lambda, evaluated_list->rest()));
|
m_env = Environment::create(lambda, evaluated_list->rest());
|
||||||
continue; // TCO
|
continue; // TCO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +153,8 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env)
|
|||||||
auto evaluated_nodes = ValueVector(count);
|
auto evaluated_nodes = ValueVector(count);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
m_ast_stack.push(nodes[i]);
|
m_ast = nodes[i];
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
ValuePtr eval_node = evalImpl();
|
ValuePtr eval_node = evalImpl();
|
||||||
if (eval_node == nullptr) {
|
if (eval_node == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -184,8 +172,8 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env)
|
|||||||
const auto& elements = std::static_pointer_cast<HashMap>(ast)->elements();
|
const auto& elements = std::static_pointer_cast<HashMap>(ast)->elements();
|
||||||
Elements evaluated_elements;
|
Elements evaluated_elements;
|
||||||
for (const auto& element : elements) {
|
for (const auto& element : elements) {
|
||||||
m_ast_stack.push(element.second);
|
m_ast = element.second;
|
||||||
m_env_stack.push(env);
|
m_env = env;
|
||||||
ValuePtr element_node = evalImpl();
|
ValuePtr element_node = evalImpl();
|
||||||
if (element_node == nullptr) {
|
if (element_node == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -231,18 +219,19 @@ ValuePtr Eval::macroExpand(ValuePtr ast, EnvironmentPtr env)
|
|||||||
{
|
{
|
||||||
while (isMacroCall(ast, env)) {
|
while (isMacroCall(ast, env)) {
|
||||||
auto list = std::static_pointer_cast<List>(ast);
|
auto list = std::static_pointer_cast<List>(ast);
|
||||||
|
|
||||||
auto value = env->get(std::static_pointer_cast<Symbol>(list->front())->symbol());
|
auto value = env->get(std::static_pointer_cast<Symbol>(list->front())->symbol());
|
||||||
auto lambda = std::static_pointer_cast<Lambda>(value);
|
auto lambda = std::static_pointer_cast<Lambda>(value);
|
||||||
|
|
||||||
m_ast_stack.push(lambda->body());
|
m_ast = lambda->body();
|
||||||
m_env_stack.push(Environment::create(lambda, list->rest()));
|
m_env = Environment::create(lambda, list->rest());
|
||||||
ast = evalImpl();
|
ast = evalImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
ValuePtr Eval::apply(std::shared_ptr<List> evaluated_list)
|
ValuePtr Eval::apply(std::shared_ptr<List> evaluated_list)
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-4
@@ -38,19 +38,18 @@ private:
|
|||||||
ValuePtr evalMacroExpand(const ValueVector& nodes, EnvironmentPtr env);
|
ValuePtr evalMacroExpand(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
ValuePtr evalQuasiQuoteExpand(const ValueVector& nodes);
|
ValuePtr evalQuasiQuoteExpand(const ValueVector& nodes);
|
||||||
ValuePtr evalQuote(const ValueVector& nodes);
|
ValuePtr evalQuote(const ValueVector& nodes);
|
||||||
|
ValuePtr evalTry(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
|
|
||||||
void evalDo(const ValueVector& nodes, EnvironmentPtr env);
|
void evalDo(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalIf(const ValueVector& nodes, EnvironmentPtr env);
|
void evalIf(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalLet(const ValueVector& nodes, EnvironmentPtr env);
|
void evalLet(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env);
|
void evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalTry(const ValueVector& nodes, EnvironmentPtr env);
|
|
||||||
|
|
||||||
ValuePtr apply(std::shared_ptr<List> evaluated_list);
|
ValuePtr apply(std::shared_ptr<List> evaluated_list);
|
||||||
|
|
||||||
ValuePtr m_ast;
|
ValuePtr m_ast;
|
||||||
EnvironmentPtr m_env;
|
EnvironmentPtr m_env;
|
||||||
|
EnvironmentPtr m_outer_env;
|
||||||
std::stack<ValuePtr> m_ast_stack;
|
|
||||||
std::stack<EnvironmentPtr> m_env_stack;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
+3
-3
@@ -518,7 +518,7 @@ ADD_FUNCTION(
|
|||||||
return makePtr<List>(collection->rest());
|
return makePtr<List>(collection->rest());
|
||||||
});
|
});
|
||||||
|
|
||||||
// (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4)
|
// (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4) -> 10
|
||||||
ADD_FUNCTION(
|
ADD_FUNCTION(
|
||||||
"apply",
|
"apply",
|
||||||
{
|
{
|
||||||
@@ -984,8 +984,8 @@ ADD_FUNCTION(
|
|||||||
|
|
||||||
void installFunctions(EnvironmentPtr env)
|
void installFunctions(EnvironmentPtr env)
|
||||||
{
|
{
|
||||||
for (const auto& [name, lambda] : s_functions) {
|
for (const auto& [name, function] : s_functions) {
|
||||||
env->set(name, makePtr<Function>(name, lambda));
|
env->set(name, makePtr<Function>(name, function));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,18 +176,3 @@ auto main(int argc, char* argv[]) -> int
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: List of things below
|
|
||||||
// v Pass stepA tests (implement leftover functions)
|
|
||||||
// v Make Macro into a subclass of Lambda (?) to simplify some logic
|
|
||||||
// v Convert std::list -> std::vector, test speed before/after
|
|
||||||
// v Better way of running mal tests
|
|
||||||
// - Make Collections/HashMaps const, construct a new one with the added items
|
|
||||||
// - Basic performance testing macros, enabled in debug builds
|
|
||||||
|
|
||||||
// Iterations to beat:
|
|
||||||
// Debug: ~5k
|
|
||||||
// Release: ~30k
|
|
||||||
// New:
|
|
||||||
// Debug: ~6k
|
|
||||||
// Release: ~37k
|
|
||||||
|
|||||||
Reference in New Issue
Block a user