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 | 8c6351ef70bfd8a800417b4349b9432a53fb421e (patch) | |
tree | d5014baa3b32111d3adcf566bd151c8aa0edfcf2 | |
parent | 8e45d4a276707a035c60181ebbb2e70ec8c70088 (diff) | |
download | txr-8c6351ef70bfd8a800417b4349b9432a53fb421e.tar.gz txr-8c6351ef70bfd8a800417b4349b9432a53fb421e.tar.bz2 txr-8c6351ef70bfd8a800417b4349b9432a53fb421e.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); } |