factor core

Upload: emporas

Post on 03-Jun-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/12/2019 Factor Core

    1/602

    USING: arrays help.markup help.syntax strings sbufs vectorskernel quotations generic generic.standard classesmath assocs sequences sequences.private combinators.privateeffects ords !IN: combinators

    "#$I%&': (cleave)combinators( (%leave combinators(

    ($he cleave combinators apply multiple quotations to a single value or set ofvalues.(*nl($o quotations:(+ *subsections bi ,bi -bi($hree quotations:(+ *subsections tri ,tri

    -tri("n array of quotations:(+ *subsections cleave ,cleave -cleave /cleave(%leave combinators provide a more readable alternative to repeated applicationsof the ( + *link keep ( combinators. $he folloing example using ( + *linkkeep (:(+ *code

    (0 1 2 3 keep( (0 1 ) 3 keep( (, 4((can be more clearly ritten using ( + *link tri (:(+ *code (0 1 2 3( (0 1 ) 3( (0 , 4 3 tri( !

    "#$I%&': (spread)combinators( (Spread combinators(($he spread combinators apply multiple quotations to multiple values. $heasterisk 5( + *snippet (4( (6 suffixed to these ords7 names signifies thatthey are spread combinators.(*nl($o quotations:(+ *subsections bi4 ,bi4 ($hree quotations:(+ *subsections tri4 ,tri4 ("n array of quotations:(+ *subsections spread (Spread combinators provide a more readable alternative to repeated applicationsof the ( + *link dip ( combinators. $he folloing example using ( + *linkdip (:(

    + *code (0 0 1 2 3 dip 1 ) 3 dip , 4((can be more clearly ritten using ( + *link tri4 (:(

  • 8/12/2019 Factor Core

    2/602

    + *code (0 1 2 3 0 1 ) 3 0 , 4 3 tri4((" generali8ation of the above combinators to any number of quotations can befound in ( + *link (combinators( (.( !

    "#$I%&': (apply)combinators( ("pply combinators(

    ($he apply combinators apply a single quotation to multiple values. $he at sign5( + *snippet (9( (6 suffixed to these ords7 names signifies that they areapply combinators.(+ *subsections bi9 ,bi9 tri9 ,tri9 (" pair of condition ords built from ( + *link bi9 ( to test to values:(+ *subsections both either ("ll of the apply combinators are equivalent to using the corresponding (+ *link (spread)combinators( ( ith the same quotation supplied for everyvalue.( !

    "#$I%&': (dip)keep)combinators( (;reserving combinators((Sometimes it is necessary to temporarily hide values on the datastack. $he (+ *snippet (dip( ( combinators invoke the quotation at the top of the stack(?ello< orld.>( print 3 times !( (if e anted to abstract out the message into a parameter< e could keep it onthe stack beteen iterations:(+ *code (: print)1= 5 message )) 6 1= 0 dup print 3 times drop !( (?oever< keeping loop)invariant values on the stack doesn7t alays ork outnicely. @or example< a ord to subtract a value from each element of asequence:(+ *code (: subtract)n 5 seq n )) seq7 6 sap 0 over ) 3 map nip !( ($hree shuffle ords are required to pass the value around. Instead< theloop)invariant value can be partially applied to a quotation using ( + *linkcurry (< yielding a ne quotation that is passed to ( + *link map (:(+ *example (: subtract)n 5 seq n )) seq7 6 0 ) 3 curry map !( (+ 1= ,= -= A subtract)n .( (+ A 1A ,A ((No consider the ord that is dual to the one above! instead of subtracting ( +*snippet (n( ( from each stack element< it subtracts each element from (+ *snippet (n( (.(*nl(Bne ay to rite this is ith a pair of ( + *link sap (s:(

    + *code (: n)subtract 5 n seq )) seq7 6 sap 0 sap ) 3 curry map !( (Since this pattern comes up often< ( + *link ith ( encapsulates it:(+ *example (: n)subtract 5 n seq )) seq7 6 0 ) 3 ith map !(

  • 8/12/2019 Factor Core

    3/602

    (-= + 1= ,= -= n)subtract .( (+ ,= 1= = (+ *see)also (fry.examples( !

    "#$I%&': (compositional)combinators( (%ompositional combinators((%ertain combinators transform quotations to produce a ne quotation.(

    + *subsections (compositional)examples( (@undamental operations:(+ *subsections curry compose (Cerived operations:(+ *subsections ,curry -curry ith prepose ($hese operations run in constant time< and in many cases are optimi8ed outaltogether by the ( + *link (compiler( (. ( + *link (fry( ( are anabstraction built on top of these operations< and code that uses thisabstraction is often clearer than direct calls to the belo ords.(*nl(%urried dataflo combinators can be used to build more complex dataflo bycombining cleave< spread and apply patterns in various ays.(+ *subsections (curried)dataflo(

    (Duotations also implement the sequence protocol< and can be manipulated ithsequence ords! see ( + *link (quotations( (. ?oever< such runtime quotationmanipulation ill not be optimi8ed by the optimi8ing compiler.( !

    "#$I%&': (booleans( (Eooleans((In @actor< any obFect that is not ( + *link f ( has a true value< and (+ *link f ( has a false value. $he ( + *link t ( obFect is the canonicaltrue value.(+ *subsections f t (" union class of the above:(+ *subsections boolean ($here are some logical operations on booleans:(+ *subsections

    boolean not and or xor(Eoolean values are most frequently used for ( + *link (conditionals( (.(+ *heading ($he f obFect and f class( ($he ( + *link f ( obFect is the unique instance of the ( + *link f ( class!the to are distinct obFects. $he latter is also a parsing ord hich adds the (+ *link f ( obFect to the parse tree at parse time. $o refer to the classitself you must use ( + *link ;BS$;BN': ;BS$;BN': ( or ( + *link ;BS$;BN': > ( to prevent the parsing ord from executing.(*nl(?ere is the ( + *link f ( obFect:(+ *example (f .( (f( (?ere is the ( + *link f ( class:(+ *example (>> f .( (;BS$;BN': f( ($hey are not equal:(+ *example (f >> f H .( (f( (?ere is an array containing the ( + *link f ( obFect:(+ *example (+ f .( (+ f ( (?ere is an array containing the ( + *link f ( class:(+ *example (+ ;BS$;BN': f .( (+ ;BS$;BN': f ( ($he ( + *link f ( obFect is an instance of the ( + *link f ( class:(

    + *example (US': classes( (f class)of .( (;BS$;BN': f( ($he ( + *link f ( class is an instance of ( + *link ord (:(+ *example (US': classes( (>> f class)of .( (ord( (Bn the other hand< ( + *link t ( is Fust a ord< and there is no class hich

  • 8/12/2019 Factor Core

    4/602

    it is a unique instance of.(+ *example (t >> t eq .( (t( (any ords hich search collections confuse the case of no element beingpresent ith an element being found equal to ( + *link f (. If thisdistinction is important< there is usually an alternative ord hich can beused! for example< compare ( + *link at ( ith ( + *link at4 (.( !

    "#$I%&': (conditionals)boolean)equivalence( ('xpressing conditionals ithboolean logic((%ertain simple conditional forms can be expressed in a simpler manner usingboolean logic.(*nl($he folloing to lines are equivalent:(+ *code (0 drop f 3 unless( (sap and( ($he folloing to lines are equivalent:(+ *code (0 3 0 3 if( (sap or( ($he folloing to lines are equivalent< here ( + *snippet (&( ( is aliteral:(+ *code (0 & 3 unless4( (& or( !

    "#$I%&': (conditionals( (%onditional combinators(($he basic conditionals:(+ *subsections if hen unless (@orms abstracting a common stack shuffle pattern:(+ *subsections if4 hen4 unless4 ("nother form abstracting a common stack shuffle pattern:(+ *subsections if (Sometimes instead of branching< you Fust need to pick one of to values:(+ *subsections ($o combinators hich abstract out nested chains of ( + *link if (:(+ *subsections cond case + *subsections (conditionals)boolean)equivalence( + *see)also (booleans( (bitise)arithmetic( both either !

    "#$I%&': (dataflo)combinators( (Cataflo combinators((Cataflo combinators express common dataflo patterns such as performing aoperation hile preserving its inputs< applying multiple operations to a singlevalue< applying a set of operations to a set of values< or applying a singleoperation to multiple values.(+ *subsections (dip)keep)combinators( (cleave)combinators( (spread)combinators( (apply)combinators((ore intricate dataflo can be constructed by composing ( + *link(curried)dataflo( (.( !

    "#$I%&': (combinators)quot( (Duotation construction utilities((Some ords for creating quotations hich can be useful for implementing methodcombinations and compiler transforms:(+ *subsections condquot casequot alistquot !

    "#$I%&': (call)unsafe( (Unsafe combinators((Unsafe calls declare an effect statically ithout any runtime checking:(+ *subsections call)effect)unsafe execute)effect)unsafe !

    "#$I%&': (call( (@undamental combinators(

    ($he most basic combinators are those that take either a quotation or ord< andinvoke it immediately. $here are to sets of these fundamental combinators. $heydiffer in hether the compiler is expected to determine the stack effect of theexpression at compile time or the stack effect is declared and verified at run

  • 8/12/2019 Factor Core

    5/602

    time.(*nl+ *heading (%ompile)time checked combinators( (Jith these combinators< the compiler attempts to determine the stack effect ofthe expression at compile time< reFecting the program if the effect cannot bedetermined. See ( + *link (inference)combinators( (.(+ *subsections call execute

    + *heading (#un)time checked combinators( (Jith these combinators< the stack effect of the expression is checked at runtime.(+ *subsections ;BS$;BN': call5 ;BS$;BN': execute5 (Note that the opening parenthesis is actually part of the ord name for (+ *snippet (call5( ( and ( + *snippet (execute5( (! they are parsing ords case)find t (no)compile( set)ord)prop

    : case 5 obF assoc )) 6 case)find + + 0 dup array 3 0 nip second call 3 + 0 dup callable 3 0 call 3 + 0 dup not 3 0 drop no)case 3 cond !

    : linear)case)quot 5 default assoc )) quot 6 0 0 1quotation > dup prefix > H suffix 3 0 > drop prefix 3 bi4 3 assoc)map alistquot !

    P;#IV"$'

    : 5distribute)buckets6 5 buckets pair keys )) 6

  • 8/12/2019 Factor Core

    17/602

  • 8/12/2019 Factor Core

    18/602

    : recursive)hashcode 5 n obF quot )) code 6 pick = PH 0 -drop = 3 0 0 1 ) 3 ,dip call 3 if ! inline

    K $hese go here< not in sequences and hashtables< since thoseK to cannot depend on us: sequence hashcode4 0 sequence)hashcode 3 recursive)hashcode !

    : array hashcode4 0 sequence)hashcode 3 recursive)hashcode !

    : reversed hashcode4 0 sequence)hashcode 3 recursive)hashcode !

    : slice hashcode4 0 sequence)hashcode 3 recursive)hashcode !

    : iota)tuple hashcode4 over = PH 0 ,drop = 3 0 nip length = sap 0 sequence)hashcode)step 3 each)integer 3 if !

    : hashtable hashcode4 0

    dup assoc)si8e 1 eq 0 assoc)hashcode 3 0 nip assoc)si8e 3 if 3 recursive)hashcode !

    : to)fixed)point 5 ... obFect quot: 5 ... obFect5n6 )) ... obFect5n216 6 )) ...obFect5n6 6 0 keep over H 3 keep 0 to)fixed)point 3 curry unless ! inline recursiveK %opyright 5%6 ,==R< ,=1= Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: assocs init kernel.private namespaces !IN: system

    SING&'$BNS: xL.-, xL.L/ arm ppc.-, ppc.L/ !

    UNIBN: xL xL.-, xL.L/ !UNIBN: ppc ppc.-, ppc.L/ !

    : cpu 5 )) class 6 > cpu get)global ! foldable

    SING&'$BNS: indos macosx linux !

    UNIBN: unix macosx linux !

    : os 5 )) class 6 > os get)global ! foldable

    : vm)compiler 5 )) string 6 > vm)compiler get)global ! foldable

    P;#IV"$'

    : stringcpu 5 str )) class 6 ?+ + (xL.-,( xL.-, + (xL.L/( xL.L/ + (arm( arm + (ppc.-,( ppc.-, + (ppc.L/( ppc.L/ at !

    : stringos 5 str )) class 6 ?+ + (indos( indos + (macosx( macosx

  • 8/12/2019 Factor Core

    19/602

    + (linux( linux at !

    ;#IV"$'

    : image 5 )) path 6 > image get)global !

    : vm 5 )) path 6 > vm get)global !

    : embedded 5 )) 6 BEX)'E'CC'C special)obFect !

    : exit 5 n )) 4 6 do)shutdon)hooks 5exit6 !USING: generic help.markup help.syntax kernel math memorynamespaces sequences kernel.private strings classes.singleton !IN: system

    "EBU$: (system(

    "#$I%&': (system( (System interface(+ *subsections

    (cpu( (os((Getting the path to the @actor V and image:(+ *subsections vm image(Getting a monotonically increasing nanosecond count:(+ *subsections nano)count ('xiting the @actor V:(+ *subsections exit !

    "#$I%&': (cpu( (;rocessor detection((;rocessor detection:(+ *subsections cpu (Supported processors:(+ *subsections xL.-, xL.L/ ppc arm(;rocessor families:(+ *subsections xL !

    "#$I%&': (os( (Bperating system detection((Bperating system detection:(+ *subsections os (Supported operating systems:(+ *subsections linux macosx indos(Bperating system families:(+ *subsections unix

    indos !

  • 8/12/2019 Factor Core

    20/602

    ?'&;: cpu+ *values + (class( singleton)class + *description (Butputs a singleton class ith the name of the current %;U architecture.( !

    ?'&;: os

    + *values + (class( singleton)class + *description (Butputs a singleton class ith the name of the current operating systemfamily.( !

    ?'&;: embedded+ *values + (( (a boolean( + *description ($ests if this @actor instance is embedded in anotherapplication.( !

    ?'&;: exit+ *values + (n( (an integer exit code(

    + *description ('xits the @actor process.( !

    ?'&;: nano)count+ *values + (ns( integer + *description (Butputs a monotonically increasing count of nanoseconds elapsedsince an arbitrary starting time. $he difference of to calls to this ordallos timing. $his ord is unaffected by system clock changes.( + *notes ($his is a lo)level ord. $he ( + *vocab)link (tools.time( (vocabulary defines ords to time code execution time.( !

    ?'&;: image+ *values + (path( (a pathname string( + *description (Butputs the pathname of the currently running @actor image.( !

    ?'&;: vm+ *values + (path( (a pathname string( + *description (Butputs the pathname of the currently running @actor V.( !USING: help.markup help.syntax quotations strings !IN: init

    ?'&;: boot+ *description (%alled on startup as part of the boot quotation to initiali8ethe runtime and prepare it for running user code.( !

    + boot startup)quot set)startup)quot related)ords

    ?'&;: startup)quot+ *values + (quot( quotation + *description (Butputs the initial quotation called by the V on startup.( !

    ?'&;: set)startup)quot+ *values + (quot( quotation + *description (Sets the initial quotation called by the V on startup. $hisquotation must begin ith a call to ( + *link boot (. $he image must be savedfor changes to the boot quotation to take effect.( + *notes ($he ( + *link (tools.deploy( ( tool uses this ord.( !

    ?'&;: startup)hooks

    + *var)description ("n association list mapping string identifiers to quotationsto be run on startup.( !

    ?'&;: shutdon)hooks

  • 8/12/2019 Factor Core

    21/602

    + *var)description ("n association list mapping string identifiers to quotationsto be run on shutdon.( !

    ?'&;: do)startup)hooks+ *description (%alls all initiali8ation hook quotations.( !

    ?'&;: do)shutdon)hooks

    + *description (%alls all shutdon hook quotations.( !

    ?'&;: add)startup)hook+ *values + (quot( quotation + (name( string + *description (#egisters a startup hook. $he hook ill alays run hen @actoris started. If the hook as not already defined< this ord also calls itimmediately.( !

    + startup)hooks do)startup)hooks add)startup)hook add)shutdon)hookdo)shutdon)hooks shutdon)hooks related)ords

    "#$I%&': (init( (Initiali8ation and startup((Jhen @actor starts< the first thing it does is call a ord:(

    + *subsections boot (Next< initiali8ation hooks are called:(+ *subsections do)startup)hooks (Initiali8ation hooks can be defined:(+ *subsections add)startup)hook (%orresponding shutdon hooks may also be defined:(+ *subsections add)shutdon)hook ($he boot quotation can be changed:(+ *subsections startup)quot set)startup)quot(Jhen quitting @actor< shutdon hooks are called:(

    + *subsection do)shutdon)hooks !

    "EBU$: (init(K %opyright 5%6 ,==/< ,== Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: assocs continuations continuations.private kernelkernel.private namespaces !IN: init

    SEB&: startup)hooksSEB&: shutdon)hooks

    startup)hooks global 0 drop V+ clone 3 cache dropshutdon)hooks global 0 drop V+ clone 3 cache drop

    : do)hooks 5 symbol )) 6 get 0 nip call5 )) 6 3 assoc)each !

    : do)startup)hooks 5 )) 6 startup)hooks do)hooks !

    : do)shutdon)hooks 5 )) 6 shutdon)hooks do)hooks !

    : add)startup)hook 5 quot name )) 6 startup)hooks get 0 at 0 drop 3 0 call5 )) 6 3 if 3

    0 set)at 3 -bi !

    : add)shutdon)hook 5 quot name )) 6 shutdon)hooks get set)at !

  • 8/12/2019 Factor Core

    22/602

    : boot 5 )) 6 init)namespaces init)catchstack init)error)handler !

    : startup)quot 5 )) quot 6 BEX)S$"#$U;)DUB$ special)obFect !

    : set)startup)quot 5 quot )) 6 BEX)S$"#$U;)DUB$ set)special)obFect !

    : shutdon)quot 5 )) quot 6 BEX)S?U$CBJN)DUB$ special)obFect !

    : set)shutdon)quot 5 quot )) 6 BEX)S?U$CBJN)DUB$ set)special)obFect !

    0 do)shutdon)hooks 3 set)shutdon)quotUSING: hashtables.private help.markup help.syntaxkernel prettyprint generic sequences sequences.privatenamespaces assocs !IN: hashtables

    "#$I%&': (hashtables.private( (?ashtable implementation details(($his hashtable implementation uses only one auxiliary array in addition to thehashtable tuple itself. $he array stores keys in even slots and values in odd

    slots. Values are looked up ith a hashing strategy that uses quadratic probingto resolve collisions.(*nl($here are to special obFects: the ( + *link 55tombstone66 ( marker and the (+ *link 55empty66 ( marker. Neither of these markers can be used as hashtablekeys.(*nl($he ( + *snippet (count( ( slot is the number of entries including deletedentries< and ( + *snippet (deleted( ( is the number of deleted entries.(+ *subsections Phash)array set)nth)pair

    (If a hashtable7s keys are mutated< or if hashing algorithms change< hashtablescan be rehashed:(+ *subsections rehash !

    "#$I%&': (hashtables( (?ashtables((" hashtable provides efficient 5expected constant time6 lookup and storage ofkeyQvalue pairs. Yeys are compared for equality< and a hashing function is usedto reduce the number of comparisons made. $he literal syntax is covered in (+ *link (syntax)hashtables( (.(*nl(Jords for constructing hashtables are in the ( + *vocab)link (hashtables( (vocabulary. ?ashtables implement the ( + *link (assocs)protocol( (< and all (+ *link (assocs( ( can be used on them! there are no hashtable)specific ordsto access and modify keys< because associative mapping operations are genericand ork ith all associative mappings.(*nl(?ashtables are a class of obFects.(+ *subsections hashtable hashtable(ou can create a ne hashtable ith an initial capacity.(+ *subsections Phashtable (If you don7t care about initial capacity< a more elegant ay to create a nehashtable is to rite:(

    + *code (?+ clone( ($o convert an assoc to a hashtable:(+ *subsections hashtable (@urther topics:(

  • 8/12/2019 Factor Core

    23/602

    + *subsections (hashtables.keys( (hashtables.utilities( (hashtables.private( !

    "#$I%&': (hashtables.keys( (?ashtable keys(

    (?ashtables rely on the ( + *link hashcode ( ord to rapidly locate valuesassociated ith keys. $he obFects used as keys in a hashtable must obey certainrestrictions.(*nl($he ( + *link hashcode ( of a key is a function of its slot values< and ifthe hashcode changes then the hashtable ill be left in an inconsistent state.$he easiest ay to avoid this problem is to never mutate obFects used ashashtable keys.(*nl(In certain advanced applications< this cannot be avoided and the best designinvolves mutating hashtable keys. In this case< a custom ( + *link hashcode4 (method must be defined hich only depends on immutable slots.(*nl

    (In addition< the ( + *link equal ( and ( + *link hashcode4 ( methods mustbe congruent< and if one is defined the other should be defined also. $his isdocumented in detail in the documentation for these respective ords.(+ *subsections hashcode hashcode4 identity)hashcode !

    "#$I%&': (hashtables.utilities( (?ashtable utilities((Utility ords to create a ne hashtable from a single keyQvalue pair:(+ *subsections associate set)at !

    "EBU$: (hashtables(

    ?'&;: hashtable+ *description ($he class of hashtables. See ( + *link (syntax)hashtables( (for syntax and ( + *link (hashtables( ( for general information.( !

    ?'&;: hash9+ *values + (key( (a key( + (array( (the underlying array of a hashtable( + (i( (the index to begin hashtable search( + *description (%omputes the index to begin searching from the hashcode of thekey. "lays outputs an even value since keys are stored at even indices of theunderlying array.( !

    ?'&;: probe+ *values + (array( (the underlying array of a hashtable( + (i( (a searchindex( + (probeZ( (an incrementing counter( + *description (Butputs the next hashtable search index.( !

    ?'&;: key9+ *values + (key( (a key( + (hash( hashtable + (array( (the underlying arrayof the hashtable( + (n( (the index of the key( + (( (a boolean indicatinghether the key as present( + *description (Searches the hashtable for the key using a quadratic probingstrategy. Searches stop if either the key or an ( + *link 55empty66 ( sentinelis found. Searches skip the ( + *link 55tombstone66 ( sentinel.( !

    + key9 ne)key9 related)ords

    ?'&;: ne)key9+ *values + (key( (a key( + (hash( hashtable + (array( (the underlying array

  • 8/12/2019 Factor Core

    24/602

    of the hashtable( + (n( (the index here the key ould be stored( + *description (Searches the hashtable for the key using a quadratic probingstrategy. If the key is not present in the hashtable< outputs the index here itshould be stored.( !

    ?'&;: set)nth)pair+ *values + (value( (the second element of the pair( + (key( (the first

    element of the pair( + (seq( (a sequence( + (n( (an index in the sequence( + *description (Stores a pair of values into the elements ith index (+ *snippet (n( ( and ( + *snippet (n21( (< respectively.( + *arning ($his ord is in the ( + *vocab)link (hashtables.private( (vocabulary because it does not perform bounds checks.( + *side)effects (seq( !

    ?'&;: reset)hash+ *values + (n( (a positive integer specifying hashtable capacity( + (hash(hashtable + *description (#esets the underlying array of the hashtable to a ne array iththe given capacity. #emoves all entries from the hashtable.(

    + *side)effects (hash( !

    ?'&;: hash)count2+ *values + (hash( hashtable + *description (%alled to increment the hashtable si8e hen a ne entry is addedith ( + *link set)at + *side)effects (hash( !

    ?'&;: hash)deleted2+ *values + (hash( hashtable + *description (%alled to increment the deleted entry counter hen an entry isremoved ith ( + *link delete)at + *side)effects (hash( !

    ?'&;: gro)hash+ *values + (hash( hashtable + *description ('nlarges the capacity of a hashtable. User code does not need tocall this ord directly.( + *side)effects (hash( !

    ?'&;: gro)hash+ *values + (hash( hashtable + *description ('nlarges the capacity of a hashtable if it is almost full. Usercode does not need to call this ord directly.( + *side)effects (hash( !

    ?'&;: Phashtable+ *values + (n( (a positive integer specifying hashtable capacity( + (hash( (ane hashtable( + *description (%reate a ne hashtable capable of storing ( + *snippet (n( (keyQvalue pairs before groing.( !

    ?'&;: associate+ *values + (value( (a value( + (key( (a key( + (hash( (a ne ( + *linkhashtable + *description (%reate a ne hashtable holding one keyQvalue pair.( !

    ?'&;: set)at

    + *values + (value( obFect + (key( obFect + (assocQf( (an assoc or ( + *linkf + (assoc( assoc

  • 8/12/2019 Factor Core

    25/602

    + *description (If the third input is an assoc< stores the keyQvalue pair intothat assoc< or else creates a ne hashtable ith the keyQvalue pair as its onlyentry.( !

    ?'&;: hashtable+ *values + (assoc( assoc + (hashtable( hashtable + *description (%onstructs a hashtable from any assoc.( !

    ?'&;: rehash+ *values + (hash( hashtable + *description (#ebuild the hashtable. $his ord should be called if thehashcodes of the hashtable7s keys have changed< or if the hashing algorithmsthemselves have changed< neither of hich should occur during normal operation.( !USING: accessors assocs continuations hashtables io kernel makemath namespaces prettyprint sequences sequences.privatetools.test vectors !IN: hashtables.tests

    0 ?+ 3 0 + 0 dup 3 ?+ mapassoc 3 unit)test

    0 3 0 1=== iota 0 dup sq 3 ?+ mapassoc (testhash( set 3 unit)test

    0 V+ 30 1=== iota 0 dup sq sap (testhash( get at H not 3 filter 3unit)test

    0 t 30 (testhash( get hashtable 3unit)test

    0 f 30 + 1 + , - hashtable 3

    unit)test

    + t 0 (value( (key( 0 associate 3 0 ?+ clone 0 set)at 3 keep 3 ,bi 0 H 3 0 0 array length 3 bi9 H 3 ,bi and3 unit)test

    K $est some hashcodes.

    0 t 3 0 0 1 , - 3 hashcode 0 1 , - 3 hashcode H 3 unit)test0 t 3 0 0 1 0 , - 3 / 3 hashcode 0 1 0 , - 3 / 3 hashcode H 3 unit)test

    0 t 3 0 1, hashcode 1, hashcode H 3 unit)test0 t 3 0 1, bignum hashcode 1, hashcode H 3 unit)test

    K $est various odd keys to see if they ork.

    1L Phashtable (testhash( set

    t + , - (testhash( get set)atf 1========================== (testhash( get set)at+ + 0 + 3 (testhash( get set)at

    0 t 3 0 + , - (testhash( get at 3 unit)test

    0 f 3 0 1========================== (testhash( get at4 drop 3 unit)test0 + 3 0 + 0 + 3 clone (testhash( get at4 drop 3 unit)test

    K #egression

  • 8/12/2019 Factor Core

    26/602

    - Phashtable (broken)remove( set1 J+ > 2 dup (x( set (broken)remove( get set)at, J+ > H dup (y( set (broken)remove( get set)at(x( get (broken)remove( get delete)at, (y( get (broken)remove( get set)at0 1 3 0 (broken)remove( get keys length 3 unit)test

    + + (salmon( (fish( + (crocodile( (reptile( + (co( (mammal( + (visual basic( (language( hashtable (testhash( set

    0 f f 3 0 (visual basic( (testhash( get delete)at (visual basic( (testhash( get at43 unit)test

    0 t 3 0 ?+ dup H 3 unit)test

    0 f 3 0 (xy8( ?+ H 3 unit)test0 t 3 0 ?+ ?+ H 3 unit)test0 f 3 0 ?+ + 1 - ?+ H 3 unit)test0 f 3 0 ?+ ?+ + 1 - H 3 unit)test0 t 3 0 ?+ + 1 - ?+ + 1 - H 3 unit)test0 f 3 0 ?+ + 1 - ?+ + 1 (hey( H 3 unit)test

    K $esting the hash element counting

    ?+ clone (counting( set(value( (key( (counting( get set)at0 1 3 0 (counting( get assoc)si8e 3 unit)test(value( (key( (counting( get set)at

    0 1 3 0 (counting( get assoc)si8e 3 unit)test(key( (counting( get delete)at0 = 3 0 (counting( get assoc)si8e 3 unit)test(key( (counting( get delete)at0 = 3 0 (counting( get assoc)si8e 3 unit)test

    K $est rehashing

    , Phashtable (rehash( set

    1 1 (rehash( get set)at, , (rehash( get set)at- - (rehash( get set)at/ / (rehash( get set)atA A (rehash( get set)atL L (rehash( get set)at

    0 L 3 0 (rehash( get assoc)si8e 3 unit)test

    0 L 3 0 (rehash( get clone assoc)si8e 3 unit)test

    (rehash( get clear)assoc

    0 = 3 0 (rehash( get assoc)si8e 3 unit)test

    0 -3 0 , ?+

  • 8/12/2019 Factor Core

    27/602

    + 1 , + , - clone at3 unit)test

    K $here as an assoc in place of assoc4 somehere- Phashtable (f)hash)test( set

    1= 0 f f (f)hash)test( get set)at 3 times

    0 1 3 0 (f)hash)test( get assoc)si8e 3 unit)test

    K #esource leak...?+ (x( set1== 0 drop (x( get clear)assoc 3 each)integer

    K %rash discovered by erg0 t 3 0 =.RA Phashtable dup clone H 3 unit)test

    K "nother crash discovered by erg

    0 3 0 ?+ clone 0 1 sap set)at 3 ignore)errors 0 , sap set)at 3 ignore)errors 0 - sap set)at 3 ignore)errors drop3 unit)test

    0 ?+ + )1 / + )- 1L + )A -L 3 0 ?+ + 1 , + - / + A L 0 0 neg 3 dip sq 3 assoc)map3 unit)test

    K Eug discovered by littledan0 + A A A A 3 0 0 ?+ + 1 , + , - + - / + / A + A L clone dup keys length < dup assoc)si8e < dup rehash dup keys length < assoc)si8e < 3 + make3 unit)test

    0 + (one( (to( - 3 0 + 1 , - ?+ + 1 (one( + , (to( substitute3 unit)test

    K Je ant this to ork0 3 0 hashtable ne (h( set 3 unit)test

    0 = 3 0 (h( get assoc)si8e 3 unit)test

    0 f f 3 0 (goo( (h( get at4 3 unit)test

  • 8/12/2019 Factor Core

    28/602

    0 3 0 1 , (h( get set)at 3 unit)test

    0 1 3 0 (h( get assoc)si8e 3 unit)test

    0 1 3 0 , (h( get at 3 unit)test

    K #andom test case

    0 ("( 3 0 1== iota 0 dup 3 ?+ mapassoc -, over delete)at ("( -, pick set)at-, of 3 unit)testK %opyright 5%6 ,==A< ,=11 Xohn Eenediktsson< Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: accessors arrays assocs kernel kernel.private mathmath.private sequences sequences.private slots.private vectors !IN: hashtables

    $U;&': hashtable+ count array)capacity + deleted array)capacity + array array !

    P;#IV"$'

    : rap 5 i array )) n 6 length 1 fixnum)fast fixnum)bitand ! inline

    : hash9 5 key array )) i 6 0 hashcode fixnum dup fixnum2fast 3 dip rap ! inline

    : probe 5 array i probeZ )) array i probeZ 6 , fixnum2fast 0 fixnum2fast over rap 3 keep ! inline

    : no)key 5 key array )) array n 6 nip f f ! inline

    : 5key96 5 key array i probeZ )) array n 6 0 -dup sap array)nth 3 dip over 55empty66 eq 0 /drop no)key 3 0 0 H 3 dip sap 0 drop rot drop t 3 0 probe 5key96 3 if 3 if ! inline recursive

    : key9 5 key hash )) array n 6 array dup length = eq 0 no)key 3 0 ,dup hash9 = 5key96 3 if ! inline

    : Phash)array 5 n )) array 6 1 2 next)poer)of), / 4 55empty66 Parray ! inline

    : init)hash 5 hash )) 6 = count = deleted drop ! inline

    : reset)hash 5 n hash )) 6 sap Phash)array array init)hash ! inline

    : hash)count2 5 hash )) 6 0 1 fixnum2fast 3 change)count drop ! inline

    : hash)deleted2 5 hash )) 6 0 1 fixnum2fast 3 change)deleted drop ! inline

    : hash)deleted) 5 hash )) 6

  • 8/12/2019 Factor Core

    29/602

    0 1 fixnum)fast 3 change)deleted drop ! inline

    K i H first)empty)or)foundK F H first)deletedK empty H if true< key as not foundKK if empty is f:

    K ) e ant to store into iKK if empty is t:K ) e ant to store into F if F is not fK ) otherise e ant to store into iK ) ... and increment count

    : 5ne)key96 5 key array i probeZ F )) array i F empty 6 0 ,dup sap array)nth 3 ,dip pick tombstone 0 rot 55empty66 eq 0 nip 0 drop 3 -dip t 3 0 pick or 0 probe 3 dip 5ne)key96 3

    if 3 0 0 0 pick 3 dip H 3 ,dip rot 0 nip 0 drop 3 -dip f 3 0 0 probe 3 dip 5ne)key96 3 if 3 if ! inline recursive

    : ne)key9 5 key hash )) array n 6 0 array ,dup hash9 = f 5ne)key96 3 keep sap 0 over 0 hash)deleted) 3 0 hash)count2 3 if sap or 3 0 ,drop 3 if ! inline

    : set)nth)pair 5 value key seq n )) 6

    , fixnum2fast 0 set)slot 3 ,keep 1 fixnum2fast set)slot ! inline

    : 5set)at6 5 value key hash )) 6 dupd ne)key9 set)nth)pair ! inline

    : 5rehash6 5 alist hash )) 6 0 sapd 5set)at6 3 curry assoc)each ! inline

    : hash)large 5 hash )) 6 0 count - fixnum4fast 1 fixnum2fast 3 0 array length 3 bi fixnum ! inline

    : each)pair 5 array quot: 5 key value )) 6 )) 6 0 0 length ,Q 3 keep 0 0 1 fixnum)shift)fast 3 dip 0 array)nth 3 ,keep pick tombstone 0 -drop 3 3 curry 3 dip 0 0 1 fixnum2fast 3 dip array)nth 3 prepose 0 if 3 curry compose each)integer ! inline

    : gro)hash 5 hash )) 6 + hashtable declare 0 0 array 3

    0 assoc)si8e 1 2 3 0 reset)hash 3 tri 3 keep 0 sapd 5set)at6 3 curry each)pair !

  • 8/12/2019 Factor Core

    30/602

    : gro)hash 5 hash )) 6 dup hash)large 0 gro)hash 3 0 drop 3 if ! inline

    ;#IV"$'

    : Phashtable 5 n )) hash 6 hashtable ne 0 reset)hash 3 keep ! inline

    : hashtable at4 key9 0 - fixnum2fast slot t 3 0 ,drop f f 3 if !

    : hashtable clear)assoc 0 init)hash 3 0 array 0 drop 55empty66 3 mapK drop 3 bi !

    : hashtable delete)at 0 nip 3 0 key9 3 ,bi 0 0 55tombstone66 dup 3 ,dip set)nth)pair hash)deleted2 3 0 -drop

    3 if !

    : hashtable assoc)si8e 0 count 3 0 deleted 3 bi ) ! inline

    : rehash 5 hash )) 6 0 alist 3 0 clear)assoc 3 0 5rehash6 3 tri !

    : hashtable set)at dup gro)hash 5set)at6 !

    : associate 5 value key )) hash 6 1 Phashtable 0 set)at 3 keep ! inline

    P;#IV"$'

    : push)unsafe 5 elt seq )) 6 0 length 3 keep 0 underlying set)array)nth 3 0 0 1 fixnum2fast + array)capacity declare 3 dip lengthPP 3 ,bi ! inline

    : collect)pairs 5 hash quot: 5 key value )) elt 6 )) seq 6 0 0 array 3 0 assoc)si8e Pvector 3 bi 3 dip sap 0 0 push)unsafe 3 curry compose each)pair 3 keep + like ! inline

    ;#IV"$'

    : hashtable alist 0 ,array 3 collect)pairs !

    : hashtable keys 0 drop 3 collect)pairs !

    : hashtable values 0 nip 3 collect)pairs !

    : hashtable clone 5clone6 0 clone 3 change)array ! inline

    : hashtable equal over hashtable 0 assocH 3 0 ,drop f 3 if !

    K Cefault method

  • 8/12/2019 Factor Core

    31/602

  • 8/12/2019 Factor Core

    32/602

    that defines slots ith certain names.(*nl(In most cases< using the setter is preferred over the riter because the stackeffect is better suited to the common case here the tuple is needed again< andhere the ne slot value as Fust computed and so is at the top of the stack.@or example< consider the case here you ant to create a tuple and fill in theslots ith literals. $he folloing version uses setters:(

    + *code (Pemail( ( >(?appy birthday>( subFect( ( + >(bob9bigcorp.com>( to( ( >(alice9bigcorp.com>( from( (send)email(($he folloing uses riters< and requires some stack shuffling:(+ *code (Pemail( ( >(?appy birthday>( over subFectPP( ( + >(bob9bigcorp.com>( over toPP( ( >(alice9bigcorp.com>( over fromPP(

    (send)email(('ven if some of the slot values come from the stack underneath the tuple beingconstructed< setters in:(+ *code (Pemail( ( sap subFect( ( sap to( ( >(alice9bigcorp.com>( from( (send)email(($he above has less shuffling than the riter version:(+ *code

    (Pemail( ( 0 subFectPP 3 keep( ( 0 toPP 3 keep( ( >(alice9bigcorp.com>( over fromPP( (send)email(($he changer ord abstracts a common pattern here a slot value is read thenstored again! so the folloing is not idiomatic code:(+ *code (find)manager( ( salary =.RA 4 salary(($he folloing version is preferred:(+ *code (find)manager( ( 0 =.RA 4 3 change)salary(+ *see)also (slots( (mirrors( !

    "#$I%&': (slot)initial)values( (Initial values of slots(("n initial value for a slot can be specified ith the ( + *link initial: (slot declaration attribute. @or certain classes< the initial value is optional!in these cases< it does not need to be specified. @or others< it is required.Initial values can be used independently of class declaration< but if specified(>(( + + + *link byte)array + *snippet (E+ ( + + + *link pinned)alien + *snippet (E"C)"&I'N( ("ll other classes are handled ith one of to cases:(

    + *list + (If the class is a union or mixin class hich ( + *emphasis (contains( (one of the above knon classes< then the initial value of the class is that ofthe knon class< ith preference given to classes earlier in the list. @orexample< if the slot is declared ( + *link obFect ( 5this is the default6< theinitial value is ( + *link f (. Similarly for ( + *link sequence ( and (+ *link assoc (.( + (If the class is a tuple class< the initial value of the slot is a ne(io.streams>( child)vocabs .((+ >(io.streams.c>( >(io.streams.duplex>( >(io.streams.lines>( >(io.streams.nested>( >(io.streams.plain>( >(io.streams.string>( ( !

    ?'&;: vocab)link+ *class)description (Instances of this class identify vocabularies hich arepotentially not loaded. $he ( + *link vocab)name ( slot is the vocabularyname.(*nl(Vocabulary links are created by calling ( + *link vocab)link (.( !

    ?'&;: vocab)link+ *values + (name( string + (vocab( (a vocabulary specifier( + *description (If the vocabulary is loaded< outputs the corresponding ( + *linkvocab ( instance< otherise creates a ne ( + *link vocab)link (.( !

    ?'&;: runnable)vocab+ *class)description ($he class of vocabularies ith a ( + *slot (main( (ord.( !USING: vocabs.loader tools.test continuations vocabs mathkernel arrays sequences namespaces io.streams.string setsparser source)files ords assocs classes.tuple definitionsdebugger compiler.units accessors eval vocabs.hierarchycombinators vocabs.parser grouping vocabs.files vocabs.refresh !IN: vocabs.loader.tests

    K $his vocab should not exist< but Fust in case...0 3 0

    0 (vocabs.loader.test( forget)vocab 3 ith)compilation)unit3 unit)test

  • 8/12/2019 Factor Core

    48/602

    0 $+ vocab)link f (vocabs.loader.test( 30 (vocabs.loader.test( vocab)link 3 unit)test

    0 t 30 (kernel( vocab)link (kernel( lookup)vocab H 3 unit)test

    IN: vocabs.loader.test.,

    : hello 5 )) 6 !

    "IN: hello

    IN: vocabs.loader.tests

    0 3 0 (vocabs.loader.test.,( run (vocabs.loader.test.,( lookup)vocab run (vocabs.loader.test.,( Pvocab)link run3 unit)test

    0 (resource:coreQvocabsQloaderQtestQaQa.factor( forget)source (vocabs.loader.test.a( forget)vocab3 ith)compilation)unit

    = (count)me( set)global

    , 0 0 (vocabs.loader.test.a( require 3 must)fail

    0 f 3 0 (vocabs.loader.test.a( lookup)vocab source)loaded 3 unit)test

    0 t 3 0 (resource:coreQvocabsQloaderQtestQaQa.factor( source)file definitions dup US': prettyprint . (v)l)t)a)hello( (vocabs.loader.test.a( lookup)ord dup . sap first in 3 unit)test3 times

    0 , 3 0 (count)me( get)global 3 unit)test

    0 (IN: vocabs.loader.test.a v)l)t)a)hello( Pstring)reader (resource:coreQvocabsQloaderQtestQaQa.factor( parse)stream3 0 error error error no)ord)error 3 must)fail)ith

    = (count)me( set)global

    0 3 0 0 (vocabs.loader.test.b( forget)vocab 3 ith)compilation)unit3 unit)test

    0 f 3 0 (vocabs.loader.test.b( vocab)files empty 3 unit)test

    0 3 0 0

  • 8/12/2019 Factor Core

    49/602

    (vocabs.loader.test.b( vocab)files 0 forget)source 3 each 3 ith)compilation)unit3 unit)test

    0 (vocabs.loader.test.b( require 3 must)fail

    0 1 3 0 (count)me( get)global 3 unit)test

    0 3 0 0 (bob( (vocabs.loader.test.b( create 0 3 define 3 ith)compilation)unit3 unit)test

    0 3 0 (vocabs.loader.test.b( refresh 3 unit)test

    0 , 3 0 (count)me( get)global 3 unit)test

    0 f 3 0 (fred( (vocabs.loader.test.b( lookup)ord undefined)ord 3 unit)test

    0 3 0 0 (vocabs.loader.test.b( vocab)files 0 forget)source 3 each 3 ith)compilation)unit3 unit)test

    0 3 0 (vocabs.loader.test.b( changed)vocab 3 unit)test

    0 3 0 (vocabs.loader.test.b( refresh 3 unit)test

    0 - 3 0 (count)me( get)global 3 unit)test

    0 + (resource:coreQkernelQkernel.factor( 1 30 (kernel( Pvocab)link here 3 unit)test

    0 + (resource:coreQkernelQkernel.factor( 1 30 (kernel( lookup)vocab here 3 unit)test

    0 3 0 0 (vocabs.loader.test.c( forget)vocab (vocabs.loader.test.d( forget)vocab 3 ith)compilation)unit3 unit)test

    0 2done2 3 0 0 (vocabs.loader.test.d( require 3 0 :1 3 recover (vocabs.loader.test.d( lookup)vocab source)loaded3 unit)test

    : forget)Funk 5 )) 6 0 + (,( (a( (b( (d( (e( (f( 0 (vocabs.loader.test.( prepend forget)vocab 3 each

    3 ith)compilation)unit !

    forget)Funk

  • 8/12/2019 Factor Core

    50/602

    0 + 3 0 (IN: xabbabbFa( eval5 )) 6 (xabbabbFa( vocab)files3 unit)test

    0 (xabbabbFa( forget)vocab 3 ith)compilation)unit

    forget)Funk

    0 3 0 0 (vocabs.loader.test.e( forget)vocab 3 ith)compilation)unit 3 unit)test

    = (vocabs.loader.test.g( set)global

    0 (vocabs.loader.test.f( forget)vocab (vocabs.loader.test.g( forget)vocab3 ith)compilation)unit

    0 3 0 (vocabs.loader.test.g( require 3 unit)test

    0 1 3 0 (vocabs.loader.test.g( get)global 3 unit)test

    0 (vocabs.loader.test.h( forget)vocab (vocabs.loader.test.i( forget)vocab3 ith)compilation)unit

    0 3 0 (vocabs.loader.test.h( require 3 unit)test

    0 (vocabs.loader.test.F( forget)vocab (vocabs.loader.test.k( forget)vocab3 ith)compilation)unit

    0 3 0 0 (vocabs.loader.test.F( require 3 0 drop :1 3 recover 3 unit)test

    0 3 0 (vocabs.loader.test.m( require 3 unit)test0 f 3 0 (vocabs.loader.test.n( lookup)vocab 3 unit)test0 3 0 (vocabs.loader.test.o( require 3 unit)test0 t 3 0 (vocabs.loader.test.n( lookup)vocab boolean 3 unit)test

    0 (mno( 0 (vocabs.loader.test.( sap suffix forget)vocab 3 each3 ith)compilation)unit

    0 3 0 (vocabs.loader.test.o( require 3 unit)test0 f 3 0 (vocabs.loader.test.n( lookup)vocab 3 unit)test0 3 0 (vocabs.loader.test.m( require 3 unit)test0 t 3 0 (vocabs.loader.test.n( lookup)vocab boolean 3 unit)test

    0 f 3 0 (vocabs.loader.test.p( lookup)vocab 3 unit)test0 3 0 (vocabs.loader.test.p.private( require 3 unit)test0 + (foo( 3 0 (vocabs.loader.test.p( ords 0 name 3 map 3 unit)test

    0 (mnop( 0 (vocabs.loader.test.( sap suffix forget)vocab 3 each3 ith)compilation)unitUSING: vocabs vocabs.loader.private help.markup help.syntax

    ords strings io !IN: vocabs.loader

    "#$I%&': (add)vocab)roots( (Jorking ith code outside of the @actor source tree(

  • 8/12/2019 Factor Core

    51/602

    (ou can ork ith code outside of the @actor source tree by adding additionaldirectories to the list of vocabulary roots.(*nl($here are three ays of doing this.(*nl($he first ay is to use an environment variable. @actor looks at the (+ *snippet (@"%$B#[#BB$S( ( environment variable for a list of ( + *snippet

    (:( ()separated paths 5on Unix6 or a list of ( + *snippet (!( ()separatedpaths 5on Jindos6.(*nl($he second ay is to create a configuration file. ou can list additionalvocabulary roots in a file that @actor reads at startup:(+ *subsections (.factor)roots( (@inally< you can add vocabulary roots by calling a ord from your ( + *snippet(.factor)rc( ( file 5see ( + *link (.factor)rc( (6:(+ *subsections add)vocab)root !

    "#$I%&': (vocabs.roots( (Vocabulary roots(($he vocabulary loader searches for vocabularies in one of the rootdirectories:(

    + *subsections vocab)roots ($he default set of roots includes the folloing directories in the @actorsource directory:(+ *list + + *snippet (core( ( ) essential system vocabularies such as (+ *vocab)link (parser( ( and ( + *vocab)link (sequences( (. $he vocabulariesin this root constitute the boot image! see ( + *link (bootstrap.image( (.( + + *snippet (basis( ( ) useful libraries and tools< such as (+ *vocab)link (compiler( (< ( + *vocab)link (ui( (< ( + *vocab)link(calendar( (< and so on.( + + *snippet (extra( ( ) additional contributed libraries.( + + *snippet (ork( ( ) a root for vocabularies hich are not intended tobe contributed back to @actor.(

    (ou can store your on vocabularies in the ( + *snippet (ork( ( directory.(+ *subsections (add)vocab)roots( !

    "#$I%&': (vocabs.icons( (Vocabulary icons(("n icon file representing the vocabulary can be provided for use by ( + *link(tools.deploy( (. If any of the folloing files exist inside the vocabularydirectory< they ill be used as icons hen the application is deployed.(+ *list + + *snippet (icon.ico( ( on Jindos( + + *snippet (icon.icns( ( on acBS M( + + *snippet (icon.png( ( on &inux and 4ESC( !

    "#$I%&': (vocabs.loader( (Vocabulary loader(($he ( + *link ;BS$;BN': US': ( and ( + *link ;BS$;BN': USING: ( ords loadvocabularies using the vocabulary loader. $he vocabulary loader is implementedin the ( + *vocab)link (vocabs.loader( ( vocabulary.(*nl($he vocabulary loader searches for vocabularies in a set of directories knonas vocabulary roots.(+ *subsections (vocabs.roots( (Vocabulary names map directly to source files inside these roots. " vocabularynamed ( + *snippet (foo.bar( ( is defined in ( + *snippet (fooQbarQbar.factor( (! that is< a source file named ( + *snippet (bar.factor( ( ithin a (

    + *snippet (bar( ( directory nested inside a ( + *snippet (foo( ( directoryof a vocabulary root. "ny level of nesting< separated by dots< is permitted.(*nl($he vocabulary directory ) ( + *snippet (bar( ( in our example ) contains a

  • 8/12/2019 Factor Core

    52/602

    source file:(+ *list + + *snippet (fooQbarQbar.factor( ( ) the source file must define ords inthe ( + *snippet (foo.bar( ( vocabulary ith an ( + *snippet (IN: foo.bar( (form( ($o other @actor source files< storing documentation and tests< respectively> "IN: help( print 3 if !

    SEB&: blacklist

    P;#IV"$'

  • 8/12/2019 Factor Core

    57/602

    : add)to)blacklist 5 error vocab )) 6 vocab)name blacklist get dup 0 set)at 3 0 -drop 3 if !

    G'N'#I%: 5require6 5 name )) 6

    : vocab 5require6

    0 dup source)loaded 2parsing2 eq 0 drop 3 0 dup source)loaded 0 dup load)source 3 unless dup docs)loaded 0 dup load)docs 3 unless drop 3 if 3 0 0 sap add)to)blacklist 3 keep rethro 3 recover !

    : vocab)link 5require6 vocab)name 5require6 !

    : string 5require6 create)vocab 5require6 !

    ;#IV"$'

    0 dup vocab)name blacklist get at4 0 rethro 3 0 drop dup find)vocab)root 0 5require6 3 0 dup lookup)vocab 0 drop 3 0 no)vocab 3 if 3 if 3 if3 require)hook set)global

    : vocab)spec here vocab)source)path dup 0 1 ,array 3 hen !

    K put here to avoid circularity beteen vocabs.loader and source)files.errors+ (source)files.errors( (debugger( (source)files.errors.debugger( require)henK %opyright 5%6 ,==R< ,== 'duardo %ava8os< Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: accessors assocs definitions kernel namespaces sequencessorting splitting strings !IN: vocabs

    SEB&: dictionary

    $U;&': vocab P identity)tuplename ordsmain helpsource)loaded docs)loaded !

    K sources)loaded slot is one of these threeSEB&: 2parsing2SEB&: 2running2SEB&: 2done2

    : Pvocab 5 name )) vocab 6 > vocab ne sap name

    ?+ clone ords !

    '##B#: bad)vocab)name name !

  • 8/12/2019 Factor Core

    58/602

    : check)vocab)name 5 name )) name 6 dup string 0 bad)vocab)name 3 unless dup 0 (:Q>> ( member 3 any 0 bad)vocab)name 3 hen !

    $U;&': vocab)link name !

    %: Pvocab)link vocab)link

    UNIBN: vocab)spec vocab vocab)link !

    G'N'#I%: vocab)name 5 vocab)spec )) name 6

    : vocab vocab)name name !

    : vocab)link vocab)name name !

    : obFect vocab)name check)vocab)name !

    : vocab)name4 5 vocab)spec )) name 6 vocab)name (.private( tail drop !

    : private)vocab 5 vocab )) 6 vocab)name (.private( tail !

    G'N'#I%: lookup)vocab 5 vocab)spec )) vocab 6

    : vocab lookup)vocab !

    : obFect lookup)vocab 5 name )) vocab 6 vocab)name dictionary get at !

    G'N'#I%: vocab)ords 5 vocab)spec )) ords 6

    : vocab vocab)ords ords !

    : obFect vocab)ords lookup)vocab vocab)ords !

    : f vocab)ords !

    G'N'#I%: vocab)help 5 vocab)spec )) help 6

    : vocab vocab)help help !

    : obFect vocab)help lookup)vocab vocab)help !

    : f vocab)help !

    G'N'#I%: vocab)main 5 vocab)spec )) main 6

    : vocab vocab)main main !

    : obFect vocab)main lookup)vocab vocab)main !

    : f vocab)main !

    SEB&: vocab)observers

    G'N'#I%: vocab)changed 5 vocab obF )) 6

    : add)vocab)observer 5 obF )) 6 vocab)observers get push !

    : remove)vocab)observer 5 obF )) 6

  • 8/12/2019 Factor Core

    59/602

    vocab)observers get remove)eqK drop !

    : notify)vocab)observers 5 vocab )) 6 vocab)observers get 0 vocab)changed 3 ith each !

    : create)vocab 5 name )) vocab 6 check)vocab)name dictionary get

    0 Pvocab dup notify)vocab)observers 3 cache !

    '##B#: no)vocab name !

    : vocabs 5 )) seq 6 dictionary get keys natural)sort !

    : ords 5 vocab )) seq 6 vocab)ords values !

    : all)ords 5 )) seq 6 dictionary get values 0 ords 3 map concat !

    : ords)named 5 str )) seq 6 dictionary get values 0 vocab)ords at 3 ith map sift !

    : child)vocab 5 prefix name )) 6 ,dup H pick empty or 0 ,drop t 3 0 sap %?"#: . suffix head 3 if !

    : child)vocabs 5 vocab )) seq 6 vocab)name vocabs 0 child)vocab 3 ith filter !

    G'N'#I%: vocab)link 5 name )) vocab 6

    : vocab)spec vocab)link !

    : obFect vocab)link dup lookup)vocab 0 3 0 Pvocab)link 3 if !

    : forget)vocab 5 vocab )) 6 0 ords forget)all 3 0 vocab)name dictionary get delete)at 3 0 notify)vocab)observers 3 tri !

    : vocab)spec forget4 forget)vocab !

    SEB&: require)hook

    ;#'CI%"$': runnable)vocab P vocab vocab)main boolean !

    INS$"N%': vocab)spec definition)mixin

    : call)require)hook 5 name )) 6 require)hook get call5 name )) 6 !

    G'N'#I%: require 5 obFect )) 6

    : vocab require name require !

    : vocab)link require name require !

    K Jhen calling (foo.private( require< load (foo( instead< but only henK (foo.private( does not exist. $he reason for this is that stage1 bootstrap

  • 8/12/2019 Factor Core

    60/602

    K starts out ith some .private vocabs that contain primitives< andK loading the public vocabs ould cause circularity issues.: string require 5 vocab )) 6 dup (.private( tail 0 over lookup)vocab 0 ,drop 3 0 nip call)require)hook 3

    if 3 0 nip call)require)hook 3 if !

    : load)vocab 5 name )) vocab 6 0 require 3 0 lookup)vocab 3 bi !IN: vocabs.parser.testsUSING: vocabs.parser tools.test eval kernel accessors definitionscompiler.units ords vocabs !

    0 (@#B: kernel H doesnotexist !( eval5 )) 6 30 error $+ no)ord)in)vocab + ord (doesnotexist( + vocab (kernel( H 3

    must)fail)ith

    0 (#'N"': doesnotexist kernel H nename( eval5 )) 6 30 error $+ no)ord)in)vocab + ord (doesnotexist( + vocab (kernel( H 3must)fail)ith

    : aaa 5 )) 6 !

    0 0 3 0 (aaa( (vocabs.parser.tests( (uutt( add)renamed)ord 3 unit)test

    0 3 0 (vocabs.parser.tests( dup add)qualified 3 unit)test

    0 aaa 3 0 (uutt( search 3 unit)test 0 aaa 3 0 (vocabs.parser.tests:aaa( search 3 unit)test

    0 3 0 0 (bbb( (vocabs.parser.tests( create drop 3 ith)compilation)unit 3unit)test

    0 (bbb( 3 0 (vocabs.parser.tests:bbb( search name 3 unit)test

    0 3 0 0 > aaa forget 3 ith)compilation)unit 3 unit)test

    0 3 0 0 (bbb( (vocabs.parser.tests( lookup)ord forget 3ith)compilation)unit 3 unit)test

    0 f 3 0 (uutt( search 3 unit)test

    0 f 3 0 (vocabs.parser.tests:aaa( search 3 unit)test

    0 3 0 (vocabs.parser.tests.foo( set)current)vocab 3 unit)test

    0 3 0 0 (bbb( current)vocab create drop 3 ith)compilation)unit 3 unit)test

    0 t 3 0 (bbb( search boolean 3 unit)test

    0 3 0 0 (vocabs.parser.tests.foo( forget)vocab 3 ith)compilation)unit 3unit)test

    0 0 (bbb( current)vocab create drop 3 ith)compilation)unit 3 0 errorno)current)vocab)error 3 must)fail)ith

  • 8/12/2019 Factor Core

    61/602

    0 begin)private 3 0 error no)current)vocab)error 3 must)fail)ith

    0 end)private 3 0 error no)current)vocab)error 3 must)fail)ith

    0 f 3 0 (bbb( search boolean 3 unit)test3 ith)manifest

    USING: help.markup help.syntax parser strings ords assocs vocabs !IN: vocabs.parser

    "#$I%&': (ord)search)errors( (Jord lookup errors((If the parser cannot not find a ord in the current vocabulary search path< itattempts to look for the ord in all loaded vocabularies.(*nl(If ( + *link auto)use ( mode is off< a restartable error is thron ith arestart for each vocabulary in question< together ith a restart hich defersthe ord in the current vocabulary< as if ( + *link ;BS$;BN': C'@'#: ( asused.(*nl(If ( + *link auto)use ( mode is on and only one vocabulary has a ord ith

    this name< the vocabulary is added to the search path and parsing continues.(*nl(If any restarts ere invoked< or if ( + *link auto)use ( is on< the parserill print the correct ( + *link ;BS$;BN': USING: ( after parsing completes.$his form can be copy and pasted back into the source file.(+ *subsections auto)use !

    "#$I%&': (ord)search)syntax( (Syntax to control ord lookup((;arsing ords hich make all ords in a vocabulary available:(+ *subsections ;BS$;BN': US': ;BS$;BN': USING: ;BS$;BN': DU"&I@I'C:

    ;BS$;BN': DU"&I@I'C)JI$?:(;arsing ords hich make a subset of all ords in a vocabulary available:(+ *subsections ;BS$;BN': @#B: ;BS$;BN': 'M%&UC': ;BS$;BN': #'N"':(#emoving vocabularies from the search path:(+ *subsections ;BS$;BN': UNUS': (In the listener< the ( + *vocab)link (scratchpad( ( is the default vocabularyfor ne ord definitions. In source files< there is no default vocabulary.Cefining ords before declaring a vocabulary ith ( + *link ;BS$;BN': IN: (results in an error.(+ *subsections ;BS$;BN': IN: !

    "#$I%&': (ord)search)semantics( (#esolution of ambiguous ord names(($here is a distinction beteen parsing ords hich perform ]open^ importsversus ]closed^ imports. "n open import introduces all ords from a vocabularyas identifiers< except possibly a finite set of exclusions. $he ( + *link;BS$;BN': US': (< ( + *link ;BS$;BN': USING: ( and ( + *link ;BS$;BN':'M%&UC': ( ords perform open imports. " closed import only adds a fixed setof identifiers. $he ( + *link ;BS$;BN': @#B: (< ( + *link ;BS$;BN': #'N"': (< ( + *link ;BS$;BN': DU"&I@I'C: ( and ( + *link ;BS$;BN': DU"&I@I'C)JI$?: ( ords perform closed imports. Note that the latter to are considered as

    closed imports< due to the fact that all identifiers they introduce areunambiguously qualified ith a prefix. $he ( + *link ;BS$;BN': IN: ( parsingord also performs a closed import of the nely)created vocabulary.(*nl

  • 8/12/2019 Factor Core

    62/602

    (Jhen the parser encounters a reference to a ord< it first searches the closedimports< in order. %losed imports are searched from the most recent to leastrecent. If the ord could not be found this ay< it searches open imports.Unlike closed imports< ith open imports< the order does not matter )) instead no)current)vocab)error boa + + (Cefine ords in scratchpad vocabulary( (scratchpad( thro)restarts dup set)current)vocab !

    : current)vocab 5 )) vocab 6 manifest get current)vocab 0 no)current)vocab 3 unless4 !

    : begin)private 5 )) 6 current)vocab name (.private( tail 0 drop 3 0 (.private( append set)current)vocab 3 if !

    : end)private 5 )) 6 current)vocab name (.private( tail 0 set)current)vocab 3 0 drop 3 if !

    : using)vocab 5 vocab )) 6 vocab)name manifest get search)vocab)names in !

    : use)vocab 5 vocab )) 6 dup using)vocab 0 vocab)name ("lready using __( (77 vocabulary( surround note. 3 0 manifest get 0 0 load)vocab 3 dip search)vocabs push 3 0 0 vocab)name 3 dip search)vocab)names adFoin 3

    ,bi 3 if !

    : auto)use)vocab 5 vocab )) 6

  • 8/12/2019 Factor Core

    67/602

    0 use)vocab 3 0 manifest get auto)used push 3 bi !

    : auto)used 5 )) 6 manifest get auto)used length = !

    : unuse)vocab 5 vocab )) 6 dup using)vocab 0 manifest get

    0 0 load)vocab 3 dip search)vocabs remove)eqK drop 3 0 0 vocab)name 3 dip search)vocab)names delete 3 ,bi 3 0 drop 3 if !

    $U;&': qualified vocab prefix ords !

    : Pqualified 5 vocab prefix )) qualified 6 5from6 qualified)ords qualified boa !

    : add)qualified 5 vocab prefix )) 6 Pqualified 5add)qualified6 !

    $U;&': from vocab names ords !

    : Pfrom 5 vocab ords )) from 6 5from6 extract)ords from boa !

    : add)ords)from 5 vocab ords )) 6 Pfrom 5add)qualified6 !

    $U;&': exclude vocab names ords !

    : Pexclude 5 vocab ords )) from 6 5from6 excluding)ords exclude boa !

    : add)ords)excluding 5 vocab ords )) 6 Pexclude 5add)qualified6 !

    $U;&': rename ord vocab ords !

    : Prename 5 ord vocab ne)name )) rename 6 0 ,dup load)vocab ords dupd at 0 3 0 sap no)ord)in)vocab 3 if 3 dip associate rename boa !

    : add)renamed)ord 5 ord vocab ne)name )) 6 Prename 5add)qualified6 !

    : use)ords 5 assoc )) 6 5use)ords6 push !

    : unuse)ords 5 assoc )) 6 5use)ords6 removeK drop !

    $U;&': ambiguous)use)error ords !

    : Pambiguous)use)error 5 ords )) error restarts 6 0 > ambiguous)use)error boa 3 0 ord)restarts 3 bi !

    P;#IV"$'

    : 5vocab)search6 5 name assocs )) ords n 6 0 ords 5lookup6 3 ith map

    sift dup length !

    : vocab)search 5 name manifest )) ordQf 6 search)vocabs

  • 8/12/2019 Factor Core

    68/602

    5vocab)search6 + + = 0 drop f 3 + 1 0 first 3 0 drop Pambiguous)use)error thro)restarts dup 0 vocabulary 3 0 name 1array 3 bi add)ords)from 3

    case !

    : qualified)search 5 name manifest )) ordQf 6 qualified)vocabs 5vocab)search6 = H 0 drop f 3 0 last 3 if !

    ;#IV"$'

    : search)manifest 5 name manifest )) ordQf 6 ,dup qualified)search dup 0 ,nip 3 0 drop vocab)search 3 if !

    : search 5 name )) ordQf 6 manifest get search)manifest !

    P;#IV"$'

    G'N'#I%: update 5 search)path)elt )) valid 6

    : trim)forgotten 5 qualified)vocab )) valid 6 0 0 nip (forgotten( ord)prop not 3 assoc)filter 3 change)ords ords assoc)empty not !

    : from update trim)forgotten !: rename update trim)forgotten !: extra)ords update trim)forgotten !: exclude update trim)forgotten !

    : qualified update dup vocab lookup)vocab 0 dup 0 prefix 3 0 vocab load)vocab 3 bi qualified)ords ords 3 0 drop f 3 if !

    : vocab update dup name lookup)vocab eq !

    : update)manifest 5 manifest )) 6 0 dup 0 name lookup)vocab 3 hen 3 change)current)vocab 0 members 0 lookup)vocab 3 filter dup fast)set 3 change)search)vocab)names sap 0 lookup)vocab 3 V+ map)as search)vocabs qualified)vocabs 0 update 3 filterK drop !

    : manifest definitions)changed nip update)manifest !

    ;#IV"$'

    : ith)manifest 5 quot )) 6 Pmanifest manifest 0 0 call 3 0 0 manifest get add)definition)observer call 3 0 manifest get remove)definition)observer 3

    0 3 cleanup 3 if)bootstrapping 3 ith)variable ! inline

  • 8/12/2019 Factor Core

    69/602

    K %opyright 5%6 ,==-< ,=1= Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: arrays assocs hashtables kernel kernel.private mathsequences vectors !S&B$: boxesS&B$: value@#B: accessors H boxes value valuePP !

    IN: namespaces

    P;#IV"$'

    $U;&': global)hashtable + boxes hashtable read)only !$U;&': global)box value !

    : 5box)at6 5 key globals )) box 6 boxes ,dup at 0 ,nip 3 0 0 f global)box boa 3 ,dip 0 set)at 3 ,curry keep 3 if4 ! foldable

    : box)at 5 key globals )) box 6

    5box)at6 + global)box declare ! inline

    : global)hashtable at4 boxes at4 0 + global)box declare value dup 3 0 drop f f 3 if ! inline

    : global)hashtable set)at box)at valuePP ! inline

    : global)hashtable delete)at box)at f sap valuePP ! inline

    : namestack4 5 )) namestack 6 %BN$'M$)BEX)N"'S$"%Y context)obFect + vector declare ! inline: n 5 namespace )) 6 namestack4 push !: ndrop 5 )) 6 namestack4 pop4 !

    ;#IV"$'

    : global 5 )) g 6 BEX)G&BE"& special)obFect + global)hashtable declare !foldable

    : namespace 5 )) namespace 6 namestack4 last ! inline: namestack 5 )) namestack 6 namestack4 clone !: set)namestack 5 namestack )) 6 vector %BN$'M$)BEX)N"'S$"%Y set)context)obFect !: init)namespaces 5 )) 6 global 1array set)namestack !: get 5 variable )) value 6 namestack4 assoc)stack ! inline: set 5 value variable )) 6 namespace set)at !: on 5 variable )) 6 t sap set ! inline: off 5 variable )) 6 f sap set ! inline: is)global 5 variable )) 6 global boxes key ! inline: get)global 5 variable )) value 6 global box)at value ! inline: set)global 5 value variable )) 6 global set)at ! inline: change 5 variable quot )) 6 0 0 get 3 keep 3 dip dip set ! inline: change)global 5 variable quot )) 6 0 0 get)global 3 keep 3 dip dip set)global ! inline

    : toggle 5 variable )) 6 0 not 3 change ! inline: 29 5 n variable )) 6 0 = or 2 3 change ! inline: inc 5 variable )) 6 1 sap 29 ! inline: dec 5 variable )) 6 )1 sap 29 ! inline

  • 8/12/2019 Factor Core

    70/602

    : ith)variables 5 ns quot )) 6 sap n call ndrop ! inline: counter 5 variable )) n 6 0 = or 1 2 dup 3 change)global ! inline: make)assoc 5 quot exemplar )) hash 6 ,= sap ne)assoc 0 sap ith)variables 3keep ! inline: ith)scope 5 quot )) 6 A Phashtable sap ith)variables ! inline: ith)variable 5 value key quot )) 6 0 associate 3 dip ith)variables ! inline: ith)global 5 quot )) 6 0 global 3 dip ith)variables ! inline

    : initiali8e 5 variable quot )) 6 0 unless4 3 curry change)global ! inlineUSING: assocs compiler.tree.debugger kernel namespacestools.test ords !IN: namespaces.tests

    ?+ clone (test)namespace( set

    : test)namespace 5 )) 6 ?+ clone dup 0 namespace H 3 ith)variables !

    0 t 3 0 test)namespace 3 unit)test

    1= (some)global( set

    0 f 30 ?+ clone 0 f (some)global( set (some)global( get 3 ith)variables 3unit)test

    SEB&: test)initiali8e

    f test)initiali8e set)global

    test)initiali8e 0 1 3 initiali8etest)initiali8e 0 , 3 initiali8e

    0 1 3 0 test)initiali8e get)global 3 unit)test

    f test)initiali8e set)globaltest)initiali8e 0 A 3 initiali8e

    0 A 3 0 test)initiali8e get)global 3 unit)test

    SEB&: toggle)test0 f 3 0 toggle)test get 3 unit)test0 t 3 0 toggle)test 0 toggle 3 0 get 3 bi 3 unit)test0 f 3 0 toggle)test 0 toggle 3 0 get 3 bi 3 unit)test

    0 t 3 0 toggle)test 0 on 3 0 get 3 bi 3 unit)test0 f 3 0 toggle)test 0 off 3 0 get 3 bi 3 unit)test

    0 t 3 0 0 test)initiali8e get)global 3 + at4 set)at inlined 3 unit)test0 t 3 0 0 test)initiali8e set)global 3 + at4 set)at inlined 3 unit)testUSING: help.markup help.syntax kernel kernel.privatesequences ords namespaces.private quotations vectorsmath.parser math ords.symbol assocs !IN: namespaces

    "#$I%&': (namespaces)combinators( (Namespace combinators(+ *subsections make)assoc ith)scope ith)variable

    ith)variables !

    "#$I%&': (namespaces)change( (%hanging variable values(

  • 8/12/2019 Factor Core

    71/602

    + *subsections on off inc dec change change)global

    toggle !

    "#$I%&': (namespaces)global( (Global variables(+ *subsections namespace global get)global set)global initiali8e ith)global !

    "#$I%&': (namespaces.private( (Namespace implementation details(($he namestack holds namespaces.(+ *subsections namestack set)namestack namespace(" pair of ords push and pop namespaces on the namestack.(+ *subsections n ndrop !

    "#$I%&': (namespaces( (Cynamic variables(($he ( + *vocab)link (namespaces( ( vocabulary implements dynamically)scopedvariables.(*nl(" dynamic variable is an entry in an assoc of bindings< here the assoc isimplicit rather than passed on the stack. $hese assocs are termed ( + *emphasis(namespaces( (. Nesting of scopes is implemented ith a search order onnamespaces< defined by a ( + *emphasis (namestack( (. Since namespaces areFust assocs< any obFect can be used as a variable. Ey convention< variables arekeyed by ( + *link (ords.symbol( (.(*nl($he ( + *link get ( and ( + *link set ( ords read and rite variablevalues. $he ( + *link get ( ord searches the chain of nested namespacesn1 foo 29>n1= foo 29>nfoo get .( (11( !

  • 8/12/2019 Factor Core

    73/602

    ?'&;: inc+ *values + (variable( (a variable< by convention a symbol( + *description (Increments the value of the variable by 1. " variable value of (+ *link f ( is interpreted as being 8ero.( + *side)effects (variable( !

    ?'&;: dec+ *values + (variable( (a variable< by convention a symbol( + *description (Cecrements the value of the variable by 1. " variable value of (+ *link f ( is interpreted as being 8ero.( + *side)effects (variable( !

    ?'&;: counter+ *values + (variable( (a variable< by convention a symbol( + (n( integer + *description (Increments the value of the variable by 1< and returns its nevalue.( + *notes ($his ord is useful for generating 5somehat6 unique identifiers. @orexample< the ( + *link gensym ( ord uses it.( + *side)effects (variable( !

    ?'&;: ith)scope+ *values + (quot( quotation + *description (%alls the quotation in a ne namespace. "ny variables set by thequotation are discarded hen it returns.( + *examples + *example (USING: math namespaces prettyprint !( (IN: scratchpad( (SEB&:x( (= x set( (0 x 0 A 2 3 change x get . 3 ith)scope x get .( (A>n=( !

    ?'&;: ith)variable+ *values + (value( obFect + (key( (a variable< by convention a symbol( + (quot( quotation

    + *description (%alls the quotation in a ne namespace here ( + *snippet(key( ( is set to ( + *snippet (value( (.( + *examples ($he folloing to phrases are equivalent:( + *code (0 - x set foo 3 ith)scope( + *code (- x 0 foo 3 ith)variable( !

    ?'&;: make)assoc+ *values + (quot( quotation + (exemplar( assoc + (hash( (a ne assoc( + *description (%alls the quotation in a ne namespace of the same type as (+ *snippet (exemplar( (< and outputs this namespace hen the quotationreturns. Useful for quickly building assocs.( !

    ?'&;: ith)variables+ *values + (ns( assoc + (quot( quotation + *description (%alls the quotation in the dynamic scope of ( + *snippet (ns( (. Jhen variables are looked up by the quotation< ( + *snippet (ns( ( ischecked first< and setting variables in the quotation stores them in (+ *snippet (ns( (.( !

    ?'&;: namespace+ *values + (namespace( assoc + *description (Butputs the current namespace. %alls to ( + *link set ( modifythis namespace.( !

    ?'&;: global+ *values + (g( assoc + *description (Butputs the global namespace. $he global namespace is alayschecked last hen looking up variable values.( !

  • 8/12/2019 Factor Core

    74/602

    ?'&;: get)global+ *values + (variable( (a variable< by convention a symbol( + (value( (thevalue( + *description (Butputs the value of a variable in the global namespace.( !

    ?'&;: set)global

    + *values + (value( (the ne value( + (variable( (a variable< by convention asymbol( + *description ("ssigns a value to the variable in the global namespace.( + *side)effects (variable( !

    ?'&;: namestack4+ *values + (namestack( (a vector of assocs( + *description (Butputs the current name stack.( !

    ?'&;: namestack+ *values + (namestack( (a vector of assocs( + *description (Butputs a copy of the current name stack.( !

    ?'&;: set)namestack+ *values + (namestack( (a vector of assocs( + *description (#eplaces the name stack ith a copy of the given vector.( !

    ?'&;: n+ *values + (namespace( assoc + *description (;ushes a namespace on the name stack.( !

    ?'&;: ndrop+ *description (;ops a namespace from the name stack.( !

    ?'&;: init)namespaces+ *description (#esets the name stack to its initial state< holding a single

    copy of the global namespace.( *lo)level)note !

    ?'&;: initiali8e+ *values + (variable( symbol + (quot( quotation + *description (If ( + *snippet (variable( ( does not have a value in theglobal namespace< calls ( + *snippet (quot( ( and assigns the result to (+ *snippet (variable( ( in the global namespace.( !K %opyright 5%6 ,==/< ,=1= Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: accessors arrays assocs definitions hashtables kernelkernel.private math math.order namespaces quotations sequencesslots.private strings vocabs !@#B: assocs H change)at !IN: ords

    EUI&$IN: ord+ hashcode fixnum initial: = name vocabulary+ def quotation initial: 0 3 props pic)def pic)tail)def+ sub)primitive read)only !

    K Need a dummy ord here because EUI&$IN: ord is not a real ordK and parse)datum looks for things that are actually ords instead ofK also looking for classes: ord 5 )) 4 6 (dummy ord( thro !

    SEB&: last)ord)symbol

    : last)ord 5 )) ord 6 > last)ord)symbol get)global !

  • 8/12/2019 Factor Core

    75/602

    : set)last)ord 5 ord )) 6 > last)ord)symbol set)global !

    : ord execute 5execute6 !

    : ord execute execute5 )) value 6 ! inline

    : ord PH 0 0 name 3 0 vocabulary 3 bi ,array 3 compare !

    : ord definer drop > : > ! !

    : ord definition def !

    : ord)prop 5 ord name )) value 6 sap props at !

    : remove)ord)prop 5 ord name )) 6 sap props delete)at !

    : set)ord)prop 5 ord value name )) 6 over

    0 pick props set)at props drop 3 0 nip remove)ord)prop 3 if !

    : change)ord)prop 5 ..a ord prop quot: 5 ..a value )) ..b nevalue 6 )) ..b 6 0 sap props 3 dip change)at ! inline

    : reset)props 5 ord seq )) 6 0 remove)ord)prop 3 ith each !

    P;#IV"$'

    : caller 5 callstack )) ord 6 callstackarray Preversed third !

    ;#IV"$'

    $U;&': undefined)ord ord !: undefined 5 )) 4 6 callstack caller > undefined)ord boa thro !

    : undefined)def 5 )) quot 6 ZK 7f7 inhibits tail call optimi8ation in non)optimi8ing ZK compiler< ensuring that e can pull out the caller ord ZK above. 0 undefined f 3 !

    ;#'CI%"$': deferred P ord def undefined)def H !: deferred definer drop > C'@'#: f !: deferred definition drop f !

    ;#'CI%"$': primitive P ord (primitive( ord)prop !: primitive definer drop > ;#II$IV': f !: primitive definition drop f !

    : lookup)ord 5 name vocab )) ord 6 vocab)ords at !

    : target)ord 5 ord )) target 6 0 name 3 0 vocabulary 3 bi lookup)ord !

    SEB&: bootstrapping

    : if)bootstrapping 5 true false )) 6 0 bootstrapping get 3 ,dip if ! inline

    : bootstrap)ord 5 ord )) target 6

  • 8/12/2019 Factor Core

    76/602

    0 target)ord 3 0 3 if)bootstrapping !

    G'N'#I%: crossref 5 ord )) 6

    : ord crossref dup (forgotten( ord)prop 0 drop f 3 0 vocabulary boolean 3 if !

    G'N'#I%: subords 5 ord )) seq 6

    : ord subords drop f !

    G'N'#I%: parent)ord 5 ord )) ordQf 6

    : ord parent)ord drop f !

    : define 5 ord def )) 6 over changed)definition 0 3 like def drop !

    : changed)effect 5 ord )) 6 0 changed)effects get add)to)unit 3

    0 dup primitive 0 drop 3 0 changed)definition 3 if 3 bi !

    : set)stack)effect 5 effect ord )) 6 ,dup (declared)effect( ord)prop H 0 ,drop 3 0 0 nip changed)effect 3 0 nip subords 0 changed)effect 3 each 3 0 sap (declared)effect( set)ord)prop 3 ,tri 3 if !

    : define)declared 5 ord def effect )) 6 0 nip sap set)stack)effect 3 0 drop define 3 -bi !

    : make)deprecated 5 ord )) 6 t (deprecated( set)ord)prop !

    : inline 5 obF )) 6 dup ord 0 (inline( ord)prop 3 0 drop f 3 if ! inline

    : recursive 5 obF )) 6 dup ord 0 (recursive( ord)prop 3 0 drop f 3 if ! inline

    : inline)recursive 5 obF )) 6 dup ord 0 dup (inline( ord)prop 0 (recursive( ord)prop 3 0 drop f 3 if 3 0 drop f 3 if ! inline

    '##B#: cannot)be)inline ord !

    G'N'#I%: make)inline 5 ord )) 6

    : ord make)inline dup inline 0 drop 3 0 0 t (inline( set)ord)prop 3 0 changed)effect 3 bi 3 if !

    : define)inline 5 ord def effect )) 6 0 define)declared 3 0 ,drop make)inline 3 -bi !

  • 8/12/2019 Factor Core

    77/602

    : make)recursive 5 ord )) 6 t (recursive( set)ord)prop !

    G'N'#I%: flushable 5 ord )) 6

    : ord flushable 0 (flushable( ord)prop 3

    0 parent)ord dup 0 flushable 3 hen 3 bi or !

    : make)flushable 5 ord )) 6 t (flushable( set)ord)prop !

    G'N'#I%: foldable 5 ord )) 6

    : ord foldable 0 (foldable( ord)prop 3 0 parent)ord dup 0 foldable 3 hen 3 bi or !

    : make)foldable 5 ord )) 6 dup make)flushable t (foldable( set)ord)prop !

    G'N'#I%: reset)ord 5 ord )) 6

    : ord reset)ord dup flushable 0 dup changed)conditionally 3 hen + (unannotated)def( (parsing( (inline( (recursive( (foldable( (flushable( (reading( (riting( (reader( (riter( (delimiter( (deprecated( reset)props !

    : reset)generic 5 ord )) 6 0 subords forget)all 3

    0 reset)ord 3 0 f pic)def f pic)tail)def + (methods( (combination( (default)method( (engines( (decision)tree( reset)props 3 tri !

    : Pord 5 name vocab )) ord 6 ,dup = hash)combine hash)combine fixnum 5ord6 dup ne)ord !

    : Puninterned)ord 5 name )) ord 6 f > Puninterned)ord counter fixnum 5ord6 ne)ords get 0 dup ne)ord 3 hen !

    : gensym 5 )) ord 6 (5 gensym 6( Puninterned)ord !

    : define)temp 5 quot effect )) ord 6 0 gensym dup 3 ,dip define)declared !

    : reveal 5 ord )) 6 dup 0 name 3 0 vocabulary 3 bi dup vocab)ords 0 3 0 no)vocab 3 if

  • 8/12/2019 Factor Core

    78/602

    set)at !

    '##B#: bad)create name vocab !

    : check)create 5 name vocab )) name vocab 6 ,dup 0 string 3 0 0 string 3 0 vocab 3 bi or 3 bi4 and 0 bad)create 3 unless !

    : create 5 name vocab )) ord 6 check)create ,dup lookup)ord dup 0 ,nip 3 0 drop vocab)name Pord dup reveal dup changed)definition 3 if !

    : constructor)ord 5 name vocab )) ord 6 0 (P( (( surround 3 dip create !

    ;#'CI%"$': parsing)ord P ord (parsing( ord)prop !

    : parsing)ord definer drop > SN$"M: > ! !

    : define)syntax 5 ord quot )) 6 0 drop 3 0 define 3 ,bi t (parsing( set)ord)prop !

    : delimiter 5 obF )) 6 dup ord 0 (delimiter( ord)prop 3 0 drop f 3 if !

    : deprecated 5 obF )) 6 dup ord 0 (deprecated( ord)prop 3 0 drop f 3 if !

    K Cefinition protocol: ord here (loc( ord)prop !

    : ord set)here sap (loc( set)ord)prop !

    : ord forget4 dup (forgotten( ord)prop 0 drop 3 0 0 subords forget)all 3 0 0 name 3 0 vocabulary vocab)ords 3 bi delete)at 3 0 t (forgotten( set)ord)prop 3 tri 3 if !

    : ord hashcode4 nip 1 slot + fixnum declare ! inline foldable

    : ord literali8e Prapper !

    INS$"N%': ord definition)mixinUSING: help.syntax help.markup ords.symbol ords compiler.units !IN: ords.symbol

    ?'&;: symbol+ *description ($he class of symbols created by ( + *link ;BS$;BN': SEB&: (.( !

    ?'&;: define)symbol+ *values + (ord( ord + *description (Cefines the ord to push itself on the stack hen executed. $his

  • 8/12/2019 Factor Core

    79/602

    is the run time equivalent of ( + *link ;BS$;BN': SEB&: (.( + *notes ($his ord must be called from inside ( + *link ith)compilation)unit (.( + *side)effects (ord( !

    "#$I%&': (ords.symbol( (Symbols((" symbol pushes itself on the stack hen executed. Ey convention< symbols are

    used as variable names 5( + *link (namespaces( (6.(+ *subsections symbol symbol(Cefining symbols at parse time:(+ *subsections ;BS$;BN': SEB&: ;BS$;BN': SEB&S:(Cefining symbols at run time:(+ *subsections define)symbol (Symbols are Fust compound definitions in disguise. $he folloing to lines are

    equivalent:(+ *code (SEB&: foo( (: foo 5 )) value 6 >> foo !( !

    "EBU$: (ords.symbol(K %opyright 5%6 ,== Slava ;estov.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: accessors definitions kernel sequences ords !IN: ords.symbol

    ;#'CI%"$': symbol P ord

    0 def 3 0 0 3 curry 3 bi sequenceH !

    : symbol definer drop > SEB&: f !

    : symbol definition drop f !

    : define)symbol 5 ord )) 6 dup 0 3 curry 5 )) value 6 define)inline !USING: arrays generic assocs kernel math namespacessequences tools.test ords definitions parser quotationsvocabs continuations classes.tuple compiler.unitsio.streams.string accessors eval ords.symbol grouping !IN: ords.tests

    0 / 3 0 0 (poo( (ords.tests( create 0 , , 2 3 5 )) n 6 define)declared 3 ith)compilation)unit (poo( (ords.tests( lookup)ord execute3 unit)test

    0 t 3 0 t vocabs 0 ords 0 ord and 3 each 3 each 3 unit)test

    C'@'#: plist)test

    0 t 3 0 > plist)test t (sample)property( set)ord)prop > plist)test (sample)property( ord)prop3 unit)test

  • 8/12/2019 Factor Core

    80/602

    0 f 3 0 > plist)test f (sample)property( set)ord)prop > plist)test (sample)property( ord)prop3 unit)test

    0 3 0 0 (create)test( (scratchpad( create + 1 , (testing( set)ord)prop 3

    ith)compilation)unit 3 unit)test

    0 + 1 , 3 0 (create)test( (scratchpad( lookup)ord (testing( ord)prop3 unit)test

    0 0 t 3 0 > array (array( (arrays( lookup)ord H 3 unit)test

    0 3 0 0 (test)scope( (scratchpad( create drop 3 ith)compilation)unit 3unit)test3 ith)scope

    0 (test)scope( 3 0 (test)scope( (scratchpad( lookup)ord name3 unit)test

    0 t 3 0 vocabs array 3 unit)test0 t 3 0 vocabs 0 ords 0 ord 3 all 3 all 3 unit)test

    0 f 3 0 gensym gensym H 3 unit)test

    SEB&: a)symbol0 t 3 0 > a)symbol symbol 3 unit)test

    K See if redefining a generic as a colon def clears some

    K ord props.G'N'#I%: testing 5 a )) b 6(IN: ords.tests : testing 5 )) 6 !( eval5 )) 6

    0 f 3 0 > testing generic 3 unit)test

    : forgotten 5 )) 6 !: another)forgotten 5 )) 6 !

    @B#G'$: forgotten

    @B#G'$: another)forgotten: another)forgotten 5 )) 6 !

    K ake sure that undefined ords thro proper errorsC'@'#: deferred0 deferred 3 0 $+ undefined)ord f deferred H 3 must)fail)ith

    0 (IN: ords.tests C'@'#: not)compiled PP not)compiled ( eval5 )) 6 30 error 0 undefined)ord 3 0 ord name (not)compiled( H 3 bi and 3must)fail)ith

    0 3 0 (IN: ords.tests @B#G'$: not)compiled( eval5 )) 6 3 unit)test

    0 3 0 0 (no)loc( (ords.tests( create drop 3 ith)compilation)unit 3 unit)test

    0 f 3 0 (no)loc( (ords.tests( lookup)ord here 3 unit)test

    0 3 0 (IN: ords.tests : no)loc), 5 )) 6 !( eval5 )) 6 3 unit)test0 f 3 0 (no)loc),( (ords.tests( lookup)ord here 3 unit)test

  • 8/12/2019 Factor Core

    81/602

  • 8/12/2019 Factor Core

    82/602

    0 (hi( ord)code 3 must)failUSING: definitions help.markup help.syntax kernel parserkernel.private vocabs classes quotationsstrings effects compiler.units !IN: ords

    "#$I%&': (interned)ords( (&ooking up and creating ords(

    (" ord is said to be ( + *emphasis (interned( ( if it is a member of thevocabulary named by its vocabulary slot. Btherise< the ord is ( + *emphasis(uninterned( (.(*nl(Jords hose names are knon at parse time )) that is< most ords making up yourprogram )) can be referenced in source code by stating their name. ?oever< theparser itself< and sometimes code you rite< ill need to create look up ordsdynamically.(*nl(;arsing ords add definitions to the current vocabulary. Jhen a source file isbeing parsed< the current vocabulary is initially set to ( + *vocab)link(scratchpad( (. $he current vocabulary may be changed ith the ( + *link;BS$;BN': IN: ( parsing ord 5see ( + *link (ord)search( (6.(

    + *subsections create create)in lookup)ord !

    "#$I%&': (uninterned)ords( (Uninterned ords((" ord that is not a member of any vocabulary is said to be ( + *emphasis(uninterned( (.(*nl($here are several ays of creating an uninterned ord:(+ *subsections Pord

    Puninterned)ord gensym define)temp !

    "#$I%&': (colon)definition( (%olon definitions(("ll ords have associated definition ( + *link (quotations( (. " ord7sdefinition quotation is called hen the ord is executed. " ( + *emphasis (colondefinition( ( is a ord here this quotation is supplied directly by the user.$his is the simplest and most common type of ord definition.(*nl(Cefining ords at parse time:(+ *subsections ;BS$;BN': : ;BS$;BN': !(Cefining ords at run time:(+ *subsections define define)declared define)inline(Jord definitions must declare their stack effect. See ( + *link (effects( (.(*nl("ll other types of ord definitions< such as ( + *link (ords.symbol( ( and (

    + *link (generic( (< are Fust special cases of the above.( !

    "#$I%&': (primitives( (;rimitives((;rimitives are ords defined in the @actor V. $hey provide the essential

  • 8/12/2019 Factor Core

    83/602

    lo)level services to the rest of the system.(+ *subsections primitive primitive !

    "#$I%&': (deferred( (Ceferred ords and mutual recursion(

    (Jords cannot be referenced before they are defined! that is< source files mustorder definitions in a strictly bottom)up fashion. $his is done to simplify theimplementation< facilitate better parse time checking and remove some odd cornercases! it also encourages better coding style.(*nl(Sometimes this restriction gets in the ay< for example hen definingmutually)recursive ords! one ay to get around this limitation is to make aforard definition.(+ *subsections ;BS$;BN': C'@'#: ($he class of deferred ord definitions:(+ *subsections deferred deferred

    (Ceferred ords thro an error hen called:(+ *subsections undefined (Ceferred ords are Fust compound definitions in disguise. $he folloing tolines are equivalent:(+ *code (C'@'#: foo( (: foo 5 )) 4 6 undefined !( !

    "#$I%&': (declarations( (%ompiler declarations((%ompiler declarations are parsing ords that set a ord property in the mostrecently defined ord. $hey appear after the final ( + *link ;BS$;BN': ! ( of

    a ord definition:(+ *code (: cubed 5 x )) y 6 dup dup 4 4 ! foldable( (%ompiler declarations assert that the ord follos a certain contract< enablingcertain optimi8ations that are not valid in general.(+ *subsections ;BS$;BN': inline ;BS$;BN': foldable ;BS$;BN': flushable ;BS$;BN': recursive(It is entirely up to the programmer to ensure that the ord satisfies thecontract of a declaration. @urthermore< if a generic ord is declared ( + *link;BS$;BN': foldable ( or ( + *link ;BS$;BN': flushable (< all methods mustsatisfy the contract. Unspecified behavior may result if a ord does not follothe contract of one of its declarations.(+ *see)also (effects( !

    "#$I%&': (ord)props( (Jord properties(('ach ord has a hashtable of properties.(+ *subsections ord)prop set)ord)prop($he stack effect of the above to ords is designed so that it is mostconvenient hen ( + *snippet (name( ( is a literal pushed on the stack right

    before executing this ord.(*nl($he folloing are some of the properties used by the library:(+ *table

  • 8/12/2019 Factor Core

    84/602

    + (;roperty( (Cocumentation( + + *snippet (>(parsing>(( + *link (parsing)ords(

    + + + *snippet (>(inline>(( (< ( + *snippet (>(foldable>(( (< (+ *snippet (flushable( + *link (declarations(

    + + *snippet (>(loc>(( + (&ocation information ) ( + *link here

    + + + *snippet (>(methods>(( (< ( + *snippet (>(combination>(( + (Seton generic ords ) ( + *link (generic(

    + + + *snippet (>(reading>(( (< ( + *snippet (>(riting>(( + (Set onslot accessor ords ) ( + *link (slots(

    + + *snippet (>(declared)effect>(( + *link (effects(

    + + + *snippet (>(help>(( (< ( + *snippet (>(help)loc>(( (< ( + *snippet(>(help)parent>(( + (Jhere ord help is stored ) ( + *link(riting)help(

    + + *snippet (>(speciali8er>(( + *link (hints(

    + + *snippet (>(predicating>(( ( Set on class predicates< stores thecorresponding class ord( (;roperties hich are defined for classes only:(+ *table + (;roperty( (Cocumentation( + + *snippet (>(class>(( + (" boolean indicating hether this ord is aclass ) ( + *link (classes(

    + + *snippet (>(coercer>(( + (" quotation for converting the top of thestack to an instance of this class(

    + + *snippet (>(constructor>(( + *link (tuple)constructors(

    + + *snippet (>(type>(( + *link (builtin)classes(

    + + + *snippet (>(superclass>(( (< ( + *snippet (>(predicate)definition>(( + *link (predicates(

    + + *snippet (>(members>(( + *link (unions(

    + + *snippet (>(slots>(( + *link (slots(

    + + *snippet (>(predicate>(( + (" quotation that tests if the top of thestack is an instance of this class ) ( + *link (class)predicates( !

    "#$I%&': (ord.private( (Jord implementation details(($he ( + *snippet (def( ( slot of a ord holds a ( + *link quotation (instance that is called hen the ord is executed.(*nl(" primitive to get the memory range storing the machine code for a ord:(+ *subsections ord)code !

    "#$I%&': (ords.introspection( (Jord introspection((Jord introspection facilities and implementation details are found in the (

    + *vocab)link (ords( ( vocabulary.(*nl(Jord obFects contain several slots:(+ *table

  • 8/12/2019 Factor Core

    85/602

    + + *snippet (name( (a ord name( + + *snippet (vocabulary( (a ord vocabulary name( + + *snippet (def( (a definition quotation( + + *snippet (props( (an assoc of ord properties< including documentationand other meta)data( (Jords are instances of a class.(

    + *subsections ord ord(Jords implement the definition protocol! see ( + *link (definitions( (.(+ *subsections (interned)ords( (uninterned)ords( (ord)props( (ord.private( !

    "#$I%&': (ords( (Jords(

    (Jords are the @actor equivalent of functions or procedures in other languages.Jords are essentially named ( + *link (quotations( (.(*nl($here are to ays of creating ord definitions:(+ *list (using parsing ords at parse time.( (using defining ords at run time.(($he latter is a more dynamic feature that can be used to implement codegeneration and such< and in fact parse time defining ords are implemented interms of run time defining ords.(*nl($ypes of ords:(

    + *subsections (colon)definition( (ords.symbol( (ords.alias( (ords.constant( (primitives(("dvanced topics:(+ *subsections (deferred( (declarations( (ords.introspection(+ *see)also (vocabularies( (vocabs.loader( (definitions( (see( !

    "EBU$: (ords(

    ?'&;: deferred+ *class)description ($he class of deferred ords created by ( + *link ;BS$;BN':C'@'#: (.( !

    + deferred ;BS$;BN': C'@'#: related)ords

    ?'&;: undefined+ *error)description ($his error is thron in to cases< and the debugger7s

    summary message reflects the cause:( + *list + (" ord as executed before being compiled. @or example< this canhappen if a macro is defined in the same compilation unit here it as used. See

  • 8/12/2019 Factor Core

    86/602

    ( + *link (compilation)units( ( for a discussion.( + (" ord defined ith ( + *link ;BS$;BN': C'@'#: ( as executed.Since this syntax is usually used for mutually)recursive ord definitions %BNS$"N$: f !

    : constant definition (constant( ord)prop literali8e 1quotation !USING: help.markup help.syntax ords.constant !IN: ords.constant

    "#$I%&': (ords.constant( (%onstants(($here is a syntax for defining ords hich push literals on the stack.(*nl(Cefine a ne ord that pushes a literal on the stack:(+ *subsections ;BS$;BN': %BNS$"N$: (Cefine an constant at run)time:(+ *subsections define)constant !

    "EBU$: (ords.constant(

    IN: ords.constant.testsUSING: tools.test math ords.constant !

    %BNS$"N$: a 2

  • 8/12/2019 Factor Core

    90/602

    0 2 3 0 a 3 unit)test

    0 t 3 0 > a constant 3 unit)test

    %BNS$"N$: b > 2

    0 > 2 3 0 b 3 unit)test

    %BNS$"N$: c + 1 , -

    0 + 1 , - 3 0 c 3 unit)test

    SEB&: foo

    0 f 3 0 > foo constant 3 unit)testUSING: math eval lexer tools.test effectssequences !IN: ords.alias.tests

    "&I"S: foo 2

    0 3 0 (IN: ords.alias.tests %BNS$"N$: foo A( eval5 )) 6 3 unit)test0 5 )) value 6 3 0 > foo stack)effect 3 unit)test

    "&I"S: )?+ ?++ ?+ + 1 , 0 (IN: ords.alias.tests )?+ + 1 , ( eval5 )) x 63 unit)testK %opyright 5%6 ,== Coug %oleman.K See http:QQfactorcode.orgQlicense.txt for ESC license.USING: accessors definitions effects kernel quotationssequences ords !IN: ords.alias

    ;#'CI%"$': alias P ord (alias( ord)prop !

    : define)alias 5 ne old )) 6 0 0 1quotation 3 0 stack)effect 3 bi define)inline 3 0 drop t (alias( set)ord)prop 3 0 parsing)ord 0 t (parsing( set)ord)prop 3 0 drop 3 if 3 ,tri !

    : alias reset)ord 0 call)next)method 3 0 f (alias( set)ord)prop 3 bi !

    : alias definer drop > "&I"S: f !USING: help.markup help.syntax ords.alias !IN: ords.alias

    "#$I%&': (ords.alias( (Jord aliasing(($here is a syntax for defining