REF: adding ref function for arrays deref.

main
bog 2023-09-24 12:17:42 +02:00
parent d9e06eeabd
commit a08f722598
7 changed files with 40 additions and 40 deletions

View File

@ -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]))
@ -17,4 +17,4 @@
(assert= 4 (second (produce)))
($ arr [2 'bim' produce false])
(assert= 6 (((arr 2)) 2))
(assert= 6 (ref ((ref arr 2)) 2))

View File

@ -195,4 +195,29 @@ namespace fkstd
{
NUM_BINOP(!=);
}
STDRET array_ref(Loc 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()));
}
}

View File

@ -20,6 +20,8 @@ namespace fkstd
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 array_ref(Loc loc, Module& mod, STDARGS args);
}
#endif

View File

@ -18,6 +18,7 @@ extern "C" void lib(Module& mod)
mod.register_function(">=", fkstd::ge);
mod.register_function("=", fkstd::eq);
mod.register_function("<>", fkstd::ne);
mod.register_function("ref", fkstd::array_ref);
mod.register_macro("!", fkstd::set_addr);
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);

View File

@ -218,12 +218,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,10 +231,9 @@ namespace fk
entry && entry->is_global() == false)
{
if (entry->node()
&& entry->node()->child(1)->type() != NODE_ARRAY
&& entry->node()->type() != NODE_ARRAY)
&& entry->node()
&& entry->node()->type() == NODE_LAMBDA)
{
std::cout << "-> " << entry->node()->string() << std::endl;
size_t arity = entry->node()->child(0)->size();
if (arity != node->size() - 1)
{
@ -264,6 +258,7 @@ namespace fk
break;
}
}
std::cerr << "cannot call node '"
<< node->string() << "'" << std::endl;
abort();

View File

@ -310,31 +310,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));

View File

@ -23,6 +23,8 @@ namespace fk
};
class Module;
FK_ERROR(execution_error);
class VM
{
public: