predicate metaclass; prettyprint, see, unparse, ' and other words are now generic
parent
24ea465e4b
commit
7a31260d23
|
@ -35,8 +35,7 @@
|
||||||
|
|
||||||
+ listener/plugin:
|
+ listener/plugin:
|
||||||
|
|
||||||
- unterminated ; -- NPE
|
- sidekick: still parsing too much
|
||||||
- no USE:'s wrong place
|
|
||||||
- errors don't always disappear
|
- errors don't always disappear
|
||||||
- console: wrong history
|
- console: wrong history
|
||||||
- listener: if too many things popped off the stack, complain
|
- listener: if too many things popped off the stack, complain
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
IN: image
|
IN: image
|
||||||
USE: errors
|
USE: errors
|
||||||
|
USE: generic
|
||||||
USE: hashtables
|
USE: hashtables
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
|
@ -128,6 +129,9 @@ SYMBOL: boot-quot
|
||||||
: heap-size-offset 5 ;
|
: heap-size-offset 5 ;
|
||||||
: header-size 6 ;
|
: header-size 6 ;
|
||||||
|
|
||||||
|
GENERIC: ' ( obj -- ptr )
|
||||||
|
#! Write an object to the image.
|
||||||
|
|
||||||
( Allocator )
|
( Allocator )
|
||||||
|
|
||||||
: here ( -- size )
|
: here ( -- size )
|
||||||
|
@ -149,11 +153,11 @@ SYMBOL: boot-quot
|
||||||
|
|
||||||
( Fixnums )
|
( Fixnums )
|
||||||
|
|
||||||
: emit-fixnum ( n -- tagged ) fixnum-tag immediate ;
|
M: fixnum ' ( n -- tagged ) fixnum-tag immediate ;
|
||||||
|
|
||||||
( Bignums )
|
( Bignums )
|
||||||
|
|
||||||
: emit-bignum ( bignum -- tagged )
|
M: bignum ' ( bignum -- tagged )
|
||||||
#! This can only emit 0, -1 and 1.
|
#! This can only emit 0, -1 and 1.
|
||||||
object-tag here-as >r
|
object-tag here-as >r
|
||||||
bignum-type >header emit
|
bignum-type >header emit
|
||||||
|
@ -170,11 +174,16 @@ SYMBOL: boot-quot
|
||||||
: t,
|
: t,
|
||||||
object-tag here-as "t" set
|
object-tag here-as "t" set
|
||||||
t-type >header emit
|
t-type >header emit
|
||||||
0 emit-fixnum emit ;
|
0 ' emit ;
|
||||||
|
|
||||||
: 0, 0 emit-bignum drop ;
|
M: t ' ( obj -- ptr ) drop "t" get ;
|
||||||
: 1, 1 emit-bignum drop ;
|
M: f ' ( obj -- ptr )
|
||||||
: -1, -1 emit-bignum drop ;
|
#! f is #define F RETAG(0,OBJECT_TYPE)
|
||||||
|
drop object-tag ;
|
||||||
|
|
||||||
|
: 0, 0 >bignum ' drop ;
|
||||||
|
: 1, 1 >bignum ' drop ;
|
||||||
|
: -1, -1 >bignum ' drop ;
|
||||||
|
|
||||||
( Beginning of the image )
|
( Beginning of the image )
|
||||||
! The image proper begins with the header, then T,
|
! The image proper begins with the header, then T,
|
||||||
|
@ -209,14 +218,12 @@ SYMBOL: boot-quot
|
||||||
dup word? [ fixup-word ] when
|
dup word? [ fixup-word ] when
|
||||||
] vector-map image set ;
|
] vector-map image set ;
|
||||||
|
|
||||||
: emit-word ( word -- pointer )
|
M: word ' ( word -- pointer )
|
||||||
dup pooled-object dup [ nip ] [ drop ] ifte ;
|
dup pooled-object dup [ nip ] [ drop ] ifte ;
|
||||||
|
|
||||||
( Conses )
|
( Conses )
|
||||||
|
|
||||||
DEFER: '
|
M: cons ' ( c -- tagged )
|
||||||
|
|
||||||
: emit-cons ( c -- tagged )
|
|
||||||
uncons ' swap '
|
uncons ' swap '
|
||||||
cons-tag here-as
|
cons-tag here-as
|
||||||
-rot emit emit ;
|
-rot emit emit ;
|
||||||
|
@ -239,7 +246,7 @@ DEFER: '
|
||||||
: pack-string ( string -- )
|
: pack-string ( string -- )
|
||||||
char tuck swap split-n (pack-string) ;
|
char tuck swap split-n (pack-string) ;
|
||||||
|
|
||||||
: (emit-string) ( string -- )
|
: emit-string ( string -- )
|
||||||
object-tag here-as swap
|
object-tag here-as swap
|
||||||
string-type >header emit
|
string-type >header emit
|
||||||
dup str-length emit
|
dup str-length emit
|
||||||
|
@ -247,13 +254,13 @@ DEFER: '
|
||||||
pack-string
|
pack-string
|
||||||
pad ;
|
pad ;
|
||||||
|
|
||||||
: emit-string ( string -- pointer )
|
M: string ' ( string -- pointer )
|
||||||
#! We pool strings so that each string is only written once
|
#! We pool strings so that each string is only written once
|
||||||
#! to the image
|
#! to the image
|
||||||
dup pooled-object dup [
|
dup pooled-object dup [
|
||||||
nip
|
nip
|
||||||
] [
|
] [
|
||||||
drop dup (emit-string) dup >r pool-object r>
|
drop dup emit-string dup >r pool-object r>
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
( Word definitions )
|
( Word definitions )
|
||||||
|
@ -300,7 +307,7 @@ DEFER: '
|
||||||
( elements -- ) [ emit ] each
|
( elements -- ) [ emit ] each
|
||||||
pad r> ;
|
pad r> ;
|
||||||
|
|
||||||
: emit-vector ( vector -- pointer )
|
M: vector ' ( vector -- pointer )
|
||||||
dup vector>list emit-array swap vector-length
|
dup vector>list emit-array swap vector-length
|
||||||
object-tag here-as >r
|
object-tag here-as >r
|
||||||
vector-type >header emit
|
vector-type >header emit
|
||||||
|
@ -308,22 +315,6 @@ DEFER: '
|
||||||
emit ( array ptr )
|
emit ( array ptr )
|
||||||
pad r> ;
|
pad r> ;
|
||||||
|
|
||||||
( Cross-compile a reference to an object )
|
|
||||||
|
|
||||||
: ' ( obj -- pointer )
|
|
||||||
[
|
|
||||||
[ fixnum? ] [ emit-fixnum ]
|
|
||||||
[ bignum? ] [ emit-bignum ]
|
|
||||||
[ word? ] [ emit-word ]
|
|
||||||
[ cons? ] [ emit-cons ]
|
|
||||||
[ string? ] [ emit-string ]
|
|
||||||
[ vector? ] [ emit-vector ]
|
|
||||||
[ t = ] [ drop "t" get ]
|
|
||||||
! f is #define F RETAG(0,OBJECT_TYPE)
|
|
||||||
[ f = ] [ drop object-tag ]
|
|
||||||
[ drop t ] [ "Cannot cross-compile: " swap cat2 throw ]
|
|
||||||
] cond ;
|
|
||||||
|
|
||||||
( End of the image )
|
( End of the image )
|
||||||
|
|
||||||
: vocabularies, ( -- )
|
: vocabularies, ( -- )
|
||||||
|
|
|
@ -35,9 +35,34 @@ USE: parser
|
||||||
USE: strings
|
USE: strings
|
||||||
USE: words
|
USE: words
|
||||||
USE: vectors
|
USE: vectors
|
||||||
|
USE: math
|
||||||
|
|
||||||
! A simple single-dispatch generic word system.
|
! A simple single-dispatch generic word system.
|
||||||
|
|
||||||
|
: predicate-word ( word -- word )
|
||||||
|
word-name "?" cat2 "in" get create ;
|
||||||
|
|
||||||
|
! Terminology:
|
||||||
|
! - type: a datatype built in to the runtime, eg fixnum, word
|
||||||
|
! cons. All objects have exactly one type, new types cannot be
|
||||||
|
! defined, and types are disjoint.
|
||||||
|
! - class: a user defined way of differentiating objects, either
|
||||||
|
! based on type, or some combination of type, predicate, or
|
||||||
|
! method map.
|
||||||
|
! - traits: a hashtable has traits of its traits slot is set to
|
||||||
|
! a hashtable mapping selector names to method definitions.
|
||||||
|
! The class of an object with traits is determined by the object
|
||||||
|
! identity of the traits method map.
|
||||||
|
! - metaclass: a metaclass is a symbol with a handful of word
|
||||||
|
! properties: "define-method" "builtin-types"
|
||||||
|
|
||||||
|
: metaclass ( class -- metaclass )
|
||||||
|
"metaclass" word-property ;
|
||||||
|
|
||||||
|
: builtin-supertypes ( class -- list )
|
||||||
|
#! A list of builtin supertypes of the class.
|
||||||
|
dup metaclass "builtin-supertypes" word-property call ;
|
||||||
|
|
||||||
! Catch-all metaclass for providing a default method.
|
! Catch-all metaclass for providing a default method.
|
||||||
SYMBOL: object
|
SYMBOL: object
|
||||||
|
|
||||||
|
@ -51,24 +76,41 @@ SYMBOL: object
|
||||||
: define-object ( generic definition -- )
|
: define-object ( generic definition -- )
|
||||||
<vtable> define-generic drop ;
|
<vtable> define-generic drop ;
|
||||||
|
|
||||||
object [ define-object ] "define-method" set-word-property
|
object object "metaclass" set-word-property
|
||||||
|
|
||||||
: predicate-word ( word -- word )
|
object [
|
||||||
word-name "?" cat2 "in" get create ;
|
define-object
|
||||||
|
] "define-method" set-word-property
|
||||||
|
|
||||||
: builtin-predicate ( type# symbol -- )
|
object [
|
||||||
predicate-word swap [ swap type eq? ] cons define-compound ;
|
drop num-types count
|
||||||
|
] "builtin-supertypes" set-word-property
|
||||||
|
|
||||||
|
! Builtin metaclass for builtin types: fixnum, word, cons, etc.
|
||||||
|
SYMBOL: builtin
|
||||||
|
|
||||||
: add-method ( definition type vtable -- )
|
: add-method ( definition type vtable -- )
|
||||||
>r "builtin-type" word-property r> set-vector-nth ;
|
>r "builtin-type" word-property r> set-vector-nth ;
|
||||||
|
|
||||||
: define-builtin ( type generic definition -- )
|
: builtin-method ( type generic definition -- )
|
||||||
-rot "vtable" word-property add-method ;
|
-rot "vtable" word-property add-method ;
|
||||||
|
|
||||||
|
builtin [ builtin-method ] "define-method" set-word-property
|
||||||
|
|
||||||
|
builtin [
|
||||||
|
"builtin-type" word-property unit
|
||||||
|
] "builtin-supertypes" set-word-property
|
||||||
|
|
||||||
|
: builtin-predicate ( type# symbol -- word )
|
||||||
|
predicate-word [
|
||||||
|
swap [ swap type eq? ] cons define-compound
|
||||||
|
] keep ;
|
||||||
|
|
||||||
: builtin-class ( number type -- )
|
: builtin-class ( number type -- )
|
||||||
dup undefined? [ dup define-symbol ] when
|
dup undefined? [ dup define-symbol ] when
|
||||||
2dup builtin-predicate
|
2dup builtin-predicate
|
||||||
dup [ define-builtin ] "define-method" set-word-property
|
dupd "predicate" set-word-property
|
||||||
|
dup builtin "metaclass" set-word-property
|
||||||
swap "builtin-type" set-word-property ;
|
swap "builtin-type" set-word-property ;
|
||||||
|
|
||||||
: BUILTIN:
|
: BUILTIN:
|
||||||
|
@ -79,19 +121,73 @@ object [ define-object ] "define-method" set-word-property
|
||||||
: builtin-type ( symbol -- n )
|
: builtin-type ( symbol -- n )
|
||||||
"builtin-type" word-property ;
|
"builtin-type" word-property ;
|
||||||
|
|
||||||
|
! Predicate metaclass for generalized predicate dispatch.
|
||||||
|
SYMBOL: predicate
|
||||||
|
|
||||||
|
: predicate-dispatch ( class definition existing -- dispatch )
|
||||||
|
[
|
||||||
|
\ dup ,
|
||||||
|
rot "predicate" word-property ,
|
||||||
|
swap , , \ ifte ,
|
||||||
|
] make-list ;
|
||||||
|
|
||||||
|
: (predicate-method) ( class generic definition type# -- )
|
||||||
|
rot "vtable" word-property
|
||||||
|
[ vector-nth predicate-dispatch ] 2keep
|
||||||
|
set-vector-nth ;
|
||||||
|
|
||||||
|
: predicate-method ( class generic definition -- )
|
||||||
|
pick builtin-supertypes [
|
||||||
|
>r 3dup r> (predicate-method)
|
||||||
|
] each 3drop ;
|
||||||
|
|
||||||
|
predicate [
|
||||||
|
predicate-method
|
||||||
|
] "define-method" set-word-property
|
||||||
|
|
||||||
|
predicate [
|
||||||
|
"superclass" word-property builtin-supertypes
|
||||||
|
] "builtin-supertypes" set-word-property
|
||||||
|
|
||||||
|
: define-predicate ( class predicate definition -- )
|
||||||
|
rot "superclass" word-property "predicate" word-property
|
||||||
|
[ \ dup , , , [ drop f ] , \ ifte , ] make-list
|
||||||
|
define-compound ;
|
||||||
|
|
||||||
|
: PREDICATE: ( -- class predicate definition )
|
||||||
|
#! Followed by a superclass name, then a class name.
|
||||||
|
scan-word
|
||||||
|
CREATE
|
||||||
|
dup rot "superclass" set-word-property
|
||||||
|
dup predicate "metaclass" set-word-property
|
||||||
|
dup predicate-word
|
||||||
|
[ dupd "predicate" set-word-property ] keep
|
||||||
|
[ define-predicate ] [ ] ; parsing
|
||||||
|
|
||||||
|
! Traits metaclass for user-defined classes based on hashtables
|
||||||
|
|
||||||
! Hashtable slot holding a selector->method map.
|
! Hashtable slot holding a selector->method map.
|
||||||
SYMBOL: traits
|
SYMBOL: traits
|
||||||
|
|
||||||
|
: traits-map ( class -- hash )
|
||||||
|
#! The method map word property maps selector words to
|
||||||
|
#! definitions.
|
||||||
|
"traits-map" word-property ;
|
||||||
|
|
||||||
|
: traits-method ( class generic definition -- )
|
||||||
|
swap rot traits-map set-hash ;
|
||||||
|
|
||||||
|
traits [ traits-method ] "define-method" set-word-property
|
||||||
|
|
||||||
|
traits [
|
||||||
|
\ vector "builtin-type" word-property unique,
|
||||||
|
] "builtin-supertypes" set-word-property
|
||||||
|
|
||||||
! Hashtable slot holding an optional delegate. Any undefined
|
! Hashtable slot holding an optional delegate. Any undefined
|
||||||
! methods are called on the delegate. The object can also
|
! methods are called on the delegate. The object can also
|
||||||
! manually pass any methods on to the delegate.
|
! manually pass any methods on to the delegate.
|
||||||
SYMBOL: delegate
|
SYMBOL: delegate
|
||||||
|
|
||||||
: traits-map ( type -- hash )
|
|
||||||
#! The method map word property maps selector words to
|
|
||||||
#! definitions.
|
|
||||||
"traits-map" word-property ;
|
|
||||||
|
|
||||||
: object-map ( obj -- hash )
|
: object-map ( obj -- hash )
|
||||||
#! Get the method map for an object.
|
#! Get the method map for an object.
|
||||||
#! We will use hashtable? here when its a first-class type.
|
#! We will use hashtable? here when its a first-class type.
|
||||||
|
@ -103,7 +199,7 @@ SYMBOL: delegate
|
||||||
: undefined-method
|
: undefined-method
|
||||||
"No applicable method." throw ;
|
"No applicable method." throw ;
|
||||||
|
|
||||||
: traits-method ( selector traits -- traits quot )
|
: traits-dispatch ( selector traits -- traits quot )
|
||||||
#! Look up the method with the traits object on the stack.
|
#! Look up the method with the traits object on the stack.
|
||||||
#! Returns the traits to call the method on; either the
|
#! Returns the traits to call the method on; either the
|
||||||
#! original object, or one of the delegates.
|
#! original object, or one of the delegates.
|
||||||
|
@ -111,7 +207,7 @@ SYMBOL: delegate
|
||||||
rot drop cdr ( method is defined )
|
rot drop cdr ( method is defined )
|
||||||
] [
|
] [
|
||||||
drop delegate swap hash* dup [
|
drop delegate swap hash* dup [
|
||||||
cdr traits-method ( check delegate )
|
cdr traits-dispatch ( check delegate )
|
||||||
] [
|
] [
|
||||||
drop [ undefined-method ] ( no delegate )
|
drop [ undefined-method ] ( no delegate )
|
||||||
] ifte
|
] ifte
|
||||||
|
@ -124,30 +220,19 @@ SYMBOL: delegate
|
||||||
traits-map [ swap object-map eq? ] cons
|
traits-map [ swap object-map eq? ] cons
|
||||||
define-compound ;
|
define-compound ;
|
||||||
|
|
||||||
: define-traits ( type generic definition -- )
|
|
||||||
swap rot traits-map set-hash ;
|
|
||||||
|
|
||||||
: TRAITS:
|
: TRAITS:
|
||||||
#! TRAITS: foo creates a new traits type. Instances can be
|
#! TRAITS: foo creates a new traits type. Instances can be
|
||||||
#! created with <foo>, and tested with foo?.
|
#! created with <foo>, and tested with foo?.
|
||||||
CREATE
|
CREATE
|
||||||
dup define-symbol
|
dup define-symbol
|
||||||
dup init-traits-map
|
dup init-traits-map
|
||||||
dup [ define-traits ] "define-method" set-word-property
|
dup traits "metaclass" set-word-property
|
||||||
traits-predicate ; parsing
|
traits-predicate ; parsing
|
||||||
|
|
||||||
: add-traits-dispatch ( word vtable -- )
|
: add-traits-dispatch ( word vtable -- )
|
||||||
>r unit [ car swap traits-method call ] cons \ vector r>
|
>r unit [ car swap traits-dispatch call ] cons \ vector r>
|
||||||
add-method ;
|
add-method ;
|
||||||
|
|
||||||
: GENERIC:
|
|
||||||
#! GENERIC: bar creates a generic word bar that calls the
|
|
||||||
#! bar method on the traits object, with the traits object
|
|
||||||
#! on the stack.
|
|
||||||
CREATE [ undefined-method ] <vtable>
|
|
||||||
2dup add-traits-dispatch
|
|
||||||
define-generic ; parsing
|
|
||||||
|
|
||||||
: constructor-word ( word -- word )
|
: constructor-word ( word -- word )
|
||||||
word-name "<" swap ">" cat3 "in" get create ;
|
word-name "<" swap ">" cat3 "in" get create ;
|
||||||
|
|
||||||
|
@ -162,14 +247,24 @@ SYMBOL: delegate
|
||||||
scan-word [ constructor-word ] keep
|
scan-word [ constructor-word ] keep
|
||||||
[ define-constructor ] [ ] ; parsing
|
[ define-constructor ] [ ] ; parsing
|
||||||
|
|
||||||
: define-method ( type -- quotation )
|
! Defining generic words
|
||||||
|
|
||||||
|
: GENERIC:
|
||||||
|
#! GENERIC: bar creates a generic word bar that calls the
|
||||||
|
#! bar method on the traits object, with the traits object
|
||||||
|
#! on the stack.
|
||||||
|
CREATE [ undefined-method ] <vtable>
|
||||||
|
2dup add-traits-dispatch
|
||||||
|
define-generic ; parsing
|
||||||
|
|
||||||
|
: define-method ( class -- quotation )
|
||||||
#! In a vain attempt at something resembling a "meta object
|
#! In a vain attempt at something resembling a "meta object
|
||||||
#! protocol", we call the "define-method" word property with
|
#! protocol", we call the "define-method" word property with
|
||||||
#! stack ( type generic definition -- ).
|
#! stack ( class generic definition -- ).
|
||||||
"define-method" word-property
|
metaclass "define-method" word-property
|
||||||
[ [ undefined-method ] ] unless* ;
|
[ [ undefined-method ] ] unless* ;
|
||||||
|
|
||||||
: M: ( -- type generic [ ] )
|
: M: ( -- class generic [ ] )
|
||||||
#! M: foo bar begins a definition of the bar generic word
|
#! M: foo bar begins a definition of the bar generic word
|
||||||
#! specialized to the foo type.
|
#! specialized to the foo type.
|
||||||
scan-word dup define-method scan-word swap [ ] ; parsing
|
scan-word dup define-method scan-word swap [ ] ; parsing
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
IN: hashtables
|
IN: hashtables
|
||||||
|
USE: generic
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
USE: math
|
USE: math
|
||||||
|
@ -35,8 +36,8 @@ USE: vectors
|
||||||
! for the lifetime of the hashtable, otherwise problems will
|
! for the lifetime of the hashtable, otherwise problems will
|
||||||
! occur. Do not use vector words with hashtables.
|
! occur. Do not use vector words with hashtables.
|
||||||
|
|
||||||
: hashtable? ( obj -- ? )
|
PREDICATE: vector hashtable ( obj -- ? )
|
||||||
dup vector? [ [ assoc? ] vector-all? ] [ drop f ] ifte ;
|
[ assoc? ] vector-all? ;
|
||||||
|
|
||||||
: <hashtable> ( buckets -- )
|
: <hashtable> ( buckets -- )
|
||||||
#! A hashtable is implemented as an array of buckets. The
|
#! A hashtable is implemented as an array of buckets. The
|
||||||
|
|
|
@ -91,7 +91,7 @@ USE: math
|
||||||
|
|
||||||
: =? ( x y z -- z/f )
|
: =? ( x y z -- z/f )
|
||||||
#! Push z if x = y, otherwise f.
|
#! Push z if x = y, otherwise f.
|
||||||
-rot = [ drop f ] unless ;
|
>r = r> f ? ;
|
||||||
|
|
||||||
: str-head? ( str begin -- str )
|
: str-head? ( str begin -- str )
|
||||||
#! If the string starts with begin, return the rest of the
|
#! If the string starts with begin, return the rest of the
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
IN: prettyprint
|
IN: prettyprint
|
||||||
USE: errors
|
USE: errors
|
||||||
USE: format
|
USE: format
|
||||||
|
USE: generic
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
USE: math
|
USE: math
|
||||||
|
@ -40,6 +41,11 @@ USE: vectors
|
||||||
USE: words
|
USE: words
|
||||||
USE: hashtables
|
USE: hashtables
|
||||||
|
|
||||||
|
GENERIC: prettyprint* ( indent obj -- indent )
|
||||||
|
|
||||||
|
M: object prettyprint* ( indent obj -- indent )
|
||||||
|
unparse write ;
|
||||||
|
|
||||||
: tab-size
|
: tab-size
|
||||||
#! Change this to suit your tastes.
|
#! Change this to suit your tastes.
|
||||||
4 ;
|
4 ;
|
||||||
|
@ -58,11 +64,12 @@ USE: hashtables
|
||||||
: prettyprint-space ( -- )
|
: prettyprint-space ( -- )
|
||||||
" " write ;
|
" " write ;
|
||||||
|
|
||||||
! Real definition follows
|
|
||||||
DEFER: prettyprint*
|
|
||||||
|
|
||||||
: prettyprint-element ( indent obj -- indent )
|
: prettyprint-element ( indent obj -- indent )
|
||||||
prettyprint* prettyprint-space ;
|
over prettyprint-limit >= [
|
||||||
|
unparse write
|
||||||
|
] [
|
||||||
|
prettyprint*
|
||||||
|
] ifte prettyprint-space ;
|
||||||
|
|
||||||
: <prettyprint ( indent -- indent )
|
: <prettyprint ( indent -- indent )
|
||||||
tab-size +
|
tab-size +
|
||||||
|
@ -107,16 +114,16 @@ DEFER: prettyprint*
|
||||||
drop [ ]
|
drop [ ]
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: prettyprint-word ( word -- )
|
M: word prettyprint* ( indent word -- indent )
|
||||||
dup word-name
|
dup word-name
|
||||||
swap dup word-attrs swap word-style append
|
swap dup word-attrs swap word-style append
|
||||||
write-attr ;
|
write-attr ;
|
||||||
|
|
||||||
: prettyprint-[ ( indent -- indent )
|
: prettyprint-[ ( indent -- indent )
|
||||||
\ [ prettyprint-word <prettyprint ;
|
\ [ prettyprint* <prettyprint ;
|
||||||
|
|
||||||
: prettyprint-] ( indent -- indent )
|
: prettyprint-] ( indent -- indent )
|
||||||
prettyprint> \ ] prettyprint-word ;
|
prettyprint> \ ] prettyprint* ;
|
||||||
|
|
||||||
: prettyprint-list ( indent list -- indent )
|
: prettyprint-list ( indent list -- indent )
|
||||||
#! Pretty-print a list, without [ and ].
|
#! Pretty-print a list, without [ and ].
|
||||||
|
@ -126,70 +133,56 @@ DEFER: prettyprint*
|
||||||
prettyprint-list
|
prettyprint-list
|
||||||
] [
|
] [
|
||||||
[
|
[
|
||||||
\ | prettyprint-word
|
\ | prettyprint*
|
||||||
prettyprint-space prettyprint-element
|
prettyprint-space prettyprint-element
|
||||||
] when*
|
] when*
|
||||||
] ifte
|
] ifte
|
||||||
] when* ;
|
] when* ;
|
||||||
|
|
||||||
: prettyprint-[] ( indent list -- indent )
|
M: cons prettyprint* ( indent list -- indent )
|
||||||
swap prettyprint-[ swap prettyprint-list prettyprint-] ;
|
swap prettyprint-[ swap prettyprint-list prettyprint-] ;
|
||||||
|
|
||||||
: prettyprint-{ ( indent -- indent )
|
: prettyprint-{ ( indent -- indent )
|
||||||
\ { prettyprint-word <prettyprint ;
|
\ { prettyprint* <prettyprint ;
|
||||||
|
|
||||||
: prettyprint-} ( indent -- indent )
|
: prettyprint-} ( indent -- indent )
|
||||||
prettyprint> \ } prettyprint-word ;
|
prettyprint> \ } prettyprint* ;
|
||||||
|
|
||||||
: prettyprint-vector ( indent list -- indent )
|
: prettyprint-vector ( indent list -- indent )
|
||||||
#! Pretty-print a vector, without { and }.
|
#! Pretty-print a vector, without { and }.
|
||||||
[ prettyprint-element ] vector-each ;
|
[ prettyprint-element ] vector-each ;
|
||||||
|
|
||||||
: prettyprint-{} ( indent vector -- indent )
|
M: vector prettyprint* ( indent vector -- indent )
|
||||||
dup vector-length 0 = [
|
dup vector-length 0 = [
|
||||||
drop
|
drop
|
||||||
\ { prettyprint-word
|
\ { prettyprint*
|
||||||
prettyprint-space
|
prettyprint-space
|
||||||
\ } prettyprint-word
|
\ } prettyprint*
|
||||||
] [
|
] [
|
||||||
swap prettyprint-{ swap prettyprint-vector prettyprint-}
|
swap prettyprint-{ swap prettyprint-vector prettyprint-}
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: prettyprint-{{ ( indent -- indent )
|
: prettyprint-{{ ( indent -- indent )
|
||||||
\ {{ prettyprint-word <prettyprint ;
|
\ {{ prettyprint* <prettyprint ;
|
||||||
|
|
||||||
: prettyprint-}} ( indent -- indent )
|
: prettyprint-}} ( indent -- indent )
|
||||||
prettyprint> \ }} prettyprint-word ;
|
prettyprint> \ }} prettyprint* ;
|
||||||
|
|
||||||
: prettyprint-{{}} ( indent hashtable -- indent )
|
M: hashtable prettyprint* ( indent hashtable -- indent )
|
||||||
hash>alist dup length 0 = [
|
hash>alist dup length 0 = [
|
||||||
drop
|
drop
|
||||||
\ {{ prettyprint-word
|
\ {{ prettyprint*
|
||||||
prettyprint-space
|
prettyprint-space
|
||||||
\ }} prettyprint-word
|
\ }} prettyprint*
|
||||||
] [
|
] [
|
||||||
swap prettyprint-{{ swap prettyprint-list prettyprint-}}
|
swap prettyprint-{{ swap prettyprint-list prettyprint-}}
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: prettyprint-object ( indent obj -- indent )
|
: prettyprint-1 ( obj -- )
|
||||||
unparse write ;
|
0 swap prettyprint* drop ;
|
||||||
|
|
||||||
: prettyprint* ( indent obj -- indent )
|
|
||||||
over prettyprint-limit >= [
|
|
||||||
prettyprint-object
|
|
||||||
] [
|
|
||||||
[
|
|
||||||
[ f = ] [ prettyprint-object ]
|
|
||||||
[ cons? ] [ prettyprint-[] ]
|
|
||||||
[ hashtable? ] [ prettyprint-{{}} ]
|
|
||||||
[ vector? ] [ prettyprint-{} ]
|
|
||||||
[ word? ] [ prettyprint-word ]
|
|
||||||
[ drop t ] [ prettyprint-object ]
|
|
||||||
] cond
|
|
||||||
] ifte ;
|
|
||||||
|
|
||||||
: prettyprint ( obj -- )
|
: prettyprint ( obj -- )
|
||||||
0 swap prettyprint* drop terpri ;
|
prettyprint-1 terpri ;
|
||||||
|
|
||||||
: vocab-link ( vocab -- link )
|
: vocab-link ( vocab -- link )
|
||||||
"vocabularies'" swap cat2 ;
|
"vocabularies'" swap cat2 ;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
IN: prettyprint
|
IN: prettyprint
|
||||||
|
USE: generic
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
USE: math
|
USE: math
|
||||||
|
@ -43,20 +44,20 @@ USE: words
|
||||||
dup vocab-attrs write-attr ;
|
dup vocab-attrs write-attr ;
|
||||||
|
|
||||||
: prettyprint-IN: ( indent word -- )
|
: prettyprint-IN: ( indent word -- )
|
||||||
\ IN: prettyprint-word prettyprint-space
|
\ IN: prettyprint* prettyprint-space
|
||||||
word-vocabulary prettyprint-vocab prettyprint-newline ;
|
word-vocabulary prettyprint-vocab prettyprint-newline ;
|
||||||
|
|
||||||
: prettyprint-: ( indent -- indent )
|
: prettyprint-: ( indent -- indent )
|
||||||
\ : prettyprint-word prettyprint-space
|
\ : prettyprint* prettyprint-space
|
||||||
tab-size + ;
|
tab-size + ;
|
||||||
|
|
||||||
: prettyprint-; ( indent -- indent )
|
: prettyprint-; ( indent -- indent )
|
||||||
\ ; prettyprint-word
|
\ ; prettyprint*
|
||||||
tab-size - ;
|
tab-size - ;
|
||||||
|
|
||||||
: prettyprint-prop ( word prop -- )
|
: prettyprint-prop ( word prop -- )
|
||||||
tuck word-name word-property [
|
tuck word-name word-property [
|
||||||
prettyprint-space prettyprint-word
|
prettyprint-space prettyprint-1
|
||||||
] [
|
] [
|
||||||
drop
|
drop
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
@ -88,29 +89,25 @@ USE: words
|
||||||
stack-effect. dup prettyprint-newline
|
stack-effect. dup prettyprint-newline
|
||||||
] keep documentation. ;
|
] keep documentation. ;
|
||||||
|
|
||||||
: see-compound ( word -- )
|
GENERIC: see ( word -- )
|
||||||
|
|
||||||
|
M: object see ( obj -- )
|
||||||
|
"Not a word: " write . ;
|
||||||
|
|
||||||
|
M: compound see ( word -- )
|
||||||
0 swap
|
0 swap
|
||||||
[ dupd prettyprint-IN: prettyprint-: ] keep
|
[ dupd prettyprint-IN: prettyprint-: ] keep
|
||||||
[ prettyprint-word ] keep
|
[ prettyprint-1 ] keep
|
||||||
[ prettyprint-docs ] keep
|
[ prettyprint-docs ] keep
|
||||||
[ word-parameter prettyprint-list prettyprint-; ] keep
|
[ word-parameter prettyprint-list prettyprint-; ] keep
|
||||||
prettyprint-plist prettyprint-newline ;
|
prettyprint-plist prettyprint-newline ;
|
||||||
|
|
||||||
: see-primitive ( word -- )
|
M: primitive see ( word -- )
|
||||||
"PRIMITIVE: " write dup unparse write stack-effect. terpri ;
|
"PRIMITIVE: " write dup unparse write stack-effect. terpri ;
|
||||||
|
|
||||||
: see-symbol ( word -- )
|
M: symbol see ( word -- )
|
||||||
\ SYMBOL: prettyprint-word prettyprint-space . ;
|
0 over prettyprint-IN:
|
||||||
|
\ SYMBOL: prettyprint-1 prettyprint-space . ;
|
||||||
|
|
||||||
: see-undefined ( word -- )
|
M: undefined see ( word -- )
|
||||||
drop "Not defined" print ;
|
drop "Not defined" print ;
|
||||||
|
|
||||||
: see ( name -- )
|
|
||||||
#! Show a word definition.
|
|
||||||
[
|
|
||||||
[ compound? ] [ see-compound ]
|
|
||||||
[ symbol? ] [ see-symbol ]
|
|
||||||
[ primitive? ] [ see-primitive ]
|
|
||||||
[ word? ] [ see-undefined ]
|
|
||||||
[ drop t ] [ "Not a word: " write . ]
|
|
||||||
] cond ;
|
|
||||||
|
|
|
@ -7,23 +7,23 @@ USE: words
|
||||||
|
|
||||||
: generic-test
|
: generic-test
|
||||||
{
|
{
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
nip
|
[ nip ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
} generic ; compiled
|
} generic ; compiled
|
||||||
|
|
||||||
[ 2 3 ] [ 2 3 t generic-test ] unit-test
|
[ 2 3 ] [ 2 3 t generic-test ] unit-test
|
||||||
|
@ -32,46 +32,46 @@ USE: words
|
||||||
|
|
||||||
: generic-literal-test
|
: generic-literal-test
|
||||||
4 {
|
4 {
|
||||||
drop
|
[ drop ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
nip
|
[ nip ]
|
||||||
} generic ; compiled
|
} generic ; compiled
|
||||||
|
|
||||||
[ ] [ generic-literal-test ] unit-test
|
[ ] [ generic-literal-test ] unit-test
|
||||||
|
|
||||||
: generic-test-alt
|
: generic-test-alt
|
||||||
{
|
{
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
nip
|
[ nip ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
drop
|
[ drop ]
|
||||||
} generic + ; compiled
|
} generic + ; compiled
|
||||||
|
|
||||||
[ 5 ] [ 2 3 4 generic-test-alt ] unit-test
|
[ 5 ] [ 2 3 4 generic-test-alt ] unit-test
|
||||||
|
@ -87,23 +87,23 @@ DEFER: generic-test-2
|
||||||
|
|
||||||
: generic-test-2
|
: generic-test-2
|
||||||
{
|
{
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-4
|
[ generic-test-4 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
generic-test-3
|
[ generic-test-3 ]
|
||||||
} generic ;
|
} generic ;
|
||||||
|
|
||||||
[ 3 ] [ t generic-test-2 ] unit-test
|
[ 3 ] [ t generic-test-2 ] unit-test
|
||||||
|
|
|
@ -62,7 +62,7 @@ USE: generic
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
[ { drop undefined-method drop undefined-method } generic ] dataflow
|
[ { [ drop ] [ undefined-method ] [ drop ] [ undefined-method ] } generic ] dataflow
|
||||||
#generic swap dataflow-contains-op? car [
|
#generic swap dataflow-contains-op? car [
|
||||||
node-param get [
|
node-param get [
|
||||||
[ [ node-param get \ undefined-method = ] bind ] some?
|
[ [ node-param get \ undefined-method = ] bind ] some?
|
||||||
|
|
|
@ -90,3 +90,13 @@ M: f bool>str drop "false" ;
|
||||||
|
|
||||||
[ t ] [ t bool>str str>bool ] unit-test
|
[ t ] [ t bool>str str>bool ] unit-test
|
||||||
[ f ] [ f bool>str str>bool ] unit-test
|
[ f ] [ f bool>str str>bool ] unit-test
|
||||||
|
|
||||||
|
PREDICATE: cons nonempty-list list? ;
|
||||||
|
|
||||||
|
GENERIC: funny-length
|
||||||
|
M: cons funny-length drop 0 ;
|
||||||
|
M: nonempty-list funny-length length ;
|
||||||
|
|
||||||
|
[ 0 ] [ [ 1 2 | 3 ] funny-length ] unit-test
|
||||||
|
[ 3 ] [ [ 1 2 3 ] funny-length ] unit-test
|
||||||
|
[ "hello" funny-length ] unit-test-fails
|
||||||
|
|
|
@ -8,7 +8,7 @@ USE: test
|
||||||
[ [ 1 2 ] ] [ 1 [ 2 ] ] [ "x" set "x" cons@ "x" get ] test-word
|
[ [ 1 2 ] ] [ 1 [ 2 ] ] [ "x" set "x" cons@ "x" get ] test-word
|
||||||
|
|
||||||
[ [ [ 2 | 3 ] [ 1 | 2 ] ] ] [
|
[ [ [ 2 | 3 ] [ 1 | 2 ] ] ] [
|
||||||
"x" off 2 1 "x" acons@ 3 2 "x" acons@ "x" get
|
"x" off 2 1 "x" [ acons ] change 3 2 "x" [ acons ] change "x" get
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ [ 5 4 3 1 ] ] [
|
[ [ 5 4 3 1 ] ] [
|
||||||
|
|
|
@ -6,6 +6,9 @@ USE: namespaces
|
||||||
USE: strings
|
USE: strings
|
||||||
USE: test
|
USE: test
|
||||||
|
|
||||||
|
[ f ] [ "a" "b" "c" =? ] unit-test
|
||||||
|
[ "c" ] [ "a" "a" "c" =? ] unit-test
|
||||||
|
|
||||||
[ f ] [ "A string." f-or-"" ] unit-test
|
[ f ] [ "A string." f-or-"" ] unit-test
|
||||||
[ t ] [ "" f-or-"" ] unit-test
|
[ t ] [ "" f-or-"" ] unit-test
|
||||||
[ t ] [ f f-or-"" ] unit-test
|
[ t ] [ f f-or-"" ] unit-test
|
||||||
|
|
|
@ -100,7 +100,6 @@ USE: unparser
|
||||||
"math/float"
|
"math/float"
|
||||||
"math/complex"
|
"math/complex"
|
||||||
"math/irrational"
|
"math/irrational"
|
||||||
"math/namespaces"
|
|
||||||
"httpd/url-encoding"
|
"httpd/url-encoding"
|
||||||
"httpd/html"
|
"httpd/html"
|
||||||
"httpd/httpd"
|
"httpd/httpd"
|
||||||
|
|
|
@ -55,3 +55,12 @@ word word-name "last-word-test" set
|
||||||
[ t ] [ vocabs [ words [ word? ] all? ] all? ] unit-test
|
[ t ] [ vocabs [ words [ word? ] all? ] all? ] unit-test
|
||||||
|
|
||||||
[ f ] [ gensym gensym = ] unit-test
|
[ f ] [ gensym gensym = ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ 123 compound? ] unit-test
|
||||||
|
|
||||||
|
: colon-def ;
|
||||||
|
[ t ] [ \ colon-def compound? ] unit-test
|
||||||
|
|
||||||
|
SYMBOL: a-symbol
|
||||||
|
[ f ] [ \ a-symbol compound? ] unit-test
|
||||||
|
[ t ] [ \ a-symbol symbol? ] unit-test
|
||||||
|
|
|
@ -156,9 +156,9 @@ USE: math
|
||||||
[
|
[
|
||||||
in-parser? [ parse-dump ] [ standard-dump ] ifte
|
in-parser? [ parse-dump ] [ standard-dump ] ifte
|
||||||
|
|
||||||
[ :s :r :n :c ] [ prettyprint-word " " write ] each
|
[ :s :r :n :c ] [ prettyprint-1 " " write ] each
|
||||||
"show stacks at time of error." print
|
"show stacks at time of error." print
|
||||||
\ :get prettyprint-word
|
\ :get prettyprint-1
|
||||||
" ( var -- value ) inspects the error namestack." print
|
" ( var -- value ) inspects the error namestack." print
|
||||||
] [
|
] [
|
||||||
flush-error-handler
|
flush-error-handler
|
||||||
|
|
|
@ -187,14 +187,14 @@ SYMBOL: meta-cf
|
||||||
|
|
||||||
: walk-banner ( -- )
|
: walk-banner ( -- )
|
||||||
"The following words control the single-stepper:" print
|
"The following words control the single-stepper:" print
|
||||||
[ &s &r &n &c ] [ prettyprint-word " " write ] each
|
[ &s &r &n &c ] [ prettyprint-1 " " write ] each
|
||||||
"show stepper stacks." print
|
"show stepper stacks." print
|
||||||
\ &get prettyprint-word
|
\ &get prettyprint-1
|
||||||
" ( var -- value ) inspects the stepper namestack." print
|
" ( var -- value ) inspects the stepper namestack." print
|
||||||
\ step prettyprint-word " -- single step" print
|
\ step prettyprint-1 " -- single step" print
|
||||||
\ (trace) prettyprint-word " -- trace until end" print
|
\ (trace) prettyprint-1 " -- trace until end" print
|
||||||
\ (run) prettyprint-word " -- run until end" print
|
\ (run) prettyprint-1 " -- run until end" print
|
||||||
\ exit prettyprint-word " -- exit single-stepper" print ;
|
\ exit prettyprint-1 " -- exit single-stepper" print ;
|
||||||
|
|
||||||
: walk ( quot -- )
|
: walk ( quot -- )
|
||||||
#! Single-step through execution of a quotation.
|
#! Single-step through execution of a quotation.
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
IN: words
|
IN: words
|
||||||
|
USE: generic
|
||||||
USE: hashtables
|
USE: hashtables
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
|
@ -41,13 +42,10 @@ USE: strings
|
||||||
pick [ set-assoc ] [ remove-assoc nip ] ifte
|
pick [ set-assoc ] [ remove-assoc nip ] ifte
|
||||||
swap set-word-plist ;
|
swap set-word-plist ;
|
||||||
|
|
||||||
: ?word-primitive ( obj -- prim/0 )
|
PREDICATE: word compound ( obj -- ? ) word-primitive 1 = ;
|
||||||
dup word? [ word-primitive ] [ drop -1 ] ifte ;
|
PREDICATE: word primitive ( obj -- ? ) word-primitive 2 > ;
|
||||||
|
PREDICATE: word symbol ( obj -- ? ) word-primitive 2 = ;
|
||||||
: compound? ( obj -- ? ) ?word-primitive 1 = ;
|
PREDICATE: word undefined ( obj -- ? ) word-primitive 0 = ;
|
||||||
: primitive? ( obj -- ? ) ?word-primitive 2 > ;
|
|
||||||
: symbol? ( obj -- ? ) ?word-primitive 2 = ;
|
|
||||||
: undefined? ( obj -- ? ) ?word-primitive 0 = ;
|
|
||||||
|
|
||||||
: word ( -- word ) global [ "last-word" get ] bind ;
|
: word ( -- word ) global [ "last-word" get ] bind ;
|
||||||
: set-word ( word -- ) global [ "last-word" set ] bind ;
|
: set-word ( word -- ) global [ "last-word" set ] bind ;
|
||||||
|
|
Loading…
Reference in New Issue