define-generic and define-simple-generic now take stack effect parameters; math-combination is a singleton instead of a tuple
parent
e0d48e3ab6
commit
4fc2182ac8
|
@ -9,6 +9,7 @@ IN: bootstrap.syntax
|
||||||
"!"
|
"!"
|
||||||
"\""
|
"\""
|
||||||
"#!"
|
"#!"
|
||||||
|
"("
|
||||||
"(("
|
"(("
|
||||||
":"
|
":"
|
||||||
";"
|
";"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: help.markup help.syntax words classes classes.algebra
|
USING: help.markup help.syntax words classes classes.algebra
|
||||||
definitions kernel alien sequences math quotations
|
definitions kernel alien sequences math quotations
|
||||||
generic.standard generic.math combinators prettyprint ;
|
generic.standard generic.math combinators prettyprint effects ;
|
||||||
IN: generic
|
IN: generic
|
||||||
|
|
||||||
ARTICLE: "method-order" "Method precedence"
|
ARTICLE: "method-order" "Method precedence"
|
||||||
|
@ -115,7 +115,7 @@ HELP: make-generic
|
||||||
$low-level-note ;
|
$low-level-note ;
|
||||||
|
|
||||||
HELP: define-generic
|
HELP: define-generic
|
||||||
{ $values { "word" word } { "combination" "a method combination" } }
|
{ $values { "word" word } { "effect" effect } { "combination" "a method combination" } }
|
||||||
{ $description "Defines a generic word. A method combination is an object which responds to the " { $link perform-combination } " generic word." }
|
{ $description "Defines a generic word. A method combination is an object which responds to the " { $link perform-combination } " generic word." }
|
||||||
{ $contract "The method combination quotation is called each time the generic word has to be updated (for example, when a method is added), and thus must be side-effect free." } ;
|
{ $contract "The method combination quotation is called each time the generic word has to be updated (for example, when a method is added), and thus must be side-effect free." } ;
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ M: f generic-forget-test-3 ;
|
||||||
|
|
||||||
[ f ] [ f generic-forget-test-3 ] unit-test
|
[ f ] [ f generic-forget-test-3 ] unit-test
|
||||||
|
|
||||||
: a-word ;
|
: a-word ( -- ) ;
|
||||||
|
|
||||||
GENERIC: a-generic ( a -- b )
|
GENERIC: a-generic ( a -- b )
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ M: integer a-generic a-word ;
|
||||||
|
|
||||||
[ t ] [ "m" get \ a-word usage memq? ] unit-test
|
[ t ] [ "m" get \ a-word usage memq? ] unit-test
|
||||||
|
|
||||||
[ ] [ "IN: generic.tests : a-generic ;" eval ] unit-test
|
[ ] [ "IN: generic.tests : a-generic ( -- ) ;" eval ] unit-test
|
||||||
|
|
||||||
[ f ] [ "m" get \ a-word usage memq? ] unit-test
|
[ f ] [ "m" get \ a-word usage memq? ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -185,13 +185,22 @@ M: sequence update-methods ( class seq -- )
|
||||||
[ changed-generic ] [ remake-generic drop ] 2bi
|
[ changed-generic ] [ remake-generic drop ] 2bi
|
||||||
] with each ;
|
] with each ;
|
||||||
|
|
||||||
: define-generic ( word combination -- )
|
: define-generic ( word combination effect -- )
|
||||||
over "combination" word-prop over = [ drop ] [
|
[ nip swap set-stack-effect ]
|
||||||
2dup "combination" set-word-prop
|
[
|
||||||
over "methods" word-prop values forget-all
|
drop
|
||||||
over H{ } clone "methods" set-word-prop
|
2dup [ "combination" word-prop ] dip = [ 2drop ] [
|
||||||
dupd define-default-method
|
{
|
||||||
] if remake-generic ;
|
[ "combination" set-word-prop ]
|
||||||
|
[ drop "methods" word-prop values forget-all ]
|
||||||
|
[ drop H{ } clone "methods" set-word-prop ]
|
||||||
|
[ define-default-method ]
|
||||||
|
}
|
||||||
|
2cleave
|
||||||
|
] if
|
||||||
|
]
|
||||||
|
[ 2drop remake-generic ]
|
||||||
|
3tri ;
|
||||||
|
|
||||||
M: generic subwords
|
M: generic subwords
|
||||||
[
|
[
|
||||||
|
|
|
@ -72,7 +72,7 @@ SYMBOL: picker
|
||||||
\ dispatch ,
|
\ dispatch ,
|
||||||
] [ ] make ; inline
|
] [ ] make ; inline
|
||||||
|
|
||||||
TUPLE: math-combination ;
|
SINGLETON: math-combination
|
||||||
|
|
||||||
M: math-combination make-default-method
|
M: math-combination make-default-method
|
||||||
drop default-math-method ;
|
drop default-math-method ;
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: parser kernel words generic namespaces ;
|
USING: parser kernel words generic namespaces effects.parser ;
|
||||||
IN: generic.parser
|
IN: generic.parser
|
||||||
|
|
||||||
ERROR: not-in-a-method-error ;
|
ERROR: not-in-a-method-error ;
|
||||||
|
|
||||||
: CREATE-GENERIC ( -- word ) CREATE dup reset-word ;
|
: CREATE-GENERIC ( -- word ) CREATE dup reset-word ;
|
||||||
|
|
||||||
|
: (GENERIC:) ( quot -- )
|
||||||
|
[ CREATE-GENERIC ] dip call complete-effect define-generic ; inline
|
||||||
|
|
||||||
: create-method-in ( class generic -- method )
|
: create-method-in ( class generic -- method )
|
||||||
create-method dup set-word dup save-location ;
|
create-method dup set-word dup save-location ;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
USING: generic help.markup help.syntax sequences math
|
USING: generic help.markup help.syntax sequences math
|
||||||
math.parser ;
|
math.parser effects ;
|
||||||
IN: generic.standard
|
IN: generic.standard
|
||||||
|
|
||||||
HELP: no-method
|
HELP: no-method
|
||||||
|
@ -28,7 +28,7 @@ HELP: hook-combination
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
HELP: define-simple-generic
|
HELP: define-simple-generic
|
||||||
{ $values { "word" "a word" } }
|
{ $values { "word" "a word" } { "effect" effect } }
|
||||||
{ $description "Defines a generic word with the " { $link standard-combination } " method combination and a dispatch position of 0." } ;
|
{ $description "Defines a generic word with the " { $link standard-combination } " method combination and a dispatch position of 0." } ;
|
||||||
|
|
||||||
{ standard-combination hook-combination } related-words
|
{ standard-combination hook-combination } related-words
|
||||||
|
|
|
@ -280,16 +280,6 @@ M: growable call-next-hooker call-next-method "growable " prepend ;
|
||||||
V{ } my-var [ call-next-hooker ] with-variable
|
V{ } my-var [ call-next-hooker ] with-variable
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
GENERIC: no-stack-effect-decl
|
|
||||||
|
|
||||||
M: hashtable no-stack-effect-decl ;
|
|
||||||
M: vector no-stack-effect-decl ;
|
|
||||||
M: sbuf no-stack-effect-decl ;
|
|
||||||
|
|
||||||
[ ] [ \ no-stack-effect-decl see ] unit-test
|
|
||||||
|
|
||||||
[ ] [ \ no-stack-effect-decl def>> . ] unit-test
|
|
||||||
|
|
||||||
! Cross-referencing with generic words
|
! Cross-referencing with generic words
|
||||||
TUPLE: xref-tuple-1 ;
|
TUPLE: xref-tuple-1 ;
|
||||||
TUPLE: xref-tuple-2 < xref-tuple-1 ;
|
TUPLE: xref-tuple-2 < xref-tuple-1 ;
|
||||||
|
|
|
@ -24,7 +24,7 @@ M: quotation engine>quot
|
||||||
ERROR: no-method object generic ;
|
ERROR: no-method object generic ;
|
||||||
|
|
||||||
: error-method ( word -- quot )
|
: error-method ( word -- quot )
|
||||||
picker swap [ no-method ] curry append ;
|
[ picker ] dip [ no-method ] curry append ;
|
||||||
|
|
||||||
: push-method ( method specializer atomic assoc -- )
|
: push-method ( method specializer atomic assoc -- )
|
||||||
[
|
[
|
||||||
|
@ -56,7 +56,7 @@ ERROR: no-method object generic ;
|
||||||
|
|
||||||
: find-default ( methods -- quot )
|
: find-default ( methods -- quot )
|
||||||
#! Side-effects methods.
|
#! Side-effects methods.
|
||||||
object bootstrap-word swap delete-at* [
|
[ object bootstrap-word ] dip delete-at* [
|
||||||
drop generic get "default-method" word-prop mangle-method
|
drop generic get "default-method" word-prop mangle-method
|
||||||
] unless ;
|
] unless ;
|
||||||
|
|
||||||
|
@ -104,8 +104,10 @@ PREDICATE: standard-generic < generic
|
||||||
PREDICATE: simple-generic < standard-generic
|
PREDICATE: simple-generic < standard-generic
|
||||||
"combination" word-prop #>> zero? ;
|
"combination" word-prop #>> zero? ;
|
||||||
|
|
||||||
: define-simple-generic ( word -- )
|
CONSTANT: simple-combination T{ standard-combination f 0 }
|
||||||
T{ standard-combination f 0 } define-generic ;
|
|
||||||
|
: define-simple-generic ( word effect -- )
|
||||||
|
[ simple-combination ] dip define-generic ;
|
||||||
|
|
||||||
: with-standard ( combination quot -- quot' )
|
: with-standard ( combination quot -- quot' )
|
||||||
[ #>> (dispatch#) ] dip with-variable ; inline
|
[ #>> (dispatch#) ] dip with-variable ; inline
|
||||||
|
|
|
@ -21,7 +21,7 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
|
||||||
object bootstrap-word >>class ;
|
object bootstrap-word >>class ;
|
||||||
|
|
||||||
: define-typecheck ( class generic quot props -- )
|
: define-typecheck ( class generic quot props -- )
|
||||||
[ dup define-simple-generic create-method ] 2dip
|
[ create-method ] 2dip
|
||||||
[ [ props>> ] [ drop ] [ ] tri* update ]
|
[ [ props>> ] [ drop ] [ ] tri* update ]
|
||||||
[ drop define ]
|
[ drop define ]
|
||||||
3bi ;
|
3bi ;
|
||||||
|
@ -36,7 +36,6 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
|
||||||
|
|
||||||
: reader-word ( name -- word )
|
: reader-word ( name -- word )
|
||||||
">>" append "accessors" create
|
">>" append "accessors" create
|
||||||
dup (( object -- value )) "declared-effect" set-word-prop
|
|
||||||
dup t "reader" set-word-prop ;
|
dup t "reader" set-word-prop ;
|
||||||
|
|
||||||
: reader-props ( slot-spec -- assoc )
|
: reader-props ( slot-spec -- assoc )
|
||||||
|
@ -46,13 +45,18 @@ PREDICATE: writer-method < method-body "writing" word-prop ;
|
||||||
t "flushable" set
|
t "flushable" set
|
||||||
] H{ } make-assoc ;
|
] H{ } make-assoc ;
|
||||||
|
|
||||||
|
: define-reader-generic ( name -- )
|
||||||
|
reader-word (( object -- value )) define-simple-generic ;
|
||||||
|
|
||||||
: define-reader ( class slot-spec -- )
|
: define-reader ( class slot-spec -- )
|
||||||
[ name>> reader-word ] [ reader-quot ] [ reader-props ] tri
|
[ nip name>> define-reader-generic ]
|
||||||
define-typecheck ;
|
[
|
||||||
|
[ name>> reader-word ] [ reader-quot ] [ reader-props ] tri
|
||||||
|
define-typecheck
|
||||||
|
] 2bi ;
|
||||||
|
|
||||||
: writer-word ( name -- word )
|
: writer-word ( name -- word )
|
||||||
"(>>" ")" surround "accessors" create
|
"(>>" ")" surround "accessors" create
|
||||||
dup (( value object -- )) "declared-effect" set-word-prop
|
|
||||||
dup t "writer" set-word-prop ;
|
dup t "writer" set-word-prop ;
|
||||||
|
|
||||||
ERROR: bad-slot-value value class ;
|
ERROR: bad-slot-value value class ;
|
||||||
|
@ -92,9 +96,14 @@ ERROR: bad-slot-value value class ;
|
||||||
: writer-props ( slot-spec -- assoc )
|
: writer-props ( slot-spec -- assoc )
|
||||||
"writing" associate ;
|
"writing" associate ;
|
||||||
|
|
||||||
|
: define-writer-generic ( name -- )
|
||||||
|
writer-word (( object value -- )) define-simple-generic ;
|
||||||
|
|
||||||
: define-writer ( class slot-spec -- )
|
: define-writer ( class slot-spec -- )
|
||||||
[ name>> writer-word ] [ writer-quot ] [ writer-props ] tri
|
[ nip name>> define-writer-generic ] [
|
||||||
define-typecheck ;
|
[ name>> writer-word ] [ writer-quot ] [ writer-props ] tri
|
||||||
|
define-typecheck
|
||||||
|
] 2bi ;
|
||||||
|
|
||||||
: setter-word ( name -- word )
|
: setter-word ( name -- word )
|
||||||
">>" prepend "accessors" create ;
|
">>" prepend "accessors" create ;
|
||||||
|
@ -134,8 +143,8 @@ ERROR: bad-slot-value value class ;
|
||||||
|
|
||||||
: define-protocol-slot ( name -- )
|
: define-protocol-slot ( name -- )
|
||||||
{
|
{
|
||||||
[ reader-word define-simple-generic ]
|
[ define-reader-generic ]
|
||||||
[ writer-word define-simple-generic ]
|
[ define-writer-generic ]
|
||||||
[ define-setter ]
|
[ define-setter ]
|
||||||
[ define-changer ]
|
[ define-changer ]
|
||||||
} cleave ;
|
} cleave ;
|
||||||
|
|
|
@ -508,8 +508,8 @@ HELP: P"
|
||||||
HELP: (
|
HELP: (
|
||||||
{ $syntax "( inputs -- outputs )" }
|
{ $syntax "( inputs -- outputs )" }
|
||||||
{ $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
|
{ $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
|
||||||
{ $description "Declares the stack effect of the most recently defined word, storing a new " { $link effect } " instance in the " { $snippet "\"declared-effect\"" } " word property." }
|
{ $description "A stack effect declaration. This is treated as a comment unless it appears inside a word definition." }
|
||||||
{ $notes "All words except those only pushing literals on the stack must have a stack effect declaration. See " { $link "effect-declaration" } " for details." } ;
|
{ $see-also "effect-declaration" } ;
|
||||||
|
|
||||||
HELP: ((
|
HELP: ((
|
||||||
{ $syntax "(( inputs -- outputs ))" }
|
{ $syntax "(( inputs -- outputs ))" }
|
||||||
|
|
|
@ -127,6 +127,11 @@ IN: bootstrap.syntax
|
||||||
";" parse-tokens
|
";" parse-tokens
|
||||||
[ create-class-in define-singleton-class ] each
|
[ create-class-in define-singleton-class ] each
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
|
"DEFER:" [
|
||||||
|
scan current-vocab create
|
||||||
|
[ fake-definition ] [ set-word ] [ [ undefined ] define ] tri
|
||||||
|
] define-core-syntax
|
||||||
|
|
||||||
"ALIAS:" [
|
"ALIAS:" [
|
||||||
CREATE-WORD scan-word define-alias
|
CREATE-WORD scan-word define-alias
|
||||||
|
@ -136,32 +141,24 @@ IN: bootstrap.syntax
|
||||||
CREATE scan-object define-constant
|
CREATE scan-object define-constant
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
"DEFER:" [
|
|
||||||
scan current-vocab create
|
|
||||||
[ fake-definition ] [ set-word ] [ [ undefined ] define ] tri
|
|
||||||
] define-core-syntax
|
|
||||||
|
|
||||||
":" [
|
":" [
|
||||||
(:) define-declared
|
(:) define-declared
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
"GENERIC:" [
|
"GENERIC:" [
|
||||||
CREATE-GENERIC define-simple-generic
|
[ simple-combination ] (GENERIC:)
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
"GENERIC#" [
|
"GENERIC#" [
|
||||||
CREATE-GENERIC
|
[ scan-word <standard-combination> ] (GENERIC:)
|
||||||
scan-word <standard-combination> define-generic
|
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
"MATH:" [
|
"MATH:" [
|
||||||
CREATE-GENERIC
|
[ math-combination ] (GENERIC:)
|
||||||
T{ math-combination } define-generic
|
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
"HOOK:" [
|
"HOOK:" [
|
||||||
CREATE-GENERIC scan-word
|
[ scan-word <hook-combination> ] (GENERIC:)
|
||||||
<hook-combination> define-generic
|
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
"M:" [
|
"M:" [
|
||||||
|
@ -220,6 +217,10 @@ IN: bootstrap.syntax
|
||||||
scan-object forget
|
scan-object forget
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
||||||
|
"(" [
|
||||||
|
")" parse-effect drop
|
||||||
|
] define-core-syntax
|
||||||
|
|
||||||
"((" [
|
"((" [
|
||||||
"))" parse-effect parsed
|
"))" parse-effect parsed
|
||||||
] define-core-syntax
|
] define-core-syntax
|
||||||
|
|
Loading…
Reference in New Issue