diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | eval.c | 18 | ||||
-rw-r--r-- | txr.1 | 6 |
3 files changed, 29 insertions, 3 deletions
@@ -1,3 +1,11 @@ +2014-01-14 Kaz Kylheku <kaz@kylheku.com> + + * eval.c (bind_args): Implemented default values for optional + arguments. + (op_defun): Permit the syntax. + + * txr.1: Documented. + 2014-01-13 Kaz Kylheku <kaz@kylheku.com> Support for pushing back bytes and characters into streams. @@ -235,8 +235,11 @@ static val bind_args(val env, val params, val args, val ctx_form) param = car(params); } + if (optargs && consp(param)) + param = car(param); + if (!bindable(param)) - eval_error(ctx_form, lit("~a: ~s is not a bindable sybol"), + eval_error(ctx_form, lit("~a: ~s is not a bindable symbol"), car(ctx_form), param, nao); new_bindings = acons(param, car(args), new_bindings); @@ -254,9 +257,16 @@ static val bind_args(val env, val params, val args, val ctx_form) if (!optargs) eval_error(ctx_form, lit("~s: too few arguments"), car(ctx_form), nao); while (consp(params)) { - if (car(params) == colon_k) + val param = car(params); + val val = nil; + if (param == colon_k) goto twocol; - new_bindings = acons(car(params), nil, new_bindings); + if (consp(param)) { + val = car(cdr(param)); + param = car(param); + } + new_bindings = acons(param, eval(val, env, ctx_form), + new_bindings); params = cdr(params); } if (bindable(params)) @@ -758,6 +768,8 @@ static val op_defun(val form, val env) colon = t; continue; } + if (colon && consp(param)) + continue; if (!bindable(param)) eval_error(form, lit("defun: parameter ~s is not a bindable symbol"), param, nao); } @@ -5821,6 +5821,12 @@ but a separator between required parameters and optional parameters. When the function is called, optional parameter for which arguments are not supplied take on the value nil. +An optional parameter can also be written in the form (<name> <expr>). +In this situation, if the call does not specify a value for the parameter, +then the parameter takes on the value of the expression <expr>. +The expression is evaluated in the environment in which the lambda +was constructed. + Functions created by lambda capture the surrounding variable bindings. |