Compare commits
5 Commits
d30e42b4e8
...
f9f73dabd3
Author | SHA1 | Date |
---|---|---|
bog | f9f73dabd3 | |
bog | 951a538cc2 | |
bog | b6c6ac3302 | |
bog | a08f722598 | |
bog | d9e06eeabd |
|
@ -1,13 +1,13 @@
|
|||
(assert= 8 ([2 6 2 8 9] 3))
|
||||
(assert= 9 ([[3 6] [9 2]] 1 0))
|
||||
(assert= 8 (ref [2 6 2 8 9] 3))
|
||||
(assert= 9 (ref [[3 6] [9 2]] 1 0))
|
||||
|
||||
($ a ['a' [[2 true] 2.3]])
|
||||
|
||||
(assert= 'a' (a 0))
|
||||
(assert= 2 (a 1 0 0))
|
||||
(assert= 'a' (ref a 0))
|
||||
(assert= 2 (ref a 1 0 0))
|
||||
|
||||
($ (second arr)
|
||||
(arr 1))
|
||||
(ref arr 1))
|
||||
|
||||
(assert= 6 (second [2 6]))
|
||||
|
||||
|
@ -15,3 +15,6 @@
|
|||
[2 4 6])
|
||||
|
||||
(assert= 4 (second (produce)))
|
||||
|
||||
($ arr [2 'bim' produce false])
|
||||
(assert= 6 (ref ((ref arr 2)) 2))
|
|
@ -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))
|
|
@ -0,0 +1,20 @@
|
|||
(assert= 7.2 7.20)
|
||||
|
||||
(assert= 4.7 (+. 3.2 1.5))
|
||||
(assert= 3.2 (+. 3.2))
|
||||
(assert= 0.0 (+.))
|
||||
|
||||
(assert= 1.7 (-. 3.2 1.5))
|
||||
(assert= -1.5 (-. 1.5))
|
||||
(assert= 0.0 (-.))
|
||||
|
||||
(assert= 77.4 (*. 21.5 3.6))
|
||||
(assert= 3.0 (*. 3.0))
|
||||
(assert= 1.0 (*.))
|
||||
|
||||
(assert= 0.57 (/. 1.14 2.0))
|
||||
(assert= .25 (/. 4.0))
|
||||
(assert= 1.0 (/.))
|
||||
|
||||
(assert= 1.5 (%. 75. 3.5))
|
||||
(assert= 15.625 (^. 2.5 3.))
|
|
@ -0,0 +1,3 @@
|
|||
(assert= 'hello world' (cat 'hello' ' world'))
|
||||
(assert= 'yoyoyo' (dup 'yo' 3))
|
||||
(assert= 'e' (char-at 'hello' 1))
|
184
libstd/fun.cpp
184
libstd/fun.cpp
|
@ -166,6 +166,118 @@ namespace fkstd
|
|||
return std::make_shared<Constant>(TYPE_INT, result, loc);
|
||||
}
|
||||
|
||||
STDRET add_float(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 0.0f, loc);
|
||||
}
|
||||
|
||||
float result = std::get<float>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
result = result + std::get<float>(args[i]->value());
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||
}
|
||||
|
||||
STDRET sub_float(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 0.0f, loc);
|
||||
}
|
||||
|
||||
float result = std::get<float>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
result = result - std::get<float>(args[i]->value());
|
||||
}
|
||||
|
||||
if (args.size() == 1)
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, -result, loc);
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||
}
|
||||
|
||||
STDRET mul_float(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
||||
}
|
||||
|
||||
float result = std::get<float>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
result = result * std::get<float>(args[i]->value());
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||
}
|
||||
|
||||
STDRET div_float(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
||||
}
|
||||
|
||||
float result = std::get<float>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
result = result / std::get<float>(args[i]->value());
|
||||
}
|
||||
|
||||
if (args.size() == 1)
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f/result, loc);
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||
}
|
||||
|
||||
STDRET mod_float(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
||||
}
|
||||
|
||||
float result = std::get<float>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
result = std::fmod(result, std::get<float>(args[i]->value()));
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||
}
|
||||
|
||||
STDRET pow_float(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, 1.0f, loc);
|
||||
}
|
||||
|
||||
float result = std::get<float>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
result = std::pow(result, std::get<float>(args[i]->value()));
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||
}
|
||||
|
||||
STDRET lt(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
NUM_BINOP(<);
|
||||
|
@ -195,4 +307,76 @@ namespace fkstd
|
|||
{
|
||||
NUM_BINOP(!=);
|
||||
}
|
||||
|
||||
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();
|
||||
size_t ref = std::get<size_t>(ref_val);
|
||||
|
||||
std::shared_ptr<Array> val =
|
||||
std::get<std::shared_ptr<Array>>(mod.vm()->load_global(ref));
|
||||
|
||||
for (size_t i=1; i<args.size() - 1; i++)
|
||||
{
|
||||
int k = std::get<int>(args[i]->value());
|
||||
|
||||
auto ref_val = val->at(k)->value();
|
||||
size_t ref = std::get<size_t>(ref_val);
|
||||
|
||||
auto arr =
|
||||
std::get<std::shared_ptr<Array>>(mod.vm()->load_global(ref));
|
||||
|
||||
val = arr;
|
||||
|
||||
}
|
||||
|
||||
return val->at(std::get<int>(args.back()->value()));
|
||||
}
|
||||
|
||||
STDRET string_cat(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
return std::make_shared<Constant>(TYPE_STRING, "", loc);
|
||||
}
|
||||
|
||||
std::string value = std::get<std::string>(args[0]->value());
|
||||
|
||||
for (size_t i=1; i<args.size(); i++)
|
||||
{
|
||||
value += std::get<std::string>(args[i]->value());
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_STRING, value, loc);
|
||||
}
|
||||
|
||||
STDRET string_dup(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
std::string str = std::get<std::string>(args[0]->value());
|
||||
int n = std::get<int>(args[1]->value());
|
||||
std::string res;
|
||||
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
res += str;
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_STRING, res, loc);
|
||||
}
|
||||
|
||||
STDRET char_at(Loc loc, Module&, STDARGS args)
|
||||
{
|
||||
std::string str = std::get<std::string>(args[0]->value());
|
||||
int n = std::get<int>(args[1]->value());
|
||||
|
||||
return std::make_shared<Constant>(TYPE_STRING,
|
||||
std::string(1, str[n]),
|
||||
loc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,26 @@ namespace fkstd
|
|||
STDRET mod_int(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET pow_int(Loc loc, Module& mod, STDARGS args);
|
||||
|
||||
STDRET add_float(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET sub_float(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET mul_float(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET div_float(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET mod_float(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET pow_float(Loc loc, Module& mod, STDARGS args);
|
||||
|
||||
STDRET lt(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET le(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET gt(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET ge(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET eq(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 string_cat(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET string_dup(Loc loc, Module& mod, STDARGS args);
|
||||
STDRET char_at(Loc loc, Module& mod, STDARGS args);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,14 @@ 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::add_float);
|
||||
mod.register_function("-.", fkstd::sub_float);
|
||||
mod.register_function("*.", fkstd::mul_float);
|
||||
mod.register_function("/.", fkstd::div_float);
|
||||
mod.register_function("%.", fkstd::mod_float);
|
||||
mod.register_function("^.", fkstd::pow_float);
|
||||
|
||||
mod.register_function("<", fkstd::lt);
|
||||
mod.register_function("<=", fkstd::le);
|
||||
mod.register_function(">", fkstd::gt);
|
||||
|
@ -19,8 +27,16 @@ extern "C" void lib(Module& mod)
|
|||
mod.register_function("=", fkstd::eq);
|
||||
mod.register_function("<>", fkstd::ne);
|
||||
|
||||
mod.register_function("not", fkstd::bool_not);
|
||||
mod.register_function("ref", fkstd::array_ref);
|
||||
mod.register_function("cat", fkstd::string_cat);
|
||||
mod.register_function("dup", fkstd::string_dup);
|
||||
mod.register_function("char-at", fkstd::char_at);
|
||||
|
||||
mod.register_macro("!", fkstd::set_addr);
|
||||
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
|
||||
mod.register_macro(":", fkstd::block);
|
||||
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);
|
||||
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,
|
||||
std::shared_ptr<Node> node,
|
||||
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
|
||||
|
|
|
@ -198,6 +198,7 @@ namespace fk
|
|||
{
|
||||
auto macro = itr->second;
|
||||
macro->call(*this, node, prog);
|
||||
break;
|
||||
}
|
||||
else if (node->child(0)->type() == NODE_NS
|
||||
&& has_macro(node->child(0)->child(1)->repr()))
|
||||
|
@ -218,12 +219,7 @@ namespace fk
|
|||
compile_prog(node->child(i), prog);
|
||||
}
|
||||
|
||||
if (node->child(0)->type() == NODE_ARRAY)
|
||||
{
|
||||
prog->add(OP_CALL_REF, node->size() - 1);
|
||||
break;
|
||||
}
|
||||
else if (node->child(0)->type() == NODE_LAMBDA
|
||||
if (node->child(0)->type() == NODE_LAMBDA
|
||||
|| node->child(0)->type() == NODE_CALL
|
||||
|| node->child(0)->type() == NODE_NS)
|
||||
{
|
||||
|
@ -236,7 +232,8 @@ namespace fk
|
|||
entry && entry->is_global() == false)
|
||||
{
|
||||
if (entry->node()
|
||||
&& entry->node()->child(1)->type() != NODE_ARRAY)
|
||||
&& entry->node()
|
||||
&& entry->node()->type() == NODE_LAMBDA)
|
||||
{
|
||||
size_t arity = entry->node()->child(0)->size();
|
||||
if (arity != node->size() - 1)
|
||||
|
@ -262,6 +259,7 @@ namespace fk
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "cannot call node '"
|
||||
<< node->string() << "'" << std::endl;
|
||||
abort();
|
||||
|
|
|
@ -196,7 +196,7 @@ namespace fk
|
|||
cursor++;
|
||||
}
|
||||
|
||||
if (repr.empty() || repr.back() == '-' || repr == ".")
|
||||
if (repr.empty() || repr.back() == '-' || repr == "." || repr == "-.")
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
35
src/VM.cpp
35
src/VM.cpp
|
@ -212,6 +212,16 @@ namespace fk
|
|||
m_pc++;
|
||||
} 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: {
|
||||
m_pc = instr.param;
|
||||
} break;
|
||||
|
@ -310,31 +320,6 @@ namespace fk
|
|||
m_pc++;
|
||||
break;
|
||||
}
|
||||
else if (std::get_if<std::shared_ptr<Array>>(&val))
|
||||
{
|
||||
std::shared_ptr<Array> val =
|
||||
std::get<std::shared_ptr<Array>>(load_global(ref));
|
||||
|
||||
for (size_t i=0; i<args.size() - 1; i++)
|
||||
{
|
||||
int k = std::get<int>(args[i]->value());
|
||||
auto ref_val = val->at(k)->value();
|
||||
|
||||
size_t ref = std::get<size_t>(ref_val);
|
||||
|
||||
auto arr =
|
||||
std::get<std::shared_ptr<Array>>(load_global(ref));
|
||||
|
||||
val = arr;
|
||||
|
||||
}
|
||||
|
||||
push(frame().program->add
|
||||
(val->at(std::get<int>(args.back()->value()))));
|
||||
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
|
||||
auto lambda = std::get<std::shared_ptr<Lambda>>(load_global(ref));
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace fk
|
|||
};
|
||||
class Module;
|
||||
|
||||
FK_ERROR(execution_error);
|
||||
|
||||
class VM
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
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_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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue