1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-22 20:40:29 +02:00
Commit graph

598 commits

Author SHA1 Message Date
BT Templeton
03e00c5c9d emacs-compatible lexical binding
* 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.
2012-02-03 18:53:49 -05:00
BT Templeton
d4cb18ad9c remove `bind-arg-lexical?'
* module/language/elisp/compile-tree-il.scm (bind-arg-lexical?): Remove.
  All callers changed to use `bind-lexically?'.
2012-02-03 18:53:48 -05:00
BT Templeton
5fa5bf7d10 fix elisp `catch'
* module/language/elisp/boot.el (catch): Only catch exceptions of type
  `elisp-exception'.
2012-02-03 18:53:48 -05:00
BT Templeton
97d9da9a87 implement `throw' in elisp
* module/language/elisp/runtime/subrs.scm (throw): Rewrite in Elisp and
  move to...
* module/language/elisp/boot.el (throw): ...here.
2012-02-03 18:53:48 -05:00
BT Templeton
221dc803b0 rewrite `map-globals'
* module/language/elisp/bindings.scm (map-globals): Use `append-map' and
  `map' instead of explicit iteration with named `let'.
2012-02-03 18:53:48 -05:00
BT Templeton
d5da7661c8 use srfi-9 for elisp bindings records
* module/language/elisp/bindings.scm: Use `(srfi srfi-9)'.
  (bindings-type): Remove low-level record type definition and replace
  with...
  (bindings): ...this, an SRFI-9 record type. All uses changed.
  (mark-global-needed!): Rename to...
  (mark-global!): ...this. All callers changed.
  (map-globals-needed): Rename to...
  (map-globals): ...this. All callers changed.
2012-02-03 18:53:48 -05:00
BT Templeton
d5ac6923c3 fix compilation of elisp forms with empty bodies
* 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.
2012-02-03 18:53:48 -05:00
BT Templeton
b652e2b93f rewrite elisp macros in elisp
* module/language/elisp/runtime/macros.scm: Remove.
  (macro-lambda, macro-prog1, macro-prog2, macro-cond, macro-and,
  macro-or, macro-catch, macro-unwind-protect): Rewrite in Elisp and
  move to...
* module/language/elisp/boot.el (lambda, prog1, prog2, cond, and, or,
  catch, unwind-protect): ...here.
  (eval-and-compile): New macro.
  (funcall, fset, null, consp, listp, car, cdr, make-symbol-signal):
  Wrap definitions in an `eval-and-compile' form so that they can be
  used by the rewritten macros.
* module/language/elisp/runtime.scm: Remove `built-in-macro'.
* module/language/elisp/Makefile.am: Remove
  module/language/elisp/runtime/macros.scm from `ELISP_LANG_SOURCES'.
2012-02-03 18:53:48 -05:00
BT Templeton
80687f2e4b new elisp special form `eval-when-compile'
* module/language/elisp/compile-tree-il.scm (compile-eval-when-compile):
  New function.
* module/language/elisp/runtime/function-slot.scm: Update module
  definition.
2012-02-03 18:53:48 -05:00
BT Templeton
a338fa3d87 remove unnecessary elisp macros
* module/language/elisp/runtime/macros.scm (when, unless, dotimes)
  (dolist, pop, push): Remove. (They are not special forms in Emacs.)

* module/language/elisp/runtime/function-slot.scm: Update import and
  export lists.

* test-suite/tests/elisp-compiler.test ("Conditionals")["failing when"]
  ["succeeding when", "failing unless", "succeeding unless"]: Remove.
  ("Iteration")["dotimes", "dolist"]: Remove.
  ("List Built-Ins")["pop", "push"]: Remove.
2012-02-03 18:53:48 -05:00
BT Templeton
8f2f65668a new string' and mapcar' elisp subrs
* module/language/elisp/boot.el (string, mapcar): New functions.
2012-02-03 18:53:48 -05:00
BT Templeton
9b15703d79 rewrite elisp subrs in elisp
* module/language/elisp/runtime/subrs.scm (%, *, +, -, /=, 1+, 1-, <)
  (<=, =, >, >=, abs, append, atom, car, car-safe, cdr, cdr-safe, cons)
  (consp, eq, equal, fceiling, ffloor, float, floatp, fround, ftruncate)
  (funcall, integerp, length, list, listp, make-list, max, min, nlistp)
  (nth, nthcdr, null, numberp, reverse, setcar, setcdr, wholenump)
  (zerop): Rewrite in Elisp and move to...
* module/language/elisp/boot.el: ...here. Some functions have stricter
  type checking, and `elisp-bool' is not currently used (so some
  predicate functions now return `#f' instead of `#nil').
  (boundp, eval, fboundp, fmakunbound, fset, load, makunbound, set)
  (symbol-function, symbol-value, throw): New functions; they call their
  existing implementations in subrs.scm.
  (@): New macro.
* module/language/elisp/runtime.scm (built-in-func): Remove. All uses
  changed.
* module/language/elisp/runtime/function-slot.scm: Update module
  definition.
2012-02-03 18:53:48 -05:00
BT Templeton
b0a9f1b4b4 remove unnecessary elisp subrs
* module/language/elisp/runtime/subrs.scm (copy-tree, number-sequence):
  Remove. (They are not subrs in Emacs.)

* test-suite/tests/elisp-compiler.test ("List Built-ins")["copy-tree",
  "number-sequence"]: Remove.
2012-02-03 18:53:48 -05:00
BT Templeton
16254e5a09 atomp' -> atom'
* module/language/elisp/runtime/subrs.scm (atomp) Rename to...
  (atom): ...this. All callers changed.
2012-02-03 18:53:48 -05:00
BT Templeton
30439aa8bb use `nil?' for elisp conditionals
* module/language/elisp/compile-tree-il.scm (compile-if): Use the `nil?'
  primitive for conditionals.
2012-02-03 18:53:48 -05:00
BT Templeton
9348168ed5 add `nil?' primitive
* libguile/boolean.c (scm_nil_p): New function.

* libguile/vm-i-scheme.c (nilp, not_nilp):
* libguile/vm-i-system.c (br_if_nil, br_if_not_nil): New instructions.
  Renumber other ops.

* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Increment.

* module/language/assembly/compile-bytecode.scm (compile-bytecode): Add
  support for writing `br-if-nil' and `br-if-not-nil' instructions.

* module/language/assembly/disassemble.scm (code-annotation): Add
  `br-if-nil' and `br-if-not-nil' to the list of branch instructions.

* module/language/tree-il/compile-glil.scm: Add `nil?' to
  `*primcall-ops*'.
  (flatten): Use the new branch instructions for `nil?' conditionals.

* module/language/tree-il/primitives.scm: Add `nil?' to
  `*interesting-primitive-names*', `*effect-free-primitives', and
  `*effect+exception-free-primitives*'.
2012-02-03 18:53:38 -05:00
BT Templeton
6937c7aa8b load boot.el
* am/guilec: Add support for compiling Elisp files.
* module/Makefile.am: New variable ELISP_SOURCES.
* module/language/elisp/boot.el: New file.
* module/language/elisp/spec.scm: Load boot.el.
2011-11-22 15:06:12 -05:00
BT Templeton
5d351f0b9b remove void-checking cruft
* module/language/elisp/compile-tree-il.scm: Don't export
  `compile-without-void-checks', which was removed. Remove unused
  `disable-void-check' variable. Update comments.
2011-11-22 15:04:12 -05:00
Andy Wingo
fb135e12a4 when leaving a non-tail let, allow bound vals to be collected
* module/language/tree-il/compile-glil.scm (flatten-lambda-case): Clear
  lexical stack slots at the end of a non-tail let, letrec, or fix.
  Fixes http://debbugs.gnu.org/9900.

* test-suite/tests/gc.test ("gc"): Add test.
2011-11-09 23:45:53 +01:00
Andy Wingo
acdf4fcc05 simplify primitives.scm for dynwind
* module/language/tree-il/primitives.scm (*primitive-expand-table*):
  Remove a dynwind hack, as we have a good inliner now.
2011-11-09 16:54:43 +01:00
Andy Wingo
8ee0b28b4d peval: fix dynwind bug.
* module/language/tree-il/peval.scm (peval): The <dynwind> compiler will
  copy the winder and unwinder values, so make sure that they are
  constant, and if not, create lexical bindings.  Fixes
  http://debbugs.gnu.org/9844.

* test-suite/tests/tree-il.test ("partial evaluation"): Add a couple
  <dynwind> tests.
2011-11-09 16:54:30 +01:00
Andy Wingo
5e9b9059a3 fix <dynwind> serialization.
* module/language/tree-il.scm (unparse-tree-il): Fix <dynwind>
  serialization.
2011-11-09 16:54:30 +01:00
Andy Wingo
16d3e0133d peval: don't copy assigned lexical bindings
* module/language/tree-il/peval.scm (peval): Since constant-expression?
  is used to determine whether to copy values, return #f if any lexical
  is assigned.
2011-11-09 16:29:46 +01:00
Andy Wingo
aa9c198588 fix misallocation of some <fix> procedures
* module/language/tree-il/analyze.scm (analyze-lexicals): When stepping
  into a non-tail form, we know that labels allocation will be invalid,
  so use an empty labels set.  Fixes http://debbugs.gnu.org/9769.

* test-suite/tests/tree-il.test ("labels allocation"): Add a test.
2011-10-20 23:50:05 +02:00
Andy Wingo
30fcf30fcf fold constants with accessors
* module/language/tree-il/peval.scm (peval): Factor constant folding out
  to a helper.  Use it in the accessor case in addition to the normal
  effect-free-primitive case.

* test-suite/tests/tree-il.test: Add a test.
2011-10-10 22:34:48 +02:00
Andy Wingo
9be8a338ac recognize string primitives
* module/language/tree-il/primitives.scm
  (*interesting-primitive-names*): Add string?, string-length, and ref
  and set.
  (*primitive-accessors*): Add string-ref.
  (*effect-free-primitives*): Add string-length and string?
  (*effect+exception-free-primitives*): Add string?.
  (*singly-valued-primitives*): Add string-length and ref and set.
2011-10-10 20:19:07 +02:00
Andy Wingo
4bf9e92875 peval support for memq and memv
* module/language/tree-il/peval.scm (peval): Add special handlers for
  memq and memv, as inline.scm used to have.  This is important for
  `case' clauses.  It is very ugly, though.

* test-suite/tests/tree-il.test ("partial evaluation"): Add tests.
2011-10-10 14:43:37 +02:00
Andy Wingo
f26c3a93ec add accessor-primitive?, peval uses it
* module/language/tree-il/primitives.scm (*primitive-accessors*): New
  set of primitives: those that access mutable memory, but are otherwise
  pure.  Include bytevector references here.
  (accessor-primitive?): New public predicate.

* module/language/tree-il/peval.scm (peval): Refactor to distinguish
  constructor-primitive? from accessor-primitive?.
2011-10-10 14:43:37 +02:00
Andy Wingo
751708726b peval: visit operands on-demand, to inline mutually recursive bindings
This commit changes to use <operand> structures to hold the context
needed to visit lexical bindings lazily, in context, instead of eagerly
visiting them for value.  This laziness enables inlining of mutually
recursive bindings.

* module/language/tree-il/peval.scm (<var>): Remove comment about copy
  propagation having to run build-var-table; things don't work like that
  any more.
  (build-var-table): Build <var> entries for all variables, even
  unreferenced variables.
  (alpha-rename): Remove.  We will rename bindings on-demand now.

  (peval lookup-var): New helper, to fetch the <var> of a gensym.

  (peval fresh-gensyms): Fold here, under peval, and in it, handle
  updating the store to record a mapping between new names and <var>
  entries from the source program.

  (peval record-source-expression): Don't call build-var-table on the
  new expression, as alpha-renaming happens on-demand now.

  (peval prune-bindings): Rewrite to work with mutually-recursive
  bindings, while optionally preserving binding order.

  (peval extend-env): New helper.

  (peval loop): OK, here goes... Remove the `operand' context, as now we
  visit operands lazily.  Add a `call' context, which does not
  copy-propagate lambda expressions, used to residualize a call after
  aborting an inlining attempt.  Change the `env' to be a mapping of
  gensym to <operand>.  Instead of looking up the operand's binding then
  alpha-renaming it, just rely on the fact that visiting the operand
  will rename it if necessary.

  If we residualize a lexical, do so with the fresh name from the
  environment.  If we visit an operand and it doesn't turn out to be
  constant, we will never be able to copy it, and so cache that fact in
  the operand.  If we residualize a binding and we know what the value
  should be, record that binding so that prune-bindings won't have to
  visit it again.  If the operand folds to a constant, cache that too,
  to save effort when unrolling loops.

  For let, letrec, fix, and lambda-case, instead of visiting the
  bindings eagerly for value, simply record the source expressions and
  environments in an <operand> and rely on copy-propagation to visit
  them later in the right context.  In the case of letrec and fix, this
  allows mutually-recursive bindings to be inlined.

  Refactor folding of "constructors" (which still need renaming) to
  avoid visiting operands twice in some contexts.

  For applications, if we have to abort, process the procedure in call
  context, which allows some folding but avoids copying lambdas.  If we
  find a recursive procedure, mark intervening counters as recursive
  too, to allow for mutual recursion at the top level.

  For lambdas, if we are processing for value, record the source
  expression so we can detect recursion.  This was previously done in
  the lexical-ref copy propagator.

* test-suite/tests/tree-il.test ("partial evaluation"): Remove unused
  recursive lexicals in a couple of cases.  Add a couple test cases for
  pruning.  Add a few recursive binding cases.
2011-10-10 13:23:32 +02:00
Andy Wingo
580a59e75e peval: add operand structure
* module/language/tree-il/peval.scm (<operand>): Add operand structure,
  to be used by peval.
2011-10-10 13:23:32 +02:00
Andy Wingo
3066999174 peval: refactor logging
* module/language/tree-il/peval.scm: Make it easier to turn on logging.
2011-10-10 13:23:32 +02:00
Andy Wingo
41d43584f2 peval: logging
* module/language/tree-il/peval.scm: Define a quick and dirty
  infrastructure for logging.  Use it in peval.
2011-10-08 01:54:20 +02:00
Andy Wingo
1082cbba47 peval: bugfix in constant-expression?
* module/language/tree-il/peval.scm (constant-expression?): Correctly
  handle lambda-case alternates.
2011-10-07 11:06:56 +02:00
Andy Wingo
012492a7f1 optimizer verifies its output
* module/language/tree-il/optimize.scm: Verify the result of partial
  evaluation.
2011-10-07 11:06:19 +02:00
Andy Wingo
6d2d689721 add tree-il verifier
* module/Makefile.am: Add debug.scm.
* module/language/tree-il/debug.scm: New file, a verifier for tree-il.
2011-10-07 11:05:43 +02:00
Andy Wingo
904981ee41 peval refactor
* module/language/tree-il/peval.scm (peval): Refactor the for-value, etc
  helpers.
2011-10-06 13:44:05 +02:00
Andy Wingo
47974c308a comment peval.scm
* module/language/tree-il/peval.scm: Add comments.  Move alpha-rename
  later in the file.
2011-10-06 10:39:14 +02:00
Ludovic Courtès
16d50b8e89 peval: Recognize module-refs to primitives.
* module/language/tree-il/optimize.scm (peval): Handle module-refs to
  primitives.

* test-suite/tests/tree-il.test ("partial evaluation"): Add test, using
  `pmatch'.
2011-09-30 15:15:15 +02:00
Andy Wingo
b275fb2691 separate peval and a new canonicalization pass into their own modules
* module/language/tree-il/peval.scm: Move to its own file.  Remove the
  bits about <prompt> thunk-application bodies, as they are not
  optimizations, simply expectations of the compiler.  `canonicalize'
  handles that now.

* module/language/tree-il/optimize.scm: Use peval from its module.
  Don't call `inline!', as that's useless now.

* module/language/tree-il/canonicalize.scm: New file, implementing a
  pass that `compile-tree-il' runs on the result from the optimizer.
  The compiler currently expects a <let> form to have bindings, for
  example, and this pass turns a <let> without bindings into its body.

* module/language/tree-il/inline.scm: Deprecate, as `peval' does
  everything this function ever did.

* module/language/tree-il/compile-glil.scm: Canonicalize after
  optimizing.  This should allow us to skip the optimizer entirely, if
  we want.

* module/Makefile.am: Update and reorder a little bit.
2011-09-28 19:39:39 +02:00
Andy Wingo
0353a2d817 ((lambda ...) ...) fix
* module/language/tree-il/optimize.scm (peval): If it's a lambda in the
  operator position, inline without a nested counter, as it's not
  possible to increase code size.
2011-09-28 00:13:56 +02:00
Andy Wingo
40be30c974 peval: more effective binding pruning
* module/language/tree-il/optimize.scm (peval): Factor prune-bindings
  out of `let' and company.  Have it process unreferenced bindings in
  effect context instead of always residualizing non-constant
  expressions.
2011-09-28 00:13:56 +02:00
Andy Wingo
fc283c92cb don't propagate pure primcalls that might not type-check
* module/language/tree-il/optimize.scm (types-check?): New helper, to
  determine if a primcall will apply without throwing an exception.
  (peval): constant-expression? returns #f for expressions that don't
  types-check?.  Effect-free primitives that type-check are void.
2011-09-28 00:13:56 +02:00
Andy Wingo
b5ae223d12 fix unparse-tree-il of <dynset>
* module/language/tree-il.scm (unparse-tree-il): Fix printing of
  `dynset'.
2011-09-28 00:13:56 +02:00
Andy Wingo
1cc1c2d7e3 peval works on all expressions
* module/language/tree-il/optimize.scm (alpha-rename, peval): Add
  <dynset> cases.  Allow any kind of <application>.  Remove the `catch'
  wrapper as now peval handles all kinds of expressions.
2011-09-28 00:13:56 +02:00
Andy Wingo
6c4ffe2b25 peval: elide make-prompt-tag in effect context
* module/language/tree-il/optimize.scm (peval): Fix a duplicate
  traversal for constructors in effect or test context.  Add support for
  eliding make-prompt-tag.

* test-suite/tests/tree-il.test ("partial evaluation"): Update the test
  for make-prompt-tag elision.
2011-09-28 00:13:56 +02:00
Andy Wingo
ea726a53b2 peval: add support for <prompt> and <abort>
* module/language/tree-il/optimize.scm (alpha-rename, peval): Handle
  <prompt> and <abort>.  Attempt to remove the prompt if the tag is
  otherwise unreferenced.

* module/language/tree-il/primitives.scm (*primitive-constructors*): Add
  make-prompt-tag as a constructor.

* test-suite/tests/tree-il.test ("partial evaluation"): Add a test that
  an prompt whose tag is unreferenced is removed.
2011-09-28 00:13:55 +02:00
Andy Wingo
fbc9387f68 peval: fix algorithmic behavior of `cons'
* module/language/tree-il/optimize.scm (peval): Fix treatment of `cons'
  to not process the value twice, leading to n^2 work.  This prevented
  primitives.scm from compiling in a reasonable amount of time, because
  it contained a `(foo ... ,@bar) form that resulted in a long sequence
  of nested conses, and no effort counter was in place as it was not
  within an inlining attempt.
2011-09-28 00:13:55 +02:00
Andy Wingo
153ca1d239 peval: more strict accounting
* module/language/tree-il/optimize.scm (transfer!, make-nested-counter):
  (make-recursive-counter, peval): Limit the algorithm's time to be
  strictly O(N) by transferring effort and size counters of recursive
  inlining attempts from containing counters.

* test-suite/tests/tree-il.test ("partial evaluation"): Update
  expectations for the ((lambda (x) (x x)) (lambda (x) (x x))) case, as
  the new accounting policy will cause the entire inlining attempt to
  abort.
2011-09-27 00:21:16 +02:00
Andy Wingo
05c9389e3f peval: fix inlining of lambda* with #:optional
* module/language/tree-il/optimize.scm (peval): Fix calculation of how
  many init expressions to drop when inlining lambdas.

* test-suite/tests/tree-il.test ("partial evaluation"): Add tests.
2011-09-26 22:34:39 +02:00
Andy Wingo
ef6c0883c3 remove unused peval helpers
* module/language/tree-il/optimize.scm (peval): Remove a couple unused
  helpers.
2011-09-26 22:24:00 +02:00