diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-01-03 03:17:33 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-01-03 03:17:33 -0800 |
commit | e75e6bda47819e2be53615a2cc8f3d1d20741be2 (patch) | |
tree | d5014baa3b32111d3adcf566bd151c8aa0edfcf2 | |
parent | 18d1c715712c74f709240fb389a6601a1a812895 (diff) | |
download | txr-e75e6bda47819e2be53615a2cc8f3d1d20741be2.tar.gz txr-e75e6bda47819e2be53615a2cc8f3d1d20741be2.tar.bz2 txr-e75e6bda47819e2be53615a2cc8f3d1d20741be2.zip |
car, cdr: fall back on lambda method.
* lib.c (car, cdr): Don't fail if the struct object has no car
or cdr method. Use it if it is available, otherwise try to
fall back on the lambda method if that is available.
-rw-r--r-- | lib.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -380,8 +380,18 @@ val car(val cons) return nil; return chr_str(cons, zero); case COBJ: - if (obj_struct_p(cons)) - return funcall1(slot(cons, car_s), cons); + if (obj_struct_p(cons)) { + { + val car_meth = maybe_slot(cons, car_s); + if (car_meth) + return funcall1(car_meth, cons); + } + { + val lambda_meth = maybe_slot(cons, lambda_s); + if (lambda_meth) + return funcall2(lambda_meth, cons, zero); + } + } default: type_mismatch(lit("~s is not a cons"), cons, nao); } @@ -411,8 +421,18 @@ val cdr(val cons) return nil; return sub(cons, one, t); case COBJ: - if (obj_struct_p(cons)) - return funcall1(slot(cons, cdr_s), cons); + if (obj_struct_p(cons)) { + { + val cdr_meth = maybe_slot(cons, cdr_s); + if (cdr_meth) + return funcall1(cdr_meth, cons); + } + { + val lambda_meth = maybe_slot(cons, lambda_s); + if (lambda_meth) + return funcall2(lambda_meth, cons, rcons(one, t)); + } + } default: type_mismatch(lit("~s is not a cons"), cons, nao); } |