diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | eval.c | 13 | ||||
-rw-r--r-- | lib.c | 131 | ||||
-rw-r--r-- | lib.h | 6 | ||||
-rw-r--r-- | txr.1 | 137 | ||||
-rw-r--r-- | txr.vim | 183 |
6 files changed, 397 insertions, 100 deletions
@@ -1,3 +1,30 @@ +2014-10-12 Kaz Kylheku <kaz@kylheku.com> + + * eval.c (merge_wrap): New static function + (eval_init): Register less as intrinsic. Retarget merge intrinsic to + merge_wrap for proper argument defaulting which is missing from merge, + and which we don't want to introduce there since internal calls + to merge don't erquire it. Change registration of sort so it has + only one required argument, not two. + + * lib.c (less_f): New global variable. + (less_tab): New static array. + (less_tab_init): New static function. + (less): New function. + (sort): Default lessfun argument to the less function. + (obj_init): GC-protect the less_f variable. + Initialize it with a function object made from the less function. + (init): Call less_tab_init. + + * lib.h (enum type): New enumeration member MAX_TYPE, an alias + for the largest type. + (less_f, less): Declared. + + * txr.1: Documented new less function, and that the lessfun + argument in sort and merge is optional, defaulting to less. + + * txr.vim: Regenerated. + 2014-10-11 Kaz Kylheku <kaz@kylheku.com> * eval.c (eval_init): Register chr_isblank and chr_isunisp as @@ -3329,6 +3329,14 @@ static val pprinl(val obj, val stream) return ret; } +static val merge_wrap(val list1, val list2, val lessfun, val keyfun) +{ + keyfun = default_arg(keyfun, identity_f); + lessfun = default_arg(lessfun, less_f); + + return merge(list1, list2, lessfun, keyfun); +} + void eval_init(void) { protect(&top_vb, &top_fb, &top_mb, &top_smb, &special, &dyn_env, @@ -3776,6 +3784,7 @@ void eval_init(void) reg_fun(intern(lit("flo-int"), user_package), func_n1(flo_int)); reg_fun(intern(lit("tofloat"), user_package), func_n1(tofloat)); reg_fun(intern(lit("toint"), user_package), func_n2o(toint, 1)); + reg_fun(intern(lit("less"), user_package), func_n2(less)); reg_fun(intern(lit("chrp"), user_package), func_n1(chrp)); reg_fun(intern(lit("chr-isalnum"), user_package), func_n1(chr_isalnum)); reg_fun(intern(lit("chr-isalpha"), user_package), func_n1(chr_isalpha)); @@ -3838,8 +3847,8 @@ 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, 3)); - reg_fun(intern(lit("sort"), user_package), func_n3o(sort, 2)); + reg_fun(intern(lit("merge"), user_package), func_n4o(merge_wrap, 2)); + reg_fun(intern(lit("sort"), user_package), func_n3o(sort, 1)); reg_fun(intern(lit("find"), user_package), func_n4o(find, 2)); reg_fun(intern(lit("multi-sort"), user_package), func_n3o(multi_sort, 2)); reg_fun(intern(lit("find-if"), user_package), func_n3o(find_if, 2)); @@ -98,7 +98,7 @@ val nil_string; val null_list; val identity_f, equal_f, eql_f, eq_f, gt_f, lt_f, car_f, cdr_f, null_f; -val list_f; +val list_f, less_f; val prog_string; @@ -3023,6 +3023,130 @@ val num_str(val str) return flo_str(str); } +static int less_tab[MAXTYPE+1][MAXTYPE+1]; + +static void less_tab_init(void) +{ + int l, r; + static int type_prec[MAXTYPE+1] = { + 2, /* NIL */ + 0, /* NUM */ + 0, /* CHR */ + 1, /* LIT */ + 3, /* CONS */ + 1, /* STR */ + 2, /* SYM */ + 6, /* PKG */ + 5, /* FUN */ + 4, /* VEC */ + 3, /* LCONS */ + 1, /* LSTR */ + 8, /* COBJ */ + 7, /* ENV */ + 0, /* BGNUM */ + 0, /* FLNUM */ + }; + + for (l = 0; l <= MAXTYPE; l++) + for (r = 0; r <= MAXTYPE; r++) { + int l_prec = type_prec[l]; + int r_prec = type_prec[r]; + + if (l_prec < r_prec) + less_tab[l][r] = 1; + else if (l_prec == r_prec) + less_tab[l][r] = 2; + } +} + +val less(val left, val right) +{ + type_t l_type, r_type; + + if (left == right) + return nil; + + l_type = type(left); + r_type = type(right); + + switch (less_tab[l_type][r_type]) { + case 0: + return nil; + case 1: + return t; + default: + break; + } + + switch (l_type) { + case NUM: + case CHR: + case BGNUM: + case FLNUM: + return lt(left, right); + case LIT: + case STR: + case LSTR: + return str_lt(left, right); + case NIL: + return str_lt(nil_string, symbol_name(right)); + case SYM: + return str_lt(left->s.name, symbol_name(right)); + case CONS: + case LCONS: + for (;;) { + val carl = car(left); + val carr = car(right); + + if (less(carl, carr)) + return t; + + if (equal(carl, carr)) { + val cdrl = cdr(left); + val cdrr = cdr(right); + + if (consp(cdrl) && consp(cdrr)) { + left = cdrl; + right = cdrr; + continue; + } + + return less(cdrl, cdrr); + } + break; + } + return nil; + case VEC: + { + cnum i; + cnum lenl = c_num(length_vec(left)); + cnum lenr = c_num(length_vec(right)); + cnum len = min(lenl, lenr); + + for (i = 0; i < len; i++) { + val litem = vecref(left, num_fast(i)); + val ritem = vecref(right, num_fast(i)); + + if (less(litem, ritem)) + return t; + + if (!equal(litem, ritem)) + return nil; + } + + return c_true (lenl < lenr); + } + case FUN: + case PKG: + case ENV: + case COBJ: + uw_throwf(type_error_s, lit("less: cannot compare ~s and ~s"), + left, right, nao); + } + + internal_error("unhandled case in less function"); +} + val chrp(val chr) { return (is_chr(chr)) ? t : nil; @@ -5424,6 +5548,7 @@ val sort(val seq_in, val lessfun, val keyfun) return make_like(nil, seq_orig); keyfun = default_arg(keyfun, identity_f); + lessfun = default_arg(lessfun, less_f); if (consp(seq)) { /* The list could have a mixture of generation 0 and 1 @@ -6086,7 +6211,7 @@ static void obj_init(void) &user_package_var, &null_string, &nil_string, &null_list, &equal_f, &eq_f, &eql_f, >_f, <_f, &car_f, &cdr_f, &null_f, &list_f, - &identity_f, &prog_string, &env_list, + &identity_f, &less_f, &prog_string, &env_list, (val *) 0); nil_string = lit("nil"); @@ -6218,6 +6343,7 @@ static void obj_init(void) cdr_f = func_n1(cdr); null_f = func_n1(null); list_f = func_n0v(identity); + less_f = func_n2(less); prog_string = string(progname); } @@ -6790,6 +6916,7 @@ void init(const wchar_t *pn, mem_t *(*oom)(mem_t *, size_t), hash_init(); regex_init(); gc_late_init(); + less_tab_init(); gc_state(gc_save); } @@ -42,7 +42,8 @@ typedef int_ptr_t cnum; typedef enum type { NIL, NUM = TAG_NUM, CHR = TAG_CHR, LIT = TAG_LIT, CONS, STR, SYM, PKG, FUN, VEC, LCONS, LSTR, COBJ, ENV, - BGNUM, FLNUM /* If extending, check TYPE_SHIFT */ + BGNUM, FLNUM, MAXTYPE = FLNUM + /* If extending, check TYPE_SHIFT */ } type_t; #define TYPE_SHIFT 4 @@ -378,7 +379,7 @@ extern val null_string; extern val null_list; /* (nil) */ extern val identity_f, equal_f, eql_f, eq_f, gt_f, lt_f, car_f, cdr_f, null_f; -extern val list_f; +extern val list_f, less_f; extern const wchar_t *progname; extern val prog_string; @@ -599,6 +600,7 @@ val flo_str(val str); val num_str(val str); val int_flo(val f); val flo_int(val i); +val less(val left, val right); val chrp(val chr); wchar_t c_chr(val chr); val chr_isalnum(val ch); @@ -14520,7 +14520,7 @@ value. .SS* List Sorting .coNP Function @ merge .synb -.mets (merge < list1 < list2 < lessfun <> [ keyfun ]) +.mets (merge < list1 < list2 >> [ lessfun <> [ keyfun ]]) .syne .desc The @@ -17236,9 +17236,136 @@ or value. The sequence or hash table is returned. +.coNP Function @ less +.synb +.mets (less < left-obj << right-obj ) +.syne +.desc +The +.code less +function determines whether +.meta left-obj +compares less than +.meta right-obj +in a generic way which handles arguments of various types. + +The function is used as the default for the +.meta lessfun +argument of the functions +.code sort +and +.codn merge . + +The +.code less +function is capable of comparing numbers, characters, symbols, strings, +as well as lists and vectors of these. + +If both arguments are the same object so that +.cblk +.meti (eq < left-obj << right-obj ) +.cble +holds true, then the function returns +.code nil +regardless of the type of +.metn left-obj , +even if the function doesn't handle comparing different instances +of that type. In other words, no object is less than itself, no matter +what it is. + +If both arguments are numbers or characters, they are compared as if using the +.code < function. + +If both arguments are strings, they are compared as if using the +.code string-lt +function. + +If both arguments are symbols, then their names are compared in +their place, as if by the +.code string-lt +function. + +If both arguments are conses, then they are compared as follows: +.RS +.IP 1. +The +.code less +function is recursively applied to the +.code car +fields of both arguments. If it yields true, then +.meta left-obj +is deemed to be less than +.metn right-obj . +.IP 2. +Otherwise, if the +.code car +fields are unequal under +the +.code equal +function, +.code less +returns +.codn nil. +.IP 3. +If the +.code car +fields are +.code equal +then +.code less +is recursively applied to the +.code cdr +fields of the arguments, and the result of that comparison is returned. +.RE + +.IP +This logic performs a lexicographic comparison on ordinary lists such +that for instance +.code (1 1) +is less than +.code (1 1 1) +but not less than +.code (1 0) +or +.codn (1) . + +Note that the empty +.code nil +list nil compared to a cons is handled by type-based precedence, described +below. + +If the arguments are vectors, they are compared lexicographically, similar +to strings. Corresponding elements, starting with element 0, of the +vectors are compared until an index position is found where the vectors +differ. If this differing position is beyond the end of one of the two vectors, +then the shorter vector is considered to be lesser. Otherwise, the result +of +.code less +is the outcome of comparing those differing elements themselves +with +.codn less . + +If the two arguments are of the above types, but of mutually different types, +then +.code less +resolves the situation based on the following precedence: numbers and +characters are less than strings, which are less than symbols, +which are less than conses, which are less than vectors. + +Note that since +.code nil +is a symbol, it is ranked lower than a cons. This interpretation ensures +correct behavior when +.code nil +is regarded as an empty list, since the empty list is lexicographically prior to +a nonempty list. + +Finally, if either of the arguments has a type other than the above discussed +types, the situation is an error. + .coNP Function @ sort .synb -.mets (sort < sequence < lessfun <> [ keyfun ]) +.mets (sort < sequence >> [ lessfun <> [ keyfun ]]) .syne .desc The @@ -17274,7 +17401,11 @@ than the right argument. For instance, if the numeric function is used on numeric keys, it produces an ascending sorted order. If the function .code > -is used, then a descending sort is produced. +is used, then a descending sort is produced. If +.meta lessfun +is omitted, then it defaults to the generic +.code less +function. The .code sort @@ -100,97 +100,98 @@ syn keyword txl_keyword contained lazy-str-force-upto lazy-str-get-trailing-list syn keyword txl_keyword contained lbind lcons-fun lconsp ldiff syn keyword txl_keyword contained length length-list length-str length-str-< syn keyword txl_keyword contained length-str-<= length-str-> length-str->= length-vec -syn keyword txl_keyword contained let let* link lisp-parse -syn keyword txl_keyword contained list list* list-str list-vector -syn keyword txl_keyword contained listp log log-alert log-auth -syn keyword txl_keyword contained log-authpriv log-cons log-crit log-daemon -syn keyword txl_keyword contained log-debug log-emerg log-err log-info -syn keyword txl_keyword contained log-ndelay log-notice log-nowait log-odelay -syn keyword txl_keyword contained log-perror log-pid log-user log-warning -syn keyword txl_keyword contained log10 log2 logand logior -syn keyword txl_keyword contained lognot logtest logtrunc logxor -syn keyword txl_keyword contained macro-form-p macro-time macroexpand macroexpand-1 -syn keyword txl_keyword contained macrolet major make-catenated-stream make-env -syn keyword txl_keyword contained make-hash make-lazy-cons make-like make-package -syn keyword txl_keyword contained make-random-state make-similar-hash make-string-byte-input-stream make-string-input-stream -syn keyword txl_keyword contained make-string-output-stream make-strlist-output-stream make-sym make-time -syn keyword txl_keyword contained make-time-utc make-trie makedev mapcar -syn keyword txl_keyword contained mapcar* mapdo maphash mappend -syn keyword txl_keyword contained mappend* mask match-fun match-regex -syn keyword txl_keyword contained match-regex-right match-str match-str-tree max -syn keyword txl_keyword contained member member-if memq memql -syn keyword txl_keyword contained memqual merge min minor -syn keyword txl_keyword contained mkdir mknod mkstring mod -syn keyword txl_keyword contained multi multi-sort n-choose-k n-perm-k -syn keyword txl_keyword contained nconc nilf none not -syn keyword txl_keyword contained nreverse null nullify num-chr -syn keyword txl_keyword contained num-str numberp oddp op -syn keyword txl_keyword contained open-command open-directory open-file open-files -syn keyword txl_keyword contained open-files* open-pipe open-process open-tail -syn keyword txl_keyword contained openlog or orf packagep -syn keyword txl_keyword contained partition partition* partition-by perm -syn keyword txl_keyword contained pop pos pos-if pos-max -syn keyword txl_keyword contained pos-min posq posql posqual -syn keyword txl_keyword contained pprinl pprint pprof prinl -syn keyword txl_keyword contained print prof prog1 progn -syn keyword txl_keyword contained prop proper-listp push pushhash -syn keyword txl_keyword contained put-byte put-char put-line put-lines -syn keyword txl_keyword contained put-string put-strings pwd qquote -syn keyword txl_keyword contained quasi quasilist quote rand -syn keyword txl_keyword contained random random-fixnum random-state-p range -syn keyword txl_keyword contained range* range-regex rcomb read -syn keyword txl_keyword contained readlink real-time-stream-p reduce-left reduce-right -syn keyword txl_keyword contained ref refset regex-compile regex-parse -syn keyword txl_keyword contained regexp regsub rehome-sym remhash -syn keyword txl_keyword contained remove-if remove-if* remove-path remq -syn keyword txl_keyword contained remq* remql remql* remqual -syn keyword txl_keyword contained remqual* rename-path repeat replace -syn keyword txl_keyword contained replace-list replace-str replace-vec rest -syn keyword txl_keyword contained ret retf return return-from -syn keyword txl_keyword contained reverse rlcp rperm rplaca -syn keyword txl_keyword contained rplacd run s-ifblk s-ifchr -syn keyword txl_keyword contained s-ifdir s-ififo s-iflnk s-ifmt -syn keyword txl_keyword contained s-ifreg s-ifsock s-irgrp s-iroth -syn keyword txl_keyword contained s-irusr s-irwxg s-irwxo s-irwxu -syn keyword txl_keyword contained s-isgid s-isuid s-isvtx s-iwgrp -syn keyword txl_keyword contained s-iwoth s-iwusr s-ixgrp s-ixoth -syn keyword txl_keyword contained s-ixusr search search-regex search-str -syn keyword txl_keyword contained search-str-tree second seek-stream select -syn keyword txl_keyword contained seqp set set-diff set-hash-userdata -syn keyword txl_keyword contained set-sig-handler sethash setitimer setlogmask -syn keyword txl_keyword contained sh sig-abrt sig-alrm sig-bus -syn keyword txl_keyword contained sig-check sig-chld sig-cont sig-fpe -syn keyword txl_keyword contained sig-hup sig-ill sig-int sig-io -syn keyword txl_keyword contained sig-iot sig-kill sig-lost sig-pipe -syn keyword txl_keyword contained sig-poll sig-prof sig-pwr sig-quit -syn keyword txl_keyword contained sig-segv sig-stkflt sig-stop sig-sys -syn keyword txl_keyword contained sig-term sig-trap sig-tstp sig-ttin -syn keyword txl_keyword contained sig-ttou sig-urg sig-usr1 sig-usr2 -syn keyword txl_keyword contained sig-vtalrm sig-winch sig-xcpu sig-xfsz -syn keyword txl_keyword contained sin sixth size-vec some -syn keyword txl_keyword contained sort source-loc source-loc-str span-str -syn keyword txl_keyword contained splice split-str split-str-set sqrt -syn keyword txl_keyword contained stat stdlib str< str<= -syn keyword txl_keyword contained str= str> str>= stream-get-prop -syn keyword txl_keyword contained stream-set-prop streamp string-extend string-lt -syn keyword txl_keyword contained stringp sub sub-list sub-str -syn keyword txl_keyword contained sub-vec symacrolet symbol-function symbol-name -syn keyword txl_keyword contained symbol-package symbol-value symbolp symlink -syn keyword txl_keyword contained sys-qquote sys-splice sys-unquote syslog -syn keyword txl_keyword contained tan tf third throw -syn keyword txl_keyword contained throwf time time-fields-local time-fields-utc -syn keyword txl_keyword contained time-string-local time-string-utc time-usec tofloat -syn keyword txl_keyword contained toint tok-str tok-where tostring -syn keyword txl_keyword contained tostringp transpose tree-bind tree-case -syn keyword txl_keyword contained tree-find trie-add trie-compress trie-lookup-begin -syn keyword txl_keyword contained trie-lookup-feed-char trie-value-at trim-str true -syn keyword txl_keyword contained trunc tuples typeof unget-byte -syn keyword txl_keyword contained unget-char uniq unless unquote -syn keyword txl_keyword contained until upcase-str update url-decode -syn keyword txl_keyword contained url-encode usleep uw-protect vec -syn keyword txl_keyword contained vec-push vec-set-length vecref vector -syn keyword txl_keyword contained vector-list vectorp when where -syn keyword txl_keyword contained while with-saved-vars zerop zip +syn keyword txl_keyword contained less let let* link +syn keyword txl_keyword contained lisp-parse list list* list-str +syn keyword txl_keyword contained list-vector listp log log-alert +syn keyword txl_keyword contained log-auth log-authpriv log-cons log-crit +syn keyword txl_keyword contained log-daemon log-debug log-emerg log-err +syn keyword txl_keyword contained log-info log-ndelay log-notice log-nowait +syn keyword txl_keyword contained log-odelay log-perror log-pid log-user +syn keyword txl_keyword contained log-warning log10 log2 logand +syn keyword txl_keyword contained logior lognot logtest logtrunc +syn keyword txl_keyword contained logxor macro-form-p macro-time macroexpand +syn keyword txl_keyword contained macroexpand-1 macrolet major make-catenated-stream +syn keyword txl_keyword contained make-env make-hash make-lazy-cons make-like +syn keyword txl_keyword contained make-package make-random-state make-similar-hash make-string-byte-input-stream +syn keyword txl_keyword contained make-string-input-stream make-string-output-stream make-strlist-output-stream make-sym +syn keyword txl_keyword contained make-time make-time-utc make-trie makedev +syn keyword txl_keyword contained mapcar mapcar* mapdo maphash +syn keyword txl_keyword contained mappend mappend* mask match-fun +syn keyword txl_keyword contained match-regex match-regex-right match-str match-str-tree +syn keyword txl_keyword contained max member member-if memq +syn keyword txl_keyword contained memql memqual merge min +syn keyword txl_keyword contained minor mkdir mknod mkstring +syn keyword txl_keyword contained mod multi multi-sort n-choose-k +syn keyword txl_keyword contained n-perm-k nconc nilf none +syn keyword txl_keyword contained not nreverse null nullify +syn keyword txl_keyword contained num-chr num-str numberp oddp +syn keyword txl_keyword contained op open-command open-directory open-file +syn keyword txl_keyword contained open-files open-files* open-pipe open-process +syn keyword txl_keyword contained open-tail openlog or orf +syn keyword txl_keyword contained packagep partition partition* partition-by +syn keyword txl_keyword contained perm pop pos pos-if +syn keyword txl_keyword contained pos-max pos-min posq posql +syn keyword txl_keyword contained posqual pprinl pprint pprof +syn keyword txl_keyword contained prinl print prof prog1 +syn keyword txl_keyword contained progn prop proper-listp push +syn keyword txl_keyword contained pushhash put-byte put-char put-line +syn keyword txl_keyword contained put-lines put-string put-strings pwd +syn keyword txl_keyword contained qquote quasi quasilist quote +syn keyword txl_keyword contained rand random random-fixnum random-state-p +syn keyword txl_keyword contained range range* range-regex rcomb +syn keyword txl_keyword contained read readlink real-time-stream-p reduce-left +syn keyword txl_keyword contained reduce-right ref refset regex-compile +syn keyword txl_keyword contained regex-parse regexp regsub rehome-sym +syn keyword txl_keyword contained remhash remove-if remove-if* remove-path +syn keyword txl_keyword contained remq remq* remql remql* +syn keyword txl_keyword contained remqual remqual* rename-path repeat +syn keyword txl_keyword contained replace replace-list replace-str replace-vec +syn keyword txl_keyword contained rest ret retf return +syn keyword txl_keyword contained return-from reverse rlcp rperm +syn keyword txl_keyword contained rplaca rplacd run s-ifblk +syn keyword txl_keyword contained s-ifchr s-ifdir s-ififo s-iflnk +syn keyword txl_keyword contained s-ifmt s-ifreg s-ifsock s-irgrp +syn keyword txl_keyword contained s-iroth s-irusr s-irwxg s-irwxo +syn keyword txl_keyword contained s-irwxu s-isgid s-isuid s-isvtx +syn keyword txl_keyword contained s-iwgrp s-iwoth s-iwusr s-ixgrp +syn keyword txl_keyword contained s-ixoth s-ixusr search search-regex +syn keyword txl_keyword contained search-str search-str-tree second seek-stream +syn keyword txl_keyword contained select seqp set set-diff +syn keyword txl_keyword contained set-hash-userdata set-sig-handler sethash setitimer +syn keyword txl_keyword contained setlogmask sh sig-abrt sig-alrm +syn keyword txl_keyword contained sig-bus sig-check sig-chld sig-cont +syn keyword txl_keyword contained sig-fpe sig-hup sig-ill sig-int +syn keyword txl_keyword contained sig-io sig-iot sig-kill sig-lost +syn keyword txl_keyword contained sig-pipe sig-poll sig-prof sig-pwr +syn keyword txl_keyword contained sig-quit sig-segv sig-stkflt sig-stop +syn keyword txl_keyword contained sig-sys sig-term sig-trap sig-tstp +syn keyword txl_keyword contained sig-ttin sig-ttou sig-urg sig-usr1 +syn keyword txl_keyword contained sig-usr2 sig-vtalrm sig-winch sig-xcpu +syn keyword txl_keyword contained sig-xfsz sin sixth size-vec +syn keyword txl_keyword contained some sort source-loc source-loc-str +syn keyword txl_keyword contained span-str splice split-str split-str-set +syn keyword txl_keyword contained sqrt stat stdlib str< +syn keyword txl_keyword contained str<= str= str> str>= +syn keyword txl_keyword contained stream-get-prop stream-set-prop streamp string-extend +syn keyword txl_keyword contained string-lt stringp sub sub-list +syn keyword txl_keyword contained sub-str sub-vec symacrolet symbol-function +syn keyword txl_keyword contained symbol-name symbol-package symbol-value symbolp +syn keyword txl_keyword contained symlink sys-qquote sys-splice sys-unquote +syn keyword txl_keyword contained syslog tan tf third +syn keyword txl_keyword contained throw throwf time time-fields-local +syn keyword txl_keyword contained time-fields-utc time-string-local time-string-utc time-usec +syn keyword txl_keyword contained tofloat toint tok-str tok-where +syn keyword txl_keyword contained tostring tostringp transpose tree-bind +syn keyword txl_keyword contained tree-case tree-find trie-add trie-compress +syn keyword txl_keyword contained trie-lookup-begin trie-lookup-feed-char trie-value-at trim-str +syn keyword txl_keyword contained true trunc tuples typeof +syn keyword txl_keyword contained unget-byte unget-char uniq unless +syn keyword txl_keyword contained unquote until upcase-str update +syn keyword txl_keyword contained url-decode url-encode usleep uw-protect +syn keyword txl_keyword contained vec vec-push vec-set-length vecref +syn keyword txl_keyword contained vector vector-list vectorp when +syn keyword txl_keyword contained where while with-saved-vars zerop +syn keyword txl_keyword contained zip syn match txr_error "@[\t ]*[*]\?[\t ]*." syn match txr_nested_error "[^\t `]\+" contained |