* module/language/elisp/compile-tree-il.scm (process-let-bindings):
Remove.
(parse-let-binding, parse-flet-binding): New procedures.
(generate-let, generate-let*): Now takes an association list mapping
symbols to values for the `bindings' argument.
(compile-let, compile-let*, compile-lexical-let)
(compile-lexical-let*): Parse the bindings list with
`parse-let-binding'.
(compile-flet): Parse the bindings list with `parse-flet-binding'.
* module/language/elisp/compile-tree-il.scm (bind-lexically?): Accept a
new `decls' argument and check it for `lexical' declarations.
Establish the same kind of binding whether or not a lexical binding
for `sym' exists, whereas previously the presence of a lexical binding
would cause newly-established bindings to be lexical bindings as well.
(split-let-bindings): Remove. All callers changed.
(generate-let, generate-let*, compile-lambda): Pass the declarations
list to `bind-lexically?'.
* test-suite/tests/elisp-compiler.test: Explicitly disable the
lexical-binding mode. Add `lexical' declarations where necessary.
* module/language/elisp/compile-tree-il.scm (split-lambda-arguments):
Remove.
(parse-lambda-list, make-simple-lambda): New procedures.
(compile-lambda): Use `parse-lambda-list' and `make-simple-lambda'.
Set empty rest arguments to the empty list instead of `#nil'.
* test-suite/tests/elisp-compiler.test ("Lambda Expressions")["rest
argument"]: Use Elisp `null' instead of a Scheme equality check.
* module/language/elisp/compile-tree-il (compile-pair): Use `function'
to perform functional evaluation. Previously, if the operator of a
compound form was not a symbol, the operator would be evaluated as a
normal expression. This happened to work only because there is a
`lambda' macro. The compiler will now signal an error if the operator
is neither a function name nor a lambda expression.
* test-suite/tests/elisp-compiler.test ("Lambda Expressions")["optional
argument"]: Remove an erroneous use of `function' in the function
position.
* module/language/elisp/compile-tree-il.scm: (always-lexical): Remove.
All uses changed.
(with-added-symbols): Remove.
(compile-with-always-lexical): Remove.
(process-options!): Remove support for the `#:always-lexical' option.
* module/language/elisp/runtime/function-slot.scm: Update import and
re-export lists.
* test-suite/tests/elisp-compiler.test: Remove or update tests using
`with-always-lexical'.
* module/language/elisp/bindings.scm (global?): New function.
* module/language/elisp/compile-tree-il.scm (lexical-binding): New
variable.
(bind-lexically?): If lexical binding is enabled, bind lexically
unless a special binding exists.
(compile-%set-lexical-binding-mode): New function.
* module/language/elisp/lexer.scm (lexical-binding-regexp): New
variable.
(lex): Return a `set-lexical-binding-mode!' token if a comment is
found while reading the first line.
* module/language/elisp/parser.scm (get-expression): Add support for
`set-lexical-binding-mode!' tokens.
* module/language/elisp/runtime/function-slot.scm: Import and re-export
the `%set-lexical-binding-mode' special form.
* test-suite/tests/elisp-compiler.test
("Let and Let*")["lambda args inside lexical-let"]: Update.
* module/language/elisp/compile-tree-il.scm (generate-let)
(generate-let*, compile-lambda, compile-with-added-symbols)
(compile-progn, compile-if): Return nil if the form's body is empty.
* test-suite/tests/elisp-compiler.test ("Sequencing")["empty progn"]:
New test.
("Conditionals")["if with no else"]: New test.
("Let and Let*")["empty let, empty let*"]: New test.
("Lambda Expressions")["empty lambda"]: New test.
* test-suite/tests/elisp-compiler.test ("Exceptions")["catch and
throw"]: Use a freshly-consed object instead of a literal object. This
test previously assumed that similar literal objects are never
identical, which no longer true.
("Equivalence Predifcates")["eq"]: Likewise.
* module/language/elisp/compile-tree-il.scm (access-variable)
(reference-variable, set-variable!): Handle globally-bound non-special
variables.
(bind-lexically?): Create lexical bindings for flet and flet*.
* module/language/elisp/runtime.scm (reference-variable, set-variable!):
Handle globally-bound non-special variables.
(built-in-func): Set the variable directly instead of storing the
function in a fluid.
* module/language/elisp/runtime/subrs.scm (funcall): Call apply
directly.
* test-suite/tests/elisp-compiler.test ("Function Definitions")["flet
and flet*"]:
Signed-off-by: Andy Wingo <wingo@pobox.com>
* module/language/elisp/compile-tree-il.scm (reference-with-check)
(compile-without-void-checks, want-void-check?): Remove.
(compile-function, compile-pair): Use `reference-variable' instead of
`reference-with-check'.
(compile-defvar): Only set `sym' if `sym' is not bound to a bound
fluid, rather than requiring that its value be `void'.
(process-options!): Remove `#:disable-void-check' option handling.
* module/language/elisp/runtime.scm (void)
(reference-variable-with-check): Remove.
(ensure-fluid!): Use an undefined fluid as the initial value for
global variables.
* module/language/elisp/runtime/function-slot.scm (without-void-checks):
Don't import or re-export.
* module/language/elisp/runtime/macros.scm (prog1, cond, or, dolist):
Don't use `without-void-checks'.
* module/language/elisp/runtime/subrs.scm (symbol-value)
(symbol-function, apply): Use `reference-variable' instead of
`reference-variable-with-check'.
(makunbound, fmakunbound, boundp, fboundp): Unset the variable's fluid
(or the variable itself, if it isn't bound to a fluid).
* test-suite/tests/elisp-compiler.test ("Variable
Setting/Referencing")["disabled void check (all)", "disabled void
check (symbol list)", "without-void-checks"]: Remove.
Signed-off-by: Andy Wingo <wingo@pobox.com>
Use #{`}#, #{,}# and #{,@}# as the quasiquote, unquote and
unquote-splicing operators, respectively. Previously they were named
escaping.
* module/language/elisp/compile-tree-il.scm (unquote?): Change "\," to
"#{,}#".
(unquote-splicing): Change "\,@" to "#{,@}#".
(#{compile-`}#): Rename from #{compile-\`}#.
* module/language/elisp/runtime/function-slot.scm: Import #{compile-`}#
instead of #{compile-\`}#, and re-export as #{`}# instead of as
#{\`}#.
* module/language/elisp/parser.scm (quotation-symbols):
* test-suite/tests/elisp-compiler.test ("Eval", "Quotation"):
* test-suite/tests/elisp-reader.test ("Parser"): Change "\`", "\,", and
"\,@" to "#{`}#", "#{,}#" and "#{,@}#", respectively.
* test-suite/tests/elisp-compiler.test (compile-test): Add
`pass-if-equal' to the list of literal identifiers
Signed-off-by: Andy Wingo <wingo@pobox.com>
Affects so far let-bound symbols, lambda arguments to come in the future.
* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Add :always-lexical option.
* test-suite/tests/elisp-compiler.test: Test it.
* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Handle without-void-checks.
* test-suite/tests/elisp-compiler.test: Test it.
* module/language/elisp/README: Document new features.
* module/language/elisp/runtime/function-slot.scm: Implement funcall, apply and
eval by using the existing compiler code.
* test-suite/tests/elisp-compiler.test: Test those.
* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Implement guile-primitive.
* test-suite/tests/elisp-compiler.test: Switched a usage of guile-ref to
the now available guile-primitive.
* module/language/elisp/README: Document it.
* module/language/elisp/bindings.scm: New fields in bindings data structure
to keep track of lexical bindings for symbols.
* module/language/elisp/compile-tree-il.scm: Implement lexical-let(*).
* test-suite/tests/elisp-compiler.test: Test lexical scoping with lexical-let.
* module/language/elisp/README: Document the change.
* module/language/elisp/compile-tree-il.scm: Add disable-void-check option.
* test-suite/tests/elisp-compiler.test: Test it.
* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Implement flet and flet*.
* test-suite/tests/elisp-compiler.test: Test flet and flet*.
* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Moved ensure-fluid! to runtime function.
* module/language/elisp/runtime.scm: Runtime functions to support dynamic value access.
* module/language/elisp/runtime/function-slot.scm: Defined the built-ins.
* test-suite/tests/elisp-compiler.test: Test them.
* module/language/elisp/README: Document it and some further ideas written down.
* module/language/elisp/compile-tree-il.scm: Implement prog1, dolist.
* module/language/elisp/runtime/macro-slot.scm: prog2 and dotimes.
* test-suite/tests/elisp-compiler.test: Test prog1, prog2, dotimes, dolist.
* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Implement defmacro and expansion.
* module/language/elisp/runtime/macro-slot.scm: New module to keep definitions.
* test-suite/Makefile.am: Add elisp-compiler.test to list of tests.
* test-suite/tests/elisp-compiler.test: Basic macro tests.
* module/language/elisp/runtime/function-slot.scm: Fixed errors in number preds.
* test-suite/tests/elisp-compiler.test: Test built-ins already implemented.