ADD: if macro and comparison functions.
parent
11a7f6a9da
commit
4d91c05aea
|
@ -0,0 +1,35 @@
|
|||
(assert= true (> 5 2))
|
||||
(assert= false (> 5 5))
|
||||
(assert= false (> 5 8))
|
||||
(assert= true (>= 5 2))
|
||||
(assert= true (>= 5 5))
|
||||
(assert= false (>= 5 8))
|
||||
(assert= true (< 1 2))
|
||||
(assert= false (< 3 3))
|
||||
(assert= false (< 5 2))
|
||||
(assert= true (<= 1 2))
|
||||
(assert= true (<= 3 3))
|
||||
(assert= false (<= 5 2))
|
||||
|
||||
(assert= true (> 5. 2.))
|
||||
(assert= false (> 5. 5.))
|
||||
(assert= false (> 5. 8.))
|
||||
(assert= true (>= 5. 2.))
|
||||
(assert= true (>= 5. 5.))
|
||||
(assert= false (>= 5. 8.))
|
||||
(assert= true (< 1. 2.))
|
||||
(assert= false (< 3. 3.))
|
||||
(assert= false (< 5. 2.))
|
||||
(assert= true (<= 1. 2.))
|
||||
(assert= true (<= 3. 3.))
|
||||
(assert= false (<= 5. 2.))
|
||||
|
||||
(assert= true (= 12 12))
|
||||
(assert= false (= 1 3))
|
||||
(assert= false (<> 16 16))
|
||||
(assert= true (<> 19 7))
|
||||
|
||||
(assert= true (= 12. 12.))
|
||||
(assert= false (= 1. 3.))
|
||||
(assert= false (<> 1.6 1.6))
|
||||
(assert= true (<> 19. 7.))
|
|
@ -0,0 +1,5 @@
|
|||
($ a (if true 12 78))
|
||||
($ b (if false 46 966))
|
||||
|
||||
(assert= 12 a)
|
||||
(assert= 966 b)
|
|
@ -1,5 +1,23 @@
|
|||
#include "fun.hpp"
|
||||
|
||||
#define NUM_BINOP(OP)\
|
||||
auto lhs = args[0]; \
|
||||
auto rhs = args[1]; \
|
||||
bool res = false; \
|
||||
\
|
||||
if (lhs->type() == TYPE_INT) \
|
||||
{ \
|
||||
res = std::get<int>(lhs->value()) OP std::get<int>(rhs->value()); \
|
||||
} \
|
||||
\
|
||||
if (lhs->type() == TYPE_FLOAT) \
|
||||
{ \
|
||||
res = std::get<float>(lhs->value()) OP std::get<float>(rhs->value()); \
|
||||
} \
|
||||
\
|
||||
return std::make_shared<Constant>(TYPE_BOOL, res, loc)
|
||||
|
||||
|
||||
namespace fkstd
|
||||
{
|
||||
STDRET assert_eq(Loc loc, STDARGS args)
|
||||
|
@ -147,4 +165,34 @@ namespace fkstd
|
|||
|
||||
return std::make_shared<Constant>(TYPE_INT, result, loc);
|
||||
}
|
||||
|
||||
STDRET lt(Loc loc, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(<);
|
||||
}
|
||||
|
||||
STDRET le(Loc loc, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(<=);
|
||||
}
|
||||
|
||||
STDRET gt(Loc loc, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(>);
|
||||
}
|
||||
|
||||
STDRET ge(Loc loc, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(>=);
|
||||
}
|
||||
|
||||
STDRET eq(Loc loc, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(==);
|
||||
}
|
||||
|
||||
STDRET ne(Loc loc, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(!=);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,13 @@ namespace fkstd
|
|||
STDRET div_int(Loc loc, STDARGS args);
|
||||
STDRET mod_int(Loc loc, STDARGS args);
|
||||
STDRET pow_int(Loc loc, STDARGS args);
|
||||
|
||||
STDRET lt(Loc loc, STDARGS args);
|
||||
STDRET le(Loc loc, STDARGS args);
|
||||
STDRET gt(Loc loc, STDARGS args);
|
||||
STDRET ge(Loc loc, STDARGS args);
|
||||
STDRET eq(Loc loc, STDARGS args);
|
||||
STDRET ne(Loc loc, STDARGS args);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,8 +12,15 @@ extern "C" void lib(Module& mod)
|
|||
mod.register_function("/", fkstd::div_int);
|
||||
mod.register_function("%", fkstd::mod_int);
|
||||
mod.register_function("^", fkstd::pow_int);
|
||||
mod.register_function("<", fkstd::lt);
|
||||
mod.register_function("<=", fkstd::le);
|
||||
mod.register_function(">", fkstd::gt);
|
||||
mod.register_function(">=", fkstd::ge);
|
||||
mod.register_function("=", fkstd::eq);
|
||||
mod.register_function("<>", fkstd::ne);
|
||||
|
||||
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
|
||||
mod.register_macro(":", fkstd::block);
|
||||
mod.register_macro("$", fkstd::decl);
|
||||
mod.register_macro("if", fkstd::if_macro);
|
||||
}
|
||||
|
|
|
@ -62,4 +62,23 @@ namespace fkstd
|
|||
|
||||
compiler.sym()->leave_scope();
|
||||
}
|
||||
|
||||
void if_macro(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program)
|
||||
{
|
||||
auto if_expr = node->child(1);
|
||||
auto then_expr = node->child(2);
|
||||
auto else_expr = node->child(3);
|
||||
|
||||
compiler.compile_prog(if_expr, program);
|
||||
size_t to_else = program->add(OP_BNE, 0 /*else*/);
|
||||
|
||||
compiler.compile_prog(then_expr, program);
|
||||
size_t to_end = program->add(OP_BR, 0 /* end */);
|
||||
|
||||
program->set_param(to_else, program->size());
|
||||
compiler.compile_prog(else_expr, program);
|
||||
program->set_param(to_end, program->size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ namespace fkstd
|
|||
void block(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program);
|
||||
|
||||
void if_macro(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace fk
|
|||
case NODE_CALL: {
|
||||
std::string ident = node->child(0)->repr();
|
||||
|
||||
|
||||
if (auto itr=m_macros.find(ident);
|
||||
itr != std::end(m_macros))
|
||||
{
|
||||
|
|
|
@ -16,6 +16,12 @@ namespace fk
|
|||
return m_instrs.size() - 1;
|
||||
}
|
||||
|
||||
void Program::set_param(size_t index, addr_t param)
|
||||
{
|
||||
assert(index < m_instrs.size());
|
||||
m_instrs[index].param = param;
|
||||
}
|
||||
|
||||
Instr Program::instr(size_t index) const
|
||||
{
|
||||
assert(index < size());
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace fk
|
|||
size_t const_size() const { return m_consts.size(); }
|
||||
|
||||
size_t add(Opcode opcode, addr_t param=NO_PARAM);
|
||||
void set_param(size_t index, addr_t param);
|
||||
|
||||
Instr instr(size_t index) const;
|
||||
std::shared_ptr<Constant> get_const(addr_t addr) const;
|
||||
|
||||
|
|
19
src/VM.cpp
19
src/VM.cpp
|
@ -27,6 +27,25 @@ namespace fk
|
|||
|
||||
switch (instr.opcode)
|
||||
{
|
||||
case OP_BR: {
|
||||
m_pc = instr.param;
|
||||
} break;
|
||||
|
||||
case OP_BNE: {
|
||||
auto cond_val = frame().program->get_const(pop());
|
||||
bool cond = std::get<bool>(cond_val->value());
|
||||
|
||||
if (!cond)
|
||||
{
|
||||
m_pc = instr.param;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pc++;
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case OP_MAKE_FUNCTION: {
|
||||
auto p = frame().program->get_const(pop());
|
||||
auto prog = std::get<std::shared_ptr<Program>>(p->value());
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
#define OPCODES(G) G(OP_LOAD_CONST), G(OP_POP), G(OP_CALL_NATIVE), \
|
||||
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_MAKE_FUNCTION), G(OP_CALL_REF), G(OP_RET), G(OP_BNE), \
|
||||
G(OP_BR)
|
||||
|
||||
#include "commons.hpp"
|
||||
|
||||
|
|
Loading…
Reference in New Issue