core: Remove some foo'bar words and a lot of postpone:
parent
f05c7e8cd8
commit
8c3df2ede4
|
@ -325,11 +325,11 @@ STRUCT: clone-test-struct { x int } { y char[3] } ;
|
|||
] with-destructors
|
||||
] unit-test
|
||||
|
||||
STRUCT: struct-that's-a-word { x int } ;
|
||||
STRUCT: struct-that-is-a-word { x int } ;
|
||||
|
||||
: struct-that's-a-word ( -- ) "OOPS" throw ;
|
||||
: struct-that-is-a-word ( -- ) "OOPS" throw ;
|
||||
|
||||
{ -77 } [ S{ struct-that's-a-word { x -77 } } clone x>> ] unit-test
|
||||
{ -77 } [ S{ struct-that-is-a-word { x -77 } } clone x>> ] unit-test
|
||||
|
||||
! Interactive parsing of struct slot definitions
|
||||
[
|
||||
|
|
|
@ -7,7 +7,7 @@ USING: compiler.cfg.instructions.syntax prettyprint splitting ;
|
|||
"use: src/int-rep temp: temp/int-rep" " " split parse-insn-slot-specs .
|
||||
]]
|
||||
|
||||
CONSTANT: parse-insn-slot-specs-result [[ {
|
||||
CONSTANT: parse-insn-slot-specs-result [[{
|
||||
T{ insn-slot-spec
|
||||
{ type use }
|
||||
{ name "src" }
|
||||
|
|
|
@ -861,10 +861,10 @@ TUPLE: some-tuple x ;
|
|||
] unit-test
|
||||
|
||||
! GC maps regression
|
||||
: anton's-regression ( -- )
|
||||
: antons-regression ( -- )
|
||||
f (free) f (free) ;
|
||||
|
||||
[ ] [ anton's-regression ] unit-test
|
||||
[ ] [ antons-regression ] unit-test
|
||||
|
||||
|
||||
STRUCT: bool-and-ptr
|
||||
|
|
|
@ -195,7 +195,7 @@ M: number detect-number ;
|
|||
[ 10 f [ <array> 0 + detect-number ] compile-call ] must-fail
|
||||
|
||||
! Regression
|
||||
[ 4 [ + ] ] [ 2 2 [ [ + ] [ call ] keep ] compile-call ] unit-test
|
||||
{ 4 [ + ] } [ 2 2 [ [ + ] [ call ] keep ] compile-call ] unit-test
|
||||
|
||||
! Regression
|
||||
: empty-compound ( -- ) ;
|
||||
|
@ -203,11 +203,11 @@ M: number detect-number ;
|
|||
: node-successor-f-bug ( x -- * )
|
||||
[ 3 throw ] [ empty-compound ] compose [ 3 throw ] if ;
|
||||
|
||||
[ t ] [ \ node-successor-f-bug word-optimized? ] unit-test
|
||||
{ t } [ \ node-successor-f-bug word-optimized? ] unit-test
|
||||
|
||||
[ ] [ [ new ] build-tree optimize-tree drop ] unit-test
|
||||
{ } [ [ new ] build-tree optimize-tree drop ] unit-test
|
||||
|
||||
[ ] [ [ <tuple> ] build-tree optimize-tree drop ] unit-test
|
||||
{ } [ [ <tuple> ] build-tree optimize-tree drop ] unit-test
|
||||
|
||||
! Regression
|
||||
: lift-throw-tail-regression ( obj -- obj str )
|
||||
|
@ -217,9 +217,9 @@ M: number detect-number ;
|
|||
] if
|
||||
] if ;
|
||||
|
||||
[ t ] [ \ lift-throw-tail-regression word-optimized? ] unit-test
|
||||
[ 3 "an integer" ] [ 3 lift-throw-tail-regression ] unit-test
|
||||
[ "hi" "a string" ] [ "hi" lift-throw-tail-regression ] unit-test
|
||||
{ t } [ \ lift-throw-tail-regression word-optimized? ] unit-test
|
||||
{ 3 "an integer" } [ 3 lift-throw-tail-regression ] unit-test
|
||||
{ "hi" "a string" } [ "hi" lift-throw-tail-regression ] unit-test
|
||||
|
||||
: lift-loop-tail-test-1 ( a quot: ( -- ) -- )
|
||||
over even? [
|
||||
|
@ -237,7 +237,7 @@ M: number detect-number ;
|
|||
|
||||
\ lift-loop-tail-test-2 def>> must-infer
|
||||
|
||||
[ 1 2 3 ] [ lift-loop-tail-test-2 ] unit-test
|
||||
{ 1 2 3 } [ lift-loop-tail-test-2 ] unit-test
|
||||
|
||||
! Forgot a recursive inline check
|
||||
: recursive-inline-hang ( a -- a )
|
||||
|
@ -248,7 +248,7 @@ HINTS: recursive-inline-hang array ;
|
|||
: recursive-inline-hang-1 ( -- a )
|
||||
{ } recursive-inline-hang ;
|
||||
|
||||
[ t ] [ \ recursive-inline-hang-1 word-optimized? ] unit-test
|
||||
{ t } [ \ recursive-inline-hang-1 word-optimized? ] unit-test
|
||||
|
||||
DEFER: recursive-inline-hang-3
|
||||
|
||||
|
@ -263,7 +263,7 @@ HINTS: recursive-inline-hang-2 array ;
|
|||
HINTS: recursive-inline-hang-3 array ;
|
||||
|
||||
! Regression
|
||||
[ ] [ { 3append-as } compile ] unit-test
|
||||
{ } [ { 3append-as } compile ] unit-test
|
||||
|
||||
! Wow
|
||||
: counter-example ( a b c d -- a' b' c' d' )
|
||||
|
@ -272,14 +272,14 @@ HINTS: recursive-inline-hang-3 array ;
|
|||
: counter-example' ( -- a' b' c' d' )
|
||||
1 2 3.0 3 counter-example ;
|
||||
|
||||
[ 2 4 6.0 0 ] [ counter-example' ] unit-test
|
||||
{ 2 4 6.0 0 } [ counter-example' ] unit-test
|
||||
|
||||
: member-test ( obj -- ? ) { + - * / /i } member? ;
|
||||
|
||||
\ member-test def>> must-infer
|
||||
[ ] [ \ member-test build-tree optimize-tree drop ] unit-test
|
||||
[ t ] [ \ + member-test ] unit-test
|
||||
[ f ] [ \ append member-test ] unit-test
|
||||
{ } [ \ member-test build-tree optimize-tree drop ] unit-test
|
||||
{ t } [ \ + member-test ] unit-test
|
||||
{ f } [ \ append member-test ] unit-test
|
||||
|
||||
! Infinite expansion
|
||||
TUPLE: cons car cdr ;
|
||||
|
@ -289,25 +289,25 @@ UNION: improper-list cons postpone: f ;
|
|||
PREDICATE: list < improper-list
|
||||
[ cdr>> list instance? ] [ t ] if* ;
|
||||
|
||||
[ t ] [
|
||||
{ t } [
|
||||
T{ cons f 1 T{ cons f 2 T{ cons f 3 f } } }
|
||||
[ list instance? ] compile-call
|
||||
] unit-test
|
||||
|
||||
! <tuple> type function bustage
|
||||
[ T{ cons } 7 ] [ cons tuple-layout [ [ <tuple> ] [ length ] bi ] compile-call ] unit-test
|
||||
{ T{ cons } 7 } [ cons tuple-layout [ [ <tuple> ] [ length ] bi ] compile-call ] unit-test
|
||||
|
||||
! Regression
|
||||
: interval-inference-bug ( obj -- obj x )
|
||||
dup "a" get { array-capacity } declare >=
|
||||
[ dup "b" get { array-capacity } declare >= [ 3 ] [ 4 ] if ] [ 5 ] if ;
|
||||
|
||||
[ t ] [ \ interval-inference-bug word-optimized? ] unit-test
|
||||
{ t } [ \ interval-inference-bug word-optimized? ] unit-test
|
||||
|
||||
[ ] [ 1 "a" set 2 "b" set ] unit-test
|
||||
[ 2 3 ] [ 2 interval-inference-bug ] unit-test
|
||||
[ 1 4 ] [ 1 interval-inference-bug ] unit-test
|
||||
[ 0 5 ] [ 0 interval-inference-bug ] unit-test
|
||||
{ } [ 1 "a" set 2 "b" set ] unit-test
|
||||
{ 2 3 } [ 2 interval-inference-bug ] unit-test
|
||||
{ 1 4 } [ 1 interval-inference-bug ] unit-test
|
||||
{ 0 5 } [ 0 interval-inference-bug ] unit-test
|
||||
|
||||
: aggressive-flush-regression ( a -- b )
|
||||
f over [ <array> drop ] dip 1 + ;
|
||||
|
@ -323,23 +323,23 @@ TUPLE: some-tuple x ;
|
|||
: allot-regression ( a -- b )
|
||||
[ ] curry some-tuple boa ;
|
||||
|
||||
[ T{ some-tuple f [ 3 ] } ] [ 3 allot-regression ] unit-test
|
||||
{ T{ some-tuple f [ 3 ] } } [ 3 allot-regression ] unit-test
|
||||
|
||||
[ 1 ] [ B{ 0 0 0 0 } [ 0 alien-signed-4 1 + ] compile-call ] unit-test
|
||||
[ 1 ] [ B{ 0 0 0 0 } [ 0 alien-unsigned-4 1 + ] compile-call ] unit-test
|
||||
[ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-signed-8 1 + ] compile-call ] unit-test
|
||||
[ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-unsigned-8 1 + ] compile-call ] unit-test
|
||||
[ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-signed-cell 1 + ] compile-call ] unit-test
|
||||
[ 1 ] [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-unsigned-cell 1 + ] compile-call ] unit-test
|
||||
{ 1 } [ B{ 0 0 0 0 } [ 0 alien-signed-4 1 + ] compile-call ] unit-test
|
||||
{ 1 } [ B{ 0 0 0 0 } [ 0 alien-unsigned-4 1 + ] compile-call ] unit-test
|
||||
{ 1 } [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-signed-8 1 + ] compile-call ] unit-test
|
||||
{ 1 } [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-unsigned-8 1 + ] compile-call ] unit-test
|
||||
{ 1 } [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-signed-cell 1 + ] compile-call ] unit-test
|
||||
{ 1 } [ B{ 0 0 0 0 0 0 0 0 } [ 0 alien-unsigned-cell 1 + ] compile-call ] unit-test
|
||||
|
||||
: deep-find-test ( seq -- ? ) [ 5 = ] deep-find ;
|
||||
|
||||
[ 5 ] [ { 1 2 { 3 { 4 5 } } } deep-find-test ] unit-test
|
||||
[ f ] [ { 1 2 { 3 { 4 } } } deep-find-test ] unit-test
|
||||
{ 5 } [ { 1 2 { 3 { 4 5 } } } deep-find-test ] unit-test
|
||||
{ f } [ { 1 2 { 3 { 4 } } } deep-find-test ] unit-test
|
||||
|
||||
[ B{ 0 1 2 3 4 5 6 7 } ] [ [ 8 <iota> [ ] B{ } map-as ] compile-call ] unit-test
|
||||
{ B{ 0 1 2 3 4 5 6 7 } } [ [ 8 <iota> [ ] B{ } map-as ] compile-call ] unit-test
|
||||
|
||||
[ 0 ] [ 1234 [ { fixnum } declare -64 shift ] compile-call ] unit-test
|
||||
{ 0 } [ 1234 [ { fixnum } declare -64 shift ] compile-call ] unit-test
|
||||
|
||||
! Loop detection problem found by doublec
|
||||
SYMBOL: counter
|
||||
|
@ -354,22 +354,22 @@ DEFER: loop-bbb
|
|||
|
||||
: loop-ccc ( -- ) loop-bbb ;
|
||||
|
||||
[ 0 ] [ 0 counter set loop-ccc counter get ] unit-test
|
||||
{ 0 } [ 0 counter set loop-ccc counter get ] unit-test
|
||||
|
||||
! Type inference issue
|
||||
[ 4 3 ] [
|
||||
{ 4 3 } [
|
||||
1 >bignum 2 >bignum
|
||||
[ { bignum integer } declare [ shift ] keep 1 + ] compile-call
|
||||
] unit-test
|
||||
|
||||
: broken-declaration ( -- ) \ + declare ;
|
||||
|
||||
[ f ] [ \ broken-declaration word-optimized? ] unit-test
|
||||
{ f } [ \ broken-declaration word-optimized? ] unit-test
|
||||
|
||||
[ ] [ [ \ broken-declaration forget ] with-compilation-unit ] unit-test
|
||||
{ } [ [ \ broken-declaration forget ] with-compilation-unit ] unit-test
|
||||
|
||||
! Interval inference issue
|
||||
[ f ] [
|
||||
{ f } [
|
||||
10 70
|
||||
[
|
||||
dup 70 >=
|
||||
|
@ -382,10 +382,10 @@ DEFER: loop-bbb
|
|||
! Modular arithmetic bug
|
||||
: modular-arithmetic-bug ( a -- b ) >integer 256 mod ;
|
||||
|
||||
[ 1 ] [ 257 modular-arithmetic-bug ] unit-test
|
||||
[ -10 ] [ -10 modular-arithmetic-bug ] unit-test
|
||||
{ 1 } [ 257 modular-arithmetic-bug ] unit-test
|
||||
{ -10 } [ -10 modular-arithmetic-bug ] unit-test
|
||||
|
||||
[ 16 ] [
|
||||
{ 16 } [
|
||||
[
|
||||
0 2
|
||||
[
|
||||
|
@ -412,10 +412,10 @@ DEFER: loop-bbb
|
|||
1 + { [ + ] [ - ] [ * ] } dispatch ;
|
||||
|
||||
[ 3 4 -1 dispatch-branch-problem ] [ "boo" = ] must-fail-with
|
||||
[ -1 ] [ 3 4 0 dispatch-branch-problem ] unit-test
|
||||
[ 12 ] [ 3 4 1 dispatch-branch-problem ] unit-test
|
||||
{ -1 } [ 3 4 0 dispatch-branch-problem ] unit-test
|
||||
{ 12 } [ 3 4 1 dispatch-branch-problem ] unit-test
|
||||
|
||||
[ 1024 bignum ] [ 10 [ 1 >bignum swap >fixnum shift ] compile-call dup class-of ] unit-test
|
||||
{ 1024 bignum } [ 10 [ 1 >bignum swap >fixnum shift ] compile-call dup class-of ] unit-test
|
||||
|
||||
TUPLE: grid-mesh-tuple { length read-only } { step read-only } ;
|
||||
|
||||
|
@ -430,17 +430,17 @@ TUPLE: grid-mesh-tuple { length read-only } { step read-only } ;
|
|||
] 2curry times
|
||||
] keep ;
|
||||
|
||||
[ { 0.5 } ] [ grid-mesh-test-case ] unit-test
|
||||
{ { 0.5 } } [ grid-mesh-test-case ] unit-test
|
||||
|
||||
[ { 1 } "bar" ] [ { 1 } [ [ [ [ "foo" throw ] [ "bar" throw ] recover ] attempt-all f ] [ ] recover ] compile-call ] unit-test
|
||||
{ { 1 } "bar" } [ { 1 } [ [ [ [ "foo" throw ] [ "bar" throw ] recover ] attempt-all f ] [ ] recover ] compile-call ] unit-test
|
||||
|
||||
GENERIC: bad-push-test-case ( a -- b )
|
||||
M: object bad-push-test-case "foo" throw ; inline
|
||||
[ { 1 } "bar" ] [ { 1 } [ [ [ [ bad-push-test-case ] [ "bar" throw ] recover ] attempt-all f ] [ ] recover ] compile-call ] unit-test
|
||||
{ { 1 } "bar" } [ { 1 } [ [ [ [ bad-push-test-case ] [ "bar" throw ] recover ] attempt-all f ] [ ] recover ] compile-call ] unit-test
|
||||
|
||||
STRUCT: BitmapData { Scan0 void* } ;
|
||||
|
||||
[ alien: 123 ] [
|
||||
{ alien: 123 } [
|
||||
[
|
||||
{ BitmapData }
|
||||
[ BitmapData memory>struct alien: 123 >>Scan0 drop ]
|
||||
|
|
|
@ -307,14 +307,14 @@ INTERSECTION: intersection-see-test sequence number ;
|
|||
|
||||
{ "postpone: \[" } [ \ [ unparse ] unit-test
|
||||
|
||||
TUPLE: started-out-hustlin' ;
|
||||
TUPLE: started-out-hustlin ;
|
||||
|
||||
GENERIC: ended-up-ballin' ( a -- b )
|
||||
GENERIC: ended-up-ballin ( a -- b )
|
||||
|
||||
M: started-out-hustlin' ended-up-ballin' ; inline
|
||||
M: started-out-hustlin ended-up-ballin ; inline
|
||||
|
||||
{ "USING: prettyprint.tests ;\nM: started-out-hustlin' ended-up-ballin' ; inline\n" } [
|
||||
[ M\\ started-out-hustlin' ended-up-ballin' see ] with-string-writer
|
||||
{ "USING: prettyprint.tests ;\nM: started-out-hustlin ended-up-ballin ; inline\n" } [
|
||||
[ M\\ started-out-hustlin ended-up-ballin see ] with-string-writer
|
||||
] unit-test
|
||||
|
||||
TUPLE: tuple-with-declared-slot { x integer } ;
|
||||
|
@ -466,7 +466,7 @@ TUPLE: fo { a intersection{ integer fixnum } initial: 0 } ;
|
|||
with-string-writer
|
||||
] unit-test
|
||||
|
||||
: margin-test ( number-of-'a's -- str )
|
||||
: margin-test ( number-of-a-s -- str )
|
||||
[
|
||||
[ ch'a <string> text "b" text ] with-pprint
|
||||
] with-string-writer ;
|
||||
|
|
|
@ -331,11 +331,11 @@ M: x11-ui-backend beep ( -- )
|
|||
dpy get 100 XBell drop ;
|
||||
|
||||
<PRIVATE
|
||||
: escape-' ( string -- string' )
|
||||
: escape-single-quote ( string -- string' )
|
||||
[ dup ch'\' = [ drop "'\\''" ] [ 1string ] if ] { } map-as concat ;
|
||||
|
||||
: xmessage ( string -- )
|
||||
escape-' "/usr/bin/env xmessage '" "'" surround system drop ;
|
||||
escape-single-quote "/usr/bin/env xmessage '" "'" surround system drop ;
|
||||
PRIVATE>
|
||||
|
||||
M: x11-ui-backend system-alert
|
||||
|
|
|
@ -24,7 +24,7 @@ HELP: sort-strings
|
|||
{ $description "This word takes a sequence of strings and sorts them according to the Unicode Collation Algorithm with the default collation order described in the DUCET. It uses code point order as a tie-breaker." } ;
|
||||
|
||||
HELP: collation-key/nfd
|
||||
{ $values { "string" string } { "key" byte-array } }
|
||||
{ $values { "string" string } { "key" byte-array } { "nfd" object } }
|
||||
{ $description "This takes a string and gives a representation of the collation key, which can be compared with " { $link <=> } ". The representation is according to the DUCET." } ;
|
||||
|
||||
HELP: string<=>
|
||||
|
|
|
@ -23,9 +23,9 @@ HELP: vocab-files
|
|||
$[
|
||||
{
|
||||
"{"
|
||||
" \"resource:basis/alien/libraries/libraries.factor\""
|
||||
" \"resource:basis/alien/libraries/libraries-docs.factor\""
|
||||
" \"resource:basis/alien/libraries/libraries-tests.factor\""
|
||||
" \"resource:core/alien/libraries/libraries.factor\""
|
||||
" \"resource:core/alien/libraries/libraries-docs.factor\""
|
||||
" \"resource:core/alien/libraries/libraries-tests.factor\""
|
||||
"}"
|
||||
} "\n" join
|
||||
]
|
||||
|
|
|
@ -149,7 +149,7 @@ HELP: alien-assembly
|
|||
ARTICLE: "alien-expiry" "Alien expiry"
|
||||
"When an image is loaded, any alien objects which persisted from the previous session are marked as having expired. This is because the C pointers they contain are almost certainly no longer valid."
|
||||
$nl
|
||||
"For this reason, the " { $link postpone: \alien: } " word should not be used in source files, since loading the source file then saving the image will result in the literal becoming expired. Use " { $link <alien> } " instead, and ensure the word calling " { $link <alien> } " is not declared " { $link postpone: flushable } "."
|
||||
"For this reason, the " { $link \ \alien: } " word should not be used in source files, since loading the source file then saving the image will result in the literal becoming expired. Use " { $link <alien> } " instead, and ensure the word calling " { $link <alien> } " is not declared " { $link \ flushable } "."
|
||||
{ $subsections expired? } ;
|
||||
|
||||
ARTICLE: "aliens" "Alien addresses"
|
||||
|
@ -205,9 +205,9 @@ ARTICLE: "reading-writing-memory" "Reading and writing memory directly"
|
|||
ARTICLE: "alien-invoke" "Calling C from Factor"
|
||||
"The easiest way to call into a C library is to define bindings using a pair of parsing words:"
|
||||
{ $subsections
|
||||
postpone: \LIBRARY:
|
||||
postpone: \FUNCTION:
|
||||
postpone: \FUNCTION-ALIAS:
|
||||
\ \LIBRARY:
|
||||
\ \FUNCTION:
|
||||
\ \FUNCTION-ALIAS:
|
||||
}
|
||||
"The above parsing words create word definitions which call a lower-level word; you can use it directly, too:"
|
||||
{ $subsections alien-invoke }
|
||||
|
@ -219,7 +219,7 @@ ARTICLE: "alien-callback" "Calling Factor from C"
|
|||
"Callbacks can be defined and passed to C code as function pointers; the C code can then invoke the callback and run Factor code:"
|
||||
{ $subsections
|
||||
alien-callback
|
||||
postpone: \CALLBACK:
|
||||
\ \CALLBACK:
|
||||
}
|
||||
"There are some caveats concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-data" } "."
|
||||
{ $see-also "byte-arrays-gc" } ;
|
||||
|
@ -227,8 +227,8 @@ ARTICLE: "alien-callback" "Calling Factor from C"
|
|||
ARTICLE: "alien-globals" "Accessing C global variables"
|
||||
"The " { $vocab-link "alien.syntax" } " vocabulary defines two parsing words for accessing the value of a global variable, and get the address of a global variable, respectively."
|
||||
{ $subsections
|
||||
postpone: \C-GLOBAL:
|
||||
postpone: \&:
|
||||
\ \C-GLOBAL:
|
||||
\ \&:
|
||||
} ;
|
||||
|
||||
ARTICLE: "alien-assembly" "Calling arbitrary assembly code"
|
||||
|
|
|
@ -65,7 +65,7 @@ HELP: longlong
|
|||
HELP: ulonglong
|
||||
{ $description "This C type represents an eight-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to 64 bits; output values will be returned as " { $link math:integer } "s." } ;
|
||||
HELP: void
|
||||
{ $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link postpone: \FUNCTION: } " or " { $link postpone: \CALLBACK: } " definition or for an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
|
||||
{ $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link \ \FUNCTION: } " or " { $link \ \CALLBACK: } " definition or for an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
|
||||
HELP: void*
|
||||
{ $description "This C type represents a generic pointer to C memory. See " { $link pointer } " for information on pointer C types." } ;
|
||||
HELP: c-string
|
||||
|
@ -84,7 +84,7 @@ HELP: pointer
|
|||
$nl
|
||||
"Pointer output values are represented in Factor as " { $link alien } "s. If the pointed-to type is a struct, the alien will automatically be wrapped in a struct object if it is not null."
|
||||
$nl
|
||||
"In " { $link postpone: \TYPEDEF: } ", " { $link postpone: \FUNCTION: } ", " { $link postpone: \CALLBACK: } ", and " { $link postpone: \STRUCT: } " definitions, pointer types can be created by suffixing " { $snippet "*" } " to a C type name. Outside of FFI definitions, a pointer C type can be created using the " { $link postpone: \pointer: } " syntax word:"
|
||||
"In " { $link \ \TYPEDEF: } ", " { $link \ \FUNCTION: } ", " { $link \ \CALLBACK: } ", and " { $link \ \STRUCT: } " definitions, pointer types can be created by suffixing " { $snippet "*" } " to a C type name. Outside of FFI definitions, a pointer C type can be created using the " { $link \ \pointer: } " syntax word:"
|
||||
{ $unchecked-example "FUNCTION: int* foo ( char* bar ) ;" }
|
||||
{ $unchecked-example ": foo ( bar -- int* )
|
||||
pointer: int f \"foo\" { pointer: char } f alien-invoke ;" } } ;
|
||||
|
@ -148,7 +148,7 @@ ARTICLE: "c-types.ambiguity" "Word name clashes with C types"
|
|||
"FUNCTION: float magic_number ( ) ;"
|
||||
"magic_number 3.0 + ."
|
||||
}
|
||||
"The correct solution is to use one of " { $link postpone: \FROM: } ", " { $link postpone: \QUALIFIED: } " or " { $link postpone: \QUALIFIED-WITH: } " to disambiguate word lookup:"
|
||||
"The correct solution is to use one of " { $link \ \FROM: } ", " { $link \ \QUALIFIED: } " or " { $link \ \QUALIFIED-WITH: } " to disambiguate word lookup:"
|
||||
{ $code
|
||||
"USING: alien.syntax math prettyprint ;"
|
||||
"QUALIFIED-WITH: alien.c-types c"
|
||||
|
@ -165,10 +165,10 @@ ARTICLE: "c-types-specs" "C type specifiers"
|
|||
$nl
|
||||
"Defining new C types:"
|
||||
{ $subsections
|
||||
postpone: \STRUCT:
|
||||
postpone: \UNION-STRUCT:
|
||||
postpone: \CALLBACK:
|
||||
postpone: \TYPEDEF:
|
||||
\ \STRUCT:
|
||||
\ \UNION-STRUCT:
|
||||
\ \CALLBACK:
|
||||
\ \TYPEDEF:
|
||||
}
|
||||
"Getting the c-type of a class:"
|
||||
{ $subsections lookup-c-type }
|
||||
|
|
|
@ -20,5 +20,5 @@ HELP: find-library
|
|||
{ $code
|
||||
"<< \"sqlite\" \"sqlite3\" find-library cdecl add-library >>"
|
||||
}
|
||||
"Note the parse time evaluation with " { $link postpone: << } "."
|
||||
"Note the parse time evaluation with " { $link \ << } "."
|
||||
} ;
|
||||
|
|
|
@ -6,10 +6,10 @@ IN: alien.libraries
|
|||
|
||||
HELP: add-library
|
||||
{ $values { "name" string } { "path" string } { "abi" "one of " { $link cdecl } " or " { $link stdcall } } }
|
||||
{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } " and the specified ABI. You can find the location of the library via words in " { $vocab-link "alien.libraries.finder" } ". The logical library name can then be used by a " { $link postpone: \LIBRARY: } " form to specify the logical library for subsequent " { $link postpone: \FUNCTION: } " definitions." }
|
||||
{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } " and the specified ABI. You can find the location of the library via words in " { $vocab-link "alien.libraries.finder" } ". The logical library name can then be used by a " { $link \ \LIBRARY: } " form to specify the logical library for subsequent " { $link \ \FUNCTION: } " definitions." }
|
||||
{ $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " must be placed within a " { $snippet "<< ... >>" } " parse-time evaluation block."
|
||||
$nl
|
||||
"This ensures that if the logical library is later used in the same file, for example by a " { $link postpone: \FUNCTION: } " definition. Otherwise, the " { $link add-library } " call will happen too late, after compilation, and the C function calls will not refer to the correct library."
|
||||
"This ensures that if the logical library is later used in the same file, for example by a " { $link \ \FUNCTION: } " definition. Otherwise, the " { $link add-library } " call will happen too late, after compilation, and the C function calls will not refer to the correct library."
|
||||
$nl
|
||||
"For details about parse-time evaluation, see " { $link "syntax-immediate" } "." }
|
||||
{ $examples "Here is a typical usage of " { $link add-library } ":"
|
||||
|
@ -24,7 +24,7 @@ $nl
|
|||
" [ drop ]"
|
||||
"} cond >>"
|
||||
}
|
||||
"Note the parse time evaluation with " { $link postpone: << } "." } ;
|
||||
"Note the parse time evaluation with " { $link \ << } "." } ;
|
||||
|
||||
HELP: deploy-library
|
||||
{ $values { "name" string } }
|
||||
|
|
|
@ -15,7 +15,7 @@ $nl
|
|||
<byte-vector>
|
||||
}
|
||||
"Literal syntax:"
|
||||
{ $subsections postpone: \BV{ }
|
||||
{ $subsections \ \BV{ }
|
||||
"If you don't care about initial capacity, a more elegant way to create a new byte vector is to write:"
|
||||
{ $code "BV{ } clone" } ;
|
||||
|
||||
|
@ -36,5 +36,5 @@ HELP: >byte-vector
|
|||
HELP: \BV{
|
||||
{ $syntax "BV{ elements... }" }
|
||||
{ $values { "elements" "a list of bytes" } }
|
||||
{ $description "Marks the beginning of a literal byte vector. Literal byte vectors are terminated by " { $link postpone: \} } "." }
|
||||
{ $description "Marks the beginning of a literal byte vector. Literal byte vectors are terminated by " { $link \ \} } "." }
|
||||
{ $examples { $code "BV{ 1 2 3 12 }" } } ;
|
||||
|
|
|
@ -5,7 +5,7 @@ IN: classes.intersection
|
|||
|
||||
ARTICLE: "intersections" "Intersection classes"
|
||||
"An object is an instance of an intersection class if it is an instance of all of its participants."
|
||||
{ $subsections postpone: \INTERSECTION: }
|
||||
{ $subsections \ \INTERSECTION: }
|
||||
{ $subsections define-intersection-class }
|
||||
"Intersection classes can be introspected:"
|
||||
{ $subsections class-participants }
|
||||
|
@ -20,11 +20,11 @@ ABOUT: "intersections"
|
|||
|
||||
HELP: define-intersection-class
|
||||
{ $values { "class" class } { "participants" "a sequence of classes" } }
|
||||
{ $description "Defines a intersection class with specified participants. This is the run time equivalent of " { $link postpone: \INTERSECTION: } "." }
|
||||
{ $description "Defines a intersection class with specified participants. This is the run time equivalent of " { $link \ \INTERSECTION: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "class" } ;
|
||||
|
||||
{ intersection-class define-intersection-class postpone: \INTERSECTION: } related-words
|
||||
{ intersection-class define-intersection-class \ \INTERSECTION: } related-words
|
||||
|
||||
HELP: intersection-class
|
||||
{ $class-description "The class of intersection classes." } ;
|
||||
|
|
|
@ -6,9 +6,9 @@ IN: classes.maybe
|
|||
ABOUT: "maybes"
|
||||
|
||||
ARTICLE: "maybes" "Maybe classes"
|
||||
"A " { $snippet "maybe" } " is an anonymous union class (" { $link "unions" } ") of its members and the " { $link postpone: f } " class. An object is an instance of a " { $snippet "maybe" } " class if it is either an instance of any of its participants, or " { $link postpone: f } "." $nl
|
||||
"The " { $snippet "maybe" } " classes are used to declare typed slots that are optional for a tuple. Without this mechanism it would be an error to assign " { $link postpone: f } " to such a typed slot, and therefore any tuple containing them without specifying an " { $link postpone: \initial: } " value could not be created with the word " { $link new } "." $nl
|
||||
"A slot with an empty " { $snippet "maybe{ }" } " class can only hold the " { $link postpone: f } " value."
|
||||
"A " { $snippet "maybe" } " is an anonymous union class (" { $link "unions" } ") of its members and the " { $link \ f } " class. An object is an instance of a " { $snippet "maybe" } " class if it is either an instance of any of its participants, or " { $link \ f } "." $nl
|
||||
"The " { $snippet "maybe" } " classes are used to declare typed slots that are optional for a tuple. Without this mechanism it would be an error to assign " { $link \ f } " to such a typed slot, and therefore any tuple containing them without specifying an " { $link \ \initial: } " value could not be created with the word " { $link new } "." $nl
|
||||
"A slot with an empty " { $snippet "maybe{ }" } " class can only hold the " { $link \ f } " value."
|
||||
{ $examples
|
||||
{ $example
|
||||
"USING: prettyprint ;"
|
||||
|
@ -17,4 +17,4 @@ ARTICLE: "maybes" "Maybe classes"
|
|||
"f"
|
||||
}
|
||||
}
|
||||
{ $see-also "unions" postpone: \maybe{ } ;
|
||||
{ $see-also "unions" \ \maybe{ } ;
|
||||
|
|
|
@ -5,8 +5,8 @@ IN: classes.mixin
|
|||
ARTICLE: "mixins" "Mixin classes"
|
||||
"An object is an instance of a union class if it is an instance of one of its members. In this respect, mixin classes are identical to union classes. However, mixin classes have the additional property that they are " { $emphasis "open" } "; new classes can be added to the mixin after the original definition of the mixin."
|
||||
{ $subsections
|
||||
postpone: \MIXIN:
|
||||
postpone: \INSTANCE:
|
||||
\ \MIXIN:
|
||||
\ \INSTANCE:
|
||||
define-mixin-class
|
||||
add-mixin-instance
|
||||
}
|
||||
|
@ -23,16 +23,16 @@ HELP: mixin-class
|
|||
|
||||
HELP: define-mixin-class
|
||||
{ $values { "class" word } }
|
||||
{ $description "Defines a mixin class. This is the run time equivalent of " { $link postpone: \MIXIN: } "." }
|
||||
{ $description "Defines a mixin class. This is the run time equivalent of " { $link \ \MIXIN: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "class" } ;
|
||||
|
||||
HELP: add-mixin-instance
|
||||
{ $values { "class" class } { "mixin" class } }
|
||||
{ $description "Defines a class to be an instance of a mixin class. This is the run time equivalent of " { $link postpone: \INSTANCE: } "." }
|
||||
{ $description "Defines a class to be an instance of a mixin class. This is the run time equivalent of " { $link \ \INSTANCE: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "class" } ;
|
||||
|
||||
{ mixin-class define-mixin-class add-mixin-instance postpone: \MIXIN: postpone: \INSTANCE: } related-words
|
||||
{ mixin-class define-mixin-class add-mixin-instance \ \MIXIN: \ \INSTANCE: } related-words
|
||||
|
||||
ABOUT: "mixins"
|
||||
|
|
|
@ -6,7 +6,7 @@ IN: classes.predicate
|
|||
ARTICLE: "predicates" "Predicate classes"
|
||||
"Predicate classes allow fine-grained control over method dispatch."
|
||||
{ $subsections
|
||||
postpone: \PREDICATE:
|
||||
\ \PREDICATE:
|
||||
define-predicate-class
|
||||
}
|
||||
"The set of predicate classes is a class:"
|
||||
|
@ -19,11 +19,11 @@ ABOUT: "predicates"
|
|||
|
||||
HELP: define-predicate-class
|
||||
{ $values { "class" class } { "superclass" class } { "definition" { $quotation ( superclass -- ? ) } } }
|
||||
{ $description "Defines a predicate class. This is the run time equivalent of " { $link postpone: \PREDICATE: } "." }
|
||||
{ $description "Defines a predicate class. This is the run time equivalent of " { $link \ \PREDICATE: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "class" } ;
|
||||
|
||||
{ predicate-class define-predicate-class postpone: \PREDICATE: } related-words
|
||||
{ predicate-class define-predicate-class \ \PREDICATE: } related-words
|
||||
|
||||
HELP: predicate-class
|
||||
{ $class-description "The class of predicate class words, defined by " { $link postpone: \PREDICATE: } " and documented in " { $link "predicates" } "." } ;
|
||||
{ $class-description "The class of predicate class words, defined by " { $link \ \PREDICATE: } " and documented in " { $link "predicates" } "." } ;
|
||||
|
|
|
@ -4,8 +4,8 @@ IN: classes.singleton
|
|||
ARTICLE: "singletons" "Singleton classes"
|
||||
"A singleton is a class with only one instance and with no state."
|
||||
{ $subsections
|
||||
postpone: \SINGLETON:
|
||||
postpone: \SINGLETONS:
|
||||
\ \SINGLETON:
|
||||
\ \SINGLETONS:
|
||||
define-singleton-class
|
||||
}
|
||||
"The set of all singleton classes is itself a class:"
|
||||
|
@ -17,9 +17,9 @@ ARTICLE: "singletons" "Singleton classes"
|
|||
HELP: define-singleton-class
|
||||
{ $values { "word" "a new word" } }
|
||||
{ $description
|
||||
"Defines a singleton class. This is the run-time equivalent of " { $link postpone: \SINGLETON: } "." } ;
|
||||
"Defines a singleton class. This is the run-time equivalent of " { $link \ \SINGLETON: } "." } ;
|
||||
|
||||
{ postpone: \SINGLETON: define-singleton-class } related-words
|
||||
{ \ \SINGLETON: define-singleton-class } related-words
|
||||
|
||||
HELP: singleton-class
|
||||
{ $class-description "The class of singleton classes." } ;
|
||||
|
|
|
@ -4,7 +4,7 @@ USING: strings help.markup help.syntax ;
|
|||
HELP: invalid-slot-name
|
||||
{ $values { "name" string } }
|
||||
{ $description "Throws an " { $link invalid-slot-name } " error." }
|
||||
{ $error-description "Thrown by " { $link postpone: \TUPLE: } " and " { $link postpone: \ERROR: } " if a suspect token appears as a slot name." }
|
||||
{ $error-description "Thrown by " { $link \ \TUPLE: } " and " { $link \ \ERROR: } " if a suspect token appears as a slot name." }
|
||||
{ $notes "The suspect tokens are chosen so that the following code raises this parse error, instead of silently creating a tuple with garbage slots:"
|
||||
{ $code
|
||||
"TUPLE: my-mistaken-tuple slot-a slot-b"
|
||||
|
|
|
@ -25,7 +25,7 @@ $nl
|
|||
"This feature is mostly intended as an optimization for low-level code designed to avoid integer overflow, or where floating point precision is sufficient. Most code needs to work transparently with large integers, and thus should avoid the coercion behavior by using " { $link integer } " and " { $link real } " in place of " { $link fixnum } " and " { $link float } "." ;
|
||||
|
||||
ARTICLE: "tuple-declarations" "Tuple slot declarations"
|
||||
"The slot specifier syntax of the " { $link postpone: \TUPLE: } " parsing word understands the following slot attributes:"
|
||||
"The slot specifier syntax of the " { $link \ \TUPLE: } " parsing word understands the following slot attributes:"
|
||||
{ $list
|
||||
"class declaration: values must satisfy the class predicate"
|
||||
{ "whether a slot is read only or not (" { $link read-only } ")" }
|
||||
|
@ -91,7 +91,7 @@ ARTICLE: "tuple-constructors" "Tuple constructors"
|
|||
boa
|
||||
}
|
||||
"A shortcut for defining BOA constructors:"
|
||||
{ $subsections postpone: \C: }
|
||||
{ $subsections \ \C: }
|
||||
"By convention, construction logic is encapsulated in a word named after the tuple class surrounded in angle brackets; for example, the constructor word for a " { $snippet "point" } " class might be named " { $snippet "<point>" } "."
|
||||
$nl
|
||||
"Constructors play a part in enforcing the invariant that slot values must always match slot declarations. The " { $link new } " word fills in the tuple with initial values, and " { $link boa } " ensures that the values on the stack match the corresponding slot declarations. See " { $link "tuple-declarations" } "."
|
||||
|
@ -183,7 +183,7 @@ $nl
|
|||
ARTICLE: "tuple-subclassing" "Tuple subclassing"
|
||||
"Tuple subclassing can be used to express natural relationships between classes at the language level. For example, every car " { $emphasis "is a" } " vehicle, so if the " { $snippet "car" } " class subclasses the " { $snippet "vehicle" } " class, it can " { $emphasis "inherit" } " the slots and methods of " { $snippet "vehicle" } "."
|
||||
$nl
|
||||
"To define one tuple class as a subclass of another, use the optional superclass parameter to " { $link postpone: \TUPLE: } ":"
|
||||
"To define one tuple class as a subclass of another, use the optional superclass parameter to " { $link \ \TUPLE: } ":"
|
||||
{ $code
|
||||
"TUPLE: subclass < superclass ... ;"
|
||||
}
|
||||
|
@ -192,11 +192,11 @@ $nl
|
|||
"tuple-inheritance-anti-example"
|
||||
}
|
||||
"Declaring a tuple class final prohibits other classes from subclassing it:"
|
||||
{ $subsections postpone: final }
|
||||
{ $subsections \ final }
|
||||
{ $see-also "call-next-method" "parameterized-constructors" "unions" "mixins" "maybes" } ;
|
||||
|
||||
ARTICLE: "tuple-introspection" "Tuple introspection"
|
||||
"In addition to the slot reader and writer words which " { $link postpone: \TUPLE: } " defines for every tuple class, it is possible to construct and take apart entire tuples in a generic way."
|
||||
"In addition to the slot reader and writer words which " { $link \ \TUPLE: } " defines for every tuple class, it is possible to construct and take apart entire tuples in a generic way."
|
||||
{ $subsections
|
||||
>tuple
|
||||
tuple>array
|
||||
|
@ -279,7 +279,7 @@ ARTICLE: "tuple-examples" "Tuple examples"
|
|||
"An example using subclassing can be found in " { $link "tuple-inheritance-example" } "." ;
|
||||
|
||||
ARTICLE: "tuple-redefinition" "Tuple redefinition"
|
||||
"In the following, the " { $emphasis "direct slots" } " of a tuple class refers to the slot names specified in the " { $link postpone: \TUPLE: } " form defining the tuple class, and the " { $emphasis "effective slots" } " refers to the concatenation of the direct slots together with slots defined on superclasses."
|
||||
"In the following, the " { $emphasis "direct slots" } " of a tuple class refers to the slot names specified in the " { $link \ \TUPLE: } " form defining the tuple class, and the " { $emphasis "effective slots" } " refers to the concatenation of the direct slots together with slots defined on superclasses."
|
||||
$nl
|
||||
"When the " { $emphasis "effective slots" } " of a tuple class change, all instances of the class, including subclasses, are updated."
|
||||
$nl
|
||||
|
@ -304,7 +304,7 @@ ARTICLE: "protocol-slots" "Protocol slots"
|
|||
"A " { $emphasis "protocol slot" } " is one which is assumed to exist by the implementation of a class, without being defined on the class itself. The burden is on subclasses (or mixin instances) to provide this slot."
|
||||
$nl
|
||||
"Protocol slots are defined using a parsing word:"
|
||||
{ $subsections postpone: \SLOT: }
|
||||
{ $subsections \ \SLOT: }
|
||||
"Protocol slots are used where the implementation of a superclass needs to assume that each subclass defines certain slots, however the slots of each subclass are potentially declared with different class specializers, thus preventing the slots from being defined in the superclass."
|
||||
$nl
|
||||
"For example, the " { $link growable } " mixin provides an implementation of the sequence protocol which wraps an underlying sequence, resizing it as necessary when elements are added beyond the length of the sequence. It assumes that the concrete mixin instances define two slots, " { $snippet "length" } " and " { $snippet "underlying" } ". These slots are defined as protocol slots: " { $snippet "SLOT: length" } " and " { $snippet "SLOT: underlying" } ". "
|
||||
|
@ -331,7 +331,7 @@ ARTICLE: "tuples" "Tuples"
|
|||
"Tuples are user-defined classes composed of named slots. They are the central data type of Factor's object system."
|
||||
{ $subsections "tuple-examples" }
|
||||
"A parsing word defines tuple classes:"
|
||||
{ $subsections postpone: \TUPLE: }
|
||||
{ $subsections \ \TUPLE: }
|
||||
"For each tuple class, several words are defined, the class word, a class predicate, and accessor words for each slot."
|
||||
$nl
|
||||
"The class word is used for defining methods on the tuple class; it has the same name as the tuple class. The predicate is named " { $snippet { $emphasis "name" } "?" } ". Initially, no specific words are defined for constructing new instances of the tuple. Constructors must be defined explicitly, and tuple slots are accessed via automatically-generated accessor words."
|
||||
|
@ -358,7 +358,7 @@ HELP: tuple=
|
|||
{ $description "Checks if two tuples have equal slot values. This is the default behavior of " { $link = } " on tuples, unless the tuple class subclasses " { $link identity-tuple } " or implements a method on " { $link equal? } ". In cases where equality has been redefined, this word can be used to get the default semantics if needed." } ;
|
||||
|
||||
HELP: tuple
|
||||
{ $class-description "The class of tuples. This class is further partitioned into disjoint subclasses; each tuple shape defined by " { $link postpone: \TUPLE: } " is a new class."
|
||||
{ $class-description "The class of tuples. This class is further partitioned into disjoint subclasses; each tuple shape defined by " { $link \ \TUPLE: } " is a new class."
|
||||
$nl
|
||||
"Tuple classes have additional word properties:"
|
||||
{ $list
|
||||
|
@ -393,15 +393,15 @@ $low-level-note ;
|
|||
HELP: check-tuple
|
||||
{ $values { "class" class } }
|
||||
{ $description "Throws a " { $link check-tuple } " error if " { $snippet "word" } " is not a tuple class word." }
|
||||
{ $error-description "Thrown if " { $link postpone: \C: } " is called with a word which does not name a tuple class." } ;
|
||||
{ $error-description "Thrown if " { $link \ \C: } " is called with a word which does not name a tuple class." } ;
|
||||
|
||||
HELP: define-tuple-class
|
||||
{ $values { "class" word } { "superclass" class } { "slots" "a sequence of strings" } }
|
||||
{ $description "Defines a tuple class inheriting from " { $snippet "superclass" } " with slots named by " { $snippet "slots" } ". This is the run time equivalent of " { $link postpone: \TUPLE: } "." }
|
||||
{ $description "Defines a tuple class inheriting from " { $snippet "superclass" } " with slots named by " { $snippet "slots" } ". This is the run time equivalent of " { $link \ \TUPLE: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "class" } ;
|
||||
|
||||
{ tuple-class define-tuple-class postpone: \TUPLE: } related-words
|
||||
{ tuple-class define-tuple-class \ \TUPLE: } related-words
|
||||
|
||||
HELP: >tuple
|
||||
{ $values { "seq" sequence } { "tuple" tuple } }
|
||||
|
@ -452,7 +452,7 @@ HELP: boa
|
|||
{ $errors "Throws an error if the slot values do not match class declarations on slots (see " { $link "tuple-declarations" } ")." } ;
|
||||
|
||||
HELP: bad-superclass
|
||||
{ $error-description "Thrown if an attempt is made to subclass a class that is not a tuple class, or a tuple class declared " { $link postpone: final } "." } ;
|
||||
{ $error-description "Thrown if an attempt is made to subclass a class that is not a tuple class, or a tuple class declared " { $link \ final } "." } ;
|
||||
|
||||
HELP: ?offset-of-slot
|
||||
{ $values { "name" string } { "tuple" tuple } { "n/f" { $maybe integer } } }
|
||||
|
|
|
@ -197,9 +197,9 @@ SYMBOL: not-a-tuple-class
|
|||
[ not-a-tuple-class boa ] must-fail
|
||||
[ not-a-tuple-class new ] must-fail
|
||||
|
||||
TUPLE: erg's-reshape-problem a b c d ;
|
||||
TUPLE: ergs-reshape-problem a b c d ;
|
||||
|
||||
C: <erg's-reshape-problem> erg's-reshape-problem
|
||||
C: <ergs-reshape-problem> ergs-reshape-problem
|
||||
|
||||
! Inheritance
|
||||
TUPLE: computer cpu ram ;
|
||||
|
@ -422,15 +422,15 @@ TUPLE: constructor-update-2 < constructor-update-1 yyy zzz ;
|
|||
! Redefinition problem
|
||||
TUPLE: redefinition-problem ;
|
||||
|
||||
UNION: redefinition-problem' redefinition-problem integer ;
|
||||
UNION: redefinition-problem-union redefinition-problem integer ;
|
||||
|
||||
{ t } [ 3 redefinition-problem'? ] unit-test
|
||||
{ t } [ 3 redefinition-problem-union? ] unit-test
|
||||
|
||||
TUPLE: redefinition-problem-2 ;
|
||||
|
||||
"IN: classes.tuple.tests TUPLE: redefinition-problem < redefinition-problem-2 ;" eval( -- )
|
||||
|
||||
{ t } [ 3 redefinition-problem'? ] unit-test
|
||||
{ t } [ 3 redefinition-problem-union? ] unit-test
|
||||
|
||||
! Hardcore unit tests
|
||||
|
||||
|
@ -603,12 +603,12 @@ must-fail-with
|
|||
|
||||
|
||||
{ } [
|
||||
"IN: classes.tuple.tests TUPLE: forget-subclass-test ; TUPLE: forget-subclass-test' < forget-subclass-test ;"
|
||||
"IN: classes.tuple.tests TUPLE: forget-subclass-test ; TUPLE: forget-subclass-test2 < forget-subclass-test ;"
|
||||
<string-reader> "forget-subclass-test" parse-stream
|
||||
drop
|
||||
] unit-test
|
||||
|
||||
{ } [ "forget-subclass-test'" "classes.tuple.tests" lookup-word new "bad-object" set ] unit-test
|
||||
{ } [ "forget-subclass-test2" "classes.tuple.tests" lookup-word new "bad-object" set ] unit-test
|
||||
|
||||
{ } [
|
||||
"IN: classes.tuple.tests TUPLE: forget-subclass-test a ;"
|
||||
|
|
|
@ -5,7 +5,7 @@ IN: classes.union
|
|||
ARTICLE: "unions" "Union classes"
|
||||
"An object is an instance of a union class if it is an instance of one of its members."
|
||||
{ $subsections
|
||||
postpone: \UNION:
|
||||
\ \UNION:
|
||||
define-union-class
|
||||
}
|
||||
"Union classes can be introspected:"
|
||||
|
@ -27,12 +27,12 @@ HELP: (define-union-class)
|
|||
|
||||
HELP: define-union-class
|
||||
{ $values { "class" class } { "members" "a sequence of classes" } }
|
||||
{ $description "Defines a union class with specified members. This is the run time equivalent of " { $link postpone: \UNION: } "." }
|
||||
{ $description "Defines a union class with specified members. This is the run time equivalent of " { $link \ \UNION: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "class"
|
||||
} ;
|
||||
|
||||
{ union-class define-union-class postpone: \UNION: } related-words
|
||||
{ union-class define-union-class \ \UNION: } related-words
|
||||
|
||||
HELP: union-class
|
||||
{ $class-description "The class of union classes." } ;
|
||||
|
|
|
@ -133,7 +133,7 @@ ARTICLE: "booleans" "Booleans"
|
|||
}
|
||||
"Boolean values are most frequently used for " { $link "conditionals" } "."
|
||||
{ $heading "The f object and f class" }
|
||||
"The " { $link f } " object is the unique instance of the " { $link f } " class; the two are distinct objects. The latter is also a parsing word which adds the " { $link f } " object to the parse tree at parse time. To refer to the class itself you must use " { $link postpone: \postpone: } " or " { $link postpone: \\ } " to prevent the parsing word from executing."
|
||||
"The " { $link f } " object is the unique instance of the " { $link f } " class; the two are distinct objects. The latter is also a parsing word which adds the " { $link f } " object to the parse tree at parse time. To refer to the class itself you must use " { $link \ \\ } " or " { $link \ \\ } " to prevent the parsing word from executing."
|
||||
$nl
|
||||
"Here is the " { $link f } " object:"
|
||||
{ $example "f ." "f" }
|
||||
|
@ -144,7 +144,7 @@ $nl
|
|||
"Here is an array containing the " { $link f } " object:"
|
||||
{ $example "{ f } ." "{ f }" }
|
||||
"Here is an array containing the " { $link f } " class:"
|
||||
{ $example "{ postpone: f } ." "{ postpone: f }" }
|
||||
{ $example "{ \ f } ." "{ f }" }
|
||||
"The " { $link f } " object is an instance of the " { $link f } " class:"
|
||||
{ $example "USE: classes" "f class-of ." "postpone: f" }
|
||||
"The " { $link f } " class is an instance of " { $link word } ":"
|
||||
|
@ -203,7 +203,7 @@ $nl
|
|||
{ $subsections call execute }
|
||||
{ $heading "Run-time checked combinators" }
|
||||
"With these combinators, the stack effect of the expression is checked at run time."
|
||||
{ $subsections postpone: \call( postpone: \execute( }
|
||||
{ $subsections \ \call( \ \execute( }
|
||||
"Note that the opening parenthesis is actually part of the word name for " { $snippet "call(" } " and " { $snippet "execute(" } "; they are parsing words, and they read a stack effect until the corresponding closing parenthesis. The underlying words are a bit more verbose, but they can be given non-constant stack effects:"
|
||||
{ $subsections call-effect execute-effect }
|
||||
{ $heading "Unchecked combinators" }
|
||||
|
@ -253,7 +253,7 @@ HELP: execute-effect
|
|||
HELP: execute-effect-unsafe
|
||||
{ $values { "word" word } { "effect" effect } }
|
||||
{ $description "Given a word and a stack effect, executes the word, blindly declaring at runtime that it has the given stack effect. This is a macro which expands given a literal effect parameter, and an arbitrary word which is not required at compile time." }
|
||||
{ $warning "If the word being executed has an incorrect stack effect, undefined behavior will result. User code should use " { $link postpone: \execute( } " instead." } ;
|
||||
{ $warning "If the word being executed has an incorrect stack effect, undefined behavior will result. User code should use " { $link \ \execute( } " instead." } ;
|
||||
|
||||
{ call-effect call-effect-unsafe execute-effect execute-effect-unsafe } related-words
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ ARTICLE: "standard-cli-args" "Command line switches for general usage"
|
|||
"The following command line switches can be passed to a bootstrapped Factor image:"
|
||||
{ $table
|
||||
{ { $snippet "-e=" { $emphasis "code" } } { "This specifies a code snippet to evaluate and then exit Factor." } }
|
||||
{ { $snippet "-run=" { $emphasis "vocab" } } { { $snippet { $emphasis "vocab" } } " is the name of a vocabulary with a " { $link postpone: \MAIN: } " hook to run on startup, for example " { $vocab-link "listener" } " or " { $vocab-link "ui.tools" } "." } }
|
||||
{ { $snippet "-run=" { $emphasis "vocab" } } { { $snippet { $emphasis "vocab" } } " is the name of a vocabulary with a " { $link \ \MAIN: } " hook to run on startup, for example " { $vocab-link "listener" } " or " { $vocab-link "ui.tools" } "." } }
|
||||
{ { $snippet "-no-user-init" } { "Inhibits the running of user initialization files on startup. See " { $link "rc-files" } "." } }
|
||||
} ;
|
||||
|
||||
|
@ -141,7 +141,7 @@ ARTICLE: "command-line" "Command line arguments"
|
|||
{ $code "factor [VM args...] [script] [args...]" }
|
||||
"Zero or more VM arguments can be passed in, followed by an optional script file name. If the script file is specified, it will be run on startup using " { $link run-script } ". Any arguments after the script file are stored in the following variable, with no further processing by Factor itself:"
|
||||
{ $subsections command-line }
|
||||
"Instead of running a script, it is also possible to run a vocabulary; this invokes the vocabulary's " { $link postpone: \MAIN: } " word:"
|
||||
"Instead of running a script, it is also possible to run a vocabulary; this invokes the vocabulary's " { $link \ \MAIN: } " word:"
|
||||
{ $code "factor [system switches...] -run=<vocab name>" }
|
||||
"If no script file or " { $snippet "-run=" } " switch is specified, Factor will start " { $link "listener" } " or " { $link "ui-tools" } ", depending on the operating system."
|
||||
$nl
|
||||
|
@ -165,7 +165,7 @@ $nl
|
|||
|
||||
HELP: run-script
|
||||
{ $values { "file" "a pathname string" } }
|
||||
{ $description "Parses the Factor source code stored in a file and runs it. The initial vocabulary search path is used. If the source file contains a " { $link postpone: \MAIN: } " declaration, the main entry point of the file will be also be executed. Loading messages will be suppressed." }
|
||||
{ $description "Parses the Factor source code stored in a file and runs it. The initial vocabulary search path is used. If the source file contains a " { $link \ \MAIN: } " declaration, the main entry point of the file will be also be executed. Loading messages will be suppressed." }
|
||||
{ $errors "Throws an error if loading the file fails, there input is malformed, or if a runtime error occurs while calling the parsed quotation or executing the main entry point." } ;
|
||||
|
||||
ABOUT: "command-line"
|
||||
|
|
|
@ -30,7 +30,7 @@ $nl
|
|||
ARTICLE: "compilation-units" "Compilation units"
|
||||
"A " { $emphasis "compilation unit" } " scopes a group of related definitions. They are compiled and entered into the system in one atomic operation."
|
||||
$nl
|
||||
"When a source file is being parsed, all definitions are part of a single compilation unit, unless the " { $link postpone: << } " parsing word is used to create nested compilation units."
|
||||
"When a source file is being parsed, all definitions are part of a single compilation unit, unless the " { $link \ << } " parsing word is used to create nested compilation units."
|
||||
$nl
|
||||
"Words defined in a compilation unit may not be called until the compilation unit is finished. The parser detects this case for parsing words and throws a " { $link staging-violation } ". Similarly, an attempt to use a macro from a word defined in the same compilation unit will throw a " { $link transform-expansion-error } ". Calling any other word from within its own compilation unit throws an " { $link undefined } " error."
|
||||
$nl
|
||||
|
|
|
@ -52,7 +52,7 @@ $nl
|
|||
ignore-errors
|
||||
}
|
||||
"Syntax sugar for defining errors:"
|
||||
{ $subsections postpone: \ERROR: }
|
||||
{ $subsections \ \ERROR: }
|
||||
"Unhandled errors are reported in the listener and can be debugged using various tools. See " { $link "debugger" } "."
|
||||
{ $subsections
|
||||
"errors-restartable"
|
||||
|
|
|
@ -52,7 +52,7 @@ $nl
|
|||
ARTICLE: "definitions" "Definitions"
|
||||
"A " { $emphasis "definition" } " is an artifact read from a source file. Words for working with definitions are found in the " { $vocab-link "definitions" } " vocabulary."
|
||||
$nl
|
||||
"Definitions are defined using parsing words. Examples of definitions together with their defining parsing words are words (" { $link postpone: \: } "), methods (" { $link postpone: \M: } "), and vocabularies (" { $link postpone: \IN: } ")."
|
||||
"Definitions are defined using parsing words. Examples of definitions together with their defining parsing words are words (" { $link \ \: } "), methods (" { $link \ \M: } "), and vocabularies (" { $link \ \IN: } ")."
|
||||
$nl
|
||||
"All definitions share some common traits:"
|
||||
{ $list
|
||||
|
@ -68,7 +68,7 @@ $nl
|
|||
"compilation-units"
|
||||
}
|
||||
"A parsing word to remove definitions:"
|
||||
{ $subsections postpone: \FORGET: }
|
||||
{ $subsections \ \FORGET: }
|
||||
{ $see-also "see" "parser" "source-files" "words" "generic" "help-impl" } ;
|
||||
|
||||
ABOUT: "definitions"
|
||||
|
|
|
@ -4,18 +4,18 @@ IN: delegate
|
|||
HELP: define-protocol
|
||||
{ $values { "protocol" "a word for the new protocol" } { "wordlist" "a sequence of words" } }
|
||||
{ $description "Defines a symbol as a protocol." }
|
||||
{ $notes "Usually, " { $link postpone: \PROTOCOL: } " should be used instead. This is only for runtime use." } ;
|
||||
{ $notes "Usually, " { $link \ \PROTOCOL: } " should be used instead. This is only for runtime use." } ;
|
||||
|
||||
HELP: \PROTOCOL:
|
||||
{ $syntax "PROTOCOL: protocol-name words... ;" }
|
||||
{ $description "Defines an explicit protocol, which can be used as a basis for delegation." } ;
|
||||
|
||||
{ define-protocol postpone: \PROTOCOL: } related-words
|
||||
{ define-protocol \ \PROTOCOL: } related-words
|
||||
|
||||
HELP: define-consult
|
||||
{ $values { "consultation" consultation } }
|
||||
{ $description "Defines a class to consult, using the quotation, on the generic words contained in the group." }
|
||||
{ $notes "Usually, " { $link postpone: \CONSULT: } " should be used instead. This is only for runtime use." } ;
|
||||
{ $notes "Usually, " { $link \ \CONSULT: } " should be used instead. This is only for runtime use." } ;
|
||||
|
||||
HELP: \CONSULT:
|
||||
{ $syntax "CONSULT: group class
|
||||
|
@ -33,9 +33,9 @@ HELP: \SLOT-PROTOCOL:
|
|||
{ $syntax "SLOT-PROTOCOL: protocol-name slots... ;" }
|
||||
{ $description "Defines a protocol consisting of reader and writer words for the listed slot names." } ;
|
||||
|
||||
{ define-protocol postpone: \PROTOCOL: } related-words
|
||||
{ define-protocol \ \PROTOCOL: } related-words
|
||||
|
||||
{ define-consult postpone: \BROADCAST: postpone: \CONSULT: } related-words
|
||||
{ define-consult \ \BROADCAST: \ \CONSULT: } related-words
|
||||
|
||||
HELP: group-words
|
||||
{ $values { "group" "a group" } { "words" "an array of words" } }
|
||||
|
@ -52,15 +52,15 @@ $nl
|
|||
$nl
|
||||
"Defining new protocols:"
|
||||
{ $subsections
|
||||
postpone: \PROTOCOL:
|
||||
\ \PROTOCOL:
|
||||
define-protocol
|
||||
}
|
||||
"Defining new protocols consisting of slot accessors:"
|
||||
{ $subsections postpone: \SLOT-PROTOCOL: }
|
||||
{ $subsections \ \SLOT-PROTOCOL: }
|
||||
"Defining consultation:"
|
||||
{ $subsections
|
||||
postpone: \BROADCAST:
|
||||
postpone: \CONSULT:
|
||||
\ \BROADCAST:
|
||||
\ \CONSULT:
|
||||
define-consult
|
||||
}
|
||||
"Every tuple class has an associated protocol consisting of all of its slot accessor methods. The " { $vocab-link "delegate.protocols" } " vocabulary defines formal protocols for the various informal protocols used in the Factor core, such as " { $link "sequence-protocol" } ", " { $link "assocs-protocol" } " or " { $link "stream-protocol" } ;
|
||||
|
|
|
@ -3,7 +3,7 @@ sequences strings words ;
|
|||
IN: effects
|
||||
|
||||
ARTICLE: "effects" "Stack effect declarations"
|
||||
"Word definition words such as " { $link postpone: \: } " and " { $link postpone: \GENERIC: } " have a " { $emphasis "stack effect declaration" } " as part of their syntax. A stack effect declaration takes the following form:"
|
||||
"Word definition words such as " { $link \ \: } " and " { $link \ \GENERIC: } " have a " { $emphasis "stack effect declaration" } " as part of their syntax. A stack effect declaration takes the following form:"
|
||||
{ $code "( input1 input2 ... -- output1 ... )" }
|
||||
"Stack elements in a stack effect are ordered so that the top of the stack is on the right side. Here is an example:"
|
||||
{ $synopsis + }
|
||||
|
@ -13,7 +13,7 @@ ARTICLE: "effects" "Stack effect declarations"
|
|||
{ $synopsis while }
|
||||
{ $synopsis if* }
|
||||
{ $synopsis each }
|
||||
"For words that are not " { $link postpone: inline } ", only the number of inputs and outputs carries semantic meaning, and effect variables are ignored. However, nested quotation declarations are enforced for inline words. Nested quotation declarations are optional for non-recursive inline combinators and only provide better error messages. However, quotation inputs to " { $link postpone: recursive } " combinators must have an effect declared. See " { $link "inference-recursive-combinators" } "."
|
||||
"For words that are not " { $link \ inline } ", only the number of inputs and outputs carries semantic meaning, and effect variables are ignored. However, nested quotation declarations are enforced for inline words. Nested quotation declarations are optional for non-recursive inline combinators and only provide better error messages. However, quotation inputs to " { $link \ recursive } " combinators must have an effect declared. See " { $link "inference-recursive-combinators" } "."
|
||||
$nl
|
||||
"In concatenative code, input and output names are for documentation purposes only and certain conventions have been established to make them more descriptive. For code written with " { $link "locals" } ", stack values are bound to local variables named by the stack effect's input parameters."
|
||||
$nl
|
||||
|
@ -100,7 +100,7 @@ f { \"a\" \"b\" } f { \"c\" } <variable-effect> ." "( a b -- c )" }
|
|||
{ <effect> <terminated-effect> <variable-effect> } related-words
|
||||
|
||||
ARTICLE: "effects-variables" "Stack effect row variables"
|
||||
"The stack effect of many " { $link postpone: inline } " combinators can have variable stack effects, depending on the effect of the quotation they call. For example, the quotation parameter to " { $link each } " receives an element from the input sequence each time it is called, but it can also manipulate values on the stack below the element as long as it leaves the same number of elements on the stack. (This is how " { $link reduce } " is implemented in terms of " { $snippet "each" } ".) The stack effect of an " { $snippet "each" } " expression thus depends on the stack effect of its input quotation:"
|
||||
"The stack effect of many " { $link \ inline } " combinators can have variable stack effects, depending on the effect of the quotation they call. For example, the quotation parameter to " { $link each } " receives an element from the input sequence each time it is called, but it can also manipulate values on the stack below the element as long as it leaves the same number of elements on the stack. (This is how " { $link reduce } " is implemented in terms of " { $snippet "each" } ".) The stack effect of an " { $snippet "each" } " expression thus depends on the stack effect of its input quotation:"
|
||||
{ $example
|
||||
"USING: io sequences stack-checker ;
|
||||
[ [ write ] each ] infer."
|
||||
|
@ -113,7 +113,7 @@ ARTICLE: "effects-variables" "Stack effect row variables"
|
|||
{ $synopsis each }
|
||||
"Using the same variable name in both the inputs and outputs (in the above case of " { $snippet "each" } ", " { $snippet "..." } ") indicates that the number of additional inputs and outputs must be the same. Using different variable names indicates that they can be independent. In combinators with multiple quotation inputs, the number of inputs or outputs represented by a particular " { $snippet ".." } " name must match among all of the quotations. For example, the branches of " { $link if* } " can take a different number of inputs from outputs, as long as they both have the same stack height. The true branch receives the test value as an added input. This is declared as follows:"
|
||||
{ $synopsis if* }
|
||||
"Stack effect variables can only occur as the first input or first output of a stack effect; names starting in " { $snippet ".." } " cause a syntax error if they occur elsewhere in the effect. For words that are not " { $link postpone: inline } ", effect variables are currently ignored by the stack checker." ;
|
||||
"Stack effect variables can only occur as the first input or first output of a stack effect; names starting in " { $snippet ".." } " cause a syntax error if they occur elsewhere in the effect. For words that are not " { $link \ inline } ", effect variables are currently ignored by the stack checker." ;
|
||||
|
||||
ABOUT: "effects"
|
||||
|
||||
|
@ -144,4 +144,4 @@ HELP: effect>string
|
|||
|
||||
HELP: stack-effect
|
||||
{ $values { "word" word } { "effect/f" { $maybe effect } } }
|
||||
{ $description "Outputs the stack effect of a word; either a stack effect declared with " { $link postpone: \( } ", or an inferred stack effect (see " { $link "inference" } ")." } ;
|
||||
{ $description "Outputs the stack effect of a word; either a stack effect declared with " { $link \ \( } ", or an inferred stack effect (see " { $link "inference" } ")." } ;
|
||||
|
|
|
@ -4,5 +4,5 @@ USING: strings effects help.markup help.syntax ;
|
|||
HELP: parse-effect
|
||||
{ $values { "end" string } { "effect" "an instance of " { $link effect } } }
|
||||
{ $description "Parses a stack effect from the current input line." }
|
||||
{ $examples "This word is used by " { $link postpone: \( } " to parse stack effect declarations." }
|
||||
{ $examples "This word is used by " { $link \ \( } " to parse stack effect declarations." }
|
||||
$parsing-note ;
|
||||
|
|
|
@ -12,7 +12,7 @@ HELP: @
|
|||
HELP: fry
|
||||
{ $values { "quot" quotation } { "quot'" quotation } }
|
||||
{ $description "Outputs a quotation that when called, fries " { $snippet "quot" } " by taking values from the stack and substituting them in." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \'[ } "; the following two lines are equivalent:"
|
||||
{ $notes "This word is used to implement " { $link \ \'[ } "; the following two lines are equivalent:"
|
||||
{ $code "[ X ] fry call" "'[ X ]" }
|
||||
}
|
||||
{ $examples "See " { $link "fry.examples" } "." } ;
|
||||
|
@ -23,12 +23,12 @@ HELP: \'[
|
|||
{ $examples "See " { $link "fry.examples" } "." } ;
|
||||
|
||||
HELP: >r/r>-in-fry-error
|
||||
{ $error-description "Thrown by " { $link postpone: \'[ } " if the fried quotation contains calls to retain stack manipulation primitives." } ;
|
||||
{ $error-description "Thrown by " { $link \ \'[ } " if the fried quotation contains calls to retain stack manipulation primitives." } ;
|
||||
|
||||
ARTICLE: "fry.examples" "Examples of fried quotations"
|
||||
"The easiest way to understand fried quotations is to look at some examples."
|
||||
$nl
|
||||
"If a quotation does not contain any fry specifiers, then " { $link postpone: \'[ } " behaves just like " { $link postpone: \[ } ":"
|
||||
"If a quotation does not contain any fry specifiers, then " { $link \ \'[ } " behaves just like " { $link \ \[ } ":"
|
||||
{ $code "{ 10 20 30 } '[ . ] each" }
|
||||
"Occurrences of " { $link _ } " on the left map directly to " { $link curry } ". That is, the following three lines are equivalent:"
|
||||
{ $code
|
||||
|
@ -80,7 +80,7 @@ ARTICLE: "fry" "Fried quotations"
|
|||
"The " { $vocab-link "fry" } " vocabulary implements " { $emphasis "fried quotation" } ". Conceptually, fried quotations are quotations with “holes” (more formally, " { $emphasis "fry specifiers" } "), and the holes are filled in when the fried quotation is pushed on the stack."
|
||||
$nl
|
||||
"Fried quotations are started by a special parsing word:"
|
||||
{ $subsections postpone: \'[ }
|
||||
{ $subsections \ \'[ }
|
||||
"There are two types of fry specifiers; the first can hold a value, and the second “splices” a quotation, as if it were inserted without surrounding brackets:"
|
||||
{ $subsections
|
||||
_
|
||||
|
|
|
@ -22,7 +22,7 @@ $nl
|
|||
{ $subsections order } ;
|
||||
|
||||
ARTICLE: "generic-introspection" "Generic word introspection"
|
||||
"In most cases, generic words and methods are defined at parse time with " { $link postpone: \GENERIC: } " (or some other parsing word) and " { $link postpone: \M: } "."
|
||||
"In most cases, generic words and methods are defined at parse time with " { $link \ \GENERIC: } " (or some other parsing word) and " { $link \ \M: } "."
|
||||
$nl
|
||||
"Sometimes, generic words need to be inspected or defined at run time; words for performing these tasks are found in the " { $vocab-link "generic" } " vocabulary."
|
||||
$nl
|
||||
|
@ -49,7 +49,7 @@ $nl
|
|||
"Low-level method constructor:"
|
||||
{ $subsections <method> }
|
||||
"Methods may be pushed on the stack with a literal syntax:"
|
||||
{ $subsections postpone: \M\\ }
|
||||
{ $subsections \ \M\\ }
|
||||
{ $see-also "see" } ;
|
||||
|
||||
ARTICLE: "method-combination" "Custom method combination"
|
||||
|
@ -60,10 +60,10 @@ ARTICLE: "method-combination" "Custom method combination"
|
|||
}
|
||||
"A table of built-in method combination defining words, and the method combinations themselves:"
|
||||
{ $table
|
||||
{ { $link postpone: \GENERIC: } { $link standard-combination } }
|
||||
{ { $link postpone: \GENERIC#: } { $link standard-combination } }
|
||||
{ { $link postpone: \HOOK: } { $link hook-combination } }
|
||||
{ { $link postpone: \MATH: } { $link math-combination } }
|
||||
{ { $link \ \GENERIC: } { $link standard-combination } }
|
||||
{ { $link \ \GENERIC#: } { $link standard-combination } }
|
||||
{ { $link \ \HOOK: } { $link hook-combination } }
|
||||
{ { $link \ \MATH: } { $link math-combination } }
|
||||
}
|
||||
"Developing a custom method combination requires that a parsing word calling " { $link define-generic } " be defined; additionally, it is a good idea to implement the " { $link "definition-protocol" } " on the class of words having this method combination, to properly support developer tools."
|
||||
$nl
|
||||
|
@ -74,12 +74,12 @@ ARTICLE: "call-next-method" "Calling less-specific methods"
|
|||
"If a generic word is called with an object and multiple methods specialize on classes that this object is an instance of, usually the most specific method is called (" { $link "method-order" } ")."
|
||||
$nl
|
||||
"Less-specific methods can be called directly:"
|
||||
{ $subsections postpone: call-next-method }
|
||||
{ $subsections \ call-next-method }
|
||||
"A lower-level word which the above expands into:"
|
||||
{ $subsections (call-next-method) }
|
||||
"To look up the next applicable method reflectively:"
|
||||
{ $subsections next-method }
|
||||
"Errors thrown by improper calls to " { $link postpone: call-next-method } ":"
|
||||
"Errors thrown by improper calls to " { $link \ call-next-method } ":"
|
||||
{ $subsections
|
||||
inconsistent-next-method
|
||||
no-next-method
|
||||
|
@ -91,15 +91,15 @@ $nl
|
|||
"A generic word behaves roughly like a long series of class predicate conditionals in a " { $link cond } " form, however methods can be defined in independent source files, reducing coupling and increasing extensibility. The method combination determines which object the generic word will " { $emphasis "dispatch" } " on; this could be the top of the stack, or some other value."
|
||||
$nl
|
||||
"Generic words which dispatch on the object at the top of the stack:"
|
||||
{ $subsections postpone: \GENERIC: }
|
||||
{ $subsections \ \GENERIC: }
|
||||
"A method combination which dispatches on a specified stack position:"
|
||||
{ $subsections postpone: \GENERIC#: }
|
||||
{ $subsections \ \GENERIC#: }
|
||||
"A method combination which dispatches on the value of a variable at the time the generic word is called:"
|
||||
{ $subsections postpone: \HOOK: }
|
||||
{ $subsections \ \HOOK: }
|
||||
"A method combination which dispatches on a pair of stack values, which must be numbers, and upgrades both to the same type of number:"
|
||||
{ $subsections postpone: \MATH: }
|
||||
{ $subsections \ \MATH: }
|
||||
"Method definition:"
|
||||
{ $subsections postpone: \M: }
|
||||
{ $subsections \ \M: }
|
||||
"Generic words must declare their stack effect in order to compile. See " { $link "effects" } "."
|
||||
{ $subsections
|
||||
"method-order"
|
||||
|
@ -114,7 +114,7 @@ ABOUT: "generic"
|
|||
HELP: generic
|
||||
{ $class-description "The class of generic words, documented in " { $link "generic" } "." } ;
|
||||
|
||||
{ generic define-generic define-simple-generic postpone: \GENERIC: postpone: \GENERIC#: postpone: \MATH: postpone: \HOOK: } related-words
|
||||
{ generic define-generic define-simple-generic \ \GENERIC: \ \GENERIC#: \ \MATH: \ \HOOK: } related-words
|
||||
|
||||
HELP: make-generic
|
||||
{ $values { "word" generic } }
|
||||
|
@ -143,7 +143,7 @@ HELP: ?lookup-method
|
|||
{ $values { "class" class } { "generic" generic } { "method/f" { $maybe method } } }
|
||||
{ $description "Looks up a method definition." } ;
|
||||
|
||||
{ lookup-method ?lookup-method create-method postpone: \M: } related-words
|
||||
{ lookup-method ?lookup-method create-method \ \M: } related-words
|
||||
|
||||
HELP: <method>
|
||||
{ $values { "class" class } { "generic" generic } { "method" "a new method definition" } }
|
||||
|
@ -156,7 +156,7 @@ HELP: order
|
|||
HELP: check-method
|
||||
{ $values { "class" class } { "generic" generic } }
|
||||
{ $description "Asserts that " { $snippet "class" } " is a class word and " { $snippet "generic" } " is a generic word, throwing a " { $link check-method } " error if the assertion fails." }
|
||||
{ $error-description "Thrown if " { $link postpone: \M: } " or " { $link create-method } " is given an invalid class or generic word." } ;
|
||||
{ $error-description "Thrown if " { $link \ \M: } " or " { $link create-method } " is given an invalid class or generic word." } ;
|
||||
|
||||
HELP: with-methods
|
||||
{ $values { "class" class } { "generic" generic } { "quot" { $quotation ( methods -- ) } } }
|
||||
|
@ -165,16 +165,16 @@ $low-level-note ;
|
|||
|
||||
HELP: create-method
|
||||
{ $values { "class" class } { "generic" generic } { "method" method } }
|
||||
{ $description "Creates a method or returns an existing one. This is the runtime equivalent of " { $link postpone: \M: } "." }
|
||||
{ $description "Creates a method or returns an existing one. This is the runtime equivalent of " { $link \ \M: } "." }
|
||||
{ $notes "To define a method, pass the output value to " { $link define } "." } ;
|
||||
|
||||
{ sort-classes order } related-words
|
||||
|
||||
HELP: (call-next-method)
|
||||
{ $values { "method" method } }
|
||||
{ $description "Low-level word implementing " { $link postpone: call-next-method } "." }
|
||||
{ $description "Low-level word implementing " { $link \ call-next-method } "." }
|
||||
{ $notes
|
||||
"The " { $link postpone: call-next-method } " word parses into this word. The following are equivalent:"
|
||||
"The " { $link \ call-next-method } " word parses into this word. The following are equivalent:"
|
||||
{ $code
|
||||
"M: class generic call-next-method ;"
|
||||
"M: class generic M\\\\ class generic (call-next-method) ;"
|
||||
|
@ -182,7 +182,7 @@ HELP: (call-next-method)
|
|||
} ;
|
||||
|
||||
HELP: no-next-method
|
||||
{ $error-description "Thrown by " { $link postpone: call-next-method } " if the current method is already the least specific method." }
|
||||
{ $error-description "Thrown by " { $link \ call-next-method } " if the current method is already the least specific method." }
|
||||
{ $examples
|
||||
"The following code throws this error:"
|
||||
{ $code
|
||||
|
@ -194,5 +194,5 @@ HELP: no-next-method
|
|||
""
|
||||
"123 error-test"
|
||||
}
|
||||
"This results in the method on " { $link integer } " being called, which then calls the method on " { $link number } ". The latter then calls " { $link postpone: call-next-method } ", however there is no method less specific than the method on " { $link number } " and so an error is thrown."
|
||||
"This results in the method on " { $link integer } " being called, which then calls the method on " { $link number } ". The latter then calls " { $link \ call-next-method } ", however there is no method less specific than the method on " { $link number } " and so an error is thrown."
|
||||
} ;
|
||||
|
|
|
@ -4,7 +4,7 @@ IN: generic.hook
|
|||
|
||||
HELP: hook-combination
|
||||
{ $class-description
|
||||
"Performs hook method combination . See " { $link postpone: \HOOK: } "."
|
||||
"Performs hook method combination . See " { $link \ \HOOK: } "."
|
||||
} ;
|
||||
|
||||
{ standard-combination hook-combination } related-words
|
||||
|
|
|
@ -26,7 +26,7 @@ HELP: no-math-method
|
|||
HELP: math-method
|
||||
{ $values { "word" generic } { "class1" class } { "class2" class } { "quot" quotation } }
|
||||
{ $description "Generates a definition for " { $snippet "word" } " when the two inputs are instances of " { $snippet "class1" } " and " { $snippet "class2" } ", respectively." }
|
||||
{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip M\\ float + ]" } } ;
|
||||
{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip M\\\\ float + ]" } } ;
|
||||
|
||||
HELP: math-class
|
||||
{ $class-description "The class of subtypes of " { $link number } " which are not " { $link null } "." } ;
|
||||
|
|
|
@ -8,7 +8,7 @@ HELP: no-method
|
|||
{ $error-description "Thrown by the " { $snippet "generic" } " word to indicate it does not have a method for the class of " { $snippet "object" } "." } ;
|
||||
|
||||
HELP: inconsistent-next-method
|
||||
{ $error-description "Thrown by " { $link postpone: call-next-method } " if the values on the stack are not compatible with the current method." }
|
||||
{ $error-description "Thrown by " { $link \ call-next-method } " if the values on the stack are not compatible with the current method." }
|
||||
{ $examples
|
||||
"The following code throws this error:"
|
||||
{ $code
|
||||
|
@ -20,7 +20,7 @@ HELP: inconsistent-next-method
|
|||
""
|
||||
"123 error-test"
|
||||
}
|
||||
"This results in the method on " { $link integer } " being called, which then passes a string to " { $link postpone: call-next-method } ". However, this fails because the string is not compatible with the current method."
|
||||
"This results in the method on " { $link integer } " being called, which then passes a string to " { $link \ call-next-method } ". However, this fails because the string is not compatible with the current method."
|
||||
$nl
|
||||
"This usually indicates programmer error; if the intention above was to call the string method on the result of " { $link number>string } ", the code should be rewritten as follows:"
|
||||
{ $code "M: integer error-test number>string error-test ;" }
|
||||
|
|
|
@ -11,7 +11,7 @@ $nl
|
|||
"In some cases, specialization will not help at all, and can make generated code slower from the increase in code size. The compiler is capable of inferring enough static type information to generate efficient code in many cases without explicit help from the programmer. Specializers should be used as a last resort, after profiling shows that a critical loop makes a lot of repeated calls to generic words which dispatch on the same class."
|
||||
$nl
|
||||
"Type hints are declared with a parsing word:"
|
||||
{ $subsections postpone: \HINTS: }
|
||||
{ $subsections \ \HINTS: }
|
||||
"The specialized version of a word which will be compiled by the compiler can be inspected:"
|
||||
{ $subsections specialized-def } ;
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ ARTICLE: "io.pathnames.presentations" "Pathname presentations"
|
|||
<pathname>
|
||||
}
|
||||
"Literal pathname presentations:"
|
||||
{ $subsections postpone: \path" }
|
||||
{ $subsections \ \path" }
|
||||
"Many words that accept pathname strings can also work on pathname presentations." ;
|
||||
|
||||
ARTICLE: "io.pathnames" "Pathnames"
|
||||
|
|
|
@ -166,7 +166,7 @@ HELP: ?
|
|||
{ $description "Chooses between two values depending on the boolean value of " { $snippet "cond" } "." } ;
|
||||
|
||||
HELP: boolean
|
||||
{ $class-description "A union of the " { $link postpone: t } " and " { $link postpone: f } " classes." } ;
|
||||
{ $class-description "A union of the " { $link \ t } " and " { $link \ f } " classes." } ;
|
||||
|
||||
HELP: >boolean
|
||||
{ $values { "obj" "a generalized boolean" } { "?" boolean } }
|
||||
|
@ -229,12 +229,12 @@ HELP: same?
|
|||
|
||||
HELP: execute
|
||||
{ $values { "word" word } }
|
||||
{ $description "Executes a word. Words which " { $link execute } " an input parameter must be declared " { $link postpone: inline } " so that a caller which passes in a literal word can have a static stack effect." }
|
||||
{ $description "Executes a word. Words which " { $link execute } " an input parameter must be declared " { $link \ inline } " so that a caller which passes in a literal word can have a static stack effect." }
|
||||
{ $examples
|
||||
{ $example "USING: kernel io words ;" "IN: scratchpad" ": twice ( word -- ) dup execute execute ; inline\n: hello ( -- ) \"Hello\" print ;\n\\ hello twice" "Hello\nHello" }
|
||||
} ;
|
||||
|
||||
{ execute postpone: \execute( } related-words
|
||||
{ execute \ \execute( } related-words
|
||||
|
||||
HELP: (execute)
|
||||
{ $values { "word" word } }
|
||||
|
@ -243,13 +243,13 @@ HELP: (execute)
|
|||
|
||||
HELP: call
|
||||
{ $values { "callable" callable } }
|
||||
{ $description "Calls a quotation. Words which " { $link call } " an input parameter must be declared " { $link postpone: inline } " so that a caller which passes in a literal quotation can have a static stack effect." }
|
||||
{ $description "Calls a quotation. Words which " { $link call } " an input parameter must be declared " { $link \ inline } " so that a caller which passes in a literal quotation can have a static stack effect." }
|
||||
{ $examples
|
||||
"The following two lines are equivalent:"
|
||||
{ $code "2 [ 2 + 3 * ] call" "2 2 + 3 *" }
|
||||
} ;
|
||||
|
||||
{ call postpone: \call( } related-words
|
||||
{ call \ \call( } related-words
|
||||
|
||||
HELP: keep
|
||||
{ $values { "x" object } { "quot" { $quotation ( ..a x -- ..b ) } } }
|
||||
|
|
|
@ -274,7 +274,7 @@ PRIVATE>
|
|||
: tri-curry@ ( x y z q -- p' q' r' ) currier tri@ ; inline
|
||||
|
||||
! Booleans
|
||||
UNION: boolean postpone: t postpone: f ;
|
||||
UNION: boolean t postpone: f ;
|
||||
|
||||
: >boolean ( obj -- ? ) [ t ] [ f ] if ; inline
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ HELP: still-parsing?
|
|||
HELP: each-token
|
||||
{ $values { "end" string } { "quot" { $quotation ( ... token -- ... ) } } }
|
||||
{ $description "Reads a sequence of tokens until the first occurrence of " { $snippet "end" } ". " { $snippet "quot" } " is called on each token as it is read." }
|
||||
{ $examples "This word is used to implement " { $link postpone: \USING: } "." }
|
||||
{ $examples "This word is used to implement " { $link \ \USING: } "." }
|
||||
$parsing-note ;
|
||||
|
||||
HELP: map-tokens
|
||||
|
|
|
@ -9,12 +9,12 @@ HELP: \|[
|
|||
|
||||
HELP: \let[
|
||||
{ $syntax "let[ code :> var code :> var code... ]" }
|
||||
{ $description "Establishes a new scope for lexical variable bindings. Variables bound with " { $link postpone: \:> } " within the body of the " { $snippet "let[" } " will be lexically scoped to the body of the " { $snippet "let[" } " form." }
|
||||
{ $description "Establishes a new scope for lexical variable bindings. Variables bound with " { $link \ \:> } " within the body of the " { $snippet "let[" } " will be lexically scoped to the body of the " { $snippet "let[" } " form." }
|
||||
{ $examples "See " { $link "locals-examples" } "." } ;
|
||||
|
||||
HELP: :>
|
||||
{ $syntax ":> var" ":> var!" ":> ( var-1 var-2 ... )" }
|
||||
{ $description "Binds one or more new lexical variables. In the " { $snippet ":> var" } " form, the value on the top of the datastack is bound to a new lexical variable named " { $snippet "var" } " and is scoped to the enclosing quotation, " { $link postpone: \let[ } " form, or " { $link postpone: \:: } " definition."
|
||||
{ $description "Binds one or more new lexical variables. In the " { $snippet ":> var" } " form, the value on the top of the datastack is bound to a new lexical variable named " { $snippet "var" } " and is scoped to the enclosing quotation, " { $link \ \let[ } " form, or " { $link \ \:: } " definition."
|
||||
$nl
|
||||
"The " { $snippet ":> ( var-1 ... )" } " form binds multiple variables to the top values of the datastack in right to left order, with the last variable bound to the top of the datastack. These two snippets have the same effect:"
|
||||
{ $code ":> c :> b :> a" }
|
||||
|
@ -22,20 +22,20 @@ $nl
|
|||
$nl
|
||||
"If any " { $snippet "var" } " name is followed by an exclamation point (" { $snippet "!" } "), that new variable is mutable. See " { $link "locals-mutable" } " for more information." }
|
||||
{ $notes
|
||||
"This syntax can only be used inside a lexical scope established by a " { $link postpone: \:: } " definition, " { $link postpone: \let[ } " form, or " { $link postpone: \|[ } " quotation. Normal quotations have their own lexical scope only if they are inside an outer scope. Definition forms such as " { $link postpone: \: } " do not establish a lexical scope by themselves unless documented otherwise, nor is there a lexical scope available at the top level of source files or in the listener. " { $link postpone: \let[ } " can be used to create a lexical scope where one is not otherwise available." }
|
||||
"This syntax can only be used inside a lexical scope established by a " { $link \ \:: } " definition, " { $link \ \let[ } " form, or " { $link \ \|[ } " quotation. Normal quotations have their own lexical scope only if they are inside an outer scope. Definition forms such as " { $link \ \: } " do not establish a lexical scope by themselves unless documented otherwise, nor is there a lexical scope available at the top level of source files or in the listener. " { $link \ \let[ } " can be used to create a lexical scope where one is not otherwise available." }
|
||||
{ $examples "See " { $link "locals-examples" } "." } ;
|
||||
|
||||
{ postpone: \let[ postpone: \:> } related-words
|
||||
{ \ \let[ \ \:> } related-words
|
||||
|
||||
HELP: ::
|
||||
{ $syntax ":: word ( vars... -- outputs... ) body... ;" }
|
||||
{ $description "Defines a word with named inputs. The word binds its input values to lexical variables from left to right, then executes the body with those bindings in scope."
|
||||
$nl
|
||||
"If any " { $snippet "var" } " name is followed by an exclamation point (" { $snippet "!" } "), the corresponding new variable is made mutable. See " { $link "locals-mutable" } " for more information." }
|
||||
{ $notes "The names of the " { $snippet "outputs" } " do not affect the word's behavior. However, the compiler verifies that the stack effect accurately represents the number of outputs as with " { $link postpone: \: } " definitions." }
|
||||
{ $notes "The names of the " { $snippet "outputs" } " do not affect the word's behavior. However, the compiler verifies that the stack effect accurately represents the number of outputs as with " { $link \ \: } " definitions." }
|
||||
{ $examples "See " { $link "locals-examples" } "." } ;
|
||||
|
||||
{ postpone: \: postpone: \:: } related-words
|
||||
{ \ \: \ \:: } related-words
|
||||
|
||||
HELP: \MACRO::
|
||||
{ $syntax "MACRO:: word ( vars... -- outputs... ) body... ;" }
|
||||
|
@ -45,7 +45,7 @@ $nl
|
|||
{ $notes "The expansion of a macro cannot reference lexical variables bound in the outer scope. There are also limitations on passing arguments involving lexical variables into macros. See " { $link "locals-limitations" } " for details." }
|
||||
{ $examples "See " { $link "locals-examples" } "." } ;
|
||||
|
||||
{ postpone: \MACRO: postpone: \MACRO:: } related-words
|
||||
{ \ \MACRO: \ \MACRO:: } related-words
|
||||
|
||||
HELP: \MEMO::
|
||||
{ $syntax "MEMO:: word ( vars... -- outputs... ) body... ;" }
|
||||
|
@ -54,21 +54,21 @@ $nl
|
|||
"If any " { $snippet "var" } " name is followed by an exclamation point (" { $snippet "!" } "), the corresponding new variable is made mutable. See " { $link "locals-mutable" } " for more information." }
|
||||
{ $examples "See " { $link "locals-examples" } "." } ;
|
||||
|
||||
{ postpone: \MEMO: postpone: \MEMO:: } related-words
|
||||
{ \ \MEMO: \ \MEMO:: } related-words
|
||||
|
||||
HELP: \M::
|
||||
{ $syntax "M:: class generic ( vars... -- outputs... ) body... ;" }
|
||||
{ $description "Defines a new method on " { $snippet "generic" } " for " { $snippet "class" } " with named inputs. The method binds its input values to lexical variables from left to right, then executes the body with those bindings in scope."
|
||||
$nl
|
||||
"If any " { $snippet "var" } " name is followed by an exclamation point (" { $snippet "!" } "), the corresponding new variable is made mutable. See " { $link "locals-mutable" } " for more information." }
|
||||
{ $notes "The names of the " { $snippet "outputs" } " do not affect the word's behavior. However, the compiler verifies that the stack effect accurately represents the number of outputs as with " { $link postpone: \M: } " definitions." }
|
||||
{ $notes "The names of the " { $snippet "outputs" } " do not affect the word's behavior. However, the compiler verifies that the stack effect accurately represents the number of outputs as with " { $link \ \M: } " definitions." }
|
||||
{ $examples "See " { $link "locals-examples" } "." } ;
|
||||
|
||||
{ postpone: \M: postpone: \M:: } related-words
|
||||
{ \ \M: \ \M:: } related-words
|
||||
|
||||
ARTICLE: "locals-examples" "Examples of lexical variables"
|
||||
{ $heading "Definitions with lexical variables" }
|
||||
"The following example demonstrates lexical variable bindings in word definitions. The " { $snippet "quadratic-roots" } " word is defined with " { $link postpone: \:: } ", so it takes its inputs from the top three elements of the datastack and binds them to the variables " { $snippet "a" } ", " { $snippet "b" } ", and " { $snippet "c" } ". In the body, the " { $snippet "disc" } " variable is bound using " { $link postpone: \:> } " and then used in the following line of code."
|
||||
"The following example demonstrates lexical variable bindings in word definitions. The " { $snippet "quadratic-roots" } " word is defined with " { $link \ \:: } ", so it takes its inputs from the top three elements of the datastack and binds them to the variables " { $snippet "a" } ", " { $snippet "b" } ", and " { $snippet "c" } ". In the body, the " { $snippet "disc" } " variable is bound using " { $link \ \:> } " and then used in the following line of code."
|
||||
{ $example "USING: locals math math.functions kernel ;
|
||||
IN: scratchpad
|
||||
:: quadratic-roots ( a b c -- x y )
|
||||
|
@ -77,7 +77,7 @@ IN: scratchpad
|
|||
1.0 1.0 -6.0 quadratic-roots"
|
||||
"\n--- Data stack:\n2.0\n-3.0"
|
||||
}
|
||||
"If you wanted to perform the quadratic formula interactively from the listener, you could use " { $link postpone: \let[ } " to provide a scope for the variables:"
|
||||
"If you wanted to perform the quadratic formula interactively from the listener, you could use " { $link \ \let[ } " to provide a scope for the variables:"
|
||||
{ $example "USING: locals math math.functions kernel ;
|
||||
IN: scratchpad
|
||||
let[ 1.0 :> a 1.0 :> b -6.0 :> c
|
||||
|
@ -90,7 +90,7 @@ let[ 1.0 :> a 1.0 :> b -6.0 :> c
|
|||
$nl
|
||||
|
||||
{ $heading "Quotations with lexical variables, and closures" }
|
||||
"These next two examples demonstrate lexical variable bindings in quotations defined with " { $link postpone: \|[ } ". In this example, the values " { $snippet "5" } " and " { $snippet "3" } " are put on the datastack. When the quotation is called, it takes those values as inputs and binds them respectively to " { $snippet "m" } " and " { $snippet "n" } " before executing the quotation:"
|
||||
"These next two examples demonstrate lexical variable bindings in quotations defined with " { $link \ \|[ } ". In this example, the values " { $snippet "5" } " and " { $snippet "3" } " are put on the datastack. When the quotation is called, it takes those values as inputs and binds them respectively to " { $snippet "m" } " and " { $snippet "n" } " before executing the quotation:"
|
||||
{ $example
|
||||
"USING: kernel locals math ;"
|
||||
"IN: scratchpad"
|
||||
|
@ -201,7 +201,7 @@ $nl
|
|||
"One exception to the above rule is that array instances containing free lexical variables (that is, immutable lexical variables not referenced in a closure) do retain identity. This allows macros such as " { $link cond } " to expand at compile time even when their arguments reference variables." ;
|
||||
|
||||
ARTICLE: "locals-mutable" "Mutable lexical variables"
|
||||
"When a lexical variable is bound using " { $link postpone: \:> } ", " { $link postpone: \:: } ", or " { $link postpone: \|[ } ", the variable may be made mutable by suffixing its name with an exclamation point (" { $snippet "!" } "). A mutable variable's value is read by giving its name without the exclamation point as usual. To write to the variable, use its name with the " { $snippet "!" } " suffix."
|
||||
"When a lexical variable is bound using " { $link \ \:> } ", " { $link \ \:: } ", or " { $link \ \|[ } ", the variable may be made mutable by suffixing its name with an exclamation point (" { $snippet "!" } "). A mutable variable's value is read by giving its name without the exclamation point as usual. To write to the variable, use its name with the " { $snippet "!" } " suffix."
|
||||
$nl
|
||||
"Mutable bindings are implemented in a manner similar to that taken by the ML language. Each mutable binding is actually an immutable binding of a mutable cell. Reading the binding automatically unboxes the value from the cell, and writing to the binding stores into it."
|
||||
$nl
|
||||
|
@ -218,7 +218,7 @@ $nl
|
|||
"Conceptually, " { $link curry } " is defined so that the following two code snippets are equivalent:"
|
||||
{ $code "3 [ - ] curry" }
|
||||
{ $code "[ 3 - ]" }
|
||||
"When quotations take named parameters using " { $link postpone: \|[ } ", " { $link curry } " fills in the variable bindings from right to left. The following two snippets are equivalent:"
|
||||
"When quotations take named parameters using " { $link \ \|[ } ", " { $link curry } " fills in the variable bindings from right to left. The following two snippets are equivalent:"
|
||||
{ $code "3 |[ a b | a b - ] curry" }
|
||||
{ $code "|[ a | a 3 - ]" }
|
||||
"Because of this, the behavior of " { $snippet "fry" } " changes when applied to such a quotation to ensure that fry conceptually behaves the same as with normal quotations, placing the fried values “underneath” the variable bindings. Thus, the following snippets are no longer equivalent:"
|
||||
|
@ -227,7 +227,7 @@ $nl
|
|||
"Instead, the first line above expands into something like the following:"
|
||||
{ $code "[ [ swap |[ a | a - ] ] curry call ]" }
|
||||
$nl
|
||||
"The precise behavior is as follows. When frying a " { $link postpone: \|[ } " quotation, a stack shuffle (" { $link mnswap } ") is prepended so that the " { $snippet "m" } " curried values, which start off at the top of the stack, are transposed with the quotation's " { $snippet "n" } " named input bindings." ;
|
||||
"The precise behavior is as follows. When frying a " { $link \ \|[ } " quotation, a stack shuffle (" { $link mnswap } ") is prepended so that the " { $snippet "m" } " curried values, which start off at the top of the stack, are transposed with the quotation's " { $snippet "n" } " named input bindings." ;
|
||||
|
||||
ARTICLE: "locals-limitations" "Limitations of lexical variables"
|
||||
"There are two main limitations of the current implementation, and both concern macros."
|
||||
|
@ -276,18 +276,18 @@ ARTICLE: "locals" "Lexical variables"
|
|||
}
|
||||
"Word definitions where the inputs are bound to lexical variables:"
|
||||
{ $subsections
|
||||
postpone: \::
|
||||
postpone: \M::
|
||||
postpone: \MEMO::
|
||||
postpone: \MACRO::
|
||||
\ \::
|
||||
\ \M::
|
||||
\ \MEMO::
|
||||
\ \MACRO::
|
||||
}
|
||||
"Lexical scoping and binding forms:"
|
||||
{ $subsections
|
||||
postpone: \let[
|
||||
postpone: \:>
|
||||
\ \let[
|
||||
\ \:>
|
||||
}
|
||||
"Quotation literals where the inputs are bound to lexical variables:"
|
||||
{ $subsections postpone: \|[ }
|
||||
{ $subsections \ \|[ }
|
||||
"Additional topics:"
|
||||
{ $subsections
|
||||
"locals-literals"
|
||||
|
|
|
@ -469,28 +469,28 @@ M:: integer lambda-method-forget-test ( a -- b ) a ;
|
|||
{ 3 } [ let[ \ + :> a 1 2 [ \ a execute ] ] call ] unit-test
|
||||
|
||||
! erg found this problem
|
||||
:: erg's-:>-bug ( n ? -- n ) ? [ n :> n n ] [ n :> b b ] if ;
|
||||
:: ergs-locals-bug ( n ? -- n ) ? [ n :> n n ] [ n :> b b ] if ;
|
||||
|
||||
{ 3 } [ 3 f erg's-:>-bug ] unit-test
|
||||
{ 3 } [ 3 f ergs-locals-bug ] unit-test
|
||||
|
||||
{ 3 } [ 3 t erg's-:>-bug ] unit-test
|
||||
{ 3 } [ 3 t ergs-locals-bug ] unit-test
|
||||
|
||||
:: erg's-:>-bug-2 ( n ? -- n ) ? n '[ _ :> n n ] [ n :> b b ] if ;
|
||||
:: ergs-locals-bug2 ( n ? -- n ) ? n '[ _ :> n n ] [ n :> b b ] if ;
|
||||
|
||||
{ 3 } [ 3 f erg's-:>-bug-2 ] unit-test
|
||||
{ 3 } [ 3 f ergs-locals-bug2 ] unit-test
|
||||
|
||||
{ 3 } [ 3 t erg's-:>-bug-2 ] unit-test
|
||||
{ 3 } [ 3 t ergs-locals-bug2 ] unit-test
|
||||
|
||||
! dharmatech found this problem
|
||||
GENERIC: ed's-bug ( a -- b )
|
||||
GENERIC: eds-bug ( a -- b )
|
||||
|
||||
M: string ed's-bug reverse ;
|
||||
M: integer ed's-bug neg ;
|
||||
M: string eds-bug reverse ;
|
||||
M: integer eds-bug neg ;
|
||||
|
||||
:: ed's-test-case ( a -- b )
|
||||
{ [ a ed's-bug ] } && ;
|
||||
:: eds-test-case ( a -- b )
|
||||
{ [ a eds-bug ] } && ;
|
||||
|
||||
{ t } [ \ ed's-test-case word-optimized? ] unit-test
|
||||
{ t } [ \ eds-test-case word-optimized? ] unit-test
|
||||
|
||||
! multiple bind
|
||||
{ 3 1 2 } [ let[ 1 2 3 :> ( a b c ) c a b ] ] unit-test
|
||||
|
|
|
@ -10,7 +10,7 @@ HELP: parse-def
|
|||
{ "name/paren" string }
|
||||
{ "def" "a " { $link def } " or a " { $link multi-def } }
|
||||
}
|
||||
{ $description "Parses the lexical variable bindings following a " { $link postpone: \:> } " token." } ;
|
||||
{ $description "Parses the lexical variable bindings following a " { $link \ \:> } " token." } ;
|
||||
|
||||
HELP: with-lambda-scope
|
||||
{ $values { "assoc" "local variables" } { "reader-quot" quotation } { "quot" quotation } }
|
||||
|
|
|
@ -30,7 +30,7 @@ HELP: \MACRO:
|
|||
} ;
|
||||
|
||||
HELP: macro
|
||||
{ $class-description "Class of words defined with " { $link postpone: \MACRO: } "." } ;
|
||||
{ $class-description "Class of words defined with " { $link \ \MACRO: } "." } ;
|
||||
|
||||
ARTICLE: "macros" "Macros"
|
||||
"The " { $vocab-link "macros" } " vocabulary implements " { $emphasis "macros" } ", which are code transformations that may run at compile-time under the right circumstances."
|
||||
|
@ -42,7 +42,7 @@ $nl
|
|||
"Factor macros are similar to Lisp macros; they are not like C preprocessor macros."
|
||||
$nl
|
||||
"Defining new macros:"
|
||||
{ $subsections postpone: \MACRO: }
|
||||
{ $subsections \ \MACRO: }
|
||||
"A slightly lower-level facility, " { $emphasis "compiler transforms" } ", allows an ordinary word definition to co-exist with a version that performs compile-time expansion. The ordinary definition is only used from code compiled with the non-optimizing compiler. Under normal circumstances, macros should be used instead of compiler transforms; compiler transforms are only used for words such as " { $link cond } " which are frequently invoked during the bootstrap process, and this having a performant non-optimized definition which does not generate code on the fly is important."
|
||||
{ $subsections define-transform }
|
||||
{ $see-also "generalizations" "fry" } ;
|
||||
|
|
|
@ -139,7 +139,7 @@ ARTICLE: "math.floats.bitwise" "Bitwise operations on floats"
|
|||
}
|
||||
"Comparing two floating point numbers for bitwise equality:"
|
||||
{ $subsections fp-bitwise= }
|
||||
{ $see-also postpone: \nan: } ;
|
||||
{ $see-also \ \nan: } ;
|
||||
|
||||
ARTICLE: "floats" "Floats"
|
||||
{ $subsections float }
|
||||
|
|
|
@ -9,7 +9,7 @@ $nl
|
|||
"Memoization is useful in situations where the set of possible inputs is small, but the results are expensive to compute and should be cached. Memoized words should not have any side effects."
|
||||
$nl
|
||||
"Defining a memoized word at parse time:"
|
||||
{ $subsections postpone: \MEMO: }
|
||||
{ $subsections \ \MEMO: }
|
||||
"Defining a memoized word at run time:"
|
||||
{ $subsections define-memoized }
|
||||
"Clearing memoized results:"
|
||||
|
@ -26,4 +26,4 @@ HELP: \MEMO:
|
|||
{ $values { "word" "a new word to define" } { "definition" "a word definition" } }
|
||||
{ $description "Defines the given word at parse time as one which memoizes its output given a particular input. The stack effect is mandatory." } ;
|
||||
|
||||
{ define-memoized postpone: \MEMO: } related-words
|
||||
{ define-memoized \ \MEMO: } related-words
|
||||
|
|
|
@ -4,7 +4,7 @@ IN: multiline
|
|||
HELP: parse-multiline-string
|
||||
{ $values { "end-text" "a string delineating the end" } { "str" "the parsed string" } }
|
||||
{ $description "Parses the input stream until the " { $snippet "end-text" } " is reached and returns the parsed text as a string." }
|
||||
{ $notes "Used to implement " { $link postpone: \[[ } "." } ;
|
||||
{ $notes "Used to implement " { $link \ \[[ } "." } ;
|
||||
|
||||
ARTICLE: "multiline" "Multiline"
|
||||
"Writing new multiline parsing words:"
|
||||
|
|
|
@ -75,4 +75,4 @@ HELP: literalize
|
|||
{ $example "USING: math prettyprint quotations sequences ;" "[ + ] [ literalize ] map ." "[ \\ + ]" }
|
||||
} ;
|
||||
|
||||
{ literalize curry <wrapper> postpone: \\ postpone: \W{ } related-words
|
||||
{ literalize curry <wrapper> \ \\ \ \W{ } related-words
|
||||
|
|
|
@ -71,7 +71,7 @@ ARTICLE: "sequence-sets" "Sequences as sets"
|
|||
$nl
|
||||
"Care must be taken in writing efficient code using sequence sets. Testing for membership with " { $link in? } ", as well as the destructive set operations, take time proportional to the size of the sequence. Another representation, like " { $link "hash-sets" } ", would take constant time for membership tests. But binary operations like " { $link union } " are asymptotically optimal, taking time proportional to the sum of the size of the inputs."
|
||||
$nl
|
||||
"As one particular example, " { $link postpone: f } " is a representation of the empty set, since it is an empty sequence." ;
|
||||
"As one particular example, " { $link f } " is a representation of the empty set, since it is an empty sequence." ;
|
||||
|
||||
HELP: set
|
||||
{ $class-description "The class of all sets. Custom implementations of the set protocol should be declared as instances of this mixin for all set implementation to work correctly." } ;
|
||||
|
|
|
@ -117,7 +117,7 @@ $nl
|
|||
ABOUT: "slots"
|
||||
|
||||
HELP: bad-initial-value
|
||||
{ $error-description "Thrown by " { $link postpone: \TUPLE: } " if a slot has an impossible initial value. "
|
||||
{ $error-description "Thrown by " { $link \ \TUPLE: } " if a slot has an impossible initial value. "
|
||||
{ $examples
|
||||
{ $unchecked-example
|
||||
"TUPLE: a { b integer initial: \"invalid\" } ;"
|
||||
|
|
|
@ -13,7 +13,7 @@ HELP: do-not-compile
|
|||
} ;
|
||||
|
||||
HELP: unknown-macro-input
|
||||
{ $error-description "Thrown when inference encounters a combinator or macro being applied to an input parameter of a non-" { $link postpone: inline } " word. The word needs to be declared " { $link postpone: inline } " before its callers can compile and run. See " { $link "inference-combinators" } " and " { $link "inference-escape" } " for details." }
|
||||
{ $error-description "Thrown when inference encounters a combinator or macro being applied to an input parameter of a non-" { $link \ inline } " word. The word needs to be declared " { $link \ inline } " before its callers can compile and run. See " { $link "inference-combinators" } " and " { $link "inference-escape" } " for details." }
|
||||
{ $examples
|
||||
"In this example, the words being defined cannot be called, because they fail to compile with a " { $link unknown-macro-input } " error:"
|
||||
{ $code
|
||||
|
@ -31,7 +31,7 @@ HELP: unknown-macro-input
|
|||
": usage ( -- )"
|
||||
" 10 [ 2 * ] good-example . ;"
|
||||
}
|
||||
"Another fix is to use " { $link postpone: \call( } ":"
|
||||
"Another fix is to use " { $link \ \call( } ":"
|
||||
{ $code
|
||||
": good-example ( quot -- )"
|
||||
" [ call( x -- y ) ] [ call( x -- y ) ] bi ;"
|
||||
|
@ -103,7 +103,7 @@ HELP: recursive-quotation-error
|
|||
} ;
|
||||
|
||||
HELP: undeclared-recursion-error
|
||||
{ $error-description "Thrown when an " { $link postpone: inline } " word which is not declared " { $link postpone: recursive } " calls itself, directly or indirectly. The " { $link postpone: recursive } " declaration is mandatory for such words." } ;
|
||||
{ $error-description "Thrown when an " { $link \ inline } " word which is not declared " { $link \ recursive } " calls itself, directly or indirectly. The " { $link \ recursive } " declaration is mandatory for such words." } ;
|
||||
|
||||
HELP: diverging-recursion-error
|
||||
{ $error-description "Thrown when stack effect inference determines that a recursive word might take an arbitrary number of values from the stack." }
|
||||
|
|
|
@ -5,7 +5,7 @@ IN: stack-checker
|
|||
ARTICLE: "inference-simple" "Straight-line stack effects"
|
||||
"The simplest case is when a piece of code does not have any branches or recursion, and just pushes literals and calls words."
|
||||
$nl
|
||||
"Pushing a literal has stack effect " { $snippet "( -- x )" } ". The stack effect of most words is always known statically from the declaration. Stack effects of " { $link postpone: inline } " words and " { $link "macros" } ", may depend on literals pushed on the stack prior to the call, and this case is discussed in " { $link "inference-combinators" } "."
|
||||
"Pushing a literal has stack effect " { $snippet "( -- x )" } ". The stack effect of most words is always known statically from the declaration. Stack effects of " { $link \ inline } " words and " { $link "macros" } ", may depend on literals pushed on the stack prior to the call, and this case is discussed in " { $link "inference-combinators" } "."
|
||||
$nl
|
||||
"The stack effect of each element in a code snippet is composed. The result is then the stack effect of the snippet."
|
||||
$nl
|
||||
|
@ -18,9 +18,9 @@ ARTICLE: "inference-combinators" "Combinator stack effects"
|
|||
"If a word calls a combinator, one of the following two conditions must hold for the stack checker to succeed:"
|
||||
{ $list
|
||||
{ "The combinator must be called with a quotation that is either literal or built from literal quotations, " { $link curry } ", and " { $link compose } ". (Note that quotations that use " { $vocab-link "fry" } " or " { $vocab-link "locals" } " use " { $link curry } " and " { $link compose } " from the perspective of the stack checker.)" }
|
||||
{ "If the word is declared " { $link postpone: inline } ", the combinator may additionally be called on one of the word's input parameters or with quotations built from the word's input parameters, literal quotations, " { $link curry } ", and " { $link compose } ". When inline, a word is itself considered to be a combinator, and its callers must in turn satisfy these conditions." }
|
||||
{ "If the word is declared " { $link \ inline } ", the combinator may additionally be called on one of the word's input parameters or with quotations built from the word's input parameters, literal quotations, " { $link curry } ", and " { $link compose } ". When inline, a word is itself considered to be a combinator, and its callers must in turn satisfy these conditions." }
|
||||
}
|
||||
"If neither condition holds, the stack checker throws a " { $link unknown-macro-input } " or " { $link bad-macro-input } " error. To make the code compile, a runtime checking combinator such as " { $link postpone: \call( } " must be used instead. See " { $link "inference-escape" } " for details. An inline combinator can be called with an unknown quotation by " { $link curry } "ing the quotation onto a literal quotation that uses " { $link postpone: \call( } "."
|
||||
"If neither condition holds, the stack checker throws a " { $link unknown-macro-input } " or " { $link bad-macro-input } " error. To make the code compile, a runtime checking combinator such as " { $link \ \call( } " must be used instead. See " { $link "inference-escape" } " for details. An inline combinator can be called with an unknown quotation by " { $link curry } "ing the quotation onto a literal quotation that uses " { $link \ \call( } "."
|
||||
{ $heading "Input stack effects" }
|
||||
"Inline combinators will verify the stack effect of their input quotations if they are declared in the combinator's stack effect. See " { $link "effects-variables" } " for details."
|
||||
{ $heading "Examples" }
|
||||
|
@ -31,12 +31,12 @@ ARTICLE: "inference-combinators" "Combinator stack effects"
|
|||
{ $example "USING: fry math sequences ;" "[ '[ _ + ] map ] infer." "( x x -- x )" }
|
||||
{ $example "USING: locals math sequences ;" "|[ a | [ a + ] map ] infer." "( x x -- x )" }
|
||||
{ $subheading "Defining an inline combinator" }
|
||||
"The following word calls a quotation twice; the word is declared " { $link postpone: inline } ", since it invokes " { $link call } " on the result of " { $link compose } " on an input parameter:"
|
||||
"The following word calls a quotation twice; the word is declared " { $link \ inline } ", since it invokes " { $link call } " on the result of " { $link compose } " on an input parameter:"
|
||||
{ $code ": twice ( value quot -- result ) dup compose call ; inline" }
|
||||
"The following code now passes the stack checker; it would fail were " { $snippet "twice" } " not declared " { $link postpone: inline } ":"
|
||||
"The following code now passes the stack checker; it would fail were " { $snippet "twice" } " not declared " { $link \ inline } ":"
|
||||
{ $unchecked-example "USE: math.functions" "[ [ sqrt ] twice ] infer." "( x -- x )" }
|
||||
{ $subheading "Defining a combinator for unknown quotations" }
|
||||
"In the next example, " { $link postpone: \call( } " must be used because the quotation is the result of calling a runtime accessor, and the compiler cannot make any static assumptions about this quotation at all:"
|
||||
"In the next example, " { $link \ \call( } " must be used because the quotation is the result of calling a runtime accessor, and the compiler cannot make any static assumptions about this quotation at all:"
|
||||
{ $code
|
||||
"TUPLE: action name quot ;"
|
||||
": perform ( value action -- result ) quot>> call( value -- result ) ;"
|
||||
|
@ -61,7 +61,7 @@ $nl
|
|||
} ;
|
||||
|
||||
ARTICLE: "inference-branches" "Branch stack effects"
|
||||
"Conditionals such as " { $link if } " and combinators built on top have the same restrictions as " { $link postpone: inline } " combinators (see " { $link "inference-combinators" } ") with the additional requirement that all branches leave the stack at the same height. If this is not the case, the stack checker throws a " { $link unbalanced-branches-error } "."
|
||||
"Conditionals such as " { $link if } " and combinators built on top have the same restrictions as " { $link \ inline } " combinators (see " { $link "inference-combinators" } ") with the additional requirement that all branches leave the stack at the same height. If this is not the case, the stack checker throws a " { $link unbalanced-branches-error } "."
|
||||
$nl
|
||||
"If all branches leave the stack at the same height, then the stack effect of the conditional is just the maximum of the stack effect of each branch. For example,"
|
||||
{ $example "[ [ + ] [ drop ] if ] infer." "( x x x -- x )" }
|
||||
|
@ -70,7 +70,7 @@ $nl
|
|||
ARTICLE: "inference-recursive-combinators" "Recursive combinator stack effects"
|
||||
"Most combinators do not call themselves recursively directly; instead, they are implemented in terms of existing combinators, for example " { $link while } ", " { $link map } ", and the " { $link "compositional-combinators" } ". In these cases, the rules outlined in " { $link "inference-combinators" } " apply."
|
||||
$nl
|
||||
"Combinators which are recursive require additional care. In addition to being declared " { $link postpone: inline } ", they must be declared " { $link postpone: recursive } ". There are three restrictions that only apply to combinators with this declaration:"
|
||||
"Combinators which are recursive require additional care. In addition to being declared " { $link \ inline } ", they must be declared " { $link \ recursive } ". There are three restrictions that only apply to combinators with this declaration:"
|
||||
{ $heading "Input quotation declaration" }
|
||||
"Input parameters which are quotations must be annotated as much in the stack effect. For example, the following will not infer:"
|
||||
{ $unchecked-example ": bad ( quot -- ) [ call ] keep bad ; inline recursive" "[ [ ] bad ] infer." "Cannot apply “call” to a run-time computed value\nmacro call" }
|
||||
|
@ -116,7 +116,7 @@ ARTICLE: "tools.inference" "Stack effect tools"
|
|||
ARTICLE: "inference-escape" "Stack effect checking escape hatches"
|
||||
"In a static checking regime, sometimes it is necessary to step outside the boundaries and run some code which cannot be statically checked; perhaps this code is constructed at run-time. There are two ways to get around the static stack checker."
|
||||
$nl
|
||||
"If the stack effect of a word or quotation is known, but the word or quotation itself is not, " { $link postpone: \execute( } " or " { $link postpone: \call( } " can be used. See " { $link "call" } " for details."
|
||||
"If the stack effect of a word or quotation is known, but the word or quotation itself is not, " { $link \ \execute( } " or " { $link \ \call( } " can be used. See " { $link "call" } " for details."
|
||||
$nl
|
||||
"If the stack effect is not known, the code being called cannot manipulate the datastack directly. Instead, it must reflect the datastack into an array:"
|
||||
{ $subsections with-datastack }
|
||||
|
|
|
@ -322,9 +322,9 @@ ERROR: custom-error ;
|
|||
|
||||
[ [ [ f dup ] [ ] while ] infer ] must-fail
|
||||
|
||||
: erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline recursive
|
||||
[ [ erg's-inference-bug ] infer ] must-fail
|
||||
FORGET: erg's-inference-bug
|
||||
: ergs-inference-bug ( -- ) f dup [ ergs-inference-bug ] when ; inline recursive
|
||||
[ [ ergs-inference-bug ] infer ] must-fail
|
||||
FORGET: ergs-inference-bug
|
||||
|
||||
: bad-recursion-3 ( -- ) dup [ [ bad-recursion-3 ] dip ] when ; inline recursive
|
||||
[ [ bad-recursion-3 ] infer ] must-fail
|
||||
|
|
|
@ -11,7 +11,7 @@ ARTICLE: "parser-algorithm" "Parser algorithm"
|
|||
$nl
|
||||
"The parser iterates through the input text, checking each character in turn. Here is the parser algorithm in more detail -- some of the concepts therein will be defined shortly:"
|
||||
{ $list
|
||||
{ "If the current character is a double-quote (\"), the " { $link postpone: \" } " parsing word is executed, causing a string to be read." }
|
||||
{ "If the current character is a double-quote (\"), the " { $link \ \" } " parsing word is executed, causing a string to be read." }
|
||||
{
|
||||
"Otherwise, the next token is taken from the input. The parser searches for a word named by the token in the currently used set of vocabularies. If the word is found, one of the following two actions is taken:"
|
||||
{ $list
|
||||
|
@ -28,8 +28,8 @@ $nl
|
|||
ARTICLE: "syntax-immediate" "Parse time evaluation"
|
||||
"Code can be evaluated at parse time. This is a rarely-used feature; one use-case is " { $link "loading-libs" } ", where you want to execute some code before the words in a source file are compiled."
|
||||
{ $subsections
|
||||
postpone: <<
|
||||
postpone: >>
|
||||
\ <<
|
||||
\ >>
|
||||
} ;
|
||||
|
||||
ARTICLE: "syntax-integers" "Integer syntax"
|
||||
|
@ -99,7 +99,7 @@ ARTICLE: "syntax-floats" "Float syntax"
|
|||
{ "Not-a-number" { $snippet "0/0." } }
|
||||
}
|
||||
"A Not-a-number literal with an arbitrary payload can also be input:"
|
||||
{ $subsections postpone: \nan: }
|
||||
{ $subsections \ \nan: }
|
||||
"Hexadecimal, octal and binary float literals are also supported. These consist of a hexadecimal, octal or binary literal with a decimal point and a mandatory base-two exponent expressed as a decimal number after " { $snippet "p" } " or " { $snippet "P" } ":"
|
||||
{ $example
|
||||
"8.0 0x1.0p3 = ."
|
||||
|
@ -131,7 +131,7 @@ ARTICLE: "syntax-complex-numbers" "Complex number syntax"
|
|||
"C{ 1/2 1/3 } ! the complex number 1/2+1/3i"
|
||||
"C{ 0 1 } ! the imaginary unit"
|
||||
}
|
||||
{ $subsections postpone: \C{ }
|
||||
{ $subsections \ \C{ }
|
||||
"More information on complex numbers can be found in " { $link "complex-numbers" } "." ;
|
||||
|
||||
ARTICLE: "syntax-numbers" "Number syntax"
|
||||
|
@ -146,10 +146,10 @@ ARTICLE: "syntax-numbers" "Number syntax"
|
|||
ARTICLE: "syntax-words" "Word syntax"
|
||||
"A word occurring inside a quotation is executed when the quotation is called. Sometimes a word needs to be pushed on the data stack instead. The canonical use case for this is passing the word to the " { $link execute } " combinator, or alternatively, reflectively accessing word properties (" { $link "word-props" } ")."
|
||||
{ $subsections
|
||||
postpone: \\
|
||||
postpone: \postpone:
|
||||
\ \\
|
||||
\ \\
|
||||
}
|
||||
"The implementation of the " { $link postpone: \\ } " word is discussed in detail in " { $link "reading-ahead" } ". Words are documented in " { $link "words" } "." ;
|
||||
"The implementation of the " { $link \ \\ } " word is discussed in detail in " { $link "reading-ahead" } ". Words are documented in " { $link "words" } "." ;
|
||||
|
||||
ARTICLE: "escape" "Character escape codes"
|
||||
{ $table
|
||||
|
@ -173,57 +173,57 @@ ARTICLE: "escape" "Character escape codes"
|
|||
ARTICLE: "syntax-strings" "Character and string syntax"
|
||||
"Factor has no distinct character type. Integers representing Unicode code points can be read by specifying a literal character, or an escaped representation thereof."
|
||||
{ $subsections
|
||||
postpone: \char:
|
||||
postpone: \"
|
||||
\ \char:
|
||||
\ \"
|
||||
"escape"
|
||||
}
|
||||
"Strings are documented in " { $link "strings" } "." ;
|
||||
|
||||
ARTICLE: "syntax-sbufs" "String buffer syntax"
|
||||
{ $subsections postpone: \sbuf" }
|
||||
{ $subsections \ \sbuf" }
|
||||
"String buffers are documented in " { $link "sbufs" } "." ;
|
||||
|
||||
ARTICLE: "syntax-arrays" "Array syntax"
|
||||
{ $subsections
|
||||
postpone: \{
|
||||
postpone: \}
|
||||
\ \{
|
||||
\ \}
|
||||
}
|
||||
"Arrays are documented in " { $link "arrays" } "." ;
|
||||
|
||||
ARTICLE: "syntax-vectors" "Vector syntax"
|
||||
{ $subsections postpone: \V{ }
|
||||
{ $subsections \ \V{ }
|
||||
"Vectors are documented in " { $link "vectors" } "." ;
|
||||
|
||||
ARTICLE: "syntax-hashtables" "Hashtable syntax"
|
||||
{ $subsections postpone: \H{ }
|
||||
{ $subsections \ \H{ }
|
||||
"Hashtables are documented in " { $link "hashtables" } "." ;
|
||||
|
||||
ARTICLE: "syntax-hash-sets" "Hash set syntax"
|
||||
{ $subsections postpone: \HS{ }
|
||||
{ $subsections \ \HS{ }
|
||||
"Hashtables are documented in " { $link "hash-sets" } "." ;
|
||||
|
||||
ARTICLE: "syntax-tuples" "Tuple syntax"
|
||||
{ $subsections postpone: \T{ }
|
||||
{ $subsections \ \T{ }
|
||||
"Tuples are documented in " { $link "tuples" } "." ;
|
||||
|
||||
ARTICLE: "syntax-quots" "Quotation syntax"
|
||||
{ $subsections
|
||||
postpone: \[
|
||||
postpone: \]
|
||||
\ \[
|
||||
\ \]
|
||||
}
|
||||
"Quotations are documented in " { $link "quotations" } "." ;
|
||||
|
||||
ARTICLE: "syntax-byte-arrays" "Byte array syntax"
|
||||
{ $subsections postpone: \B{ }
|
||||
{ $subsections \ \B{ }
|
||||
"Byte arrays are documented in " { $link "byte-arrays" } "." ;
|
||||
|
||||
ARTICLE: "syntax-pathnames" "Pathname syntax"
|
||||
{ $subsections postpone: \path" }
|
||||
{ $subsections \ \path" }
|
||||
"Pathnames are documented in " { $link "io.pathnames" } "." ;
|
||||
|
||||
ARTICLE: "syntax-effects" "Stack effect syntax"
|
||||
"Note that this is " { $emphasis "not" } " syntax to declare stack effects of words. This pushes an " { $link effect } " instance on the stack for reflection, for use with words such as " { $link define-declared } ", " { $link call-effect } " and " { $link execute-effect } "."
|
||||
{ $subsections postpone: \( }
|
||||
{ $subsections \ \( }
|
||||
{ $see-also "effects" "inference" "tools.inference" } ;
|
||||
|
||||
ARTICLE: "syntax-literals" "Literals"
|
||||
|
@ -287,7 +287,7 @@ HELP: inline
|
|||
HELP: recursive
|
||||
{ $syntax ": foo ... ; recursive" }
|
||||
{ $description "Declares the most recently defined word as a recursive word." }
|
||||
{ $notes "This declaration is only required for " { $link postpone: inline } " words which call themselves. See " { $link "inference-recursive-combinators" } "." } ;
|
||||
{ $notes "This declaration is only required for " { $link \ inline } " words which call themselves. See " { $link "inference-recursive-combinators" } "." } ;
|
||||
|
||||
HELP: foldable
|
||||
{ $syntax ": foo ... ; foldable" }
|
||||
|
@ -329,7 +329,7 @@ HELP: \[
|
|||
{ $description "Marks the beginning of a literal quotation." }
|
||||
{ $examples { $code "[ 1 2 3 ]" } } ;
|
||||
|
||||
{ postpone: \[ postpone: \] } related-words
|
||||
{ \ \[ \ \] } related-words
|
||||
|
||||
HELP: \]
|
||||
{ $syntax "]" }
|
||||
|
@ -343,24 +343,24 @@ HELP: \}
|
|||
$nl
|
||||
"Parsing words can use this word as a generic end delimiter." } ;
|
||||
|
||||
{ postpone: \{ postpone: \V{ postpone: \H{ postpone: \HS{ postpone: \C{ postpone: \T{ postpone: \W{ postpone: \} } related-words
|
||||
{ \ \{ \ \V{ \ \H{ \ \HS{ \ \C{ \ \T{ \ \W{ \ \} } related-words
|
||||
|
||||
HELP: \{
|
||||
{ $syntax "{ elements... }" }
|
||||
{ $values { "elements" "a list of objects" } }
|
||||
{ $description "Marks the beginning of a literal array. Literal arrays are terminated by " { $link postpone: \} } "." }
|
||||
{ $description "Marks the beginning of a literal array. Literal arrays are terminated by " { $link \ \} } "." }
|
||||
{ $examples { $code "{ 1 2 3 }" } } ;
|
||||
|
||||
HELP: \V{
|
||||
{ $syntax "V{ elements... }" }
|
||||
{ $values { "elements" "a list of objects" } }
|
||||
{ $description "Marks the beginning of a literal vector. Literal vectors are terminated by " { $link postpone: \} } "." }
|
||||
{ $description "Marks the beginning of a literal vector. Literal vectors are terminated by " { $link \ \} } "." }
|
||||
{ $examples { $code "V{ 1 2 3 }" } } ;
|
||||
|
||||
HELP: \B{
|
||||
{ $syntax "B{ elements... }" }
|
||||
{ $values { "elements" "a list of integers" } }
|
||||
{ $description "Marks the beginning of a literal byte array. Literal byte arrays are terminated by " { $link postpone: \} } "." }
|
||||
{ $description "Marks the beginning of a literal byte array. Literal byte arrays are terminated by " { $link \ \} } "." }
|
||||
{ $examples { $code "B{ 1 2 3 }" } } ;
|
||||
|
||||
HELP: \intersection{
|
||||
|
@ -371,19 +371,19 @@ HELP: \intersection{
|
|||
HELP: \H{
|
||||
{ $syntax "H{ { key value }... }" }
|
||||
{ $values { "key" object } { "value" object } }
|
||||
{ $description "Marks the beginning of a literal hashtable, given as a list of two-element arrays holding key/value pairs. Literal hashtables are terminated by " { $link postpone: \} } "." }
|
||||
{ $description "Marks the beginning of a literal hashtable, given as a list of two-element arrays holding key/value pairs. Literal hashtables are terminated by " { $link \ \} } "." }
|
||||
{ $examples { $code "H{ { \"tuna\" \"fish\" } { \"jalapeno\" \"vegetable\" } }" } } ;
|
||||
|
||||
HELP: \HS{
|
||||
{ $syntax "HS{ members ... }" }
|
||||
{ $values { "members" "a list of objects" } }
|
||||
{ $description "Marks the beginning of a literal hash set, given as a list of its members. Literal hashtables are terminated by " { $link postpone: \} } "." }
|
||||
{ $description "Marks the beginning of a literal hash set, given as a list of its members. Literal hashtables are terminated by " { $link \ \} } "." }
|
||||
{ $examples { $code "HS{ 3 \"foo\" }" } } ;
|
||||
|
||||
HELP: \C{
|
||||
{ $syntax "C{ real-part imaginary-part }" }
|
||||
{ $values { "real-part" "a real number" } { "imaginary-part" "a real number" } }
|
||||
{ $description "Parses a complex number given in rectangular form as a pair of real numbers. Literal complex numbers are terminated by " { $link postpone: \} } "." } ;
|
||||
{ $description "Parses a complex number given in rectangular form as a pair of real numbers. Literal complex numbers are terminated by " { $link \ \} } "." } ;
|
||||
|
||||
HELP: \T{
|
||||
{ $syntax "T{ class }" "T{ class f slot-values... }" "T{ class { slot-name slot-value } ... }" }
|
||||
|
@ -393,7 +393,7 @@ $nl
|
|||
"Three literal syntax forms are recognized:"
|
||||
{ $list
|
||||
{ "empty tuple form: if no slot values are specified, then the literal tuple will have all slots set to their initial values (see " { $link "slot-initial-values" } ")." }
|
||||
{ "BOA-form: if the first element of " { $snippet "slots" } " is " { $snippet "f" } ", then the remaining elements are slot values corresponding to slots in the order in which they are defined in the " { $link postpone: \TUPLE: } " form." }
|
||||
{ "BOA-form: if the first element of " { $snippet "slots" } " is " { $snippet "f" } ", then the remaining elements are slot values corresponding to slots in the order in which they are defined in the " { $link \ \TUPLE: } " form." }
|
||||
{ "assoc-form: otherwise, " { $snippet "slots" } " is interpreted as a sequence of " { $snippet "{ slot-name value }" } " pairs. The " { $snippet "slot-name" } " should not be quoted." }
|
||||
}
|
||||
"BOA form is more concise, whereas assoc form is more readable for larger tuples with many slots, or if only a few slots are to be specified."
|
||||
|
@ -416,13 +416,13 @@ $nl
|
|||
HELP: \W{
|
||||
{ $syntax "W{ object }" }
|
||||
{ $values { "object" object } }
|
||||
{ $description "Marks the beginning of a literal wrapper. Literal wrappers are terminated by " { $link postpone: \} } "." } ;
|
||||
{ $description "Marks the beginning of a literal wrapper. Literal wrappers are terminated by " { $link \ \} } "." } ;
|
||||
|
||||
HELP: \postpone:
|
||||
{ $syntax "postpone: word" }
|
||||
HELP: \\
|
||||
{ $syntax "\ word" }
|
||||
{ $values { "word" word } }
|
||||
{ $description "Reads the next word from the input string and appends the word to the parse tree, even if it is a parsing word." }
|
||||
{ $examples "For an ordinary word " { $snippet "foo" } ", " { $snippet "foo" } " and " { $snippet "postpone: foo" } " are equivalent; however, if " { $snippet "foo" } " is a parsing word, the former will execute it at parse time, while the latter will execute it at runtime." }
|
||||
{ $examples "For an ordinary word " { $snippet "foo" } ", " { $snippet "foo" } " and " { $snippet "\ foo" } " are equivalent; however, if " { $snippet "foo" } " is a parsing word, the former will execute it at parse time, while the latter will execute it at runtime." }
|
||||
{ $notes "This word is used inside parsing words to delegate further action to another parsing word, and to refer to parsing words literally from literal arrays and such." } ;
|
||||
|
||||
HELP: \:
|
||||
|
@ -431,7 +431,7 @@ HELP: \:
|
|||
{ $description "Defines a word with the given stack effect in the current vocabulary." }
|
||||
{ $examples { $code ": ask-name ( -- name )\n \"What is your name? \" write readln ;\n: greet ( name -- )\n \"Greetings, \" write print ;\n: friend ( -- )\n ask-name greet ;" } } ;
|
||||
|
||||
{ postpone: \: postpone: \; define } related-words
|
||||
{ \ \: \ \; define } related-words
|
||||
|
||||
HELP: ;
|
||||
{ $syntax ";" }
|
||||
|
@ -447,7 +447,7 @@ HELP: \SYMBOL:
|
|||
{ $description "Defines a new symbol word in the current vocabulary. Symbols push themselves on the stack when executed, and are used to identify variables (see " { $link "namespaces" } ") as well as for storing crufties in word properties (see " { $link "word-props" } ")." }
|
||||
{ $examples { $example "USE: prettyprint" "IN: scratchpad" "SYMBOL: foo\nfoo ." "foo" } } ;
|
||||
|
||||
{ define-symbol postpone: \SYMBOL: postpone: \SYMBOLS: } related-words
|
||||
{ define-symbol \ \SYMBOL: \ \SYMBOLS: } related-words
|
||||
|
||||
HELP: \SYMBOLS:
|
||||
{ $syntax "SYMBOLS: words... ;" }
|
||||
|
@ -485,7 +485,7 @@ HELP: \ALIAS:
|
|||
}
|
||||
} ;
|
||||
|
||||
{ define-alias postpone: \ALIAS: } related-words
|
||||
{ define-alias \ \ALIAS: } related-words
|
||||
|
||||
HELP: \CONSTANT:
|
||||
{ $syntax "CONSTANT: word value" }
|
||||
|
@ -493,9 +493,9 @@ HELP: \CONSTANT:
|
|||
{ $description "Creates a word which pushes a value on the stack." }
|
||||
{ $examples { $code "CONSTANT: magic 1" "CONSTANT: science 0xff0f" } } ;
|
||||
|
||||
{ define-constant postpone: \CONSTANT: } related-words
|
||||
{ define-constant \ \CONSTANT: } related-words
|
||||
|
||||
HELP: \\
|
||||
HELP: \postpone:
|
||||
{ $syntax "\\ word" }
|
||||
{ $values { "word" word } }
|
||||
{ $description "Reads the next word from the input and appends a wrapper holding the word to the parse tree. When the evaluator encounters a wrapper, it pushes the wrapped word literally on the data stack." }
|
||||
|
@ -552,7 +552,7 @@ HELP: \QUALIFIED:
|
|||
|
||||
HELP: \QUALIFIED-WITH:
|
||||
{ $syntax "QUALIFIED-WITH: vocab word-prefix" }
|
||||
{ $description "Like " { $link postpone: \QUALIFIED: } " but uses " { $snippet "word-prefix" } " as prefix." }
|
||||
{ $description "Like " { $link \ \QUALIFIED: } " but uses " { $snippet "word-prefix" } " as prefix." }
|
||||
{ $examples { $example
|
||||
"USING: prettyprint ;"
|
||||
"QUALIFIED-WITH: math m"
|
||||
|
@ -567,7 +567,7 @@ HELP: \FROM:
|
|||
{ $examples
|
||||
"Both the " { $vocab-link "vocabs.parser" } " and " { $vocab-link "binary-search" } " vocabularies define a word named " { $snippet "search" } ". The following will throw an " { $link ambiguous-use-error } ":"
|
||||
{ $code "USING: vocabs.parser binary-search ;" "... search ..." }
|
||||
"Because " { $link postpone: \FROM: } " takes precedence over a " { $link postpone: \USING: } ", the ambiguity can be resolved explicitly. Suppose you wanted the " { $vocab-link "binary-search" } " vocabulary's " { $snippet "search" } " word:"
|
||||
"Because " { $link \ \FROM: } " takes precedence over a " { $link \ \USING: } ", the ambiguity can be resolved explicitly. Suppose you wanted the " { $vocab-link "binary-search" } " vocabulary's " { $snippet "search" } " word:"
|
||||
{ $code "USING: vocabs.parser binary-search ;" "FROM: binary-search => search ;" "... search ..." }
|
||||
} ;
|
||||
|
||||
|
@ -591,7 +591,7 @@ HELP: \RENAME:
|
|||
HELP: \IN:
|
||||
{ $syntax "IN: vocabulary" }
|
||||
{ $values { "vocabulary" "a new vocabulary name" } }
|
||||
{ $description "Sets the current vocabulary where new words will be defined, creating the vocabulary first if it does not exist. After the vocabulary has been created, it can be listed in " { $link postpone: \USE: } " and " { $link postpone: \USING: } " declarations." } ;
|
||||
{ $description "Sets the current vocabulary where new words will be defined, creating the vocabulary first if it does not exist. After the vocabulary has been created, it can be listed in " { $link \ \USE: } " and " { $link \ \USING: } " declarations." } ;
|
||||
|
||||
HELP: \char:
|
||||
{ $syntax "ch'token" }
|
||||
|
@ -623,19 +623,19 @@ HELP: \"
|
|||
HELP: \sbuf"
|
||||
{ $syntax "sbuf\"string... \"" }
|
||||
{ $values { "string" "literal and escaped characters" } }
|
||||
{ $description "Reads from the input string until the next occurrence of " { $link postpone: \" } ", converts the string to a string buffer, and appends it to the parse tree." }
|
||||
{ $description "Reads from the input string until the next occurrence of " { $link \ \" } ", converts the string to a string buffer, and appends it to the parse tree." }
|
||||
{ $examples { $example "USING: io strings ;" "sbuf\"Hello world\" >string print" "Hello world" } } ;
|
||||
|
||||
HELP: \path"
|
||||
{ $syntax "path\"pathname\"" }
|
||||
{ $values { "pathname" "a pathname string" } }
|
||||
{ $description "Reads from the input string until the next occurrence of " { $link postpone: \" } ", creates a new " { $link pathname } ", and appends it to the parse tree. Pathnames presented in the UI are clickable, which opens them in a text editor configured with " { $link "editor" } "." }
|
||||
{ $examples { $example "USING: accessors io io.files ;" "P\" foo.txt\" string>> print" "foo.txt" } } ;
|
||||
{ $description "Reads from the input string until the next occurrence of " { $link \ \" } ", creates a new " { $link pathname } ", and appends it to the parse tree. Pathnames presented in the UI are clickable, which opens them in a text editor configured with " { $link "editor" } "." }
|
||||
{ $examples { $example "USING: accessors io io.files ;" "path\"foo.txt\" string>> print" "foo.txt" } } ;
|
||||
|
||||
HELP: \(
|
||||
{ $syntax "( inputs -- outputs )" }
|
||||
{ $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
|
||||
{ $description "Literal stack effect syntax. Also used by syntax words (such as " { $link postpone: \: } "), typically declaring the stack effect of the word definition which follows." }
|
||||
{ $description "Literal stack effect syntax. Also used by syntax words (such as " { $link \ \: } "), typically declaring the stack effect of the word definition which follows." }
|
||||
{ $notes "Useful for meta-programming with " { $link define-declared } "." }
|
||||
{ $examples
|
||||
{ $example
|
||||
|
@ -690,7 +690,7 @@ HELP: \MATH:
|
|||
HELP: \HOOK:
|
||||
{ $syntax "HOOK: word variable ( stack -- effect )" }
|
||||
{ $values { "word" "a new word to define" } { "variable" word } }
|
||||
{ $description "Defines a new hook word in the current vocabulary. Hook words are generic words which dispatch on the value of a variable, so methods are defined with " { $link postpone: \M: } ". Hook words differ from other generic words in that the dispatch value is removed from the stack before the chosen method is called." }
|
||||
{ $description "Defines a new hook word in the current vocabulary. Hook words are generic words which dispatch on the value of a variable, so methods are defined with " { $link \ \M: } ". Hook words differ from other generic words in that the dispatch value is removed from the stack before the chosen method is called." }
|
||||
{ $examples
|
||||
{ $example
|
||||
"USING: io namespaces ;"
|
||||
|
@ -728,7 +728,7 @@ HELP: \INTERSECTION:
|
|||
HELP: \MIXIN:
|
||||
{ $syntax "MIXIN: class" }
|
||||
{ $values { "class" "a new class word to define" } }
|
||||
{ $description "Defines a mixin class. A mixin is similar to a union class, except it has no members initially, and new members can be added with the " { $link postpone: \INSTANCE: } " word." }
|
||||
{ $description "Defines a mixin class. A mixin is similar to a union class, except it has no members initially, and new members can be added with the " { $link \ \INSTANCE: } " word." }
|
||||
{ $examples "The " { $link sequence } " and " { $link assoc } " mixin classes." } ;
|
||||
|
||||
HELP: \INSTANCE:
|
||||
|
@ -866,7 +866,7 @@ HELP: PRIVATE>
|
|||
{ $syntax "<PRIVATE ... PRIVATE>" }
|
||||
{ $description "Ends a block of private word definitions." } ;
|
||||
|
||||
{ postpone: \<PRIVATE postpone: \PRIVATE> } related-words
|
||||
{ \ \<PRIVATE \ \PRIVATE> } related-words
|
||||
|
||||
HELP: <<
|
||||
{ $syntax "<< ... >>" }
|
||||
|
@ -885,9 +885,9 @@ HELP: call-next-method
|
|||
"Throws a " { $link no-next-method } " error if this is the least specific method, and throws an " { $link inconsistent-next-method } " error if the values at the top of the stack are not compatible with the current method's specializer."
|
||||
} ;
|
||||
|
||||
{ postpone: call-next-method (call-next-method) next-method } related-words
|
||||
{ \ call-next-method (call-next-method) next-method } related-words
|
||||
|
||||
{ postpone: << postpone: >> } related-words
|
||||
{ \ << \ >> } related-words
|
||||
|
||||
HELP: \call(
|
||||
{ $syntax "call( stack -- effect )" }
|
||||
|
@ -912,4 +912,4 @@ HELP: \execute(
|
|||
}
|
||||
} ;
|
||||
|
||||
{ postpone: \call( postpone: \execute( } related-words
|
||||
{ \ \call( \ \execute( } related-words
|
||||
|
|
|
@ -7,7 +7,7 @@ HELP: \TYPED:
|
|||
{ $syntax
|
||||
"TYPED: word ( a b: class ... -- x: class y ... )
|
||||
body ;" }
|
||||
{ $description "Like " { $link postpone: \: } ", defines a new word with a given stack effect in the current vocabulary. The inputs and outputs of the stack effect can additionally be given type annotations in the form " { $snippet "a: class" } ". When invoked, the word will attempt to coerce its input values to the declared input types before executing the body, throwing an " { $link input-mismatch-error } " if the types cannot be made to match. The word will likewise attempt to coerce its outputs to their declared types and throw an " { $link output-mismatch-error } " if the types cannot be made to match." }
|
||||
{ $description "Like " { $link \ \: } ", defines a new word with a given stack effect in the current vocabulary. The inputs and outputs of the stack effect can additionally be given type annotations in the form " { $snippet "a: class" } ". When invoked, the word will attempt to coerce its input values to the declared input types before executing the body, throwing an " { $link input-mismatch-error } " if the types cannot be made to match. The word will likewise attempt to coerce its outputs to their declared types and throw an " { $link output-mismatch-error } " if the types cannot be made to match." }
|
||||
{ $notes "The aforementioned type conversions and checks are structured in such a way that they will be eliminated by the compiler if it can statically determine that the types of the inputs at a call site or of the outputs in the word definition are always correct." }
|
||||
{ $examples
|
||||
"A version of " { $link + } " specialized for floats, converting other real number types:"
|
||||
|
@ -25,7 +25,7 @@ HELP: \TYPED::
|
|||
{ $syntax
|
||||
"TYPED:: word ( a b: class ... -- x: class y ... )
|
||||
body ;" }
|
||||
{ $description "Like " { $link postpone: \:: } ", defines a new word with named inputs in the current vocabulary. The inputs and outputs of the stack effect can additionally be given type annotations in the form " { $snippet "a: class" } ". When invoked, the word will attempt to coerce its input values to the declared input types before executing the body, throwing an " { $link input-mismatch-error } " if the types cannot be made to match. The word will likewise attempt to coerce its outputs to their declared types and throw an " { $link output-mismatch-error } " if the types cannot be made to match." }
|
||||
{ $description "Like " { $link \ \:: } ", defines a new word with named inputs in the current vocabulary. The inputs and outputs of the stack effect can additionally be given type annotations in the form " { $snippet "a: class" } ". When invoked, the word will attempt to coerce its input values to the declared input types before executing the body, throwing an " { $link input-mismatch-error } " if the types cannot be made to match. The word will likewise attempt to coerce its outputs to their declared types and throw an " { $link output-mismatch-error } " if the types cannot be made to match." }
|
||||
{ $notes "The aforementioned type conversions and checks are structured in such a way that they will be eliminated by the compiler if it can statically determine that the types of the inputs at a call site or of the outputs in the word definition are always correct." }
|
||||
{ $examples
|
||||
"A version of the quadratic formula specialized for floats, converting other real number types:"
|
||||
|
@ -45,25 +45,25 @@ TYPED:: quadratic-roots ( a: float b: float c: float -- q1: float q2: float )
|
|||
|
||||
HELP: define-typed
|
||||
{ $values { "word" word } { "def" quotation } { "effect" effect } }
|
||||
{ $description "The runtime equivalent to " { $link postpone: \TYPED: } " and " { $link postpone: \TYPED:: } ". Defines " { $snippet "word" } " with " { $snippet "def" } " as its body and " { $snippet "effect" } " as its stack effect. The word will check that its inputs and outputs correspond to the types specified in " { $snippet "effect" } " as described in the " { $link postpone: \TYPED: } " documentation." } ;
|
||||
{ $description "The runtime equivalent to " { $link \ \TYPED: } " and " { $link \ \TYPED:: } ". Defines " { $snippet "word" } " with " { $snippet "def" } " as its body and " { $snippet "effect" } " as its stack effect. The word will check that its inputs and outputs correspond to the types specified in " { $snippet "effect" } " as described in the " { $link \ \TYPED: } " documentation." } ;
|
||||
|
||||
HELP: input-mismatch-error
|
||||
{ $values { "word" word } { "expected-types" array } }
|
||||
{ $class-description "Errors of this class are raised at runtime by " { $link postpone: \TYPED: } " words when they are invoked with input values that do not match their type annotations. The " { $snippet "word" } " slot indicates the word that failed, and the " { $snippet "expected-types" } " slot specifies the input types expected." } ;
|
||||
{ $class-description "Errors of this class are raised at runtime by " { $link \ \TYPED: } " words when they are invoked with input values that do not match their type annotations. The " { $snippet "word" } " slot indicates the word that failed, and the " { $snippet "expected-types" } " slot specifies the input types expected." } ;
|
||||
|
||||
HELP: output-mismatch-error
|
||||
{ $values { "word" word } { "expected-types" array } }
|
||||
{ $class-description "Errors of this class are raised at runtime by " { $link postpone: \TYPED: } " words when they attempt to output values that do not match their type annotations. The " { $snippet "word" } " slot indicates the word that failed, and the " { $snippet "expected-types" } " slot specifies the output types expected." } ;
|
||||
{ $class-description "Errors of this class are raised at runtime by " { $link \ \TYPED: } " words when they attempt to output values that do not match their type annotations. The " { $snippet "word" } " slot indicates the word that failed, and the " { $snippet "expected-types" } " slot specifies the output types expected." } ;
|
||||
|
||||
{ postpone: \TYPED: postpone: \TYPED:: define-typed } related-words
|
||||
{ \ \TYPED: \ \TYPED:: define-typed } related-words
|
||||
|
||||
ARTICLE: "typed" "Strongly-typed word definitions"
|
||||
"The Factor compiler supports advanced compiler optimizations that take advantage of the type information it can glean from source code. The " { $vocab-link "typed" } " vocabulary provides syntax that allows words to provide checked type information about their inputs and outputs and improve the performance of compiled code."
|
||||
$nl
|
||||
"Parameters and return values of typed words where the type is declared to be a " { $link postpone: final } " tuple class with all slots " { $link read-only } " are passed by value."
|
||||
"Parameters and return values of typed words where the type is declared to be a " { $link \ final } " tuple class with all slots " { $link read-only } " are passed by value."
|
||||
{ $subsections
|
||||
postpone: \TYPED:
|
||||
postpone: \TYPED::
|
||||
\ \TYPED:
|
||||
\ \TYPED::
|
||||
}
|
||||
"Defining typed words at run time:"
|
||||
{ $subsections
|
||||
|
|
|
@ -37,7 +37,7 @@ ARTICLE: "vocabs.icons" "Vocabulary icons"
|
|||
"The icon file will be embedded in the vocab's image file." ;
|
||||
|
||||
ARTICLE: "vocabs.loader" "Vocabulary loader"
|
||||
"The " { $link postpone: \USE: } " and " { $link postpone: \USING: } " words load vocabularies using the vocabulary loader. The vocabulary loader is implemented in the " { $vocab-link "vocabs.loader" } " vocabulary."
|
||||
"The " { $link \ \USE: } " and " { $link \ \USING: } " words load vocabularies using the vocabulary loader. The vocabulary loader is implemented in the " { $vocab-link "vocabs.loader" } " vocabulary."
|
||||
$nl
|
||||
"The vocabulary loader searches for vocabularies in a set of directories known as vocabulary roots."
|
||||
{ $subsections "vocabs.roots" }
|
||||
|
@ -64,7 +64,7 @@ $nl
|
|||
$nl
|
||||
"Application vocabularies can define a main entry point, giving the user a convenient way to run the application:"
|
||||
{ $subsections
|
||||
postpone: \MAIN:
|
||||
\ \MAIN:
|
||||
run
|
||||
runnable-vocab
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ HELP: load-vocab
|
|||
|
||||
HELP: vocab-main
|
||||
{ $values { "vocab-spec" "a vocabulary specifier" } { "main" word } }
|
||||
{ $description "Outputs the main entry point for a vocabulary. The entry point can be executed with " { $link run } " and set with " { $link postpone: \MAIN: } "." } ;
|
||||
{ $description "Outputs the main entry point for a vocabulary. The entry point can be executed with " { $link run } " and set with " { $link \ \MAIN: } "." } ;
|
||||
|
||||
HELP: vocab-roots
|
||||
{ $var-description "A sequence of pathname strings to search for vocabularies." } ;
|
||||
|
@ -99,7 +99,7 @@ HELP: find-vocab-root
|
|||
HELP: no-vocab
|
||||
{ $values { "name" "a vocabulary name" } }
|
||||
{ $description "A " { $link no-vocab } " error tuple. Call " { $link no-vocab } " to throw it." }
|
||||
{ $error-description "Thrown when a " { $link postpone: \USE: } " or " { $link postpone: \USING: } " form refers to a non-existent vocabulary." } ;
|
||||
{ $error-description "Thrown when a " { $link \ \USE: } " or " { $link \ \USING: } " form refers to a non-existent vocabulary." } ;
|
||||
|
||||
HELP: load-help?
|
||||
{ $var-description "If set to a true value, documentation will be automatically loaded when vocabularies are loaded. This variable is usually on, except when Factor has been bootstrapped without the help system." } ;
|
||||
|
@ -125,7 +125,7 @@ HELP: require-when
|
|||
|
||||
HELP: run
|
||||
{ $values { "vocab" "a vocabulary specifier" } }
|
||||
{ $description "Runs a vocabulary's main entry point. The main entry point is set with the " { $link postpone: \MAIN: } " parsing word." } ;
|
||||
{ $description "Runs a vocabulary's main entry point. The main entry point is set with the " { $link \ \MAIN: } " parsing word." } ;
|
||||
|
||||
HELP: vocab-source-path
|
||||
{ $values { "vocab" "a vocabulary specifier" } { "path/f" { $maybe "a pathname string" } } }
|
||||
|
|
|
@ -5,53 +5,53 @@ IN: vocabs.parser
|
|||
ARTICLE: "word-search-errors" "Word lookup errors"
|
||||
"If the parser cannot not find a word in the current vocabulary search path, it attempts to look for the word in all loaded vocabularies."
|
||||
$nl
|
||||
"If " { $link auto-use? } " mode is off, a restartable error is thrown with a restart for each vocabulary in question, together with a restart which defers the word in the current vocabulary, as if " { $link postpone: \DEFER: } " was used."
|
||||
"If " { $link auto-use? } " mode is off, a restartable error is thrown with a restart for each vocabulary in question, together with a restart which defers the word in the current vocabulary, as if " { $link \ \DEFER: } " was used."
|
||||
$nl
|
||||
"If " { $link auto-use? } " mode is on and only one vocabulary has a word with this name, the vocabulary is added to the search path and parsing continues."
|
||||
$nl
|
||||
"If any restarts were invoked, or if " { $link auto-use? } " is on, the parser will print the correct " { $link postpone: \USING: } " after parsing completes. This form can be copy and pasted back into the source file."
|
||||
"If any restarts were invoked, or if " { $link auto-use? } " is on, the parser will print the correct " { $link \ \USING: } " after parsing completes. This form can be copy and pasted back into the source file."
|
||||
{ $subsections auto-use? } ;
|
||||
|
||||
ARTICLE: "word-search-syntax" "Syntax to control word lookup"
|
||||
"Parsing words which make all words in a vocabulary available:"
|
||||
{ $subsections
|
||||
postpone: \USE:
|
||||
postpone: \USING:
|
||||
postpone: \QUALIFIED:
|
||||
postpone: \QUALIFIED-WITH:
|
||||
\ \USE:
|
||||
\ \USING:
|
||||
\ \QUALIFIED:
|
||||
\ \QUALIFIED-WITH:
|
||||
}
|
||||
"Parsing words which make a subset of all words in a vocabulary available:"
|
||||
{ $subsections
|
||||
postpone: \FROM:
|
||||
postpone: \EXCLUDE:
|
||||
postpone: \RENAME:
|
||||
\ \FROM:
|
||||
\ \EXCLUDE:
|
||||
\ \RENAME:
|
||||
}
|
||||
"Removing vocabularies from the search path:"
|
||||
{ $subsections postpone: \UNUSE: }
|
||||
"In the listener, the " { $vocab-link "scratchpad" } " is the default vocabulary for new word definitions. In source files, there is no default vocabulary. Defining words before declaring a vocabulary with " { $link postpone: \IN: } " results in an error."
|
||||
{ $subsections postpone: \IN: } ;
|
||||
{ $subsections \ \UNUSE: }
|
||||
"In the listener, the " { $vocab-link "scratchpad" } " is the default vocabulary for new word definitions. In source files, there is no default vocabulary. Defining words before declaring a vocabulary with " { $link \ \IN: } " results in an error."
|
||||
{ $subsections \ \IN: } ;
|
||||
|
||||
ARTICLE: "word-search-semantics" "Resolution of ambiguous word names"
|
||||
"There is a distinction between parsing words which perform “open” imports versus “closed” imports. An open import introduces all words from a vocabulary as identifiers, except possibly a finite set of exclusions. The " { $link postpone: \USE: } ", " { $link postpone: \USING: } " and " { $link postpone: \EXCLUDE: } " words perform open imports. A closed import only adds a fixed set of identifiers. The " { $link postpone: \FROM: } ", " { $link postpone: \RENAME: } ", " { $link postpone: \QUALIFIED: } " and " { $link postpone: \QUALIFIED-WITH: } " words perform closed imports. Note that the latter two are considered as closed imports, due to the fact that all identifiers they introduce are unambiguously qualified with a prefix. The " { $link postpone: \IN: } " parsing word also performs a closed import of the newly-created vocabulary."
|
||||
"There is a distinction between parsing words which perform “open” imports versus “closed” imports. An open import introduces all words from a vocabulary as identifiers, except possibly a finite set of exclusions. The " { $link \ \USE: } ", " { $link \ \USING: } " and " { $link \ \EXCLUDE: } " words perform open imports. A closed import only adds a fixed set of identifiers. The " { $link \ \FROM: } ", " { $link \ \RENAME: } ", " { $link \ \QUALIFIED: } " and " { $link \ \QUALIFIED-WITH: } " words perform closed imports. Note that the latter two are considered as closed imports, due to the fact that all identifiers they introduce are unambiguously qualified with a prefix. The " { $link \ \IN: } " parsing word also performs a closed import of the newly-created vocabulary."
|
||||
$nl
|
||||
"When the parser encounters a reference to a word, it first searches the closed imports, in order. Closed imports are searched from the most recent to least recent. If the word could not be found this way, it searches open imports. Unlike closed imports, with open imports, the order does not matter -- instead, if more than one vocabulary defines a word with this name, an error is thrown."
|
||||
{ $subsections ambiguous-use-error }
|
||||
"To resolve the error, add a closed import, using " { $link postpone: \FROM: } ", " { $link postpone: \QUALIFIED: } " or " { $link postpone: \QUALIFIED-WITH: } ". The closed import will then take precedence over the open imports, and the ambiguity will be resolved."
|
||||
"To resolve the error, add a closed import, using " { $link \ \FROM: } ", " { $link \ \QUALIFIED: } " or " { $link \ \QUALIFIED-WITH: } ". The closed import will then take precedence over the open imports, and the ambiguity will be resolved."
|
||||
$nl
|
||||
"The rationale for this behavior is as follows. Open imports are named such because they are open to future extension; if a future version of a vocabulary that you use adds new words, those new words will now be in scope in your source file, too. To avoid problems, any references to the new word have to be resolved since the parser cannot safely determine which vocabulary was meant. This problem can be avoided entirely by using only closed imports, but this leads to additional verbosity."
|
||||
$nl
|
||||
"In practice, a small set of guidelines helps avoid name clashes:"
|
||||
{ $list
|
||||
"Keep vocabularies small"
|
||||
{ "Hide internal words using " { $link postpone: \<PRIVATE } }
|
||||
{ "Make good use of " { $link postpone: \FROM: } ", " { $link postpone: \QUALIFIED: } " or " { $link postpone: \QUALIFIED-WITH: } }
|
||||
{ "Hide internal words using " { $link \ \<PRIVATE } }
|
||||
{ "Make good use of " { $link \ \FROM: } ", " { $link \ \QUALIFIED: } " or " { $link \ \QUALIFIED-WITH: } }
|
||||
} ;
|
||||
|
||||
ARTICLE: "word-search-private" "Private words"
|
||||
"Words which only serve as implementation detail should be defined in a private code block. Words in a private code blocks get defined in a vocabulary whose name is the name of the current vocabulary suffixed with " { $snippet ".private" } ". Privacy is not enforced by the system; private words can be called from other vocabularies, and from the listener. However, this should be avoided where possible."
|
||||
{ $subsections
|
||||
postpone: \<PRIVATE
|
||||
postpone: \PRIVATE>
|
||||
\ \<PRIVATE
|
||||
\ \PRIVATE>
|
||||
} ;
|
||||
|
||||
ARTICLE: "word-search" "Parse-time word lookup"
|
||||
|
@ -79,7 +79,7 @@ $nl
|
|||
add-words-from
|
||||
add-words-excluding
|
||||
}
|
||||
"Words used to implement " { $link postpone: \IN: } ":"
|
||||
"Words used to implement " { $link \ \IN: } ":"
|
||||
{ $subsections
|
||||
current-vocab
|
||||
set-current-vocab
|
||||
|
@ -113,10 +113,10 @@ HELP: <no-word-error>
|
|||
HELP: set-current-vocab
|
||||
{ $values { "name" string } }
|
||||
{ $description "Sets the current vocabulary where new words will be defined, creating the vocabulary first if it does not exist." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \IN: } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \IN: } "." } ;
|
||||
|
||||
HELP: no-current-vocab
|
||||
{ $error-description "Thrown when a new word is defined in a source file that does not have an " { $link postpone: \IN: } " form." } ;
|
||||
{ $error-description "Thrown when a new word is defined in a source file that does not have an " { $link \ \IN: } " form." } ;
|
||||
|
||||
HELP: current-vocab
|
||||
{ $values { "vocab" vocab } }
|
||||
|
@ -125,41 +125,41 @@ HELP: current-vocab
|
|||
|
||||
HELP: begin-private
|
||||
{ $description "Begins a block of private word definitions. Private word definitions are placed in the current vocabulary name, suffixed with " { $snippet ".private" } "." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \<PRIVATE } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \<PRIVATE } "." } ;
|
||||
|
||||
HELP: end-private
|
||||
{ $description "Ends a block of private word definitions." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \PRIVATE> } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \PRIVATE> } "." } ;
|
||||
|
||||
HELP: use-vocab
|
||||
{ $values { "vocab" "a vocabulary specifier" } }
|
||||
{ $description "Adds a vocabulary to the current manifest." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \USE: } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \USE: } "." } ;
|
||||
|
||||
HELP: unuse-vocab
|
||||
{ $values { "vocab" "a vocabulary specifier" } }
|
||||
{ $description "Removes a vocabulary from the current manifest." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \UNUSE: } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \UNUSE: } "." } ;
|
||||
|
||||
HELP: add-qualified
|
||||
{ $values { "vocab" "a vocabulary specifier" } { "prefix" string } }
|
||||
{ $description "Adds the vocabulary's words, prefixed with the given string, to the current manifest." }
|
||||
{ $notes "If adding the vocabulary introduces ambiguity, the vocabulary will take precedence when resolving any ambiguous names. See the example in " { $link postpone: \QUALIFIED: } " for further explanation." } ;
|
||||
{ $notes "If adding the vocabulary introduces ambiguity, the vocabulary will take precedence when resolving any ambiguous names. See the example in " { $link \ \QUALIFIED: } " for further explanation." } ;
|
||||
|
||||
HELP: add-words-from
|
||||
{ $values { "vocab" "a vocabulary specifier" } { "words" { $sequence "word names" } } }
|
||||
{ $description "Adds " { $snippet "words" } " from " { $snippet "vocab" } " to the current manifest." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \FROM: } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \FROM: } "." } ;
|
||||
|
||||
HELP: add-words-excluding
|
||||
{ $values { "vocab" "a vocabulary specifier" } { "words" { $sequence "word names" } } }
|
||||
{ $description "Adds all words except for " { $snippet "words" } " from " { $snippet "vocab" } " to the manifest." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \EXCLUDE: } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \EXCLUDE: } "." } ;
|
||||
|
||||
HELP: add-renamed-word
|
||||
{ $values { "word" string } { "vocab" "a vocabulary specifier" } { "new-name" string } }
|
||||
{ $description "Imports " { $snippet "word" } " from " { $snippet "vocab" } ", but renamed to " { $snippet "new-name" } "." }
|
||||
{ $notes "This word is used to implement " { $link postpone: \RENAME: } "." } ;
|
||||
{ $notes "This word is used to implement " { $link \ \RENAME: } "." } ;
|
||||
|
||||
HELP: use-words
|
||||
{ $values { "assoc" assoc } }
|
||||
|
@ -170,7 +170,7 @@ HELP: unuse-words
|
|||
{ $description "Removes an assoc mapping word names to words from the current manifest." } ;
|
||||
|
||||
HELP: ambiguous-use-error
|
||||
{ $error-description "Thrown when a word name referenced in source file is available in more than one vocabulary in the manifest. Such cases must be explicitly disambiguated using " { $link postpone: \FROM: } ", " { $link postpone: \EXCLUDE: } ", " { $link postpone: \QUALIFIED: } ", or " { $link postpone: \QUALIFIED-WITH: } "." } ;
|
||||
{ $error-description "Thrown when a word name referenced in source file is available in more than one vocabulary in the manifest. Such cases must be explicitly disambiguated using " { $link \ \FROM: } ", " { $link \ \EXCLUDE: } ", " { $link \ \QUALIFIED: } ", or " { $link \ \QUALIFIED-WITH: } "." } ;
|
||||
|
||||
HELP: search-manifest
|
||||
{ $values { "name" string } { "manifest" manifest } { "word/f" { $maybe word } } }
|
||||
|
|
|
@ -5,7 +5,7 @@ ARTICLE: "words.alias" "Word aliasing"
|
|||
"There is a syntax for defining new names for existing words. This useful for C library bindings, for example in the Win32 API, where words need to be renamed for symmetry."
|
||||
$nl
|
||||
"Define a new word that aliases another word:"
|
||||
{ $subsections postpone: \ALIAS: }
|
||||
{ $subsections \ \ALIAS: }
|
||||
"Define an alias at run-time:"
|
||||
{ $subsections define-alias } ;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ ARTICLE: "words.constant" "Constants"
|
|||
"There is a syntax for defining words which push literals on the stack."
|
||||
$nl
|
||||
"Define a new word that pushes a literal on the stack:"
|
||||
{ $subsections postpone: \CONSTANT: }
|
||||
{ $subsections \ \CONSTANT: }
|
||||
"Define an constant at run-time:"
|
||||
{ $subsections define-constant } ;
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@ USING: help.syntax help.markup words.symbol words compiler.units ;
|
|||
IN: words.symbol
|
||||
|
||||
HELP: symbol
|
||||
{ $class-description "The class of symbols created by " { $link postpone: \SYMBOL: } "." } ;
|
||||
{ $class-description "The class of symbols created by " { $link \ \SYMBOL: } "." } ;
|
||||
|
||||
HELP: define-symbol
|
||||
{ $values { "word" word } }
|
||||
{ $description "Defines the word to push itself on the stack when executed. This is the run time equivalent of " { $link postpone: \SYMBOL: } "." }
|
||||
{ $description "Defines the word to push itself on the stack when executed. This is the run time equivalent of " { $link \ \SYMBOL: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
||||
|
@ -18,8 +18,8 @@ ARTICLE: "words.symbol" "Symbols"
|
|||
}
|
||||
"Defining symbols at parse time:"
|
||||
{ $subsections
|
||||
postpone: \SYMBOL:
|
||||
postpone: \SYMBOLS:
|
||||
\ \SYMBOL:
|
||||
\ \SYMBOLS:
|
||||
}
|
||||
"Defining symbols at run time:"
|
||||
{ $subsections define-symbol }
|
||||
|
|
|
@ -7,7 +7,7 @@ ARTICLE: "interned-words" "Looking up and creating words"
|
|||
$nl
|
||||
"Words whose names are known at parse time -- that is, most words making up your program -- can be referenced in source code by stating their name. However, the parser itself, and sometimes code you write, will need to look up words dynamically."
|
||||
$nl
|
||||
"Parsing words add definitions to the current vocabulary. When a source file is being parsed, the current vocabulary is initially set to " { $vocab-link "scratchpad" } ". The current vocabulary may be changed with the " { $link postpone: \IN: } " parsing word (see " { $link "word-search" } ")."
|
||||
"Parsing words add definitions to the current vocabulary. When a source file is being parsed, the current vocabulary is initially set to " { $vocab-link "scratchpad" } ". The current vocabulary may be changed with the " { $link \ \IN: } " parsing word (see " { $link "word-search" } ")."
|
||||
{ $subsections
|
||||
create-word
|
||||
create-word-in
|
||||
|
@ -30,8 +30,8 @@ ARTICLE: "colon-definition" "Colon definitions"
|
|||
$nl
|
||||
"Defining words at parse time:"
|
||||
{ $subsections
|
||||
postpone: \:
|
||||
postpone: \;
|
||||
\ \:
|
||||
\ \;
|
||||
}
|
||||
"Defining words at run time:"
|
||||
{ $subsections
|
||||
|
@ -54,7 +54,7 @@ ARTICLE: "deferred" "Deferred words and mutual recursion"
|
|||
"Words cannot be referenced before they are defined; that is, source files must order definitions in a strictly bottom-up fashion. This is done to simplify the implementation, facilitate better parse time checking and remove some odd corner cases; it also encourages better coding style."
|
||||
$nl
|
||||
"Sometimes this restriction gets in the way, for example when defining mutually-recursive words; one way to get around this limitation is to make a forward definition."
|
||||
{ $subsections postpone: \DEFER: }
|
||||
{ $subsections \ \DEFER: }
|
||||
"The class of deferred word definitions:"
|
||||
{ $subsections
|
||||
deferred
|
||||
|
@ -69,16 +69,16 @@ $nl
|
|||
} ;
|
||||
|
||||
ARTICLE: "declarations" "Compiler declarations"
|
||||
"Compiler declarations are parsing words that set a word property in the most recently defined word. They appear after the final " { $link postpone: \; } " of a word definition:"
|
||||
"Compiler declarations are parsing words that set a word property in the most recently defined word. They appear after the final " { $link \ \; } " of a word definition:"
|
||||
{ $code ": cubed ( x -- y ) dup dup * * ; foldable" }
|
||||
"Compiler declarations assert that the word follows a certain contract, enabling certain optimizations that are not valid in general."
|
||||
{ $subsections
|
||||
postpone: inline
|
||||
postpone: foldable
|
||||
postpone: flushable
|
||||
postpone: recursive
|
||||
\ inline
|
||||
\ foldable
|
||||
\ flushable
|
||||
\ recursive
|
||||
}
|
||||
"It is entirely up to the programmer to ensure that the word satisfies the contract of a declaration. Furthermore, if a generic word is declared " { $link postpone: foldable } " or " { $link postpone: flushable } ", all methods must satisfy the contract. Unspecified behavior may result if a word does not follow the contract of one of its declarations."
|
||||
"It is entirely up to the programmer to ensure that the word satisfies the contract of a declaration. Furthermore, if a generic word is declared " { $link \ foldable } " or " { $link \ flushable } ", all methods must satisfy the contract. Unspecified behavior may result if a word does not follow the contract of one of its declarations."
|
||||
{ $see-also "effects" } ;
|
||||
|
||||
ARTICLE: "word-props" "Word properties"
|
||||
|
@ -257,15 +257,15 @@ HELP: changed-effect
|
|||
{ $see-also changed-effects } ;
|
||||
|
||||
HELP: deferred
|
||||
{ $class-description "The class of deferred words created by " { $link postpone: \DEFER: } "." } ;
|
||||
{ $class-description "The class of deferred words created by " { $link \ \DEFER: } "." } ;
|
||||
|
||||
{ deferred postpone: \DEFER: } related-words
|
||||
{ deferred \ \DEFER: } related-words
|
||||
|
||||
HELP: undefined
|
||||
{ $error-description "This error is thrown in two cases, and the debugger's summary message reflects the cause:"
|
||||
{ $list
|
||||
{ "A word was executed before being compiled. For example, this can happen if a macro is defined in the same compilation unit where it was used. See " { $link "compilation-units" } " for a discussion." }
|
||||
{ "A word defined with " { $link postpone: \DEFER: } " was executed. Since this syntax is usually used for mutually-recursive word definitions, executing a deferred word usually indicates a programmer mistake." }
|
||||
{ "A word defined with " { $link \ \DEFER: } " was executed. Since this syntax is usually used for mutually-recursive word definitions, executing a deferred word usually indicates a programmer mistake." }
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -297,7 +297,7 @@ HELP: word-code
|
|||
|
||||
HELP: define
|
||||
{ $values { "word" word } { "def" quotation } }
|
||||
{ $description "Defines the word to call a quotation when executed. This is the run time equivalent of " { $link postpone: \: } "." }
|
||||
{ $description "Defines the word to call a quotation when executed. This is the run time equivalent of " { $link \ \: } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
||||
|
@ -373,7 +373,7 @@ HELP: constructor-word
|
|||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $examples { $example "USING: compiler.units prettyprint words ;" "[ \"salmon\" \"scratchpad\" constructor-word ] with-compilation-unit ." "<salmon>" } } ;
|
||||
|
||||
{ postpone: \FORGET: forget forget* forget-vocab } related-words
|
||||
{ \ \FORGET: forget forget* forget-vocab } related-words
|
||||
|
||||
HELP: target-word
|
||||
{ $values { "word" word } { "target" word } }
|
||||
|
@ -385,7 +385,7 @@ HELP: bootstrap-word
|
|||
|
||||
HELP: parsing-word?
|
||||
{ $values { "object" object } { "?" boolean } }
|
||||
{ $description "Tests if an object is a parsing word declared by " { $link postpone: \SYNTAX: } "." }
|
||||
{ $description "Tests if an object is a parsing word declared by " { $link \ \SYNTAX: } "." }
|
||||
{ $notes "Outputs " { $link f } " if the object is not a word." } ;
|
||||
|
||||
HELP: define-declared
|
||||
|
@ -406,17 +406,17 @@ HELP: define-temp
|
|||
|
||||
HELP: delimiter?
|
||||
{ $values { "obj" object } { "?" boolean } }
|
||||
{ $description "Tests if an object is a delimiter word declared by " { $link postpone: delimiter } "." }
|
||||
{ $description "Tests if an object is a delimiter word declared by " { $link \ delimiter } "." }
|
||||
{ $notes "Outputs " { $link f } " if the object is not a word." } ;
|
||||
|
||||
HELP: deprecated?
|
||||
{ $values { "obj" object } { "?" boolean } }
|
||||
{ $description "Tests if an object is " { $link postpone: deprecated } "." }
|
||||
{ $description "Tests if an object is " { $link \ deprecated } "." }
|
||||
{ $notes "Outputs " { $link f } " if the object is not a word." } ;
|
||||
|
||||
HELP: inline?
|
||||
{ $values { "obj" object } { "?" boolean } }
|
||||
{ $description "Tests if an object is " { $link postpone: inline } "." }
|
||||
{ $description "Tests if an object is " { $link \ inline } "." }
|
||||
{ $notes "Outputs " { $link f } " if the object is not a word." } ;
|
||||
|
||||
HELP: subwords
|
||||
|
@ -426,33 +426,33 @@ HELP: subwords
|
|||
{ $example
|
||||
"USING: math.functions prettyprint words ;"
|
||||
"\\ sin subwords ."
|
||||
"{ M\\ object sin M\\ complex sin M\\ real sin M\\ float sin }"
|
||||
"{ M\\\\ object sin M\\\\ complex sin M\\\\ real sin M\\\\ float sin }"
|
||||
}
|
||||
}
|
||||
{ $notes "Outputs " { $link f } " if the word isn't generic." } ;
|
||||
|
||||
HELP: make-deprecated
|
||||
{ $values { "word" word } }
|
||||
{ $description "Declares a word as " { $link postpone: deprecated } "." }
|
||||
{ $description "Declares a word as " { $link \ deprecated } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
||||
HELP: make-flushable
|
||||
{ $values { "word" word } }
|
||||
{ $description "Declares a word as " { $link postpone: flushable } "." }
|
||||
{ $description "Declares a word as " { $link \ flushable } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
||||
HELP: make-foldable
|
||||
{ $values { "word" word } }
|
||||
{ $description "Declares a word as " { $link postpone: foldable } "." }
|
||||
{ $description "Declares a word as " { $link \ foldable } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
||||
HELP: make-inline
|
||||
{ $values { "word" word } }
|
||||
{ $description "Declares a word as " { $link postpone: inline } "." }
|
||||
{ $description "Declares a word as " { $link \ inline } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
||||
HELP: define-inline
|
||||
{ $values { "word" word } { "def" quotation } { "effect" effect } }
|
||||
{ $description "Defines a word and makes it " { $link postpone: inline } "." }
|
||||
{ $description "Defines a word and makes it " { $link \ inline } "." }
|
||||
{ $notes "This word must be called from inside " { $link with-compilation-unit } "." }
|
||||
{ $side-effects "word" } ;
|
||||
|
|
Loading…
Reference in New Issue