diff options
author | olpc user <olpc@xo-5d-f7-86.localdomain> | 2019-12-09 06:51:41 -0800 |
---|---|---|
committer | olpc user <olpc@xo-5d-f7-86.localdomain> | 2019-12-09 06:51:41 -0800 |
commit | e6f2b95fb543b535b1914bd4954e240dbd724275 (patch) | |
tree | dcd081c1098489bc5c2172e5e535abb56094e763 /starts/meaning-vm/level-2/funcs.cpp | |
parent | 8ceeb5f83f22ed3db06fc02bb23710ccc1dbbb90 (diff) | |
download | standingwithresilience-e6f2b95fb543b535b1914bd4954e240dbd724275.tar.gz standingwithresilience-e6f2b95fb543b535b1914bd4954e240dbd724275.zip |
positional argument sugar for habits
Diffstat (limited to 'starts/meaning-vm/level-2/funcs.cpp')
-rw-r--r-- | starts/meaning-vm/level-2/funcs.cpp | 43 |
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; +} + } } |