2005-02-17 16:10:35 -05:00
|
|
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2004-11-03 23:35:36 -05:00
|
|
|
IN: interpreter
|
2005-02-17 16:10:35 -05:00
|
|
|
USING: errors kernel lists math namespaces prettyprint stdio
|
|
|
|
strings vectors words ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
! A Factor interpreter written in Factor. Used by compiler for
|
|
|
|
! partial evaluation, also for trace and step.
|
|
|
|
|
|
|
|
! Meta-stacks
|
|
|
|
SYMBOL: meta-r
|
|
|
|
: push-r meta-r get vector-push ;
|
|
|
|
: pop-r meta-r get vector-pop ;
|
|
|
|
SYMBOL: meta-d
|
|
|
|
: push-d meta-d get vector-push ;
|
|
|
|
: pop-d meta-d get vector-pop ;
|
2004-12-26 01:42:09 -05:00
|
|
|
: peek-d meta-d get vector-peek ;
|
2005-02-17 16:10:35 -05:00
|
|
|
: peek-next-d meta-d get [ vector-length 2 - ] keep vector-nth ;
|
2004-11-03 23:35:36 -05:00
|
|
|
SYMBOL: meta-n
|
|
|
|
SYMBOL: meta-c
|
|
|
|
|
|
|
|
! Call frame
|
|
|
|
SYMBOL: meta-cf
|
|
|
|
|
|
|
|
: init-interpreter ( -- )
|
|
|
|
10 <vector> meta-r set
|
|
|
|
10 <vector> meta-d set
|
2004-11-21 19:27:18 -05:00
|
|
|
namestack meta-n set
|
2004-11-20 16:57:01 -05:00
|
|
|
f meta-c set
|
2004-11-03 23:35:36 -05:00
|
|
|
f meta-cf set ;
|
|
|
|
|
|
|
|
: copy-interpreter ( -- )
|
|
|
|
#! Copy interpreter state from containing namespaces.
|
2005-01-28 23:55:22 -05:00
|
|
|
meta-r [ clone ] change
|
|
|
|
meta-d [ clone ] change
|
2004-12-04 15:10:46 -05:00
|
|
|
meta-n [ ] change
|
|
|
|
meta-c [ ] change ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
: done-cf? ( -- ? )
|
|
|
|
meta-cf get not ;
|
|
|
|
|
|
|
|
: done? ( -- ? )
|
2005-01-14 12:01:48 -05:00
|
|
|
done-cf? meta-r get vector-length 0 = and ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
! Callframe.
|
|
|
|
: up ( -- )
|
|
|
|
pop-r meta-cf set ;
|
|
|
|
|
|
|
|
: next ( -- obj )
|
2004-12-10 21:39:27 -05:00
|
|
|
meta-cf get [ meta-cf [ uncons ] change ] [ up next ] ifte ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
: host-word ( word -- )
|
|
|
|
#! Swap in the meta-interpreter's stacks, execute the word,
|
|
|
|
#! swap in the old stacks. This is so messy.
|
|
|
|
push-d datastack push-d
|
|
|
|
meta-d get set-datastack
|
|
|
|
>r execute datastack r> tuck vector-push
|
|
|
|
set-datastack meta-d set ;
|
|
|
|
|
|
|
|
: meta-call ( quot -- )
|
|
|
|
#! Note we do tail call optimization here.
|
2004-12-04 15:10:46 -05:00
|
|
|
meta-cf [ [ push-r ] when* ] change ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
: meta-word ( word -- )
|
2005-03-05 14:45:23 -05:00
|
|
|
dup "meta-word" word-prop [
|
2005-01-02 23:57:54 -05:00
|
|
|
call
|
2004-11-03 23:35:36 -05:00
|
|
|
] [
|
2005-03-05 14:45:23 -05:00
|
|
|
dup compound? [ word-def meta-call ] [ host-word ] ifte
|
2005-01-02 23:57:54 -05:00
|
|
|
] ?ifte ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
: do ( obj -- )
|
|
|
|
dup word? [ meta-word ] [ push-d ] ifte ;
|
|
|
|
|
2004-12-17 21:46:19 -05:00
|
|
|
: meta-word-1 ( word -- )
|
2005-03-05 14:45:23 -05:00
|
|
|
dup "meta-word" word-prop [ call ] [ host-word ] ?ifte ;
|
2004-12-17 21:46:19 -05:00
|
|
|
|
|
|
|
: do-1 ( obj -- )
|
|
|
|
dup word? [ meta-word-1 ] [ push-d ] ifte ;
|
|
|
|
|
2005-03-03 20:43:55 -05:00
|
|
|
: interpret ( quot -- )
|
2004-11-03 23:35:36 -05:00
|
|
|
#! The quotation is called with each word as its executed.
|
2005-03-03 20:43:55 -05:00
|
|
|
done? [ drop ] [ [ next swap call ] keep interpret ] ifte ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
2005-03-03 20:43:55 -05:00
|
|
|
: run ( -- ) [ do ] interpret ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
|
|
|
: set-meta-word ( word quot -- )
|
2005-03-05 14:45:23 -05:00
|
|
|
"meta-word" set-word-prop ;
|
2004-11-03 23:35:36 -05:00
|
|
|
|
2005-01-28 23:55:22 -05:00
|
|
|
\ datastack [ meta-d get clone push-d ] set-meta-word
|
|
|
|
\ set-datastack [ pop-d clone meta-d set ] set-meta-word
|
2004-11-03 23:35:36 -05:00
|
|
|
\ >r [ pop-d push-r ] set-meta-word
|
|
|
|
\ r> [ pop-r push-d ] set-meta-word
|
2005-01-28 23:55:22 -05:00
|
|
|
\ callstack [ meta-r get clone push-d ] set-meta-word
|
|
|
|
\ set-callstack [ pop-d clone meta-r set ] set-meta-word
|
2004-11-20 16:57:01 -05:00
|
|
|
\ namestack [ meta-n get push-d ] set-meta-word
|
|
|
|
\ set-namestack [ pop-d meta-n set ] set-meta-word
|
|
|
|
\ catchstack [ meta-c get push-d ] set-meta-word
|
|
|
|
\ set-catchstack [ pop-d meta-c set ] set-meta-word
|
2004-11-03 23:35:36 -05:00
|
|
|
\ call [ pop-d meta-call ] set-meta-word
|
|
|
|
\ execute [ pop-d meta-word ] set-meta-word
|
|
|
|
\ ifte [ pop-d pop-d pop-d [ nip ] [ drop ] ifte meta-call ] set-meta-word
|