ADD: 'and', 'or', 'not' boolean operations.
parent
a08f722598
commit
b6c6ac3302
|
@ -0,0 +1,18 @@
|
||||||
|
(assert= true true)
|
||||||
|
(assert= false false)
|
||||||
|
|
||||||
|
(assert= false (not true))
|
||||||
|
(assert= true (not false))
|
||||||
|
|
||||||
|
(assert= true (and true true))
|
||||||
|
(assert= false (and true false))
|
||||||
|
(assert= false (and false true))
|
||||||
|
(assert= false (and false false))
|
||||||
|
|
||||||
|
(assert= true (or true true))
|
||||||
|
(assert= true (or true false))
|
||||||
|
(assert= true (or false true))
|
||||||
|
(assert= false (or false false))
|
||||||
|
|
||||||
|
(and false (: (assert= 0 1) false))
|
||||||
|
(or true (: (assert= 0 1) false))
|
|
@ -196,7 +196,13 @@ namespace fkstd
|
||||||
NUM_BINOP(!=);
|
NUM_BINOP(!=);
|
||||||
}
|
}
|
||||||
|
|
||||||
STDRET array_ref(Loc loc, Module& mod, STDARGS args)
|
STDRET bool_not(Loc loc, Module&, STDARGS args)
|
||||||
|
{
|
||||||
|
bool val = std::get<bool>(args[0]->value());
|
||||||
|
return std::make_shared<Constant>(TYPE_BOOL, !val, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDRET array_ref(Loc, Module& mod, STDARGS args)
|
||||||
{
|
{
|
||||||
auto ref_val = args[0]->value();
|
auto ref_val = args[0]->value();
|
||||||
size_t ref = std::get<size_t>(ref_val);
|
size_t ref = std::get<size_t>(ref_val);
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace fkstd
|
||||||
STDRET eq(Loc loc, Module& mod, STDARGS args);
|
STDRET eq(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET ne(Loc loc, Module& mod, STDARGS args);
|
STDRET ne(Loc loc, Module& mod, STDARGS args);
|
||||||
|
|
||||||
|
STDRET bool_not(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET array_ref(Loc loc, Module& mod, STDARGS args);
|
STDRET array_ref(Loc loc, Module& mod, STDARGS args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,14 @@ extern "C" void lib(Module& mod)
|
||||||
mod.register_function(">=", fkstd::ge);
|
mod.register_function(">=", fkstd::ge);
|
||||||
mod.register_function("=", fkstd::eq);
|
mod.register_function("=", fkstd::eq);
|
||||||
mod.register_function("<>", fkstd::ne);
|
mod.register_function("<>", fkstd::ne);
|
||||||
|
|
||||||
|
mod.register_function("not", fkstd::bool_not);
|
||||||
mod.register_function("ref", fkstd::array_ref);
|
mod.register_function("ref", fkstd::array_ref);
|
||||||
|
|
||||||
mod.register_macro("!", fkstd::set_addr);
|
mod.register_macro("!", fkstd::set_addr);
|
||||||
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
|
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
|
||||||
mod.register_macro(":", fkstd::block);
|
mod.register_macro(":", fkstd::block);
|
||||||
mod.register_macro("if", fkstd::if_macro);
|
mod.register_macro("if", fkstd::if_macro);
|
||||||
|
mod.register_macro("and", fkstd::and_macro);
|
||||||
|
mod.register_macro("or", fkstd::or_macro);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,4 +103,67 @@ namespace fkstd
|
||||||
compiler.compile_prog(else_expr, program);
|
compiler.compile_prog(else_expr, program);
|
||||||
program->set_param(to_end, program->size());
|
program->set_param(to_end, program->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void and_macro(Compiler& compiler,
|
||||||
|
std::shared_ptr<Node> node,
|
||||||
|
std::shared_ptr<Program> program)
|
||||||
|
{
|
||||||
|
std::vector<size_t> to_false;
|
||||||
|
|
||||||
|
for (size_t i=1; i<node->size(); i++)
|
||||||
|
{
|
||||||
|
compiler.compile_prog(node->child(i), program);
|
||||||
|
size_t addr = program->add(OP_BNE, 0 /* to end*/);
|
||||||
|
to_false.push_back(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
||||||
|
true,
|
||||||
|
node->loc()));
|
||||||
|
|
||||||
|
size_t out_addr = program->add(OP_BR, 0 /* to end*/);
|
||||||
|
|
||||||
|
for (auto addr: to_false)
|
||||||
|
{
|
||||||
|
program->set_param(addr, program->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
||||||
|
false,
|
||||||
|
node->loc()));
|
||||||
|
|
||||||
|
program->set_param(out_addr, program->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void or_macro(Compiler& compiler,
|
||||||
|
std::shared_ptr<Node> node,
|
||||||
|
std::shared_ptr<Program> program)
|
||||||
|
{
|
||||||
|
std::vector<size_t> to_true;
|
||||||
|
|
||||||
|
for (size_t i=1; i<node->size(); i++)
|
||||||
|
{
|
||||||
|
compiler.compile_prog(node->child(i), program);
|
||||||
|
program->add(OP_NOT);
|
||||||
|
size_t addr = program->add(OP_BNE, 0 /* to end*/);
|
||||||
|
to_true.push_back(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
||||||
|
false,
|
||||||
|
node->loc()));
|
||||||
|
|
||||||
|
size_t out_addr = program->add(OP_BR, 0 /* to end*/);
|
||||||
|
|
||||||
|
for (auto addr: to_true)
|
||||||
|
{
|
||||||
|
program->set_param(addr, program->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
||||||
|
true,
|
||||||
|
node->loc()));
|
||||||
|
|
||||||
|
program->set_param(out_addr, program->size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,14 @@ namespace fkstd
|
||||||
void if_macro(Compiler& compiler,
|
void if_macro(Compiler& compiler,
|
||||||
std::shared_ptr<Node> node,
|
std::shared_ptr<Node> node,
|
||||||
std::shared_ptr<Program> program);
|
std::shared_ptr<Program> program);
|
||||||
|
|
||||||
|
void and_macro(Compiler& compiler,
|
||||||
|
std::shared_ptr<Node> node,
|
||||||
|
std::shared_ptr<Program> program);
|
||||||
|
|
||||||
|
void or_macro(Compiler& compiler,
|
||||||
|
std::shared_ptr<Node> node,
|
||||||
|
std::shared_ptr<Program> program);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -198,6 +198,7 @@ namespace fk
|
||||||
{
|
{
|
||||||
auto macro = itr->second;
|
auto macro = itr->second;
|
||||||
macro->call(*this, node, prog);
|
macro->call(*this, node, prog);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (node->child(0)->type() == NODE_NS
|
else if (node->child(0)->type() == NODE_NS
|
||||||
&& has_macro(node->child(0)->child(1)->repr()))
|
&& has_macro(node->child(0)->child(1)->repr()))
|
||||||
|
|
10
src/VM.cpp
10
src/VM.cpp
|
@ -212,6 +212,16 @@ namespace fk
|
||||||
m_pc++;
|
m_pc++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case OP_NOT: {
|
||||||
|
auto c_val = frame().program->get_const(pop());
|
||||||
|
bool val = std::get<bool>(c_val->value());
|
||||||
|
push(frame().
|
||||||
|
program->add(std::make_shared<Constant>(TYPE_BOOL,
|
||||||
|
!val,
|
||||||
|
c_val->loc())));
|
||||||
|
m_pc++;
|
||||||
|
} break;
|
||||||
|
|
||||||
case OP_BR: {
|
case OP_BR: {
|
||||||
m_pc = instr.param;
|
m_pc = instr.param;
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
G(OP_LOAD_GLOBAL), G(OP_LOAD_LOCAL), G(OP_STORE_LOCAL), \
|
G(OP_LOAD_GLOBAL), G(OP_LOAD_LOCAL), G(OP_STORE_LOCAL), \
|
||||||
G(OP_MAKE_FUNCTION), G(OP_CALL_REF), G(OP_RET), G(OP_BNE), \
|
G(OP_MAKE_FUNCTION), G(OP_CALL_REF), G(OP_RET), G(OP_BNE), \
|
||||||
G(OP_BR), G(OP_LOAD_CLOSURE), G(OP_STORE_CLOSURE), \
|
G(OP_BR), G(OP_LOAD_CLOSURE), G(OP_STORE_CLOSURE), \
|
||||||
G(OP_LOAD_MOD), G(OP_IMPORT), G(OP_IMPORT_SYS), G(OP_MAKE_ARRAY)
|
G(OP_LOAD_MOD), G(OP_IMPORT), G(OP_IMPORT_SYS), G(OP_MAKE_ARRAY), \
|
||||||
|
G(OP_NOT)
|
||||||
|
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue