blob: a8835f4151d7457965603f851048af4ebaa34cd7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#include "funcs.hpp"
#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(concepts::context);
return ctx;
}
ref makehabit(ref name, std::initializer_list<ref> argnames, std::function<void(ref)> code)
{
ref habit = level1::a(concepts::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 or call instances
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<ref>()(ref::context());
posarg = habit;
while (posarg.linked(next-positional-argument)) {
posarg = posarg[next-positional-argument];
ref::context().unlink(posarg[argument]);
}
return ret;
}
}
}
|