ADD: 'and', 'or', 'not' boolean operations.

main
bog 2023-09-24 13:03:33 +02:00
parent a08f722598
commit b6c6ac3302
9 changed files with 114 additions and 2 deletions

18
examples/bool.fk Normal file
View File

@ -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))

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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());
}
} }

View File

@ -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

View File

@ -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()))

View File

@ -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;

View File

@ -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"