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 /lib.c | |
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.
Diffstat (limited to 'lib.c')
-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); } |