Permalink
Browse files

applied list binding template

  • Loading branch information...
1 parent eefcfc4 commit b92e0e31d11baf7fdabb6beffa7d02bea0bfbdb1 @y2q-actionman committed May 31, 2012
Showing with 37 additions and 57 deletions.
  1. +1 −3 src/cons.hh
  2. +18 −6 src/cons.i.hh
  3. +18 −48 src/eval.cc
View
@@ -33,9 +33,7 @@ auto do_list(Lisp_ptr p, MainFun&&, LastFun&& lf)
-> decltype(lf(p));
template<typename... Fun>
-void bind_cons_list(Lisp_ptr, Fun&&...);
-
-inline void bind_cons_list(Lisp_ptr);
+int bind_cons_list(Lisp_ptr, Fun&&...);
void free_cons_list(Lisp_ptr);
View
@@ -59,15 +59,27 @@ auto do_list(Lisp_ptr lis, MainFun&& m_fun, LastFun&& l_fun)
}
template<typename Fun1, typename... FunRest>
-void bind_cons_list(Lisp_ptr p, Fun1&& f, FunRest&&... fr){
+int bind_cons_list_i(int len, Lisp_ptr p, Fun1&& f, FunRest&&... fr){
auto c = p.get<Cons*>();
+ if(!c) return len;
- f(c->car());
-
- if(nullp(c->cdr())) return;
- return bind_cons_list(c->cdr(), fr...);
+ len += 1;
+ f(c);
+
+ if(nullp(c->cdr())) return len;
+
+ return bind_cons_list_i(len, c->cdr(), fr...);
}
-inline void bind_cons_list(Lisp_ptr){}
+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
View
@@ -148,60 +148,30 @@ Lisp_ptr eval_lambda(const Cons* rest){
Lisp_ptr eval_if(Cons* rest){
// extracting
-#if 0
- auto test = rest->car();
-
- if(rest->cdr().tag() != Ptr_tag::cons){
- fprintf(stderr, "eval error: if has invalid conseq!\n");
- return {};
- }
-
- auto conseq_l = rest->cdr().get<Cons*>();
- if(!conseq_l){
- fprintf(stderr, "eval error: if has no conseq!\n");
- return {};
- }
-
- auto conseq = conseq_l->car();
-
- if(conseq_l->cdr().tag() != Ptr_tag::cons){
- fprintf(stderr, "eval error: if has invalid alt!\n");
- return {};
- }
-
- auto alt = Lisp_ptr{};
-
- if(auto alt_l = conseq_l->cdr().get<Cons*>()){
- alt = alt_l->car();
-
- if(alt_l->cdr().tag() != Ptr_tag::cons
- || alt_l->cdr().get<Cons*>()){
- fprintf(stderr, "eval error: if has extra alts!\n");
- return {};
- }
- }
-#endif
-
- bool flag = true;
Lisp_ptr test, conseq, alt;
+ int len =
bind_cons_list(Lisp_ptr(rest),
- [&](Lisp_ptr p){
- if(!p) flag = false;
- test = p;
- },
- [&](Lisp_ptr p){
- if(!p) flag = false;
- conseq = p;
+ [&](Cons* c){
+ test = c->car();
},
- [&](Lisp_ptr p){
- flag = true;
- alt = p;
+ [&](Cons* c){
+ conseq = c->car();
},
- [&](Lisp_ptr){
- flag = false;
+ [&](Cons* c){
+ alt = c->car();
});
- if(!flag) return {};
+
+ switch(len){
+ case 1:
+ fprintf(stderr, "eval error: informal if expr! (no test expr)\n");
+ return {};
+ case 2: case 3: // successed
+ break;
+ default:
+ fprintf(stderr, "eval error: informal if expr! (more than %d exprs)\n", len);
+ return {};
+ }
// evaluating
VM.code().push(test);

0 comments on commit b92e0e3

Please sign in to comment.