* module/system/base/pmatch.scm (pmatch): Always wrap with 'let', even
if the expression appears atomic, because in the presence of
'identifier-syntax', we cannot know what an atomic expression will
later expand to. Also use '#:export-syntax' instead of '#:export'
to export 'pmatch'.
* module/ice-9/boot-9.scm (cond, case): Reimplement using syntax-case,
with improved error messages and support for '=>' within 'case' as
mandated by the R7RS. Add warnings for duplicate case datums and
case datums that cannot be meaningfully compared using 'eqv?'.
* module/system/base/message.scm (%warning-types): Add 'bad-case-datum'
and 'duplicate-case-datum' warning types.
* test-suite/tests/syntax.test (cond, case): Update tests to reflect
improved error reporting. Add tests for '=>' within 'case'.
* test-suite/tests/tree-il.test (partial evaluation): Update tests to
reflect changes in how 'case' is expanded.
* doc/ref/api-control.texi (Conditionals): Document '=>' within 'case'.
* module/language/tree-il/analyze.scm
(format-analysis)[check-simple-format-args]: New procedure. Use it.
Add support for applications of <module-ref>.
* module/system/base/message.scm (%warning-types): Handle the `format
simple-format' warning.
* module/language/scheme/spec.scm (scheme)[make-default-environment]:
Use `simple-format' as the default `format'.
* test-suite/tests/tree-il.test ("warnings")["format"]: Explicitly use
(@ (ice-9 format) format) where needed.
("simple-format"): New test prefix.
* module/system/base/target.scm (%target-endianness, %target-word-size):
New fluids.
(%native-word-size): New variable.
(with-target): Set these fluids.
(cpu-endianness, cpu-word-size, triplet-cpu, triplet-vendor,
triplet-os): New procedures.
(target-cpu, target-vendor, target-os): Use them.
(target-endianness, target-word-size): Refer to the corresponding
fluid.
* libguile/objcodes.c (target_endianness_var, target_word_size_var): New
global variables.
(NATIVE_ENDIANNESS): New macro.
(target_endianness, target_word_size, to_native_order): New functions.
(make_objcode_from_file): Use `scm_bytecode_to_native_objcode' instead
of `scm_bytecode_to_objcode'.
(bytecode_to_objcode): New function, based on `scm_bytecode_to_objcode',
with the addition of an `endianness' and `word_size' parameters.
(scm_bytecode_to_objcode): Use it.
(scm_bytecode_to_native_objcode): New function.
(scm_write_objcode): Use `target_word_size' and `target_endianness'.
Convert OBJCODE's len and meta-len to native byte order.
(scm_init_objcodes): Initialize `target_endianness_var' and
`target_word_size_var'.
* libguile/objcodes.h (scm_bytecode_to_native_objcode): New declaration.
* libguile/vm.c (really_make_boot_program): Use
`scm_bytecode_to_native_objcode' instead of `scm_bytecode_to_objcode'.
* test-suite/tests/asm-to-bytecode.test (%objcode-cookie-size): New
variable.
(test-target): New procedure.
("cross-compilation"): Add `test-target' calls and the "unknown
target" test.
* module/system/base/target.scm (validate-target): Accept any tuple with
at least 3 parts.
* test-suite/tests/asm-to-bytecode.test (test-triplet): New procedure.
("cross-compilation"): New test prefix.
* libguile/load.c (canonical_to_suffix, scm_primitive_load_path):
* module/ice-9/boot-9.scm (load-in-vicinity):
* module/system/base/compile.scm (compiled-file-name): If the canonical
path of a file is a DOS-style path with a drive letter, turn it into a
path suffix it by removing the colon and prefixing a "/".
Inspired by a patch from Jan Nieuwenhuizen.
* module/system/base/language.scm (current-language): Default to 'scheme
here, rather than relying on *current-language* always being bound.
Thanks to 亚光唐 <texnician@gmail.com> for the report.
* module/Makefile.am:
* module/system/base/target.scm: Add a minimal module to parameterize
the target system type and inspect properties on it like cpu, vendor,
os, endianness, and word size.
This is so that compiling the same code on environments with different
locale settings yields the same result.
* module/system/base/compile.scm (compile-file): When ENC if #f, default
to "UTF-8" instead of `(fluid-ref %default-port-encoding)'.
* doc/ref/api-evaluation.texi (Compilation): Document the default output
file name and default source file encoding for `compile-file' and
`guile-tools compile'.
* module/system/base/lalr.scm (source-location->source-properties): New
public function, to produce source properties that can be given to the
compiler.
* module/language/tree-il/analyze.scm (&syntax-error): New variable.
(format-string-argument-count): Throw to &SYNTAX-ERROR when a syntax
error in a format string is encountered.
(format-analysis): Catch &SYNTAX-ERROR and convert as a warning of the
appropriate type.
* module/system/base/message.scm (%warning-types)[format]: Handle
`syntax-error' warnings.
* test-suite/tests/tree-il.test
("warnings")["conditionals"]("unterminated", "unexpected ~;",
"unexpected ~]"): New tests.
["unterminated ~{...~}"]: New test.
* module/language/tree-il/analyze.scm (format-analysis): Add new
sub-warnings: `wrong-port', `wrong-format-string',
`non-literal-format-string', and `wrong-num-args'.
* module/system/base/message.scm (%warning-types)[format]: Handle
them.
* test-suite/tests/tree-il.test ("warnings")["wrong port arg",
"wrong format string", "non-literal format string",
"wrong number of args"]: New tests.
* module/language/tree-il/analyze.scm (format-string-argument-count):
Return two values, the minimum and maximum number of arguments.
Add support for most of `format' escapes, including conditionals.
(format-analysis): Adjust accordingly.
* module/system/base/message.scm (%warning-types)[format]: Take two
arguments, MIN and MAX, instead of EXPECTED. Display warning
accordingly.
* test-suite/tests/tree-il.test ("warnings")["format"]("~%, ~~, ~&, ~t,
~_, and ~\\n", "~{...~}", "~{...~}, too many args", "~@{...~}",
"~@{...~}, too few args", "~(...~)", "~v", "~v:@y", "~*", "~?",
"complex 1", "complex 2", "complex 3"): New tests.
("conditionals"): New test prefix.
* am/guilec (install-data-hook): Remove.
(guile_install_go_files): New variable.
($(guile_install_go_files)): New dependency.
* libguile/load.c (compiled_is_fresh): Check for ordering of STAT_SOURCE
and STAT_COMPILED, not equality.
* module/ice-9/boot-9.scm (load): Ditto.
* module/system/base/compile.scm (call-with-output-file/atomic): Don't
set the timestamp of TEMPLATE.
* module/system/base/compile.scm:
* module/system/base/language.scm (*current-language*, current-language):
Move this fluid and thunk down to (system base language).
* module/system/base/language.scm (<language>): Remove the `version'
field from languages. It just wasn't useful.
* module/language/assembly/spec.scm:
* module/language/brainfuck/spec.scm:
* module/language/bytecode/spec.scm:
* module/language/ecmascript/spec.scm:
* module/language/elisp/spec.scm:
* module/language/glil/spec.scm:
* module/language/objcode/spec.scm:
* module/language/scheme/spec.scm:
* module/language/tree-il/spec.scm:
* module/language/value/spec.scm: Remove #:version from all language
definitions. Shorten some language names (e.g. "Guile Scheme" ->
"Scheme").
* module/system/base/compile.scm (compile-file, compile-and-load): Add a
keyword arg #:canonicalization, which defaults to 'relative. In this
way, one might compile "../module/ice-9/boot-9.scm", but the path that
gets residualized into the .go is "ice-9/boot-9.scm".
* module/system/base/compile.scm (compiled-file-name): Add a comment.
* module/ice-9/boot-9.scm (load): Avoid loading up (system base compile)
just to compute an autocompiled file name. Fixes the issue whereby
guile-tools snarf-check-and-output-texi was inadvertantly loading up
srfi-1, and thereby a stale library, just to see if guile-tools itself
had a compiled version.
Not sure what the right unit test is here, other than vigilance.
* libguile/posix.h:
* libguile/posix.c (scm_utime): Add optional nanosecond arguments. This
is an incompatible change on the C level, but it's unlikely people are
using this POSIX wrapper function, because they would just use the
POSIX function directly. Hopefully, anyway.
* module/system/base/compile.scm (call-with-output-file/atomic):
Propagate source timestamps to targets with nanosecond precision, if
available. Fixes build on systems with ext4 filesystems.
* libguile/filesys.c (scm_stat2scm):
* module/ice-9/posix.scm (stat:atimensec, stat:mtimensec)
(stat:ctimensec): Add three new elements to Scheme stat structures,
for nanosecond-level timestamps.
* configure.ac: Add checks for utimensat, and for nanosecond fields in
struct stat. We should switch to using Gnulib things for these,
though.
* doc/ref/posix.texi (File System): Add documentation for utime's
additional arguments, and nanosecond stat timestamp accessors.
* module/language/tree-il/analyze.scm (<reference-dag>): New record
type.
(dag-reachable-nodes, dag-reachable-nodes*, unused-variable-analysis):
New variables.
(unbound-variable-analysis): Slightly simplify the `up' procedure.
* module/language/tree-il/compile-glil.scm (%warning-passes): Add
`unused-toplevel'.
* module/system/base/message.scm (%warning-types): Likewise.
* test-suite/tests/tree-il.test (%opts-w-unused-toplevel): New variable.
("warnings")["unused-toplevel"]: New test prefix.
* module/language/tree-il/analyze.scm (<arity-info>): New record type.
(validate-arity, arity-analysis): New variables.
* module/language/tree-il/compile-glil.scm (%warning-passes): Add
`arity-mismatch'.
* module/system/base/message.scm (%warning-types): Likewise.
* test-suite/tests/tree-il.test (read-and-compile): Remove, as it's now
public.
(%opts-w-arity): New.
("warnings")["arity mismatch"]: New test prefix.
* test-suite/Makefile.am:
* test-suite/tests/brainfuck.test: Add a brainfuck test.
* module/system/base/compile.scm: Also export read-and-compile.
* module/language/tree-il/spec.scm (join): Fix the joiner in the
0-expression case.
* module/language/tree-il/primitives.scm (+): Recognize (+ x -1) as 1-.
* module/language/brainfuck/parse.scm (read-brainfuck): Return EOF if we
actually received EOF, and there were no expressions read.
* module/language/brainfuck/compile-tree-il.scm (compile-body): Fix the
compiler for the new format of "lambda" in tree-il.
* module/ice-9/boot-9.scm (make-fresh-user-module): New public function,
makes an anonymous beautified module.
* module/language/objcode/spec.scm: We used to have some things in here
that allowed lexical variable names and values to be a part of the
environment, but no more. Now an environment is just a module. If you
want to "inject" free variables into code, just use lambda.
* module/language/scheme/compile-tree-il.scm (compile-tree-il): Same
here. Also, rely on the fact that an environment *will* be a module --
because (system base compile) guarantees that for us.
* module/language/scheme/spec.scm (scheme): In the reader, rely on the
environment being a module. Define a #:make-default-environment
handler, which returns a beautified module, augmented with a fresh
definition for current-reader, so that side effects to current-reader
are restricted to the compilation unit.
* module/language/tree-il/analyze.scm
(report-possibly-unbound-variables):
* module/language/tree-il/compile-glil.scm (compile-glil):
* module/language/tree-il/optimize.scm (optimize!): The environment will
be a module.
* module/system/base/language.scm (<language>): New field,
`make-default-environment'. Defaults to `make-fresh-user-module'.
(default-environment): New accessor, returns a default environment for
a language.
* module/system/repl/common.scm (repl-compile): Always compile relative
to the current module, because a module is always acceptable as an
environment.
* module/system/base/compile.scm (compile-file, compile-and-load): Both
of these have a new keyword argument, #:env. For `compile-file', it
defaults to the default environment of the source language, and for
`compile-and-load', to the current module.
(read-and-compile): If there are no expressions read, pass the joiner
its default environment (via `default-environment joint').
* module/system/base/compile.scm (current-compilation-environment):
Remove, as the only thing that needed it (language readers) now get
the environment as an argument.
(read-and-compile, compile): Rework for no *compilation-environment*,
and default the environment using the define* mechanism.
* module/language/tree-il/analyze.scm (env-module): Hack around the lack
of a current compilation module. Will fix this in the next commit so
that the environment is always valid.
* module/language/assembly/spec.scm:
* module/language/brainfuck/spec.scm:
* module/language/bytecode/spec.scm:
* module/language/ecmascript/spec.scm:
* module/language/glil/spec.scm:
* module/language/scheme/spec.scm:
* module/language/tree-il/spec.scm: Language-readers now take two
arguments: the port and the environment. This should allow for
compile-environment-specific reader behavior.
* module/system/base/compile.scm (read-and-compile):
* module/system/repl/common.scm (repl-read): Pass the environment to the
language-reader.
* module/system/repl/repl.scm (meta-reader, prompting-meta-read):
* module/system/repl/command.scm (define-meta-command): Use the second
argument to repl-reader, so we avoid frobbing current-reader.
* module/language/scheme/spec.scm (scheme)[#:reader]: Honor the
compilation environment's `current-reader'.
* module/system/base/compile.scm (*compilation-environment*): New
fluid.
(current-compilation-environment): New procedure.
(make-compilation-module): Provide a fresh `current-reader' fluid.
(read-and-compile): Set `*compilation-environment*' appropriately.
(compile): Likewise.
* test-suite/tests/compiler.test (read-and-compile): New.
("current-reader"): New test prefix.
* module/system/base/compile.scm (make-compilation-module,
language-default-environment): New procedures.
(read-and-compile, compile): Have ENV default to
`(language-default-environment from)'.
(compile-and-load): Compile in `(current-module)'.
* module/system/repl/common.scm (repl-compile): Explicitly compile in
the current module so that macro definitions are visible.
* libguile/load.c (kw_env): New variable.
(do_try_autocompile): Call `compile-file' with `#:env (current-module)'.
* test-suite/tests/compiler.test ("psyntax")["compile uses a fresh module by
default", "compile-time definitions are isolated"]: New tests.
["compile in current module"]: Specify `#:env (current-module)'.
["redefinition"]: Adjust.
* test-suite/tests/bytevectors.test (c&e): Explicitly compile in the
current module so that its imports are visible.
Ports are given two additional properties: a character encoding and
a conversion failure strategy. These properties have getters and setters.
The new properties are used to convert any locale text to/from the
internal representation of strings.
If unspecified, ports use a default value. The default value of these
properties is held in a fluid. The default character encoding can be
modified by calling setlocale.
ISO-8859-1 is treated specially. Since it is a native encoding of
strings, it can be processed more quickly. Source code is assumed to be
ISO-8859-1 unless otherwise specified. The encoding of a source code
file can be given as 'coding: XXXXX' in a magic comment at the top of a
file.
The C functions that deal with encoding often use a null pointer
as shorthand for the native Latin-1 encoding, for efficiency's sake.
* test-suite/tests/encoding-iso88591.test: new tests
* test-suite/tests/encoding-iso88597.test: new tests
* test-suite/tests/encoding-utf8.test: new tests
* test-suite/tests/encoding-escapes.test: new tests
* test-suite/tests/numbers.test: declare 'binary' encoding
* test-suite/tests/ports.test: declare 'binary' encoding
* test-suite/tests/r6rs-ports.test: declare 'binary' encoding
* module/system/base/compile.scm (compile-file): use source-code
file's self-declared encoding when compiling files
* libguile/strports.c: store string ports in locale encoding
(scm_strport_to_locale_u8vector, scm_call_with_output_locale_u8vector)
(scm_open_input_locale_u8vector, scm_get_output_locale_u8vector):
new functions
* libguile/strings.h: new declaration for scm_i_string_contains_char
* libguile/strings.c (scm_i_string_contains_char): new function
(scm_from_stringn, scm_to_stringn): use NULL for Latin-1
(scm_from_locale_stringn, scm_to_locale_stringn): respect character
encoding of input and output ports
* libguile/read.h: declaration for scm_scan_for_encoding
* libguile/read.c:
(read_token): now takes scheme string instead of C string/length
(read_complete_token): new function
(scm_read_sexp, scm_read_number, scm_read_mixed_case_symbol)
(scm_read_number_and_radix, scm_read_quote, scm_read_semicolon_comment)
(scm_read_srfi4_vector, scm_read_bytevector, scm_read_guile_bit_vector)
(scm_read_scsh_block_comment, scm_read_commented_expression)
(scm_read_extended_symbol, scm_read_sharp_extension, scm_read_shart)
(scm_read_expression): use scm_t_wchar for char type, use read_complete_token
(scm_scan_for_encoding): new function to find a file's character encoding
(scm_file_encoding): new function to find a port's character encoding
* libguile/rdelim.c: don't unpack strings
* libguile/print.h: declaration for modified function
scm_i_charprint
* libguile/print.c: use locale when printing characters and
strings
(scm_i_charprint): input parameter is now scm_t_wchar
(scm_simple_format): don't unpack strings
* libguile/posix.h: new declaration for scm_setbinary.
* libguile/posix.c (scm_setlocale): set default and stdio port
encodings based on the locale's character encoding
(scm_setbinary): new function
* libguile/ports.h (scm_t_port): add encoding and failed
conversion handler to port type. Declarations for new or modified
functions scm_getc, scm_unget_byte, scm_ungetc,
scm_i_get_port_encoding, scm_i_set_port_encoding_x,
scm_port_encoding, scm_set_port_encoding_x,
scm_i_get_conversion_strategy, scm_i_set_conversion_strategy_x,
scm_port_conversion_strategy, scm_set_port_conversion_strategy_x.
* libguile/ports.c: assign the current ports to zero on startup so
we can see if they've been set.
(scm_current_input_port, scm_current_output_port,
scm_current_error_port): return #f if the port is not yet
initialized
(scm_new_port_table_entry): set up a new port's encoding and
illegal sequence handler based on the thread's current defaults
(scm_i_remove_port): free port encoding name when port is removed
(scm_i_mode_bits_n): now takes a scheme string instead of a c
string and length. All callers changed.
(SCM_MBCHAR_BUF_SIZE): new const
(scm_getc): new function, since the scm_getc in inline.h is now
scm_get_byte_or_eof. This pulls one codepoint from a port.
(scm_lfwrite_substr, scm_lfwrite_str): now uses port's encoding
(scm_unget_byte): new function, incorportaing the low-level functionality
of scm_ungetc
(scm_ungetc): uses scm_unget_byte
* libguile/numbers.h (scm_t_wchar): compilation order problem with
scm_t_wchar being use in functions in multiple headers. Forward
declare scm_t_wchar.
* libguile/load.c (scm_primitive_load): scan for file encoding at
top of file and use it to set the load port's encoding
* libguile/inline.h (scm_get_byte_or_eof): new function
incorporating most of the functionality of scm_getc.
* libguile/fports.c (fport_fill_input): now returns scm_t_wchar
* libguile/chars.h (scm_t_wchar): avoid compilation order problem
with declaration of scm_t_wchar
* module/language/tree-il.scm (tree-il-fold): Fix for let-values case.
(make-tree-il-folder): New public macro, makes a multi-valued folder
specific to the number of seeds that the user wants.
* module/language/tree-il/optimize.scm (optimize!): Reverse the order of
inline! and fix-letrec!, as the latter might expose opportunities for
the former.
* module/srfi/srfi-11.scm (let-values): Reimplement in terms of
syntax-case, so that its expressions may reference hygienically bound
variables. See the NEWS for the rationale.
(let*-values): An empty let*-values still introduces a local `let'
binding contour.
* module/system/base/syntax.scm (record-case): Yukkkk. Reimplement in
terms of syntax-case. Ug-ly, but see the NEWS again: "Lexical bindings
introduced by hygienic macros may not be referenced by nonhygienic
macros."
* module/Makefile.am (BRAINFUCK_LANG_SOURCES): Compile at the end. Add
compile-tree-il.scm.
* module/language/brainfuck/compile-tree-il.scm: New compiler, compiles
to tree-il instead of scheme. I thought it would be more illustrative,
though there are some uncommented bits.
* module/language/brainfuck/parse.scm: Modify not to put a header on the
scheme representation. After all, we don't put <scheme> before scheme
code, do we? :)
* module/language/brainfuck/spec.scm: Add tree-il compiler.
* module/language/tree-il.scm: Understand (set! (lexical foo) ...).
* module/system/base/language.scm: Update license. Actually, updates
licenses on all these.