-
Notifications
You must be signed in to change notification settings - Fork 1
/
range.cpp
65 lines (53 loc) · 1.54 KB
/
range.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
58
59
60
61
62
63
64
65
#include <cstring>
#include "./range.h"
packToken* Range::next() {
int64_t value = i;
if ((step > 0 && value >= to) || (step < 0 && value <= to)) {
i = from;
return NULL;
} else {
i += step;
last = static_cast<double>(value);
return &last;
}
}
void Range::reset() { i=from; }
/* * * * * Built-in range function: * * * * */
const char* range_args[] = {"from", "to", "step"};
packToken default_range(TokenMap scope) {
int64_t to, step, from;
packToken* p_from = scope.find("from");
packToken* p_to = scope.find("to");
packToken* p_step = scope.find("step");
if ((*p_from)->type & NUM) {
from = p_from->asInt();
} else if ((*p_from)->type == NONE) {
throw std::invalid_argument("range() expects at least 1 argument!");
} else {
throw std::invalid_argument("range() expects only numbers!");
}
if ((*p_to)->type == NONE) {
to = from;
from = 0;
step = 1;
} else if ((*p_to)->type & NUM) {
to = p_to->asInt();
if ((*p_step)->type & NUM) {
step = p_step->asInt();
} else if ((*p_step)->type == NONE) {
step = 1;
} else {
throw std::invalid_argument("range() expects only numbers!");
}
} else {
throw std::invalid_argument("range() expects only numbers!");
}
return packToken(new Range(from, to, step));
}
/* * * * * Range Startup class * * * * */
struct Range::Startup {
Startup() {
TokenMap& global = TokenMap::default_global();
global["range"] = CppFunction(default_range, 3, range_args, "range");
}
} iterator_startup;