/
cons.i.hh
85 lines (65 loc) · 1.38 KB
/
cons.i.hh
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
#ifndef CONS_I_HH
#define CONS_I_HH
#ifndef CONS_HH
#error "Please include via parent file"
#endif
inline
Cons::Cons(Lisp_ptr x, Lisp_ptr y)
: car_(x), cdr_(y){}
inline
Lisp_ptr Cons::car() const {
return this ? car_ : NIL;
}
inline
Lisp_ptr Cons::cdr() const {
return this ? cdr_ : NIL;
}
inline
void Cons::rplaca(Lisp_ptr p){
if(this)
car_ = p;
}
inline
void Cons::rplacd(Lisp_ptr p){
if(this)
cdr_ = p;
}
inline
bool nullp(Lisp_ptr p){
return (p.tag() == Ptr_tag::cons)
&& (p.get<Cons*>() == Cons::NIL.get<Cons*>());
}
template<typename MainFun, typename LastFun>
auto do_list(Lisp_ptr lis, MainFun&& m_fun, LastFun&& l_fun)
-> decltype(l_fun(lis)){
Lisp_ptr p = lis;
while(1){
if(p.tag() != Ptr_tag::cons)
break; // null or dot list end.
auto c = p.get<Cons*>();
if(!c) break; // reached nil
if(!m_fun(c))
break;
p = c->cdr();
}
return l_fun(p);
}
template<typename Fun1, typename... FunRest>
int bind_cons_list_i(int len, Lisp_ptr p, Fun1&& f, FunRest&&... fr){
auto c = p.get<Cons*>();
if(!c) return len;
len += 1;
f(c);
if(nullp(c->cdr())) return len;
return bind_cons_list_i(len, c->cdr(), fr...);
}
inline
int bind_cons_list_i(int len, Lisp_ptr){
return len+1;
}
template<typename... Fun>
inline
int bind_cons_list(Lisp_ptr p, Fun&&... f){
return bind_cons_list_i(0, p, f...);
}
#endif // CONS_I_HH