diff options
-rw-r--r-- | ChangeLog | 52 | ||||
-rw-r--r-- | arith.c | 2 | ||||
-rw-r--r-- | eval.c | 37 | ||||
-rw-r--r-- | hash.c | 2 | ||||
-rw-r--r-- | lib.c | 145 | ||||
-rw-r--r-- | lib.h | 13 | ||||
-rw-r--r-- | rand.c | 6 | ||||
-rw-r--r-- | regex.c | 10 | ||||
-rw-r--r-- | stream.c | 21 | ||||
-rw-r--r-- | syslog.c | 9 | ||||
-rw-r--r-- | txr.1 | 147 |
11 files changed, 223 insertions, 221 deletions
@@ -1,5 +1,57 @@ 2014-02-05 Kaz Kylheku <kaz@kylheku.com> + * arith.c (lognot): Conform to new scheme for defaulting optional args. + + * eval.c (apply): Unconditionally use colon_k for missing optional + args, for intrinsic functions. + (eval_intrinsic, rangev, rangev_star, errno_wrap): Conform to new + scheme for defaulting optional args. + (reg_fun_mark): Function removed. + (eval_init): Switch reduce_left and reduce_right back to reg_fun + registration. + + * hash.c (gethash_n): Conform to new scheme for defaulting optional + arguments. + + * lib.c (sub_list, replace_list, remove_if, keep_if, remove_if_lazy, + keep_if_lazy, tree_find, count_if, some_satisfy, all_satisfy, + none_satisfy, search_str, match_str, match_str_tree, sub_str, + replace_str, cat_str, tok_str, intern, rehome_sym, sub_vec, + replace_vec, lazy_str, sort, multi_sort, find, find_if, set_diff, + obj_print, obj_pprint): Conform to new scheme for defaulting optional + arguments. + (func_f0, func_f1, func_f2, func_f3, func_f4, func_n0, func_n1, + func_n2, func_n3, func_n4, func_n5, func_n6, func_n7, func_f0v, + func_f1v, func_f2v, func_f3v, func_f4v, func_n0v, func_n1v, + func_n2v, func_n3v, func_n4v, func_n5v, func_n6v, func_n7v): + Remove references to removed mark_missing_args member of struct func. + (func_set_mark_missing): Function removed. + (generic_funcall): Unconditionally use colon_k for missing optional + args, for intrinsic functions. + + * lib.h (struct func): mark_missing_args member removed. + (func_set_mark_missing): Declaration removed. + (default_arg, default_bool_arg): New inline functions. + + * rand.c (random): Left argument is not optional. + (rnd): Conform to new scheme for defaulting optional arguments. + + * regex.c (search_regex, match_regex): Conform to new scheme for + defaulting optional arguments. + + * stream.c (unget_char, unget_byte, put_string, put_char, put_byte, + put_line): Conform to new scheme for defaulting optional arguments. + + * syslog.c (openlog_wrap): Conform to new scheme for defaulting + optional arguments. + + * txr.1: Remove the specification that nil is a sentinel value in + default arguments, where necessary. Use consistent syntax for + specifying variable parts in argument lists. A few errors and omissions + addressed. + +2014-02-05 Kaz Kylheku <kaz@kylheku.com> + * eval.c (bind_args): Support optional parameters in the form (sym initform present-p-sym). Also, support the convention that a value of : explicitly passed for an optional argument produces @@ -1700,7 +1700,7 @@ val lognot(val a, val bits) { val b; - if (bits) + if (default_bool_arg(bits)) return comp_trunc(a, bits); switch (type(a)) { @@ -331,7 +331,6 @@ twocol: val apply(val fun, val arglist, val ctx_form) { val arg[32], *p = arg; - val missing; int variadic, fixparam, reqargs, nargs; if (symbolp(fun)) { @@ -343,8 +342,6 @@ val apply(val fun, val arglist, val ctx_form) type_check (fun, FUN); - missing = fun->f.mark_missing_args ? colon_k : nil; - if (!listp(arglist)) { val arglist_conv = tolist(arglist); type_assert (listp(arglist_conv), @@ -372,7 +369,7 @@ val apply(val fun, val arglist, val ctx_form) car(ctx_form), nao); for (; nargs < fixparam; nargs++) - *p++ = missing; + *p++ = colon_k; switch (fun->f.functype) { case F0: @@ -415,7 +412,7 @@ val apply(val fun, val arglist, val ctx_form) car(ctx_form), nao); for (; nargs < fixparam; nargs++) - *p++ = missing; + *p++ = colon_k; switch (fun->f.functype) { case FINTERP: @@ -501,9 +498,8 @@ val interp_fun(val env, val fun, val args) val eval_intrinsic(val form, val env) { - uses_or2; form = expand(form); - return eval(form, or2(env, make_env(nil, nil, env)), form); + return eval(form, default_arg(env, make_env(nil, nil, env)), form); } static val do_eval(val form, val env, val ctx_form, @@ -2065,10 +2061,9 @@ static val rangev_func(val env, val lcons) static val rangev(val args) { - uses_or2; - val from = or2(first(args), zero); - val to = second(args); - val step = or2(third(args), if3(to && gt(from, to), negone, one)); + val from = default_arg(first(args), zero); + val to = default_bool_arg(second(args)); + val step = default_arg(third(args), if3(to && gt(from, to), negone, one)); val env = cons(from, cons(to, step)); return make_lazy_cons(func_f1(env, rangev_func)); @@ -2101,8 +2096,8 @@ static val range_star_v_func(val env, val lcons) static val range_star_v(val args) { uses_or2; - val from = or2(first(args), zero); - val to = second(args); + val from = default_arg(first(args), zero); + val to = default_bool_arg(second(args)); if (eql(from, to)) { return nil; @@ -2197,7 +2192,7 @@ static val force(val promise) static val errno_wrap(val newval) { val oldval = num(errno); - if (newval) + if (default_bool_arg(newval)) errno = c_num(newval); return oldval; } @@ -2257,12 +2252,6 @@ static void reg_fun(val sym, val fun) sethash(top_fb, sym, cons(sym, fun)); } -static void reg_fun_mark(val sym, val fun) -{ - sethash(top_fb, sym, cons(sym, fun)); - func_set_mark_missing(fun); -} - static void c_var_mark(val obj) { struct c_var *cv = (struct c_var *) obj->co.handle; @@ -2441,10 +2430,8 @@ void eval_init(void) reg_fun(intern(lit("mappend"), user_package), func_n1v(mappendv)); reg_fun(intern(lit("mappend*"), user_package), func_n1v(lazy_mappendv)); reg_fun(apply_s, func_n1v(apply_intrinsic)); - reg_fun_mark(intern(lit("reduce-left"), user_package), - func_n4o(reduce_left, 2)); - reg_fun_mark(intern(lit("reduce-right"), user_package), - func_n4o(reduce_right, 2)); + reg_fun(intern(lit("reduce-left"), user_package), func_n4o(reduce_left, 2)); + reg_fun(intern(lit("reduce-right"), user_package), func_n4o(reduce_right, 2)); reg_fun(intern(lit("second"), user_package), func_n1(second)); reg_fun(intern(lit("third"), user_package), func_n1(third)); @@ -2757,7 +2744,7 @@ void eval_init(void) reg_fun(intern(lit("copy-cons"), user_package), func_n1(copy_cons)); reg_fun(intern(lit("copy-alist"), user_package), func_n1(copy_alist)); reg_fun(intern(lit("prop"), user_package), func_n2(getplist)); - reg_fun(intern(lit("merge"), user_package), func_n4o(merge, 2)); + reg_fun(intern(lit("merge"), user_package), func_n4o(merge, 3)); reg_fun(intern(lit("sort"), user_package), func_n3o(sort, 2)); reg_fun(intern(lit("find"), user_package), func_n4o(find, 2)); reg_fun(intern(lit("multi-sort"), user_package), func_n3o(multi_sort, 2)); @@ -455,7 +455,7 @@ val gethash_n(val hash, val key, val notfound_val) struct hash *h = (struct hash *) cobj_handle(hash, hash_s); val chain = vecref(h->table, num_fast(h->hash_fun(key) % h->modulus)); val existing = h->assoc_fun(key, chain); - return if3(existing, cdr(existing), notfound_val); + return if3(existing, cdr(existing), default_bool_arg(notfound_val)); } val sethash(val hash, val key, val value) @@ -638,7 +638,7 @@ val sub_list(val list, val from, val to) if (!list) return nil; - if (from == nil) + if (null_or_missing_p(from)) from = zero; else if (from == t) from = nil; @@ -648,9 +648,9 @@ val sub_list(val list, val from, val to) to = nil; } - if (to == t) + if (to == t || null_or_missing_p(to)) to = nil; - else if (to && lt(to, zero)) + else if (!null_or_missing_p(to) && lt(to, zero)) to = plus(to, if3(len, len, len = length(list))); if (to && from && gt(from, to)) { @@ -692,7 +692,7 @@ val replace_list(val list, val items, val from, val to) if (!list) return items; - if (from == nil) + if (null_or_missing_p(from)) from = zero; else if (from == t) from = nil; @@ -702,7 +702,7 @@ val replace_list(val list, val items, val from, val to) to = len; } - if (to == t) + if (to == t || null_or_missing_p(to)) to = nil; if (to && lt(to, zero)) to = plus(to, len ? len : (len = length(list))); @@ -892,8 +892,7 @@ val remove_if(val pred, val list, val key) val list_orig = list; val lastmatch = cons(nil, list); - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { val subj = funcall1(key, car(list)); @@ -914,8 +913,7 @@ val keep_if(val pred, val list, val key) val list_orig = list; val lastmatch = cons(nil, list); - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { val subj = funcall1(key, car(list)); @@ -968,23 +966,19 @@ val remqual_lazy(val obj, val list) val remove_if_lazy(val pred, val list, val key) { - uses_or2; - val pred_key = chain(or2(key, identity_f), pred, nao); + val pred_key = chain(default_arg(key, identity_f), pred, nao); return rem_lazy_rec(pred_key, list, nil, nil); } val keep_if_lazy(val pred, val list, val key) { - uses_or2; - val pred_key = chain(or2(key, identity_f), pred, null_f, nao); + val pred_key = chain(default_arg(key, identity_f), pred, null_f, nao); return rem_lazy_rec(pred_key, list, nil, nil); } val tree_find(val obj, val tree, val testfun) { - uses_or2; - - if (funcall2(or2(testfun, equal_f), obj, tree)) + if (funcall2(default_arg(testfun, equal_f), obj, tree)) return t; else if (consp(tree)) return some_satisfy(tree, curry_123_2(func_n3(tree_find), @@ -1029,8 +1023,7 @@ val count_if(val pred, val list, val key) { val count = zero; - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { val subj = funcall1(key, car(list)); @@ -1045,8 +1038,7 @@ val count_if(val pred, val list, val key) val some_satisfy(val list, val pred, val key) { - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { val item; @@ -1061,8 +1053,7 @@ val all_satisfy(val list, val pred, val key) { val item = t; - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { if ((item = funcall1(pred, funcall1(key, car(list)))) == nil) @@ -1074,8 +1065,7 @@ val all_satisfy(val list, val pred, val key) val none_satisfy(val list, val pred, val key) { - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { if (funcall1(pred, funcall1(key, car(list)))) @@ -1934,9 +1924,8 @@ const wchar_t *c_str(val obj) val search_str(val haystack, val needle, val start_num, val from_end) { - uses_or2; - - start_num = or2(start_num, zero); + from_end = default_bool_arg(from_end); + start_num = default_arg(start_num, zero); if (length_str_lt(haystack, start_num)) { return nil; @@ -2004,8 +1993,7 @@ val match_str(val bigstr, val str, val pos) { val i, p; - if (pos == nil) - pos = zero; + pos = default_arg(pos, zero); for (i = zero; length_str_gt(bigstr, p = plus(pos, i)) && length_str_gt(str, i); @@ -2020,8 +2008,7 @@ val match_str(val bigstr, val str, val pos) val match_str_tree(val bigstr, val tree, val pos) { - if (pos == nil) - pos = zero; + pos = default_arg(pos, zero); if (stringp(tree)) { if (match_str(bigstr, tree, pos)) @@ -2104,7 +2091,7 @@ val sub_str(val str_in, val from, val to) len = length_str(str_in); - if (from == nil) + if (null_or_missing_p(from)) from = zero; else if (from == t) return null_string; @@ -2114,7 +2101,7 @@ val sub_str(val str_in, val from, val to) to = len; } - if (to == nil || to == t) + if (null_or_missing_p(to) || to == t) to = len; else if (lt(to, zero)) to = plus(to, len); @@ -2145,7 +2132,7 @@ val replace_str(val str_in, val items, val from, val to) uw_throwf(error_s, lit("replace-str: string ~s of type ~s not supported"), str_in, typeof(str_in), nao); - if (from == nil) + if (null_or_missing_p(from)) from = zero; else if (from == t) from = len; @@ -2155,7 +2142,7 @@ val replace_str(val str_in, val items, val from, val to) to = len; } - if (to == nil || to == t) + if (null_or_missing_p(to) || to == t) to = len; else if (lt(to, zero)) to = plus(to, len); @@ -2215,7 +2202,7 @@ val cat_str(val list, val sep) cnum total = 0; val iter; wchar_t *str, *ptr; - cnum len_sep = sep ? c_num(length_str(sep)) : 0; + cnum len_sep = (!null_or_missing_p(sep)) ? c_num(length_str(sep)) : 0; for (iter = list; iter != nil; iter = cdr(iter)) { val item = car(iter); @@ -2354,6 +2341,8 @@ val tok_str(val str, val tok_regex, val keep_sep) list_collect_decl (out, iter); val pos = zero; + keep_sep = default_bool_arg(keep_sep); + for (;;) { cons_bind (new_pos, len, search_regex(str, tok_regex, pos, nil)); val end; @@ -2761,7 +2750,7 @@ val intern(val str, val package) val new_p; val *place; - if (nullp(package)) { + if (null_or_missing_p(package)) { package = user_package; } else if (stringp(package)) { val p = find_package(package); @@ -2788,7 +2777,7 @@ val rehome_sym(val sym, val package) if (!sym) return nil; - if (nullp(package)) { + if (null_or_missing_p(package)) { package = user_package; } else if (stringp(package)) { val p = find_package(package); @@ -2833,7 +2822,6 @@ val func_f0(val env, val (*fun)(val)) obj->f.variadic = 0; obj->f.fixparam = 0; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2847,7 +2835,6 @@ val func_f1(val env, val (*fun)(val, val)) obj->f.variadic = 0; obj->f.fixparam = 1; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2861,7 +2848,6 @@ val func_f2(val env, val (*fun)(val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 2; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2875,7 +2861,6 @@ val func_f3(val env, val (*fun)(val, val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 3; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2889,7 +2874,6 @@ val func_f4(val env, val (*fun)(val, val, val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 4; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2903,7 +2887,6 @@ val func_n0(val (*fun)(void)) obj->f.variadic = 0; obj->f.fixparam = 0; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2917,7 +2900,6 @@ val func_n1(val (*fun)(val)) obj->f.variadic = 0; obj->f.fixparam = 1; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2931,7 +2913,6 @@ val func_n2(val (*fun)(val, val)) obj->f.variadic = 0; obj->f.fixparam = 2; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2945,7 +2926,6 @@ val func_n3(val (*fun)(val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 3; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2959,7 +2939,6 @@ val func_n4(val (*fun)(val, val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 4; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2973,7 +2952,6 @@ val func_n5(val (*fun)(val, val, val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 5; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -2987,7 +2965,6 @@ val func_n6(val (*fun)(val, val, val, val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 6; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3001,7 +2978,6 @@ val func_n7(val (*fun)(val, val, val, val, val, val, val)) obj->f.variadic = 0; obj->f.fixparam = 7; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3015,7 +2991,6 @@ val func_f0v(val env, val (*fun)(val, val)) obj->f.variadic = 1; obj->f.fixparam = 0; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3029,7 +3004,6 @@ val func_f1v(val env, val (*fun)(val env, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 1; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3043,7 +3017,6 @@ val func_f2v(val env, val (*fun)(val env, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 2; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3057,7 +3030,6 @@ val func_f3v(val env, val (*fun)(val env, val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 3; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3071,7 +3043,6 @@ val func_f4v(val env, val (*fun)(val env, val, val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 4; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3085,7 +3056,6 @@ val func_n0v(val (*fun)(val rest)) obj->f.variadic = 1; obj->f.fixparam = 0; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3099,7 +3069,6 @@ val func_n1v(val (*fun)(val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 1; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3113,7 +3082,6 @@ val func_n2v(val (*fun)(val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 2; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3127,7 +3095,6 @@ val func_n3v(val (*fun)(val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 3; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3141,7 +3108,6 @@ val func_n4v(val (*fun)(val, val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 4; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3155,7 +3121,6 @@ val func_n5v(val (*fun)(val, val, val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 5; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3169,7 +3134,6 @@ val func_n6v(val (*fun)(val, val, val, val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 6; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3183,7 +3147,6 @@ val func_n7v(val (*fun)(val, val, val, val, val, val, val, val rest)) obj->f.variadic = 1; obj->f.fixparam = 7; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3232,7 +3195,6 @@ val func_interp(val env, val form) obj->f.variadic = 1; obj->f.fixparam = 0; obj->f.optargs = 0; - obj->f.mark_missing_args = 0; return obj; } @@ -3258,13 +3220,6 @@ val func_set_env(val fun, val env) return env; } -val func_set_mark_missing(val fun) -{ - type_check(fun, FUN); - fun->f.mark_missing_args = 1; - return nil; -} - val functionp(val obj) { return type(obj) == FUN ? t : nil; @@ -3278,11 +3233,9 @@ val interp_fun_p(val obj) static val generic_funcall(val fun, val arg[], int nargs) { int variadic, fixparam, reqargs; - val missing; type_check (fun, FUN); - missing = fun->f.mark_missing_args ? colon_k : nil; variadic = fun->f.variadic; fixparam = fun->f.fixparam; reqargs = fixparam - fun->f.optargs; @@ -3295,7 +3248,7 @@ static val generic_funcall(val fun, val arg[], int nargs) uw_throw(error_s, lit("funcall: too many arguments")); for (; nargs < fixparam; ) - arg[nargs++] = missing; + arg[nargs++] = colon_k; switch (fun->f.functype) { case F0: @@ -3337,7 +3290,7 @@ static val generic_funcall(val fun, val arg[], int nargs) uw_throw(error_s, lit("funcall: missing required arguments")); for (; nargs < fixparam; ) - arg[nargs++] = missing; + arg[nargs++] = colon_k; for (; nargs > fixparam; ) arglist = cons(arg[--nargs], arglist); @@ -3995,7 +3948,7 @@ val sub_vec(val vec_in, val from, val to) { val len = length_vec(vec_in); - if (from == nil) + if (null_or_missing_p(from)) from = zero; else if (from == t) from = len; @@ -4005,7 +3958,7 @@ val sub_vec(val vec_in, val from, val to) to = len; } - if (to == nil || to == t) + if (null_or_missing_p(to) || to == t) to = len; else if (lt(to, zero)) to = plus(to, len); @@ -4039,7 +3992,7 @@ val replace_vec(val vec_in, val items, val from, val to) val len_it = length(it_seq); val len_rep; - if (from == nil) + if (null_or_missing_p(from)) from = zero; else if (from == t) from = len; @@ -4049,7 +4002,7 @@ val replace_vec(val vec_in, val items, val from, val to) to = len; } - if (to == nil || to == t) + if (null_or_missing_p(to) || to == t) to = len; else if (lt(to, zero)) to = plus(to, len); @@ -4192,14 +4145,14 @@ val lazy_stream_cons(val stream) val lazy_str(val lst, val term, val limit) { - uses_or2; val obj = make_obj(); obj->ls.type = LSTR; /* Must init before calling something that can gc! */ obj->ls.opts = obj->ls.list = obj->ls.prefix = nil; - term = or2(term, lit("\n")); + term = default_arg(term, lit("\n")); + limit = default_bool_arg(limit); if (nullp(lst)) { obj->ls.prefix = null_string; @@ -4697,8 +4650,7 @@ val sort(val seq, val lessfun, val keyfun) if (!seq) return nil; - if (!keyfun) - keyfun = identity_f; + keyfun = default_arg(keyfun, identity_f); if (consp(seq)) { /* The list could have a mixture of generation 0 and 1 @@ -4739,6 +4691,8 @@ val multi_sort(val lists, val funcs, val key_funcs) { val tuples = mapcarv(func_n0v(identity), lists); + key_funcs = default_bool_arg(key_funcs); + if (functionp(funcs)) funcs = cons(funcs, nil); @@ -4750,11 +4704,8 @@ val multi_sort(val lists, val funcs, val key_funcs) val find(val item, val list, val testfun, val keyfun) { - if (!keyfun) - keyfun = identity_f; - - if (!testfun) - testfun = equal_f; + testfun = default_arg(testfun, equal_f); + keyfun = default_arg(keyfun, identity_f); for (; list; list = cdr(list)) { val elem = car(list); @@ -4769,8 +4720,7 @@ val find(val item, val list, val testfun, val keyfun) val find_if(val pred, val list, val key) { - if (!key) - key = identity_f; + key = default_arg(key, identity_f); for (; list; list = cdr(list)) { val item = car(list); @@ -4789,11 +4739,8 @@ val set_diff(val list1, val list2, val testfun, val keyfun) list_collect_decl (out, ptail); val list_orig = list1; - if (!keyfun) - keyfun = identity_f; - - if (!testfun) - testfun = equal_f; + testfun = default_arg(testfun, equal_f); + keyfun = default_arg(keyfun, identity_f); for (; list1; list1 = cdr(list1)) { /* optimization: list2 is a tail of list1, and so we @@ -5110,8 +5057,7 @@ static void obj_init(void) val obj_print(val obj, val out) { - if (out == nil) - out = std_output; + out = default_arg(out, std_output); switch (type(obj)) { case NIL: @@ -5277,8 +5223,7 @@ val obj_print(val obj, val out) val obj_pprint(val obj, val out) { - if (out == nil) - out = std_output; + out = default_arg(out, std_output); switch (type(obj)) { case NIL: @@ -106,7 +106,7 @@ struct func { unsigned fixparam : 7; /* total non-variadic parameters */ unsigned optargs : 7; /* fixparam - optargs = required args */ unsigned variadic : 1; - unsigned mark_missing_args: 1; /* missing opt. args given as special value */ + unsigned : 1; unsigned functype : 16; val env; union { @@ -601,7 +601,6 @@ val func_interp(val env, val form); val func_get_form(val fun); val func_get_env(val fun); val func_set_env(val fun, val env); -val func_set_mark_missing(val fun); val functionp(val); val interp_fun_p(val); val funcall(val fun); @@ -740,6 +739,16 @@ INLINE val null_or_missing_p(val v) { return (!v || v == colon_k) ? t : nil; } #define c_true(c_cond) ((c_cond) ? t : nil) +INLINE val default_arg(val arg, val dfl) +{ + return if3(null_or_missing_p(arg), dfl, arg); +} + +INLINE val default_bool_arg(val arg) +{ + return if3(missingp(arg), nil, arg); +} + #define list_collect_decl(OUT, PTAIL) \ val OUT = nil, *PTAIL = &OUT @@ -167,10 +167,9 @@ val random_fixnum(val state) val random(val state, val modulus) { - uses_or2; struct random_state *r = (struct random_state *) - cobj_handle(or2(state, random_state), - random_state_s); + cobj_handle(random_state, random_state_s); + if (bignump(modulus)) { mp_int *m = mp(modulus); int bits = mp_count_bits(m); @@ -245,6 +244,7 @@ invalid: val rnd(val modulus, val state) { + state = default_arg(state, random_state); return random(state, modulus); } @@ -1770,8 +1770,8 @@ static regm_result_t regex_machine_feed(regex_machine_t *regm, wchar_t ch) val search_regex(val haystack, val needle_regex, val start, val from_end) { - if (!start) - start = zero; + start = default_arg(start, zero); + from_end = default_bool_arg(from_end); if (length_str_lt(haystack, start)) { return nil; @@ -1827,8 +1827,8 @@ val match_regex(val str, val reg, val pos) regex_machine_t regm; val i, retval; regm_result_t last_res = REGM_INCOMPLETE; - if (!pos) - pos = zero; + + pos = default_arg(pos, zero); regex_machine_init(®m, reg); @@ -1859,7 +1859,7 @@ val match_regex_right(val str, val regex, val end) val pos = zero; val slen = length(str); - if (!end || gt(end, slen)) + if (null_or_missing_p(end) || gt(end, slen)) end = slen; while (lt(pos, end)) { @@ -1358,8 +1358,7 @@ val get_byte(val stream) val unget_char(val ch, val stream) { - if (!stream) - stream = std_input; + stream = default_arg(stream, std_input); type_check (stream, COBJ); type_assert (stream->co.cls == stream_s, (lit("~a is not a stream"), @@ -1375,8 +1374,7 @@ val unget_byte(val byte, val stream) { cnum b = c_num(byte); - if (!stream) - stream = std_input; + stream = default_arg(stream, std_input); type_check (stream, COBJ); type_assert (stream->co.cls == stream_s, (lit("~a is not a stream"), @@ -1919,8 +1917,7 @@ val formatv(val stream, val string, val args) val put_string(val string, val stream) { - if (!stream) - stream = std_output; + stream = default_arg(stream, std_output); type_check (stream, COBJ); type_assert (stream->co.cls == stream_s, (lit("~a is not a stream"), @@ -1934,8 +1931,7 @@ val put_string(val string, val stream) val put_char(val ch, val stream) { - if (!stream) - stream = std_output; + stream = default_arg(stream, std_output); type_check (stream, COBJ); type_assert (stream->co.cls == stream_s, (lit("~a is not a stream"), @@ -1951,8 +1947,7 @@ val put_byte(val byte, val stream) { cnum b = c_num(byte); - if (!stream) - stream = std_output; + stream = default_arg(stream, std_output); type_check (stream, COBJ); type_assert (stream->co.cls == stream_s, (lit("~a is not a stream"), @@ -1968,7 +1963,6 @@ val put_byte(val byte, val stream) } } - val put_line(val string, val stream) { return (put_string(string, stream), put_char(chr('\n'), stream)); @@ -2118,7 +2112,10 @@ val open_process(val name, val mode_str, val args) pid_t pid; char **argv = 0, *utf8name = 0; val iter; - int i, nargs = c_num(length(args)); + int i, nargs; + + args = default_bool_arg(args); + nargs = c_num(length(args)); if (pipe(fd) == -1) { uw_throwf(file_error_s, lit("opening pipe ~a, pipe syscall failed: ~a/~s"), @@ -93,11 +93,12 @@ val openlog_wrap(val wident, val optmask, val facility) { static char *ident; char *old_ident = ident; - + + optmask = default_arg(optmask, zero); + facility = default_arg(facility, num_fast(LOG_USER)); + ident = utf8_dup_to(c_str(wident)); - openlog(ident, - if3(optmask, c_num(optmask), 0), - if3(facility, c_num(facility), LOG_USER)); + openlog(ident, c_num(optmask), c_num(facility)); free(old_ident); return nil; @@ -4773,7 +4773,7 @@ definitions are in error: The TXR language contains an embedded Lisp dialect called TXR Lisp. -This language is exposed in TXR in three ways. +This language is exposed in TXR in several ways. Firstly, in any situation that calls for an expression, a Lisp expression can be used, if it is preceded by the @ symbol. The Lisp expression @@ -4791,6 +4791,9 @@ as part of the matching logic of the TXR pattern language. The return value of the rightmost expression is examined. If it is nil, then the @(require) directive triggers a match failure. Otherwise, matching proceeds. +Lastly, TXR Lisp expressions can be evaluated via the txr command line, +using the -e and -p options. + Examples: Bind variable a to the integer 4: @@ -5134,6 +5137,12 @@ This indicates a repetition of zero or more of the given syntax enclosed in the braces or syntactic unit. .TP +{syntax}+ <word>+ + +This indicates a repetition of one or more of the given +syntax enclosed in the braces or syntactic unit. + +.TP [syntax] [<word>] Square brackets indicate optional syntax. @@ -6599,7 +6608,7 @@ Examples: .TP Syntax: -(list* {<value>}*) +(list* <value>*) .TP Description: @@ -6922,10 +6931,10 @@ in <list> which are eq, eql or equal to <object>, and return the count. .TP Syntax: - (remove-if <predicate-function> <list> : <key-function>) - (keep-if <predicate-function> <list> : <key-function>) - (remove-if* <predicate-function> <list> : <key-function>) - (keep-if* <predicate-function> <list> : <key-function>) + (remove-if <predicate-function> <list> [<key-function>]) + (keep-if <predicate-function> <list> [<key-function>]) + (remove-if* <predicate-function> <list> [<key-function>]) + (keep-if* <predicate-function> <list> [<key-function>]) .TP Description @@ -6938,8 +6947,8 @@ and may even be the same list object if no items are removed. The optional <key-function> specifies how each element from the <list> is transformed to an argument to <predicate-function>. If this argument is omitted -or specified as nil, then the predicate function is applied to the elements -directly, a behavior which is identical to <key-function> being (fun identity). +then the predicate function is applied to the elements directly, a behavior +which is identical to <key-function> being (fun identity). The keep-if function is exactly like remove-if, except the sense of the predicate is inverted. The function keep-if retains those items @@ -6970,18 +6979,18 @@ Examples: .TP Syntax: - (count-if <predicate-function> <list> : <key-function>) + (count-if <predicate-function> <list> [<key-function>]) .TP Description: -The countove-if function counts the numer of elements of <list> which satisfy +The count-if function counts the numer of elements of <list> which satisfy <predicate-function> and returns the count. The optional <key-function> specifies how each element from the <list> is transformed to an argument to <predicate-function>. If this argument is omitted -or specified as nil, then the predicate function is applied to the elements -directly, a behavior which is identical to <key-function> being (fun identity). +then the predicate function is applied to the elements directly, a behavior +which is identical to <key-function> being (fun identity). .SS Function tree-find @@ -7186,7 +7195,7 @@ can be expressed as: .TP Syntax: - (apply <function> [ {<arg>}* <trailing-args> ]) + (apply <function> [ <arg>* <trailing-args> ]) .TP Description: @@ -7243,8 +7252,8 @@ cannot be a compound form. .TP Syntax: - (reduce-left <binary-function> <list> : <init-value> <key-function>) - (reduce-right <binary-function> <list> : <init-value> <key-function>) + (reduce-left <binary-function> <list> [ <init-value> [ <key-function> ]]) + (reduce-right <binary-function> <list> [ <init-value> [ <key-function> ]]) .TP Description: @@ -7327,18 +7336,18 @@ Examples: .TP Syntax: - (some <list> <predicate-fun> <key-fun>) - (all <list> <predicate-fun> <key-fun>) - (none <list> <predicate-fun> <key-fun>) + (some <list> <predicate-fun> [<key-fun>]) + (all <list> <predicate-fun> [<key-fun>]) + (none <list> <predicate-fun> [<key-fun>]) .TP Description -The some, all and none functions apply a predicate test over a list of -elements. The elements of <list> are reduced to values using <key-fun>, which -is a one-argument function. If <key-fun> is specified as nil, then (fun -identity) is substituted, and thus the values of the list are taken as they -are. +The some, all and none functions apply a predicate test function +<predicate-fun> over a list of elements. If the argument <key-fun> is +specified, then values <list> are passed into <key-fun>, and <predicate-fun> is +applied to the resulting values. If <key-fun> is omitted, the behavior is +as if <key-fun> is the identity function. These functions have short-circuiting semantics and return conventions similar to the and and or operators. @@ -7532,7 +7541,7 @@ found, or due to the property being present with a nil value. .TP Syntax: - (merge <list1> <list2> <lessfun> <keyfun>) + (merge <list1> <list2> <lessfun> [<keyfun>]) .TP Description: @@ -7710,7 +7719,7 @@ the gen-func to populate it with the first item. .TP Syntax: - (repeat <list1> {<listn>}*) + (repeat <list1> <list>*) .TP Description: @@ -7948,7 +7957,7 @@ the <haystack> string and returns its position. If no such occurrence exists, it returns nil. If a <start> argument is specified, it gives the starting index for the -search. If the <from-end> argument is specified and is non-nil, it means +search. If the <from-end> argument is specified and is not nil, it means that the search is conducted right-to-left. If multiple matches are possible, it will find the rightmost one rather than the leftmost one. @@ -8572,8 +8581,8 @@ The lazy-str function constructs a lazy string which draws material from If the optional <terminator> argument is given, then it specifies a string which is appended to every string from <string-list>, before that string is -incorporated into the lazy string. If <terminator> is not given, or specified -as nil, then it defaults to the string "\en", and so the strings from +incorporated into the lazy string. If <terminator> is not given, +then it defaults to the string "\en", and so the strings from <string-list> are effectively treated as lines which get terminated by newlines as they accumulate into the growing prefix of the lazy string. To avoid the use of a terminator string, a null string <terminator> argument @@ -8952,8 +8961,8 @@ The sub function extracts a slice from input sequence <sequence>. The slice is a sequence of the same type as <sequence>. If the <to> parameter is omitted, the behavior is as if it were specified -as nil. Likewise, if the <from> parameter is omitted, the behavior is -as if nil were specified. Thus (sub a) means (sub a nil nil). +as 0. Likewise, if the <from> parameter is omitted, the behavior is +as if t were specified. Thus (sub a) means (sub a 0 t). The following equivalence holds between the sub function and the DWIM-bracket syntax: @@ -8982,7 +8991,8 @@ The replace function replaces a subsequence of the <sequence> with insertion is performed. If <replacement-sequence> is empty (for example, the empty list nil), then a deletion is performed. -If the <from> and <to> parameters are omitted, their values default to nil. +If the <from> and <to> parameters are omitted, their values default +to 0 and t respectively. The following equivalence holds between assignment to a place denoted by DWIM bracket syntax and the replace function: @@ -9597,8 +9607,8 @@ a limit on the number of bits. .TP Syntax: - (logand . <integers>) - (logior . <integers>) + (logand <integer>*) + (logior <integer>*) (logxor <int1> <int2>) .TP @@ -9691,7 +9701,7 @@ the bitwise representations are ...111100 and ...11110. .TP Syntax: - (mask . <integer-values>) + (mask <integer>*) .TP Description: @@ -9723,9 +9733,9 @@ In other words, the following equivalences hold: .TP Syntax: - (throw <symbol> . <args>) - (throwf <symbol> <format-string> . <format-args>) - (error <format-string> . <format-args>) + (throw <symbol> <arg>*) + (throwf <symbol> <format-string> <format-arg>*) + (error <format-string> <format-arg>*) .TP Description: @@ -9792,7 +9802,7 @@ and error. .TP Syntax: - (search-regex <haystack-string> <needle-regex> : <start> <from-end>) + (search-regex <haystack-string> <needle-regex> [ <start> [<from-end>] ]) .TP Description @@ -9810,7 +9820,7 @@ cdr indicates the length of the match. .TP Syntax: - (match-regex <string> <regex> : <position>) + (match-regex <string> <regex> [<position>]) .TP Description @@ -9825,7 +9835,7 @@ If it does not match, then nil is returned. .TP Syntax: - (match-regex-right <string> <regex> : <end-position>) + (match-regex-right <string> <regex> [<end-position>]) .TP Description @@ -9928,7 +9938,7 @@ object. For any other object type, it returns nil. .TP Syntax: - (regex-compile <form-or-string> : <error-stream>) + (regex-compile <form-or-string> [<error-stream>]) .TP Description: @@ -9967,7 +9977,7 @@ Examples: .TP Syntax: - (regex-parse <string> : <error-stream>) + (regex-parse <string> [<error-stream>]) .TP Description: @@ -9998,7 +10008,7 @@ which is suitable as input to regex-compile. Syntax: (make-hash <weak-keys> <weak-vals> <equal-based>) - (hash [ :weak-keys ] [ :weak-vals ] [ :equal-based ]) + (hash { :weak-keys | :weak-vals | :equal-based }*) .TP Description: @@ -10072,7 +10082,7 @@ The return value is <hash>. .TP Syntax: - (group-by <func> <sequence> . <options>) + (group-by <func> <sequence> <option>*) .TP Description: @@ -10083,7 +10093,7 @@ but lists of elements of <sequence>. The function <func> is applied toe each element of <sequence> to compute a key. That key is used to determine which list the item is added to in the hash table. -The trailing arguments <options>, if any, consist of the same keywords +The trailing arguments <option>*, if any, consist of the same keywords that are understood by the hash function, and determine the properties of the hash. @@ -10471,7 +10481,7 @@ a parameter from the outermost op, into the innermost op. .TP Syntax: - (chain {<func>}*) + (chain <func>*) .TP Description: @@ -10517,8 +10527,8 @@ op operator is this: .TP Syntax: - (andf {<func>}*) - (orf {<func>}*) + (andf <func>*) + (orf <func>*) .TP Description: @@ -10568,8 +10578,8 @@ resulting value is returned. Otherwise the arguments are passed to <else-func> and the resulting value is returned. If <then-func> needs to be called, but is nil, then nil is returned -immediately. Likewise, if <else-func> needs to be calld, but is nil, then nil -is returned. +immediately. Likewise, if <else-func> needs to be called, but is omitted or +nil, then nil is returned. The iffi function differs from iff only in the defaulting behavior with respect to the <else-func> argument. The following equivalences hold: @@ -10612,16 +10622,16 @@ the /dev/null device on Unix, but does not involve the operating system. .TP Syntax: - (format <stream-designator> <format-string> {<args>}*) + (format <stream-designator> <format-string> <format-arg>*) .TP Description: The format function performs output to a stream given by <stream-designator>, by interpreting the actions implicit in a <format-string>, incorporating -material pulled from additional arguments given by <args>. Though the function -is simple to invoke, there is complexity in format string language, which is -documented below. +material pulled from additional arguments given by <format-arg>*. Though the +function is simple to invoke, there is complexity in format string language, +which is documented below. The <stream-designator> argument can be a stream object, or one of the values t and nil. The value t serves as a shorthand for *stdout*. The value nil @@ -11149,7 +11159,7 @@ catenation. .TP Syntax: - (make-catenated-stream . streams) + (make-catenated-stream <stream>*) .TP Description @@ -11185,8 +11195,8 @@ are compatible with the intended operations. .TP Syntax: - (read : <source> <error-stream>) - (lisp-parse <source> : <error-stream>) ;; obsolescent synonym for read + (read [ <source> [<error-stream>] ]) + (lisp-parse <source> [<error-stream>]) ;; obsolescent synonym for read .TP Description: @@ -11327,7 +11337,7 @@ changes the current working directory, and the path name is relative. Syntax: (open-command <system-command> <mode-string>) - (open-process <command> <mode-string> <argument-strings>) + (open-process <command> <mode-string> [<argument-strings>]) .TP Description: @@ -11353,7 +11363,7 @@ popen function. The <argument-strings> argument is a list of strings which specifies additional optional arguments to be passed passed to the program. The <command> argument becomes the first argument, and <argument-strings> become the second and -subsequent arguments. +subsequent arguments. If <argument-strings> is omitted, it defaults to empty. If a coprocess is open for writing (<mode-string> is specified as "w"), then writing on the returned stream feeds input to that program's standard input @@ -11651,8 +11661,8 @@ of zero, or for a step direction which cannot meet the endpoint. The <to> argument specifies the endpoint value, which, if it occurs in the sequence, is excluded from it by the range* function, but included by the range -function. If <to> is missing, then there is no endpoint, and the sequence -which is generated is infinite, regardless of <step>. +function. If <to> is missing, or specified as nil, then there is no endpoint, +and the sequence which is generated is infinite, regardless of <step>. If <from> is omitted, then the sequence begins at zero, otherwise <from> must be an integer which specifies the initial value. @@ -11767,7 +11777,7 @@ savings time). .SH UNIX PROGRAMMING -.SS Functions errno and set-errno +.SS Function errno .TP Syntax: @@ -11778,8 +11788,9 @@ Syntax: Description: These functions retrieves the current value of the C library error variable -errno. If the argument <new-errno> is present and is not nil, then it becomes -the new value of errno. The value returned is the prior value. +errno. If the argument <new-errno> is present and is not nil, then it +specifies a value which is stored into errno. The value returned is the prior +value. .SS Funtion exit @@ -11994,7 +12005,7 @@ these result in multiple syslog mesages. .TP Syntax: - (openlog <id-string> : <options> <facility>) + (openlog <id-string> [ <options> [<facility>] ]) .TP Description: @@ -12058,15 +12069,15 @@ Example: .TP Syntax: - (syslog <priority> <format> . <args>) + (syslog <priority> <format> <format-arg>*) .TP Description: This function is the interface to the syslog C function. The printf formatting capabilities of the function are not used; it follows the conventions of the -TXR Lisp format function instead. Note in particular that %m for interpolating -the value of strerror(errno) is currenly not supported. +TXR Lisp format function instead. Note in particular that the %m convention +for interpolating the value of strerror(errno) is currenly not supported. .SH WEB PROGRAMMING SUPPORT |