blob: e4fc090799fa805dee6be7d4db29444ef3049122 (
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#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");
}
habit.fun<ref>()(ref::context());
posarg = habit;
while (posarg.linked(next-positional-argument)) {
posarg = posarg[next-positional-argument];
ref::context().unlink(posarg[argument]);
}
if (ref::context().linked(result)) {
ref ret = ref::context().get(result);
ref::context().unlink(result, ret);
return ret;
}
return nothing;
}
ref dohabit(ref habit, std::initializer_list<std::initializer_list<ref>> pairs)
{
using namespace concepts;
// TODO: subcontexts or call instances
ref ctx = ref::context();
for (auto pair : pairs) {
auto second = pair.begin(); ++ second;
ctx.link(pair.begin(), second);
}
habit.fun<ref>()(ctx);
for (auto pair : pairs) {
auto second = pair.begin(); ++ second;
ctx.unlink(pair.begin(), second);
}
if (ctx.linked(result)) {
ref ret = ctx.get(result);
ctx.unlink(result, ret);
return ret;
}
return nothing;
}
}
}
|