]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of http://factorcode.org/git/factor
authorJoe Groff <arcata@gmail.com>
Wed, 28 Oct 2009 21:17:24 +0000 (16:17 -0500)
committerJoe Groff <arcata@gmail.com>
Wed, 28 Oct 2009 21:17:24 +0000 (16:17 -0500)
Conflicts:
basis/locals/locals.factor
basis/peg/peg.factor
extra/infix/infix.factor

113 files changed:
basis/alien/fortran/fortran.factor
basis/alien/parser/parser.factor
basis/bitstreams/bitstreams.factor
basis/calendar/calendar.factor
basis/channels/examples/examples.factor
basis/checksums/hmac/hmac.factor
basis/classes/struct/bit-accessors/bit-accessors.factor
basis/compiler/cfg/intrinsics/alien/alien.factor
basis/compiler/cfg/intrinsics/allot/allot.factor
basis/compiler/cfg/intrinsics/simd/simd.factor
basis/compiler/cfg/intrinsics/slots/slots.factor
basis/compiler/cfg/ssa/liveness/liveness.factor
basis/compiler/tree/dead-code/recursive/recursive.factor
basis/compiler/tree/dead-code/simple/simple.factor
basis/compiler/tree/propagation/known-words/known-words.factor
basis/compiler/utilities/utilities.factor
basis/concurrency/exchangers/exchangers-tests.factor
basis/concurrency/flags/flags-tests.factor
basis/concurrency/locks/locks-tests.factor
basis/core-text/core-text.factor
basis/cpu/ppc/ppc.factor
basis/farkup/farkup.factor
basis/fry/fry-docs.factor
basis/functors/functors.factor
basis/furnace/auth/providers/providers.factor
basis/interpolate/interpolate-tests.factor
basis/io/encodings/gb18030/gb18030.factor
basis/io/launcher/unix/unix-tests.factor
basis/io/mmap/windows/windows.factor
basis/io/monitors/macosx/macosx.factor
basis/io/sockets/secure/openssl/openssl.factor
basis/io/sockets/unix/unix.factor
basis/lcs/lcs.factor
basis/locals/errors/errors.factor
basis/locals/fry/fry.factor
basis/locals/locals-docs.factor
basis/locals/locals-tests.factor
basis/locals/locals.factor
basis/locals/macros/macros.factor
basis/locals/parser/parser.factor
basis/locals/prettyprint/prettyprint.factor
basis/locals/rewrite/sugar/sugar.factor
basis/locals/types/types.factor
basis/math/matrices/matrices.factor
basis/math/primes/miller-rabin/miller-rabin.factor
basis/math/vectors/conversion/conversion.factor
basis/math/vectors/simd/simd-tests.factor
basis/models/product/product-tests.factor
basis/opengl/opengl.factor
basis/opengl/textures/textures.factor
basis/peg/ebnf/ebnf.factor
basis/peg/peg.factor
basis/persistent/hashtables/nodes/bitmap/bitmap.factor
basis/persistent/hashtables/nodes/collision/collision.factor
basis/persistent/hashtables/nodes/full/full.factor
basis/persistent/hashtables/nodes/leaf/leaf.factor
basis/regexp/nfa/nfa.factor
basis/stack-checker/known-words/known-words.factor
basis/threads/threads-tests.factor
basis/tools/walker/debug/debug.factor
basis/unicode/collation/collation.factor
basis/unix/unix.factor
basis/windows/dinput/constants/constants.factor
basis/xml/syntax/syntax-docs.factor
basis/xml/syntax/syntax-tests.factor
extra/benchmark/beust2/beust2.factor
extra/benchmark/fasta/fasta.factor
extra/benchmark/yuv-to-rgb/yuv-to-rgb.factor
extra/crypto/aes/aes.factor
extra/crypto/passwd-md5/passwd-md5.factor
extra/decimals/decimals.factor
extra/dns/cache/nx/nx.factor [deleted file]
extra/dns/cache/rr/rr.factor [deleted file]
extra/dns/dns.factor [deleted file]
extra/dns/forwarding/forwarding.factor [deleted file]
extra/dns/misc/misc.factor [deleted file]
extra/dns/resolver/resolver.factor [deleted file]
extra/dns/server/server.factor [deleted file]
extra/dns/stub/stub.factor [deleted file]
extra/dns/util/util.factor [deleted file]
extra/galois-talk/galois-talk.factor
extra/google-tech-talk/google-tech-talk.factor
extra/gpu/render/render.factor
extra/images/normalization/normalization.factor
extra/infix/infix-docs.factor
extra/infix/infix-tests.factor
extra/infix/infix.factor
extra/jamshred/player/player.factor
extra/jamshred/tunnel/tunnel.factor
extra/mason/common/common.factor
extra/math/matrices/simd/simd.factor
extra/mongodb/connection/connection.factor
extra/mongodb/driver/driver.factor
extra/mongodb/operations/operations.factor
extra/nurbs/nurbs.factor
extra/project-euler/073/073.factor
extra/project-euler/150/150.factor
extra/reports/noise/noise.factor
extra/sequences/product/product.factor
extra/spider/spider.factor
extra/ui/gadgets/alerts/alerts.factor
extra/vpri-talk/vpri-talk.factor
misc/Factor.tmbundle/Snippets/let.tmSnippet
misc/fuel/fuel-syntax.el
unmaintained/dns/cache/nx/nx.factor [new file with mode: 0644]
unmaintained/dns/cache/rr/rr.factor [new file with mode: 0644]
unmaintained/dns/dns.factor [new file with mode: 0644]
unmaintained/dns/forwarding/forwarding.factor [new file with mode: 0644]
unmaintained/dns/misc/misc.factor [new file with mode: 0644]
unmaintained/dns/resolver/resolver.factor [new file with mode: 0644]
unmaintained/dns/server/server.factor [new file with mode: 0644]
unmaintained/dns/stub/stub.factor [new file with mode: 0644]
unmaintained/dns/util/util.factor [new file with mode: 0644]

index caa3b7a1154482a45467ebd76d4738c1002ea898..d7659d8400f90e110a691dd98ebcfbb3bccb865e 100644 (file)
@@ -330,7 +330,7 @@ M: character-type (<fortran-result>)
     ] if-empty ;
 
 :: [fortran-invoke] ( [args>args] return library function parameters -- [args>args] quot ) 
-    return parameters fortran-sig>c-sig :> c-parameters :> c-return
+    return parameters fortran-sig>c-sig :> ( c-return c-parameters )
     function fortran-name>symbol-name :> c-function
     [args>args] 
     c-return library c-function c-parameters \ alien-invoke
index 4b83739efe07cc1782ea389d8d971cf0002eee61..0cf495fd25d4cd53592be9fdf989d50ad16f6995 100644 (file)
@@ -98,7 +98,7 @@ IN: alien.parser
     type-name current-vocab create :> type-word 
     type-word [ reset-generic ] [ reset-c-type ] bi
     void* type-word typedef
-    parameters return parse-arglist :> callback-effect :> types
+    parameters return parse-arglist :> ( types callback-effect )
     type-word callback-effect "callback-effect" set-word-prop
     type-word lib "callback-library" set-word-prop
     type-word return types lib library-abi callback-quot (( quot -- alien )) ;
index 0eef54dc66c6ae2f6738d992c38da26d080216a1..c4e1ec42b2fca6943629f7495f735f5191141e03 100644 (file)
@@ -113,7 +113,7 @@ PRIVATE>
 M:: lsb0-bit-writer poke ( value n bs -- )
     value n <widthed> :> widthed
     widthed
-    bs widthed>> #bits>> 8 swap - split-widthed :> remainder :> byte
+    bs widthed>> #bits>> 8 swap - split-widthed :> ( byte remainder )
     byte bs widthed>> |widthed :> new-byte
     new-byte #bits>> 8 = [
         new-byte bits>> bs bytes>> push
@@ -143,7 +143,7 @@ ERROR: not-enough-bits n bit-reader ;
     neg shift n bits ;
 
 :: adjust-bits ( n bs -- )
-    n 8 /mod :> #bits :> #bytes
+    n 8 /mod :> ( #bytes #bits )
     bs [ #bytes + ] change-byte-pos
     bit-pos>> #bits + dup 8 >= [
         8 - bs (>>bit-pos)
index a8bb60cbf36396f4098e37c23baf3b0b52a67d80..0378e2701ee16e2a61c58576e13bf4ec3f4222ef 100644 (file)
@@ -119,16 +119,16 @@ GENERIC: easter ( obj -- obj' )
 
 :: easter-month-day ( year -- month day )
     year 19 mod :> a
-    year 100 /mod :> c :> b
-    b 4 /mod :> e :> d
+    year 100 /mod :> ( b c )
+    b 4 /mod :> ( d e )
     b 8 + 25 /i :> f
     b f - 1 + 3 /i :> g
     19 a * b + d - g - 15 + 30 mod :> h
-    c 4 /mod :> k :> i
+    c 4 /mod :> ( i k )
     32 2 e * + 2 i * + h - k - 7 mod :> l
     a 11 h * + 22 l * + 451 /i :> m
 
-    h l + 7 m * - 114 + 31 /mod 1 + :> day :> month
+    h l + 7 m * - 114 + 31 /mod 1 + :> ( month day )
     month day ;
 
 M: integer easter ( year -- timestamp )
index 99fa41cd400e7788dc76a2046ca124f7b3d05760..4b48d7923c6ebbc7d784aac64bc2f6ca55fc9abb 100644 (file)
@@ -25,12 +25,11 @@ IN: channels.examples
     ] 3keep filter ;
 
 :: (sieve) ( prime c -- )
-    [let | p [ c from ] 
-           newc [ <channel> ] |
-        p prime to
-        [ newc p c filter ] "Filter" spawn drop
-        prime newc (sieve)
-    ] ;
+    c from :> p
+    <channel> :> newc
+    p prime to
+    [ newc p c filter ] "Filter" spawn drop
+    prime newc (sieve) ;
 
 : sieve ( prime -- ) 
     #! Send prime numbers to 'prime' channel
index 9ec78248a1c5f2064eab91413a91ca36b924c73f..cb536cd75ed6bbb2a1f09866bcaba197c743196c 100755 (executable)
@@ -24,7 +24,7 @@ PRIVATE>
 
 :: hmac-stream ( stream key checksum -- value )
     checksum initialize-checksum-state :> checksum-state
-    checksum key checksum-state init-key :> Ki :> Ko
+    checksum key checksum-state init-key :> ( Ko Ki )
     checksum-state Ki add-checksum-bytes
     stream add-checksum-stream get-checksum
     checksum initialize-checksum-state
index c535e52c0a2cce1cf19354efb39cd91e0288efba..c5959ab7acde83e447cbb749a0d9613ddcea2f05 100644 (file)
@@ -10,7 +10,7 @@ IN: classes.struct.bit-accessors
     [ 2^ 1 - ] bi@ swap bitnot bitand ;
 
 :: manipulate-bits ( offset bits step-quot -- quot shift-amount offset' bits' )
-    offset 8 /mod :> start-bit :> i
+    offset 8 /mod :> ( i start-bit )
     start-bit bits + 8 min :> end-bit
     start-bit end-bit ones-between :> mask
     end-bit start-bit - :> used-bits
index a37e100c3e5c823afb8be082e2c2c2d2a6843c89..fb993681e8b25aff4e7365484aff85075a4b9659 100644 (file)
@@ -22,12 +22,10 @@ IN: compiler.cfg.intrinsics.alien
     ] [ emit-primitive ] if ;
 
 :: inline-alien ( node quot test -- )
-    [let | infos [ node node-input-infos ] |
-        infos test call
-        [ infos quot call ]
-        [ node emit-primitive ]
-        if
-    ] ; inline
+    node node-input-infos :> infos
+    infos test call
+    [ infos quot call ]
+    [ node emit-primitive ] if ; inline
 
 : inline-alien-getter? ( infos -- ? )
     [ first class>> c-ptr class<= ]
index 8283299ea8afd140cbb2bc6f10657d1524570cb2..044b839f4da2fff6e9cc63e6c71891ccaef466a0 100644 (file)
@@ -43,17 +43,15 @@ IN: compiler.cfg.intrinsics.allot
     2 + cells array ^^allot ;
 
 :: emit-<array> ( node -- )
-    [let | len [ node node-input-infos first literal>> ] |
-        len expand-<array>? [
-            [let | elt [ ds-pop ]
-                   reg [ len ^^allot-array ] |
-                ds-drop
-                len reg array store-length
-                len reg elt array store-initial-element
-                reg ds-push
-            ]
-        ] [ node emit-primitive ] if
-    ] ;
+    node node-input-infos first literal>> :> len
+    len expand-<array>? [
+        ds-pop :> elt
+        len ^^allot-array :> reg
+        ds-drop
+        len reg array store-length
+        len reg elt array store-initial-element
+        reg ds-push
+    ] [ node emit-primitive ] if ;
 
 : expand-(byte-array)? ( obj -- ? )
     dup integer? [ 0 1024 between? ] [ drop f ] if ;
index 9d17ddd0f8ec8ce88a148ba0f406348b419f7479..84646be78bfc994856cd2ea330033b74ab6fa795 100644 (file)
@@ -156,18 +156,18 @@ MACRO: if-literals-match ( quots -- )
     [ [ ^^fill-vector ] [ ^^xor-vector ] bi ] if ;
 
 :: ((generate-compare-vector)) ( src1 src2 rep {cc,swap} -- dst )
-    {cc,swap} first2 :> swap? :> cc
+    {cc,swap} first2 :> ( cc swap? )
     swap?
     [ src2 src1 rep cc ^^compare-vector ]
     [ src1 src2 rep cc ^^compare-vector ] if ;
 
 :: (generate-compare-vector) ( src1 src2 rep orig-cc -- dst )
-    rep orig-cc %compare-vector-ccs :> not? :> ccs
+    rep orig-cc %compare-vector-ccs :> ( ccs not? )
 
     ccs empty?
     [ rep not? [ ^^fill-vector ] [ ^^zero-vector ] if ]
     [
-        ccs unclip :> first-cc :> rest-ccs
+        ccs unclip :> ( rest-ccs first-cc )
         src1 src2 rep first-cc ((generate-compare-vector)) :> first-dst
 
         rest-ccs first-dst
index e1088a80ef980c9cc1cd7598ecfe1b9c808413b5..39151083e53e4da8c085b30ba16491ecd05d6f7b 100644 (file)
@@ -42,7 +42,7 @@ IN: compiler.cfg.intrinsics.slots
     first class>> immediate class<= not ;
 
 :: (emit-set-slot) ( infos -- )
-    3inputs :> slot :> obj :> src
+    3inputs :> ( src obj slot )
 
     slot infos second value-tag ^^tag-offset>slot :> slot
 
@@ -54,7 +54,7 @@ IN: compiler.cfg.intrinsics.slots
 :: (emit-set-slot-imm) ( infos -- )
     ds-drop
 
-    2inputs :> obj :> src
+    2inputs :> ( src obj )
 
     infos third literal>> :> slot
     infos second value-tag :> tag
index 1ed6010dbe894bf16fff9362a5d47d51d7f31c81..7847de28fcae16c39680206df8fbf6440731d28a 100644 (file)
@@ -121,10 +121,9 @@ PRIVATE>
 PRIVATE>
 
 :: live-out? ( vreg node -- ? )
-    [let | def [ vreg def-of ] |
-        {
-            { [ node def eq? ] [ vreg uses-of def only? not ] }
-            { [ def node strictly-dominates? ] [ vreg node (live-out?) ] }
-            [ f ]
-        } cond
-    ] ;
+    vreg def-of :> def
+    {
+        { [ node def eq? ] [ vreg uses-of def only? not ] }
+        { [ def node strictly-dominates? ] [ vreg node (live-out?) ] }
+        [ f ]
+    } cond ;
index b0ab864c80f2cb2bf3ac34c7e672c319ee7634a7..482d370947bb626a601c217fc42689edd9ee5f8b 100644 (file)
@@ -39,14 +39,13 @@ M: #enter-recursive remove-dead-code*
     2bi ;
 
 :: (drop-call-recursive-outputs) ( inputs outputs -- #shuffle )
-    [let* | new-live-outputs [ inputs outputs filter-corresponding make-values ]
-            live-outputs [ outputs filter-live ] |
-        new-live-outputs
-        live-outputs
-        live-outputs
-        new-live-outputs
-        drop-values
-    ] ;
+    inputs outputs filter-corresponding make-values :> new-live-outputs
+    outputs filter-live :> live-outputs
+    new-live-outputs
+    live-outputs
+    live-outputs
+    new-live-outputs
+    drop-values ;
 
 : drop-call-recursive-outputs ( node -- #shuffle )
     dup [ label>> return>> in-d>> ] [ out-d>> ] bi
@@ -60,22 +59,20 @@ M: #call-recursive remove-dead-code*
     tri 3array ;
 
 :: drop-recursive-inputs ( node -- shuffle )
-    [let* | shuffle [ node [ in-d>> ] [ label>> enter-out>> ] bi drop-dead-inputs ]
-            new-outputs [ shuffle out-d>> ] |
-        node new-outputs
-        [ [ label>> enter-recursive>> ] dip >>in-d drop ] [ >>in-d drop ] 2bi
-        shuffle
-    ] ;
+    node [ in-d>> ] [ label>> enter-out>> ] bi drop-dead-inputs :> shuffle
+    shuffle out-d>> :> new-outputs
+    node new-outputs
+    [ [ label>> enter-recursive>> ] dip >>in-d drop ] [ >>in-d drop ] 2bi
+    shuffle ;
 
 :: drop-recursive-outputs ( node -- shuffle )
-    [let* | return [ node label>> return>> ]
-            new-inputs [ return in-d>> filter-live ]
-            new-outputs [ return [ in-d>> ] [ out-d>> ] bi filter-corresponding ] |
-        return
-        [ new-inputs >>in-d new-outputs >>out-d drop ]
-        [ drop-dead-outputs ]
-        bi
-    ] ;
+    node label>> return>> :> return
+    return in-d>> filter-live :> new-inputs
+    return [ in-d>> ] [ out-d>> ] bi filter-corresponding :> new-outputs
+    return
+    [ new-inputs >>in-d new-outputs >>out-d drop ]
+    [ drop-dead-outputs ]
+    bi ;
 
 M: #recursive remove-dead-code* ( node -- nodes )
     [ drop-recursive-inputs ]
index 5134a67a5bb53edf0cce2f3d010ee1a7fa6cf9cf..f6165a44ab94bba1695f905ac74f8ea67f45baa7 100755 (executable)
@@ -71,14 +71,13 @@ M: #alien-indirect compute-live-values* nip look-at-inputs ;
     filter-corresponding zip #data-shuffle ; inline
 
 :: drop-dead-values ( outputs -- #shuffle )
-    [let* | new-outputs [ outputs make-values ]
-            live-outputs [ outputs filter-live ] |
-        new-outputs
-        live-outputs
-        outputs
-        new-outputs
-        drop-values
-    ] ;
+    outputs make-values :> new-outputs
+    outputs filter-live :> live-outputs
+    new-outputs
+    live-outputs
+    outputs
+    new-outputs
+    drop-values ;
 
 : drop-dead-outputs ( node -- #shuffle )
     dup out-d>> drop-dead-values [ in-d>> >>out-d drop ] keep ;
index e21ab74cc25790c584b5586c1cea057bb075e530..5646dca3fb3773ab5f1937ab31ea066c879d1937 100644 (file)
@@ -159,12 +159,11 @@ IN: compiler.tree.propagation.known-words
 \ bitxor [ [ interval-bitxor ] [ integer-valued ] binary-op ] each-derived-op
 
 :: (comparison-constraints) ( in1 in2 op -- constraint )
-    [let | i1 [ in1 value-info interval>> ]
-           i2 [ in2 value-info interval>> ] |
-       in1 i1 i2 op assumption is-in-interval
-       in2 i2 i1 op swap-comparison assumption is-in-interval
-       /\
-    ] ;
+    in1 value-info interval>> :> i1
+    in2 value-info interval>> :> i2
+    in1 i1 i2 op assumption is-in-interval
+    in2 i2 i1 op swap-comparison assumption is-in-interval
+    /\ ;
 
 :: comparison-constraints ( in1 in2 out op -- constraint )
     in1 in2 op (comparison-constraints) out t-->
index b6c6910e34538aed940ecd5da7dd93b44982ad9d..84080a73d7ce2399a2e9aa6f8415a17c916f3ee3 100644 (file)
@@ -36,13 +36,11 @@ yield-hook [ [ ] ] initialize
 : penultimate ( seq -- elt ) [ length 2 - ] keep nth ;
 
 :: compress-path ( source assoc -- destination )
-    [let | destination [ source assoc at ] |
-        source destination = [ source ] [
-            [let | destination' [ destination assoc compress-path ] |
-                destination' destination = [
-                    destination' source assoc set-at
-                ] unless
-                destination'
-            ]
-        ] if
-    ] ;
+    source assoc at :> destination
+    source destination = [ source ] [
+        destination assoc compress-path :> destination'
+        destination' destination = [
+            destination' source assoc set-at
+        ] unless
+        destination'
+    ] if ;
index a8214cf42f2301a5712a034df555f20053c3bbf3..c411aaea92254edf4974a1fcbf5f18e3f60e052a 100644 (file)
@@ -5,27 +5,25 @@ FROM: sequences => 3append ;
 IN: concurrency.exchangers.tests\r
 \r
 :: exchanger-test ( -- string )\r
-    [let |\r
-        ex [ <exchanger> ]\r
-        c [ 2 <count-down> ]\r
-        v1! [ f ]\r
-        v2! [ f ]\r
-        pr [ <promise> ] |\r
+    <exchanger> :> ex\r
+    2 <count-down> :> c\r
+    f :> v1!\r
+    f :> v2!\r
+    <promise> :> pr\r
 \r
-        [\r
-            c await\r
-            v1 ", " v2 3append pr fulfill\r
-        ] "Awaiter" spawn drop\r
+    [\r
+        c await\r
+        v1 ", " v2 3append pr fulfill\r
+    ] "Awaiter" spawn drop\r
 \r
-        [\r
-            "Goodbye world" ex exchange v1! c count-down\r
-        ] "Exchanger 1" spawn drop\r
+    [\r
+        "Goodbye world" ex exchange v1! c count-down\r
+    ] "Exchanger 1" spawn drop\r
 \r
-        [\r
-            "Hello world" ex exchange v2! c count-down\r
-        ] "Exchanger 2" spawn drop\r
+    [\r
+        "Hello world" ex exchange v2! c count-down\r
+    ] "Exchanger 2" spawn drop\r
 \r
-        pr ?promise\r
-    ] ;\r
+    pr ?promise ;\r
 \r
 [ "Hello world, Goodbye world" ] [ exchanger-test ] unit-test\r
index 4fc00b71dd74df1c5c604b7d0703bc6c38b384a1..8402a5663164a5215f39deb5117b5b2b36962517 100644 (file)
@@ -3,46 +3,41 @@ kernel threads locals accessors calendar ;
 IN: concurrency.flags.tests\r
 \r
 :: flag-test-1 ( -- val )\r
-    [let | f [ <flag> ] |\r
-        [ f raise-flag ] "Flag test" spawn drop\r
-        f lower-flag\r
-        f value>>\r
-    ] ;\r
+    <flag> :> f\r
+    [ f raise-flag ] "Flag test" spawn drop\r
+    f lower-flag\r
+    f value>> ;\r
 \r
 [ f ] [ flag-test-1 ] unit-test\r
 \r
 :: flag-test-2 ( -- ? )\r
-    [let | f [ <flag> ] |\r
-        [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
-        f lower-flag\r
-        f value>>\r
-    ] ;\r
+    <flag> :> f\r
+    [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
+    f lower-flag\r
+    f value>> ;\r
 \r
 [ f ] [ flag-test-2 ] unit-test\r
 \r
 :: flag-test-3 ( -- val )\r
-    [let | f [ <flag> ] |\r
-        f raise-flag\r
-        f value>>\r
-    ] ;\r
+    <flag> :> f\r
+    f raise-flag\r
+    f value>> ;\r
 \r
 [ t ] [ flag-test-3 ] unit-test\r
 \r
 :: flag-test-4 ( -- val )\r
-    [let | f [ <flag> ] |\r
-        [ f raise-flag ] "Flag test" spawn drop\r
-        f wait-for-flag\r
-        f value>>\r
-    ] ;\r
+    <flag> :> f\r
+    [ f raise-flag ] "Flag test" spawn drop\r
+    f wait-for-flag\r
+    f value>> ;\r
 \r
 [ t ] [ flag-test-4 ] unit-test\r
 \r
 :: flag-test-5 ( -- val )\r
-    [let | f [ <flag> ] |\r
-        [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
-        f wait-for-flag\r
-        f value>>\r
-    ] ;\r
+    <flag> :> f\r
+    [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop\r
+    f wait-for-flag\r
+    f value>> ;\r
 \r
 [ t ] [ flag-test-5 ] unit-test\r
 \r
index f199876fd0c5d360c564debc1439724130f1ec08..c58d012b3fa74dac8123e2de407f342997f40ed8 100644 (file)
@@ -4,57 +4,55 @@ threads sequences calendar accessors ;
 IN: concurrency.locks.tests\r
 \r
 :: lock-test-0 ( -- v )\r
-    [let | v [ V{ } clone ]\r
-           c [ 2 <count-down> ] |\r
-\r
-           [\r
-               yield\r
-               1 v push\r
-               yield\r
-               2 v push\r
-               c count-down\r
-           ] "Lock test 1" spawn drop\r
-\r
-           [\r
-               yield\r
-               3 v push\r
-               yield\r
-               4 v push\r
-               c count-down\r
-           ] "Lock test 2" spawn drop\r
-\r
-           c await\r
-           v\r
-    ] ;\r
+    V{ } clone :> v\r
+    2 <count-down> :> c\r
+\r
+    [\r
+        yield\r
+        1 v push\r
+        yield\r
+        2 v push\r
+        c count-down\r
+    ] "Lock test 1" spawn drop\r
+\r
+    [\r
+        yield\r
+        3 v push\r
+        yield\r
+        4 v push\r
+        c count-down\r
+    ] "Lock test 2" spawn drop\r
+\r
+    c await\r
+    v ;\r
 \r
 :: lock-test-1 ( -- v )\r
-    [let | v [ V{ } clone ]\r
-           l [ <lock> ]\r
-           c [ 2 <count-down> ] |\r
-\r
-           [\r
-               l [\r
-                   yield\r
-                   1 v push\r
-                   yield\r
-                   2 v push\r
-               ] with-lock\r
-               c count-down\r
-           ] "Lock test 1" spawn drop\r
-\r
-           [\r
-               l [\r
-                   yield\r
-                   3 v push\r
-                   yield\r
-                   4 v push\r
-               ] with-lock\r
-               c count-down\r
-           ] "Lock test 2" spawn drop\r
-\r
-           c await\r
-           v\r
-    ] ;\r
+    V{ } clone :> v\r
+    <lock> :> l\r
+    2 <count-down> :> c\r
+\r
+    [\r
+        l [\r
+            yield\r
+            1 v push\r
+            yield\r
+            2 v push\r
+        ] with-lock\r
+        c count-down\r
+    ] "Lock test 1" spawn drop\r
+\r
+    [\r
+        l [\r
+            yield\r
+            3 v push\r
+            yield\r
+            4 v push\r
+        ] with-lock\r
+        c count-down\r
+    ] "Lock test 2" spawn drop\r
+\r
+    c await\r
+    v ;\r
 \r
 [ V{ 1 3 2 4 } ] [ lock-test-0 ] unit-test\r
 [ V{ 1 2 3 4 } ] [ lock-test-1 ] unit-test\r
@@ -80,98 +78,96 @@ IN: concurrency.locks.tests
 [ ] [ <rw-lock> dup [ [ ] with-read-lock ] with-write-lock ] unit-test\r
 \r
 :: rw-lock-test-1 ( -- v )\r
-    [let | l [ <rw-lock> ]\r
-           c [ 1 <count-down> ]\r
-           c' [ 1 <count-down> ]\r
-           c'' [ 4 <count-down> ]\r
-           v [ V{ } clone ] |\r
-\r
-           [\r
-               l [\r
-                   1 v push\r
-                   c count-down\r
-                   yield\r
-                   3 v push\r
-               ] with-read-lock\r
-               c'' count-down\r
-           ] "R/W lock test 1" spawn drop\r
-\r
-           [\r
-               c await\r
-               l [\r
-                   4 v push\r
-                   1 seconds sleep\r
-                   5 v push\r
-               ] with-write-lock\r
-               c'' count-down\r
-           ] "R/W lock test 2" spawn drop\r
-\r
-           [\r
-               c await\r
-               l [\r
-                   2 v push\r
-                   c' count-down\r
-               ] with-read-lock\r
-               c'' count-down\r
-           ] "R/W lock test 4" spawn drop\r
-\r
-           [\r
-               c' await\r
-               l [\r
-                   6 v push\r
-               ] with-write-lock\r
-               c'' count-down\r
-           ] "R/W lock test 5" spawn drop\r
-\r
-           c'' await\r
-           v\r
-    ] ;\r
+    <rw-lock> :> l\r
+    1 <count-down> :> c\r
+    1 <count-down> :> c'\r
+    4 <count-down> :> c''\r
+    V{ } clone :> v\r
+\r
+    [\r
+        l [\r
+            1 v push\r
+            c count-down\r
+            yield\r
+            3 v push\r
+        ] with-read-lock\r
+        c'' count-down\r
+    ] "R/W lock test 1" spawn drop\r
+\r
+    [\r
+        c await\r
+        l [\r
+            4 v push\r
+            1 seconds sleep\r
+            5 v push\r
+        ] with-write-lock\r
+        c'' count-down\r
+    ] "R/W lock test 2" spawn drop\r
+\r
+    [\r
+        c await\r
+        l [\r
+            2 v push\r
+            c' count-down\r
+        ] with-read-lock\r
+        c'' count-down\r
+    ] "R/W lock test 4" spawn drop\r
+\r
+    [\r
+        c' await\r
+        l [\r
+            6 v push\r
+        ] with-write-lock\r
+        c'' count-down\r
+    ] "R/W lock test 5" spawn drop\r
+\r
+    c'' await\r
+    v ;\r
 \r
 [ V{ 1 2 3 4 5 6 } ] [ rw-lock-test-1 ] unit-test\r
 \r
 :: rw-lock-test-2 ( -- v )\r
-    [let | l [ <rw-lock> ]\r
-           c [ 1 <count-down> ]\r
-           c' [ 2 <count-down> ]\r
-           v [ V{ } clone ] |\r
-\r
-           [\r
-               l [\r
-                   1 v push\r
-                   c count-down\r
-                   1 seconds sleep\r
-                   2 v push\r
-               ] with-write-lock\r
-               c' count-down\r
-           ] "R/W lock test 1" spawn drop\r
-\r
-           [\r
-               c await\r
-               l [\r
-                   3 v push\r
-               ] with-read-lock\r
-               c' count-down\r
-           ] "R/W lock test 2" spawn drop\r
-\r
-           c' await\r
-           v\r
-    ] ;\r
+    <rw-lock> :> l\r
+    1 <count-down> :> c\r
+    2 <count-down> :> c'\r
+    V{ } clone :> v\r
+\r
+    [\r
+        l [\r
+            1 v push\r
+            c count-down\r
+            1 seconds sleep\r
+            2 v push\r
+        ] with-write-lock\r
+        c' count-down\r
+    ] "R/W lock test 1" spawn drop\r
+\r
+    [\r
+        c await\r
+        l [\r
+            3 v push\r
+        ] with-read-lock\r
+        c' count-down\r
+    ] "R/W lock test 2" spawn drop\r
+\r
+    c' await\r
+    v ;\r
 \r
 [ V{ 1 2 3 } ] [ rw-lock-test-2 ] unit-test\r
 \r
 ! Test lock timeouts\r
 :: lock-timeout-test ( -- v )\r
-    [let | l [ <lock> ] |\r
-        [\r
-            l [ 1 seconds sleep ] with-lock\r
-        ] "Lock holder" spawn drop\r
+    <lock> :> l\r
 \r
-        [\r
-            l 1/10 seconds [ ] with-lock-timeout\r
-        ] "Lock timeout-er" spawn-linked drop\r
+    [\r
+        l [ 1 seconds sleep ] with-lock\r
+    ] "Lock holder" spawn drop\r
+\r
+    [\r
+        l 1/10 seconds [ ] with-lock-timeout\r
+    ] "Lock timeout-er" spawn-linked drop\r
 \r
-        receive\r
-    ] ;\r
+    receive ;\r
 \r
 [ lock-timeout-test ] [\r
     thread>> name>> "Lock timeout-er" =\r
index 3459b368f79bc0cbdb8c8c0207dfcd9c0c888580..e431df941424ef135bd90861886a50cc4aade04e 100644 (file)
@@ -112,35 +112,34 @@ TUPLE: line < disposable line metrics image loc dim ;
     [
         line new-disposable
 
-        [let* | open-font [ font cache-font ]
-                line [ string open-font font foreground>> <CTLine> |CFRelease ]
-
-                rect [ line line-rect ]
-                (loc) [ rect origin>> CGPoint>loc ]
-                (dim) [ rect size>> CGSize>dim ]
-                (ext) [ (loc) (dim) v+ ]
-                loc [ (loc) [ floor ] map ]
-                ext [ (loc) (dim) [ + ceiling ] 2map ]
-                dim [ ext loc [ - >integer 1 max ] 2map ]
-                metrics [ open-font line compute-line-metrics ] |
-
-            line >>line
-
-            metrics >>metrics
-
-            dim [
-                {
-                    [ font dim fill-background ]
-                    [ loc dim line string fill-selection-background ]
-                    [ loc set-text-position ]
-                    [ [ line ] dip CTLineDraw ]
-                } cleave
-            ] make-bitmap-image >>image
-
-            metrics loc dim line-loc >>loc
-
-            metrics metrics>dim >>dim
-        ]
+        font cache-font :> open-font
+        string open-font font foreground>> <CTLine> |CFRelease :> line
+
+        line line-rect :> rect
+        rect origin>> CGPoint>loc :> (loc)
+        rect size>> CGSize>dim :> (dim)
+        (loc) (dim) v+ :> (ext)
+        (loc) [ floor ] map :> loc
+        (loc) (dim) [ + ceiling ] 2map :> ext
+        ext loc [ - >integer 1 max ] 2map :> dim
+        open-font line compute-line-metrics :> metrics
+
+        line >>line
+
+        metrics >>metrics
+
+        dim [
+            {
+                [ font dim fill-background ]
+                [ loc dim line string fill-selection-background ]
+                [ loc set-text-position ]
+                [ [ line ] dip CTLineDraw ]
+            } cleave
+        ] make-bitmap-image >>image
+
+        metrics loc dim line-loc >>loc
+
+        metrics metrics>dim >>dim
     ] with-destructors ;
 
 M: line dispose* line>> CFRelease ;
index 517aa7587dcfddec0898937bcae3fe44bcc5e3e0..8ddacaa0e1a65d870542e15bec9d76e73ecc2473 100644 (file)
@@ -504,11 +504,11 @@ M: ppc %compare [ (%compare) ] 2dip %boolean ;
 M: ppc %compare-imm [ (%compare-imm) ] 2dip %boolean ;
 
 M:: ppc %compare-float-ordered ( dst src1 src2 cc temp -- )
-    src1 src2 cc negate-cc \ (%compare-float-ordered) (%compare-float) :> branch2 :> branch1
+    src1 src2 cc negate-cc \ (%compare-float-ordered) (%compare-float) :> ( branch1 branch2 )
     dst temp branch1 branch2 (%boolean) ;
 
 M:: ppc %compare-float-unordered ( dst src1 src2 cc temp -- )
-    src1 src2 cc negate-cc \ (%compare-float-unordered) (%compare-float) :> branch2 :> branch1
+    src1 src2 cc negate-cc \ (%compare-float-unordered) (%compare-float) :> ( branch1 branch2 )
     dst temp branch1 branch2 (%boolean) ;
 
 :: %branch ( label cc -- )
@@ -534,11 +534,11 @@ M:: ppc %compare-imm-branch ( label src1 src2 cc -- )
     branch2 [ label branch2 execute( label -- ) ] when ; inline
 
 M:: ppc %compare-float-ordered-branch ( label src1 src2 cc -- )
-    src1 src2 cc \ (%compare-float-ordered) (%compare-float) :> branch2 :> branch1
+    src1 src2 cc \ (%compare-float-ordered) (%compare-float) :> ( branch1 branch2 )
     label branch1 branch2 (%branch) ;
 
 M:: ppc %compare-float-unordered-branch ( label src1 src2 cc -- )
-    src1 src2 cc \ (%compare-float-unordered) (%compare-float) :> branch2 :> branch1
+    src1 src2 cc \ (%compare-float-unordered) (%compare-float) :> ( branch1 branch2 )
     label branch1 branch2 (%branch) ;
 
 : load-from-frame ( dst n rep -- )
index 2a1ac85de06312fffc8e526f6433ff24fc95d9fe..57954385706ed1a007bb0e0b1f8803eb6bab31c9 100644 (file)
@@ -114,8 +114,8 @@ DEFER: (parse-paragraph)
 
 :: (take-until) ( state delimiter accum -- string/f state' )
     state empty? [ accum "\n" join f ] [
-        state unclip-slice :> first :> rest
-        first delimiter split1 :> after :> before
+        state unclip-slice :> ( rest first )
+        first delimiter split1 :> ( before after )
         before accum push
         after [
             accum "\n" join
index 13b9e61632112829c116d128cc5d17304e76f992..9602933785d60492af2ff4ac419145f4a178c01f 100644 (file)
@@ -68,10 +68,10 @@ ARTICLE: "fry.philosophy" "Fried quotation philosophy"
     "'[ [ _ key? ] all? ] filter"\r
     "[ [ key? ] curry all? ] curry filter"\r
 }\r
-"There is a mapping from fried quotations to lexical closures as defined in the " { $vocab-link "locals" } " vocabulary. Namely, a fried quotation is equivalent to a “let” form where each local binding is only used once, and bindings are used in the same order in which they are defined. The following two lines are equivalent:"\r
+"There is a mapping from fried quotations to lexical closures as defined in the " { $vocab-link "locals" } " vocabulary. Namely, a fried quotation is equivalent to a " { $snippet "[| | ]" } " form where each local binding is only used once, and bindings are used in the same order in which they are defined. The following two lines are equivalent:"\r
 { $code\r
     "'[ 3 _ + 4 _ / ]"\r
-    "[let | a [ ] b [ ] | [ 3 a + 4 b / ] ]"\r
+    "[| a b | 3 a + 4 b / ]"\r
 } ;\r
 \r
 ARTICLE: "fry" "Fried quotations"\r
index 56aa6f0d1be913ecb56895964d082cae3ad03116..a03463e91171fa2447daf3d5960ab47bc7882a83 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays classes.mixin classes.parser
+USING: accessors arrays assocs classes.mixin classes.parser
 classes.singleton classes.tuple classes.tuple.parser
 combinators effects.parser fry functors.backend generic
 generic.parser interpolate io.streams.string kernel lexer
@@ -144,10 +144,31 @@ DEFER: ;FUNCTOR delimiter
 : pop-functor-words ( -- )
     functor-words unuse-words ;
 
+: (parse-bindings) ( end -- )
+    dup parse-binding dup [
+        first2 [ make-local ] dip 2array ,
+        (parse-bindings)
+    ] [ 2drop ] if ;
+
+: with-bindings ( quot -- words assoc )
+    '[
+        in-lambda? on
+        _ H{ } make-assoc
+    ] { } make swap ; inline
+
+: parse-bindings ( end -- words assoc )
+    [
+        namespace use-words
+        (parse-bindings)
+        namespace unuse-words
+    ] with-bindings ;
+
 : parse-functor-body ( -- form )
     push-functor-words
-    "WHERE" parse-bindings*
-    [ \ ;FUNCTOR parse-until >quotation ] ((parse-lambda)) <let*> 1quotation
+    "WHERE" parse-bindings
+    [ [ swap <def> suffix ] { } assoc>map concat ]
+    [ [ \ ;FUNCTOR parse-until >quotation ] ((parse-lambda)) ] bi*
+    [ ] append-as
     pop-functor-words ;
 
 : (FUNCTOR:) ( -- word def effect )
index 1933fc8c59db682b97edb8f216816d663e2a7b21..44374fb5a62c78645da25713d4b28f3bd6636bf2 100644 (file)
@@ -23,26 +23,24 @@ GENERIC: new-user ( user provider -- user/f )
 ! Password recovery support\r
 \r
 :: issue-ticket ( email username provider -- user/f )\r
-    [let | user [ username provider get-user ] |\r
-        user [\r
-            user email>> length 0 > [\r
-                user email>> email = [\r
-                    user\r
-                    256 random-bits >hex >>ticket\r
-                    dup provider update-user\r
-                ] [ f ] if\r
+    username provider get-user :> user\r
+    user [\r
+        user email>> length 0 > [\r
+            user email>> email = [\r
+                user\r
+                256 random-bits >hex >>ticket\r
+                dup provider update-user\r
             ] [ f ] if\r
         ] [ f ] if\r
-    ] ;\r
+    ] [ f ] if ;\r
 \r
 :: claim-ticket ( ticket username provider -- user/f )\r
-    [let | user [ username provider get-user ] |\r
-        user [\r
-            user ticket>> ticket = [\r
-                user f >>ticket dup provider update-user\r
-            ] [ f ] if\r
+    username provider get-user :> user\r
+    user [\r
+        user ticket>> ticket = [\r
+            user f >>ticket dup provider update-user\r
         ] [ f ] if\r
-    ] ;\r
+    ] [ f ] if ;\r
 \r
 ! For configuration\r
 \r
index c15debd9b546c193df96febfaeb88954d15056da..8f84da4ff797467319bb5de915699464d0693b8a 100644 (file)
@@ -16,7 +16,8 @@ IN: interpolate.tests
 ] unit-test
 
 [ "Oops, I accidentally the whole economy..." ] [
-    [let | noun [ "economy" ] |
+    [let
+        "economy" :> noun
         [ I[ Oops, I accidentally the whole ${noun}...]I ] with-string-writer
     ]
 ] unit-test
index 2aa2c5d7a4d01641727e4df7d45bee560327be46..512b52ef19e85f165c0022e73139f4a982095c12 100644 (file)
@@ -48,7 +48,8 @@ TUPLE: range ufirst ulast bfirst blast ;
     ] dip set-at ;
 
 : xml>gb-data ( stream -- mapping ranges )
-    [let | mapping [ H{ } clone ] ranges [ V{ } clone ] |
+    [let
+        H{ } clone :> mapping V{ } clone :> ranges
         [
             dup contained? [ 
                 dup name>> main>> {
@@ -57,7 +58,7 @@ TUPLE: range ufirst ulast bfirst blast ;
                     [ 2drop ]
                 } case
             ] [ drop ] if
-        ] each-element mapping ranges 
+        ] each-element mapping ranges
     ] ;
 
 : unlinear ( num -- bytes )
index 852d8171e403233ea31a49ea4d295fe7ed2eb5ac..7fa7f4b2c68d0357dd8ecb17ce6de04815130ba3 100644 (file)
@@ -125,14 +125,15 @@ concurrency.promises threads unix.process ;
 
 ! Killed processes were exiting with code 0 on FreeBSD
 [ f ] [
-    [let | p [ <promise> ]
-           s [ <promise> ] |
-       [
-           "sleep 1000" run-detached
-           [ p fulfill ] [ wait-for-process s fulfill ] bi
-       ] in-thread
-
-       p ?promise handle>> 9 kill drop
-       s ?promise 0 =
+    [let 
+        <promise> :> p
+        <promise> :> s
+        [
+            "sleep 1000" run-detached
+            [ p fulfill ] [ wait-for-process s fulfill ] bi
+        ] in-thread
+
+        p ?promise handle>> 9 kill drop
+        s ?promise 0 =
     ]
 ] unit-test
index a2c1f972a6c1bbc7b36182bcb06ae7671d0fcde5..e3e3116b59047f5852b9912f7cecdab773bce76a 100644 (file)
@@ -12,14 +12,13 @@ IN: io.mmap.windows
     MapViewOfFile [ win32-error=0/f ] keep ;
 
 :: mmap-open ( path length access-mode create-mode protect access -- handle handle address )
-    [let | lo [ length 32 bits ]
-           hi [ length -32 shift 32 bits ] |
-        { "SeCreateGlobalPrivilege" "SeLockMemoryPrivilege" } [
-            path access-mode create-mode 0 open-file |dispose
-            dup handle>> f protect hi lo f create-file-mapping |dispose
-            dup handle>> access 0 0 0 map-view-of-file
-        ] with-privileges
-    ] ;
+    length 32 bits :> lo
+    length -32 shift 32 bits :> hi
+    { "SeCreateGlobalPrivilege" "SeLockMemoryPrivilege" } [
+        path access-mode create-mode 0 open-file |dispose
+        dup handle>> f protect hi lo f create-file-mapping |dispose
+        dup handle>> access 0 0 0 map-view-of-file
+    ] with-privileges ;
 
 TUPLE: win32-mapped-file file mapping ;
 
index 96f178fb7967ad9dba79970c19dfdf8dace7bb69..e71fb2eca2f9476ac364fbae266684a252104e80 100644 (file)
@@ -11,11 +11,10 @@ TUPLE: macosx-monitor < monitor handle ;
     '[ first { +modify-file+ } _ queue-change ] each ;
 
 M:: macosx (monitor) ( path recursive? mailbox -- monitor )
-    [let | path [ path normalize-path ] |
-        path mailbox macosx-monitor new-monitor
-        dup [ enqueue-notifications ] curry
-        path 1array 0 0 <event-stream> >>handle
-    ] ;
+    path normalize-path :> path
+    path mailbox macosx-monitor new-monitor
+    dup [ enqueue-notifications ] curry
+    path 1array 0 0 <event-stream> >>handle ;
 
 M: macosx-monitor dispose* handle>> dispose ;
 
index 400a44ea020c78daa5e4d7165de773af5ac4f638..f934842e8c83ad75d91f6e970bd2a1f38581b97f 100644 (file)
@@ -35,10 +35,9 @@ TUPLE: openssl-context < secure-context aliens sessions ;
     [| buf size rwflag password! |
         password [ B{ 0 } password! ] unless
 
-        [let | len [ password strlen ] |
-            buf password len 1 + size min memcpy
-            len
-        ]
+        password strlen :> len
+        buf password len 1 + size min memcpy
+        len
     ] alien-callback ;
 
 : default-pasword ( ctx -- alien )
index 3564b3289002eac773526dedacdca14cd17071cf..8ece039dc1f0ad0f306e332648133e7d6d47a77c 100755 (executable)
@@ -120,7 +120,7 @@ CONSTANT: packet-size 65536
 [ packet-size malloc receive-buffer set-global ] "io.sockets.unix" add-init-hook
 
 :: do-receive ( port -- packet sockaddr )
-    port addr>> empty-sockaddr/size :> len :> sockaddr
+    port addr>> empty-sockaddr/size :> ( sockaddr len )
     port handle>> handle-fd ! s
     receive-buffer get-global ! buf
     packet-size ! nbytes
index aabd4bbafcd6e84d55d4dbb7e008e197b30ecf0d..38920f5764669daffbb2d6f07602de6dca37b27f 100644 (file)
@@ -25,11 +25,11 @@ IN: lcs
     [ [ + ] curry map ] with map ;\r
 \r
 :: run-lcs ( old new init step -- matrix )\r
-    [let | matrix [ old length 1 + new length 1 + init call ] |\r
-        old length [| i |\r
-            new length\r
-            [| j | i j matrix old new step loop-step ] each\r
-        ] each matrix ] ; inline\r
+    old length 1 + new length 1 + init call :> matrix\r
+    old length [| i |\r
+        new length\r
+        [| j | i j matrix old new step loop-step ] each\r
+    ] each matrix ; inline\r
 PRIVATE>\r
 \r
 : levenshtein ( old new -- n )\r
index e7b4c5a88439954b03b0b9350a9825f4e41bb564..468671361f8fe34f63674e6ab30e94e38159ae74 100644 (file)
@@ -9,10 +9,10 @@ M: >r/r>-in-lambda-error summary
     drop
     "Explicit retain stack manipulation is not permitted in lambda bodies" ;
 
-ERROR: binding-form-in-literal-error ;
+ERROR: let-form-in-literal-error ;
 
-M: binding-form-in-literal-error summary
-    drop "[let, [let* and [wlet not permitted inside literals" ;
+M: let-form-in-literal-error summary
+    drop "[let not permitted inside literals" ;
 
 ERROR: local-writer-in-literal-error ;
 
@@ -27,7 +27,7 @@ M: local-word-in-literal-error summary
 ERROR: :>-outside-lambda-error ;
 
 M: :>-outside-lambda-error summary
-    drop ":> cannot be used outside of lambda expressions" ;
+    drop ":> cannot be used outside of [let, [|, or :: forms" ;
 
 ERROR: bad-local args obj ;
 
index 9dc924334c742a833f8948bc9049542b3018a760..ff6a491a79d7e2d13e8df2687633fa71ac1dba71 100644 (file)
@@ -6,7 +6,7 @@ IN: locals.fry
 
 ! Support for mixing locals with fry
 
-M: binding-form count-inputs body>> count-inputs ;
+M: let count-inputs body>> count-inputs ;
 
 M: lambda count-inputs body>> count-inputs ;
 
@@ -14,5 +14,5 @@ M: lambda deep-fry
     clone [ shallow-fry swap ] change-body
     [ [ vars>> length ] keep '[ _ _ mnswap @ ] , ] [ drop [ncurry] % ] 2bi ;
 
-M: binding-form deep-fry
+M: let deep-fry
     clone [ fry '[ @ call ] ] change-body , ;
index 92c34eb53beecf7b7213af21a8e66ccce9d993bf..0f27240c33da14fe0bd5cfd20ac64813d2398218 100644 (file)
@@ -8,45 +8,30 @@ HELP: [|
 { $examples "See " { $link "locals-examples" } "." } ;
 
 HELP: [let
-{ $syntax "[let | var-1 [ value-1... ]\n        var-2 [ value-2... ]\n        ... |\n    body... ]" }
-{ $description "Evaluates each " { $snippet "value-n" } " form and binds its result to a new local variable named " { $snippet "var-n" } " lexically scoped to the " { $snippet "body" } ", then evaluates " { $snippet "body" } ". The " { $snippet "value-n" } " forms are evaluated in parallel, so a " { $snippet "value-n" } " form may not refer to previous " { $snippet "var-n" } " definitions inside the same " { $link POSTPONE: [let } " form, unlike " { $link POSTPONE: [let* } "." }
+{ $syntax "[let code :> var code :> var code... ]" }
+{ $description "Establishes a new lexical scope for local 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." }
 { $examples "See " { $link "locals-examples" } "." } ;
 
-HELP: [let*
-{ $syntax "[let* | var-1 [ value-1... ]\n        var-2 [ value-2... ]\n        ... |\n    body... ]" }
-{ $description "Evaluates each " { $snippet "value-n" } " form and binds its result to a new local variable named " { $snippet "var-n" } " lexically scoped to the " { $snippet "body" } ", then evaluates " { $snippet "body" } ". The " { $snippet "value-n" } " forms are evaluated sequentially, so a " { $snippet "value-n" } " form may refer to previous " { $snippet "var-n" } " definitions inside the same " { $link POSTPONE: [let* } " form." }
-{ $examples "See " { $link "locals-examples" } "." } ;
-
-{ POSTPONE: [let POSTPONE: [let* } related-words
-
-HELP: [wlet
-{ $syntax "[wlet | binding1 [ body1... ]\n        binding2 [ body2... ]\n        ... |\n     body... ]" }
-{ $description "Introduces a set of lexically-scoped non-recursive local functions. The bodies may not refer to other bindings within the same " { $link POSTPONE: [wlet } " form." }
-{ $examples
-    { $example
-        "USING: locals math prettyprint sequences ;"
-        "IN: scratchpad"
-        ":: quuxify ( n seq -- newseq )"
-        "    [wlet | add-n [| m | m n + ] |"
-        "        seq [ add-n ] map ] ;"
-        "2 { 1 2 3 } quuxify ."
-        "{ 3 4 5 }"
-    }
-} ;
-
 HELP: :>
-{ $syntax ":> var" ":> var!" }
-{ $description "Binds the value on the top of the datastack to a new local variable named " { $snippet "var" } ", lexically scoped to the enclosing quotation or definition."
+{ $syntax ":> var" ":> var!" ":> ( var-1 var-2 ... )" }
+{ $description "Binds one or more new local variables. In the " { $snippet ":> var" } " form, the value on the top of the datastack to a new local variable named " { $snippet "var" } ", lexically scoped to the enclosing quotation, " { $link POSTPONE: [let } " form, or " { $link POSTPONE: :: } " definition."
+$nl
+"The " { $snippet ":> ( var-1 ... )" } " form binds multiple local variables from the top of the datastack in left to right order. These two snippets would have the same effect:"
+{ $code ":> c :> b :> a" }
+{ $code ":> ( a b c )" }
 $nl
-"If the " { $snippet "var" } " name is followed by an exclamation point (" { $snippet "!" } "), the new variable will be mutable. See " { $link "locals-mutable" } " for more information on mutable local bindings." }
+"If any " { $snippet "var" } " name is followed by an exclamation point (" { $snippet "!" } "), that new variable will be mutable. See " { $link "locals-mutable" } " for more information on mutable local bindings." }
 { $notes
-    "This syntax can only be used inside a " { $link POSTPONE: :: } " word, " { $link POSTPONE: [let } ", " { $link POSTPONE: [let* } ",  or " { $link POSTPONE: [wlet } " form, or inside a quotation literal inside one of those forms."
-}
+    "This syntax can only be used inside a lexical scope established by a " { $link POSTPONE: :: } " definition, " { $link POSTPONE: [let } " form, or " { $link POSTPONE: [| } " quotation. Definition forms such as " { $link POSTPONE: : } " do not establish a lexical scope by themselves, nor is there a lexical scope available at the top level of source files or in the listener. To use local variable bindings in these situations, use " { $link POSTPONE: [let } " to provide a scope for them." }
 { $examples "See " { $link "locals-examples" } "." } ;
 
+{ POSTPONE: [let POSTPONE: :> } related-words
+
 HELP: ::
-{ $syntax ":: word ( bindings... -- outputs... ) body... ;" }
-{ $description "Defines a word with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope." }
+{ $syntax ":: word ( vars... -- outputs... ) body... ;" }
+{ $description "Defines a word with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope."
+$nl
+"If any of the " { $snippet "vars" } "' names is followed by an exclamation point (" { $snippet "!" } "), that variable will be mutable. See " { $link "locals-mutable" } " for more information on mutable local bindings." }
 { $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." }
 { $examples "See " { $link "locals-examples" } "." } ;
 
@@ -54,21 +39,27 @@ HELP: ::
 
 HELP: MACRO::
 { $syntax "MACRO:: word ( bindings... -- outputs... ) body... ;" }
-{ $description "Defines a macro with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope." }
+{ $description "Defines a macro with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope."
+$nl
+"If any of the " { $snippet "vars" } "' names is followed by an exclamation point (" { $snippet "!" } "), that variable will be mutable. See " { $link "locals-mutable" } " for more information on mutable local bindings." }
 { $examples "See " { $link "locals-examples" } "." } ;
 
 { POSTPONE: MACRO: POSTPONE: MACRO:: } related-words
 
 HELP: MEMO::
 { $syntax "MEMO:: word ( bindings... -- outputs... ) body... ;" }
-{ $description "Defines a macro with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope." }
+{ $description "Defines a memoized word with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope."
+$nl
+"If any of the " { $snippet "vars" } "' names is followed by an exclamation point (" { $snippet "!" } "), that variable will be mutable. See " { $link "locals-mutable" } " for more information on mutable local bindings." }
 { $examples "See " { $link "locals-examples" } "." } ;
 
 { POSTPONE: MEMO: POSTPONE: MEMO:: } related-words
                                           
 HELP: M::
 { $syntax "M:: class generic ( bindings... -- outputs... ) body... ;" }
-{ $description "Defines a macro with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope." }
+{ $description "Defines a new method on " { $snippet "generic" } " for " { $snippet "class" } " with named inputs; it reads datastack values into local variable bindings from left to right, then executes the body with those bindings in lexical scope."
+$nl
+"If any of the " { $snippet "vars" } "' names is followed by an exclamation point (" { $snippet "!" } "), that variable will be mutable. See " { $link "locals-mutable" } " for more information on mutable local bindings." }
 { $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." }
 { $examples "See " { $link "locals-examples" } "." } ;
 
@@ -86,14 +77,13 @@ IN: scratchpad
 """2.0
 -3.0"""
 }
-{ $snippet "quadratic-roots" } " can also be expressed with " { $link POSTPONE: [let } ":"
+"If you wanted to perform the quadratic formula interactively from the listener, you could use " { $link POSTPONE: [let } " to provide a scope for the local variables:"
 { $example """USING: locals math math.functions kernel ;
 IN: scratchpad
-:: quadratic-roots ( a b c -- x y )
-    [let | disc [ b sq 4 a c * * - sqrt ] |
-        b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@
-    ] ;
-1.0 1.0 -6.0 quadratic-roots [ . ] bi@"""
+[let 1.0 :> a 1.0 :> b -6.0 :> c
+    b sq 4 a c * * - sqrt :> disc
+    b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@
+] [ . ] bi@"""
 """2.0
 -3.0"""
 }
@@ -216,11 +206,11 @@ $nl
 "One exception to the above rule is that array instances containing free local variables (that is, immutable local variables not referenced in a closure) do retain identity. This allows macros such as " { $link cond } " to recognize that the array is constant and expand at compile time." ;
 
 ARTICLE: "locals-mutable" "Mutable locals"
-"In the list of bindings supplied to " { $link POSTPONE: :: } ", " { $link POSTPONE: [let } ", " { $link POSTPONE: [let* } " or " { $link POSTPONE: [| } ", a mutable binding may be introduced by suffixing its named with " { $snippet "!" } ". Mutable bindings are read by giving their name as usual; the suffix is not part of the binding's name. To write to a mutable binding, use the binding's name with the " { $snippet "!" } " suffix."
+"Whenever a local 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 "!" } ") when it is bound. The variable's value can be 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 the ML language; each mutable binding is actually an immutable binding of a mutable cell (in Factor's case, a 1-element array); reading the binding automatically dereferences the array, and writing to the binding stores into the array."
 $nl
-"Writing to mutable locals in outer scopes is fully supported and has the expected semantics. See " { $link "locals-examples" } " for examples of mutable local variables in action." ;
+"Writing to mutable locals in outer scopes is fully supported and has full closure semantics. See " { $link "locals-examples" } " for examples of mutable local variables in action." ;
 
 ARTICLE: "locals-fry" "Locals and fry"
 "Locals integrate with " { $link "fry" } " so that mixing locals with fried quotations gives intuitive results."
@@ -296,12 +286,10 @@ ARTICLE: "locals" "Lexical variables and closures"
     POSTPONE: MEMO::
     POSTPONE: MACRO::
 }
-"Lexical binding forms:"
+"Lexical scoping and binding forms:"
 { $subsections
-    POSTPONE: :>
     POSTPONE: [let
-    POSTPONE: [let*
-    POSTPONE: [wlet
+    POSTPONE: :>
 }
 "Quotation literals where the inputs are named local variables:"
 { $subsections POSTPONE: [| }
index 63b6d68feb3a4131eb5ed4415711ad754c67c48a..581ed5de33329912f4acbbf9710b790346cdc833 100644 (file)
@@ -26,58 +26,35 @@ IN: locals.tests
 [ { 5 6 7 } ] [ { 1 2 3 } 4 map-test-2 ] unit-test
 
 :: let-test ( c -- d )
-    [let | a [ 1 ] b [ 2 ] | a b + c + ] ;
+    [let 1 :> a 2 :> b a b + c + ] ;
 
 [ 7 ] [ 4 let-test ] unit-test
 
 :: let-test-2 ( a -- a )
-    a [let | a [ ] | [let | b [ a ] | a ] ] ;
+    a [let :> a [let a :> b a ] ] ;
 
 [ 3 ] [ 3 let-test-2 ] unit-test
 
 :: let-test-3 ( a -- a )
-    a [let | a [ ] | [let | b [ [ a ] ] | [let | a [ 3 ] | b ] ] ] ;
+    a [let :> a [let [ a ] :> b [let 3 :> a b ] ] ] ;
 
 :: let-test-4 ( a -- b )
-    a [let | a [ 1 ] b [ ] | a b 2array ] ;
+    a [let 1 :> a :> b a b 2array ] ;
 
 [ { 1 2 } ] [ 2 let-test-4 ] unit-test
 
 :: let-test-5 ( a b -- b )
-    a b [let | a [ ] b [ ] | a b 2array ] ;
+    a b [let :> a :> b a b 2array ] ;
 
 [ { 2 1 } ] [ 1 2 let-test-5 ] unit-test
 
 :: let-test-6 ( a -- b )
-    a [let | a [ ] b [ 1 ] | a b 2array ] ;
+    a [let :> a 1 :> b a b 2array ] ;
 
 [ { 2 1 } ] [ 2 let-test-6 ] unit-test
 
 [ -1 ] [ -1 let-test-3 call ] unit-test
 
-[ 5 ] [
-    [let | a [ 3 ] | [wlet | func [ a + ] | 2 func ] ]
-] unit-test
-
-:: wlet-test-2 ( a b -- seq )
-    [wlet | add-b [ b + ] |
-        a [ add-b ] map ] ;
-
-
-[ { 4 5 6 } ] [ { 2 3 4 } 2 wlet-test-2 ] unit-test
-    
-:: wlet-test-3 ( a -- b )
-    [wlet | add-a [ a + ] | [ add-a ] ]
-    [let | a [ 3 ] | a swap call ] ;
-
-[ 5 ] [ 2 wlet-test-3 ] unit-test
-
-:: wlet-test-4 ( a -- b )
-    [wlet | sub-a [| b | b a - ] |
-        3 sub-a ] ;
-
-[ -7 ] [ 10 wlet-test-4 ] unit-test
-
 :: write-test-1 ( n! -- q )
     [| i | n i + dup n! ] ;
 
@@ -94,8 +71,7 @@ IN: locals.tests
 [ 5 ] [ 2 "q" get call ] unit-test
 
 :: write-test-2 ( -- q )
-    [let | n! [ 0 ] |
-        [| i | n i + dup n! ] ] ;
+    [let 0 :> n! [| i | n i + dup n! ] ] ;
 
 write-test-2 "q" set
 
@@ -116,17 +92,11 @@ write-test-2 "q" set
 
 [ ] [ 1 2 write-test-3 call ] unit-test
 
-:: write-test-4 ( x! -- q ) [ [let | y! [ 0 ] | f x! ] ] ;
+:: write-test-4 ( x! -- q ) [ [let 0 :> y! f x! ] ] ;
 
 [ ] [ 5 write-test-4 drop ] unit-test
 
-! Not really a write test; just enforcing consistency
-:: write-test-5 ( x -- y )
-    [wlet | fun! [ x + ] | 5 fun! ] ;
-
-[ 9 ] [ 4 write-test-5 ] unit-test
-
-:: let-let-test ( n -- n ) [let | n [ n 3 + ] | n ] ;
+:: let-let-test ( n -- n ) [let n 3 + :> n n ] ;
 
 [ 13 ] [ 10 let-let-test ] unit-test
 
@@ -164,18 +134,12 @@ M:: string lambda-generic ( a b -- c ) a b lambda-generic-2 ;
 
 [ ] [ \ lambda-generic see ] unit-test
 
-:: unparse-test-1 ( a -- ) [let | a! [ 3 ] | ] ;
+:: unparse-test-1 ( a -- ) [let 3 :> a! 4 :> b ] ;
 
-[ "[let | a! [ 3 ] | ]" ] [
+[ "[let 3 :> a! 4 :> b ]" ] [
     \ unparse-test-1 "lambda" word-prop body>> first unparse
 ] unit-test
 
-:: unparse-test-2 ( -- ) [wlet | a! [ ] | ] ;
-
-[ "[wlet | a! [ ] | ]" ] [
-    \ unparse-test-2 "lambda" word-prop body>> first unparse
-] unit-test
-
 :: unparse-test-3 ( -- b ) [| a! | ] ;
 
 [ "[| a! | ]" ] [
@@ -198,38 +162,6 @@ DEFER: xyzzy
 
 [ 5 ] [ 10 xyzzy ] unit-test
 
-:: let*-test-1 ( a -- b )
-    [let* | b [ a 1 + ]
-            c [ b 1 + ] |
-        a b c 3array ] ;
-
-[ { 1 2 3 } ] [ 1 let*-test-1 ] unit-test
-
-:: let*-test-2 ( a -- b )
-    [let* | b [ a 1 + ]
-            c! [ b 1 + ] |
-        a b c 3array ] ;
-
-[ { 1 2 3 } ] [ 1 let*-test-2 ] unit-test
-
-:: let*-test-3 ( a -- b )
-    [let* | b [ a 1 + ]
-            c! [ b 1 + ] |
-        c 1 + c!  a b c 3array ] ;
-
-[ { 1 2 4 } ] [ 1 let*-test-3 ] unit-test
-
-:: let*-test-4 ( a b -- c d )
-    [let | a [ b ]
-           b [ a ] |
-        [let* | a'  [ a  ]
-                a'' [ a' ]
-                b'  [ b  ]
-                b'' [ b' ] |
-            a'' b'' ] ] ;
-
-[ "xxx" "yyy" ] [ "yyy" "xxx" let*-test-4 ] unit-test
-
 GENERIC: next-method-test ( a -- b )
 
 M: integer next-method-test 3 + ;
@@ -244,11 +176,11 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ;
 
 { 3 0 } [| a b c | ] must-infer-as
 
-[ ] [ 1 [let | a [ ] | ] ] unit-test
+[ ] [ 1 [let :> a ] ] unit-test
 
-[ 3 ] [ 1 [let | a [ ] | 3 ] ] unit-test
+[ 3 ] [ 1 [let :> a 3 ] ] unit-test
 
-[ ] [ 1 2 [let | a [ ] b [ ] | ] ] unit-test
+[ ] [ 1 2 [let :> a :> b ] ] unit-test
 
 :: a-word-with-locals ( a b -- ) ;
 
@@ -306,10 +238,10 @@ M:: sequence method-with-locals ( a -- y ) a reverse ;
 [ t ] [ 12 &&-test ] unit-test
 
 :: let-and-cond-test-1 ( -- a )
-    [let | a [ 10 ] |
-        [let | a [ 20 ] |
+    [let 10 :> a
+        [let 20 :> a
             {
-                { [ t ] [ [let | c [ 30 ] | a ] ] }
+                { [ t ] [ [let 30 :> c a ] ] }
             } cond
         ]
     ] ;
@@ -319,8 +251,8 @@ M:: sequence method-with-locals ( a -- y ) a reverse ;
 [ 20 ] [ let-and-cond-test-1 ] unit-test
 
 :: let-and-cond-test-2 ( -- pair )
-    [let | A [ 10 ] |
-        [let | B [ 20 ] |
+    [let 10 :> A
+        [let 20 :> B
             { { [ t ] [ { A B } ] } } cond
         ]
     ] ;
@@ -333,7 +265,7 @@ M:: sequence method-with-locals ( a -- y ) a reverse ;
 [ { 10 20    } ] [ 10 20    [| a b   | { a b   } ] call ] unit-test
 [ { 10 20 30 } ] [ 10 20 30 [| a b c | { a b c } ] call ] unit-test
 
-[ { 10 20 30 } ] [ [let | a [ 10 ] b [ 20 ] c [ 30 ] | { a b c } ] ] unit-test
+[ { 10 20 30 } ] [ [let 10 :> a 20 :> b 30 :> c { a b c } ] ] unit-test
 
 [ V{ 10 20 30 } ] [ 10 20 30 [| a b c | V{ a b c } ] call ] unit-test
 
@@ -453,7 +385,7 @@ M:: integer lambda-method-forget-test ( a -- b ) a ;
 [ 10 ] [ 10 [| A | { [ A ] } ] call first call ] unit-test
 
 [
-    "USING: locals fry math ; 1 '[ [let | A [ 10 ] | A _ + ] ]"
+    "USING: locals fry math ; 1 '[ [let 10 :> A A _ + ] ]"
     eval( -- ) call
 ] [ error>> >r/r>-in-fry-error? ] must-fail-with
     
@@ -465,10 +397,7 @@ M:: integer lambda-method-forget-test ( a -- b ) a ;
 [ t ] [ 3 funny-macro-test ] unit-test
 [ f ] [ 2 funny-macro-test ] unit-test
 
-! Some odd parser corner cases
 [ "USE: locals [let" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
-[ "USE: locals [let |" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
-[ "USE: locals [let | a" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
 [ "USE: locals [|" eval( -- ) ] [ error>> unexpected-eof? ] must-fail-with
 
 [ 25 ] [ 5 [| a | { [ a sq ] } cond ] call ] unit-test
@@ -484,15 +413,9 @@ M:: integer lambda-method-forget-test ( a -- b ) a ;
 
 [ 3 ] [ 3 [| a | \ a ] call ] unit-test
 
-[ "USE: locals [| | { [let | a [ 0 ] | a ] } ]" eval( -- ) ] must-fail
+[ "USE: locals [| | { [let 0 :> a a ] } ]" eval( -- ) ] must-fail
 
-[ "USE: locals [| | { [wlet | a [ 0 ] | a ] } ]" eval( -- ) ] must-fail
-
-[ "USE: locals [| | { [let* | a [ 0 ] | a ] } ]" eval( -- ) ] must-fail
-
-[ "USE: locals [| | [let | a! [ 0 ] | { a! } ] ]" eval( -- ) ] must-fail
-
-[ "USE: locals [| | [wlet | a [ 0 ] | { a } ] ]" eval( -- ) ] must-fail
+[ "USE: locals [| | [let 0 :> a! { a! } ] ]" eval( -- ) ] must-fail
 
 [ "USE: locals [| | { :> a } ]" eval( -- ) ] must-fail
 
@@ -504,27 +427,14 @@ M:: integer lambda-method-forget-test ( a -- b ) a ;
 
 [ 3 ] [ 2 [| | :> a! a 1 + a! a ] call ] unit-test
 
-:: wlet-&&-test ( a -- ? )
-    [wlet | is-integer? [ a integer? ]
-            is-even? [ a even? ]
-            >10? [ a 10 > ] |
-        { [ is-integer? ] [ is-even? ] [ >10? ] } &&
-    ] ;
-
-\ wlet-&&-test def>> must-infer
-[ f ] [ 1.5 wlet-&&-test ] unit-test
-[ f ] [ 3 wlet-&&-test ] unit-test
-[ f ] [ 8 wlet-&&-test ] unit-test
-[ t ] [ 12 wlet-&&-test ] unit-test
-
 : fry-locals-test-1 ( -- n )
-    [let | | 6 '[ [let | A [ 4 ] | A _ + ] ] call ] ;
+    [let 6 '[ [let 4 :> A A _ + ] ] call ] ;
 
 \ fry-locals-test-1 def>> must-infer
 [ 10 ] [ fry-locals-test-1 ] unit-test
 
 :: fry-locals-test-2 ( -- n )
-    [let | | 6 '[ [let | A [ 4 ] | A _ + ] ] call ] ;
+    [let 6 '[ [let 4 :> A A _ + ] ] call ] ;
 
 \ fry-locals-test-2 def>> must-infer
 [ 10 ] [ fry-locals-test-2 ] unit-test
@@ -542,18 +452,18 @@ M:: integer lambda-method-forget-test ( a -- b ) a ;
 ] unit-test
 
 [ 10 ] [
-    [| | 0 '[ [let | A [ 10 ] | A _ + ] ] call ] call
+    [| | 0 '[ [let 10 :> A A _ + ] ] call ] call
 ] unit-test
 
 ! littledan found this problem
-[ "bar" ] [ [let | a [ [let | foo [ "bar" ] | foo ] ] | a ] ] unit-test
-[ 10 ] [ [let | a [ 10 ] | [let | b [ a ] | b ] ] ] unit-test
+[ "bar" ] [ [let [let "bar" :> foo foo ] :> a a ] ] unit-test
+[ 10 ] [ [let 10 :> a [let a :> b b ] ] ] unit-test
 
-[ { \ + } ] [ [let | x [ \ + ] | { \ x } ] ] unit-test
+[ { \ + } ] [ [let \ + :> x { \ x } ] ] unit-test
 
-[ { \ + 3 } ] [ [let | a [ 3 ] | { \ + a } ] ] unit-test
+[ { \ + 3 } ] [ [let 3 :> a { \ + a } ] ] unit-test
 
-[ 3 ] [ [let | a [ \ + ] | 1 2 [ \ a execute ] ] call ] unit-test
+[ 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 ;
@@ -578,3 +488,6 @@ M: integer ed's-bug neg ;
    { [ a ed's-bug ] } && ;
 
 [ t ] [ \ ed's-test-case optimized? ] unit-test
+
+! multiple bind
+[ 3 1 2 ] [ [let 1 2 3 :> ( a b c ) c a b ] ] unit-test
index aa0a064c0d0eee3b57ae7c85f3db8ae83976c249..8e940bfdd8b8100fb9eedc68c0253e0b8411d795 100644 (file)
@@ -7,16 +7,12 @@ IN: locals
 
 SYNTAX: :>
     scan locals get [ :>-outside-lambda-error ] unless*
-    [ make-local ] bind <def> suffix! ;
+    parse-def suffix! ;
 
 SYNTAX: [| parse-lambda append! ;
 
 SYNTAX: [let parse-let append! ;
 
-SYNTAX: [let* parse-let* append! ;
-
-SYNTAX: [wlet parse-wlet append! ;
-
 SYNTAX: :: (::) define-declared ;
 
 SYNTAX: M:: (M::) define ;
index 2b52c53eb5a792eebdbc4d4a4b225c41729b0052..e64693f2a364588820836f4a08215cfcf6cd2aec 100644 (file)
@@ -7,13 +7,11 @@ M: lambda expand-macros clone [ expand-macros ] change-body ;
 
 M: lambda expand-macros* expand-macros literal ;
 
-M: binding-form expand-macros
-    clone
-        [ [ expand-macros ] assoc-map ] change-bindings
-        [ expand-macros ] change-body ;
+M: let expand-macros
+    clone [ expand-macros ] change-body ;
 
-M: binding-form expand-macros* expand-macros literal ;
+M: let expand-macros* expand-macros literal ;
 
 M: lambda condomize? drop t ;
 
-M: lambda condomize '[ @ ] ;
\ No newline at end of file
+M: lambda condomize '[ @ ] ;
index 8cfe45d1ba7e53e1265b693c2168342e5da4b5ee..c0184ee0efed1be229a01e3eee80d41f813b478b 100644 (file)
@@ -46,6 +46,12 @@ SYMBOL: locals
     (parse-lambda) <lambda>
     ?rewrite-closures ;
 
+: parse-multi-def ( locals -- multi-def )
+    ")" parse-tokens swap [ [ make-local ] map ] bind <multi-def> ;
+
+: parse-def ( name/paren locals -- def )
+    over "(" = [ nip parse-multi-def ] [ [ make-local ] bind <def> ] if ;
+
 M: lambda-parser parse-quotation ( -- quotation )
     H{ } clone (parse-lambda) ;
 
@@ -56,48 +62,8 @@ M: lambda-parser parse-quotation ( -- quotation )
         [ nip scan-object 2array ]
     } cond ;
 
-: (parse-bindings) ( end -- )
-    dup parse-binding dup [
-        first2 [ make-local ] dip 2array ,
-        (parse-bindings)
-    ] [ 2drop ] if ;
-
-: with-bindings ( quot -- words assoc )
-    '[
-        in-lambda? on
-        _ H{ } make-assoc
-    ] { } make swap ; inline
-
-: parse-bindings ( end -- bindings vars )
-    [ (parse-bindings) ] with-bindings ;
-
 : parse-let ( -- form )
-    "|" expect "|" parse-bindings
-    (parse-lambda) <let> ?rewrite-closures ;
-
-: parse-bindings* ( end -- words assoc )
-    [
-        namespace use-words
-        (parse-bindings)
-        namespace unuse-words
-    ] with-bindings ;
-
-: parse-let* ( -- form )
-    "|" expect "|" parse-bindings*
-    (parse-lambda) <let*> ?rewrite-closures ;
-
-: (parse-wbindings) ( end -- )
-    dup parse-binding dup [
-        first2 [ make-local-word ] keep 2array ,
-        (parse-wbindings)
-    ] [ 2drop ] if ;
-
-: parse-wbindings ( end -- bindings vars )
-    [ (parse-wbindings) ] with-bindings ;
-
-: parse-wlet ( -- form )
-    "|" expect "|" parse-wbindings
-    (parse-lambda) <wlet> ?rewrite-closures ;
+    H{ } clone (parse-lambda) <let> ?rewrite-closures ;
 
 : parse-locals ( -- effect vars assoc )
     complete-effect
@@ -121,4 +87,4 @@ M: lambda-parser parse-quotation ( -- quotation )
     [
         [ parse-definition ] 
         parse-locals-definition drop
-    ] with-method-definition ;
\ No newline at end of file
+    ] with-method-definition ;
index 187b663c3c60f9888da19da695a3072d22926b13..b0fbebbf31a8cf892d1a4dba322f1c6a853fe182 100644 (file)
@@ -27,22 +27,17 @@ M: lambda pprint*
 
 : pprint-let ( let word -- )
     pprint-word
-    [ body>> ] [ bindings>> ] bi
-    \ | pprint-word
-    t <inset
-    <block
-    [ <block [ pprint-var ] dip pprint* block> ] assoc-each
-    block>
-    \ | pprint-word
-    <block pprint-elements block>
-    block>
+    <block body>> pprint-elements block>
     \ ] pprint-word ;
 
 M: let pprint* \ [let pprint-let ;
 
-M: wlet pprint* \ [wlet pprint-let ;
-
-M: let* pprint* \ [let* pprint-let ;
-
 M: def pprint*
-    <block \ :> pprint-word local>> pprint-word block> ;
+    dup local>> word?
+    [ <block \ :> pprint-word local>> pprint-var block> ]
+    [ pprint-tuple ] if ;
+
+M: multi-def pprint*
+    dup locals>> [ word? ] all?
+    [ <block \ :> pprint-word "(" text locals>> [ pprint-var ] each ")" text block> ]
+    [ pprint-tuple ] if ;
index c1bde9312ec1d032d78515fc8000f0bdd9255354..a8a12d2614d86c3e353e44e93ca76db7d9e3db76 100755 (executable)
@@ -6,7 +6,7 @@ locals.errors locals.types make quotations sequences vectors
 words ;
 IN: locals.rewrite.sugar
 
-! Step 1: rewrite [| [let [let* [wlet into :> forms, turn
+! Step 1: rewrite [| into :> forms, turn
 ! literals with locals in them into code which constructs
 ! the literal after pushing locals on the stack
 
@@ -73,7 +73,7 @@ M: quotation rewrite-element rewrite-sugar* ;
 
 M: lambda rewrite-element rewrite-sugar* ;
 
-M: binding-form rewrite-element binding-form-in-literal-error ;
+M: let rewrite-element let-form-in-literal-error ;
 
 M: local rewrite-element , ;
 
@@ -104,6 +104,8 @@ M: tuple rewrite-sugar* rewrite-element ;
 
 M: def rewrite-sugar* , ;
 
+M: multi-def rewrite-sugar* locals>> <reversed> [ <def> , ] each ;
+
 M: hashtable rewrite-sugar* rewrite-element ;
 
 M: wrapper rewrite-sugar*
@@ -115,17 +117,5 @@ M: word rewrite-sugar*
 
 M: object rewrite-sugar* , ;
 
-: let-rewrite ( body bindings -- )
-    [ quotation-rewrite % <def> , ] assoc-each
-    quotation-rewrite % ;
-
 M: let rewrite-sugar*
-    [ body>> ] [ bindings>> ] bi let-rewrite ;
-
-M: let* rewrite-sugar*
-    [ body>> ] [ bindings>> ] bi let-rewrite ;
-
-M: wlet rewrite-sugar*
-    [ body>> ] [ bindings>> ] bi
-    [ '[ _ ] ] assoc-map
-    let-rewrite ;
+    body>> quotation-rewrite % ;
index 3ed753e094c9cda310b37fde12adf41f56c6f991..424ef682439edad6faaa049f2aec34366b09533c 100644 (file)
@@ -8,20 +8,10 @@ TUPLE: lambda vars body ;
 
 C: <lambda> lambda
 
-TUPLE: binding-form bindings body ;
-
-TUPLE: let < binding-form ;
+TUPLE: let body ;
 
 C: <let> let
 
-TUPLE: let* < binding-form ;
-
-C: <let*> let*
-
-TUPLE: wlet < binding-form ;
-
-C: <wlet> wlet
-
 TUPLE: quote local ;
 
 C: <quote> quote
@@ -32,6 +22,10 @@ TUPLE: def local ;
 
 C: <def> def
 
+TUPLE: multi-def locals ;
+
+C: <multi-def> multi-def
+
 PREDICATE: local < word "local?" word-prop ;
 
 : <local> ( name -- word )
index f3d039e54ad4a3632479f02138f09dc1868d655e..75b9be5caec547429b2ff10422bf45dafa9c6e97 100644 (file)
@@ -16,7 +16,7 @@ IN: math.matrices
 :: rotation-matrix3 ( axis theta -- matrix )
     theta cos :> c
     theta sin :> s
-    axis first3 :> z :> y :> x
+    axis first3 :> ( x y z )
     x sq 1.0 x sq - c * +     x y * 1.0 c - * z s * -   x z * 1.0 c - * y s * + 3array
     x y * 1.0 c - * z s * +   y sq 1.0 y sq - c * +     y z * 1.0 c - * x s * - 3array
     x z * 1.0 c - * y s * -   y z * 1.0 c - * x s * +   z sq 1.0 z sq - c * +   3array
@@ -25,14 +25,14 @@ IN: math.matrices
 :: rotation-matrix4 ( axis theta -- matrix )
     theta cos :> c
     theta sin :> s
-    axis first3 :> z :> y :> x
+    axis first3 :> ( x y z )
     x sq 1.0 x sq - c * +     x y * 1.0 c - * z s * -   x z * 1.0 c - * y s * +   0 4array
     x y * 1.0 c - * z s * +   y sq 1.0 y sq - c * +     y z * 1.0 c - * x s * -   0 4array
     x z * 1.0 c - * y s * -   y z * 1.0 c - * x s * +   z sq 1.0 z sq - c * +     0 4array
     { 0.0 0.0 0.0 1.0 } 4array ;
 
 :: translation-matrix4 ( offset -- matrix )
-    offset first3 :> z :> y :> x
+    offset first3 :> ( x y z )
     {
         { 1.0 0.0 0.0 x   }
         { 0.0 1.0 0.0 y   }
@@ -44,7 +44,7 @@ IN: math.matrices
     dup number? [ dup dup ] [ first3 ] if ;
 
 :: scale-matrix3 ( factors -- matrix )
-    factors >scale-factors :> z :> y :> x
+    factors >scale-factors :> ( x y z )
     {
         { x   0.0 0.0 }
         { 0.0 y   0.0 }
@@ -52,7 +52,7 @@ IN: math.matrices
     } ;
 
 :: scale-matrix4 ( factors -- matrix )
-    factors >scale-factors :> z :> y :> x
+    factors >scale-factors :> ( x y z )
     {
         { x   0.0 0.0 0.0 }
         { 0.0 y   0.0 0.0 }
@@ -64,7 +64,7 @@ IN: math.matrices
     [ recip ] map scale-matrix4 ;
 
 :: frustum-matrix4 ( xy-dim near far -- matrix )
-    xy-dim first2 :> y :> x
+    xy-dim first2 :> ( x y )
     near x /f :> xf
     near y /f :> yf
     near far + near far - /f :> zf
index b0dfc4ed35900a66f23282e534f8feb8d1342dbb..04b1330cc2e0bec710355bf32b387d812a28fa5f 100755 (executable)
@@ -8,7 +8,7 @@ IN: math.primes.miller-rabin
 
 :: (miller-rabin) ( n trials -- ? )
     n 1 - :> n-1
-    n-1 factor-2s :> s :> r
+    n-1 factor-2s :> ( r s )
     0 :> a!
     trials [
         drop
index a4f90ce938dbb93567254755a87c31ed6a15c12c..fd58b11dc8a31526fc5498bec4721355e9a18da0 100644 (file)
@@ -81,8 +81,8 @@ ERROR: bad-vconvert-input value expected-type ;
 PRIVATE>
 
 MACRO:: vconvert ( from-type to-type -- )
-    from-type new [ element-type ] [ byte-length ] bi :> from-length :> from-element
-    to-type   new [ element-type ] [ byte-length ] bi :> to-length   :> to-element
+    from-type new [ element-type ] [ byte-length ] bi :> ( from-element from-length )
+    to-type   new [ element-type ] [ byte-length ] bi :> ( to-element   to-length   )
     from-element heap-size :> from-size
     to-element   heap-size :> to-size   
 
index 7803c009547cbcde14c6ac3a394138b10407940c..7ba9f243cefd7327d72a7384675df0cd248b6dab 100644 (file)
@@ -391,8 +391,8 @@ TUPLE: inconsistent-vector-test bool branch ;
     2dup = [ drop ] [ inconsistent-vector-test boa ] if ;
 
 :: test-vector-tests ( vector decl -- none? any? all? )
-    vector decl test-vector-tests-bool :> bool-all :> bool-any :> bool-none
-    vector decl test-vector-tests-branch :> branch-all :> branch-any :> branch-none
+    vector decl test-vector-tests-bool :> ( bool-none bool-any bool-all )
+    vector decl test-vector-tests-branch :> ( branch-none branch-any branch-all )
     
     bool-none branch-none ?inconsistent
     bool-any  branch-any  ?inconsistent
index f52dc8a3b0a3c29f887936acf2cc9c4a121a694c..c26866e83b41630c9311ca14921e9bb368520bc7 100644 (file)
@@ -27,11 +27,12 @@ TUPLE: an-observer { i integer } ;
 M: an-observer model-changed nip [ 1 + ] change-i drop ;\r
 \r
 [ 1 0 ] [\r
-    [let* | m1 [ 1 <model> ]\r
-            m2 [ 2 <model> ]\r
-            c [ { m1 m2 } <product> ]\r
-            o1 [ an-observer new ]\r
-            o2 [ an-observer new ] |\r
+    [let\r
+        1 <model> :> m1\r
+        2 <model> :> m2\r
+        { m1 m2 } <product> :> c\r
+        an-observer new :> o1\r
+        an-observer new :> o2\r
         \r
         o1 m1 add-connection\r
         o2 m2 add-connection\r
index cdf68cebd35720a2223ec0e23039587dbb672f22..513ed912e46e6dc13bbe21a06866412295996a64 100755 (executable)
@@ -95,8 +95,8 @@ MACRO: all-enabled-client-state ( seq quot -- )
     #! We use GL_LINE_STRIP with a duplicated first vertex
     #! instead of GL_LINE_LOOP to work around a bug in Apple's
     #! X3100 driver.
-    loc first2 :> y :> x
-    dim first2 :> h :> w
+    loc first2 :> ( x y )
+    dim first2 :> ( w h )
     [
         x 0.5 +     y 0.5 +
         x w + 0.3 - y 0.5 +
@@ -115,8 +115,8 @@ MACRO: all-enabled-client-state ( seq quot -- )
     rect-vertices (gl-rect) ;
 
 :: (fill-rect-vertices) ( loc dim -- vertices )
-    loc first2 :> y :> x
-    dim first2 :> h :> w
+    loc first2 :> ( x y )
+    dim first2 :> ( w h )
     [
         x      y
         x w +  y
index d846afe3a90cb492ed63bc47703b7c102203e94e..e53383c98bf9899215e6eebf58e0dcdd449825eb 100755 (executable)
@@ -278,7 +278,7 @@ TUPLE: single-texture < disposable image dim loc texture-coords texture display-
     ] unless ;
 
 :: tex-image ( image bitmap -- )
-    image image-format :> type :> format :> internal-format
+    image image-format :> ( internal-format format type )
     GL_TEXTURE_2D 0 internal-format
     image dim>> adjust-texture-dim first2 0
     format type bitmap glTexImage2D ;
index a7fd07a5ecb0abc47899447ec30f157c3a0adf04..5ddd5f9bf08e04699ac9ce3bdf16b145553b762d 100644 (file)
@@ -445,16 +445,16 @@ M: ebnf-sequence build-locals ( code ast -- code )
       drop \r
     ] [ \r
       [\r
-        "FROM: locals => [let* ; FROM: sequences => nth ; [let* | " %\r
-          dup length swap [\r
-            dup ebnf-var? [\r
+        "FROM: locals => [let :> ; FROM: sequences => nth ; [let " %\r
+          dup length [\r
+            over ebnf-var? [\r
+              " " % # " over nth :> " %\r
               name>> % \r
-              " [ " % # " over nth ] " %\r
             ] [\r
               2drop\r
             ] if\r
           ] 2each\r
-          " " %\r
+          " " %\r
           %  \r
           " nip ]" %     \r
       ] "" make \r
@@ -463,9 +463,9 @@ M: ebnf-sequence build-locals ( code ast -- code )
 \r
 M: ebnf-var build-locals ( code ast -- )\r
   [\r
-    "FROM: locals => [let* ; FROM: kernel => dup nip ; [let* | " %\r
-    name>> % " [ dup ] " %\r
-    " " %\r
+    "FROM: locals => [let :> ; FROM: kernel => dup nip ; [let " %\r
+    " dup :> " % name>> %\r
+    " " %\r
     %  \r
     " nip ]" %     \r
   ] "" make ;\r
index 4a247a8a0fffb0e581bb6d90fb627f53ec925ab3..d4397627e809d216665762b075b8360e0d837d33 100644 (file)
@@ -172,9 +172,7 @@ TUPLE: peg-head rule-id involved-set eval-set ;
   l lrstack get (setup-lr) ;
 
 :: lr-answer ( r p m -- ast )
-  [let* |
-          h [ m ans>> head>> ]
-        |
+    m ans>> head>> :> h
     h rule-id>> r rule-id eq? [
       m ans>> seed>> m (>>ans)
       m ans>> failed? [
@@ -184,14 +182,11 @@ TUPLE: peg-head rule-id involved-set eval-set ;
       ] if
     ] [
       m ans>> seed>>
-    ] if
-  ] ; inline
+    ] if ; inline
 
 :: recall ( r p -- memo-entry )
-  [let* |
-          m [ p r rule-id memo ]
-          h [ p heads at ]
-        |
+    p r rule-id memo :> m
+    p heads at :> h
     h [
       m r rule-id h involved-set>> h rule-id>> suffix member? not and [
         fail p memo-entry boa
@@ -207,15 +202,12 @@ TUPLE: peg-head rule-id involved-set eval-set ;
       ] if
     ] [
       m
-    ] if
-  ] ; inline
+    ] if ; inline
 
 :: apply-non-memo-rule ( r p -- ast )
-  [let* |
-          lr  [ fail r rule-id f lrstack get left-recursion boa ]
-          m   [ lr lrstack set lr p memo-entry boa dup p r rule-id set-memo ]
-          ans [ r eval-rule ]
-        |
+    fail r rule-id f lrstack get left-recursion boa :> lr
+    lr lrstack set lr p memo-entry boa dup p r rule-id set-memo :> m
+    r eval-rule :> ans
     lrstack get next>> lrstack set
     pos get m (>>pos)
     lr head>> [
@@ -226,8 +218,7 @@ TUPLE: peg-head rule-id involved-set eval-set ;
     ] [
       ans m (>>ans)
       ans
-    ] if
-  ] ; inline
+    ] if ; inline
 
 : apply-memo-rule ( r m -- ast )
   [ ans>> ] [ pos>> ] bi pos set
@@ -622,20 +613,19 @@ PRIVATE>
 ERROR: parse-failed input word ;
 
 SYNTAX: PEG:
-  (:)
-  [let | effect [ ] def [ ] word [ ] |
-    [
-      [
-        [let | compiled-def [ def call compile ] |
+    [let
+        (:) :> ( word def effect )
+        [
           [
-            dup compiled-def compiled-parse
-            [ ast>> ] [ word parse-failed ] ?if
-          ]
-          word swap effect define-declared
-        ]
-      ] with-compilation-unit
-    ] append!
-  ] ;
+            def call compile :> compiled-def
+            [
+              dup compiled-def compiled-parse
+              [ ast>> ] [ word parse-failed ] ?if
+            ]
+            word swap effect define-declared
+          ] with-compilation-unit
+        ] append!
+    ] ;
 
 USING: vocabs vocabs.loader ;
 
index 4c764eba9331d2bbdfeeb407e41758b054a51ccd..d623e900192dd5e2696aa7cb67c4945b26c29298 100644 (file)
@@ -10,77 +10,70 @@ IN: persistent.hashtables.nodes.bitmap
 : index ( bit bitmap -- n ) [ 1 - ] dip bitand bit-count ; inline
 
 M:: bitmap-node (entry-at) ( key hashcode bitmap-node -- entry )
-    [let* | shift [ bitmap-node shift>> ]
-            bit [ hashcode shift bitpos ]
-            bitmap [ bitmap-node bitmap>> ]
-            nodes [ bitmap-node nodes>> ] |
-       bitmap bit bitand 0 eq? [ f ] [
-           key hashcode
-           bit bitmap index nodes nth-unsafe
-           (entry-at)
-        ] if
-    ] ;
+    bitmap-node shift>> :> shift
+    hashcode shift bitpos :> bit
+    bitmap-node bitmap>> :> bitmap
+    bitmap-node nodes>> :> nodes
+    bitmap bit bitand 0 eq? [ f ] [
+        key hashcode
+        bit bitmap index nodes nth-unsafe
+        (entry-at)
+    ] if ;
 
 M:: bitmap-node (new-at) ( shift value key hashcode bitmap-node -- node' added-leaf )
-    [let* | shift [ bitmap-node shift>> ]
-            bit [ hashcode shift bitpos ]
-            bitmap [ bitmap-node bitmap>> ]
-            idx [ bit bitmap index ]
-            nodes [ bitmap-node nodes>> ] |
-        bitmap bit bitand 0 eq? [
-            [let | new-leaf [ value key hashcode <leaf-node> ] |
-                bitmap bit bitor
-                new-leaf idx nodes insert-nth
-                shift
-                <bitmap-node>
-                new-leaf
-            ]
+    bitmap-node shift>> :> shift
+    hashcode shift bitpos :> bit
+    bitmap-node bitmap>> :> bitmap
+    bit bitmap index :> idx
+    bitmap-node nodes>> :> nodes
+
+    bitmap bit bitand 0 eq? [
+        value key hashcode <leaf-node> :> new-leaf
+        bitmap bit bitor
+        new-leaf idx nodes insert-nth
+        shift
+        <bitmap-node>
+        new-leaf
+    ] [
+        idx nodes nth :> n
+        shift radix-bits + value key hashcode n (new-at) :> ( n' new-leaf )
+        n n' eq? [
+            bitmap-node
         ] [
-            [let | n [ idx nodes nth ] |
-                shift radix-bits + value key hashcode n (new-at)
-                [let | new-leaf [ ] n' [ ] |
-                    n n' eq? [
-                        bitmap-node
-                    ] [
-                        bitmap
-                        n' idx nodes new-nth
-                        shift
-                        <bitmap-node>
-                    ] if
-                    new-leaf
-                ]
-            ]
+            bitmap
+            n' idx nodes new-nth
+            shift
+            <bitmap-node>
         ] if
-    ] ;
+        new-leaf
+    ] if ;
 
 M:: bitmap-node (pluck-at) ( key hashcode bitmap-node -- node' )
-    [let | bit [ hashcode bitmap-node shift>> bitpos ]
-           bitmap [ bitmap-node bitmap>> ]
-           nodes [ bitmap-node nodes>> ]
-           shift [ bitmap-node shift>> ] |
-           bit bitmap bitand 0 eq? [ bitmap-node ] [
-            [let* | idx [ bit bitmap index ]
-                    n [ idx nodes nth-unsafe ]
-                    n' [ key hashcode n (pluck-at) ] |
-                n n' eq? [
-                    bitmap-node
-                ] [
-                    n' [
-                        bitmap
-                        n' idx nodes new-nth
-                        shift
-                        <bitmap-node>
-                    ] [
-                        bitmap bit eq? [ f ] [
-                            bitmap bit bitnot bitand
-                            idx nodes remove-nth
-                            shift
-                            <bitmap-node>
-                        ] if
-                    ] if
+    hashcode bitmap-node shift>> bitpos :> bit
+    bitmap-node bitmap>> :> bitmap
+    bitmap-node nodes>> :> nodes
+    bitmap-node shift>> :> shift
+    bit bitmap bitand 0 eq? [ bitmap-node ] [
+        bit bitmap index :> idx
+        idx nodes nth-unsafe :> n
+        key hashcode n (pluck-at) :> n'
+        n n' eq? [
+            bitmap-node
+        ] [
+            n' [
+                bitmap
+                n' idx nodes new-nth
+                shift
+                <bitmap-node>
+            ] [
+                bitmap bit eq? [ f ] [
+                    bitmap bit bitnot bitand
+                    idx nodes remove-nth
+                    shift
+                    <bitmap-node>
                 ] if
-            ]
+            ] if
         ] if
-    ] ;
+    ] if ;
 
 M: bitmap-node >alist% ( node -- ) nodes>> >alist-each% ;
index 2ee4008f2b437ce7e159f474a8ae7cd4bacaade4..3d1612862a3b46d9d0059bceeafef770048f1538 100644 (file)
@@ -15,43 +15,39 @@ M:: collision-node (entry-at) ( key hashcode collision-node -- leaf-node )
 
 M:: collision-node (pluck-at) ( key hashcode collision-node -- leaf-node )
     hashcode collision-node hashcode>> eq? [
-        [let | idx [ key hashcode collision-node find-index drop ] |
-            idx [
-                idx collision-node leaves>> smash [
-                    collision-node hashcode>>
-                    <collision-node>
-                ] when
-            ] [ collision-node ] if
-        ]
+        key hashcode collision-node find-index drop :> idx
+        idx [
+            idx collision-node leaves>> smash [
+                collision-node hashcode>>
+                <collision-node>
+            ] when
+        ] [ collision-node ] if
     ] [ collision-node ] if ;
 
 M:: collision-node (new-at) ( shift value key hashcode collision-node -- node' added-leaf )
     hashcode collision-node hashcode>> eq? [
-        key hashcode collision-node find-index
-        [let | leaf-node [ ] idx [ ] |
-            idx [
-                value leaf-node value>> = [
-                    collision-node f
-                ] [
-                    hashcode
-                    value key hashcode <leaf-node>
-                    idx
-                    collision-node leaves>>
-                    new-nth
-                    <collision-node>
-                    f
-                ] if
+        key hashcode collision-node find-index :> ( idx leaf-node )
+        idx [
+            value leaf-node value>> = [
+                collision-node f
             ] [
-                [let | new-leaf-node [ value key hashcode <leaf-node> ] |
-                    hashcode
-                    collision-node leaves>>
-                    new-leaf-node
-                    suffix
-                    <collision-node>
-                    new-leaf-node
-                ]
+                hashcode
+                value key hashcode <leaf-node>
+                idx
+                collision-node leaves>>
+                new-nth
+                <collision-node>
+                f
             ] if
-        ]
+        ] [
+            value key hashcode <leaf-node> :> new-leaf-node
+            hashcode
+            collision-node leaves>>
+            new-leaf-node
+            suffix
+            <collision-node>
+            new-leaf-node
+        ] if
     ] [
         shift collision-node value key hashcode make-bitmap-node
     ] if ;
index 5c60c91dca39aa53d91fe2139264226e83496f45..5a9cc2506d2fe79e6fc1e92c00d13f710c347866 100644 (file)
@@ -8,39 +8,37 @@ persistent.hashtables.nodes ;
 IN: persistent.hashtables.nodes.full
 
 M:: full-node (new-at) ( shift value key hashcode full-node -- node' added-leaf )
-    [let* | nodes [ full-node nodes>> ] 
-            idx [ hashcode full-node shift>> mask ]
-            n [ idx nodes nth-unsafe ] |
-        shift radix-bits + value key hashcode n (new-at)
-        [let | new-leaf [ ] n' [ ] |
-            n n' eq? [
-                full-node
-            ] [
-                n' idx nodes new-nth shift <full-node>
-            ] if
-            new-leaf
-        ]
-    ] ;
+    full-node nodes>> :> nodes
+    hashcode full-node shift>> mask :> idx
+    idx nodes nth-unsafe :> n
+
+    shift radix-bits + value key hashcode n (new-at) :> ( n' new-leaf )
+    n n' eq? [
+        full-node
+    ] [
+        n' idx nodes new-nth shift <full-node>
+    ] if
+    new-leaf ;
 
 M:: full-node (pluck-at) ( key hashcode full-node -- node' )
-    [let* | idx [ hashcode full-node shift>> mask ]
-            n [ idx full-node nodes>> nth ]
-            n' [ key hashcode n (pluck-at) ] |
-        n n' eq? [
-            full-node
+    hashcode full-node shift>> mask :> idx
+    idx full-node nodes>> nth :> n
+    key hashcode n (pluck-at) :> n'
+
+    n n' eq? [
+        full-node
+    ] [
+        n' [
+            n' idx full-node nodes>> new-nth
+            full-node shift>>
+            <full-node>
         ] [
-            n' [
-                n' idx full-node nodes>> new-nth
-                full-node shift>>
-                <full-node>
-            ] [
-                hashcode full-node shift>> bitpos bitnot full-bitmap-mask bitand
-                idx full-node nodes>> remove-nth
-                full-node shift>>
-                <bitmap-node>
-            ] if
+            hashcode full-node shift>> bitpos bitnot full-bitmap-mask bitand
+            idx full-node nodes>> remove-nth
+            full-node shift>>
+            <bitmap-node>
         ] if
-    ] ;
+    ] if ;
 
 M:: full-node (entry-at) ( key hashcode full-node -- node' )
     key hashcode
index 94174d566704019b34a6c976b27d3546f8791616..0a15ea6305f11ff4969ec6c2f8f9d0cd17953ed3 100644 (file)
@@ -19,10 +19,9 @@ M:: leaf-node (new-at) ( shift value key hashcode leaf-node -- node' added-leaf
             value leaf-node value>> =
             [ leaf-node f ] [ value key hashcode <leaf-node> f ] if
         ] [
-            [let | new-leaf [ value key hashcode <leaf-node> ] |
-                hashcode leaf-node new-leaf 2array <collision-node>
-                new-leaf
-            ]
+            value key hashcode <leaf-node> :> new-leaf
+            hashcode leaf-node new-leaf 2array <collision-node>
+            new-leaf
         ] if
     ] [ shift leaf-node value key hashcode make-bitmap-node ] if ;
 
index a692f707780f239754fe7570ce116f580f304542..35edcf328af1afea0b564a3eceb95a087c715df5 100644 (file)
@@ -46,7 +46,7 @@ GENERIC: nfa-node ( node -- start-state end-state )
     epsilon nfa-table get add-transition ;
 
 M:: star nfa-node ( node -- start end )
-    node term>> nfa-node :> s1 :> s0
+    node term>> nfa-node :> ( s0 s1 )
     next-state :> s2
     next-state :> s3
     s1 s0 epsilon-transition
index 8cddac5a752e52e8871da9048d071a166811d325..62a9526e20e7a8ccf1b975fbfb0d32a3d841c999 100644 (file)
@@ -192,17 +192,17 @@ M: bad-executable summary
 
 \ load-local [ infer-load-local ] "special" set-word-prop
 
-: infer-get-local ( -- )
-    [let* | n [ pop-literal nip 1 swap - ]
-            in-r [ n consume-r ]
-            out-d [ in-r first copy-value 1array ]
-            out-r [ in-r copy-values ] |
-         out-d output-d
-         out-r output-r
-         f out-d in-r out-r
-         out-r in-r zip out-d first in-r first 2array suffix
-         #shuffle,
-    ] ;
+:: infer-get-local ( -- )
+    pop-literal nip 1 swap - :> n
+    n consume-r :> in-r
+    in-r first copy-value 1array :> out-d
+    in-r copy-values :> out-r
+
+    out-d output-d
+    out-r output-r
+    f out-d in-r out-r
+    out-r in-r zip out-d first in-r first 2array suffix
+    #shuffle, ;
 
 \ get-local [ infer-get-local ] "special" set-word-prop
 
index 610a664c7b85f6542e6c3038051d0ee7bf20892f..79aad20b856b0e875dbdf222b96b43b530b7de37 100644 (file)
@@ -32,13 +32,12 @@ yield
 [ [ 3 throw ] "A" suspend ] [ 3 = ] must-fail-with
 
 :: spawn-namespace-test ( -- ? )
-    [let | p [ <promise> ] g [ gensym ] |
-        [
-            g "x" set
-            [ "x" get p fulfill ] "B" spawn drop
-        ] with-scope
-        p ?promise g eq?
-    ] ;
+    <promise> :> p gensym :> g
+    [
+        g "x" set
+        [ "x" get p fulfill ] "B" spawn drop
+    ] with-scope
+    p ?promise g eq? ;
 
 [ t ] [ spawn-namespace-test ] unit-test
 
index 80113607d42c44349ddd35607d737130f8ec8273..2ab74bf7359b3f19e212484c0357b069043ce0ea 100644 (file)
@@ -6,26 +6,25 @@ namespaces namespaces.private assocs accessors ;
 IN: tools.walker.debug
 
 :: test-walker ( quot -- data )
-    [let | p [ <promise> ] |
-        [
-            H{ } clone >n
+    <promise> :> p
+    [
+        H{ } clone >n
 
-            [
-                p promise-fulfilled?
-                [ drop ] [ p fulfill ] if
-                2drop
-            ] show-walker-hook set
+        [
+            p promise-fulfilled?
+            [ drop ] [ p fulfill ] if
+            2drop
+        ] show-walker-hook set
 
-            break
+        break
 
-            quot call
-        ] "Walker test" spawn drop
+        quot call
+    ] "Walker test" spawn drop
 
-        step-into-all
-        p ?promise
-        send-synchronous drop
+    step-into-all
+    p ?promise
+    send-synchronous drop
 
-        p ?promise
-        variables>> walker-continuation swap at
-        value>> data>>
-    ] ;
+    p ?promise
+    variables>> walker-continuation swap at
+    value>> data>> ;
index 5cab884b3c4c7eb6bba2702a971fd048c7d943e0..ea0487c703525e8c9b311ebdf8f7e5484e3ca269 100755 (executable)
@@ -76,10 +76,9 @@ ducet insert-helpers
     drop [ 0 ] unless* tail-slice ;\r
 \r
 :: ?combine ( char slice i -- ? )\r
-    [let | str [ i slice nth char suffix ] |\r
-        str ducet key? dup\r
-        [ str i slice set-nth ] when\r
-    ] ;\r
+    i slice nth char suffix :> str\r
+    str ducet key? dup\r
+    [ str i slice set-nth ] when ;\r
 \r
 : add ( char -- )\r
     dup blocked? [ 1string , ] [\r
index afe24905d69ba11c18cd227bf64b1d40ee46a90a..11792d91a72320eb80065fdcd0d7e6bd0ee12a31 100644 (file)
@@ -48,18 +48,17 @@ ERROR: unix-error errno message ;
 ERROR: unix-system-call-error args errno message word ;
 
 MACRO:: unix-system-call ( quot -- )
-    [let | n [ quot infer in>> ]
-           word [ quot first ] |
-        [
-            n ndup quot call dup 0 < [
-                drop
-                n narray
-                errno dup strerror
-                word unix-system-call-error
-            ] [
-                n nnip
-            ] if
-        ]
+    quot infer in>> :> n
+    quot first :> word
+    [
+        n ndup quot call dup 0 < [
+            drop
+            n narray
+            errno dup strerror
+            word unix-system-call-error
+        ] [
+            n nnip
+        ] if
     ] ;
 
 HOOK: open-file os ( path flags mode -- fd )
index 3c0509c49d1a8c4a606fbdea48dd9720ff75bfa7..adbf29dfdd90099dceb74a69d12ab5d46d33929a 100755 (executable)
@@ -56,13 +56,12 @@ M: array array-base-type first ;
     DIOBJECTDATAFORMAT <struct-boa> ;
 
 :: make-DIOBJECTDATAFORMAT-array ( struct array -- alien )
-    [let | alien [ array length malloc-DIOBJECTDATAFORMAT-array ] |
-        array [| args i |
-            struct args <DIOBJECTDATAFORMAT>
-            i alien set-nth
-        ] each-index
-        alien
-    ] ;
+    array length malloc-DIOBJECTDATAFORMAT-array :> alien
+    array [| args i |
+        struct args <DIOBJECTDATAFORMAT>
+        i alien set-nth
+    ] each-index
+    alien ;
 
 : <DIDATAFORMAT> ( dwFlags dwDataSize struct rgodf-array -- alien )
     [ DIDATAFORMAT heap-size DIOBJECTDATAFORMAT heap-size ] 4 ndip
index 9e0c50a37d40ffbfcc667cba82043572fc7c38de..376c9b3f0ccf8ff1a68804f943f5e809a6e5ac7c 100644 (file)
@@ -74,12 +74,12 @@ $nl
 "Here is an example of the locals version:"
 { $example
 """USING: locals urls xml.syntax xml.writer ;
-[let |
-    number [ 3 ]
-    false [ f ]
-    url [ URL" http://factorcode.org/" ]
-    string [ "hello" ]
-    word [ \\ drop ] |
+[let
+    3 :> number
+    f :> false
+    URL" http://factorcode.org/" :> url
+    "hello" :> string
+    \\ drop :> word
     <XML
         <x
             number=<-number->
index 5c1669adb101671a65c1c1291a9107a590424a6f..40c86237a781d80cce2796156da86652fb761876 100644 (file)
@@ -54,8 +54,7 @@ XML-NS: foo http://blah.com
   y
   <foo/>
 </x>""" ] [
-    [let* | a [ "one" ] c [ "two" ] x [ "y" ]
-           d [ [XML <-x-> <foo/> XML] ] |
+    [let "one" :> a "two" :> c "y" :> x [XML <-x-> <foo/> XML] :> d
         <XML
             <x> <-a-> <b val=<-c->/> <-d-> </x>
         XML> pprint-xml>string
index 14ebcb1c5b4e50bfbda653b63b6928af992f14a5..92715dc9c727eacafda7400228b8c49bc42cf6ce 100755 (executable)
@@ -7,25 +7,24 @@ IN: benchmark.beust2
 
 :: (count-numbers) ( remaining first value used max listener: ( -- ) -- ? )
     10 first - iota [| i |
-        [let* | digit [ i first + ]
-                mask [ digit 2^ ]
-                value' [ i value + ] |
-            used mask bitand zero? [
-                value max > [ t ] [
-                    remaining 1 <= [
-                        listener call f
-                    ] [
-                        remaining 1 -
-                        0
-                        value' 10 *
-                        used mask bitor
-                        max
-                        listener
-                        (count-numbers)
-                    ] if
+        i first + :> digit
+        digit 2^ :> mask
+        i value + :> value'
+        used mask bitand zero? [
+            value max > [ t ] [
+                remaining 1 <= [
+                    listener call f
+                ] [
+                    remaining 1 -
+                    0
+                    value' 10 *
+                    used mask bitor
+                    max
+                    listener
+                    (count-numbers)
                 ] if
-            ] [ f ] if
-        ]
+            ] if
+        ] [ f ] if
     ] any? ; inline recursive
 
 :: count-numbers ( max listener -- )
@@ -33,9 +32,8 @@ IN: benchmark.beust2
     inline
 
 :: beust ( -- )
-    [let | i! [ 0 ] |
-        5000000000 [ i 1 + i! ] count-numbers
-        i number>string " unique numbers." append print
-    ] ;
+    0 :> i!
+    5000000000 [ i 1 + i! ] count-numbers
+    i number>string " unique numbers." append print ;
 
 MAIN: beust
index 1ad769173bb8c4c5291c46cad2212fd79dfb4879..5ba285dbb18343441d63a89938a359b913571ace 100755 (executable)
@@ -71,37 +71,35 @@ CONSTANT: homo-sapiens
     [ make-random-fasta ] 2curry split-lines ; inline
 
 :: make-repeat-fasta ( k len alu -- k' )
-    [let | kn [ alu length ] |
-        len [ k + kn mod alu nth-unsafe ] "" map-as print
-        k len +
-    ] ; inline
+    alu length :> kn
+    len [ k + kn mod alu nth-unsafe ] "" map-as print
+    k len + ; inline
 
 : write-repeat-fasta ( n alu desc id -- )
     write-description
-    [let | k! [ 0 ] alu [ ] |
+    [let
+        :> alu
+        0 :> k!
         [| len | k len alu make-repeat-fasta k! ] split-lines
     ] ; inline
 
 : fasta ( n out -- )
     homo-sapiens make-cumulative
     IUB make-cumulative
-    [let | homo-sapiens-floats [ ]
-           homo-sapiens-chars [ ]
-           IUB-floats [ ]
-           IUB-chars [ ]
-           out [ ]
-           n [ ]
-           seed [ initial-seed ] |
+    [let
+        :> ( n out IUB-chars IUB-floats homo-sapiens-chars homo-sapiens-floats )
+        initial-seed :> seed
 
         out ascii [
             n 2 * ALU "Homo sapiens alu" "ONE" write-repeat-fasta
 
             initial-seed
-            n 3 * homo-sapiens-chars homo-sapiens-floats "IUB ambiguity codes" "TWO" write-random-fasta
-            n 5 * IUB-chars IUB-floats "Homo sapiens frequency" "THREE" write-random-fasta
+            n 3 * homo-sapiens-chars homo-sapiens-floats
+            "IUB ambiguity codes" "TWO" write-random-fasta
+            n 5 * IUB-chars IUB-floats
+            "Homo sapiens frequency" "THREE" write-random-fasta
             drop
         ] with-file-writer
-
     ] ;
 
 : run-fasta ( -- ) 2500000 reverse-complement-in fasta ;
index bd13de32c744f8a6aeba3bc9cb6339d923ed4c48..024887991e9af4a12865846bd3cafecc2b994a84 100644 (file)
@@ -17,20 +17,19 @@ STRUCT: yuv_buffer
     { v void* } ;
 
 :: fake-data ( -- rgb yuv )
-    [let* | w [ 1600 ]
-            h [ 1200 ]
-            buffer [ yuv_buffer <struct> ]
-            rgb [ w h * 3 * <byte-array> ] |
-        rgb buffer
-            w >>y_width
-            h >>y_height
-            h >>uv_height
-            w >>y_stride
-            w >>uv_stride
-            w h * [ dup * ] B{ } map-as malloc-byte-array &free >>y
-            w h * 2/ [ dup dup * * ] B{ } map-as malloc-byte-array &free >>u
-            w h * 2/ [ dup * dup * ] B{ } map-as malloc-byte-array &free >>v
-    ] ;
+    1600 :> w
+    1200 :> h
+    yuv_buffer <struct> :> buffer
+    w h * 3 * <byte-array> :> rgb
+    rgb buffer
+        w >>y_width
+        h >>y_height
+        h >>uv_height
+        w >>y_stride
+        w >>uv_stride
+        w h * [ dup * ] B{ } map-as malloc-byte-array &free >>y
+        w h * 2/ [ dup dup * * ] B{ } map-as malloc-byte-array &free >>u
+        w h * 2/ [ dup * dup * ] B{ } map-as malloc-byte-array &free >>v ;
 
 : clamp ( n -- n )
     255 min 0 max ; inline
index 0807420266dd2ace7573f7688c7306907fe40452..a5a6709c6d61c2d555ecbf68560cc3a1ca208fd4 100644 (file)
@@ -61,37 +61,33 @@ CONSTANT: AES_BLOCK_SIZE 16
     bitor bitor bitor 32 bits ;
 
 :: set-t ( T i -- )
-    [let* |
-        a1 [ i sbox nth ]
-        a2 [ a1 xtime ]
-        a3 [ a1 a2 bitxor ] |
-            a2 a1 a1 a3 ui32 i T set-nth
-            a3 a2 a1 a1 ui32 i HEX: 100 + T set-nth
-            a1 a3 a2 a1 ui32 i HEX: 200 + T set-nth
-            a1 a1 a3 a2 ui32 i HEX: 300 + T set-nth
-        ] ;
+    i sbox nth :> a1
+    a1 xtime :> a2
+    a1 a2 bitxor :> a3
 
+    a2 a1 a1 a3 ui32 i T set-nth
+    a3 a2 a1 a1 ui32 i HEX: 100 + T set-nth
+    a1 a3 a2 a1 ui32 i HEX: 200 + T set-nth
+    a1 a1 a3 a2 ui32 i HEX: 300 + T set-nth ;
 
 MEMO:: t-table ( -- array )
     1024 0 <array>
     dup 256 [ set-t ] with each ;
 
 :: set-d ( D i -- )
-    [let* |
-        a1 [ i inv-sbox nth ]
-        a2 [ a1 xtime ]
-        a4 [ a2 xtime ]
-        a8 [ a4 xtime ]
-        a9 [ a8 a1 bitxor ]
-        ab [ a9 a2 bitxor ]
-        ad [ a9 a4 bitxor ]
-        ae [ a8 a4 a2 bitxor bitxor ]
-        |
-            ae a9 ad ab ui32 i D set-nth
-            ab ae a9 ad ui32 i HEX: 100 + D set-nth
-            ad ab ae a9 ui32 i HEX: 200 + D set-nth
-            a9 ad ab ae ui32 i HEX: 300 + D set-nth
-        ] ;
+    i inv-sbox nth :> a1
+    a1 xtime :> a2
+    a2 xtime :> a4
+    a4 xtime :> a8
+    a8 a1 bitxor :> a9
+    a9 a2 bitxor :> ab
+    a9 a4 bitxor :> ad
+    a8 a4 a2 bitxor bitxor :> ae
+
+    ae a9 ad ab ui32 i D set-nth
+    ab ae a9 ad ui32 i HEX: 100 + D set-nth
+    ad ab ae a9 ui32 i HEX: 200 + D set-nth
+    a9 ad ab ae ui32 i HEX: 300 + D set-nth ;
     
 MEMO:: d-table ( -- array )
     1024 0 <array>
index 30650c1e401daa806ef75eeb5e84cf6631359f9c..f5219e7a3ffe4a58213f8e48d09ddb450e1f9a93 100644 (file)
@@ -17,28 +17,29 @@ IN: crypto.passwd-md5
 PRIVATE>
 
 :: passwd-md5 ( magic salt password -- bytes )
-    [let* | final! [ password magic salt 3append
-                salt password tuck 3append md5 checksum-bytes
-                password length
-                [ 16 / ceiling swap <repetition> concat ] keep
-                head-slice append
-                password [ length make-bits ] [ first ] bi
-                '[ CHAR: \0 _ ? ] "" map-as append
-                md5 checksum-bytes ] |
-        1000 [
-            "" swap
-            {
-                [ 0 bit? password final ? append ]
-                [ 3 mod 0 > [ salt append ] when ]
-                [ 7 mod 0 > [ password append ] when ]
-                [ 0 bit? final password ? append ]
-            } cleave md5 checksum-bytes final!
-        ] each
+    password magic salt 3append
+    salt password tuck 3append md5 checksum-bytes
+    password length
+    [ 16 / ceiling swap <repetition> concat ] keep
+    head-slice append
+    password [ length make-bits ] [ first ] bi
+    '[ CHAR: \0 _ ? ] "" map-as append
+    md5 checksum-bytes :> final!
 
-        magic salt "$" 3append
-        { 12 0 6 13 1 7 14 2 8 15 3 9 5 4 10 } final nths 3 group
-        [ first3 [ 16 shift ] [ 8 shift ] bi* + + 4 to64 ] map concat
-        11 final nth 2 to64 3append ] ;
+    1000 iota [
+        "" swap
+        {
+            [ 0 bit? password final ? append ]
+            [ 3 mod 0 > [ salt append ] when ]
+            [ 7 mod 0 > [ password append ] when ]
+            [ 0 bit? final password ? append ]
+        } cleave md5 checksum-bytes final!
+    ] each
+
+    magic salt "$" 3append
+    { 12 0 6 13 1 7 14 2 8 15 3 9 5 4 10 } final nths 3 group
+    [ first3 [ 16 shift ] [ 8 shift ] bi* + + 4 to64 ] map concat
+    11 final nth 2 to64 3append ;
         
 : parse-shadow-password ( string -- magic salt password )
     "$" split harvest first3 [ "$" tuck 3append ] 2dip ;
index 8ca9ea91c51e9f816afec21f60f10427d283b635..cc12b4fed1822ec35349bd18b52de74a9c554d35 100644 (file)
@@ -75,8 +75,8 @@ M: decimal before?
 
 :: D/ ( D1 D2 a -- D3 )
     D1 D2 guard-decimals 2drop
-    D1 >decimal< :> e1 :> m1
-    D2 >decimal< :> e2 :> m2
+    D1 >decimal< :> ( m1 e1 )
+    D2 >decimal< :> ( m2 e2 )
     m1 a 10^ *
     m2 /i
     
diff --git a/extra/dns/cache/nx/nx.factor b/extra/dns/cache/nx/nx.factor
deleted file mode 100644 (file)
index 9904f85..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-USING: kernel assocs locals combinators
-       math math.functions system unicode.case ;
-
-IN: dns.cache.nx
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: nx-cache ( -- table ) H{ } ;
-
-: nx-cache-at        (      name -- time ) >lower nx-cache at        ;
-: nx-cache-delete-at (      name --      ) >lower nx-cache delete-at ;
-: nx-cache-set-at    ( time name --      ) >lower nx-cache set-at    ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: now ( -- seconds ) millis 1000.0 / round >integer ;
-
-:: non-existent-name? ( NAME -- ? )
-   [let | TIME [ NAME nx-cache-at ] |
-     {
-       { [ TIME f    = ] [                         f ] }
-       { [ TIME now <= ] [ NAME nx-cache-delete-at f ] }
-       { [ t           ] [                         t ] }
-     }
-     cond
-   ] ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-:: cache-non-existent-name ( NAME TTL -- )
-   [let | TIME [ TTL now + ] | TIME NAME nx-cache-set-at ] ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
diff --git a/extra/dns/cache/rr/rr.factor b/extra/dns/cache/rr/rr.factor
deleted file mode 100644 (file)
index cb80190..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-
-USING: kernel sequences assocs sets locals combinators
-       accessors system math math.functions unicode.case prettyprint
-       combinators.smart dns ;
-
-IN: dns.cache.rr
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: <entry> time data ;
-
-: now ( -- seconds ) millis 1000.0 / round >integer ;
-
-: expired? ( <entry> -- ? ) time>> now <= ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: make-cache-key ( obj -- key )
-  [ [ name>> >lower ] [ type>> ] [ class>> ] tri ] output>array ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: cache ( -- table ) H{ } ;
-
-: cache-at     (     obj -- ent ) make-cache-key cache at ;
-: cache-delete (     obj --     ) make-cache-key cache delete-at ;
-: cache-set-at ( ent obj --     ) make-cache-key cache set-at ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-:: cache-get ( OBJ -- rrs/f )
-   [let | ENT [ OBJ cache-at ] |
-     {
-       { [ ENT f =      ] [                  f ] }
-       { [ ENT expired? ] [ OBJ cache-delete f ] }
-       {
-         [ t ]
-         [
-           [let | NAME  [ OBJ name>>       ]
-                  TYPE  [ OBJ type>>       ]
-                  CLASS [ OBJ class>>      ]
-                  TTL   [ ENT time>> now - ] |
-             ENT data>>
-               [| RDATA | T{ rr f NAME TYPE CLASS TTL RDATA } ]
-             map
-           ]
-         ]
-       }
-     }
-     cond
-   ] ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-:: cache-add ( RR -- )
-   [let | ENT   [ RR cache-at    ]
-          TIME  [ RR ttl>> now + ]
-          RDATA [ RR rdata>>     ] |
-     {
-       { [ ENT f =      ] [ T{ <entry> f TIME V{ RDATA } } RR cache-set-at ] }
-       { [ ENT expired? ] [ RR cache-delete RR cache-add                   ] }
-       { [ t            ] [ TIME ENT (>>time) RDATA ENT data>> adjoin      ] }
-     }
-     cond
-   ] ;
\ No newline at end of file
diff --git a/extra/dns/dns.factor b/extra/dns/dns.factor
deleted file mode 100644 (file)
index f16664f..0000000
+++ /dev/null
@@ -1,501 +0,0 @@
-
-USING: kernel byte-arrays combinators strings arrays sequences splitting
-       grouping
-       math math.functions math.parser random
-       destructors
-       io io.binary io.sockets io.encodings.binary
-       accessors
-       combinators.smart
-       assocs
-       ;
-
-IN: dns
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: query name type class ;
-
-TUPLE: rr name type class ttl rdata ;
-
-TUPLE: hinfo cpu os ;
-
-TUPLE: mx preference exchange ;
-
-TUPLE: soa mname rname serial refresh retry expire minimum ;
-
-TUPLE: message
-       id qr opcode aa tc rd ra z rcode
-       question-section
-       answer-section
-       authority-section
-       additional-section ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: random-id ( -- id ) 2 16 ^ random ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! TYPE
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOLS: A NS MD MF CNAME SOA MB MG MR NULL WKS PTR HINFO MINFO MX TXT AAAA ;
-
-: type-table ( -- table )
-  {
-    { A     1 }
-    { NS    2 }
-    { MD    3 }
-    { MF    4 }
-    { CNAME 5 }
-    { SOA   6 }
-    { MB    7 }
-    { MG    8 }
-    { MR    9 }
-    { NULL  10 }
-    { WKS   11 }
-    { PTR   12 }
-    { HINFO 13 }
-    { MINFO 14 }
-    { MX    15 }
-    { TXT   16 }
-    { AAAA  28 }
-  } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! CLASS
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOLS: IN CS CH HS ;
-
-: class-table ( -- table )
-  {
-    { IN 1 }
-    { CS 2 }
-    { CH 3 }
-    { HS 4 }
-  } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! OPCODE
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOLS: QUERY IQUERY STATUS ;
-
-: opcode-table ( -- table )
-  {
-    { QUERY  0 }
-    { IQUERY 1 }
-    { STATUS 2 }
-  } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! RCODE
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOLS: NO-ERROR FORMAT-ERROR SERVER-FAILURE NAME-ERROR NOT-IMPLEMENTED
-         REFUSED ;
-
-: rcode-table ( -- table )
-  {
-    { NO-ERROR        0 }
-    { FORMAT-ERROR    1 }
-    { SERVER-FAILURE  2 }
-    { NAME-ERROR      3 }
-    { NOT-IMPLEMENTED 4 }
-    { REFUSED         5 }
-  } ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: <message> ( -- message )
-  message new
-    random-id >>id
-    0         >>qr
-    QUERY     >>opcode
-    0         >>aa
-    0         >>tc
-    1         >>rd
-    0         >>ra
-    0         >>z
-    NO-ERROR  >>rcode
-    { }       >>question-section
-    { }       >>answer-section
-    { }       >>authority-section
-    { }       >>additional-section ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: ip->ba ( ip -- ba ) "." split [ string>number ] map >byte-array ;
-
-: ipv6->ba ( ip -- ba ) ":" split [ 16 base> ] map [ 2 >be ] map concat ;
-
-: label->ba ( label -- ba ) [ >byte-array ] [ length ] bi prefix ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: uint8->ba  ( n -- ba ) 1 >be ;
-: uint16->ba ( n -- ba ) 2 >be ;
-: uint32->ba ( n -- ba ) 4 >be ;
-: uint64->ba ( n -- ba ) 8 >be ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: dn->ba ( dn -- ba ) "." split [ label->ba ] map concat ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: query->ba ( query -- ba )
-  [
-    {
-      [ name>>                 dn->ba ]
-      [ type>>  type-table  at uint16->ba ]
-      [ class>> class-table at uint16->ba ]
-    } cleave
-  ] output>array concat ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: hinfo->ba ( rdata -- ba )
-    [ cpu>> label->ba ]
-    [ os>>  label->ba ]
-  bi append ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: mx->ba ( rdata -- ba )
-    [ preference>> uint16->ba ]
-    [ exchange>>   dn->ba ]
-  bi append ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: soa->ba ( rdata -- ba )
-  [
-    {
-      [ mname>>   dn->ba ]
-      [ rname>>   dn->ba ]
-      [ serial>>  uint32->ba ]
-      [ refresh>> uint32->ba ]
-      [ retry>>   uint32->ba ]
-      [ expire>>  uint32->ba ]
-      [ minimum>> uint32->ba ]
-    } cleave
-  ] output>array concat ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: rdata->ba ( type rdata -- ba )
-  swap
-    {
-      { CNAME [ dn->ba ] }
-      { HINFO [ hinfo->ba ] }
-      { MX    [ mx->ba ] }
-      { NS    [ dn->ba ] }
-      { PTR   [ dn->ba ] }
-      { SOA   [ soa->ba ] }
-      { A     [ ip->ba ] }
-    }
-  case ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: rr->ba ( rr -- ba )
-  [
-    {
-      [ name>>                 dn->ba     ]
-      [ type>>  type-table  at uint16->ba ]
-      [ class>> class-table at uint16->ba ]
-      [ ttl>>   uint32->ba ]
-      [
-        [ type>>            ] [ rdata>> ] bi rdata->ba
-        [ length uint16->ba ] [         ] bi append
-      ]
-    } cleave
-  ] output>array concat ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: header-bits-ba ( message -- ba )
-  [
-    {
-      [ qr>>                     15 shift ]
-      [ opcode>> opcode-table at 11 shift ]
-      [ aa>>                     10 shift ]
-      [ tc>>                      9 shift ]
-      [ rd>>                      8 shift ]
-      [ ra>>                      7 shift ]
-      [ z>>                       4 shift ]
-      [ rcode>>  rcode-table at   0 shift ]
-    } cleave
-  ] sum-outputs uint16->ba ;
-
-: message->ba ( message -- ba )
-  [
-    {
-      [ id>> uint16->ba ]
-      [ header-bits-ba ]
-      [ question-section>>   length uint16->ba ]
-      [ answer-section>>     length uint16->ba ]
-      [ authority-section>>  length uint16->ba ]
-      [ additional-section>> length uint16->ba ]
-      [ question-section>>   [ query->ba ] map concat ]
-      [ answer-section>>     [ rr->ba    ] map concat ]
-      [ authority-section>>  [ rr->ba    ] map concat ]
-      [ additional-section>> [ rr->ba    ] map concat ]
-    } cleave
-  ] output>array concat ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-single ( ba i -- n ) at ;
-: get-double ( ba i -- n ) dup 2 + subseq be> ;
-: get-quad   ( ba i -- n ) dup 4 + subseq be> ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: label-length ( ba i -- length ) get-single ;
-
-: skip-label ( ba i -- ba i ) 2dup label-length + 1 + ;
-
-: null-label? ( ba i -- ? ) get-single 0 = ;
-
-: get-label ( ba i -- label ) [ 1 + ] [ skip-label nip ] 2bi subseq >string ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: bit-test ( a b -- ? ) bitand 0 = not ;
-
-: pointer? ( ba i -- ? ) get-single BIN: 11000000 bit-test ;
-
-: pointer ( ba i -- val ) get-double BIN: 0011111111111111 bitand ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: skip-name ( ba i -- ba i )
-    {
-      { [ 2dup null-label? ] [ 1 + ] }
-      { [ 2dup pointer?    ] [ 2 + ] }
-      { [ t ] [ skip-label skip-name ] }
-    }
-  cond ;
-
-: get-name ( ba i -- name )
-    {
-      { [ 2dup null-label? ] [ 2drop "" ] }
-      { [ 2dup pointer?    ] [ dupd pointer get-name ] }
-      {
-        [ t ]
-        [
-          [ get-label ]
-          [ skip-label get-name ]
-          2bi
-          "." glue 
-        ]
-      }
-    }
-  cond ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-query ( ba i -- query )
-    [ get-name ]
-    [
-      skip-name
-      [ 0 + get-double type-table  value-at ]
-      [ 2 + get-double class-table value-at ]
-      2bi
-    ]
-  2bi query boa ;
-
-: skip-query ( ba i -- ba i ) skip-name 4 + ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-mx ( ba i -- mx ) [ get-double ] [ 2 + get-double ] 2bi mx boa ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-soa ( ba i -- soa )
-    {
-      [           get-name ]
-      [ skip-name get-name ]
-      [
-        skip-name
-        skip-name
-        {
-          [  0 + get-quad ]
-          [  4 + get-quad ]
-          [  8 + get-quad ]
-          [ 12 + get-quad ]
-          [ 16 + get-quad ]
-        }
-          2cleave
-      ]
-    }
-  2cleave soa boa ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-ip ( ba i -- ip ) dup 4 + subseq >array [ number>string ] map "." join ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-ipv6 ( ba i -- ip )
-  dup 16 + subseq 2 group [ be> 16 >base ] map ":" join ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-rdata ( ba i type -- rdata )
-    {
-      { CNAME [ get-name ] }
-      { NS    [ get-name ] }
-      { PTR   [ get-name ] }
-      { MX    [ get-mx   ] }
-      { SOA   [ get-soa  ] }
-      { A     [ get-ip   ] }
-      { AAAA  [ get-ipv6 ] }
-    }
-  case ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-rr ( ba i -- rr )
-  [ get-name ]
-  [
-    skip-name
-      {
-        [ 0 + get-double type-table  value-at ]
-        [ 2 + get-double class-table value-at ]
-        [ 4 + get-quad   ]
-        [ [ 10 + ] [ get-double type-table value-at ] 2bi get-rdata ]
-      }
-    2cleave
-  ]
-    2bi rr boa ;
-
-: skip-rr ( ba i -- ba i ) skip-name 8 + 2dup get-double + 2 + ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-question-section ( ba i count -- seq ba i )
-  [ drop [ skip-query ] [ get-query ] 2bi ] map -rot ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-rr-section ( ba i count -- seq ba i )
-  [ drop [ skip-rr ] [ get-rr ] 2bi ] map -rot ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: >> ( x n -- y ) neg shift ;
-
-: get-header-bits ( ba i -- qr opcode aa tc rd ra z rcode )
-    get-double
-    {
-      [ 15 >> BIN:    1 bitand ]
-      [ 11 >> BIN:  111 bitand opcode-table value-at ]
-      [ 10 >> BIN:    1 bitand ]
-      [  9 >> BIN:    1 bitand ]
-      [  8 >> BIN:    1 bitand ]
-      [  7 >> BIN:    1 bitand ]
-      [  4 >> BIN:  111 bitand ]
-      [       BIN: 1111 bitand rcode-table value-at ]
-    }
-  cleave ;
-
-: parse-message ( ba -- message )
-  0
-  {
-    [ get-double ]
-    [ 2 + get-header-bits ]
-    [
-      4 +
-      {
-        [ 8 +            ]
-        [ 0 + get-double ]
-        [ 2 + get-double ]
-        [ 4 + get-double ]
-        [ 6 + get-double ]
-      }
-        2cleave
-      {
-        [ get-question-section ]
-        [ get-rr-section ]
-        [ get-rr-section ]
-        [ get-rr-section ]
-      } spread
-      2drop
-    ]
-  }
-    2cleave message boa ;
-
-: ba->message ( ba -- message ) parse-message ;
-
-: with-message-bytes ( ba quot -- ) [ ba->message ] dip call message->ba ; inline
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: send-receive-udp ( ba server -- ba )
-  f 0 <inet4> <datagram>
-    [
-      [ send ] [ receive drop ] bi
-    ]
-  with-disposal ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: send-receive-tcp ( ba server -- ba )
-  [ dup length 2 >be prepend ] [ ] bi*
-  binary
-    [
-      write flush
-      2 read be> read
-    ]
-  with-client ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: >dns-inet4 ( obj -- inet4 )
-  dup string?
-    [ 53 <inet4> ]
-    [            ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: ask-server ( message server -- message )
-  [ message->ba ] [ >dns-inet4 ] bi*
-  2dup
-  send-receive-udp parse-message
-  dup tc>> 1 =
-    [ drop send-receive-tcp parse-message ]
-    [ nip nip                             ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: dns-servers ( -- seq ) V{ } ;
-
-: dns-server ( -- server ) dns-servers random ;
-
-: ask ( message -- message ) dns-server ask-server ;
-
-: query->message ( query -- message ) <message> swap 1array >>question-section ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: message-query ( message -- query ) question-section>> first ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-ERROR: name-error name ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: fully-qualified ( name -- name )
-    {
-      { [ dup empty?         ] [ "." append ] }
-      { [ dup last CHAR: . = ] [            ] }
-      { [ t                  ] [ "." append ] }
-    }
-  cond ;
diff --git a/extra/dns/forwarding/forwarding.factor b/extra/dns/forwarding/forwarding.factor
deleted file mode 100644 (file)
index 4b7db30..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-
-USING: kernel sequences combinators accessors locals random
-       combinators.short-circuit
-       io.sockets
-       dns dns.util dns.cache.rr dns.cache.nx
-       dns.resolver ;
-
-IN: dns.forwarding
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-:: query->rrs ( QUERY -- rrs/f )
-   [let | RRS [ QUERY cache-get ] |
-     RRS
-       [ RRS ]
-       [
-         [let | NAME  [ QUERY name>>  ]
-                TYPE  [ QUERY type>>  ]
-                CLASS [ QUERY class>> ] |
-               
-           [let | RRS/CNAME [ T{ query f NAME CNAME CLASS } cache-get ] |
-
-             RRS/CNAME f =
-               [ f ]
-               [
-                 [let | RR/CNAME [ RRS/CNAME first ] |
-            
-                   [let | REAL-NAME [ RR/CNAME rdata>> ] |
-              
-                     [let | RRS [
-                                  T{ query f REAL-NAME TYPE CLASS } query->rrs
-                                ] |
-
-                       RRS
-                         [ RRS/CNAME RRS append ]
-                         [ f ]
-                       if
-                     ] ] ]
-               ]
-             if
-           ] ]
-       ]
-     if
-   ] ;
-
-:: answer-from-cache ( MSG -- msg/f )
-   [let | QUERY [ MSG message-query ] |
-
-     [let | NX  [ QUERY name>> non-existent-name? ]
-            RRS [ QUERY query->rrs                ] |
-
-       {
-         { [ NX  ] [ MSG NAME-ERROR >>rcode          ] }
-         { [ RRS ] [ MSG RRS        >>answer-section ] }
-         { [ t   ] [ f                               ] }
-       }
-       cond
-     ]
-   ] ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: message-soa ( message -- rr/soa )
-  authority-section>> [ type>> SOA = ] filter first ;
-
-! :: cache-message ( MSG -- msg )
-!    MSG rcode>> NAME-ERROR =
-!      [
-!        [let | NAME [ MSG message-query name>> ]
-!               TTL  [ MSG message-soa   ttl>>  ] |
-!          NAME TTL cache-non-existent-name
-!        ]
-!      ]
-!    when
-!    MSG answer-section>>     [ cache-add ] each
-!    MSG authority-section>>  [ cache-add ] each
-!    MSG additional-section>> [ cache-add ] each
-!    MSG ;
-
-:: cache-message ( MSG -- msg )
-   MSG rcode>> NAME-ERROR =
-     [
-       [let | RR/SOA [ MSG
-                         authority-section>>
-                         [ type>> SOA = ] filter
-                       dup empty? [ drop f ] [ first ] if ] |
-         RR/SOA
-           [
-             [let | NAME [ MSG message-query name>> ]
-                    TTL  [ MSG message-soa   ttl>>  ] |
-               NAME TTL cache-non-existent-name
-             ]
-           ]
-         when
-       ]
-     ]
-   when
-   MSG answer-section>>     [ cache-add ] each
-   MSG authority-section>>  [ cache-add ] each
-   MSG additional-section>> [ cache-add ] each
-   MSG ;
-
-! : answer-from-server ( msg servers -- msg ) random ask-server cache-message ;
-
-: answer-from-server ( msg servers -- msg ) ask-servers cache-message ;
-
-:: find-answer ( MSG SERVERS -- msg )
-   { [ MSG answer-from-cache ] [ MSG SERVERS answer-from-server ] } 0|| ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-:: start-server ( ADDR-SPEC SERVERS -- )
-
-  [let | SOCKET [ ADDR-SPEC <datagram> ] |
-
-    [
-      SOCKET receive-packet
-        [ parse-message SERVERS find-answer message->ba ]
-      change-data
-      respond
-    ]
-    forever
-
-  ] ;
diff --git a/extra/dns/misc/misc.factor b/extra/dns/misc/misc.factor
deleted file mode 100644 (file)
index 72f553c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-
-USING: kernel combinators sequences splitting math 
-       io.files io.encodings.utf8 random dns.util ;
-
-IN: dns.misc
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: resolv-conf-servers ( -- seq )
-  "/etc/resolv.conf" utf8 file-lines
-  [ " " split ] map
-  [ first "nameserver" = ] filter
-  [ second ] map ;
-
-: resolv-conf-server ( -- ip ) resolv-conf-servers random ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: cdr-name ( name -- name ) dup CHAR: . index 1 + tail ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: domain-has-name? ( domain name -- ? )
-    {
-      { [ 2dup =       ] [ 2drop t ] }
-      { [ 2dup longer? ] [ 2drop f ] }
-      { [ t            ] [ cdr-name domain-has-name? ] }
-    }
-  cond ;
-
-: name-in-domain? ( name domain -- ? ) swap domain-has-name? ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
diff --git a/extra/dns/resolver/resolver.factor b/extra/dns/resolver/resolver.factor
deleted file mode 100644 (file)
index 32ad236..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-
-USING: kernel accessors namespaces continuations
-       io io.sockets io.binary io.timeouts io.encodings.binary
-       destructors
-       locals strings sequences random prettyprint calendar dns dns.misc ;
-
-IN: dns.resolver
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-:: send-receive-udp ( BA SERVER -- ba )
-   T{ inet4 f f 0 } <datagram>
-   T{ duration { second 3 } } over set-timeout
-     [| SOCKET | BA SERVER SOCKET send SOCKET receive drop ]
-   with-disposal ;
-
-:: send-receive-tcp ( BA SERVER -- ba )
-   [let | BA [ BA length 2 >be BA append ] |
-     SERVER binary
-       [
-         T{ duration { second 3 } } input-stream get set-timeout
-         BA write flush 2 read be> read
-       ]
-     with-client                                        ] ;
-
-:: send-receive-server ( BA SERVER -- msg )
-   [let | RESULT [ BA SERVER send-receive-udp parse-message ] |
-     RESULT tc>> 1 =
-       [ BA SERVER send-receive-tcp parse-message ]
-       [ RESULT                                   ]
-     if                                                 ] ;
-
-: >dns-inet4 ( obj -- inet4 ) dup string? [ 53 <inet4> ] [ ] if ;
-
-:: send-receive-servers ( BA SERVERS -- msg )
-   SERVERS empty? [ "send-receive-servers: servers list empty" throw ] when
-   [let | SERVER [ SERVERS random >dns-inet4 ] |
-     ! if this throws an error ...
-     [ BA SERVER send-receive-server ]
-     ! we try with the other servers...
-     [ drop BA SERVER SERVERS remove send-receive-servers ]
-     recover                                            ] ;
-
-:: ask-servers ( MSG SERVERS -- msg )
-   MSG message->ba SERVERS send-receive-servers ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: fully-qualified ( name -- name ) dup "." tail? [ ] [ "." append ] if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: dns-servers ( -- seq )
-  \ dns-servers get
-    [ ]
-    [ resolv-conf-servers \ dns-servers set dns-servers ]
-  if* ;
-
-! : dns-server ( -- server ) dns-servers random ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: dns-ip4 ( name -- ips )
-  fully-qualified
-  [let | MSG [ A IN query boa query->message dns-servers ask-servers ] |
-    MSG rcode>> NO-ERROR =
-      [ MSG answer-section>> [ type>> A = ] filter [ rdata>> ] map ]
-      [ "dns-ip: rcode = " MSG rcode>> unparse append throw        ]
-    if ] ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
diff --git a/extra/dns/server/server.factor b/extra/dns/server/server.factor
deleted file mode 100644 (file)
index 773fe31..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-
-USING: kernel combinators sequences sets math threads namespaces continuations
-       debugger io io.sockets unicode.case accessors destructors
-       combinators.short-circuit combinators.smart
-       fry arrays
-       dns dns.util dns.misc ;
-
-IN: dns.server
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: records-var
-
-: records ( -- records ) records-var get ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: {name-type-class} ( obj -- array )
-  [ [ name>> >lower ] [ type>> ] [ class>> ] tri ] output>array ; 
-
-: rr=query? ( obj obj -- ? ) [ {name-type-class} ] bi@ = ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: matching-rrs  ( query -- rrs ) records [ rr=query? ] with filter ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! zones
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: zones    ( -- names ) records [ type>> NS  = ] filter [ name>> ] map prune ;
-: my-zones ( -- names ) records [ type>> SOA = ] filter [ name>> ] map ;
-
-: delegated-zones ( -- names ) zones my-zones diff ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! name->zone
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: name->zone ( name -- zone/f )
-  zones sort-largest-first [ name-in-domain? ] with find nip ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! name->authority
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: name->authority ( name -- rrs-ns ) name->zone NS IN query boa matching-rrs ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! extract-names
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: rr->rdata-names ( rr -- names/f )
-    {
-      { [ dup type>> NS    = ] [ rdata>>            1array ] }
-      { [ dup type>> MX    = ] [ rdata>> exchange>> 1array ] }
-      { [ dup type>> CNAME = ] [ rdata>>            1array ] }
-      { [ t ]                  [ drop f ] }
-    }
-  cond ;
-
-: extract-rdata-names ( message -- names )
-  [ answer-section>> ] [ authority-section>> ] bi append
-  [ rr->rdata-names ] map concat ;
-
-: extract-names ( message -- names )
-  [ message-query name>> ] [ extract-rdata-names ] bi swap prefix ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! fill-authority
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: fill-authority ( message -- message )
-  dup
-    extract-names [ name->authority ] map concat prune
-    over answer-section>> diff
-  >>authority-section ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! fill-additional
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: name->rrs-a ( name -- rrs-a ) A IN query boa matching-rrs ;
-
-: fill-additional ( message -- message )
-  dup
-    extract-rdata-names [ name->rrs-a ] map concat prune
-    over answer-section>> diff
-  >>additional-section ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! query->rrs
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-DEFER: query->rrs
-
-: matching-rrs? ( query -- rrs/f ) matching-rrs [ empty? ] [ drop f ] [ ] 1if ;
-
-: matching-cname? ( query -- rrs/f )
-  [ ] [ clone CNAME >>type matching-rrs ] bi ! query rrs
-  [ empty? not ]
-    [ first swap clone over rdata>> >>name query->rrs swap prefix ]
-    [ 2drop f ]
-  1if ;
-
-: query->rrs ( query -- rrs/f ) { [ matching-rrs? ] [ matching-cname? ] } 1|| ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! have-answers
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: have-answers ( message -- message/f )
-  dup message-query query->rrs
-  [ empty? ]
-    [ 2drop f ]
-    [ >>answer-section fill-authority fill-additional ]
-  1if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! have-delegates?
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: cdr-name ( name -- name ) dup CHAR: . index 1 + tail ;
-
-: is-soa? ( name -- ? ) SOA IN query boa matching-rrs empty? not ;
-
-: have-ns? ( name -- rrs/f )
-  NS IN query boa matching-rrs [ empty? ] [ drop f ] [ ] 1if ;
-
-: name->delegates ( name -- rrs-ns )
-    {
-      [ "" =    { } and ]
-      [ is-soa? { } and ]
-      [ have-ns? ]
-      [ cdr-name name->delegates ]
-    }
-  1|| ;
-
-: have-delegates ( message -- message/f )
-  dup message-query name>> name->delegates ! message rrs-ns
-  [ empty? ]
-    [ 2drop f ]
-    [
-      dup [ rdata>> A IN query boa matching-rrs ] map concat
-                                           ! message rrs-ns rrs-a
-      [ >>authority-section ]
-      [ >>additional-section ]
-      bi*
-    ]
-  1if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! outsize-zones
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: outside-zones ( message -- message/f )
-  dup message-query name>> name->zone f =
-    [ ]
-    [ drop f ]
-  if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! is-nx
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: is-nx ( message -- message/f )
-  [ message-query name>> records [ name>> = ] with filter empty? ]
-    [
-      NAME-ERROR >>rcode
-      dup
-        message-query name>> name->zone SOA IN query boa matching-rrs
-      >>authority-section
-    ]
-    [ drop f ]
-  1if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: none-of-type ( message -- message )
-  dup
-    message-query name>> name->zone SOA IN query boa matching-rrs
-  >>authority-section ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: find-answer ( message -- message )
-    {
-      [ have-answers   ]
-      [ have-delegates ]
-      [ outside-zones  ]
-      [ is-nx          ]
-      [ none-of-type   ]
-    }
-  1|| ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: (handle-request) ( packet -- )
-  [ [ find-answer ] with-message-bytes ] change-data respond ;
-
-: handle-request ( packet -- ) [ (handle-request) ] curry in-thread ;
-
-: receive-loop ( socket -- )
-  [ receive-packet handle-request ] [ receive-loop ] bi ;
-
-: loop ( addr-spec -- )
-  [ <datagram> '[ _ [ receive-loop ] with-disposal ] try ] [ loop ] bi ;
-
diff --git a/extra/dns/stub/stub.factor b/extra/dns/stub/stub.factor
deleted file mode 100644 (file)
index a15feb5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-USING: kernel sequences random accessors dns ;
-
-IN: dns.stub
-
-! Stub resolver
-! 
-! Generally useful, but particularly when running a forwarding,
-! caching, nameserver on localhost with multiple Factor instances
-! querying it.
-
-: name->ip ( name -- ip )
-  A IN query boa
-  query->message
-  ask
-  dup rcode>> NAME-ERROR =
-    [ message-query name>> name-error ]
-    [ answer-section>> [ type>> A = ] filter random rdata>> ]
-  if ;
-
diff --git a/extra/dns/util/util.factor b/extra/dns/util/util.factor
deleted file mode 100644 (file)
index 6934d3b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-USING: kernel sequences sorting math math.order macros fry ;
-
-IN: dns.util
-
-: tri-chain ( obj p q r -- x y z )
-  [ [ call dup ] dip call dup ] dip call ; inline
-
-MACRO: 1if ( test then else -- ) '[ dup @ _ _ if ] ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: sort-largest-first ( seq -- seq ) [ length ] sort-with reverse ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: longer? ( seq seq -- ? ) [ length ] bi@ > ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USING: io.sockets accessors ;
-
-TUPLE: packet data addr socket ;
-
-: receive-packet ( socket -- packet ) [ receive ] keep packet boa ;
-
-: respond ( packet -- ) [ data>> ] [ addr>> ] [ socket>> ] tri send ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: forever ( quot: ( -- ) -- ) [ call ] [ forever ] bi ; inline recursive
\ No newline at end of file
index 0d2a5a73d8ae49fe6bd110486325fb2010a69d44..4c9c04ba8d2c28adfb761617b27fe2589b5f80e0 100644 (file)
@@ -189,7 +189,7 @@ CONSTANT: galois-slides
     }
     { $slide "Locals and lexical scope"
         { "Define lambda words with " { $link POSTPONE: :: } }
-        { "Establish bindings with " { $link POSTPONE: [let } " and " { $link POSTPONE: [let* } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
         "Mutable bindings with correct semantics"
         { "Named inputs for quotations with " { $link POSTPONE: [| } }
         "Full closures"
index 5f33af04fec51daa9cd455876bcf7f398a61f64a..02d0bedb2cb6738eeaf2754161ce6154dab662ee 100644 (file)
@@ -272,7 +272,7 @@ CONSTANT: google-slides
     }
     { $slide "Locals and lexical scope"
         { "Define lambda words with " { $link POSTPONE: :: } }
-        { "Establish bindings with " { $link POSTPONE: [let } " and " { $link POSTPONE: [let* } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
         "Mutable bindings with correct semantics"
         { "Named inputs for quotations with " { $link POSTPONE: [| } }
         "Full closures"
index 5f92cf3dbf3d4ac70bb0f8769b8b99bcc1361650..1a13d3e55630cf73c72b142e5d418dd603eb337c 100644 (file)
@@ -332,13 +332,13 @@ DEFER: [bind-uniform-tuple]
     ] [
         { [ ] }
         name "." append 1array
-    ] if* :> name-prefixes :> quot-prefixes
+    ] if* :> ( quot-prefixes name-prefixes )
     type all-uniform-tuple-slots :> uniforms
 
     texture-unit quot-prefixes name-prefixes [| quot-prefix name-prefix |
         uniforms name-prefix [bind-uniform-tuple]
         quot-prefix prepend
-    ] 2map :> value-cleave :> texture-unit'
+    ] 2map :> ( texture-unit' value-cleave )
 
     texture-unit' 
     value>>-quot { value-cleave 2cleave } append ;
@@ -356,7 +356,7 @@ DEFER: [bind-uniform-tuple]
     } cond ;
 
 :: [bind-uniform-tuple] ( texture-unit uniforms prefix -- texture-unit' quot )
-    texture-unit uniforms [ prefix [bind-uniform] ] map :> uniforms-cleave :> texture-unit'
+    texture-unit uniforms [ prefix [bind-uniform] ] map :> ( texture-unit' uniforms-cleave )
 
     texture-unit'
     { uniforms-cleave 2cleave } >quotation ;
index 0beaa1de1d13afa13d965d9a51597154953adf71..2bd7e6883ffb7ba93e8947ab0323ae67aeb31d56 100755 (executable)
@@ -26,11 +26,11 @@ CONSTANT: fill-value 255
     ] B{ } map-as ;
 
 :: permute ( bytes src-order dst-order -- new-bytes )
-    [let | src [ src-order name>> ]
-           dst [ dst-order name>> ] |
-        bytes src length group
-        [ pad4 src dst permutation shuffle dst length head ]
-        map concat ] ;
+    src-order name>> :> src
+    dst-order name>> :> dst
+    bytes src length group
+    [ pad4 src dst permutation shuffle dst length head ]
+    map concat ;
 
 : (reorder-components) ( image src-order dest-order -- image )
     [ permute ] 2curry change-bitmap ;
index d99116424fd6b2f41ed839843294eb956edadc74..917480dd3ffe89a276158b4857c4f31fcf2aaf82 100644 (file)
@@ -25,25 +25,10 @@ HELP: [infix
     }
 } ;
 
-HELP: [infix|
-{ $syntax "[infix| binding1 [ value1... ]\n        binding2 [ value2... ]\n        ... |\n    infix-expression infix]" }
-{ $description "Introduces a set of lexical bindings and evaluates the body as a snippet of infix code. The values are evaluated in parallel, and may not refer to other bindings within the same " { $link POSTPONE: [infix| } " form, as it is based on " { $link POSTPONE: [let } "." }
-{ $examples
-    { $example
-        "USING: infix prettyprint ;"
-        "IN: scratchpad"
-        "[infix| pi [ 3.14 ] r [ 12 ] | r*r*pi infix] ."
-        "452.16"
-    }
-} ;
-
-{ POSTPONE: [infix POSTPONE: [infix| } related-words
-
 ARTICLE: "infix" "Infix notation"
 "The " { $vocab-link "infix" } " vocabulary implements support for infix notation in Factor source code."
 { $subsections
     POSTPONE: [infix
-    POSTPONE: [infix|
 }
 $nl
 "The usual infix math operators are supported:"
@@ -76,8 +61,8 @@ $nl
 $nl
 "You can access " { $vocab-link "sequences" } " inside infix expressions with the familiar " { $snippet "arr[index]" } " notation."
 { $example
-    "USING: arrays infix ;"
-    "[infix| myarr [ { 1 2 3 4 } ] | myarr[4/2]*3 infix] ."
+    "USING: arrays locals infix ;"
+    "[let { 1 2 3 4 } :> myarr [infix myarr[4/2]*3 infix] ] ."
     "9"
 }
 "Please note: in Factor " { $emphasis "fixnums are sequences too." } " If you are not careful with sequence accesses you may introduce subtle bugs:"
index 5e3d5d67cb6eb913c7469f60106154690258e84c..c2b0d9d7b4474b357a8d03820942bb4879d144fb 100644 (file)
@@ -13,17 +13,6 @@ IN: infix.tests
      -5*
      0 infix] ] unit-test
 
-[ 452.16 ] [ [infix| r [ 12 ] pi [ 3.14 ] |
-    r*r*pi infix] ] unit-test
-[ 0 ] [ [infix| a [ 3 ] | 0 infix] ] unit-test
-[ 4/5 ] [ [infix| x [ 3 ] f [ 12 ] | f/(f+x) infix] ] unit-test
-[ 144 ] [ [infix| a [ 0 ] b [ 12 ] | b*b-a infix] ] unit-test
-
-[ 0 ] [ [infix| a [ { 0 1 2 3 } ] | a[0] infix] ] unit-test
-[ 0 ] [ [infix| a [ { 0 1 2 3 } ] | 3*a[0]*2*a[1] infix] ] unit-test
-[ 6 ] [ [infix| a [ { 0 1 2 3 } ] | a[0]+a[10%3]+a[3-1]+a[18/6] infix] ] unit-test
-[ -1 ] [ [infix| a [ { 0 1 2 3 } ] | -a[+1] infix] ] unit-test
-
 [ 0.0 ] [ [infix sin(0) infix] ] unit-test
 [ 10 ] [ [infix lcm(2,5) infix] ] unit-test
 [ 1.0 ] [ [infix +cos(-0*+3) infix] ] unit-test
@@ -42,4 +31,4 @@ IN: infix.tests
 [ t ] [ 5 \ stupid_function check-word ] unit-test
 [ 10 ] [ [infix stupid_function (0, 1, 2, 3, 4) infix] ] unit-test
 
-[ -1 ] [ [let | a [ 1 ] | [infix -a infix] ] ] unit-test
+[ -1 ] [ [let 1 :> a [infix -a infix] ] ] unit-test
index ab578124f803ed12e8d0535af1fecea6427e0222..48ac35264b2081eb302d5c9624a20e1304a57537 100644 (file)
@@ -83,14 +83,3 @@ PRIVATE>
 
 SYNTAX: [infix
     "infix]" [infix-parse suffix! \ call suffix! ;
-
-<PRIVATE
-
-: parse-infix-locals ( assoc end -- quot )
-    '[ _ [infix-parse prepare-operand ] ((parse-lambda)) ;
-
-PRIVATE>
-
-SYNTAX: [infix|
-    "|" parse-bindings "infix]" parse-infix-locals <let>
-    ?rewrite-closures append! ;
index e4c954d793d04f2b33fbd5a9971c2dbab67eb498..baeacd750bccbd38014b11c26a82ecb171eed501 100644 (file)
@@ -101,11 +101,12 @@ CONSTANT: max-speed 30.0
     ] if ;
 
 :: move-player-on-heading ( d-left player distance heading -- d-left' player )
-    [let* | d-to-move [ d-left distance min ]
-            move-v [ d-to-move heading n*v ] |
-        move-v player location+
-        heading player update-nearest-segment2
-        d-left d-to-move - player ] ;
+    d-left distance min :> d-to-move
+    d-to-move heading n*v :> move-v
+
+    move-v player location+
+    heading player update-nearest-segment2
+    d-left d-to-move - player ;
 
 : distance-to-move-freely ( player -- distance )
     [ almost-to-collision ]
index 742f8346225d379b7dd1323b8d53e354ac8fd096..f7eac9d02cab343f611abc49532e3c237adcbb8f 100644 (file)
@@ -107,13 +107,13 @@ CONSTANT: default-segment-radius 1
     } case ;
 
 :: distance-to-next-segment ( current next location heading -- distance )
-    [let | cf [ current forward>> ] |
-        cf next location>> v. cf location v. - cf heading v. / ] ;
+    current forward>> :> cf
+    cf next location>> v. cf location v. - cf heading v. / ;
 
 :: distance-to-next-segment-area ( current next location heading -- distance )
-    [let | cf [ current forward>> ]
-           h [ next current half-way-between-oints ] |
-        cf h v. cf location v. - cf heading v. / ] ;
+    current forward>> :> cf
+    next current half-way-between-oints :> h
+    cf h v. cf location v. - cf heading v. / ;
 
 : vector-to-centre ( seg loc -- v )
     over location>> swap v- swap forward>> proj-perp ;
@@ -138,10 +138,10 @@ CONSTANT: distant 1000
     v norm 0 = [
         distant
     ] [
-        [let* | a [ v dup v. ]
-                b [ v w v. 2 * ]
-                c [ w dup v. r sq - ] |
-            c b a quadratic max-real ]
+        v dup v. :> a
+        v w v. 2 * :> b
+        w dup v. r sq - :> c
+        c b a quadratic max-real
     ] if ;
 
 : sideways-heading ( oint segment -- v )
index 22e37f8a8ccd0d0042bfbeb5278fbdfdba0ef410..7b5a0194d3cd1840522a3d271144fb9f4518496e 100755 (executable)
@@ -33,13 +33,12 @@ M: unix really-delete-tree delete-tree ;
     '[ drop @ f ] attempt-all drop ; inline
 
 :: upload-safely ( local username host remote -- )
-    [let* | temp [ remote ".incomplete" append ]
-            scp-remote [ { username "@" host ":" temp } concat ]
-            scp [ scp-command get ]
-            ssh [ ssh-command get ] |
-        5 [ { scp local scp-remote } short-running-process ] retry
-        5 [ { ssh host "-l" username "mv" temp remote } short-running-process ] retry
-    ] ;
+    remote ".incomplete" append :> temp
+    { username "@" host ":" temp } concat :> scp-remote
+    scp-command get :> scp
+    ssh-command get :> ssh
+    5 [ { scp local scp-remote } short-running-process ] retry
+    5 [ { ssh host "-l" username "mv" temp remote } short-running-process ] retry ;
 
 : eval-file ( file -- obj )
     dup utf8 file-lines parse-fresh
index d65d1c4103bb326129aedde0c0dce07db7c82d1f..97290964eb62e53029459aece396d7980bd05435 100644 (file)
@@ -35,8 +35,8 @@ M: matrix4 new-sequence 2drop matrix4 (struct) ; inline
 
 :: 2map-columns ( a b quot -- c )
     [
-        a columns :> a4 :> a3 :> a2 :> a1
-        b columns :> b4 :> b3 :> b2 :> b1
+        a columns :> ( a1 a2 a3 a4 )
+        b columns :> ( b1 b2 b3 b4 )
 
         a1 b1 quot call
         a2 b2 quot call
@@ -61,8 +61,8 @@ TYPED: n/m4 ( a: float b: matrix4 -- c: matrix4 ) [ n/v ] with map-columns ;
 
 TYPED:: m4. ( a: matrix4 b: matrix4 -- c: matrix4 )
     [
-        a columns :> a4 :> a3 :> a2 :> a1
-        b columns :> b4 :> b3 :> b2 :> b1
+        a columns :> ( a1 a2 a3 a4 )
+        b columns :> ( b1 b2 b3 b4 )
 
         b1 first  a1 n*v :> c1a
         b2 first  a1 n*v :> c2a
@@ -86,7 +86,7 @@ TYPED:: m4. ( a: matrix4 b: matrix4 -- c: matrix4 )
     ] make-matrix4 ;
 
 TYPED:: m4.v ( m: matrix4 v: float-4 -- v': float-4 )
-    m columns :> m4 :> m3 :> m2 :> m1
+    m columns :> ( m1 m2 m3 m4 )
     
     v first  m1 n*v
     v second m2 n*v v+
index 45cced5b3b98acebbc365128885909a38ead8f2b..1d38aa38d521cccf49c4a354cab4476c349ee2fa 100644 (file)
@@ -123,15 +123,16 @@ CONSTRUCTOR: mdb-connection ( instance -- mdb-connection ) ;
 PRIVATE>
 
 :: verify-nodes ( mdb -- )
-    [ [let* | acc [ V{ } clone ]
-              node1 [ mdb dup master-node [ check-node ] keep ]
-              node2 [ mdb node1 remote>>
-                      [ [ check-node ] keep ]
-                      [ drop f ] if*  ]
-              | node1 [ acc push ] when*
-                node2 [ acc push ] when*
-                mdb acc nodelist>table >>nodes drop 
-              ]
+    [
+        V{ } clone :> acc
+        mdb dup master-node [ check-node ] keep :> node1
+        mdb node1 remote>>
+        [ [ check-node ] keep ]
+        [ drop f ] if*  :> node2
+
+        node1 [ acc push ] when*
+        node2 [ acc push ] when*
+        mdb acc nodelist>table >>nodes drop 
     ] with-destructors ; 
               
 : mdb-open ( mdb -- mdb-connection )
@@ -143,4 +144,4 @@ PRIVATE>
      [ dispose f ] change-handle drop ;
 
 M: mdb-connection dispose
-     mdb-close ;
\ No newline at end of file
+     mdb-close ;
index 9538972582b0913979a146baf65301aaab6f4484..294672523cbb6c237d2870cbcc92c4a36235cc0e 100644 (file)
@@ -151,14 +151,16 @@ M: mdb-collection create-collection
     [ "$cmd" = ] [ "system" head? ] bi or ;
 
 : check-collection ( collection -- fq-collection )
-    [let* | instance [ mdb-instance ]
-            instance-name [ instance name>> ] |        
+    [let
+        mdb-instance :> instance
+        instance name>> :> instance-name
         dup mdb-collection? [ name>> ] when
         "." split1 over instance-name =
         [ nip ] [ drop ] if
         [ ] [ reserved-namespace? ] bi
         [ instance (ensure-collection) ] unless
-        [ instance-name ] dip "." glue ] ; 
+        [ instance-name ] dip "." glue
+    ] ;
 
 : fix-query-collection ( mdb-query -- mdb-query )
     [ check-collection ] change-collection ; inline
index d4ee789523f70d49b1569d1d614b1a996b3ac7c5..7e99c52aacf6d95085815e7ceef72565fb26f1eb 100644 (file)
@@ -105,15 +105,14 @@ USE: tools.walker
     ! [ dump-to-file ] keep
     write flush ; inline
 
-: build-query-object ( query -- selector )
-    [let | selector [ H{ } clone ] |
-        { [ orderby>> [ "orderby" selector set-at ] when* ]
-          [ explain>> [ "$explain" selector set-at ] when* ]
-          [ hint>> [ "$hint" selector set-at ] when* ] 
-          [ query>> "query" selector set-at ]
-        } cleave
-        selector
-    ] ;     
+:: build-query-object ( query -- selector )
+    H{ } clone :> selector
+    query { [ orderby>> [ "orderby" selector set-at ] when* ]
+      [ explain>> [ "$explain" selector set-at ] when* ]
+      [ hint>> [ "$hint" selector set-at ] when* ] 
+      [ query>> "query" selector set-at ]
+    } cleave
+    selector ;
 
 PRIVATE>
 
index 0df063e2c6dbce5558d47d8169450bef9594cfa6..38ab0c31da2e16f4efc46eadf084ada94a624a4d 100644 (file)
@@ -60,7 +60,7 @@ TUPLE: nurbs-curve
 
 :: (eval-bases) ( curve t interval values order -- values' )
     order 2 - curve (knot-constants)>> nth :> all-knot-constants
-    interval order interval + all-knot-constants clip-range :> to :> from
+    interval order interval + all-knot-constants clip-range :> ( from to )
     from to all-knot-constants subseq :> knot-constants
     values { 0.0 } { 0.0 } surround 2 <clumps> :> bases
 
index 8ab0b171904a2018028cca711e23847fe9fca93b..b63a71946e8503ab1b33899dce33f638b98d2f7c 100644 (file)
@@ -33,13 +33,12 @@ IN: project-euler.073
 <PRIVATE
 
 :: (euler073) ( counter limit lo hi -- counter' )
-    [let | m [ lo hi mediant ] |
-        m denominator limit <= [
-            counter 1 +
-            limit lo m (euler073)
-            limit m hi (euler073)
-        ] [ counter ] if
-    ] ;
+    lo hi mediant :> m
+    m denominator limit <= [
+        counter 1 +
+        limit lo m (euler073)
+        limit m hi (euler073)
+    ] [ counter ] if ;
 
 PRIVATE>
 
index a54b7d1db0faa147fd98c6b2a82ba21efaa163b8..e6278a1e172297e77e4b7105274340352138ddb9 100644 (file)
@@ -54,17 +54,16 @@ IN: project-euler.150
     0 1000 [1,b] [ [ next ] replicate partial-sums ] map nip ;
 
 :: (euler150) ( m -- n )
-    [let | table [ sums-triangle ] |
-        m [| x |
-            x 1 + [| y |
-                m x - [0,b) [| z |
-                    x z + table nth-unsafe
-                    [ y z + 1 + swap nth-unsafe ]
-                    [ y        swap nth-unsafe ] bi -
-                ] map partial-sum-infimum
-            ] map-infimum
+    sums-triangle :> table
+    m [| x |
+        x 1 + [| y |
+            m x - [0,b) [| z |
+                x z + table nth-unsafe
+                [ y z + 1 + swap nth-unsafe ]
+                [ y        swap nth-unsafe ] bi -
+            ] map partial-sum-infimum
         ] map-infimum
-    ] ;
+    ] map-infimum ;
 
 HINTS: (euler150) fixnum ;
 
index f5c2ea9811b0b25eb4d00fba5e83e48bed9e14b0..cae2c20877c8b59e2a4b30525377a8292a988865 100755 (executable)
@@ -81,8 +81,6 @@ M: wrapper noise wrapped>> noise ;
 \r
 M: let noise body>> noise ;\r
 \r
-M: wlet noise body>> noise ;\r
-\r
 M: lambda noise body>> noise ;\r
 \r
 M: object noise drop { 0 0 } ;\r
index c94e13a67311136f118434827b8fe262f360193e..f783fad31204a3744ff21b8499aee057f787b5fc 100644 (file)
@@ -49,7 +49,7 @@ M: product-sequence nth
     product@ nths ;
 
 :: product-each ( sequences quot -- )
-    sequences start-product-iter :> lengths :> ns
+    sequences start-product-iter :> ( ns lengths )
     lengths [ 0 = ] any? [
         [ ns lengths end-product-iter? ]
         [ ns sequences nths quot call ns lengths product-iter ] until
index 9d3aa6c65127d81da8138263dfac7d04770777b4..4ce998294b283c26b12adb972281c5b379231346 100644 (file)
@@ -69,12 +69,12 @@ fetched-in parsed-html links processed-in fetched-at ;
 
 :: fill-spidered-result ( spider spider-result -- )
     f spider-result url>> spider spidered>> set-at
-    [ spider-result url>> http-get ] benchmark :> fetched-in :> html :> headers
+    [ spider-result url>> http-get ] benchmark :> ( headers html fetched-in )
     [
         html parse-html
         spider currently-spidering>>
         over find-all-links normalize-hrefs
-    ] benchmark :> processed-in :> links :> parsed-html
+    ] benchmark :> ( parsed-html links processed-in )
     spider-result
         headers >>headers
         fetched-in >>fetched-in
index 254e2821395fe1b16c9470cefceddf0f867ccbb1..70943e6674ca136ab8f26514865db8ec733ea084 100644 (file)
@@ -12,12 +12,13 @@ IN: ui.gadgets.alerts
 : alert* ( str -- ) [ ] swap alert ;
 
 :: ask-user ( string -- model' )
-   [ [let | lbl  [ string <label>  T{ font { name "sans-serif" } { size 14 } } >>font dup , ]
-            fldm [ <model-field*> ->% 1 ]
-            btn  [ "okay" <model-border-btn> ] |
-         btn -> [ fldm swap updates ]
-                [ [ drop lbl close-window ] $> , ] bi
-   ] ] <vbox> { 161 86 } >>pref-dim "" open-window ;
+    [
+        string <label>  T{ font { name "sans-serif" } { size 14 } } >>font dup , :> lbl
+        <model-field*> ->% 1 :> fldm
+        "okay" <model-border-btn> :> btn
+        btn -> [ fldm swap updates ]
+               [ [ drop lbl close-window ] $> , ] bi
+    ] <vbox> { 161 86 } >>pref-dim "" open-window ;
 
 MACRO: ask-buttons ( buttons -- quot ) dup length [
       [ swap
@@ -25,4 +26,4 @@ MACRO: ask-buttons ( buttons -- quot ) dup length [
          [ [ <model-border-btn> [ close-window ] >>hook -> ] map ] <hbox> , ] <vbox>
          "" open-window
       ] dip firstn
-   ] 2curry ;
\ No newline at end of file
+   ] 2curry ;
index 518462d7bb26e9338c67ee65bdad6f550807eb23..b0a4b146d49d97604da27ab6309d030d090a254a 100644 (file)
@@ -209,7 +209,7 @@ CONSTANT: vpri-slides
     }
     { $slide "Locals and lexical scope"
         { "Define lambda words with " { $link POSTPONE: :: } }
-        { "Establish bindings with " { $link POSTPONE: [let } " and " { $link POSTPONE: [let* } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
         "Mutable bindings with correct semantics"
         { "Named inputs for quotations with " { $link POSTPONE: [| } }
         "Full closures"
index f1e8a388f73e23eef5ea4d98e52e1957991a3a64..54b392d77563fa1fb0b264db11709e0e99b1fa9f 100644 (file)
@@ -3,10 +3,7 @@
 <plist version="1.0">
 <dict>
        <key>content</key>
-       <string>
-   [let | $1 [ $2 ] $3|
-      $0
-   ]</string>
+       <string>[let $0 ]</string>
        <key>name</key>
        <string>let</string>
        <key>scope</key>
index 73d6781313909d150b3913b47046c56e199e5c15..8c4dbc4f8c362fa02772fee884a35972774fab06 100644 (file)
     ("\\(\n\\| \\);\\_>" (1 ">b"))
     ;; Let and lambda:
     ("\\_<\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))
-    ("\\(\\[\\)\\(let\\|wlet\\|let\\*\\)\\( \\|$\\)" (1 "(]"))
+    ("\\(\\[\\)\\(let\\|let\\*\\)\\( \\|$\\)" (1 "(]"))
     ("\\(\\[\\)\\(|\\) +[^|]* \\(|\\)" (1 "(]") (2 "(|") (3 ")|"))
     (" \\(|\\) " (1 "(|"))
     (" \\(|\\)$" (1 ")"))
diff --git a/unmaintained/dns/cache/nx/nx.factor b/unmaintained/dns/cache/nx/nx.factor
new file mode 100644 (file)
index 0000000..9904f85
--- /dev/null
@@ -0,0 +1,35 @@
+
+USING: kernel assocs locals combinators
+       math math.functions system unicode.case ;
+
+IN: dns.cache.nx
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: nx-cache ( -- table ) H{ } ;
+
+: nx-cache-at        (      name -- time ) >lower nx-cache at        ;
+: nx-cache-delete-at (      name --      ) >lower nx-cache delete-at ;
+: nx-cache-set-at    ( time name --      ) >lower nx-cache set-at    ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: now ( -- seconds ) millis 1000.0 / round >integer ;
+
+:: non-existent-name? ( NAME -- ? )
+   [let | TIME [ NAME nx-cache-at ] |
+     {
+       { [ TIME f    = ] [                         f ] }
+       { [ TIME now <= ] [ NAME nx-cache-delete-at f ] }
+       { [ t           ] [                         t ] }
+     }
+     cond
+   ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: cache-non-existent-name ( NAME TTL -- )
+   [let | TIME [ TTL now + ] | TIME NAME nx-cache-set-at ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
diff --git a/unmaintained/dns/cache/rr/rr.factor b/unmaintained/dns/cache/rr/rr.factor
new file mode 100644 (file)
index 0000000..cb80190
--- /dev/null
@@ -0,0 +1,65 @@
+
+USING: kernel sequences assocs sets locals combinators
+       accessors system math math.functions unicode.case prettyprint
+       combinators.smart dns ;
+
+IN: dns.cache.rr
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: <entry> time data ;
+
+: now ( -- seconds ) millis 1000.0 / round >integer ;
+
+: expired? ( <entry> -- ? ) time>> now <= ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-cache-key ( obj -- key )
+  [ [ name>> >lower ] [ type>> ] [ class>> ] tri ] output>array ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: cache ( -- table ) H{ } ;
+
+: cache-at     (     obj -- ent ) make-cache-key cache at ;
+: cache-delete (     obj --     ) make-cache-key cache delete-at ;
+: cache-set-at ( ent obj --     ) make-cache-key cache set-at ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: cache-get ( OBJ -- rrs/f )
+   [let | ENT [ OBJ cache-at ] |
+     {
+       { [ ENT f =      ] [                  f ] }
+       { [ ENT expired? ] [ OBJ cache-delete f ] }
+       {
+         [ t ]
+         [
+           [let | NAME  [ OBJ name>>       ]
+                  TYPE  [ OBJ type>>       ]
+                  CLASS [ OBJ class>>      ]
+                  TTL   [ ENT time>> now - ] |
+             ENT data>>
+               [| RDATA | T{ rr f NAME TYPE CLASS TTL RDATA } ]
+             map
+           ]
+         ]
+       }
+     }
+     cond
+   ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: cache-add ( RR -- )
+   [let | ENT   [ RR cache-at    ]
+          TIME  [ RR ttl>> now + ]
+          RDATA [ RR rdata>>     ] |
+     {
+       { [ ENT f =      ] [ T{ <entry> f TIME V{ RDATA } } RR cache-set-at ] }
+       { [ ENT expired? ] [ RR cache-delete RR cache-add                   ] }
+       { [ t            ] [ TIME ENT (>>time) RDATA ENT data>> adjoin      ] }
+     }
+     cond
+   ] ;
\ No newline at end of file
diff --git a/unmaintained/dns/dns.factor b/unmaintained/dns/dns.factor
new file mode 100644 (file)
index 0000000..f16664f
--- /dev/null
@@ -0,0 +1,501 @@
+
+USING: kernel byte-arrays combinators strings arrays sequences splitting
+       grouping
+       math math.functions math.parser random
+       destructors
+       io io.binary io.sockets io.encodings.binary
+       accessors
+       combinators.smart
+       assocs
+       ;
+
+IN: dns
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: query name type class ;
+
+TUPLE: rr name type class ttl rdata ;
+
+TUPLE: hinfo cpu os ;
+
+TUPLE: mx preference exchange ;
+
+TUPLE: soa mname rname serial refresh retry expire minimum ;
+
+TUPLE: message
+       id qr opcode aa tc rd ra z rcode
+       question-section
+       answer-section
+       authority-section
+       additional-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: random-id ( -- id ) 2 16 ^ random ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! TYPE
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOLS: A NS MD MF CNAME SOA MB MG MR NULL WKS PTR HINFO MINFO MX TXT AAAA ;
+
+: type-table ( -- table )
+  {
+    { A     1 }
+    { NS    2 }
+    { MD    3 }
+    { MF    4 }
+    { CNAME 5 }
+    { SOA   6 }
+    { MB    7 }
+    { MG    8 }
+    { MR    9 }
+    { NULL  10 }
+    { WKS   11 }
+    { PTR   12 }
+    { HINFO 13 }
+    { MINFO 14 }
+    { MX    15 }
+    { TXT   16 }
+    { AAAA  28 }
+  } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! CLASS
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOLS: IN CS CH HS ;
+
+: class-table ( -- table )
+  {
+    { IN 1 }
+    { CS 2 }
+    { CH 3 }
+    { HS 4 }
+  } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! OPCODE
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOLS: QUERY IQUERY STATUS ;
+
+: opcode-table ( -- table )
+  {
+    { QUERY  0 }
+    { IQUERY 1 }
+    { STATUS 2 }
+  } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! RCODE
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOLS: NO-ERROR FORMAT-ERROR SERVER-FAILURE NAME-ERROR NOT-IMPLEMENTED
+         REFUSED ;
+
+: rcode-table ( -- table )
+  {
+    { NO-ERROR        0 }
+    { FORMAT-ERROR    1 }
+    { SERVER-FAILURE  2 }
+    { NAME-ERROR      3 }
+    { NOT-IMPLEMENTED 4 }
+    { REFUSED         5 }
+  } ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: <message> ( -- message )
+  message new
+    random-id >>id
+    0         >>qr
+    QUERY     >>opcode
+    0         >>aa
+    0         >>tc
+    1         >>rd
+    0         >>ra
+    0         >>z
+    NO-ERROR  >>rcode
+    { }       >>question-section
+    { }       >>answer-section
+    { }       >>authority-section
+    { }       >>additional-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: ip->ba ( ip -- ba ) "." split [ string>number ] map >byte-array ;
+
+: ipv6->ba ( ip -- ba ) ":" split [ 16 base> ] map [ 2 >be ] map concat ;
+
+: label->ba ( label -- ba ) [ >byte-array ] [ length ] bi prefix ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: uint8->ba  ( n -- ba ) 1 >be ;
+: uint16->ba ( n -- ba ) 2 >be ;
+: uint32->ba ( n -- ba ) 4 >be ;
+: uint64->ba ( n -- ba ) 8 >be ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: dn->ba ( dn -- ba ) "." split [ label->ba ] map concat ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: query->ba ( query -- ba )
+  [
+    {
+      [ name>>                 dn->ba ]
+      [ type>>  type-table  at uint16->ba ]
+      [ class>> class-table at uint16->ba ]
+    } cleave
+  ] output>array concat ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: hinfo->ba ( rdata -- ba )
+    [ cpu>> label->ba ]
+    [ os>>  label->ba ]
+  bi append ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: mx->ba ( rdata -- ba )
+    [ preference>> uint16->ba ]
+    [ exchange>>   dn->ba ]
+  bi append ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: soa->ba ( rdata -- ba )
+  [
+    {
+      [ mname>>   dn->ba ]
+      [ rname>>   dn->ba ]
+      [ serial>>  uint32->ba ]
+      [ refresh>> uint32->ba ]
+      [ retry>>   uint32->ba ]
+      [ expire>>  uint32->ba ]
+      [ minimum>> uint32->ba ]
+    } cleave
+  ] output>array concat ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: rdata->ba ( type rdata -- ba )
+  swap
+    {
+      { CNAME [ dn->ba ] }
+      { HINFO [ hinfo->ba ] }
+      { MX    [ mx->ba ] }
+      { NS    [ dn->ba ] }
+      { PTR   [ dn->ba ] }
+      { SOA   [ soa->ba ] }
+      { A     [ ip->ba ] }
+    }
+  case ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: rr->ba ( rr -- ba )
+  [
+    {
+      [ name>>                 dn->ba     ]
+      [ type>>  type-table  at uint16->ba ]
+      [ class>> class-table at uint16->ba ]
+      [ ttl>>   uint32->ba ]
+      [
+        [ type>>            ] [ rdata>> ] bi rdata->ba
+        [ length uint16->ba ] [         ] bi append
+      ]
+    } cleave
+  ] output>array concat ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: header-bits-ba ( message -- ba )
+  [
+    {
+      [ qr>>                     15 shift ]
+      [ opcode>> opcode-table at 11 shift ]
+      [ aa>>                     10 shift ]
+      [ tc>>                      9 shift ]
+      [ rd>>                      8 shift ]
+      [ ra>>                      7 shift ]
+      [ z>>                       4 shift ]
+      [ rcode>>  rcode-table at   0 shift ]
+    } cleave
+  ] sum-outputs uint16->ba ;
+
+: message->ba ( message -- ba )
+  [
+    {
+      [ id>> uint16->ba ]
+      [ header-bits-ba ]
+      [ question-section>>   length uint16->ba ]
+      [ answer-section>>     length uint16->ba ]
+      [ authority-section>>  length uint16->ba ]
+      [ additional-section>> length uint16->ba ]
+      [ question-section>>   [ query->ba ] map concat ]
+      [ answer-section>>     [ rr->ba    ] map concat ]
+      [ authority-section>>  [ rr->ba    ] map concat ]
+      [ additional-section>> [ rr->ba    ] map concat ]
+    } cleave
+  ] output>array concat ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-single ( ba i -- n ) at ;
+: get-double ( ba i -- n ) dup 2 + subseq be> ;
+: get-quad   ( ba i -- n ) dup 4 + subseq be> ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: label-length ( ba i -- length ) get-single ;
+
+: skip-label ( ba i -- ba i ) 2dup label-length + 1 + ;
+
+: null-label? ( ba i -- ? ) get-single 0 = ;
+
+: get-label ( ba i -- label ) [ 1 + ] [ skip-label nip ] 2bi subseq >string ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: bit-test ( a b -- ? ) bitand 0 = not ;
+
+: pointer? ( ba i -- ? ) get-single BIN: 11000000 bit-test ;
+
+: pointer ( ba i -- val ) get-double BIN: 0011111111111111 bitand ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: skip-name ( ba i -- ba i )
+    {
+      { [ 2dup null-label? ] [ 1 + ] }
+      { [ 2dup pointer?    ] [ 2 + ] }
+      { [ t ] [ skip-label skip-name ] }
+    }
+  cond ;
+
+: get-name ( ba i -- name )
+    {
+      { [ 2dup null-label? ] [ 2drop "" ] }
+      { [ 2dup pointer?    ] [ dupd pointer get-name ] }
+      {
+        [ t ]
+        [
+          [ get-label ]
+          [ skip-label get-name ]
+          2bi
+          "." glue 
+        ]
+      }
+    }
+  cond ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-query ( ba i -- query )
+    [ get-name ]
+    [
+      skip-name
+      [ 0 + get-double type-table  value-at ]
+      [ 2 + get-double class-table value-at ]
+      2bi
+    ]
+  2bi query boa ;
+
+: skip-query ( ba i -- ba i ) skip-name 4 + ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-mx ( ba i -- mx ) [ get-double ] [ 2 + get-double ] 2bi mx boa ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-soa ( ba i -- soa )
+    {
+      [           get-name ]
+      [ skip-name get-name ]
+      [
+        skip-name
+        skip-name
+        {
+          [  0 + get-quad ]
+          [  4 + get-quad ]
+          [  8 + get-quad ]
+          [ 12 + get-quad ]
+          [ 16 + get-quad ]
+        }
+          2cleave
+      ]
+    }
+  2cleave soa boa ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-ip ( ba i -- ip ) dup 4 + subseq >array [ number>string ] map "." join ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-ipv6 ( ba i -- ip )
+  dup 16 + subseq 2 group [ be> 16 >base ] map ":" join ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-rdata ( ba i type -- rdata )
+    {
+      { CNAME [ get-name ] }
+      { NS    [ get-name ] }
+      { PTR   [ get-name ] }
+      { MX    [ get-mx   ] }
+      { SOA   [ get-soa  ] }
+      { A     [ get-ip   ] }
+      { AAAA  [ get-ipv6 ] }
+    }
+  case ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-rr ( ba i -- rr )
+  [ get-name ]
+  [
+    skip-name
+      {
+        [ 0 + get-double type-table  value-at ]
+        [ 2 + get-double class-table value-at ]
+        [ 4 + get-quad   ]
+        [ [ 10 + ] [ get-double type-table value-at ] 2bi get-rdata ]
+      }
+    2cleave
+  ]
+    2bi rr boa ;
+
+: skip-rr ( ba i -- ba i ) skip-name 8 + 2dup get-double + 2 + ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-question-section ( ba i count -- seq ba i )
+  [ drop [ skip-query ] [ get-query ] 2bi ] map -rot ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-rr-section ( ba i count -- seq ba i )
+  [ drop [ skip-rr ] [ get-rr ] 2bi ] map -rot ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: >> ( x n -- y ) neg shift ;
+
+: get-header-bits ( ba i -- qr opcode aa tc rd ra z rcode )
+    get-double
+    {
+      [ 15 >> BIN:    1 bitand ]
+      [ 11 >> BIN:  111 bitand opcode-table value-at ]
+      [ 10 >> BIN:    1 bitand ]
+      [  9 >> BIN:    1 bitand ]
+      [  8 >> BIN:    1 bitand ]
+      [  7 >> BIN:    1 bitand ]
+      [  4 >> BIN:  111 bitand ]
+      [       BIN: 1111 bitand rcode-table value-at ]
+    }
+  cleave ;
+
+: parse-message ( ba -- message )
+  0
+  {
+    [ get-double ]
+    [ 2 + get-header-bits ]
+    [
+      4 +
+      {
+        [ 8 +            ]
+        [ 0 + get-double ]
+        [ 2 + get-double ]
+        [ 4 + get-double ]
+        [ 6 + get-double ]
+      }
+        2cleave
+      {
+        [ get-question-section ]
+        [ get-rr-section ]
+        [ get-rr-section ]
+        [ get-rr-section ]
+      } spread
+      2drop
+    ]
+  }
+    2cleave message boa ;
+
+: ba->message ( ba -- message ) parse-message ;
+
+: with-message-bytes ( ba quot -- ) [ ba->message ] dip call message->ba ; inline
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: send-receive-udp ( ba server -- ba )
+  f 0 <inet4> <datagram>
+    [
+      [ send ] [ receive drop ] bi
+    ]
+  with-disposal ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: send-receive-tcp ( ba server -- ba )
+  [ dup length 2 >be prepend ] [ ] bi*
+  binary
+    [
+      write flush
+      2 read be> read
+    ]
+  with-client ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: >dns-inet4 ( obj -- inet4 )
+  dup string?
+    [ 53 <inet4> ]
+    [            ]
+  if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: ask-server ( message server -- message )
+  [ message->ba ] [ >dns-inet4 ] bi*
+  2dup
+  send-receive-udp parse-message
+  dup tc>> 1 =
+    [ drop send-receive-tcp parse-message ]
+    [ nip nip                             ]
+  if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: dns-servers ( -- seq ) V{ } ;
+
+: dns-server ( -- server ) dns-servers random ;
+
+: ask ( message -- message ) dns-server ask-server ;
+
+: query->message ( query -- message ) <message> swap 1array >>question-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: message-query ( message -- query ) question-section>> first ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ERROR: name-error name ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: fully-qualified ( name -- name )
+    {
+      { [ dup empty?         ] [ "." append ] }
+      { [ dup last CHAR: . = ] [            ] }
+      { [ t                  ] [ "." append ] }
+    }
+  cond ;
diff --git a/unmaintained/dns/forwarding/forwarding.factor b/unmaintained/dns/forwarding/forwarding.factor
new file mode 100644 (file)
index 0000000..4b7db30
--- /dev/null
@@ -0,0 +1,124 @@
+
+USING: kernel sequences combinators accessors locals random
+       combinators.short-circuit
+       io.sockets
+       dns dns.util dns.cache.rr dns.cache.nx
+       dns.resolver ;
+
+IN: dns.forwarding
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: query->rrs ( QUERY -- rrs/f )
+   [let | RRS [ QUERY cache-get ] |
+     RRS
+       [ RRS ]
+       [
+         [let | NAME  [ QUERY name>>  ]
+                TYPE  [ QUERY type>>  ]
+                CLASS [ QUERY class>> ] |
+               
+           [let | RRS/CNAME [ T{ query f NAME CNAME CLASS } cache-get ] |
+
+             RRS/CNAME f =
+               [ f ]
+               [
+                 [let | RR/CNAME [ RRS/CNAME first ] |
+            
+                   [let | REAL-NAME [ RR/CNAME rdata>> ] |
+              
+                     [let | RRS [
+                                  T{ query f REAL-NAME TYPE CLASS } query->rrs
+                                ] |
+
+                       RRS
+                         [ RRS/CNAME RRS append ]
+                         [ f ]
+                       if
+                     ] ] ]
+               ]
+             if
+           ] ]
+       ]
+     if
+   ] ;
+
+:: answer-from-cache ( MSG -- msg/f )
+   [let | QUERY [ MSG message-query ] |
+
+     [let | NX  [ QUERY name>> non-existent-name? ]
+            RRS [ QUERY query->rrs                ] |
+
+       {
+         { [ NX  ] [ MSG NAME-ERROR >>rcode          ] }
+         { [ RRS ] [ MSG RRS        >>answer-section ] }
+         { [ t   ] [ f                               ] }
+       }
+       cond
+     ]
+   ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: message-soa ( message -- rr/soa )
+  authority-section>> [ type>> SOA = ] filter first ;
+
+! :: cache-message ( MSG -- msg )
+!    MSG rcode>> NAME-ERROR =
+!      [
+!        [let | NAME [ MSG message-query name>> ]
+!               TTL  [ MSG message-soa   ttl>>  ] |
+!          NAME TTL cache-non-existent-name
+!        ]
+!      ]
+!    when
+!    MSG answer-section>>     [ cache-add ] each
+!    MSG authority-section>>  [ cache-add ] each
+!    MSG additional-section>> [ cache-add ] each
+!    MSG ;
+
+:: cache-message ( MSG -- msg )
+   MSG rcode>> NAME-ERROR =
+     [
+       [let | RR/SOA [ MSG
+                         authority-section>>
+                         [ type>> SOA = ] filter
+                       dup empty? [ drop f ] [ first ] if ] |
+         RR/SOA
+           [
+             [let | NAME [ MSG message-query name>> ]
+                    TTL  [ MSG message-soa   ttl>>  ] |
+               NAME TTL cache-non-existent-name
+             ]
+           ]
+         when
+       ]
+     ]
+   when
+   MSG answer-section>>     [ cache-add ] each
+   MSG authority-section>>  [ cache-add ] each
+   MSG additional-section>> [ cache-add ] each
+   MSG ;
+
+! : answer-from-server ( msg servers -- msg ) random ask-server cache-message ;
+
+: answer-from-server ( msg servers -- msg ) ask-servers cache-message ;
+
+:: find-answer ( MSG SERVERS -- msg )
+   { [ MSG answer-from-cache ] [ MSG SERVERS answer-from-server ] } 0|| ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: start-server ( ADDR-SPEC SERVERS -- )
+
+  [let | SOCKET [ ADDR-SPEC <datagram> ] |
+
+    [
+      SOCKET receive-packet
+        [ parse-message SERVERS find-answer message->ba ]
+      change-data
+      respond
+    ]
+    forever
+
+  ] ;
diff --git a/unmaintained/dns/misc/misc.factor b/unmaintained/dns/misc/misc.factor
new file mode 100644 (file)
index 0000000..72f553c
--- /dev/null
@@ -0,0 +1,34 @@
+
+USING: kernel combinators sequences splitting math 
+       io.files io.encodings.utf8 random dns.util ;
+
+IN: dns.misc
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: resolv-conf-servers ( -- seq )
+  "/etc/resolv.conf" utf8 file-lines
+  [ " " split ] map
+  [ first "nameserver" = ] filter
+  [ second ] map ;
+
+: resolv-conf-server ( -- ip ) resolv-conf-servers random ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: cdr-name ( name -- name ) dup CHAR: . index 1 + tail ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: domain-has-name? ( domain name -- ? )
+    {
+      { [ 2dup =       ] [ 2drop t ] }
+      { [ 2dup longer? ] [ 2drop f ] }
+      { [ t            ] [ cdr-name domain-has-name? ] }
+    }
+  cond ;
+
+: name-in-domain? ( name domain -- ? ) swap domain-has-name? ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
diff --git a/unmaintained/dns/resolver/resolver.factor b/unmaintained/dns/resolver/resolver.factor
new file mode 100644 (file)
index 0000000..32ad236
--- /dev/null
@@ -0,0 +1,72 @@
+
+USING: kernel accessors namespaces continuations
+       io io.sockets io.binary io.timeouts io.encodings.binary
+       destructors
+       locals strings sequences random prettyprint calendar dns dns.misc ;
+
+IN: dns.resolver
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+:: send-receive-udp ( BA SERVER -- ba )
+   T{ inet4 f f 0 } <datagram>
+   T{ duration { second 3 } } over set-timeout
+     [| SOCKET | BA SERVER SOCKET send SOCKET receive drop ]
+   with-disposal ;
+
+:: send-receive-tcp ( BA SERVER -- ba )
+   [let | BA [ BA length 2 >be BA append ] |
+     SERVER binary
+       [
+         T{ duration { second 3 } } input-stream get set-timeout
+         BA write flush 2 read be> read
+       ]
+     with-client                                        ] ;
+
+:: send-receive-server ( BA SERVER -- msg )
+   [let | RESULT [ BA SERVER send-receive-udp parse-message ] |
+     RESULT tc>> 1 =
+       [ BA SERVER send-receive-tcp parse-message ]
+       [ RESULT                                   ]
+     if                                                 ] ;
+
+: >dns-inet4 ( obj -- inet4 ) dup string? [ 53 <inet4> ] [ ] if ;
+
+:: send-receive-servers ( BA SERVERS -- msg )
+   SERVERS empty? [ "send-receive-servers: servers list empty" throw ] when
+   [let | SERVER [ SERVERS random >dns-inet4 ] |
+     ! if this throws an error ...
+     [ BA SERVER send-receive-server ]
+     ! we try with the other servers...
+     [ drop BA SERVER SERVERS remove send-receive-servers ]
+     recover                                            ] ;
+
+:: ask-servers ( MSG SERVERS -- msg )
+   MSG message->ba SERVERS send-receive-servers ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: fully-qualified ( name -- name ) dup "." tail? [ ] [ "." append ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: dns-servers ( -- seq )
+  \ dns-servers get
+    [ ]
+    [ resolv-conf-servers \ dns-servers set dns-servers ]
+  if* ;
+
+! : dns-server ( -- server ) dns-servers random ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: dns-ip4 ( name -- ips )
+  fully-qualified
+  [let | MSG [ A IN query boa query->message dns-servers ask-servers ] |
+    MSG rcode>> NO-ERROR =
+      [ MSG answer-section>> [ type>> A = ] filter [ rdata>> ] map ]
+      [ "dns-ip: rcode = " MSG rcode>> unparse append throw        ]
+    if ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
diff --git a/unmaintained/dns/server/server.factor b/unmaintained/dns/server/server.factor
new file mode 100644 (file)
index 0000000..773fe31
--- /dev/null
@@ -0,0 +1,208 @@
+
+USING: kernel combinators sequences sets math threads namespaces continuations
+       debugger io io.sockets unicode.case accessors destructors
+       combinators.short-circuit combinators.smart
+       fry arrays
+       dns dns.util dns.misc ;
+
+IN: dns.server
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: records-var
+
+: records ( -- records ) records-var get ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: {name-type-class} ( obj -- array )
+  [ [ name>> >lower ] [ type>> ] [ class>> ] tri ] output>array ; 
+
+: rr=query? ( obj obj -- ? ) [ {name-type-class} ] bi@ = ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: matching-rrs  ( query -- rrs ) records [ rr=query? ] with filter ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! zones
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: zones    ( -- names ) records [ type>> NS  = ] filter [ name>> ] map prune ;
+: my-zones ( -- names ) records [ type>> SOA = ] filter [ name>> ] map ;
+
+: delegated-zones ( -- names ) zones my-zones diff ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! name->zone
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: name->zone ( name -- zone/f )
+  zones sort-largest-first [ name-in-domain? ] with find nip ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! name->authority
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: name->authority ( name -- rrs-ns ) name->zone NS IN query boa matching-rrs ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! extract-names
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: rr->rdata-names ( rr -- names/f )
+    {
+      { [ dup type>> NS    = ] [ rdata>>            1array ] }
+      { [ dup type>> MX    = ] [ rdata>> exchange>> 1array ] }
+      { [ dup type>> CNAME = ] [ rdata>>            1array ] }
+      { [ t ]                  [ drop f ] }
+    }
+  cond ;
+
+: extract-rdata-names ( message -- names )
+  [ answer-section>> ] [ authority-section>> ] bi append
+  [ rr->rdata-names ] map concat ;
+
+: extract-names ( message -- names )
+  [ message-query name>> ] [ extract-rdata-names ] bi swap prefix ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! fill-authority
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: fill-authority ( message -- message )
+  dup
+    extract-names [ name->authority ] map concat prune
+    over answer-section>> diff
+  >>authority-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! fill-additional
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: name->rrs-a ( name -- rrs-a ) A IN query boa matching-rrs ;
+
+: fill-additional ( message -- message )
+  dup
+    extract-rdata-names [ name->rrs-a ] map concat prune
+    over answer-section>> diff
+  >>additional-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! query->rrs
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+DEFER: query->rrs
+
+: matching-rrs? ( query -- rrs/f ) matching-rrs [ empty? ] [ drop f ] [ ] 1if ;
+
+: matching-cname? ( query -- rrs/f )
+  [ ] [ clone CNAME >>type matching-rrs ] bi ! query rrs
+  [ empty? not ]
+    [ first swap clone over rdata>> >>name query->rrs swap prefix ]
+    [ 2drop f ]
+  1if ;
+
+: query->rrs ( query -- rrs/f ) { [ matching-rrs? ] [ matching-cname? ] } 1|| ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! have-answers
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: have-answers ( message -- message/f )
+  dup message-query query->rrs
+  [ empty? ]
+    [ 2drop f ]
+    [ >>answer-section fill-authority fill-additional ]
+  1if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! have-delegates?
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: cdr-name ( name -- name ) dup CHAR: . index 1 + tail ;
+
+: is-soa? ( name -- ? ) SOA IN query boa matching-rrs empty? not ;
+
+: have-ns? ( name -- rrs/f )
+  NS IN query boa matching-rrs [ empty? ] [ drop f ] [ ] 1if ;
+
+: name->delegates ( name -- rrs-ns )
+    {
+      [ "" =    { } and ]
+      [ is-soa? { } and ]
+      [ have-ns? ]
+      [ cdr-name name->delegates ]
+    }
+  1|| ;
+
+: have-delegates ( message -- message/f )
+  dup message-query name>> name->delegates ! message rrs-ns
+  [ empty? ]
+    [ 2drop f ]
+    [
+      dup [ rdata>> A IN query boa matching-rrs ] map concat
+                                           ! message rrs-ns rrs-a
+      [ >>authority-section ]
+      [ >>additional-section ]
+      bi*
+    ]
+  1if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! outsize-zones
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: outside-zones ( message -- message/f )
+  dup message-query name>> name->zone f =
+    [ ]
+    [ drop f ]
+  if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! is-nx
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: is-nx ( message -- message/f )
+  [ message-query name>> records [ name>> = ] with filter empty? ]
+    [
+      NAME-ERROR >>rcode
+      dup
+        message-query name>> name->zone SOA IN query boa matching-rrs
+      >>authority-section
+    ]
+    [ drop f ]
+  1if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: none-of-type ( message -- message )
+  dup
+    message-query name>> name->zone SOA IN query boa matching-rrs
+  >>authority-section ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: find-answer ( message -- message )
+    {
+      [ have-answers   ]
+      [ have-delegates ]
+      [ outside-zones  ]
+      [ is-nx          ]
+      [ none-of-type   ]
+    }
+  1|| ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: (handle-request) ( packet -- )
+  [ [ find-answer ] with-message-bytes ] change-data respond ;
+
+: handle-request ( packet -- ) [ (handle-request) ] curry in-thread ;
+
+: receive-loop ( socket -- )
+  [ receive-packet handle-request ] [ receive-loop ] bi ;
+
+: loop ( addr-spec -- )
+  [ <datagram> '[ _ [ receive-loop ] with-disposal ] try ] [ loop ] bi ;
+
diff --git a/unmaintained/dns/stub/stub.factor b/unmaintained/dns/stub/stub.factor
new file mode 100644 (file)
index 0000000..a15feb5
--- /dev/null
@@ -0,0 +1,20 @@
+
+USING: kernel sequences random accessors dns ;
+
+IN: dns.stub
+
+! Stub resolver
+! 
+! Generally useful, but particularly when running a forwarding,
+! caching, nameserver on localhost with multiple Factor instances
+! querying it.
+
+: name->ip ( name -- ip )
+  A IN query boa
+  query->message
+  ask
+  dup rcode>> NAME-ERROR =
+    [ message-query name>> name-error ]
+    [ answer-section>> [ type>> A = ] filter random rdata>> ]
+  if ;
+
diff --git a/unmaintained/dns/util/util.factor b/unmaintained/dns/util/util.factor
new file mode 100644 (file)
index 0000000..6934d3b
--- /dev/null
@@ -0,0 +1,31 @@
+
+USING: kernel sequences sorting math math.order macros fry ;
+
+IN: dns.util
+
+: tri-chain ( obj p q r -- x y z )
+  [ [ call dup ] dip call dup ] dip call ; inline
+
+MACRO: 1if ( test then else -- ) '[ dup @ _ _ if ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: sort-largest-first ( seq -- seq ) [ length ] sort-with reverse ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: longer? ( seq seq -- ? ) [ length ] bi@ > ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USING: io.sockets accessors ;
+
+TUPLE: packet data addr socket ;
+
+: receive-packet ( socket -- packet ) [ receive ] keep packet boa ;
+
+: respond ( packet -- ) [ data>> ] [ addr>> ] [ socket>> ] tri send ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: forever ( quot: ( -- ) -- ) [ call ] [ forever ] bi ; inline recursive
\ No newline at end of file