2004-09-06 22:39:12 -04:00
|
|
|
! :folding=indent:collapseFolds=1:
|
|
|
|
|
|
|
|
! $Id$
|
|
|
|
!
|
|
|
|
! Copyright (C) 2004 Slava Pestov.
|
|
|
|
!
|
|
|
|
! Redistribution and use in source and binary forms, with or without
|
|
|
|
! modification, are permitted provided that the following conditions are met:
|
|
|
|
!
|
|
|
|
! 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
! this list of conditions and the following disclaimer.
|
|
|
|
!
|
|
|
|
! 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
! this list of conditions and the following disclaimer in the documentation
|
|
|
|
! and/or other materials provided with the distribution.
|
|
|
|
!
|
|
|
|
! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
IN: compiler
|
|
|
|
USE: combinators
|
|
|
|
USE: errors
|
2004-09-28 00:24:36 -04:00
|
|
|
USE: hashtables
|
2004-09-06 22:39:12 -04:00
|
|
|
USE: kernel
|
2004-09-08 02:31:03 -04:00
|
|
|
USE: lists
|
|
|
|
USE: logic
|
|
|
|
USE: math
|
|
|
|
USE: namespaces
|
|
|
|
USE: parser
|
2004-10-01 22:02:54 -04:00
|
|
|
USE: prettyprint
|
2004-09-08 02:31:03 -04:00
|
|
|
USE: stack
|
2004-10-03 16:07:48 -04:00
|
|
|
USE: stdio
|
2004-09-08 02:31:03 -04:00
|
|
|
USE: strings
|
|
|
|
USE: unparser
|
2004-09-06 22:39:12 -04:00
|
|
|
USE: vectors
|
2004-09-08 02:31:03 -04:00
|
|
|
USE: words
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-09-28 00:24:36 -04:00
|
|
|
! We use a hashtable "compiled-xts" that maps words to
|
|
|
|
! xt's that are currently being compiled. The commit-xt's word
|
|
|
|
! sets the xt of each word in the hashtable to the value in the
|
|
|
|
! hastable.
|
|
|
|
!
|
|
|
|
! This has the advantage that we can compile a word before the
|
|
|
|
! words it depends on and perform a fixup later; among other
|
|
|
|
! things this enables mutually recursive words.
|
|
|
|
|
|
|
|
SYMBOL: compiled-xts
|
|
|
|
|
|
|
|
: save-xt ( word -- )
|
|
|
|
cell compile-aligned
|
|
|
|
compiled-offset swap compiled-xts acons@ ;
|
|
|
|
|
2004-10-04 21:51:57 -04:00
|
|
|
: commit-xt ( xt word -- )
|
2004-10-16 21:55:13 -04:00
|
|
|
dup t "compiled" set-word-property set-word-xt ;
|
2004-10-04 21:51:57 -04:00
|
|
|
|
2004-09-28 00:24:36 -04:00
|
|
|
: commit-xts ( -- )
|
2004-10-04 21:51:57 -04:00
|
|
|
compiled-xts get [ unswons commit-xt ] each
|
2004-09-28 00:24:36 -04:00
|
|
|
compiled-xts off ;
|
|
|
|
|
|
|
|
: compiled-xt ( word -- xt )
|
2004-10-03 16:07:48 -04:00
|
|
|
dup compiled-xts get assoc [ nip ] [ word-xt ] ifte* ;
|
2004-09-28 00:24:36 -04:00
|
|
|
|
2004-10-04 21:51:57 -04:00
|
|
|
! "deferred-xts" is a list of [ where word relative ] pairs; the
|
|
|
|
! xt of word when its done compiling will be written to the
|
|
|
|
! offset, relative to the offset.
|
2004-09-28 00:24:36 -04:00
|
|
|
|
|
|
|
SYMBOL: deferred-xts
|
|
|
|
|
2004-10-03 16:07:48 -04:00
|
|
|
! Words being compiled are consed onto this list. When a word
|
|
|
|
! is encountered that has not been previously compiled, it is
|
|
|
|
! consed onto this list. Compilation stops when the list is
|
|
|
|
! empty.
|
|
|
|
|
|
|
|
SYMBOL: compile-words
|
|
|
|
|
2004-10-01 22:02:54 -04:00
|
|
|
: defer-xt ( word where relative -- )
|
|
|
|
#! After word is compiled, put its XT at where, relative.
|
|
|
|
3list deferred-xts cons@ ;
|
2004-09-28 00:24:36 -04:00
|
|
|
|
2004-10-04 21:51:57 -04:00
|
|
|
: compiling? ( word -- ? )
|
|
|
|
#! A word that is compiling or already compiled will not be
|
|
|
|
#! added to the list of words to be compiled.
|
|
|
|
dup compiled? [
|
|
|
|
drop t
|
|
|
|
] [
|
|
|
|
dup compile-words get contains? [
|
|
|
|
drop t
|
|
|
|
] [
|
|
|
|
compiled-xts get assoc
|
|
|
|
] ifte
|
|
|
|
] ifte ;
|
|
|
|
|
2004-10-01 22:02:54 -04:00
|
|
|
: fixup-deferred-xt ( word where relative -- )
|
2004-10-06 21:04:01 -04:00
|
|
|
rot dup compiling? [
|
2004-10-01 22:02:54 -04:00
|
|
|
compiled-xt swap - swap set-compiled-cell
|
|
|
|
] [
|
|
|
|
"Not compiled: " swap word-name cat2 throw
|
|
|
|
] ifte ;
|
2004-09-28 00:24:36 -04:00
|
|
|
|
|
|
|
: fixup-deferred-xts ( -- )
|
2004-10-01 22:02:54 -04:00
|
|
|
deferred-xts get [
|
|
|
|
uncons uncons car fixup-deferred-xt
|
|
|
|
] each
|
2004-09-28 00:24:36 -04:00
|
|
|
deferred-xts off ;
|
|
|
|
|
|
|
|
: postpone-word ( word -- )
|
2004-10-06 21:04:01 -04:00
|
|
|
dup compiling? [ drop ] [ compile-words unique@ ] ifte ;
|
2004-09-28 00:24:36 -04:00
|
|
|
|
|
|
|
! During compilation, these two variables store pending
|
|
|
|
! literals. Literals are either consumed at compile-time by
|
|
|
|
! words with special compilation behavior, or otherwise they are
|
|
|
|
! compiled into code that pushes them.
|
|
|
|
|
|
|
|
SYMBOL: compile-datastack
|
|
|
|
SYMBOL: compile-callstack
|
|
|
|
|
2004-09-07 01:34:10 -04:00
|
|
|
: pop-literal ( -- obj )
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-datastack get vector-pop ;
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: immediate? ( obj -- ? )
|
|
|
|
#! fixnums and f have a pointerless representation, and
|
|
|
|
#! are compiled immediately. Everything else can be moved
|
|
|
|
#! by GC, and is indexed through a table.
|
|
|
|
dup fixnum? swap f eq? or ;
|
|
|
|
|
2004-09-06 22:39:12 -04:00
|
|
|
: compile-literal ( obj -- )
|
2004-09-08 02:31:03 -04:00
|
|
|
dup immediate? [
|
2004-09-26 20:16:02 -04:00
|
|
|
address LITERAL
|
2004-09-06 22:39:12 -04:00
|
|
|
] [
|
|
|
|
intern-literal [LITERAL]
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: commit-literals ( -- )
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-datastack get
|
2004-09-08 02:31:03 -04:00
|
|
|
dup vector-empty? [
|
|
|
|
drop
|
|
|
|
] [
|
|
|
|
dup [ compile-literal ] vector-each
|
|
|
|
0 swap set-vector-length
|
|
|
|
] ifte ;
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-09-28 00:24:36 -04:00
|
|
|
: postpone-literal ( obj -- )
|
2004-09-07 01:34:10 -04:00
|
|
|
#! Literals are not compiled immediately, so that words like
|
|
|
|
#! ifte with special compilation behavior can work.
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-datastack get vector-push ;
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: tail? ( -- ? )
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-callstack get vector-empty? ;
|
2004-09-08 02:31:03 -04:00
|
|
|
|
2004-09-07 01:34:10 -04:00
|
|
|
: compile-simple-word ( word -- )
|
|
|
|
#! Compile a JMP at the end (tail call optimization)
|
2004-10-01 22:02:54 -04:00
|
|
|
dup postpone-word
|
|
|
|
commit-literals tail? [ JUMP ] [ CALL ] ifte
|
|
|
|
compiled-offset defer-xt ;
|
2004-09-07 01:34:10 -04:00
|
|
|
|
|
|
|
: compile-word ( word -- )
|
|
|
|
#! If a word has a compiling property, then it has special
|
|
|
|
#! compilation behavior.
|
2004-09-28 00:24:36 -04:00
|
|
|
dup "compiling" word-property dup [
|
2004-09-07 01:34:10 -04:00
|
|
|
nip call
|
|
|
|
] [
|
|
|
|
drop compile-simple-word
|
|
|
|
] ifte ;
|
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: begin-compiling-quot ( quot -- )
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-callstack get vector-push ;
|
2004-09-08 02:31:03 -04:00
|
|
|
|
|
|
|
: end-compiling-quot ( -- )
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-callstack get vector-pop drop ;
|
2004-09-08 02:31:03 -04:00
|
|
|
|
|
|
|
: compiling ( quot -- )
|
|
|
|
#! Called on each iteration of compile-loop, with the
|
|
|
|
#! remaining quotation.
|
2004-09-06 22:39:12 -04:00
|
|
|
[
|
2004-09-28 00:24:36 -04:00
|
|
|
compile-callstack get
|
2004-09-08 02:31:03 -04:00
|
|
|
dup vector-length pred
|
|
|
|
swap set-vector-nth
|
|
|
|
] [
|
|
|
|
end-compiling-quot
|
|
|
|
] ifte* ;
|
|
|
|
|
|
|
|
: compile-atom ( obj -- )
|
2004-09-28 00:24:36 -04:00
|
|
|
dup word? [ compile-word ] [ postpone-literal ] ifte ;
|
2004-09-06 22:39:12 -04:00
|
|
|
|
|
|
|
: compile-loop ( quot -- )
|
2004-09-08 02:31:03 -04:00
|
|
|
[
|
|
|
|
uncons dup compiling swap compile-atom compile-loop
|
|
|
|
] when* ;
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: compile-quot ( quot -- )
|
|
|
|
[
|
|
|
|
dup begin-compiling-quot compile-loop commit-literals
|
|
|
|
] when* ;
|
|
|
|
|
|
|
|
: with-compiler ( quot -- )
|
2004-09-06 22:39:12 -04:00
|
|
|
[
|
2004-09-28 00:24:36 -04:00
|
|
|
10 <vector> compile-datastack set
|
|
|
|
10 <vector> compile-callstack set
|
2004-09-08 02:31:03 -04:00
|
|
|
call
|
2004-09-28 00:24:36 -04:00
|
|
|
fixup-deferred-xts
|
|
|
|
commit-xts
|
2004-09-06 22:39:12 -04:00
|
|
|
] with-scope ;
|
|
|
|
|
2004-09-28 00:24:36 -04:00
|
|
|
: (compile) ( word -- )
|
|
|
|
#! Should be called inside the with-compiler scope.
|
2004-10-17 19:01:16 -04:00
|
|
|
dup save-xt word-parameter compile-quot RET ;
|
2004-09-08 02:31:03 -04:00
|
|
|
|
2004-09-28 00:24:36 -04:00
|
|
|
: compile-postponed ( -- )
|
|
|
|
compile-words get [
|
|
|
|
uncons compile-words set (compile) compile-postponed
|
|
|
|
] when* ;
|
2004-09-08 02:31:03 -04:00
|
|
|
|
2004-09-06 22:39:12 -04:00
|
|
|
: compile ( word -- )
|
2004-09-28 00:24:36 -04:00
|
|
|
[ postpone-word compile-postponed ] with-compiler ;
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-11-21 21:16:16 -05:00
|
|
|
: compiled
|
|
|
|
#! Compile the most recently defined word.
|
|
|
|
word compile ; parsing
|