factor/library/tools/interpreter.factor

113 lines
2.9 KiB
Factor
Raw Normal View History

2006-05-15 01:49:07 -04:00
! Copyright (C) 2004, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: interpreter
2006-05-16 16:50:51 -04:00
USING: errors generic io kernel kernel-internals math
namespaces prettyprint sequences strings vectors words ;
2006-03-25 01:06:52 -05:00
! A Factor interpreter written in Factor. It can transfer the
! continuation to and from the primary interpreter. Used by
! compiler for partial evaluation, also by the walker.
2006-05-15 01:37:11 -04:00
! Meta-stacks;
SYMBOL: meta-d
2005-04-06 21:41:49 -04:00
: push-d meta-d get push ;
: pop-d meta-d get pop ;
: peek-d meta-d get peek ;
2006-05-15 01:37:11 -04:00
SYMBOL: meta-r
: push-r meta-r get push ;
: pop-r meta-r get pop ;
: peek-r meta-r get peek ;
SYMBOL: meta-c
2006-05-15 01:37:11 -04:00
: push-c meta-c get push ;
: pop-c meta-c get pop ;
: peek-c meta-c get peek ;
SYMBOL: meta-name
SYMBOL: meta-catch
! Call frame
SYMBOL: callframe
SYMBOL: callframe-scan
SYMBOL: callframe-end
! Callframe.
: up ( -- )
pop-c callframe-end set
pop-c callframe-scan set
pop-c callframe set ;
: done? ( -- ? ) callframe-scan get callframe-end get >= ;
: next ( -- obj )
done? [
up next
] [
callframe-scan get callframe get nth callframe-scan inc
] if ;
2005-06-15 23:27:28 -04:00
: meta-interp ( -- interp )
2006-05-15 01:37:11 -04:00
meta-d get meta-r get meta-c get
meta-name get meta-catch get <continuation> ;
2005-06-15 23:27:28 -04:00
: set-meta-interp ( interp -- )
2006-05-15 01:37:11 -04:00
>continuation<
meta-catch set
meta-name set
meta-c set
meta-r set
meta-d set ;
2005-06-15 23:27:28 -04:00
: save-callframe ( -- )
callframe get push-c
callframe-scan get push-c
callframe-end get push-c ;
: (meta-call) ( quot -- )
dup callframe set
length callframe-end set
0 callframe-scan set ;
: meta-call ( quot -- )
#! Note we do tail call optimization here.
done? [ save-callframe ] unless (meta-call) ;
: host-word ( word -- )
[
[
swap , \ continuation , , \ continue-with ,
] [ ] make dup push-c 0 push-c length push-c
meta-interp continue
] callcc1 set-meta-interp drop ;
2005-09-28 20:09:10 -04:00
GENERIC: do-1 ( object -- )
M: word do-1 ( word -- )
dup "meta-word" word-prop [ call ] [ host-word ] ?if ;
M: wrapper do-1 ( wrapper -- ) wrapped push-d ;
M: object do-1 ( object -- ) push-d ;
GENERIC: do ( obj -- )
M: word do ( word -- )
dup "meta-word" word-prop [
2005-01-02 23:57:54 -05:00
call
] [
dup compound? [ word-def meta-call ] [ host-word ] if
2005-09-24 15:21:17 -04:00
] ?if ;
2005-09-28 20:09:10 -04:00
M: object do ( object -- ) do-1 ;
2005-03-10 17:57:22 -05:00
2005-12-03 17:34:59 -05:00
! The interpreter loses object identity of the name and catch
! stacks -- they are copied after each step -- so we execute
2006-06-04 16:20:40 -04:00
! these atomically and don't allow stepping into these words
2005-12-03 17:34:59 -05:00
\ >n [ \ >n host-word ] "meta-word" set-word-prop
\ n> [ \ n> host-word ] "meta-word" set-word-prop
\ >c [ \ >c host-word ] "meta-word" set-word-prop
\ c> [ \ c> host-word ] "meta-word" set-word-prop
2005-09-28 20:09:10 -04:00
\ call [ pop-d meta-call ] "meta-word" set-word-prop
\ execute [ pop-d do ] "meta-word" set-word-prop
\ if [ pop-d pop-d pop-d [ nip ] [ drop ] if meta-call ] "meta-word" set-word-prop
\ dispatch [ pop-d pop-d swap nth meta-call ] "meta-word" set-word-prop