-
Notifications
You must be signed in to change notification settings - Fork 0
/
lambda.cpp
58 lines (41 loc) · 1.34 KB
/
lambda.cpp
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
#include "frame.hpp"
#include "lambda.hpp"
Exit Lambda::call(Frame& f, std::shared_ptr<Value> slf) {
std::vector<std::shared_ptr<Value>> args;
// if they didn't pass any args then create an empty argument list
if (f.stack.empty() || f.stack.back().type != Value::ARR) {
args = std::vector<std::shared_ptr<Value>>();
} else { // unfortunate i can't just std::move the value without fixing container:(
args = *f.stack.back().arr;
f.stack.pop_back();
}
// scope into body
std::shared_ptr<Frame> lam = f.scope(body, false);
// assign params
for (size_t i = 0; i < params.size(); i++)
lam->setVar(params[i], i + 1 > args.size() ?
std::make_shared<Value>() : args[i]);
// add self and arguments
/* INSIGHT: should be a variable or definition?
* why definition?
- its constant, cant change it :/
-
*/
if (slf)
lam->defs.emplace("self", slf);
else if (self)
lam->defs.emplace("self", self);
else
lam->defs.emplace("self", std::make_shared<Value>()); // empty
// set args
lam->defs.emplace("arguments", std::make_shared<Value>(std::move(args)));
// capture exit value
Frame::Exit&& ev = lam->run(lam);
// merge stacks
f.stack.insert(f.stack.end(), lam->stack.begin(), lam->stack.end());
if (ev.reason == Frame::Exit::RETURN)
return Frame::Exit();
if (ev.reason == Frame::Exit::UP)
ev.number--;
return ev;
}