summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--eval.c31
-rw-r--r--lib.c56
-rw-r--r--lib.h4
-rw-r--r--stream.c112
-rw-r--r--stream.h4
-rw-r--r--txr.vim43
7 files changed, 244 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 5ca95f7a..1febf32f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
2011-11-28 Kaz Kylheku <kaz@kylheku.com>
+ Adding streams functions to Lisp evaluator.
+
+ * eval.c (op_let): Bugfix: was not evaluating var init forms.
+ (reg_var): New static function.
+ (eval_init): Registered numerous stream functions and the
+ three standard streams.
+
+ * lib.c (obj_print, obj_pprint): Modified to return a value.
+ (init): eval_init called after stream_init, because eval
+ needs the three standrad streams prepared.
+
+ * lib.h (obj_print, obj_pprint): Declarations updated.
+
+ * stream.c (format): Support t as a shorthand for standard output.
+ (formatv, open_directory, open_file, open_pipe): New functions.
+ (w_opendir): New static function.
+
+ * stream.h (formatv, open_directory, open_file, open_pipe):
+ Declared.
+
+ * txr.vim: set iskeyword such that keyword can contain special
+ characters. Set b:current_syntax to "lisp".
+ (txl_keyword): New keyword category populated with TXR Lisp keywords
+ defined as separate category.
+ (txr_list): Contains txl_keyword.
+ (txr_meta): Contains txl_keyword and txr_list.
+
+2011-11-28 Kaz Kylheku <kaz@kylheku.com>
+
mapcar, mappend and apply functions.
fun operator.
diff --git a/eval.c b/eval.c
index 26b01772..fed7f272 100644
--- a/eval.c
+++ b/eval.c
@@ -359,7 +359,7 @@ static val op_let(val form, val env)
if (!consp(cdr(item)))
eval_error(form, lit("let: invalid syntax: ~s"), item, nao);
var = first(item);
- val = second(item);
+ val = eval(second(item), env, form);
}
if (symbolp(var)) {
@@ -766,6 +766,11 @@ static void reg_fun(val sym, val fun)
sethash(top_fb, sym, cons(sym, fun));
}
+static void reg_var(val sym, val obj)
+{
+ sethash(top_vb, sym, cons(sym, obj));
+}
+
void eval_init(void)
{
protect(&top_vb, &top_fb, &op_table, (val *) 0);
@@ -858,6 +863,30 @@ void eval_init(void)
reg_fun(intern(lit("eval"), user_package), func_n2(eval_intrinsic));
+ reg_var(intern(lit("*stdout*"), user_package), std_output);
+ reg_var(intern(lit("*stdin*"), user_package), std_input);
+ reg_var(intern(lit("*stderr*"), user_package), std_error);
+ reg_fun(intern(lit("format"), user_package), func_n2v(formatv));
+ reg_fun(intern(lit("print"), user_package), func_n2(obj_print));
+ reg_fun(intern(lit("pprint"), user_package), func_n2(obj_pprint));
+ reg_fun(intern(lit("make-string-input-stream"), user_package), func_n1(make_string_input_stream));
+ reg_fun(intern(lit("make-string-byte-input-stream"), user_package), func_n1(make_string_byte_input_stream));
+ reg_fun(intern(lit("make-string-output-stream"), user_package), func_n0(make_string_output_stream));
+ reg_fun(intern(lit("get-string-from-stream"), user_package), func_n1(get_string_from_stream));
+ reg_fun(intern(lit("make-strlist-output-stream"), user_package), func_n0(make_strlist_output_stream));
+ reg_fun(intern(lit("get-list-from-stream"), user_package), func_n1(get_list_from_stream));
+ reg_fun(intern(lit("close-stream"), user_package), func_n2(close_stream));
+ reg_fun(intern(lit("get-line"), user_package), func_n1(get_line));
+ reg_fun(intern(lit("get-char"), user_package), func_n1(get_char));
+ reg_fun(intern(lit("get-byte"), user_package), func_n1(get_byte));
+ reg_fun(intern(lit("put-string"), user_package), func_n2(put_string));
+ reg_fun(intern(lit("put-line"), user_package), func_n2(put_line));
+ reg_fun(intern(lit("put-char"), user_package), func_n2(put_char));
+ reg_fun(intern(lit("flush-stream"), user_package), func_n1(flush_stream));
+ reg_fun(intern(lit("open-directory"), user_package), func_n1(open_directory));
+ reg_fun(intern(lit("open-file"), user_package), func_n2(open_file));
+ reg_fun(intern(lit("open-pipe"), user_package), func_n2(open_pipe));
+
eval_error_s = intern(lit("eval-error"), user_package);
uw_register_subtype(eval_error_s, error_s);
}
diff --git a/lib.c b/lib.c
index 63893f0b..fdf5758e 100644
--- a/lib.c
+++ b/lib.c
@@ -2970,11 +2970,11 @@ static void obj_init(void)
prog_string = string(progname);
}
-void obj_print(val obj, val out)
+val obj_print(val obj, val out)
{
if (obj == nil) {
put_string(out, lit("nil"));
- return;
+ return obj;
}
switch (type(obj)) {
@@ -3009,7 +3009,7 @@ void obj_print(val obj, val out)
}
}
}
- return;
+ return obj;
case LIT:
case STR:
{
@@ -3036,7 +3036,7 @@ void obj_print(val obj, val out)
}
put_char(out, chr('"'));
}
- return;
+ return obj;
case CHR:
{
wchar_t ch = c_chr(obj);
@@ -3060,10 +3060,10 @@ void obj_print(val obj, val out)
format(out, lit("x~x"), num(ch), nao);
}
}
- return;
+ return obj;
case NUM:
format(out, lit("~s"), obj, nao);
- return;
+ return obj;
case SYM:
if (obj->s.package != user_package) {
if (!obj->s.package)
@@ -3073,13 +3073,13 @@ void obj_print(val obj, val out)
put_char(out, chr(':'));
}
put_string(out, symbol_name(obj));
- return;
+ return obj;
case PKG:
format(out, lit("#<package: ~s>"), obj->pk.name, nao);
- return;
+ return obj;
case FUN:
format(out, lit("#<function: type ~a>"), num(obj->f.functype), nao);
- return;
+ return obj;
case VEC:
{
cnum i, fill = c_num(obj->v.vec[vec_fill]);
@@ -3091,27 +3091,28 @@ void obj_print(val obj, val out)
}
put_char(out, chr(')'));
}
- return;
+ return obj;
case LSTR:
obj_print(obj->ls.prefix, out);
put_string(out, lit("#<... lazy string>"));
- return;
+ return obj;
case COBJ:
obj->co.ops->print(obj, out);
- return;
+ return obj;
case ENV:
format(out, lit("#<environment: ~p>"), (void *) obj, nao);
- return;
+ return obj;
}
format(out, lit("#<garbage: ~p>"), (void *) obj, nao);
+ return obj;
}
-void obj_pprint(val obj, val out)
+val obj_pprint(val obj, val out)
{
if (obj == nil) {
put_string(out, lit("nil"));
- return;
+ return obj;
}
switch (type(obj)) {
@@ -3146,26 +3147,26 @@ void obj_pprint(val obj, val out)
}
}
}
- return;
+ return obj;
case LIT:
case STR:
put_string(out, obj);
- return;
+ return obj;
case CHR:
put_char(out, obj);
- return;
+ return obj;
case NUM:
format(out, lit("~s"), obj, nao);
- return;
+ return obj;
case SYM:
put_string(out, symbol_name(obj));
- return;
+ return obj;
case PKG:
format(out, lit("#<package: ~s>"), obj->pk.name, nao);
- return;
+ return obj;
case FUN:
format(out, lit("#<function: type ~a>"), num(obj->f.functype), nao);
- return;
+ return obj;
case VEC:
{
cnum i, fill = c_num(obj->v.vec[vec_fill]);
@@ -3177,20 +3178,21 @@ void obj_pprint(val obj, val out)
}
put_char(out, chr(')'));
}
- return;
+ return obj;
case LSTR:
obj_pprint(obj->ls.prefix, out);
put_string(out, lit("..."));
- return;
+ return obj;
case COBJ:
obj->co.ops->print(obj, out);
- return;
+ return obj;
case ENV:
format(out, lit("#<environment: ~p>"), (void *) obj, nao);
- return;
+ return obj;
}
format(out, lit("#<garbage: ~p>"), (void *) obj, nao);
+ return obj;
}
void init(const wchar_t *pn, mem_t *(*oom)(mem_t *, size_t),
@@ -3204,8 +3206,8 @@ void init(const wchar_t *pn, mem_t *(*oom)(mem_t *, size_t),
gc_init(stack_bottom);
obj_init();
uw_init();
- eval_init();
stream_init();
+ eval_init();
filter_init();
gc_state(gc_save);
diff --git a/lib.h b/lib.h
index d83a0cef..aa3064f0 100644
--- a/lib.h
+++ b/lib.h
@@ -489,8 +489,8 @@ val find(val list, val key, val testfun, val keyfun);
val set_diff(val list1, val list2, val testfun, val keyfun);
val env(void);
-void obj_print(val obj, val stream);
-void obj_pprint(val obj, val stream);
+val obj_print(val obj, val stream);
+val obj_pprint(val obj, val stream);
void init(const wchar_t *progname, mem_t *(*oom_realloc)(mem_t *, size_t),
val *stack_bottom);
void dump(val obj, val stream);
diff --git a/stream.c b/stream.c
index 3e71b53e..395d9ab6 100644
--- a/stream.c
+++ b/stream.c
@@ -1018,7 +1018,9 @@ val vformat_to_string(val fmtstr, va_list vl)
val format(val stream, val str, ...)
{
- val st = or2(stream, make_string_output_stream());
+ val st = if3(stream == t,
+ std_output,
+ or2(stream, make_string_output_stream()));
type_check (st, COBJ);
type_assert (st->co.cls == stream_s, (lit("~a is not a stream"), st, nao));
@@ -1032,6 +1034,53 @@ val format(val stream, val str, ...)
}
}
+val formatv(val stream, val string, val args)
+{
+ val arg[32], *p = arg;
+
+ for (; args && p - arg < 32; args = cdr(args), p++)
+ *p = car(args);
+
+ switch (p - arg) {
+ case 0: return format(stream, string, nao);
+ case 1: return format(stream, string, arg[0], nao);
+ case 2: return format(stream, string, arg[0], arg[1], nao);
+ case 3: return format(stream, string, arg[0], arg[1], arg[2], nao);
+ case 4: return format(stream, string, arg[0], arg[1], arg[2], arg[3], nao);
+ case 5: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], nao);
+ case 6: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], nao);
+ case 7: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], nao);
+ case 8: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], nao);
+ case 9: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], nao);
+ case 10: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], nao);
+ case 11: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], nao);
+ case 12: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], nao);
+ case 13: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], nao);
+ case 14: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], nao);
+ case 15: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], nao);
+ case 16: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], nao);
+ case 17: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], nao);
+ case 18: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], nao);
+ case 19: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], nao);
+ case 20: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], nao);
+ case 21: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], nao);
+ case 22: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], nao);
+ case 23: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], nao);
+ case 24: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], nao);
+ case 25: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], nao);
+ case 26: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], nao);
+ case 27: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], arg[26], nao);
+ case 28: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], arg[26], arg[27], nao);
+ case 29: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], arg[26], arg[27], arg[28], nao);
+ case 30: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], arg[26], arg[27], arg[28], arg[29], nao);
+ case 31: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], arg[26], arg[27], arg[28], arg[29], arg[30], nao);
+ case 32: return format(stream, string, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13], arg[14], arg[15], arg[16], arg[17], arg[18], arg[19], arg[20], arg[21], arg[22], arg[23], arg[24], arg[25], arg[26], arg[27], arg[28], arg[29], arg[30], arg[31], nao);
+ }
+
+ uw_throwf(file_error_s, lit("too many arguments to format"), nao);
+ abort();
+}
+
val put_string(val stream, val string)
{
type_check (stream, COBJ);
@@ -1073,6 +1122,67 @@ val flush_stream(val stream)
}
}
+static DIR *w_opendir(const wchar_t *wname)
+{
+ char *name = (char *) utf8_dup_to(wname);
+ DIR *d = opendir(name);
+ free(name);
+ return d;
+}
+
+val open_directory(val path)
+{
+ DIR *d = w_opendir(c_str(path));
+
+ if (!d)
+ uw_throwf(file_error_s, lit("error opening directory ~a: ~a/~s"),
+ path, num(errno), string_utf8(strerror(errno)), nao);
+
+ return make_dir_stream(d);
+}
+
+val open_file(val path, val mode_str)
+{
+ FILE *f = w_fopen(c_str(path), c_str(mode_str));
+ val input = nil, output = nil;
+
+ if (!f)
+ uw_throwf(file_error_s, lit("error opening ~a: ~a/~s"),
+ path, num(errno), string_utf8(strerror(errno)), nao);
+
+ if (break_str(mode_str, lit("w")))
+ output = t;
+ if (break_str(mode_str, lit("a")))
+ output = t;
+ if (break_str(mode_str, lit("r")))
+ input = t;
+ if (break_str(mode_str, lit("+")))
+ input = output = t;
+
+ return make_stdio_stream(f, path, input, output);
+}
+
+val open_pipe(val path, val mode_str)
+{
+ FILE *f = w_popen(c_str(path), c_str(mode_str));
+ val input = nil, output = nil;
+
+ if (!f)
+ uw_throwf(file_error_s, lit("error opening pipe ~a: ~a/~s"),
+ path, num(errno), string_utf8(strerror(errno)), nao);
+
+ if (break_str(mode_str, lit("w")))
+ output = t;
+ if (break_str(mode_str, lit("a")))
+ output = t;
+ if (break_str(mode_str, lit("r")))
+ input = t;
+ if (break_str(mode_str, lit("+")))
+ input = output = t;
+
+ return make_pipe_stream(f, path, input, output);
+}
+
void stream_init(void)
{
protect(&std_input, &std_output, &std_error, (val *) 0);
diff --git a/stream.h b/stream.h
index 8dbc0dd8..a65954ba 100644
--- a/stream.h
+++ b/stream.h
@@ -42,9 +42,13 @@ val get_byte(val);
val vformat(val stream, val string, va_list);
val vformat_to_string(val string, va_list);
val format(val stream, val string, ...);
+val formatv(val stream, val string, val args);
val put_string(val stream, val string);
val put_line(val stream, val string);
val put_char(val stream, val ch);
val flush_stream(val stream);
+val open_directory(val path);
+val open_file(val path, val mode_str);
+val open_pipe(val path, val mode_str);
void stream_init(void);
diff --git a/txr.vim b/txr.vim
index 63875c5c..3ef872f4 100644
--- a/txr.vim
+++ b/txr.vim
@@ -8,7 +8,7 @@
" put this file there.
" 2. In your .vimrc, add this command to associate *.txr files
" with the txr filetype.
-" :au BufRead,BufNewFile *.txr set filetype=txr
+" :au BufRead,BufNewFile *.txr set filetype=txr | set lisp
"
" If you want syntax highlighting to be on automatically (for any language)
" you need to add ":syntax on" in your .vimrc also. But you knew that already!
@@ -16,6 +16,8 @@
syn case match
syn spell toplevel
+setlocal iskeyword=a-z,+,-,*,<,>,=
+
syn keyword txr_keyword contained skip trailer freeform block accept fail
syn keyword txr_keyword contained next some all none and or
syn keyword txr_keyword contained maybe cases choose gather collect coll until last end
@@ -24,7 +26,37 @@ syn keyword txr_keyword contained repeat rep first last single empty
syn keyword txr_keyword contained define try catch finally throw
syn keyword txr_keyword contained defex throw deffilter filter eof eol
-syn match txr_at "@[ \t]*@"
+syn keyword txl_keyword contained let lambda call cond if and or defvar defun
+syn keyword txl_keyword contained inc dec push pop gethash list append apply
+syn keyword txl_keyword contained cons list atom null consp listp proper-listp
+syn keyword txl_keyword contained length mapcar mappend apply
+syn keyword txl_keyword contained + - * trunc mod numberp > < >= <= max min
+syn keyword txl_keyword contained int-str
+
+syn keyword txl_keyword contained search-regex match-regex
+
+syn keyword txl_keyword contained make-hash gethash sethash pushhash remhash
+syn keyword txl_keyword contained hash-count get-hash-userdata
+syn keyword txl_keyword contained set-hash-userdata
+
+syn keyword txl_keyword contained eval
+
+syn keyword txl_keyword contained *stdout* *stdin* *stderr*
+syn keyword txl_keyword contained format print pprint
+syn keyword txl_keyword contained make-string-input-stream
+syn keyword txl_keyword contained make-string-byte-input-stream
+syn keyword txl_keyword contained make-string-output-stream
+syn keyword txl_keyword contained get-string-from-stream
+syn keyword txl_keyword contained make-strlist-output-stream
+syn keyword txl_keyword contained get-list-from-stream
+syn keyword txl_keyword contained close-stream
+syn keyword txl_keyword contained get-line get-char get-byte
+syn keyword txl_keyword contained put-string put-line put-char
+syn keyword txl_keyword contained flush-stream open-directory
+syn keyword txl_keyword contained open-file open-pipe
+
+set lispwords=let open-file
+
syn match txr_comment "@[ \t]*#.*"
syn match txr_contin "@[ \t]*\\$"
syn match txr_hashbang "^#!.*"
@@ -42,9 +74,9 @@ syn region txr_bracevar matchgroup=Delimiter start="@[ \t]*[*]\?{" matchgroup=De
syn region txr_directive matchgroup=Delimiter start="@[ \t]*(" matchgroup=Delimiter end=")" contains=txr_keyword,txr_string,txr_list,txr_meta,txr_quasilit,txr_num,txr_ident,txr_regex,txr_string,txr_variable,txr_chr
-syn region txr_list contained matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=txr_string,txr_regex,txr_num,txr_ident,txr_variable,txr_meta,txr_list,txr_quasilit,txr_chr
+syn region txr_list contained matchgroup=Delimiter start="(" matchgroup=Delimiter end=")" contains=txl_keyword,txr_string,txr_regex,txr_num,txr_ident,txr_variable,txr_meta,txr_list,txr_quasilit,txr_chr
-syn region txr_meta contained matchgroup=Delimiter start="@[ \t]*(" matchgroup=Delimiter end=")" contains=txr_string,txr_regex,txr_num,txr_ident,txr_variable,txr_quasilit,txr_chr
+syn region txr_meta contained matchgroup=Delimiter start="@[ \t]*(" matchgroup=Delimiter end=")" contains=txl_keyword,txr_string,txr_list,txr_regex,txr_num,txr_ident,txr_variable,txr_quasilit,txr_chrb
syn region txr_string contained oneline start=+"+ skip=+\\\\\|\\"+ end=+"+
syn region txr_quasilit contained oneline start=+`+ skip=+\\\\\|\\`+ end=+`+ contains=txr_directive,txr_variable,txr_bracevar
@@ -56,6 +88,7 @@ hi def link txr_hashbang Comment
hi def link txr_contin Comment
hi def link txr_char String
hi def link txr_keyword Keyword
+hi def link txl_keyword Keyword
hi def link txr_string String
hi def link txr_chr String
hi def link txr_quasilit String
@@ -65,3 +98,5 @@ hi def link txr_variable Identifier
hi def link txr_bracevar Identifier
hi def link txr_ident Identifier
hi def link txr_num Number
+
+let b:current_syntax = "lisp"