mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Merge remote-tracking branch 'origin/stable-2.0'
Conflicts: libguile/read.c test-suite/tests/tree-il.test
This commit is contained in:
commit
a41bed83ab
10 changed files with 426 additions and 205 deletions
|
@ -212,18 +212,30 @@ result of the @code{cond}-expression.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn syntax case key clause1 clause2 @dots{}
|
@deffn syntax case key clause1 clause2 @dots{}
|
||||||
@var{key} may be any expression, the @var{clause}s must have the form
|
@var{key} may be any expression, and the @var{clause}s must have the form
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{})
|
((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{})
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
((@var{datum1} @dots{}) => @var{expression})
|
||||||
|
@end lisp
|
||||||
|
|
||||||
and the last @var{clause} may have the form
|
and the last @var{clause} may have the form
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(else @var{expr1} @var{expr2} @dots{})
|
(else @var{expr1} @var{expr2} @dots{})
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(else => @var{expression})
|
||||||
|
@end lisp
|
||||||
|
|
||||||
All @var{datum}s must be distinct. First, @var{key} is evaluated. The
|
All @var{datum}s must be distinct. First, @var{key} is evaluated. The
|
||||||
result of this evaluation is compared against all @var{datum} values using
|
result of this evaluation is compared against all @var{datum} values using
|
||||||
@code{eqv?}. When this comparison succeeds, the expression(s) following
|
@code{eqv?}. When this comparison succeeds, the expression(s) following
|
||||||
|
@ -234,6 +246,11 @@ If the @var{key} matches no @var{datum} and there is an
|
||||||
@code{else}-clause, the expressions following the @code{else} are
|
@code{else}-clause, the expressions following the @code{else} are
|
||||||
evaluated. If there is no such clause, the result of the expression is
|
evaluated. If there is no such clause, the result of the expression is
|
||||||
unspecified.
|
unspecified.
|
||||||
|
|
||||||
|
For the @code{=>} clause types, @var{expression} is evaluated and the
|
||||||
|
resulting procedure is applied to the value of @var{key}. The result of
|
||||||
|
this procedure application is then the result of the
|
||||||
|
@code{case}-expression.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -238,11 +238,11 @@ that, if an error occurs when evaluating the transformed expression,
|
||||||
Guile's debugger can point back to the file and location where the
|
Guile's debugger can point back to the file and location where the
|
||||||
expression originated.
|
expression originated.
|
||||||
|
|
||||||
The way that source properties are stored means that Guile can only
|
The way that source properties are stored means that Guile cannot
|
||||||
associate source properties with parenthesized expressions, and not, for
|
associate source properties with individual numbers, symbols,
|
||||||
example, with individual symbols, numbers or strings. The difference
|
characters, booleans, or keywords. This can be seen by typing
|
||||||
can be seen by typing @code{(xxx)} and @code{xxx} at the Guile prompt
|
@code{(xxx)} and @code{xxx} at the Guile prompt (where the variable
|
||||||
(where the variable @code{xxx} has not been defined):
|
@code{xxx} has not been defined):
|
||||||
|
|
||||||
@example
|
@example
|
||||||
scheme@@(guile-user)> (xxx)
|
scheme@@(guile-user)> (xxx)
|
||||||
|
@ -288,8 +288,8 @@ Return the property specified by @var{key} from @var{obj}'s source
|
||||||
properties.
|
properties.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
If the @code{positions} reader option is enabled, each parenthesized
|
If the @code{positions} reader option is enabled, supported expressions
|
||||||
expression will have values set for the @code{filename}, @code{line} and
|
will have values set for the @code{filename}, @code{line} and
|
||||||
@code{column} properties.
|
@code{column} properties.
|
||||||
|
|
||||||
Source properties are also associated with syntax objects. Procedural
|
Source properties are also associated with syntax objects. Procedural
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
|
/* Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -1971,33 +1971,15 @@ SCM_DEFINE (scm_string_to_utf8, "string->utf8",
|
||||||
#define FUNC_NAME s_scm_string_to_utf8
|
#define FUNC_NAME s_scm_string_to_utf8
|
||||||
{
|
{
|
||||||
SCM utf;
|
SCM utf;
|
||||||
uint8_t *c_utf;
|
scm_t_uint8 *c_utf;
|
||||||
size_t c_strlen, c_utf_len = 0;
|
size_t c_utf_len = 0;
|
||||||
|
|
||||||
SCM_VALIDATE_STRING (1, str);
|
SCM_VALIDATE_STRING (1, str);
|
||||||
|
|
||||||
c_strlen = scm_i_string_length (str);
|
c_utf = (scm_t_uint8 *) scm_to_utf8_stringn (str, &c_utf_len);
|
||||||
if (scm_i_is_narrow_string (str))
|
utf = make_bytevector (c_utf_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
||||||
c_utf = u8_conv_from_encoding ("ISO-8859-1", iconveh_question_mark,
|
memcpy (SCM_BYTEVECTOR_CONTENTS (utf), c_utf, c_utf_len);
|
||||||
scm_i_string_chars (str), c_strlen,
|
free (c_utf);
|
||||||
NULL, NULL, &c_utf_len);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const scm_t_wchar *wbuf = scm_i_string_wide_chars (str);
|
|
||||||
c_utf = u32_to_u8 ((const uint32_t *) wbuf, c_strlen, NULL, &c_utf_len);
|
|
||||||
}
|
|
||||||
if (SCM_UNLIKELY (c_utf == NULL))
|
|
||||||
scm_syserror (FUNC_NAME);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scm_dynwind_begin (0);
|
|
||||||
scm_dynwind_free (c_utf);
|
|
||||||
|
|
||||||
utf = make_bytevector (c_utf_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
|
||||||
memcpy (SCM_BYTEVECTOR_CONTENTS (utf), c_utf, c_utf_len);
|
|
||||||
|
|
||||||
scm_dynwind_end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (utf);
|
return (utf);
|
||||||
}
|
}
|
||||||
|
@ -2014,6 +1996,14 @@ SCM_DEFINE (scm_string_to_utf16, "string->utf16",
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static void
|
||||||
|
swap_u32 (scm_t_wchar *vals, size_t len)
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
for (n = 0; n < len; n++)
|
||||||
|
vals[n] = bswap_32 (vals[n]);
|
||||||
|
}
|
||||||
|
|
||||||
SCM_DEFINE (scm_string_to_utf32, "string->utf32",
|
SCM_DEFINE (scm_string_to_utf32, "string->utf32",
|
||||||
1, 1, 0,
|
1, 1, 0,
|
||||||
(SCM str, SCM endianness),
|
(SCM str, SCM endianness),
|
||||||
|
@ -2021,7 +2011,21 @@ SCM_DEFINE (scm_string_to_utf32, "string->utf32",
|
||||||
"encoding of @var{str}.")
|
"encoding of @var{str}.")
|
||||||
#define FUNC_NAME s_scm_string_to_utf32
|
#define FUNC_NAME s_scm_string_to_utf32
|
||||||
{
|
{
|
||||||
STRING_TO_UTF (32);
|
SCM bv;
|
||||||
|
scm_t_wchar *wchars;
|
||||||
|
size_t wchar_len, bytes_len;
|
||||||
|
|
||||||
|
wchars = scm_to_utf32_stringn (str, &wchar_len);
|
||||||
|
bytes_len = wchar_len * sizeof (scm_t_wchar);
|
||||||
|
if (!scm_is_eq (SCM_UNBNDP (endianness) ? scm_endianness_big : endianness,
|
||||||
|
scm_i_native_endianness))
|
||||||
|
swap_u32 (wchars, wchar_len);
|
||||||
|
|
||||||
|
bv = make_bytevector (bytes_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
||||||
|
memcpy (SCM_BYTEVECTOR_CONTENTS (bv), wchars, bytes_len);
|
||||||
|
free (wchars);
|
||||||
|
|
||||||
|
return bv;
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
121
libguile/read.c
121
libguile/read.c
|
@ -1,5 +1,5 @@
|
||||||
/* Copyright (C) 1995,1996,1997,1999,2000,2001,2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
/* Copyright (C) 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2006,
|
||||||
* Foundation, Inc.
|
* 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -142,13 +142,13 @@ SCM_DEFINE (scm_read_options, "read-options-interface", 0, 1, 0,
|
||||||
characters to procedures. */
|
characters to procedures. */
|
||||||
static SCM *scm_i_read_hash_procedures;
|
static SCM *scm_i_read_hash_procedures;
|
||||||
|
|
||||||
static inline SCM
|
static SCM
|
||||||
scm_i_read_hash_procedures_ref (void)
|
scm_i_read_hash_procedures_ref (void)
|
||||||
{
|
{
|
||||||
return scm_fluid_ref (*scm_i_read_hash_procedures);
|
return scm_fluid_ref (*scm_i_read_hash_procedures);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static void
|
||||||
scm_i_read_hash_procedures_set_x (SCM value)
|
scm_i_read_hash_procedures_set_x (SCM value)
|
||||||
{
|
{
|
||||||
scm_fluid_set_x (*scm_i_read_hash_procedures, value);
|
scm_fluid_set_x (*scm_i_read_hash_procedures, value);
|
||||||
|
@ -197,7 +197,7 @@ scm_i_read_hash_procedures_set_x (SCM value)
|
||||||
|| ((_chr) == 'd') || ((_chr) == 'l'))
|
|| ((_chr) == 'd') || ((_chr) == 'l'))
|
||||||
|
|
||||||
/* Read an SCSH block comment. */
|
/* Read an SCSH block comment. */
|
||||||
static inline SCM scm_read_scsh_block_comment (scm_t_wchar, SCM);
|
static SCM scm_read_scsh_block_comment (scm_t_wchar, SCM);
|
||||||
static SCM scm_read_r6rs_block_comment (scm_t_wchar, SCM);
|
static SCM scm_read_r6rs_block_comment (scm_t_wchar, SCM);
|
||||||
static SCM scm_read_commented_expression (scm_t_wchar, SCM);
|
static SCM scm_read_commented_expression (scm_t_wchar, SCM);
|
||||||
static SCM scm_read_shebang (scm_t_wchar, SCM);
|
static SCM scm_read_shebang (scm_t_wchar, SCM);
|
||||||
|
@ -207,7 +207,7 @@ static SCM scm_get_hash_procedure (int);
|
||||||
result in the pre-allocated buffer BUF. Return zero if the whole token has
|
result in the pre-allocated buffer BUF. Return zero if the whole token has
|
||||||
fewer than BUF_SIZE bytes, non-zero otherwise. READ will be set the number of
|
fewer than BUF_SIZE bytes, non-zero otherwise. READ will be set the number of
|
||||||
bytes actually read. */
|
bytes actually read. */
|
||||||
static inline int
|
static int
|
||||||
read_token (SCM port, char *buf, const size_t buf_size, size_t *read)
|
read_token (SCM port, char *buf, const size_t buf_size, size_t *read)
|
||||||
{
|
{
|
||||||
*read = 0;
|
*read = 0;
|
||||||
|
@ -286,7 +286,7 @@ read_complete_token (SCM port, char *buffer, const size_t buffer_size,
|
||||||
static int
|
static int
|
||||||
flush_ws (SCM port, const char *eoferr)
|
flush_ws (SCM port, const char *eoferr)
|
||||||
{
|
{
|
||||||
register scm_t_wchar c;
|
scm_t_wchar c;
|
||||||
while (1)
|
while (1)
|
||||||
switch (c = scm_getc_unlocked (port))
|
switch (c = scm_getc_unlocked (port))
|
||||||
{
|
{
|
||||||
|
@ -356,9 +356,17 @@ flush_ws (SCM port, const char *eoferr)
|
||||||
/* Token readers. */
|
/* Token readers. */
|
||||||
|
|
||||||
static SCM scm_read_expression (SCM port);
|
static SCM scm_read_expression (SCM port);
|
||||||
static SCM scm_read_sharp (int chr, SCM port);
|
static SCM scm_read_sharp (int chr, SCM port, long line, int column);
|
||||||
|
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
maybe_annotate_source (SCM x, SCM port, long line, int column)
|
||||||
|
{
|
||||||
|
if (SCM_RECORD_POSITIONS_P)
|
||||||
|
scm_i_set_source_properties_x (x, line, column, SCM_FILENAME (port));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
scm_read_sexp (scm_t_wchar chr, SCM port)
|
scm_read_sexp (scm_t_wchar chr, SCM port)
|
||||||
#define FUNC_NAME "scm_i_lreadparen"
|
#define FUNC_NAME "scm_i_lreadparen"
|
||||||
|
@ -423,10 +431,7 @@ scm_read_sexp (scm_t_wchar chr, SCM port)
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (SCM_RECORD_POSITIONS_P)
|
return maybe_annotate_source (ans, port, line, column);
|
||||||
scm_i_set_source_properties_x (ans, line, column, SCM_FILENAME (port));
|
|
||||||
|
|
||||||
return ans;
|
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
@ -492,6 +497,10 @@ scm_read_string (int chr, SCM port)
|
||||||
unsigned c_str_len = 0;
|
unsigned c_str_len = 0;
|
||||||
scm_t_wchar c;
|
scm_t_wchar c;
|
||||||
|
|
||||||
|
/* Need to capture line and column numbers here. */
|
||||||
|
long line = SCM_LINUM (port);
|
||||||
|
int column = SCM_COL (port) - 1;
|
||||||
|
|
||||||
str = scm_i_make_string (READER_STRING_BUFFER_SIZE, NULL, 0);
|
str = scm_i_make_string (READER_STRING_BUFFER_SIZE, NULL, 0);
|
||||||
while ('"' != (c = scm_getc_unlocked (port)))
|
while ('"' != (c = scm_getc_unlocked (port)))
|
||||||
{
|
{
|
||||||
|
@ -575,13 +584,8 @@ scm_read_string (int chr, SCM port)
|
||||||
scm_i_string_set_x (str, c_str_len++, c);
|
scm_i_string_set_x (str, c_str_len++, c);
|
||||||
scm_i_string_stop_writing ();
|
scm_i_string_stop_writing ();
|
||||||
}
|
}
|
||||||
|
return maybe_annotate_source (scm_i_substring_copy (str, 0, c_str_len),
|
||||||
if (c_str_len > 0)
|
port, line, column);
|
||||||
{
|
|
||||||
return scm_i_substring_copy (str, 0, c_str_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return scm_nullstr;
|
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
@ -780,10 +784,7 @@ scm_read_quote (int chr, SCM port)
|
||||||
}
|
}
|
||||||
|
|
||||||
p = scm_cons2 (p, scm_read_expression (port), SCM_EOL);
|
p = scm_cons2 (p, scm_read_expression (port), SCM_EOL);
|
||||||
if (SCM_RECORD_POSITIONS_P)
|
return maybe_annotate_source (p, port, line, column);
|
||||||
scm_i_set_source_properties_x (p, line, column, SCM_FILENAME (port));
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM_SYMBOL (sym_syntax, "syntax");
|
SCM_SYMBOL (sym_syntax, "syntax");
|
||||||
|
@ -830,13 +831,10 @@ scm_read_syntax (int chr, SCM port)
|
||||||
}
|
}
|
||||||
|
|
||||||
p = scm_cons2 (p, scm_read_expression (port), SCM_EOL);
|
p = scm_cons2 (p, scm_read_expression (port), SCM_EOL);
|
||||||
if (SCM_RECORD_POSITIONS_P)
|
return maybe_annotate_source (p, port, line, column);
|
||||||
scm_i_set_source_properties_x (p, line, column, SCM_FILENAME (port));
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SCM
|
static SCM
|
||||||
scm_read_nil (int chr, SCM port)
|
scm_read_nil (int chr, SCM port)
|
||||||
{
|
{
|
||||||
SCM id = scm_read_mixed_case_symbol (chr, port);
|
SCM id = scm_read_mixed_case_symbol (chr, port);
|
||||||
|
@ -849,7 +847,7 @@ scm_read_nil (int chr, SCM port)
|
||||||
return SCM_ELISP_NIL;
|
return SCM_ELISP_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SCM
|
static SCM
|
||||||
scm_read_semicolon_comment (int chr, SCM port)
|
scm_read_semicolon_comment (int chr, SCM port)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
@ -990,7 +988,7 @@ scm_read_character (scm_t_wchar chr, SCM port)
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
static inline SCM
|
static SCM
|
||||||
scm_read_keyword (int chr, SCM port)
|
scm_read_keyword (int chr, SCM port)
|
||||||
{
|
{
|
||||||
SCM symbol;
|
SCM symbol;
|
||||||
|
@ -1009,24 +1007,35 @@ scm_read_keyword (int chr, SCM port)
|
||||||
return (scm_symbol_to_keyword (symbol));
|
return (scm_symbol_to_keyword (symbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SCM
|
static SCM
|
||||||
scm_read_vector (int chr, SCM port)
|
scm_read_vector (int chr, SCM port, long line, int column)
|
||||||
{
|
{
|
||||||
/* Note: We call `scm_read_sexp ()' rather than READER here in order to
|
/* Note: We call `scm_read_sexp ()' rather than READER here in order to
|
||||||
guarantee that it's going to do what we want. After all, this is an
|
guarantee that it's going to do what we want. After all, this is an
|
||||||
implementation detail of `scm_read_vector ()', not a desirable
|
implementation detail of `scm_read_vector ()', not a desirable
|
||||||
property. */
|
property. */
|
||||||
return (scm_vector (scm_read_sexp (chr, port)));
|
return maybe_annotate_source (scm_vector (scm_read_sexp (chr, port)),
|
||||||
}
|
port, line, column);
|
||||||
|
|
||||||
static inline SCM
|
|
||||||
scm_read_srfi4_vector (int chr, SCM port)
|
|
||||||
{
|
|
||||||
return scm_i_read_array (port, chr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
scm_read_bytevector (scm_t_wchar chr, SCM port)
|
scm_read_array (int chr, SCM port, long line, int column)
|
||||||
|
{
|
||||||
|
SCM result = scm_i_read_array (port, chr);
|
||||||
|
if (scm_is_false (result))
|
||||||
|
return result;
|
||||||
|
else
|
||||||
|
return maybe_annotate_source (result, port, line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
scm_read_srfi4_vector (int chr, SCM port, long line, int column)
|
||||||
|
{
|
||||||
|
return scm_read_array (chr, port, line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
scm_read_bytevector (scm_t_wchar chr, SCM port, long line, int column)
|
||||||
{
|
{
|
||||||
chr = scm_getc_unlocked (port);
|
chr = scm_getc_unlocked (port);
|
||||||
if (chr != 'u')
|
if (chr != 'u')
|
||||||
|
@ -1040,7 +1049,9 @@ scm_read_bytevector (scm_t_wchar chr, SCM port)
|
||||||
if (chr != '(')
|
if (chr != '(')
|
||||||
goto syntax;
|
goto syntax;
|
||||||
|
|
||||||
return scm_u8_list_to_bytevector (scm_read_sexp (chr, port));
|
return maybe_annotate_source
|
||||||
|
(scm_u8_list_to_bytevector (scm_read_sexp (chr, port)),
|
||||||
|
port, line, column);
|
||||||
|
|
||||||
syntax:
|
syntax:
|
||||||
scm_i_input_error ("read_bytevector", port,
|
scm_i_input_error ("read_bytevector", port,
|
||||||
|
@ -1050,7 +1061,7 @@ scm_read_bytevector (scm_t_wchar chr, SCM port)
|
||||||
}
|
}
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
scm_read_guile_bit_vector (scm_t_wchar chr, SCM port)
|
scm_read_guile_bit_vector (scm_t_wchar chr, SCM port, long line, int column)
|
||||||
{
|
{
|
||||||
/* Read the `#*10101'-style read syntax for bit vectors in Guile. This is
|
/* Read the `#*10101'-style read syntax for bit vectors in Guile. This is
|
||||||
terribly inefficient but who cares? */
|
terribly inefficient but who cares? */
|
||||||
|
@ -1066,10 +1077,12 @@ scm_read_guile_bit_vector (scm_t_wchar chr, SCM port)
|
||||||
if (chr != EOF)
|
if (chr != EOF)
|
||||||
scm_ungetc_unlocked (chr, port);
|
scm_ungetc_unlocked (chr, port);
|
||||||
|
|
||||||
return scm_bitvector (scm_reverse_x (s_bits, SCM_EOL));
|
return maybe_annotate_source
|
||||||
|
(scm_bitvector (scm_reverse_x (s_bits, SCM_EOL)),
|
||||||
|
port, line, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SCM
|
static SCM
|
||||||
scm_read_scsh_block_comment (scm_t_wchar chr, SCM port)
|
scm_read_scsh_block_comment (scm_t_wchar chr, SCM port)
|
||||||
{
|
{
|
||||||
int bang_seen = 0;
|
int bang_seen = 0;
|
||||||
|
@ -1302,7 +1315,7 @@ scm_read_sharp_extension (int chr, SCM port)
|
||||||
/* The reader for the sharp `#' character. It basically dispatches reads
|
/* The reader for the sharp `#' character. It basically dispatches reads
|
||||||
among the above token readers. */
|
among the above token readers. */
|
||||||
static SCM
|
static SCM
|
||||||
scm_read_sharp (scm_t_wchar chr, SCM port)
|
scm_read_sharp (scm_t_wchar chr, SCM port, long line, int column)
|
||||||
#define FUNC_NAME "scm_lreadr"
|
#define FUNC_NAME "scm_lreadr"
|
||||||
{
|
{
|
||||||
SCM result;
|
SCM result;
|
||||||
|
@ -1318,28 +1331,27 @@ scm_read_sharp (scm_t_wchar chr, SCM port)
|
||||||
case '\\':
|
case '\\':
|
||||||
return (scm_read_character (chr, port));
|
return (scm_read_character (chr, port));
|
||||||
case '(':
|
case '(':
|
||||||
return (scm_read_vector (chr, port));
|
return (scm_read_vector (chr, port, line, column));
|
||||||
case 's':
|
case 's':
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'c':
|
case 'c':
|
||||||
/* This one may return either a boolean or an SRFI-4 vector. */
|
/* This one may return either a boolean or an SRFI-4 vector. */
|
||||||
return (scm_read_srfi4_vector (chr, port));
|
return (scm_read_srfi4_vector (chr, port, line, column));
|
||||||
case 'v':
|
case 'v':
|
||||||
return (scm_read_bytevector (chr, port));
|
return (scm_read_bytevector (chr, port, line, column));
|
||||||
case '*':
|
case '*':
|
||||||
return (scm_read_guile_bit_vector (chr, port));
|
return (scm_read_guile_bit_vector (chr, port, line, column));
|
||||||
case 't':
|
case 't':
|
||||||
case 'T':
|
case 'T':
|
||||||
case 'F':
|
case 'F':
|
||||||
/* This one may return either a boolean or an SRFI-4 vector. */
|
|
||||||
return (scm_read_boolean (chr, port));
|
return (scm_read_boolean (chr, port));
|
||||||
case ':':
|
case ':':
|
||||||
return (scm_read_keyword (chr, port));
|
return (scm_read_keyword (chr, port));
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
case '@':
|
case '@':
|
||||||
return (scm_i_read_array (port, chr));
|
return (scm_read_array (chr, port, line, column));
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'e':
|
case 'e':
|
||||||
|
@ -1396,7 +1408,7 @@ scm_read_expression (SCM port)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
register scm_t_wchar chr;
|
scm_t_wchar chr;
|
||||||
|
|
||||||
chr = scm_getc_unlocked (port);
|
chr = scm_getc_unlocked (port);
|
||||||
|
|
||||||
|
@ -1422,8 +1434,9 @@ scm_read_expression (SCM port)
|
||||||
return (scm_read_quote (chr, port));
|
return (scm_read_quote (chr, port));
|
||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
SCM result;
|
long line = SCM_LINUM (port);
|
||||||
result = scm_read_sharp (chr, port);
|
int column = SCM_COL (port) - 1;
|
||||||
|
SCM result = scm_read_sharp (chr, port, line, column);
|
||||||
if (scm_is_eq (result, SCM_UNSPECIFIED))
|
if (scm_is_eq (result, SCM_UNSPECIFIED))
|
||||||
/* We read a comment or some such. */
|
/* We read a comment or some such. */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -372,31 +372,36 @@ scm_i_substring_read_only (SCM str, size_t start, size_t end)
|
||||||
SCM
|
SCM
|
||||||
scm_i_substring_copy (SCM str, size_t start, size_t end)
|
scm_i_substring_copy (SCM str, size_t start, size_t end)
|
||||||
{
|
{
|
||||||
size_t len = end - start;
|
if (start == end)
|
||||||
SCM buf, my_buf, substr;
|
return scm_i_make_string (0, NULL, 0);
|
||||||
size_t str_start;
|
|
||||||
int wide = 0;
|
|
||||||
get_str_buf_start (&str, &buf, &str_start);
|
|
||||||
if (scm_i_is_narrow_string (str))
|
|
||||||
{
|
|
||||||
my_buf = make_stringbuf (len);
|
|
||||||
memcpy (STRINGBUF_CHARS (my_buf),
|
|
||||||
STRINGBUF_CHARS (buf) + str_start + start, len);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_buf = make_wide_stringbuf (len);
|
size_t len = end - start;
|
||||||
u32_cpy ((scm_t_uint32 *) STRINGBUF_WIDE_CHARS (my_buf),
|
SCM buf, my_buf, substr;
|
||||||
(scm_t_uint32 *) (STRINGBUF_WIDE_CHARS (buf) + str_start
|
size_t str_start;
|
||||||
+ start), len);
|
int wide = 0;
|
||||||
wide = 1;
|
get_str_buf_start (&str, &buf, &str_start);
|
||||||
|
if (scm_i_is_narrow_string (str))
|
||||||
|
{
|
||||||
|
my_buf = make_stringbuf (len);
|
||||||
|
memcpy (STRINGBUF_CHARS (my_buf),
|
||||||
|
STRINGBUF_CHARS (buf) + str_start + start, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_buf = make_wide_stringbuf (len);
|
||||||
|
u32_cpy ((scm_t_uint32 *) STRINGBUF_WIDE_CHARS (my_buf),
|
||||||
|
(scm_t_uint32 *) (STRINGBUF_WIDE_CHARS (buf) + str_start
|
||||||
|
+ start), len);
|
||||||
|
wide = 1;
|
||||||
|
}
|
||||||
|
scm_remember_upto_here_1 (buf);
|
||||||
|
substr = scm_double_cell (STRING_TAG, SCM_UNPACK (my_buf),
|
||||||
|
(scm_t_bits) 0, (scm_t_bits) len);
|
||||||
|
if (wide)
|
||||||
|
scm_i_try_narrow_string (substr);
|
||||||
|
return substr;
|
||||||
}
|
}
|
||||||
scm_remember_upto_here_1 (buf);
|
|
||||||
substr = scm_double_cell (STRING_TAG, SCM_UNPACK (my_buf),
|
|
||||||
(scm_t_bits) 0, (scm_t_bits) len);
|
|
||||||
if (wide)
|
|
||||||
scm_i_try_narrow_string (substr);
|
|
||||||
return substr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
|
@ -1918,10 +1923,47 @@ scm_to_utf8_string (SCM str)
|
||||||
return scm_to_utf8_stringn (str, NULL);
|
return scm_to_utf8_stringn (str, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
latin1_u8_strlen (const scm_t_uint8 *str, size_t len)
|
||||||
|
{
|
||||||
|
size_t ret, i;
|
||||||
|
for (i = 0, ret = 0; i < len; i++)
|
||||||
|
ret += (str[i] < 128) ? 1 : 2;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static scm_t_uint8*
|
||||||
|
latin1_to_u8 (const scm_t_uint8 *str, size_t latin_len,
|
||||||
|
scm_t_uint8 *u8_result, size_t *u8_lenp)
|
||||||
|
{
|
||||||
|
size_t i, n;
|
||||||
|
size_t u8_len = latin1_u8_strlen (str, latin_len);
|
||||||
|
|
||||||
|
if (!(u8_result && u8_lenp && *u8_lenp > u8_len))
|
||||||
|
u8_result = scm_malloc (u8_len + 1);
|
||||||
|
if (u8_lenp)
|
||||||
|
*u8_lenp = u8_len;
|
||||||
|
|
||||||
|
for (i = 0, n = 0; i < latin_len; i++)
|
||||||
|
n += u8_uctomb (u8_result + n, str[i], u8_len - n);
|
||||||
|
if (n != u8_len)
|
||||||
|
abort ();
|
||||||
|
u8_result[n] = 0;
|
||||||
|
|
||||||
|
return u8_result;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
scm_to_utf8_stringn (SCM str, size_t *lenp)
|
scm_to_utf8_stringn (SCM str, size_t *lenp)
|
||||||
{
|
{
|
||||||
return scm_to_stringn (str, lenp, "UTF-8", SCM_FAILED_CONVERSION_ERROR);
|
if (scm_i_is_narrow_string (str))
|
||||||
|
return (char *) latin1_to_u8 ((scm_t_uint8 *) scm_i_string_chars (str),
|
||||||
|
scm_i_string_length (str),
|
||||||
|
NULL, lenp);
|
||||||
|
else
|
||||||
|
return (char *) u32_to_u8 ((scm_t_uint32*)scm_i_string_wide_chars (str),
|
||||||
|
scm_i_string_length (str),
|
||||||
|
NULL, lenp);
|
||||||
}
|
}
|
||||||
|
|
||||||
scm_t_wchar *
|
scm_t_wchar *
|
||||||
|
@ -1939,9 +1981,20 @@ scm_to_utf32_stringn (SCM str, size_t *lenp)
|
||||||
SCM_VALIDATE_STRING (1, str);
|
SCM_VALIDATE_STRING (1, str);
|
||||||
|
|
||||||
if (scm_i_is_narrow_string (str))
|
if (scm_i_is_narrow_string (str))
|
||||||
result = (scm_t_wchar *)
|
{
|
||||||
scm_to_stringn (str, lenp, "UTF-32",
|
scm_t_uint8 *codepoints;
|
||||||
SCM_FAILED_CONVERSION_ERROR);
|
size_t i, len;
|
||||||
|
|
||||||
|
codepoints = (scm_t_uint8*) scm_i_string_chars (str);
|
||||||
|
len = scm_i_string_length (str);
|
||||||
|
if (lenp)
|
||||||
|
*lenp = len;
|
||||||
|
|
||||||
|
result = scm_malloc ((len + 1) * sizeof (scm_t_wchar));
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
result[i] = codepoints[i];
|
||||||
|
result[len] = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
|
@ -411,70 +411,150 @@ If there is no handler at all, Guile prints an error and then exits."
|
||||||
((_ x) x)
|
((_ x) x)
|
||||||
((_ x y ...) (let ((t x)) (if t t (or y ...))))))
|
((_ x y ...) (let ((t x)) (if t t (or y ...))))))
|
||||||
|
|
||||||
|
(include-from-path "ice-9/quasisyntax")
|
||||||
|
|
||||||
(define-syntax-rule (when test stmt stmt* ...)
|
(define-syntax-rule (when test stmt stmt* ...)
|
||||||
(if test (begin stmt stmt* ...)))
|
(if test (begin stmt stmt* ...)))
|
||||||
|
|
||||||
(define-syntax-rule (unless test stmt stmt* ...)
|
(define-syntax-rule (unless test stmt stmt* ...)
|
||||||
(if (not test) (begin stmt stmt* ...)))
|
(if (not test) (begin stmt stmt* ...)))
|
||||||
|
|
||||||
;; The "maybe-more" bits are something of a hack, so that we can support
|
|
||||||
;; SRFI-61. Rewrites into a standalone syntax-case macro would be
|
|
||||||
;; appreciated.
|
|
||||||
(define-syntax cond
|
(define-syntax cond
|
||||||
(syntax-rules (=> else)
|
(lambda (whole-expr)
|
||||||
((_ "maybe-more" test consequent)
|
(define (fold f seed xs)
|
||||||
(if test consequent))
|
(let loop ((xs xs) (seed seed))
|
||||||
|
(if (null? xs) seed
|
||||||
((_ "maybe-more" test consequent clause ...)
|
(loop (cdr xs) (f (car xs) seed)))))
|
||||||
(if test consequent (cond clause ...)))
|
(define (reverse-map f xs)
|
||||||
|
(fold (lambda (x seed) (cons (f x) seed))
|
||||||
((_ (else else1 else2 ...))
|
'() xs))
|
||||||
(begin else1 else2 ...))
|
(syntax-case whole-expr ()
|
||||||
|
((_ clause clauses ...)
|
||||||
((_ (test => receiver) more-clause ...)
|
#`(begin
|
||||||
(let ((t test))
|
#,@(fold (lambda (clause-builder tail)
|
||||||
(cond "maybe-more" t (receiver t) more-clause ...)))
|
(clause-builder tail))
|
||||||
|
#'()
|
||||||
((_ (generator guard => receiver) more-clause ...)
|
(reverse-map
|
||||||
(call-with-values (lambda () generator)
|
(lambda (clause)
|
||||||
(lambda t
|
(define* (bad-clause #:optional (msg "invalid clause"))
|
||||||
(cond "maybe-more"
|
(syntax-violation 'cond msg whole-expr clause))
|
||||||
(apply guard t) (apply receiver t) more-clause ...))))
|
(syntax-case clause (=> else)
|
||||||
|
((else e e* ...)
|
||||||
((_ (test => receiver ...) more-clause ...)
|
(lambda (tail)
|
||||||
(syntax-violation 'cond "wrong number of receiver expressions"
|
(if (null? tail)
|
||||||
'(test => receiver ...)))
|
#'((begin e e* ...))
|
||||||
((_ (generator guard => receiver ...) more-clause ...)
|
(bad-clause "else must be the last clause"))))
|
||||||
(syntax-violation 'cond "wrong number of receiver expressions"
|
((else . _) (bad-clause))
|
||||||
'(generator guard => receiver ...)))
|
((test => receiver)
|
||||||
|
(lambda (tail)
|
||||||
((_ (test) more-clause ...)
|
#`((let ((t test))
|
||||||
(let ((t test))
|
(if t
|
||||||
(cond "maybe-more" t t more-clause ...)))
|
(receiver t)
|
||||||
|
#,@tail)))))
|
||||||
((_ (test body1 body2 ...) more-clause ...)
|
((test => receiver ...)
|
||||||
(cond "maybe-more"
|
(bad-clause "wrong number of receiver expressions"))
|
||||||
test (begin body1 body2 ...) more-clause ...))))
|
((generator guard => receiver)
|
||||||
|
(lambda (tail)
|
||||||
|
#`((call-with-values (lambda () generator)
|
||||||
|
(lambda vals
|
||||||
|
(if (apply guard vals)
|
||||||
|
(apply receiver vals)
|
||||||
|
#,@tail))))))
|
||||||
|
((generator guard => receiver ...)
|
||||||
|
(bad-clause "wrong number of receiver expressions"))
|
||||||
|
((test)
|
||||||
|
(lambda (tail)
|
||||||
|
#`((let ((t test))
|
||||||
|
(if t t #,@tail)))))
|
||||||
|
((test e e* ...)
|
||||||
|
(lambda (tail)
|
||||||
|
#`((if test
|
||||||
|
(begin e e* ...)
|
||||||
|
#,@tail))))
|
||||||
|
(_ (bad-clause))))
|
||||||
|
#'(clause clauses ...))))))))
|
||||||
|
|
||||||
(define-syntax case
|
(define-syntax case
|
||||||
(syntax-rules (else)
|
(lambda (whole-expr)
|
||||||
((case (key ...)
|
(define (fold f seed xs)
|
||||||
clauses ...)
|
(let loop ((xs xs) (seed seed))
|
||||||
(let ((atom-key (key ...)))
|
(if (null? xs) seed
|
||||||
(case atom-key clauses ...)))
|
(loop (cdr xs) (f (car xs) seed)))))
|
||||||
((case key
|
(define (fold2 f a b xs)
|
||||||
(else result1 result2 ...))
|
(let loop ((xs xs) (a a) (b b))
|
||||||
(begin result1 result2 ...))
|
(if (null? xs) (values a b)
|
||||||
((case key
|
(call-with-values
|
||||||
((atoms ...) result1 result2 ...))
|
(lambda () (f (car xs) a b))
|
||||||
(if (memv key '(atoms ...))
|
(lambda (a b)
|
||||||
(begin result1 result2 ...)))
|
(loop (cdr xs) a b))))))
|
||||||
((case key
|
(define (reverse-map-with-seed f seed xs)
|
||||||
((atoms ...) result1 result2 ...)
|
(fold2 (lambda (x ys seed)
|
||||||
clause clauses ...)
|
(call-with-values
|
||||||
(if (memv key '(atoms ...))
|
(lambda () (f x seed))
|
||||||
(begin result1 result2 ...)
|
(lambda (y seed)
|
||||||
(case key clause clauses ...)))))
|
(values (cons y ys) seed))))
|
||||||
|
'() seed xs))
|
||||||
|
(syntax-case whole-expr ()
|
||||||
|
((_ expr clause clauses ...)
|
||||||
|
(with-syntax ((key #'key))
|
||||||
|
#`(let ((key expr))
|
||||||
|
#,@(fold
|
||||||
|
(lambda (clause-builder tail)
|
||||||
|
(clause-builder tail))
|
||||||
|
#'()
|
||||||
|
(reverse-map-with-seed
|
||||||
|
(lambda (clause seen)
|
||||||
|
(define* (bad-clause #:optional (msg "invalid clause"))
|
||||||
|
(syntax-violation 'case msg whole-expr clause))
|
||||||
|
(syntax-case clause ()
|
||||||
|
((test . rest)
|
||||||
|
(with-syntax
|
||||||
|
((clause-expr
|
||||||
|
(syntax-case #'rest (=>)
|
||||||
|
((=> receiver) #'(receiver key))
|
||||||
|
((=> receiver ...)
|
||||||
|
(bad-clause
|
||||||
|
"wrong number of receiver expressions"))
|
||||||
|
((e e* ...) #'(begin e e* ...))
|
||||||
|
(_ (bad-clause)))))
|
||||||
|
(syntax-case #'test (else)
|
||||||
|
((datums ...)
|
||||||
|
(let ((seen
|
||||||
|
(fold
|
||||||
|
(lambda (datum seen)
|
||||||
|
(define (warn-datum type)
|
||||||
|
((@ (system base message)
|
||||||
|
warning)
|
||||||
|
type
|
||||||
|
(append (source-properties datum)
|
||||||
|
(source-properties
|
||||||
|
(syntax->datum #'test)))
|
||||||
|
datum
|
||||||
|
(syntax->datum clause)
|
||||||
|
(syntax->datum whole-expr)))
|
||||||
|
(if (memv datum seen)
|
||||||
|
(warn-datum 'duplicate-case-datum))
|
||||||
|
(if (or (pair? datum)
|
||||||
|
(array? datum)
|
||||||
|
(generalized-vector? datum))
|
||||||
|
(warn-datum 'bad-case-datum))
|
||||||
|
(cons datum seen))
|
||||||
|
seen
|
||||||
|
(map syntax->datum #'(datums ...)))))
|
||||||
|
(values (lambda (tail)
|
||||||
|
#`((if (memv key '(datums ...))
|
||||||
|
clause-expr
|
||||||
|
#,@tail)))
|
||||||
|
seen)))
|
||||||
|
(else (values (lambda (tail)
|
||||||
|
(if (null? tail)
|
||||||
|
#'(clause-expr)
|
||||||
|
(bad-clause
|
||||||
|
"else must be the last clause")))
|
||||||
|
seen))
|
||||||
|
(_ (bad-clause)))))
|
||||||
|
(_ (bad-clause))))
|
||||||
|
'() #'(clause clauses ...)))))))))
|
||||||
|
|
||||||
(define-syntax do
|
(define-syntax do
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
|
@ -502,8 +582,6 @@ If there is no handler at all, Guile prints an error and then exits."
|
||||||
(define-syntax-rule (delay exp)
|
(define-syntax-rule (delay exp)
|
||||||
(make-promise (lambda () exp)))
|
(make-promise (lambda () exp)))
|
||||||
|
|
||||||
(include-from-path "ice-9/quasisyntax")
|
|
||||||
|
|
||||||
(define-syntax current-source-location
|
(define-syntax current-source-location
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(syntax-case x ()
|
(syntax-case x ()
|
||||||
|
|
|
@ -126,6 +126,20 @@
|
||||||
"~A: warning: possibly wrong number of arguments to `~A'~%"
|
"~A: warning: possibly wrong number of arguments to `~A'~%"
|
||||||
loc name))))
|
loc name))))
|
||||||
|
|
||||||
|
(duplicate-case-datum
|
||||||
|
"report a duplicate datum in a case expression"
|
||||||
|
,(lambda (port loc datum clause case-expr)
|
||||||
|
(emit port
|
||||||
|
"~A: warning: duplicate datum ~S in clause ~S of case expression ~S~%"
|
||||||
|
loc datum clause case-expr)))
|
||||||
|
|
||||||
|
(bad-case-datum
|
||||||
|
"report a case datum that cannot be meaningfully compared using `eqv?'"
|
||||||
|
,(lambda (port loc datum clause case-expr)
|
||||||
|
(emit port
|
||||||
|
"~A: warning: datum ~S cannot be meaningfully compared using `eqv?' in clause ~S of case expression ~S~%"
|
||||||
|
loc datum clause case-expr)))
|
||||||
|
|
||||||
(format
|
(format
|
||||||
"report wrong number of arguments to `format'"
|
"report wrong number of arguments to `format'"
|
||||||
,(lambda (port loc . rest)
|
,(lambda (port loc . rest)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;;;; srfi-13.test --- Test suite for Guile's SRFI-13 functions. -*- scheme -*-
|
;;;; srfi-13.test --- Test suite for Guile's SRFI-13 functions. -*- scheme -*-
|
||||||
;;;; Martin Grabmueller, 2001-05-07
|
;;;; Martin Grabmueller, 2001-05-07
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2001, 2004, 2005, 2006, 2011 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2001, 2004, 2005, 2006, 2011, 2012 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -561,13 +561,15 @@
|
||||||
(with-test-prefix "substring/shared"
|
(with-test-prefix "substring/shared"
|
||||||
|
|
||||||
(pass-if "empty string"
|
(pass-if "empty string"
|
||||||
(eq? "" (substring/shared "" 0)))
|
(let ((s ""))
|
||||||
|
(eq? s (substring/shared s 0))))
|
||||||
(pass-if "non-empty string"
|
|
||||||
(string=? "foo" (substring/shared "foo-bar" 0 3)))
|
|
||||||
|
|
||||||
(pass-if "non-empty string, not eq?"
|
(pass-if "non-empty string, not eq?"
|
||||||
(string=? "foo-bar" (substring/shared "foo-bar" 0 7))))
|
(string=? "foo" (substring/shared "foo-bar" 0 3)))
|
||||||
|
|
||||||
|
(pass-if "shared copy of non-empty string is eq?"
|
||||||
|
(let ((s "foo-bar"))
|
||||||
|
(eq? s (substring/shared s 0 7)))))
|
||||||
|
|
||||||
(with-test-prefix "string-copy!"
|
(with-test-prefix "string-copy!"
|
||||||
|
|
||||||
|
|
|
@ -648,11 +648,13 @@
|
||||||
|
|
||||||
(pass-if-syntax-error "missing recipient"
|
(pass-if-syntax-error "missing recipient"
|
||||||
'(cond . "wrong number of receiver expressions")
|
'(cond . "wrong number of receiver expressions")
|
||||||
(cond (#t identity =>)))
|
(eval '(cond (#t identity =>))
|
||||||
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "extra recipient"
|
(pass-if-syntax-error "extra recipient"
|
||||||
'(cond . "wrong number of receiver expressions")
|
'(cond . "wrong number of receiver expressions")
|
||||||
(cond (#t identity => identity identity))))
|
(eval '(cond (#t identity => identity identity))
|
||||||
|
(interaction-environment))))
|
||||||
|
|
||||||
(with-test-prefix "bad or missing clauses"
|
(with-test-prefix "bad or missing clauses"
|
||||||
|
|
||||||
|
@ -662,43 +664,48 @@
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond #t)"
|
(pass-if-syntax-error "(cond #t)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond #t)
|
(eval '(cond #t)
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond 1)"
|
(pass-if-syntax-error "(cond 1)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond 1)
|
(eval '(cond 1)
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond 1 2)"
|
(pass-if-syntax-error "(cond 1 2)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond 1 2)
|
(eval '(cond 1 2)
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond 1 2 3)"
|
(pass-if-syntax-error "(cond 1 2 3)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond 1 2 3)
|
(eval '(cond 1 2 3)
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond 1 2 3 4)"
|
(pass-if-syntax-error "(cond 1 2 3 4)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond 1 2 3 4)
|
(eval '(cond 1 2 3 4)
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond ())"
|
(pass-if-syntax-error "(cond ())"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond ())
|
(eval '(cond ())
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond () 1)"
|
(pass-if-syntax-error "(cond () 1)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond () 1)
|
(eval '(cond () 1)
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(cond (1) 1)"
|
(pass-if-syntax-error "(cond (1) 1)"
|
||||||
exception:generic-syncase-error
|
'(cond . "invalid clause")
|
||||||
(eval '(cond (1) 1)
|
(eval '(cond (1) 1)
|
||||||
|
(interaction-environment)))
|
||||||
|
|
||||||
|
(pass-if-syntax-error "(cond (else #f) (#t #t))"
|
||||||
|
'(cond . "else must be the last clause")
|
||||||
|
(eval '(cond (else #f) (#t #t))
|
||||||
(interaction-environment))))
|
(interaction-environment))))
|
||||||
|
|
||||||
(with-test-prefix "wrong number of arguments"
|
(with-test-prefix "wrong number of arguments"
|
||||||
|
@ -712,10 +719,46 @@
|
||||||
(pass-if "clause with empty labels list"
|
(pass-if "clause with empty labels list"
|
||||||
(case 1 (() #f) (else #t)))
|
(case 1 (() #f) (else #t)))
|
||||||
|
|
||||||
|
(with-test-prefix "case handles '=> correctly"
|
||||||
|
|
||||||
|
(pass-if "(1 2 3) => list"
|
||||||
|
(equal? (case 1 ((1 2 3) => list))
|
||||||
|
'(1)))
|
||||||
|
|
||||||
|
(pass-if "else => list"
|
||||||
|
(equal? (case 6
|
||||||
|
((1 2 3) 'wrong)
|
||||||
|
(else => list))
|
||||||
|
'(6)))
|
||||||
|
|
||||||
|
(with-test-prefix "bound '=> is handled correctly"
|
||||||
|
|
||||||
|
(pass-if "(1) => 'ok"
|
||||||
|
(let ((=> 'foo))
|
||||||
|
(eq? (case 1 ((1) => 'ok)) 'ok)))
|
||||||
|
|
||||||
|
(pass-if "else =>"
|
||||||
|
(let ((=> 'foo))
|
||||||
|
(eq? (case 1 (else =>)) 'foo)))
|
||||||
|
|
||||||
|
(pass-if "else => list"
|
||||||
|
(let ((=> 'foo))
|
||||||
|
(eq? (case 1 (else => identity)) identity))))
|
||||||
|
|
||||||
|
(pass-if-syntax-error "missing recipient"
|
||||||
|
'(case . "wrong number of receiver expressions")
|
||||||
|
(eval '(case 1 ((1) =>))
|
||||||
|
(interaction-environment)))
|
||||||
|
|
||||||
|
(pass-if-syntax-error "extra recipient"
|
||||||
|
'(case . "wrong number of receiver expressions")
|
||||||
|
(eval '(case 1 ((1) => identity identity))
|
||||||
|
(interaction-environment))))
|
||||||
|
|
||||||
(with-test-prefix "case is hygienic"
|
(with-test-prefix "case is hygienic"
|
||||||
|
|
||||||
(pass-if-syntax-error "bound 'else is handled correctly"
|
(pass-if-syntax-error "bound 'else is handled correctly"
|
||||||
exception:generic-syncase-error
|
'(case . "invalid clause")
|
||||||
(eval '(let ((else #f)) (case 1 (else #f)))
|
(eval '(let ((else #f)) (case 1 (else #f)))
|
||||||
(interaction-environment))))
|
(interaction-environment))))
|
||||||
|
|
||||||
|
@ -742,22 +785,22 @@
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(case 1 \"foo\")"
|
(pass-if-syntax-error "(case 1 \"foo\")"
|
||||||
exception:generic-syncase-error
|
'(case . "invalid clause")
|
||||||
(eval '(case 1 "foo")
|
(eval '(case 1 "foo")
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(case 1 ())"
|
(pass-if-syntax-error "(case 1 ())"
|
||||||
exception:generic-syncase-error
|
'(case . "invalid clause")
|
||||||
(eval '(case 1 ())
|
(eval '(case 1 ())
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(case 1 (\"foo\"))"
|
(pass-if-syntax-error "(case 1 (\"foo\"))"
|
||||||
exception:generic-syncase-error
|
'(case . "invalid clause")
|
||||||
(eval '(case 1 ("foo"))
|
(eval '(case 1 ("foo"))
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(case 1 (\"foo\" \"bar\"))"
|
(pass-if-syntax-error "(case 1 (\"foo\" \"bar\"))"
|
||||||
exception:generic-syncase-error
|
'(case . "invalid clause")
|
||||||
(eval '(case 1 ("foo" "bar"))
|
(eval '(case 1 ("foo" "bar"))
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
|
@ -767,7 +810,7 @@
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(case 1 ((2) \"bar\") (else))"
|
(pass-if-syntax-error "(case 1 ((2) \"bar\") (else))"
|
||||||
exception:generic-syncase-error
|
'(case . "invalid clause")
|
||||||
(eval '(case 1 ((2) "bar") (else))
|
(eval '(case 1 ((2) "bar") (else))
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
|
@ -777,7 +820,7 @@
|
||||||
(interaction-environment)))
|
(interaction-environment)))
|
||||||
|
|
||||||
(pass-if-syntax-error "(case 1 (else #f) ((1) #t))"
|
(pass-if-syntax-error "(case 1 (else #f) ((1) #t))"
|
||||||
exception:generic-syncase-error
|
'(case . "else must be the last clause")
|
||||||
(eval '(case 1 (else #f) ((1) #t))
|
(eval '(case 1 (else #f) ((1) #t))
|
||||||
(interaction-environment)))))
|
(interaction-environment)))))
|
||||||
|
|
||||||
|
|
|
@ -1162,24 +1162,21 @@
|
||||||
(case foo
|
(case foo
|
||||||
((3 2 1) 'a)
|
((3 2 1) 'a)
|
||||||
(else 'b))
|
(else 'b))
|
||||||
(if (let (t) (_) ((toplevel foo))
|
(let (key) (_) ((toplevel foo))
|
||||||
(if (primcall eqv? (lexical t _) (const 3))
|
(if (if (primcall eqv? (lexical key _) (const 3))
|
||||||
(const #t)
|
(const #t)
|
||||||
(if (primcall eqv? (lexical t _) (const 2))
|
(if (primcall eqv? (lexical key _) (const 2))
|
||||||
(const #t)
|
(const #t)
|
||||||
(primcall eqv? (lexical t _) (const 1)))))
|
(primcall eqv? (lexical key _) (const 1))))
|
||||||
(const a)
|
(const a)
|
||||||
(const b)))
|
(const b))))
|
||||||
|
|
||||||
(pass-if-peval
|
(pass-if-peval
|
||||||
;; Memv with non-constant key, empty list, test context. Currently
|
;; Memv with non-constant key, empty list, test context.
|
||||||
;; doesn't fold entirely.
|
|
||||||
(case foo
|
(case foo
|
||||||
(() 'a)
|
(() 'a)
|
||||||
(else 'b))
|
(else 'b))
|
||||||
(if (seq (toplevel foo) (const #f))
|
(seq (toplevel foo) (const 'b)))
|
||||||
(const a)
|
|
||||||
(const b)))
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Below are cases where constant propagation should bail out.
|
;; Below are cases where constant propagation should bail out.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue