summaryrefslogtreecommitdiff
path: root/starts/meaning-vm/level-2/funcs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'starts/meaning-vm/level-2/funcs.cpp')
-rw-r--r--starts/meaning-vm/level-2/funcs.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/starts/meaning-vm/level-2/funcs.cpp b/starts/meaning-vm/level-2/funcs.cpp
index c25ead2..b17d221 100644
--- a/starts/meaning-vm/level-2/funcs.cpp
+++ b/starts/meaning-vm/level-2/funcs.cpp
@@ -2,17 +2,58 @@
#include "../level-1/sugar.hpp"
#include "ref.hpp"
+#include "concepts.hpp"
namespace intellect {
using namespace level1;
namespace level2 {
+using namespace concepts;
+
ref context()
{
- static thread_local auto ctx = a("context");
+ static thread_local auto ctx = a(concepts::context);
return ctx;
}
+ref makehabit(ref name, std::initializer_list<ref> argnames, std::function<void()> code)
+{
+ ref habit = level1::a(habit, name);
+ ref posarg = habit;
+ for (auto argname : argnames) {
+ ref nextarg = a(positional-argument);
+ nextarg.set(argument, argname);
+ posarg.set(next-positional-argument, nextarg);
+ posarg = nextarg;
+ }
+ habit.fun(code);
+ return habit;
+}
+
+ref dohabit(ref habit, std::initializer_list<ref> args)
+{
+ using namespace concepts;
+ ref posarg = habit;
+ for (ref const & arg : args) {
+ if (!posarg.linked(next-positional-argument)) {
+ throw std::invalid_argument("wrong number of arguments to habit");
+ }
+ posarg = posarg[next-positional-argument];
+ // TODO: subcontexts
+ ref::context().set(posarg[argument], arg);
+ }
+ if (posarg.linked(next-positional-argument)) {
+ throw std::invalid_argument("wrong number of arguments to habit");
+ }
+ ref ret = habit.fun<>()();
+ posarg = habit;
+ while (posarg.linked(next-positional-argument)) {
+ posarg = posarg[next-positional-argument];
+ ref::context().unlink(posarg[argument]);
+ }
+ return ret;
+}
+
}
}