summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--eval.c15
-rw-r--r--lib.c45
-rw-r--r--lib.h6
-rw-r--r--match.c16
-rw-r--r--parser.l4
-rw-r--r--parser.y22
-rw-r--r--stream.c2
-rw-r--r--txr.131
9 files changed, 152 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 578830ef..78d206ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,38 @@
2011-12-06 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (op_unwind_protect): Fixed uninitialized variable
+ warning.
+ (eval_init): New functions registered: typeof and vector functions,
+ as well as length_list.
+
+ * lib.c (length): Function renamed to length_list, because it is
+ list specific.
+ (length_vec, size_vec, vector_list): New functions.
+ (length): New function, generic over lists, vectors and strings.
+
+ * lib.h (length_list, length_vec, size_vec, vector_list): Declared.
+
+ * match.c (h_var, h_fun, robust_length, v_deffilter, v_fun): Use
+ length_list instead of length.
+
+ * parser.l: Introduced # token.
+
+ * parser.y (vector): New nonterminal.
+ (expr): vector is a kind of expr.
+ (chrlist): Bugfix: single-character syntax was not working;
+ for instance #\x to denote the charcter x.
+ (lit_char_helper): Use length_list instead of length.
+
+ * stream.c (string_in_get_line): Bugfix: this was using
+ the wrong length function: length was being applied to a string.
+ The genericity of length makes that correct now, but changing
+ to length_str anyway.
+
+ * txr.1: Blank sections created for functions. Vector syntax
+ documented.
+
+2011-12-06 Kaz Kylheku <kaz@kylheku.com>
+
* configure: Forgot to treat octal number in the processing
of conftest.syms. Removed useless eval.
diff --git a/eval.c b/eval.c
index 85176f7f..f3abb911 100644
--- a/eval.c
+++ b/eval.c
@@ -630,7 +630,7 @@ static val op_unwind_protect(val form, val env)
{
val prot_form = second(form);
val cleanup_forms = rest(rest(form));
- val result;
+ val result = nil;
uw_catch_begin(nil, exsym, exvals);
@@ -1061,13 +1061,14 @@ void eval_init(void)
reg_fun(append_s, func_n0v(appendv));
reg_fun(list_s, func_n0v(identity));
reg_fun(intern(lit("identity"), user_package), identity_f);
+ reg_fun(intern(lit("typeof"), user_package), func_n1(typeof));
reg_fun(intern(lit("atom"), user_package), func_n1(atom));
reg_fun(intern(lit("null"), user_package), func_n1(nullp));
reg_fun(intern(lit("consp"), user_package), func_n1(consp));
reg_fun(intern(lit("listp"), user_package), func_n1(listp));
reg_fun(intern(lit("proper-listp"), user_package), func_n1(proper_listp));
- reg_fun(intern(lit("length"), user_package), func_n1(length));
+ reg_fun(intern(lit("length-list"), user_package), func_n1(length_list));
reg_fun(intern(lit("mapcar"), user_package), func_n1v(mapcarv));
reg_fun(intern(lit("mappend"), user_package), func_n1v(mappendv));
@@ -1185,6 +1186,16 @@ void eval_init(void)
reg_fun(intern(lit("compl-span-str"), user_package), func_n2(compl_span_str));
reg_fun(intern(lit("break-str"), user_package), func_n2(break_str));
+ reg_fun(intern(lit("vector"), user_package), func_n1(vector));
+ reg_fun(intern(lit("vec-get-fill"), user_package), func_n1(vec_get_fill));
+ reg_fun(intern(lit("vec-set-fill"), user_package), func_n2(vec_set_fill));
+ reg_fun(intern(lit("vecref"), user_package), func_n2(vecref));
+ reg_fun(intern(lit("vec-push"), user_package), func_n2(vec_push));
+ reg_fun(intern(lit("length-vec"), user_package), func_n1(length_vec));
+ reg_fun(intern(lit("size-vec"), user_package), func_n1(size_vec));
+ reg_fun(intern(lit("vector-list"), user_package), func_n1(vector_list));
+ reg_fun(intern(lit("length"), user_package), func_n1(length));
+
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 d20d7b20..672efa4a 100644
--- a/lib.c
+++ b/lib.c
@@ -719,7 +719,7 @@ val proper_listp(val obj)
return (obj == nil) ? t : nil;
}
-val length(val list)
+val length_list(val list)
{
cnum len = 0;
while (consp(list)) {
@@ -2310,6 +2310,31 @@ val vec_push(val vec, val item)
return fill;
}
+val length_vec(val vec)
+{
+ type_check(vec, VEC);
+ return vec->v.vec[vec_fill];
+}
+
+val size_vec(val vec)
+{
+ type_check(vec, VEC);
+ return vec->v.vec[vec_alloc];
+}
+
+val vector_list(val list)
+{
+ val vec = vector(num(2));
+
+ if (!listp(list))
+ uw_throwf(error_s, lit("vector_list: list expected, not ~s"), list, nao);
+
+ for (; consp(list); list = cdr(list))
+ vec_push(vec, car(list));
+
+ return vec;
+}
+
static val lazy_stream_func(val env, val lcons)
{
val stream = car(env);
@@ -2854,6 +2879,24 @@ val set_diff(val list1, val list2, val testfun, val keyfun)
return out;
}
+val length(val seq)
+{
+ if (seq == nil)
+ return num(0);
+ else switch (type(seq)) {
+ case CONS:
+ case LCONS:
+ return length_list(seq);
+ case LIT:
+ case STR:
+ return length_str(seq);
+ case VEC:
+ return length_vec(seq);
+ default:
+ type_mismatch(lit("~s is not a sequence"), cons, nao);
+ }
+}
+
val env(void)
{
if (env_list) {
diff --git a/lib.h b/lib.h
index 28bf0579..414e7726 100644
--- a/lib.h
+++ b/lib.h
@@ -339,7 +339,7 @@ val nullp(val obj);
val atom(val obj);
val listp(val obj);
val proper_listp(val obj);
-val length(val list);
+val length_list(val list);
val getplist(val list, val key);
val getplist_f(val list, val key, val *found);
val proper_plist_to_alist(val list);
@@ -456,6 +456,9 @@ val vec_set_fill(val vec, val fill);
val vecref(val vec, val ind);
val *vecref_l(val vec, val ind);
val vec_push(val vec, val item);
+val length_vec(val vec);
+val size_vec(val vec);
+val vector_list(val list);
val lazy_stream_cons(val stream);
val lazy_str(val list, val term, val limit);
val lazy_str_force_upto(val lstr, val index);
@@ -490,6 +493,7 @@ val merge(val list1, val list2, val lessfun, val keyfun);
val sort(val list, val lessfun, val keyfun);
val find(val list, val key, val testfun, val keyfun);
val set_diff(val list1, val list2, val testfun, val keyfun);
+val length(val seq);
val env(void);
val obj_print(val obj, val stream);
diff --git a/match.c b/match.c
index 1777dd6d..3071844b 100644
--- a/match.c
+++ b/match.c
@@ -447,7 +447,7 @@ static val h_var(match_line_ctx c, match_line_ctx *cout)
val modifier = first(modifiers);
val pair = assoc(c.bindings, sym); /* var exists already? */
- if (gt(length(modifiers), one)) {
+ if (gt(length_list(modifiers), one)) {
sem_error(elem, lit("multiple modifiers on variable ~s"),
sym, nao);
}
@@ -556,7 +556,7 @@ static val h_var(match_line_ctx c, match_line_ctx *cout)
val next_modifier = first(fourth(pat));
val pair = assoc(c.bindings, second_sym); /* var exists already? */
- if (gt(length(next_modifiers), one)) {
+ if (gt(length_list(next_modifiers), one)) {
sem_error(elem, lit("multiple modifiers on variable ~s"),
second_sym, nao);
}
@@ -994,9 +994,9 @@ static val h_fun(match_line_ctx c, match_line_ctx *cout)
val piter, aiter;
val bindings_cp = copy_list(c.bindings);
- if (!equal(length(args), length(params)))
+ if (!equal(length(args), length_list(params)))
sem_error(elem, lit("function ~a takes ~a argument(s)"),
- sym, length(params), nao);
+ sym, length_list(params), nao);
for (piter = params, aiter = args; piter;
piter = cdr(piter), aiter = cdr(aiter))
@@ -1462,7 +1462,7 @@ static val robust_length(val obj)
return zero;
if (atom(obj))
return negone;
- return length(obj);
+ return length_list(obj);
}
static val bind_car(val bind_cons)
@@ -2948,7 +2948,7 @@ static val v_deffilter(match_files_ctx *c)
val table_evaled = txeval(specline, table, c->bindings);
if (!all_satisfy(table_evaled, andf(func_n1(listp),
- chain(func_n1(length),
+ chain(func_n1(length_list),
curry_12_1(func_n2(ge), two), nao),
chain(func_n1(rest),
curry_123_1(func_n3(all_satisfy),
@@ -3025,9 +3025,9 @@ static val v_fun(match_files_ctx *c)
debug_check(specline, c->bindings, if2(consp(c->data), car(c->data)), c->data_lineno, nil);
- if (!equal(length(args), length(params)))
+ if (!equal(length_list(args), length_list(params)))
sem_error(specline, lit("function ~a takes ~a argument(s)"),
- sym, length(params), nao);
+ sym, length_list(params), nao);
for (piter = params, aiter = args; piter;
piter = cdr(piter), aiter = cdr(aiter))
diff --git a/parser.l b/parser.l
index cee0d834..e22c6d74 100644
--- a/parser.l
+++ b/parser.l
@@ -403,6 +403,10 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return '`';
}
+<NESTED># {
+ return '#';
+ }
+
<SPECIAL>@ {
yy_pop_state();
yylval.lexeme = chk_strdup(L"@");
diff --git a/parser.y b/parser.y
index 82fd9101..5b0e857d 100644
--- a/parser.y
+++ b/parser.y
@@ -82,7 +82,7 @@ static val parsed_spec;
%type <val> clause_parts additional_parts
%type <val> output_clause define_clause try_clause catch_clauses_opt
%type <val> line elems_opt elems clause_parts_h additional_parts_h
-%type <val> text texts elem var var_op meta_expr
+%type <val> text texts elem var var_op meta_expr vector
%type <val> list exprs exprs_opt expr out_clauses out_clauses_opt out_clause
%type <val> repeat_clause repeat_parts_opt o_line
%type <val> o_elems_opt o_elems_opt2 o_elems o_elem o_var rep_elem rep_parts_opt
@@ -605,6 +605,9 @@ o_var : IDENT { $$ = list(var_s, intern(string_own($1), nil),
var_op : '*' { $$ = list(t, nao); }
;
+vector : '#' list { $$ = rlcp(vector_list($2), $2); }
+ ;
+
list : '(' exprs ')' { $$ = rl($2, num($1)); }
| '(' ')' { $$ = nil; }
| ',' expr { val expr = $2;
@@ -645,6 +648,7 @@ expr : IDENT { $$ = rl(intern(string_own($1), nil),
rl($$, num(lineno)); }
| NUMBER { $$ = num($1); }
| list { $$ = $1; }
+ | vector { $$ = $1; }
| meta_expr { $$ = $1; }
| regex { $$ = cons(regex_compile(rest($1)),
rest($1));
@@ -736,15 +740,17 @@ strlit : '"' '"' { $$ = null_string; }
yybadtoken(yychar, lit("string literal")); }
;
-chrlit : HASH_BACKSLASH IDENT { wchar_t ch = char_from_name($2);
+chrlit : HASH_BACKSLASH IDENT { wchar_t ch;
val str = string_own($2);
+ if ($2[1] == 0)
+ { ch = $2[0]; }
+ else
+ { ch = char_from_name($2);
+ if (ch == L'!')
+ { yyerrorf(lit("unknown character name: ~a"),
+ str, nao); }}
end_of_char();
- if (ch == L'!')
- { yyerrorf(lit("unknown character name: ~a"),
- str, nao); }
$$ = chr(ch); }
- | HASH_BACKSLASH LITCHAR { $$ = chr($2);
- end_of_char(); }
| HASH_BACKSLASH error { $$ = nil;
yybadtoken(yychar,
lit("character literal")); }
@@ -870,7 +876,7 @@ static val lit_char_helper(val litchars)
val ret = nil;
if (litchars) {
- val len = length(litchars), iter, ix;
+ val len = length_list(litchars), iter, ix;
ret = mkustring(len);
for (iter = litchars, ix = zero;
iter;
diff --git a/stream.c b/stream.c
index e337e523..be638608 100644
--- a/stream.c
+++ b/stream.c
@@ -313,7 +313,7 @@ static val string_in_get_line(val stream)
val pos = cdr(pair);
/* TODO: broken, should only scan to newline */
- if (lt(pos, length(string))) {
+ if (lt(pos, length_str(string))) {
val result = sub_str(string, pos, nil);
*cdr_l(pair) = length_str(string);
return result;
diff --git a/txr.1 b/txr.1
index 9f9ff8c9..43d49c42 100644
--- a/txr.1
+++ b/txr.1
@@ -4269,6 +4269,13 @@ and not a quasiquote.
.PP
+.SS Vectors
+
+.IP #(...)
+
+A hash token followed by a list denotes a vector. For example #(1 2 a)
+is a three-element vector containing the numbers 1 and 2, and the symbol a.
+
.SS Nested Quotes
Quotes can be nested. What if it is necessary to unquote something in the
@@ -4671,6 +4678,10 @@ Programs can define named functions with the defun operator
The following are Lisp functions and variables built-in to TXR.
+.SS Function identity
+
+.SS Function typeof
+
.SS Function cons
.SS Functions car and first
@@ -4695,7 +4706,7 @@ The following are Lisp functions and variables built-in to TXR.
.SS Functions listp and proper-listp
-.SS Function length
+.SS Function length-list
.SS Function mapcar
@@ -4841,6 +4852,24 @@ The following are Lisp functions and variables built-in to TXR.
.SS Function break-str
+.SS Function vector
+
+.SS Function vec-get-fill
+
+.SS Function vec-set-fill
+
+.SS Function vecref
+
+.SS Function vec-push
+
+.SS Function length-vec
+
+.SS Function size-vec
+
+.SS Function vector-list
+
+.SS Function length
+
.SH APPENDIX A: NOTES ON EXOTIC REGULAR EXPRESSIONS