From e6f2b95fb543b535b1914bd4954e240dbd724275 Mon Sep 17 00:00:00 2001 From: olpc user Date: Mon, 9 Dec 2019 06:51:41 -0800 Subject: positional argument sugar for habits --- starts/meaning-vm/level-2/funcs.cpp | 43 ++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'starts/meaning-vm/level-2/funcs.cpp') 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 argnames, std::function 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 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; +} + } } -- cgit v1.2.3