* module/language/tree-il/optimize.scm (peval): Propagate ARGS to BODY
only when all of ARGS are pure. Change APP to use `maybe-unconst' for
its arguments.
* test-suite/tests/tree-il.test ("partial evaluation"): Add tests for
mutability preservation and non-propagation of non-constant arguments
to lambdas.
* module/language/tree-il/optimize.scm (peval)[make-values]: Distinguish
between 1 or another number of values.
[mutable?, make-value-construction, maybe-unconst]: New procedures.
Use it in <let>, <letrec>, <toplevel-define>, and <lambda-case>.
* test-suite/tests/tree-il.test ("partial evaluation"): Add tests
for mutability preservation.
Thanks to William R. Cook for his excellent tutorial,
<http://softlang.uni-koblenz.de/dsl11/>.
* module/language/tree-il/optimize.scm (optimize!): Call `peval' unless
the #:partial-eval? option asks otherwise.
(peval): New procedure.
* module/language/tree-il/inline.scm: Add comment.
* module/language/tree-il/primitives.scm (*primitive-constructors*): New
variable.
(*effect-free-primitives*): Use it.
(constructor-primitive?): New primitive.
* test-suite/tests/tree-il.test (assert-tree-il->glil): Extend to
support `with-partial-evaluation', `without-partial-evaluation', and
`with-options'.
(peval): New binding.
(pass-if-peval): New macro.
("lexical refs"): Run tests without partial evaluation.
("letrec"): Likewise.
("the or hack"): Likewise.
("conditional"): Likewise, for some tests.
("sequence"): Adjust to new generated code.
("partial evaluation"): New test prefix.
* module/language/tree-il/primitives.scm (+, *, cons*): In the case of
just one argument (the identity case), expand to (values x) instead of
just x. Fixes values truncation in that case.
(values): Likewise remove (values x) -> x translation, as the compiler
will do it for us, and this fixes (values (values 1 2)).
* module/language/tree-il/compile-glil.scm (flatten-lambda-case): Handle
`values' in a push context here.
* test-suite/tests/tree-il.test ("values"): Add some tests.
http://savannah.gnu.org/bugs/?33362
* module/language/tree-il/compile-glil.scm (flatten-lambda-case): Rename
from flatten, as it really just takes a particular case. Instead of
iteratively compiling lambda cases through `comp', tail-call through
flatten-lambda-case. This allows code to see which case it's being
compiled in. Take advantage of that to limit the self-tail-call
optimization to self-calls to the same case -- otherwise we might be
jumping to a label without having reserved the right number of
locals.
(flatten-lambda): Adapt the caller.
* test-suite/tests/compiler.test ("case-lambda"): Add a test.
* libguile/expand.h:
* module/language/tree-il.scm: Rename "sequence" to "seq", and instead
of taking a list of expressions, take a head and a tail.
* module/language/tree-il/analyze.scm:
* module/language/tree-il/compile-glil.scm:
* module/language/tree-il/fix-letrec.scm:
* module/language/tree-il/spec.scm:
* module/language/elisp/compile-tree-il.scm:
* module/ice-9/psyntax.scm:
* module/ice-9/psyntax-pp.scm:
* module/ice-9/eval.scm:
* libguile/memoize.h:
* libguile/memoize.c:
* libguile/expand.c:
* libguile/eval.c: Adapt to the new seq format.
* module/language/tree-il/compile-glil.scm (flatten): When compiling a
<prompt> in push context with an RA, after the body returns normally,
jump to that RA instead of to our POST label (which in that case does
not need to be emitted). Fixes a tail <prompt> in a push <fix>.
* test-suite/tests/control.test ("prompt in different contexts"): Add
more test cases.
* module/language/tree-il/fix-letrec.scm (partition-vars): Previously,
for letrec* we treated all unreferenced vars as complex, because of
orderings of effects that could arise in their definitions. But we
can actually keep simple and lambda vars as unreferenced, as their
initializers cannot cause side effects.
(fix-letrec!): Remove letrec* -> letrec code, as it's unneeded.
* module/language/tree-il/fix-letrec.scm (fix-letrec!): When X is a
`letrec*' with only lambdas and simple expressions, analyze it as if
it were a `letrec'.
* test-suite/tests/tree-il.test ("letrec"): Add test for
`(letrec* (x y) (xx yy) ((const 1) (const 2)) (lexical y yy))'.
* module/language/tree-il/inline.scm (boolean-value): Add a case for
applications of primitives, and move the memq/memv->bool code here.
(inline!): We were inlining (memq 'a '(a b c)) => #t, and not the list
tail, which was an embarrassing bug. Fixed by moving this code to the
boolean-value function. Thanks to Mark Harig for the report.
* module/language/tree-il/fix-letrec.scm: Replace U+2019 with an ASCII
quote. The iconv implementation on FreeBSD would immediately notice
and bail out when reading it under a US-ASCII locale.
* module/language/tree-il/compile-glil.scm (flatten-lambda): Don't emit
a self-label, because when we can't match the args for a lexical call,
we have no space to shuffle args and jump.
(flatten): Apply the self-tail-call optimization to optional args
too, but only if the procedure is fix-allocated. If we can't apply the
optimization, use the normal tail-call sequence.
* test-suite/tests/optargs.test ("lambda* inits"): Add tests.
* module/language/tree-il/compile-glil.scm (vars->bind-list, flatten):
Make internal self-checking error messages more clear, for
implementors of other languages.
* module/language/tree-il/analyze.scm (gensym?): New procedure.
(unused-variable-analysis): Ignore variables whose name passes
`gensym?' or is `_'.
(unused-toplevel-analysis): Ignore variables whose name passes
`gensym?'.
* test-suite/tests/tree-il.test ("warnings")["unused-variable"]("special
variable names"): New test.
["unused-toplevel"]("special variable names"): New test.
* module/language/tree-il/analyze.scm (format-analysis): Don't warn on
non-literal format string if the format string is a lexical ref to a
variable named "fmt". A slight hack, but effective :)
* module/system/repl/command.scm (display-stat): Rename the format
string to "fmt".
* 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.
* libguile/vm-i-scheme.c (symbol?, vector?): New
instructions. Renumbered the rest.
* libguile/vm-i-system.c: Renumber instructions.
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* module/ice-9/psyntax.scm (binding-type, binding-value): Define using
macros so that we inline to car and cdr opcodes. Oh, for an inliner :)
* module/language/tree-il/compile-glil.scm (*primcall-ops*)
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*, *effect-free-primitives*)
(*effect+exception-free-primitives*): Add symbol? and vector?
inlines.
* module/ice-9/boot-9.scm (make-struct/no-tail): Define a version of
this function. Because during optimization we resolve make-struct to
make-struct/no-tail, we need an implemented make-struct/no-tail if we
are to be able to run scheme made from tree-il->scheme.
* module/language/tree-il/compile-glil.scm (*primcall-ops*): Remove
variable-set case, as there is no "variable-set!" primitive.
(flatten): Add a special hack for variable-set!. Ugly, I know.
* module/language/tree-il/primitives.scm (*effect-free-primitives*): Add
make-struct/no-tail.
(*effect+exception-free-primitives*): Remove make-struct, as it could
raise an exception.
(variable-set!): Remove expansion to variable-set.
* test-suite/tests/tree-il.test ("letrec"): Add some tests.
* module/language/tree-il/compile-glil.scm (flatten): Add support for
compiling letrec* in its unoptimized form.
* module/language/tree-il/fix-letrec.scm (simple-expression?):
Parameterize, so that letrec* will not treat `(car x)' as primitive
(because it could raise an exception).
(partition-vars): Lump unreferenced vars in with complex vars, when
compiling letrec*.
(fix-letrec!): No need to evaluate inits within a let for letrec*.
* module/language/tree-il/primitives.scm
(effect+exception-free-primitive?): New predicate, like
effect-free-primitive?, but excludes accessors that could raise
exceptions.
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*, *effect-free-primitives*): Recognize
make-prompt-tag as interesting and effect-free.
* module/language/tree-il/inline.scm (boolean-value, inline!): Add a
case for inlining conditional expressions.
* test-suite/tests/tree-il.test: Fix conditional tests to have a
non-inlinable condition.
* module/language/tree-il.scm (<tree-il>): Rename `vars' fields of
<let>, <letrec>, <fix>, and <lambda-case> to `gensyms'. For clarity,
and to match <lexical-ref>.
* module/language/tree-il.scm:
* module/language/tree-il/analyze.scm:
* module/language/tree-il/compile-glil.scm:
* module/language/tree-il/fix-letrec.scm:
* module/language/tree-il/inline.scm: Update all callers.
* 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").
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump for make-struct
change.
* libguile/struct.c (scm_i_alloc_struct): Use scm_words instead of
scm_gc_malloc to simplify the code and inline the call to GC_MALLOC.
* module/language/tree-il/compile-glil.scm (*primcall-ops*): Compile
make-struct/no-tail to make-struct.
* module/language/tree-il/primitives.scm (define-primitive-expander):
Allow a conditional branch of #f to aboirt inlining.
(make-struct): Expand into make-struct/no-tail in the case that
tail-size is 0.
* libguile/vm-i-scheme.c (make-struct): Adapt to always assume tail-size
is 0. Inline allocation if possible. Don't decrement the SP past live
objects on the stack, which could cause GC to miss references. Use the
NULLSTACK macro.
* libguile/procprop.h (scm_sym_arity): Deprecate. I didn't move it to
deprecated.h though, because that might have some boot implications --
though I didn't check.
* libguile/procprop.c (scm_procedure_properties)
(scm_set_procedure_properties_x, scm_procedure_property)
(scm_set_procedure_property_x): Deprecate access to a procedure's
arity via procedure-properties. Users should use
procedure-minimum-arity.
* module/ice-9/channel.scm (eval):
* module/ice-9/session.scm (arity):
* module/language/tree-il/analyze.scm (validate-arity): Fix up instances
of (procedure-property x 'arity) to use procedure-minimum-arity.
* libguile/programs.h:
* libguile/programs.c (scm_program_name): Remove. procedure-name is
sufficient.
* module/system/vm/program.scm (program-name): Remove from exports list.
(program-documentation): Remove; procedure-documentation is
sufficient.
* libguile/debug.c (scm_procedure_name): Remove special case for
programs.
* module/language/tree-il/analyze.scm (validate-arity): Use
procedure-name.
* module/ice-9/documentation.scm (object-documentation): Just use
procedure-documentation, without special cases for programs.
* module/language/tree-il/inline.scm (inline!): Only inline (lambda args
(apply (lambda ...) args)) if the outer lambda has rest args. Thanks
to Mark Weaver for the note.
* module/ice-9/boot-9.scm (default-prompt-tag, make-prompt-tag): New
functions.
(call-with-prompt, abort-to-prompt): Rename from `prompt' and `abort',
respectively. These names are more clear, and allow `prompt' and
`abort' to have more convenient, less general bindings.
(default-throw-handler, custom-throw-handler, catch, %start-stack):
Adapt callers.
* module/ice-9/control.scm: Adapt re-export list.
(control): Remove binding, until we're sure that it is Sitaram's
control.
(abort): New binding, aborts to the nearest prompt with the default
tag.
(%): Use call-with-prompt.
* module/language/tree-il/primitives.scm (*primitive-expand-table*):
(*interesting-primitive-names*): Adapt for prompt/abort changes.
* test-suite/tests/control.test: Take advantage of the defaults for %
and abort.
* module/language/tree-il/compile-glil.scm (flatten): Change to use the
anonymous <glil-mv-bind> form when truncating to 0 or 1 values. In
those cases, remove the <glil-unbind> statements. As a side effect,
fixes compilation of abort in a "values" context.
Thanks to Tristan Colgate for the bug report.
* test-suite/tests/tree-il.test: Update to expect anonymous mv-bind.
* module/language/tree-il/inline.scm (inline!): Fix indenting for
lambda-case. In an amusing turn of events, use the inliner to
de-inline prompt bodies, if the prompt is not escape-only.
* libguile/control.h:
* libguile/control.c (scm_c_make_prompt): Take an extra arg, a cookie.
Continuations will be rewindable only if the abort has the same cookie
as the prompt.
(scm_at_abort): Redefine from scm_abort, and instead of taking rest
args, take the abort values as a list directly. Also, don't allow
rewinding, because we won't support rewinding the C stack with
delimited continuations.
* libguile/eval.c (eval): Adapt to scm_c_make_prompt change.
* libguile/vm-engine.c (vm_engine): Use vp->cookie to get a unique value
corresponding to this VM invocation.
* libguile/vm-i-system.c (prompt): Pass the cookie to scm_c_make_prompt.
(abort): Take an additional tail arg.
* libguile/vm.c (vm_abort): Parse out the abort tail arg. This is for
the @abort case, or the (apply abort ...) case.
(make_vm): Initialize the cookie to 0.
* libguile/vm.h (struct scm_vm): Add cookie.
* module/ice-9/boot-9.scm (abort): Define here as a trampoline to
@abort. Needed to make sure that a call to abort dispatches to a VM
opcode, so the cookie will be the same.
* module/language/tree-il.scm (<tree-il>): Add a "tail" field to
<abort>, for the (apply abort ...) case, or (@abort tag args). Should
be #<const ()> in the normal case. Add support throughout.
* module/language/tree-il/analyze.scm (analyze-lexicals): Add abort-tail
support here too.
* module/language/tree-il/compile-glil.scm (flatten): Compile the tail
argument appropriately.
* module/language/tree-il/primitives.scm (*primitive-expand-table*): Fix
@abort and abort cases to pass the tail arg to make-abort.