diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-03-27 06:36:36 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-03-27 06:36:36 -0700 |
commit | b4045996e6ba899a982561d38467f3f118624a12 (patch) | |
tree | 894373cb7d980088e2285dad64df78c26b7c32a2 | |
parent | d0b116d378634d1b33d85585afa45a2768d7c972 (diff) | |
download | txr-b4045996e6ba899a982561d38467f3f118624a12.tar.gz txr-b4045996e6ba899a982561d38467f3f118624a12.tar.bz2 txr-b4045996e6ba899a982561d38467f3f118624a12.zip |
compiler: recognize call and apply forms.
* share/txr/stdlib/compiler.tl (compiler): New slots, gcallop
and callop.
(compiler comp-fun-form): Restructured to handle apply and
call forms, turning them into better code, exploiting the
call, gcall, apply and gapply instructions.
(compiler comp-call): Take opcode argument so apply calls can
be handled.
-rw-r--r-- | share/txr/stdlib/compiler.tl | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl index 00fcaf65..7418ac93 100644 --- a/share/txr/stdlib/compiler.tl +++ b/share/txr/stdlib/compiler.tl @@ -115,7 +115,9 @@ (data (hash :eql-based)) (fidx (hash :eql-based)) (ftab (hash :eql-based)) - last-form) + last-form + (:static gcallop (relate '(apply usr:apply call) '(gapply gapply gcall))) + (:static callop (relate '(apply usr:apply call) '(apply apply call)))) (defmeth compiler get-dreg (me atom) (iflet ((dreg [me.dreg atom])) @@ -764,18 +766,28 @@ me.(compile oreg env (expand qexp)))) (defmeth compiler comp-fun-form (me oreg env sym args) - (condlet - (((fbind env.(lookup-fun sym))) - me.(comp-call-impl oreg env 'call fbind.loc args)) - (((fidx me.(get-fidx sym))) - (caseq sym - (call me.(comp-call oreg env args)) - (t me.(comp-call-impl oreg env 'gcall fidx args)))))) - -(defmeth compiler comp-call (me oreg env args) + (caseql sym + ((call apply usr:apply) + (let ((gopcode [me.gcallop sym]) + (opcode [me.callop sym])) + (tree-case (car args) + ((op arg) (if (and (eq op 'fun) (bindable arg)) + (let ((fbind env.(lookup-fun arg))) + me.(comp-call-impl oreg env (if fbind opcode gopcode) + (if fbind fbind.loc me.(get-fidx arg)) + (cdr args))) + :)) + (arg me.(comp-call oreg env + (if (eq sym 'usr:apply) 'apply sym) args))))) + (t (let ((fbind env.(lookup-fun sym))) + me.(comp-call-impl oreg env (if fbind 'call 'gcall) + (if fbind fbind.loc me.(get-fidx sym)) + args))))) + +(defmeth compiler comp-call (me oreg env opcode args) (tree-bind (fform . fargs) args (let* ((ffrag me.(compile oreg env fform)) - (cfrag me.(comp-call-impl oreg env 'call ffrag.oreg fargs))) + (cfrag me.(comp-call-impl oreg env opcode ffrag.oreg fargs))) (new (frag cfrag.oreg (append ffrag.code cfrag.code) |