From cf18828cca7bc6f8981f5f5119a9aa7151103541 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Tue, 11 Mar 2008 10:38:34 +1100 Subject: [PATCH 01/47] starting bank account stuff --- extra/bank/bank.factor | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 extra/bank/bank.factor diff --git a/extra/bank/bank.factor b/extra/bank/bank.factor new file mode 100644 index 0000000000..c9228bedd5 --- /dev/null +++ b/extra/bank/bank.factor @@ -0,0 +1,33 @@ +USING: accessors calendar kernel money new-slots sequences ; +IN: bank + +MIXIN: policy +TUPLE: simple-policy interest-rate ; +INSTANCE: simple-policy policy +C: simple-policy + +GENERIC: interest-rate ( date account policy -- rate ) +M: simple-policy interest-rate 2nip interest-rate>> ; + +: daily-interest-rate ( date account policy -- rate ) + pick days-in-year >r interest-rate r> / ; + +TUPLE: account name balance transactions ; + +: ( name -- account ) + 0 V{ } clone account construct-boa ; + +TUPLE: transaction date amount description ; + +C: transaction + +: >>transaction ( account transaction -- account ) + over transactions>> push ; + +: open-account ( date opening-balance name -- account ) + >r "Account Opened" >>transaction ; + +: open-account-now ( opening-balance name -- account ) + now -rot open-account ; + + From a7acb16e2002b2f8cb9d77e3753a61aa2d5fb5c0 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Sun, 16 Mar 2008 12:41:13 +1100 Subject: [PATCH 02/47] semantic-db: committing latest changes --- extra/semantic-db/context/context.factor | 8 +-- extra/semantic-db/hierarchy/hierarchy.factor | 13 +++-- .../semantic-db/membership/membership.factor | 6 +++ extra/semantic-db/relations/relations.factor | 2 +- extra/semantic-db/semantic-db-tests.factor | 49 +++++++++---------- 5 files changed, 38 insertions(+), 40 deletions(-) create mode 100644 extra/semantic-db/membership/membership.factor diff --git a/extra/semantic-db/context/context.factor b/extra/semantic-db/context/context.factor index 777c481ebb..9d2e175b5e 100644 --- a/extra/semantic-db/context/context.factor +++ b/extra/semantic-db/context/context.factor @@ -6,11 +6,5 @@ IN: semantic-db.context : create-context* ( context-name -- context-id ) create-node* ; : create-context ( context-name -- ) create-context* drop ; -: context ( -- context-id ) - \ context get ; +SYMBOL: context -: set-context ( context-id -- ) - \ context set ; - -: with-context ( context-id quot -- ) - >r \ context r> with-variable ; diff --git a/extra/semantic-db/hierarchy/hierarchy.factor b/extra/semantic-db/hierarchy/hierarchy.factor index be0789ba5e..f180ddb5df 100644 --- a/extra/semantic-db/hierarchy/hierarchy.factor +++ b/extra/semantic-db/hierarchy/hierarchy.factor @@ -1,32 +1,31 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors db.tuples hashtables kernel new-slots +USING: accessors db.tuples hashtables kernel namespaces new-slots semantic-db semantic-db.relations sequences sequences.deep ; IN: semantic-db.hierarchy TUPLE: tree id children ; C: tree -: has-parent-relation ( -- relation-id ) - "has parent" relation-id ; +SYMBOL: has-parent-relation : parent-child* ( parent child -- arc-id ) - has-parent-relation spin create-arc* ; + has-parent-relation get spin create-arc* ; : parent-child ( parent child -- ) parent-child* drop ; : un-parent-child ( parent child -- ) - has-parent-relation spin select-tuples [ id>> delete-arc ] each ; + has-parent-relation get spin select-tuples [ id>> delete-arc ] each ; : child-arcs ( node-id -- child-arcs ) - has-parent-relation f rot select-tuples ; + has-parent-relation get f rot select-tuples ; : children ( node-id -- children ) child-arcs [ subject>> ] map ; : parent-arcs ( node-id -- parent-arcs ) - has-parent-relation swap f select-tuples ; + has-parent-relation get swap f select-tuples ; : parents ( node-id -- parents ) parent-arcs [ object>> ] map ; diff --git a/extra/semantic-db/membership/membership.factor b/extra/semantic-db/membership/membership.factor new file mode 100644 index 0000000000..c386922979 --- /dev/null +++ b/extra/semantic-db/membership/membership.factor @@ -0,0 +1,6 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel new-slots semantic-db semantic-db.relations ; +IN: semantic-db.membership + + diff --git a/extra/semantic-db/relations/relations.factor b/extra/semantic-db/relations/relations.factor index 17c335c4ae..58003c9e9d 100644 --- a/extra/semantic-db/relations/relations.factor +++ b/extra/semantic-db/relations/relations.factor @@ -23,4 +23,4 @@ IN: semantic-db.relations single-int-results ?first ; : relation-id ( relation-name -- relation-id ) - context swap [ get-relation ] [ create-relation* ] ensure2 ; + context get swap [ get-relation ] [ create-relation* ] ensure2 ; diff --git a/extra/semantic-db/semantic-db-tests.factor b/extra/semantic-db/semantic-db-tests.factor index 257133c67f..fad2ea6332 100644 --- a/extra/semantic-db/semantic-db-tests.factor +++ b/extra/semantic-db/semantic-db-tests.factor @@ -24,16 +24,15 @@ delete-db test-db [ init-semantic-db - "test content" create-context* [ - [ 4 ] [ context ] unit-test - [ 5 ] [ context "is test content" create-relation* ] unit-test - [ 5 ] [ context "is test content" get-relation ] unit-test - [ 5 ] [ "is test content" relation-id ] unit-test - [ 7 ] [ "has parent" relation-id ] unit-test - [ 7 ] [ "has parent" relation-id ] unit-test - [ "has parent" ] [ "has parent" relation-id node-content ] unit-test - [ "test content" ] [ context node-content ] unit-test - ] with-context + "test content" create-context* context set + [ 4 ] [ context get ] unit-test + [ 5 ] [ context get "is test content" create-relation* ] unit-test + [ 5 ] [ context get "is test content" get-relation ] unit-test + [ 5 ] [ "is test content" relation-id ] unit-test + [ 7 ] [ "has parent" relation-id ] unit-test + [ 7 ] [ "has parent" relation-id ] unit-test + [ "has parent" ] [ "has parent" relation-id node-content ] unit-test + [ "test content" ] [ context get node-content ] unit-test ! type-type 1array [ "type" ensure-type ] unit-test ! [ { 1 2 3 } ] [ type-type select-nodes-of-type ] unit-test ! [ 1 ] [ type-type select-node-of-type ] unit-test @@ -52,21 +51,21 @@ delete-db ! test hierarchy test-db [ init-semantic-db - "family tree" create-context* [ - "adam" create-node* "adam" set - "eve" create-node* "eve" set - "bob" create-node* "bob" set - "fran" create-node* "fran" set - "charlie" create-node* "charlie" set - "gertrude" create-node* "gertrude" set - [ t ] [ "adam" get "bob" get parent-child* integer? ] unit-test - { { "eve" "bob" } { "eve" "fran" } { "bob" "gertrude" } { "bob" "fran" } { "fran" "charlie" } } [ first2 [ get ] 2apply parent-child ] each - [ { "bob" "fran" } ] [ "eve" get children [ node-content ] map ] unit-test - [ { "adam" "eve" } ] [ "bob" get parents [ node-content ] map ] unit-test - [ "fran" { "charlie" } ] [ "fran" get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test - [ { "adam" "eve" } ] [ "charlie" get get-root-nodes [ node-content ] map natural-sort >array ] unit-test - [ { } ] [ "fran" get "charlie" get tuck un-parent-child parents [ node-content ] map ] unit-test - ] with-context + "family tree" create-context* context set + "has parent" relation-id has-parent-relation set + "adam" create-node* "adam" set + "eve" create-node* "eve" set + "bob" create-node* "bob" set + "fran" create-node* "fran" set + "charlie" create-node* "charlie" set + "gertrude" create-node* "gertrude" set + [ t ] [ "adam" get "bob" get parent-child* integer? ] unit-test + { { "eve" "bob" } { "eve" "fran" } { "bob" "gertrude" } { "bob" "fran" } { "fran" "charlie" } } [ first2 [ get ] 2apply parent-child ] each + [ { "bob" "fran" } ] [ "eve" get children [ node-content ] map ] unit-test + [ { "adam" "eve" } ] [ "bob" get parents [ node-content ] map ] unit-test + [ "fran" { "charlie" } ] [ "fran" get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test + [ { "adam" "eve" } ] [ "charlie" get get-root-nodes [ node-content ] map natural-sort >array ] unit-test + [ { } ] [ "fran" get "charlie" get tuck un-parent-child parents [ node-content ] map ] unit-test ] with-db delete-db From 09c61d7d0a94d33c60ecd9babce043b0c70547d0 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Sun, 16 Mar 2008 13:25:27 +1100 Subject: [PATCH 03/47] new-graphs: starting a library that has directed and undirected graphs --- extra/new-graphs/new-graphs.factor | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 extra/new-graphs/new-graphs.factor diff --git a/extra/new-graphs/new-graphs.factor b/extra/new-graphs/new-graphs.factor new file mode 100644 index 0000000000..b82ed8a22d --- /dev/null +++ b/extra/new-graphs/new-graphs.factor @@ -0,0 +1,21 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs kernel new-slots sequences vectors ; +IN: new-graphs + +TUPLE: graph edges ; +TUPLE: digraph ; +TUPLE: undigraph ; + +: ( -- graph ) + H{ } clone graph construct-boa H{ } clone over set-delegate ; + +: ( -- graph ) + digraph construct-empty tuck set-delegate ; + +: ( -- graph ) + undigraph construct-empty tuck set-delegate ; + +GENERIC: add-vertex ( key value graph -- ) +M: graph add-vertex ( key value digraph -- ) set-at ; + From c90c0025c7544e54bb696e686a7271f55d55f2f7 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Wed, 19 Mar 2008 21:22:15 +1100 Subject: [PATCH 04/47] semantic-db: move everything into one vocab --- extra/semantic-db/context/context.factor | 10 --- extra/semantic-db/hierarchy/hierarchy.factor | 44 --------- .../semantic-db/membership/membership.factor | 6 -- extra/semantic-db/relations/relations.factor | 26 ------ extra/semantic-db/semantic-db-tests.factor | 66 +++++++------- extra/semantic-db/semantic-db.factor | 90 +++++++++++++++---- 6 files changed, 107 insertions(+), 135 deletions(-) delete mode 100644 extra/semantic-db/context/context.factor delete mode 100644 extra/semantic-db/hierarchy/hierarchy.factor delete mode 100644 extra/semantic-db/membership/membership.factor delete mode 100644 extra/semantic-db/relations/relations.factor diff --git a/extra/semantic-db/context/context.factor b/extra/semantic-db/context/context.factor deleted file mode 100644 index 9d2e175b5e..0000000000 --- a/extra/semantic-db/context/context.factor +++ /dev/null @@ -1,10 +0,0 @@ -! Copyright (C) 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: kernel namespaces semantic-db ; -IN: semantic-db.context - -: create-context* ( context-name -- context-id ) create-node* ; -: create-context ( context-name -- ) create-context* drop ; - -SYMBOL: context - diff --git a/extra/semantic-db/hierarchy/hierarchy.factor b/extra/semantic-db/hierarchy/hierarchy.factor deleted file mode 100644 index f180ddb5df..0000000000 --- a/extra/semantic-db/hierarchy/hierarchy.factor +++ /dev/null @@ -1,44 +0,0 @@ -! Copyright (C) 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: accessors db.tuples hashtables kernel namespaces new-slots -semantic-db semantic-db.relations sequences sequences.deep ; -IN: semantic-db.hierarchy - -TUPLE: tree id children ; -C: tree - -SYMBOL: has-parent-relation - -: parent-child* ( parent child -- arc-id ) - has-parent-relation get spin create-arc* ; - -: parent-child ( parent child -- ) - parent-child* drop ; - -: un-parent-child ( parent child -- ) - has-parent-relation get spin select-tuples [ id>> delete-arc ] each ; - -: child-arcs ( node-id -- child-arcs ) - has-parent-relation get f rot select-tuples ; - -: children ( node-id -- children ) - child-arcs [ subject>> ] map ; - -: parent-arcs ( node-id -- parent-arcs ) - has-parent-relation get swap f select-tuples ; - -: parents ( node-id -- parents ) - parent-arcs [ object>> ] map ; - -: get-node-hierarchy ( node-id -- tree ) - dup children [ get-node-hierarchy ] map ; - -: (get-root-nodes) ( node-id -- root-nodes/node-id ) - dup parents dup empty? [ - drop - ] [ - nip [ (get-root-nodes) ] map - ] if ; - -: get-root-nodes ( node-id -- root-nodes ) - (get-root-nodes) flatten prune ; diff --git a/extra/semantic-db/membership/membership.factor b/extra/semantic-db/membership/membership.factor deleted file mode 100644 index c386922979..0000000000 --- a/extra/semantic-db/membership/membership.factor +++ /dev/null @@ -1,6 +0,0 @@ -! Copyright (C) 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel new-slots semantic-db semantic-db.relations ; -IN: semantic-db.membership - - diff --git a/extra/semantic-db/relations/relations.factor b/extra/semantic-db/relations/relations.factor deleted file mode 100644 index 58003c9e9d..0000000000 --- a/extra/semantic-db/relations/relations.factor +++ /dev/null @@ -1,26 +0,0 @@ -! Copyright (C) 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: db.types kernel namespaces semantic-db semantic-db.context -sequences.lib ; -IN: semantic-db.relations - -! relations: -! - have a context in context 'semantic-db' - -: create-relation* ( context-id relation-name -- relation-id ) - create-node* tuck has-context-relation spin create-arc ; - -: create-relation ( context-id relation-name -- ) - create-relation* drop ; - -: get-relation ( context-id relation-name -- relation-id/f ) - [ - ":name" TEXT param , - ":context" INTEGER param , - has-context-relation ":has_context" INTEGER param , - ] { } make - "select n.id from node n, arc a where n.content = :name and n.id = a.subject and a.relation = :has_context and a.object = :context" - single-int-results ?first ; - -: relation-id ( relation-name -- relation-id ) - context get swap [ get-relation ] [ create-relation* ] ensure2 ; diff --git a/extra/semantic-db/semantic-db-tests.factor b/extra/semantic-db/semantic-db-tests.factor index fad2ea6332..47363b8f5d 100644 --- a/extra/semantic-db/semantic-db-tests.factor +++ b/extra/semantic-db/semantic-db-tests.factor @@ -1,10 +1,12 @@ -USING: accessors arrays continuations db db.sqlite -db.tuples io.files kernel math namespaces semantic-db -semantic-db.context semantic-db.hierarchy -semantic-db.relations sequences sorting tools.test -tools.walker ; +USING: accessors arrays continuations db db.sqlite db.tuples io.files +kernel math namespaces semantic-db + +sequences sorting tools.test tools.walker ; IN: semantic-db.tests +SYMBOL: context +SYMBOL: has-parent-relation + : db-path "semantic-db-test.db" temp-file ; : test-db db-path sqlite-db ; : delete-db [ db-path delete-file ] ignore-errors ; @@ -13,25 +15,25 @@ delete-db test-db [ create-node-table create-arc-table - [ 1 ] [ "first node" create-node* ] unit-test - [ 2 ] [ "second node" create-node* ] unit-test - [ 3 ] [ "third node" create-node* ] unit-test - [ 4 ] [ f create-node* ] unit-test - [ 5 ] [ 1 2 3 create-arc* ] unit-test + [ 1 ] [ "first node" create-node ] unit-test + [ 2 ] [ "second node" create-node ] unit-test + [ 3 ] [ "third node" create-node ] unit-test + [ 4 ] [ f create-node ] unit-test + [ 5 ] [ 1 2 3 create-arc ] unit-test ] with-db delete-db test-db [ init-semantic-db - "test content" create-context* context set + "test content" create-context context set [ 4 ] [ context get ] unit-test - [ 5 ] [ context get "is test content" create-relation* ] unit-test - [ 5 ] [ context get "is test content" get-relation ] unit-test - [ 5 ] [ "is test content" relation-id ] unit-test - [ 7 ] [ "has parent" relation-id ] unit-test - [ 7 ] [ "has parent" relation-id ] unit-test - [ "has parent" ] [ "has parent" relation-id node-content ] unit-test + [ 5 ] [ "is test content" context get create-relation ] unit-test + [ 5 ] [ "is test content" context get get-relation ] unit-test + [ 5 ] [ "is test content" context get relation-id ] unit-test + [ 7 ] [ "has parent" context get relation-id ] unit-test + [ 7 ] [ "has parent" context get relation-id ] unit-test + [ "has parent" ] [ "has parent" context get relation-id node-content ] unit-test [ "test content" ] [ context get node-content ] unit-test ! type-type 1array [ "type" ensure-type ] unit-test ! [ { 1 2 3 } ] [ type-type select-nodes-of-type ] unit-test @@ -51,21 +53,21 @@ delete-db ! test hierarchy test-db [ init-semantic-db - "family tree" create-context* context set - "has parent" relation-id has-parent-relation set - "adam" create-node* "adam" set - "eve" create-node* "eve" set - "bob" create-node* "bob" set - "fran" create-node* "fran" set - "charlie" create-node* "charlie" set - "gertrude" create-node* "gertrude" set - [ t ] [ "adam" get "bob" get parent-child* integer? ] unit-test - { { "eve" "bob" } { "eve" "fran" } { "bob" "gertrude" } { "bob" "fran" } { "fran" "charlie" } } [ first2 [ get ] 2apply parent-child ] each - [ { "bob" "fran" } ] [ "eve" get children [ node-content ] map ] unit-test - [ { "adam" "eve" } ] [ "bob" get parents [ node-content ] map ] unit-test - [ "fran" { "charlie" } ] [ "fran" get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test - [ { "adam" "eve" } ] [ "charlie" get get-root-nodes [ node-content ] map natural-sort >array ] unit-test - [ { } ] [ "fran" get "charlie" get tuck un-parent-child parents [ node-content ] map ] unit-test + "family tree" create-context context set + "has parent" context get relation-id has-parent-relation set + "adam" create-node "adam" set + "eve" create-node "eve" set + "bob" create-node "bob" set + "fran" create-node "fran" set + "charlie" create-node "charlie" set + "gertrude" create-node "gertrude" set + [ t ] [ "adam" get "bob" get has-parent-relation get parent-child integer? ] unit-test + { { "eve" "bob" } { "eve" "fran" } { "bob" "gertrude" } { "bob" "fran" } { "fran" "charlie" } } [ first2 [ get ] 2apply has-parent-relation get parent-child drop ] each + [ { "bob" "fran" } ] [ "eve" get has-parent-relation get children [ node-content ] map ] unit-test + [ { "adam" "eve" } ] [ "bob" get has-parent-relation get parents [ node-content ] map ] unit-test + [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test + [ { "adam" "eve" } ] [ "charlie" get has-parent-relation get get-root-nodes [ node-content ] map natural-sort >array ] unit-test + [ { } ] [ "fran" get "charlie" get tuck has-parent-relation get un-parent-child has-parent-relation get parents [ node-content ] map ] unit-test ] with-db delete-db diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index e8075c016d..340514fd11 100644 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays continuations db db.tuples db.types db.sqlite kernel math math.parser new-slots sequences ; +USING: accessors arrays continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots sequences sequences.deep sequences.lib ; IN: semantic-db TUPLE: node id content ; @@ -22,19 +22,16 @@ node "node" : delete-node ( node-id -- ) delete-tuple ; -: create-node* ( str -- node-id ) +: create-node ( str -- node-id ) dup insert-tuple id>> ; -: create-node ( str -- ) - create-node* drop ; - : node-content ( id -- str ) f swap >>id select-tuple content>> ; -TUPLE: arc id relation subject object ; +TUPLE: arc id subject object relation ; -: ( relation subject object -- arc ) - arc construct-empty swap >>object swap >>subject swap >>relation ; +: ( subject object relation -- arc ) + arc construct-empty swap >>relation swap >>object swap >>subject ; : ( id -- arc ) arc construct-empty swap >>id ; @@ -45,12 +42,9 @@ TUPLE: arc id relation subject object ; : delete-arc ( arc-id -- ) dup delete-node delete-tuple ; -: create-arc* ( relation subject object -- arc-id ) +: create-arc ( subject object relation -- arc-id ) dup insert-arc id>> ; -: create-arc ( relation subject object -- ) - create-arc* drop ; - arc "arc" { { "id" "id" INTEGER +assigned-id+ } ! foreign key to node table? @@ -59,18 +53,17 @@ arc "arc" { "object" "object" INTEGER +not-null+ } } define-persistent -: create-arc-table ( -- ) - arc create-table ; +: create-arc-table ( -- ) arc create-table ; : create-bootstrap-nodes ( -- ) - "semantic-db" create-node - "has context" create-node ; + "semantic-db" create-node drop + "has context" create-node drop ; : semantic-db-context 1 ; : has-context-relation 2 ; : create-bootstrap-arcs ( -- ) - has-context-relation has-context-relation semantic-db-context create-arc ; + has-context-relation semantic-db-context has-context-relation create-arc drop ; : init-semantic-db ( -- ) create-node-table create-arc-table create-bootstrap-nodes create-bootstrap-arcs ; @@ -87,3 +80,66 @@ arc "arc" #! quot2 ( x y -- z ) creates a new z if quot1 returns f >r >r 2dup r> call [ 2nip ] r> if* ; +: create-context ( context-name -- context-id ) create-node ; + +! relations: +! - have a context in context 'semantic-db' + +: create-relation ( relation-name context-id -- relation-id ) + [ create-node dup ] dip has-context-relation create-arc drop ; + +: get-relation ( relation-name context-id -- relation-id/f ) + [ + ":context" INTEGER param , + ":name" TEXT param , + has-context-relation ":has_context" INTEGER param , + ] { } make + "select n.id from node n, arc a where n.content = :name and n.id = a.subject and a.relation = :has_context and a.object = :context" + single-int-results ?first ; + +: relation-id ( relation-name context-id -- relation-id ) + [ get-relation ] [ create-relation ] ensure2 ; + +! hierarchy +TUPLE: tree id children ; +C: tree + +: parent-child ( parent child has-parent-relation -- arc-id ) swapd create-arc ; + +: un-parent-child ( parent child has-parent-relation -- ) + swapd select-tuples [ id>> delete-arc ] each ; + +: child-arcs ( parent-id has-parent-relation -- child-arcs ) + f -rot select-tuples ; + +: children ( node-id has-parent-relation -- children ) + child-arcs [ subject>> ] map ; + +: parent-arcs ( node-id has-parent-relation -- parent-arcs ) + f swap select-tuples ; + +: parents ( node-id has-parent-relation -- parents ) + parent-arcs [ object>> ] map ; + +: get-node-hierarchy ( node-id has-parent-relation -- tree ) + 2dup children >r [ get-node-hierarchy ] curry r> swap map ; + +: (get-root-nodes) ( node-id has-parent-relation -- root-nodes/node-id ) + 2dup parents dup empty? [ + 2drop + ] [ + >r nip [ (get-root-nodes) ] curry r> swap map + ] if ; + +: get-root-nodes ( node-id has-parent-relation -- root-nodes ) + (get-root-nodes) flatten prune ; + +! sets + +: in-set* ( set member in-set-relation -- arc-id ) swapd create-arc ; + +: in-set? ( set member in-set-relation -- ? ) + swapd select-tuples length 0 > ; + +: set-members ( set in-set-relation -- members ) + f -rot select-tuples [ id>> ] map ; From 3df71e5447c05fb6e815124ddd40af66de4ff0cf Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Fri, 21 Mar 2008 02:01:58 +1100 Subject: [PATCH 05/47] semantic-db: add RELATION: --- extra/semantic-db/semantic-db-tests.factor | 31 +++---- extra/semantic-db/semantic-db.factor | 97 ++++++++++++++++------ 2 files changed, 81 insertions(+), 47 deletions(-) diff --git a/extra/semantic-db/semantic-db-tests.factor b/extra/semantic-db/semantic-db-tests.factor index 47363b8f5d..0dccab330b 100644 --- a/extra/semantic-db/semantic-db-tests.factor +++ b/extra/semantic-db/semantic-db-tests.factor @@ -14,15 +14,13 @@ SYMBOL: has-parent-relation delete-db test-db [ - create-node-table create-arc-table + node create-table arc create-table [ 1 ] [ "first node" create-node ] unit-test [ 2 ] [ "second node" create-node ] unit-test [ 3 ] [ "third node" create-node ] unit-test [ 4 ] [ f create-node ] unit-test [ 5 ] [ 1 2 3 create-arc ] unit-test -] with-db - -delete-db +] with-db delete-db test-db [ init-semantic-db @@ -35,20 +33,7 @@ test-db [ [ 7 ] [ "has parent" context get relation-id ] unit-test [ "has parent" ] [ "has parent" context get relation-id node-content ] unit-test [ "test content" ] [ context get node-content ] unit-test - ! type-type 1array [ "type" ensure-type ] unit-test - ! [ { 1 2 3 } ] [ type-type select-nodes-of-type ] unit-test - ! [ 1 ] [ type-type select-node-of-type ] unit-test - ! [ t ] [ "content" ensure-type integer? ] unit-test - ! [ t ] [ "content" ensure-type "content" ensure-type = ] unit-test - ! [ t ] [ "content" ensure-type "first content" create-node-of-type integer? ] unit-test - ! [ t ] [ "content" ensure-type select-node-of-type integer? ] unit-test - ! [ t ] [ "content" ensure-type "first content" select-node-of-type-with-content integer? ] unit-test - ! [ t ] [ "content" ensure-type "first content" ensure-node-of-type integer? ] unit-test - ! [ t ] [ "content" ensure-type "second content" ensure-node-of-type integer? ] unit-test - ! [ 2 ] [ "content" ensure-type select-nodes-of-type length ] unit-test -] with-db - -delete-db +] with-db delete-db ! test hierarchy test-db [ @@ -68,6 +53,12 @@ test-db [ [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test [ { "adam" "eve" } ] [ "charlie" get has-parent-relation get get-root-nodes [ node-content ] map natural-sort >array ] unit-test [ { } ] [ "fran" get "charlie" get tuck has-parent-relation get un-parent-child has-parent-relation get parents [ node-content ] map ] unit-test -] with-db +] with-db delete-db + +RELATION: test-relation + +test-db [ + init-semantic-db + [ 5 ] [ test-relation ] unit-test +] with-db delete-db -delete-db diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index 340514fd11..f73b76327b 100644 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots sequences sequences.deep sequences.lib ; +USING: accessors arrays combinators.cleave continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots parser sequences sequences.deep sequences.lib words ; IN: semantic-db TUPLE: node id content ; @@ -16,9 +16,6 @@ node "node" { "content" "content" TEXT } } define-persistent -: create-node-table ( -- ) - node create-table ; - : delete-node ( node-id -- ) delete-tuple ; @@ -45,6 +42,30 @@ TUPLE: arc id subject object relation ; : create-arc ( subject object relation -- arc-id ) dup insert-arc id>> ; +: has-arc? ( subject object relation -- ? ) + select-tuples length 0 > ; + +: select-arcs ( subject object relation -- arcs ) + select-tuples ; + +: select-arc-ids ( subject object relation -- arc-ids ) + select-arcs [ id>> ] map ; + +: select-arc-subjects ( subject object relation -- subject-ids ) + select-arcs [ subject>> ] map ; + +: select-arc-objects ( subject object relation -- object-ids ) + select-arcs [ object>> ] map ; + +: delete-arcs ( subject object relation -- ) + select-arcs [ id>> delete-arc ] each ; + +: subject-relation ( subject relation -- subject object relation ) + f swap ; + +: object-relation ( object relation -- subject object relation ) + f -rot ; + arc "arc" { { "id" "id" INTEGER +assigned-id+ } ! foreign key to node table? @@ -53,20 +74,20 @@ arc "arc" { "object" "object" INTEGER +not-null+ } } define-persistent -: create-arc-table ( -- ) arc create-table ; - : create-bootstrap-nodes ( -- ) "semantic-db" create-node drop - "has context" create-node drop ; + "has-context" create-node drop ; -: semantic-db-context 1 ; +: semantic-db-context 1 ; : has-context-relation 2 ; : create-bootstrap-arcs ( -- ) has-context-relation semantic-db-context has-context-relation create-arc drop ; : init-semantic-db ( -- ) - create-node-table create-arc-table create-bootstrap-nodes create-bootstrap-arcs ; + node create-table + arc create-table + create-bootstrap-nodes create-bootstrap-arcs ; : param ( value key type -- param ) swapd 3array ; @@ -75,13 +96,31 @@ arc "arc" f f [ do-bound-query ] with-disposal [ first string>number ] map ; +: ensure1 ( x quot1 quot2 -- y ) + #! quot1 ( x -- y/f ) tries to find an existing y + #! quot2 ( x -- y ) creates a new y if quot1 returns f + >r dupd call [ nip ] r> if* ; + : ensure2 ( x y quot1 quot2 -- z ) - #! quot1 ( x y -- z/f ) finds an existing z + #! quot1 ( x y -- z/f ) tries to find an existing z #! quot2 ( x y -- z ) creates a new z if quot1 returns f >r >r 2dup r> call [ 2nip ] r> if* ; +! contexts: +! - a node n is a context iff there exists a relation r such that r has context n : create-context ( context-name -- context-id ) create-node ; +: get-context ( context-name -- context-id/f ) + [ + ":name" TEXT param , + has-context-relation ":has_context" INTEGER param , + ] { } make + "select distinct n.id from node n, arc a where n.content = :name and a.relation = :has_context and a.object = n.id" + single-int-results ?first ; + +: context-id ( context-name -- context-id ) + [ get-context ] [ create-context ] ensure1 ; + ! relations: ! - have a context in context 'semantic-db' @@ -100,26 +139,28 @@ arc "arc" : relation-id ( relation-name context-id -- relation-id ) [ get-relation ] [ create-relation ] ensure2 ; +! RELATION: is-fooey +! - define a word is-fooey in the current vocab (foo), that when called: +! - finds or creates a node called "is-fooey" with context "foo", and returns its id +: RELATION: + CREATE-WORD dup [ word-name ] [ word-vocabulary ] bi + [ context-id relation-id ] 2curry define ; parsing + ! hierarchy TUPLE: tree id children ; C: tree -: parent-child ( parent child has-parent-relation -- arc-id ) swapd create-arc ; +: parent-child ( parent child has-parent-relation -- arc-id ) + swapd create-arc ; : un-parent-child ( parent child has-parent-relation -- ) - swapd select-tuples [ id>> delete-arc ] each ; - -: child-arcs ( parent-id has-parent-relation -- child-arcs ) - f -rot select-tuples ; + swapd delete-arcs ; : children ( node-id has-parent-relation -- children ) - child-arcs [ subject>> ] map ; - -: parent-arcs ( node-id has-parent-relation -- parent-arcs ) - f swap select-tuples ; + object-relation select-arc-subjects ; : parents ( node-id has-parent-relation -- parents ) - parent-arcs [ object>> ] map ; + subject-relation select-arc-objects ; : get-node-hierarchy ( node-id has-parent-relation -- tree ) 2dup children >r [ get-node-hierarchy ] curry r> swap map ; @@ -135,11 +176,13 @@ C: tree (get-root-nodes) flatten prune ; ! sets - -: in-set* ( set member in-set-relation -- arc-id ) swapd create-arc ; - -: in-set? ( set member in-set-relation -- ? ) - swapd select-tuples length 0 > ; - +: in-set ( member set in-set-relation -- arc-id ) create-arc ; +: in-set? ( member set in-set-relation -- ? ) has-arc? ; : set-members ( set in-set-relation -- members ) - f -rot select-tuples [ id>> ] map ; + object-relation select-arc-subjects ; + +! attributes +: has-attribute ( node value has-attribute-relation -- arc-id ) create-arc ; +: has-attribute? ( node value has-attribute-relation -- ? ) has-arc? ; +: nodes-with-attribute ( value has-attribute-relation -- node-ids ) + object-relation select-arc-subjects ; From 43aba96e8c858617638edf8e5ff3796f24f2b4f8 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Tue, 25 Mar 2008 17:38:14 +1100 Subject: [PATCH 06/47] semantic-db: new RELATION: syntax --- extra/semantic-db/semantic-db-tests.factor | 81 +++++++++--------- extra/semantic-db/semantic-db.factor | 96 ++++++++++++++-------- 2 files changed, 102 insertions(+), 75 deletions(-) diff --git a/extra/semantic-db/semantic-db-tests.factor b/extra/semantic-db/semantic-db-tests.factor index 0dccab330b..7fa0ff2176 100644 --- a/extra/semantic-db/semantic-db-tests.factor +++ b/extra/semantic-db/semantic-db-tests.factor @@ -5,7 +5,6 @@ sequences sorting tools.test tools.walker ; IN: semantic-db.tests SYMBOL: context -SYMBOL: has-parent-relation : db-path "semantic-db-test.db" temp-file ; : test-db db-path sqlite-db ; @@ -22,43 +21,43 @@ test-db [ [ 5 ] [ 1 2 3 create-arc ] unit-test ] with-db delete-db -test-db [ - init-semantic-db - "test content" create-context context set - [ 4 ] [ context get ] unit-test - [ 5 ] [ "is test content" context get create-relation ] unit-test - [ 5 ] [ "is test content" context get get-relation ] unit-test - [ 5 ] [ "is test content" context get relation-id ] unit-test - [ 7 ] [ "has parent" context get relation-id ] unit-test - [ 7 ] [ "has parent" context get relation-id ] unit-test - [ "has parent" ] [ "has parent" context get relation-id node-content ] unit-test - [ "test content" ] [ context get node-content ] unit-test -] with-db delete-db - -! test hierarchy -test-db [ - init-semantic-db - "family tree" create-context context set - "has parent" context get relation-id has-parent-relation set - "adam" create-node "adam" set - "eve" create-node "eve" set - "bob" create-node "bob" set - "fran" create-node "fran" set - "charlie" create-node "charlie" set - "gertrude" create-node "gertrude" set - [ t ] [ "adam" get "bob" get has-parent-relation get parent-child integer? ] unit-test - { { "eve" "bob" } { "eve" "fran" } { "bob" "gertrude" } { "bob" "fran" } { "fran" "charlie" } } [ first2 [ get ] 2apply has-parent-relation get parent-child drop ] each - [ { "bob" "fran" } ] [ "eve" get has-parent-relation get children [ node-content ] map ] unit-test - [ { "adam" "eve" } ] [ "bob" get has-parent-relation get parents [ node-content ] map ] unit-test - [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test - [ { "adam" "eve" } ] [ "charlie" get has-parent-relation get get-root-nodes [ node-content ] map natural-sort >array ] unit-test - [ { } ] [ "fran" get "charlie" get tuck has-parent-relation get un-parent-child has-parent-relation get parents [ node-content ] map ] unit-test -] with-db delete-db - -RELATION: test-relation - -test-db [ - init-semantic-db - [ 5 ] [ test-relation ] unit-test -] with-db delete-db - + test-db [ + init-semantic-db + "test content" create-context context set + [ 4 ] [ context get ] unit-test + [ 5 ] [ "is test content" context get create-relation ] unit-test + [ 5 ] [ "is test content" context get get-relation ] unit-test + [ 5 ] [ "is test content" context get relation-id ] unit-test + [ 7 ] [ "has parent" context get relation-id ] unit-test + [ 7 ] [ "has parent" context get relation-id ] unit-test + [ "has parent" ] [ "has parent" context get relation-id node-content ] unit-test + [ "test content" ] [ context get node-content ] unit-test + ] with-db delete-db + + ! "test1" f f f f f define-relation + ! "test2" t t t t t define-relation + RELATION: test + test-db [ + init-semantic-db + [ 5 ] [ test-relation ] unit-test + ] with-db delete-db + + ! test hierarchy + RELATION: has-parent + test-db [ + init-semantic-db + "adam" create-node "adam" set + "eve" create-node "eve" set + "bob" create-node "bob" set + "fran" create-node "fran" set + "charlie" create-node "charlie" set + "gertrude" create-node "gertrude" set + [ t ] [ "bob" get "adam" get has-parent integer? ] unit-test + { { "bob" "eve" } { "fran" "eve" } { "gertrude" "bob" } { "fran" "bob" } { "charlie" "fran" } } [ first2 [ get ] 2apply has-parent drop ] each + [ { "bob" "fran" } ] [ "eve" get has-parent-relation children [ node-content ] map ] unit-test + [ { "adam" "eve" } ] [ "bob" get has-parent-relation parents [ node-content ] map ] unit-test + [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test + [ { "adam" "eve" } ] [ "charlie" get has-parent-relation get-root-nodes [ node-content ] map natural-sort >array ] unit-test + [ { } ] [ "charlie" get dup "fran" get !has-parent has-parent-relation parents [ node-content ] map ] unit-test + ] with-db delete-db + diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index f73b76327b..d4e2c1ed1a 100644 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays combinators.cleave continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots parser sequences sequences.deep sequences.lib words ; +USING: accessors arrays combinators combinators.cleave continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots parser sequences sequences.deep sequences.lib strings words ; IN: semantic-db TUPLE: node id content ; @@ -54,18 +54,18 @@ TUPLE: arc id subject object relation ; : select-arc-subjects ( subject object relation -- subject-ids ) select-arcs [ subject>> ] map ; +: select-subjects ( object relation -- subject-ids ) + f -rot select-arc-subjects ; + : select-arc-objects ( subject object relation -- object-ids ) select-arcs [ object>> ] map ; +: select-objects ( subject relation -- object-ids ) + f swap select-arc-objects ; + : delete-arcs ( subject object relation -- ) select-arcs [ id>> delete-arc ] each ; -: subject-relation ( subject relation -- subject object relation ) - f swap ; - -: object-relation ( object relation -- subject object relation ) - f -rot ; - arc "arc" { { "id" "id" INTEGER +assigned-id+ } ! foreign key to node table? @@ -139,28 +139,67 @@ arc "arc" : relation-id ( relation-name context-id -- relation-id ) [ get-relation ] [ create-relation ] ensure2 ; -! RELATION: is-fooey -! - define a word is-fooey in the current vocab (foo), that when called: -! - finds or creates a node called "is-fooey" with context "foo", and returns its id +TUPLE: relation-definition relate id-word unrelate related? subjects objects ; +C: relation-definition + +> ] dip default-word-name + ] if ; + +: (define-relation-word) ( id-word word-name definition -- id-word ) + >r create-in over [ execute ] curry r> compose define ; + +: define-relation-word ( relation-definition id-word given-word-name word-type definition -- relation-definition id-word ) + >r >r [ + pick swap r> choose-word-name r> (define-relation-word) + ] [ + r> r> 2drop + ] if* ; + +: define-relation-words ( relation-definition id-word -- ) + over relate>> "relate" [ create-arc ] define-relation-word + over unrelate>> "unrelate" [ delete-arcs ] define-relation-word + over related?>> "related?" [ has-arc? ] define-relation-word + over subjects>> "subjects" [ select-subjects ] define-relation-word + over objects>> "objects" [ select-objects ] define-relation-word + 2drop ; + +: define-id-word ( relation-definition id-word -- ) + [ relate>> ] dip tuck word-vocabulary + [ context-id relation-id ] 2curry define ; + +: create-id-word ( relation-definition -- id-word ) + dup id-word>> "id-word" choose-word-name create-in ; + +PRIVATE> + +: define-relation ( relation-definition -- ) + dup create-id-word 2dup define-id-word define-relation-words ; + : RELATION: - CREATE-WORD dup [ word-name ] [ word-vocabulary ] bi - [ context-id relation-id ] 2curry define ; parsing + scan t t t t t define-relation ; parsing ! hierarchy TUPLE: tree id children ; C: tree -: parent-child ( parent child has-parent-relation -- arc-id ) - swapd create-arc ; - -: un-parent-child ( parent child has-parent-relation -- ) - swapd delete-arcs ; - -: children ( node-id has-parent-relation -- children ) - object-relation select-arc-subjects ; - -: parents ( node-id has-parent-relation -- parents ) - subject-relation select-arc-objects ; +: children ( node-id has-parent-relation -- children ) select-subjects ; +: parents ( node-id has-parent-relation -- parents ) select-objects ; : get-node-hierarchy ( node-id has-parent-relation -- tree ) 2dup children >r [ get-node-hierarchy ] curry r> swap map ; @@ -175,14 +214,3 @@ C: tree : get-root-nodes ( node-id has-parent-relation -- root-nodes ) (get-root-nodes) flatten prune ; -! sets -: in-set ( member set in-set-relation -- arc-id ) create-arc ; -: in-set? ( member set in-set-relation -- ? ) has-arc? ; -: set-members ( set in-set-relation -- members ) - object-relation select-arc-subjects ; - -! attributes -: has-attribute ( node value has-attribute-relation -- arc-id ) create-arc ; -: has-attribute? ( node value has-attribute-relation -- ? ) has-arc? ; -: nodes-with-attribute ( value has-attribute-relation -- node-ids ) - object-relation select-arc-subjects ; From 18a09b54b1619e35ac3f8b9cfb309fca38fee245 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Tue, 25 Mar 2008 23:00:06 +1100 Subject: [PATCH 07/47] semantic-db: trivial change --- extra/semantic-db/semantic-db.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index d4e2c1ed1a..ee276260f3 100644 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -23,7 +23,7 @@ node "node" dup insert-tuple id>> ; : node-content ( id -- str ) - f swap >>id select-tuple content>> ; + select-tuple content>> ; TUPLE: arc id subject object relation ; From 4c449296b207fba5ba4de2125e0e6beb5ef93292 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 27 Mar 2008 11:18:32 -0500 Subject: [PATCH 08/47] Fix NetBSD FFI --- core/cpu/x86/architecture/architecture.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cpu/x86/architecture/architecture.factor b/core/cpu/x86/architecture/architecture.factor index 49b05ea48f..f993639c05 100755 --- a/core/cpu/x86/architecture/architecture.factor +++ b/core/cpu/x86/architecture/architecture.factor @@ -156,7 +156,7 @@ M: x86-backend %unbox-small-struct ( size -- ) M: x86-backend struct-small-enough? ( size -- ? ) { 1 2 4 8 } member? - os { "linux" "solaris" } member? not and ; + os { "linux" "netbsd" "solaris" } member? not and ; M: x86-backend %return ( -- ) 0 %unwind ; From aad587d6647607042bbbed72e59cbbb67d801c46 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 27 Mar 2008 11:48:51 -0500 Subject: [PATCH 09/47] Fix deploy test --- extra/tools/deploy/deploy-tests.factor | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extra/tools/deploy/deploy-tests.factor b/extra/tools/deploy/deploy-tests.factor index 8db34320de..5030763a3d 100755 --- a/extra/tools/deploy/deploy-tests.factor +++ b/extra/tools/deploy/deploy-tests.factor @@ -1,10 +1,11 @@ IN: tools.deploy.tests USING: tools.test system io.files kernel tools.deploy.config tools.deploy.backend math sequences io.launcher arrays -namespaces ; +namespaces continuations ; : shake-and-bake ( vocab -- ) - "." resource-path [ + [ "test.image" temp-file delete-file ] ignore-errors + "resource:" [ >r vm "test.image" temp-file r> dup deploy-config make-deploy-image From 5dd354333ff18503d54b54ab81d96acd8b18e08a Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Tue, 1 Apr 2008 12:07:02 +1100 Subject: [PATCH 10/47] semantic-db: pass around node objects instead of ids --- extra/semantic-db/semantic-db-tests.factor | 45 ++-- extra/semantic-db/semantic-db.factor | 227 +++++++++++++-------- 2 files changed, 169 insertions(+), 103 deletions(-) diff --git a/extra/semantic-db/semantic-db-tests.factor b/extra/semantic-db/semantic-db-tests.factor index 7fa0ff2176..ac620de4d9 100644 --- a/extra/semantic-db/semantic-db-tests.factor +++ b/extra/semantic-db/semantic-db-tests.factor @@ -1,7 +1,6 @@ USING: accessors arrays continuations db db.sqlite db.tuples io.files -kernel math namespaces semantic-db - -sequences sorting tools.test tools.walker ; +kernel math namespaces semantic-db sequences sorting tools.test +tools.walker ; IN: semantic-db.tests SYMBOL: context @@ -14,32 +13,34 @@ delete-db test-db [ node create-table arc create-table - [ 1 ] [ "first node" create-node ] unit-test - [ 2 ] [ "second node" create-node ] unit-test - [ 3 ] [ "third node" create-node ] unit-test - [ 4 ] [ f create-node ] unit-test - [ 5 ] [ 1 2 3 create-arc ] unit-test + [ 1 ] [ "first node" create-node id>> ] unit-test + [ 2 ] [ "second node" create-node id>> ] unit-test + [ 3 ] [ "third node" create-node id>> ] unit-test + [ 4 ] [ f create-node id>> ] unit-test + [ ] [ 1 f 2 f 3 f create-arc ] unit-test ] with-db delete-db test-db [ init-semantic-db "test content" create-context context set - [ 4 ] [ context get ] unit-test - [ 5 ] [ "is test content" context get create-relation ] unit-test - [ 5 ] [ "is test content" context get get-relation ] unit-test - [ 5 ] [ "is test content" context get relation-id ] unit-test - [ 7 ] [ "has parent" context get relation-id ] unit-test - [ 7 ] [ "has parent" context get relation-id ] unit-test - [ "has parent" ] [ "has parent" context get relation-id node-content ] unit-test + [ T{ node f 3 "test content" } ] [ context get ] unit-test + [ T{ node f 4 "is test content" } ] [ "is test content" context get create-relation ] unit-test + [ T{ node f 4 "is test content" } ] [ "is test content" context get get-relation ] unit-test + [ T{ node f 4 "is test content" } ] [ "is test content" context get ensure-relation ] unit-test + [ T{ node f 5 "has parent" } ] [ "has parent" context get ensure-relation ] unit-test + [ T{ node f 5 "has parent" } ] [ "has parent" context get ensure-relation ] unit-test + [ "has parent" ] [ "has parent" context get ensure-relation node-content ] unit-test [ "test content" ] [ context get node-content ] unit-test ] with-db delete-db - ! "test1" f f f f f define-relation + ! "test1" "test1-relation-id-word" f f f f define-relation ! "test2" t t t t t define-relation - RELATION: test + RELATION: test3 test-db [ init-semantic-db - [ 5 ] [ test-relation ] unit-test + ! [ T{ node f 3 "test1" } ] [ test1-relation-id-word ] unit-test + ! [ T{ node f 4 "test2" } ] [ test2-relation ] unit-test + [ T{ node f 4 "test3" } ] [ test3-relation ] unit-test ] with-db delete-db ! test hierarchy @@ -52,12 +53,14 @@ test-db [ "fran" create-node "fran" set "charlie" create-node "charlie" set "gertrude" create-node "gertrude" set - [ t ] [ "bob" get "adam" get has-parent integer? ] unit-test - { { "bob" "eve" } { "fran" "eve" } { "gertrude" "bob" } { "fran" "bob" } { "charlie" "fran" } } [ first2 [ get ] 2apply has-parent drop ] each + [ ] [ "bob" get "adam" get has-parent ] unit-test + { { "bob" "eve" } { "fran" "eve" } { "gertrude" "bob" } { "fran" "bob" } { "charlie" "fran" } } [ first2 [ get ] 2apply has-parent ] each [ { "bob" "fran" } ] [ "eve" get has-parent-relation children [ node-content ] map ] unit-test [ { "adam" "eve" } ] [ "bob" get has-parent-relation parents [ node-content ] map ] unit-test - [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get-node-hierarchy dup tree-id node-content swap tree-children [ tree-id node-content ] map ] unit-test + [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get-node-hierarchy dup node>> node-content swap children>> [ node>> node-content ] map ] unit-test [ { "adam" "eve" } ] [ "charlie" get has-parent-relation get-root-nodes [ node-content ] map natural-sort >array ] unit-test [ { } ] [ "charlie" get dup "fran" get !has-parent has-parent-relation parents [ node-content ] map ] unit-test + [ { "adam" "eve" } ] [ has-parent-relation ultimate-objects node-results [ node-content ] map ] unit-test + [ { "fran" "gertrude" } ] [ has-parent-relation ultimate-subjects node-results [ node-content ] map ] unit-test ] with-db delete-db diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index ee276260f3..2500441b11 100755 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -1,14 +1,13 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays combinators combinators.cleave continuations db db.tuples db.types db.sqlite hashtables kernel math math.parser namespaces new-slots parser sequences sequences.deep sequences.lib strings words ; +USING: accessors arrays combinators combinators.cleave combinators.lib +continuations db db.tuples db.types db.sqlite hashtables kernel math +math.parser namespaces parser sequences sequences.deep +sequences.lib strings words ; IN: semantic-db TUPLE: node id content ; -: ( content -- node ) - node construct-empty swap >>content ; - -: ( id -- node ) - node construct-empty swap >>id ; +C: node node "node" { @@ -16,15 +15,14 @@ node "node" { "content" "content" TEXT } } define-persistent -: delete-node ( node-id -- ) - delete-tuple ; +: delete-node ( node -- ) delete-tuple ; +: create-node ( content -- node ) f swap dup insert-tuple ; +: load-node ( id -- node ) f select-tuple ; -: create-node ( str -- node-id ) - dup insert-tuple id>> ; - -: node-content ( id -- str ) - select-tuple content>> ; +: node-content ( node -- content ) + dup content>> [ nip ] [ select-tuple content>> ] if* ; +! TODO: get rid of arc id and write our own sql TUPLE: arc id subject object relation ; : ( subject object relation -- arc ) @@ -33,42 +31,50 @@ TUPLE: arc id subject object relation ; : ( id -- arc ) arc construct-empty swap >>id ; -: insert-arc ( arc -- ) - f dup insert-tuple id>> >>id insert-tuple ; +: delete-arc ( arc -- ) delete-tuple ; -: delete-arc ( arc-id -- ) - dup delete-node delete-tuple ; +: create-arc ( subject object relation -- ) + [ id>> ] 3apply insert-tuple ; -: create-arc ( subject object relation -- arc-id ) - dup insert-arc id>> ; - -: has-arc? ( subject object relation -- ? ) - select-tuples length 0 > ; +: nodes>arc ( subject object relation -- arc ) + [ [ id>> ] [ f ] if* ] 3apply ; : select-arcs ( subject object relation -- arcs ) - select-tuples ; + nodes>arc select-tuples ; -: select-arc-ids ( subject object relation -- arc-ids ) - select-arcs [ id>> ] map ; +: has-arc? ( subject object relation -- ? ) + select-arcs length 0 > ; -: select-arc-subjects ( subject object relation -- subject-ids ) - select-arcs [ subject>> ] map ; +: select-arc-subjects ( subject object relation -- subjects ) + select-arcs [ subject>> f ] map ; -: select-subjects ( object relation -- subject-ids ) +: select-arc-subject ( subject object relation -- subject ) + select-arcs ?first [ subject>> f ] [ f ] if* ; + +: select-subjects ( object relation -- subjects ) f -rot select-arc-subjects ; -: select-arc-objects ( subject object relation -- object-ids ) - select-arcs [ object>> ] map ; +: select-subject ( object relation -- subject ) + f -rot select-arc-subject ; -: select-objects ( subject relation -- object-ids ) +: select-arc-objects ( subject object relation -- objects ) + select-arcs [ object>> f ] map ; + +: select-arc-object ( subject object relation -- object ) + select-arcs ?first [ object>> f ] [ f ] if* ; + +: select-objects ( subject relation -- objects ) f swap select-arc-objects ; +: select-object ( subject relation -- object ) + f swap select-arc-object ; + : delete-arcs ( subject object relation -- ) - select-arcs [ id>> delete-arc ] each ; + select-arcs [ delete-arc ] each ; arc "arc" { - { "id" "id" INTEGER +assigned-id+ } ! foreign key to node table? + { "id" "id" +native-id+ +autoincrement+ } { "relation" "relation" INTEGER +not-null+ } { "subject" "subject" INTEGER +not-null+ } { "object" "object" INTEGER +not-null+ } @@ -78,66 +84,99 @@ arc "arc" "semantic-db" create-node drop "has-context" create-node drop ; -: semantic-db-context 1 ; -: has-context-relation 2 ; +: semantic-db-context T{ node f 1 "semantic-db" } ; +: has-context-relation T{ node f 2 "has-context" } ; : create-bootstrap-arcs ( -- ) - has-context-relation semantic-db-context has-context-relation create-arc drop ; + has-context-relation semantic-db-context has-context-relation create-arc ; : init-semantic-db ( -- ) - node create-table - arc create-table + node create-table arc create-table create-bootstrap-nodes create-bootstrap-arcs ; -: param ( value key type -- param ) - swapd 3array ; +: param ( value key type -- param ) swapd 3array ; -: single-int-results ( bindings sql -- array ) - f f [ do-bound-query ] with-disposal - [ first string>number ] map ; +! db utilities +: results ( bindings sql -- array ) + f f [ do-bound-query ] with-disposal ; -: ensure1 ( x quot1 quot2 -- y ) - #! quot1 ( x -- y/f ) tries to find an existing y - #! quot2 ( x -- y ) creates a new y if quot1 returns f - >r dupd call [ nip ] r> if* ; +: node-result ( result -- node ) + dup first string>number swap second ; -: ensure2 ( x y quot1 quot2 -- z ) - #! quot1 ( x y -- z/f ) tries to find an existing z - #! quot2 ( x y -- z ) creates a new z if quot1 returns f - >r >r 2dup r> call [ 2nip ] r> if* ; +: ?1node-result ( results -- node ) + ?first [ node-result ] [ f ] if* ; + +: node-results ( results -- nodes ) + [ node-result ] map ; + +: subjects-with-cor ( content object relation -- sql-results ) + [ id>> ] 2apply + [ + ":relation" INTEGER param , + ":object" INTEGER param , + ":content" TEXT param , + ] { } make + "select n.id, n.content from node n, arc a where n.content = :content and n.id = a.subject and a.relation = :relation and a.object = :object" results ; + +: objects-with-csr ( content subject relation -- sql-results ) + [ id>> ] 2apply + [ + ":relation" INTEGER param , + ":subject" INTEGER param , + ":content" TEXT param , + ] { } make + "select n.id, n.content from node n, arc a where n.content = :content and n.id = a.object and a.relation = :relation and a.subject = :subject" results ; + +: (with-relation) ( content relation -- bindings sql ) + id>> [ ":relation" INTEGER param , ":content" TEXT param , ] { } make + "select distinct n.id, n.content from node n, arc a where n.content = :content and a.relation = :relation" ; + +: subjects-with-relation ( content relation -- sql-results ) + (with-relation) " and a.object = n.id" append results ; + +: objects-with-relation ( content relation -- sql-results ) + (with-relation) " and a.subject = n.id" append results ; + +: (ultimate) ( relation b a -- sql-results ) + [ + "select distinct n.id, n.content from node n, arc a where a.relation = :relation and n.id = a." % % " and n.id not in (select b." % % " from arc b where b.relation = :relation)" % + ] "" make [ id>> ":relation" INTEGER param 1array ] dip results ; + +: ultimate-objects ( relation -- sql-results ) + "subject" "object" (ultimate) ; + +: ultimate-subjects ( relation -- sql-results ) + "object" "subject" (ultimate) ; ! contexts: ! - a node n is a context iff there exists a relation r such that r has context n -: create-context ( context-name -- context-id ) create-node ; +: create-context ( context-name -- context ) create-node ; -: get-context ( context-name -- context-id/f ) - [ - ":name" TEXT param , - has-context-relation ":has_context" INTEGER param , - ] { } make - "select distinct n.id from node n, arc a where n.content = :name and a.relation = :has_context and a.object = n.id" - single-int-results ?first ; +: get-context ( context-name -- context/f ) + has-context-relation subjects-with-relation ?1node-result ; -: context-id ( context-name -- context-id ) - [ get-context ] [ create-context ] ensure1 ; +: ensure-context ( context-name -- context ) + dup get-context [ + nip + ] [ + create-context + ] if* ; ! relations: ! - have a context in context 'semantic-db' -: create-relation ( relation-name context-id -- relation-id ) - [ create-node dup ] dip has-context-relation create-arc drop ; +: create-relation ( relation-name context -- relation ) + [ create-node dup ] dip has-context-relation create-arc ; -: get-relation ( relation-name context-id -- relation-id/f ) - [ - ":context" INTEGER param , - ":name" TEXT param , - has-context-relation ":has_context" INTEGER param , - ] { } make - "select n.id from node n, arc a where n.content = :name and n.id = a.subject and a.relation = :has_context and a.object = :context" - single-int-results ?first ; +: get-relation ( relation-name context -- relation/f ) + has-context-relation subjects-with-cor ?1node-result ; -: relation-id ( relation-name context-id -- relation-id ) - [ get-relation ] [ create-relation ] ensure2 ; +: ensure-relation ( relation-name context -- relation ) + 2dup get-relation [ + 2nip + ] [ + create-relation + ] if* ; TUPLE: relation-definition relate id-word unrelate related? subjects objects ; C: relation-definition @@ -181,7 +220,7 @@ C: relation-definition : define-id-word ( relation-definition id-word -- ) [ relate>> ] dip tuck word-vocabulary - [ context-id relation-id ] 2curry define ; + [ ensure-context ensure-relation ] 2curry define ; : create-id-word ( relation-definition -- id-word ) dup id-word>> "id-word" choose-word-name create-in ; @@ -195,22 +234,46 @@ PRIVATE> scan t t t t t define-relation ; parsing ! hierarchy -TUPLE: tree id children ; -C: tree +TUPLE: node-tree node children ; +C: node-tree -: children ( node-id has-parent-relation -- children ) select-subjects ; -: parents ( node-id has-parent-relation -- parents ) select-objects ; +: children ( node has-parent-relation -- children ) select-subjects ; +: parents ( node has-parent-relation -- parents ) select-objects ; -: get-node-hierarchy ( node-id has-parent-relation -- tree ) - 2dup children >r [ get-node-hierarchy ] curry r> swap map ; +: get-node-tree ( node child-selector -- node-tree ) + 2dup call >r [ get-node-tree ] curry r> swap map ; -: (get-root-nodes) ( node-id has-parent-relation -- root-nodes/node-id ) +! : get-node-tree ( node has-parent-relation -- node-tree ) +! 2dup children >r [ get-node-tree ] curry r> swap map ; +: get-node-tree-s ( node has-parent-relation -- tree ) + [ select-subjects ] curry get-node-tree ; + +: get-node-tree-o ( node has-child-relation -- tree ) + [ select-objects ] curry get-node-tree ; + +: (get-node-chain) ( node next-selector seq -- seq ) + pick [ + over push >r [ call ] keep r> (get-node-chain) + ] [ + 2nip + ] if* ; + +: get-node-chain ( node next-selector -- seq ) + V{ } clone (get-node-chain) ; + +: get-node-chain-o ( node relation -- seq ) + [ select-object ] curry get-node-chain ; + +: get-node-chain-s ( node relation -- seq ) + [ select-subject ] curry get-node-chain ; + +: (get-root-nodes) ( node has-parent-relation -- root-nodes/node ) 2dup parents dup empty? [ 2drop ] [ >r nip [ (get-root-nodes) ] curry r> swap map ] if ; -: get-root-nodes ( node-id has-parent-relation -- root-nodes ) +: get-root-nodes ( node has-parent-relation -- root-nodes ) (get-root-nodes) flatten prune ; From e8abcf8d8583c917ba85790d21f775778f7d716e Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Tue, 1 Apr 2008 13:41:03 +1100 Subject: [PATCH 11/47] semantic-db: change 2apply to bi@ --- extra/semantic-db/semantic-db-tests.factor | 4 ++-- extra/semantic-db/semantic-db.factor | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/semantic-db/semantic-db-tests.factor b/extra/semantic-db/semantic-db-tests.factor index ac620de4d9..8fec6d5cbb 100644 --- a/extra/semantic-db/semantic-db-tests.factor +++ b/extra/semantic-db/semantic-db-tests.factor @@ -54,10 +54,10 @@ test-db [ "charlie" create-node "charlie" set "gertrude" create-node "gertrude" set [ ] [ "bob" get "adam" get has-parent ] unit-test - { { "bob" "eve" } { "fran" "eve" } { "gertrude" "bob" } { "fran" "bob" } { "charlie" "fran" } } [ first2 [ get ] 2apply has-parent ] each + { { "bob" "eve" } { "fran" "eve" } { "gertrude" "bob" } { "fran" "bob" } { "charlie" "fran" } } [ first2 [ get ] bi@ has-parent ] each [ { "bob" "fran" } ] [ "eve" get has-parent-relation children [ node-content ] map ] unit-test [ { "adam" "eve" } ] [ "bob" get has-parent-relation parents [ node-content ] map ] unit-test - [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get-node-hierarchy dup node>> node-content swap children>> [ node>> node-content ] map ] unit-test + [ "fran" { "charlie" } ] [ "fran" get has-parent-relation get-node-tree-s dup node>> node-content swap children>> [ node>> node-content ] map ] unit-test [ { "adam" "eve" } ] [ "charlie" get has-parent-relation get-root-nodes [ node-content ] map natural-sort >array ] unit-test [ { } ] [ "charlie" get dup "fran" get !has-parent has-parent-relation parents [ node-content ] map ] unit-test [ { "adam" "eve" } ] [ has-parent-relation ultimate-objects node-results [ node-content ] map ] unit-test diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index 2500441b11..b33d795c9c 100755 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -110,7 +110,7 @@ arc "arc" [ node-result ] map ; : subjects-with-cor ( content object relation -- sql-results ) - [ id>> ] 2apply + [ id>> ] bi@ [ ":relation" INTEGER param , ":object" INTEGER param , @@ -119,7 +119,7 @@ arc "arc" "select n.id, n.content from node n, arc a where n.content = :content and n.id = a.subject and a.relation = :relation and a.object = :object" results ; : objects-with-csr ( content subject relation -- sql-results ) - [ id>> ] 2apply + [ id>> ] bi@ [ ":relation" INTEGER param , ":subject" INTEGER param , From 21e30d86815a813aed7c099867e619e368910b64 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Wed, 9 Apr 2008 09:22:12 +1000 Subject: [PATCH 12/47] semantic-db: add node= --- extra/semantic-db/semantic-db.factor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index b33d795c9c..2ac667a94c 100755 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -22,6 +22,8 @@ node "node" : node-content ( node -- content ) dup content>> [ nip ] [ select-tuple content>> ] if* ; +: node= ( node node -- ? ) [ id>> ] bi@ = ; + ! TODO: get rid of arc id and write our own sql TUPLE: arc id subject object relation ; From 7a748b23c8021db06fa2f563b612be70be268333 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Wed, 9 Apr 2008 09:23:33 +1000 Subject: [PATCH 13/47] initial work on tangle --- extra/tangle/html/html-tests.factor | 7 ++++ extra/tangle/html/html.factor | 33 +++++++++++++++++++ extra/tangle/menu/menu.factor | 22 +++++++++++++ extra/tangle/page/page.factor | 23 +++++++++++++ extra/tangle/path/path.factor | 51 +++++++++++++++++++++++++++++ extra/tangle/tangle-tests.factor | 26 +++++++++++++++ extra/tangle/tangle.factor | 49 +++++++++++++++++++++++++++ 7 files changed, 211 insertions(+) create mode 100644 extra/tangle/html/html-tests.factor create mode 100644 extra/tangle/html/html.factor create mode 100644 extra/tangle/menu/menu.factor create mode 100644 extra/tangle/page/page.factor create mode 100644 extra/tangle/path/path.factor create mode 100644 extra/tangle/tangle-tests.factor create mode 100644 extra/tangle/tangle.factor diff --git a/extra/tangle/html/html-tests.factor b/extra/tangle/html/html-tests.factor new file mode 100644 index 0000000000..8e7d8c24e1 --- /dev/null +++ b/extra/tangle/html/html-tests.factor @@ -0,0 +1,7 @@ +USING: html kernel semantic-db tangle.html tools.test ; +IN: tangle.html.tests + +[ "test" ] [ "test" >html ] unit-test +[ "
  • An Item
" ] [ { "An Item" } >html ] unit-test +[ "
  • One
  • Two
  • Three, ah ah ah
" ] [ { "One" "Two" "Three, ah ah ah" } >html ] unit-test +[ "some link" ] [ "foo/bar" "some link" >html ] unit-test diff --git a/extra/tangle/html/html.factor b/extra/tangle/html/html.factor new file mode 100644 index 0000000000..9c55b66528 --- /dev/null +++ b/extra/tangle/html/html.factor @@ -0,0 +1,33 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors html html.elements io io.streams.string kernel namespaces semantic-db sequences strings tangle.path ; +IN: tangle.html + +TUPLE: element attributes ; + +TUPLE: ulist < element items ; +: ( items -- element ) + H{ } clone swap ulist construct-boa ; + +TUPLE: link < element href text ; +: ( href text -- element ) + H{ } clone -rot link construct-boa ; + +GENERIC: >html ( element -- str ) + +M: string >html ( str -- str ) ; + +M: link >html ( link -- str ) + [ > =href a> text>> write ] with-string-writer ; + +M: node >html ( node -- str ) + dup node>path [ + swap node-content >html + ] [ + node-content + ] if* ; + +M: ulist >html ( ulist -- str ) + [ +
    items>> [
  • >html write
  • ] each
+ ] with-string-writer ; diff --git a/extra/tangle/menu/menu.factor b/extra/tangle/menu/menu.factor new file mode 100644 index 0000000000..9740acee1c --- /dev/null +++ b/extra/tangle/menu/menu.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel semantic-db sequences tangle.html ; +IN: tangle.menu + +RELATION: subitem-of +RELATION: before + +: get-menus ( -- nodes ) + subitem-of-relation ultimate-objects node-results ; + +: get-menu ( name -- node ) + get-menus [ node-content = ] with find nip ; + +: ensure-menu ( name -- node ) + dup get-menu [ nip ] [ create-node ] if* ; + +: load-menu ( name -- menu ) + get-menu subitem-of-relation get-node-tree-s ; + +: menu>ulist ( menu -- str ) children>> ; +: menu>html ( menu -- str ) menu>ulist >html ; diff --git a/extra/tangle/page/page.factor b/extra/tangle/page/page.factor new file mode 100644 index 0000000000..db3d58d5f3 --- /dev/null +++ b/extra/tangle/page/page.factor @@ -0,0 +1,23 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel semantic-db sequences sequences.lib ; +IN: tangle.page + +RELATION: has-abbreviation +RELATION: has-content +RELATION: has-subsection +RELATION: before +RELATION: authored-by +RELATION: authored-on + +TUPLE: page name abbreviation author created content ; +C: page + +: load-page-content ( node -- content ) + has-content-objects [ node-content ] map concat ; + +: load-page ( node -- page ) + dup [ has-abbreviation-objects ?first ] keep + [ authored-by-objects ?first ] keep + [ authored-on-objects ?first ] keep + load-page-content ; diff --git a/extra/tangle/path/path.factor b/extra/tangle/path/path.factor new file mode 100644 index 0000000000..e7cf3de967 --- /dev/null +++ b/extra/tangle/path/path.factor @@ -0,0 +1,51 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: kernel semantic-db sequences sequences.lib splitting ; +IN: tangle.path + +RELATION: has-filename +RELATION: in-directory + +: create-root ( -- node ) "" create-node ; + +: get-root ( -- node ) + in-directory-relation ultimate-objects ?1node-result ; + +: ensure-root ( -- node ) get-root [ create-root ] unless* ; + +: create-file ( parent name -- node ) + create-node swap dupd in-directory ; + +: files-in-directory ( node -- nodes ) in-directory-subjects ; + +: file-in-directory ( name node -- node ) + in-directory-relation subjects-with-cor ?1node-result ; + +: parent-directory ( file-node -- dir-node ) + in-directory-objects ?first ; + +: (path>node) ( node name -- node ) + swap [ file-in-directory ] [ drop f ] if* ; + +USE: tools.walker +: path>node ( path -- node ) + "/" split ensure-root swap [ (path>node) ] each ; + +: (node>path) ( root seq node -- seq ) + pick over node= [ + drop nip + ] [ + dup node-content pick push + parent-directory [ + (node>path) + ] [ + 2drop f + ] if* + ] if ; + +: node>path* ( root node -- path ) + V{ } clone swap (node>path) dup empty? + [ drop f ] [ "/" join ] if ; + +: node>path ( node -- path ) + ensure-root swap node>path* ; diff --git a/extra/tangle/tangle-tests.factor b/extra/tangle/tangle-tests.factor new file mode 100644 index 0000000000..7b78e07473 --- /dev/null +++ b/extra/tangle/tangle-tests.factor @@ -0,0 +1,26 @@ +USING: accessors arrays continuations db db.sqlite io.files kernel semantic-db sequences tangle tangle.html tangle.menu tangle.page tangle.path tools.test tools.walker tuple-syntax ; +IN: tangle.tests + +: db-path "tangle-test.db" temp-file ; +: test-db db-path sqlite-db ; +: delete-db [ db-path delete-file ] ignore-errors ; + +: test-tangle ( -- ) + ensure-root "foo" create-file "bar" create-file "pluck_eggs" create-file + "How to Pluck Eggs" create-node swap has-filename + "Main Menu" ensure-menu "home" create-node swap subitem-of ; + +test-db [ + init-semantic-db test-tangle + [ "pluck_eggs" ] [ "foo/bar/pluck_eggs" path>node [ node-content ] when* ] unit-test + [ "How to Pluck Eggs" ] [ "foo/bar/pluck_eggs" path>node [ has-filename-subjects first node-content ] when* ] unit-test + [ "foo/bar/pluck_eggs" ] [ "foo/bar/pluck_eggs" path>node node>path ] unit-test + [ f ] [ TUPLE{ node id: 666 content: "some content" } parent-directory ] unit-test + [ f ] [ TUPLE{ node id: 666 content: "some content" } node>path ] unit-test + [ "Main Menu" ] [ "Main Menu" ensure-menu node-content ] unit-test + [ t ] [ "Main Menu" ensure-menu "Main Menu" ensure-menu node= ] unit-test + [ "Main Menu" { "home" } ] [ "Main Menu" load-menu dup node>> node-content swap children>> [ node>> node-content ] map >array ] unit-test + [ { "home" } ] [ "Main Menu" load-menu menu>ulist items>> [ node>> node-content ] map >array ] unit-test + [ f ] [ TUPLE{ node id: 666 content: "node text" } node>path ] unit-test + [ "node text" ] [ TUPLE{ node id: 666 content: "node text" } >html ] unit-test +] with-db delete-db diff --git a/extra/tangle/tangle.factor b/extra/tangle/tangle.factor new file mode 100644 index 0000000000..cbd3b94058 --- /dev/null +++ b/extra/tangle/tangle.factor @@ -0,0 +1,49 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs db db.sqlite db.postgresql http.server io kernel namespaces semantic-db sequences strings ; +IN: tangle + +GENERIC: render* ( content templater -- output ) +GENERIC: render ( content templater -- ) + +TUPLE: echo-template ; +C: echo-template + +M: echo-template render* drop ; +! METHOD: render* { string echo-template } drop ; +M: object render render* write ; + +TUPLE: tangle db templater ; +C: tangle + +TUPLE: sqlite-tangle ; +TUPLE: postgres-tangle ; + +: make-tangle ( db templater type -- tangle ) + construct-empty [ ] dip tuck set-delegate ; + +: ( db templater -- tangle ) sqlite-tangle make-tangle ; +: ( db templater -- tangle ) postgres-tangle make-tangle ; + +: with-tangle ( tangle quot -- ) + [ db>> ] dip with-db ; + +: init-db ( tangle -- tangle ) + dup [ init-semantic-db ] with-tangle ; + +GENERIC# new-db 1 ( tangle obj -- tangle ) +M: sqlite-tangle new-db ( tangle filename -- tangle ) + sqlite-db >>db init-db ; +M: postgres-tangle new-db ( tangle args -- tangle ) + postgresql-db >>db init-db ; + +TUPLE: node-responder tangle ; +C: node-responder + +M: node-responder call-responder ( path responder -- response ) + "text/plain" nip request-params + [ "node-id" swap at* [ >>body ] [ drop ] if ] when* nip ; + +: test-tangle ( -- ) + f f main-responder set ; + From 14426af0c35c0e9650524b03e0ca0fb6cdc3cdca Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Wed, 9 Apr 2008 17:38:04 +1000 Subject: [PATCH 14/47] adding bank account simulator --- extra/bank/bank-tests.factor | 34 ++++++++++++++++ extra/bank/bank.factor | 76 ++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 extra/bank/bank-tests.factor diff --git a/extra/bank/bank-tests.factor b/extra/bank/bank-tests.factor new file mode 100644 index 0000000000..2aa31f1e85 --- /dev/null +++ b/extra/bank/bank-tests.factor @@ -0,0 +1,34 @@ +USING: accessors arrays bank calendar kernel math math.functions namespaces tools.test tools.walker ; +IN: bank.tests + +SYMBOL: my-account +[ + "Alex's Take Over the World Fund" 0.07 1 2007 11 1 6101.94 open-account my-account set + [ 6137 ] [ my-account get 2007 12 2 process-to-date balance>> round >integer ] unit-test + [ 6137 ] [ my-account get 2007 12 2 process-to-date balance>> round >integer ] unit-test +] with-scope + +[ + "Petty Cash" 0.07 1 2006 12 1 10962.18 open-account my-account set + [ 11027 ] [ my-account get 2007 1 2 process-to-date balance>> round >integer ] unit-test +] with-scope + +[ + "Saving to buy a pony" 0.0725 1 2008 3 3 11106.24 open-account my-account set + [ 8416 ] [ + my-account get [ + 2008 3 11 -750 "Need to buy food" , + 2008 3 25 -500 "Going to a party" , + 2008 4 8 -800 "Losing interest in the pony..." , + 2008 4 8 -700 "Buying a rocking horse" , + ] { } make inserting-transactions balance>> round >integer + ] unit-test +] with-scope + +[ + [ 6781 ] [ + "..." 0.07 1 2007 4 10 4398.50 open-account + 2007 10 26 2000 "..." 1array inserting-transactions + 2008 4 10 process-to-date dup balance>> swap unpaid-interest>> + round >integer + ] unit-test +] with-scope diff --git a/extra/bank/bank.factor b/extra/bank/bank.factor index c9228bedd5..0ea4bae2b3 100644 --- a/extra/bank/bank.factor +++ b/extra/bank/bank.factor @@ -1,33 +1,69 @@ -USING: accessors calendar kernel money new-slots sequences ; +USING: accessors calendar kernel math money sequences ; IN: bank -MIXIN: policy -TUPLE: simple-policy interest-rate ; -INSTANCE: simple-policy policy -C: simple-policy +TUPLE: account name interest-rate interest-payment-day opening-date transactions unpaid-interest interest-last-paid ; -GENERIC: interest-rate ( date account policy -- rate ) -M: simple-policy interest-rate 2nip interest-rate>> ; - -: daily-interest-rate ( date account policy -- rate ) - pick days-in-year >r interest-rate r> / ; - -TUPLE: account name balance transactions ; - -: ( name -- account ) - 0 V{ } clone account construct-boa ; +: ( name interest-rate interest-payment-day opening-date -- account ) + V{ } clone 0 pick account construct-boa ; TUPLE: transaction date amount description ; - C: transaction : >>transaction ( account transaction -- account ) over transactions>> push ; -: open-account ( date opening-balance name -- account ) - >r "Account Opened" >>transaction ; +: total ( transactions -- balance ) + 0 [ amount>> + ] reduce ; -: open-account-now ( opening-balance name -- account ) - now -rot open-account ; +: balance>> ( account -- balance ) transactions>> total ; +: open-account ( name interest-rate interest-payment-day opening-date opening-balance -- account ) + >r [ ] keep r> "Account Opened" >>transaction ; +: daily-rate ( yearly-rate day -- daily-rate ) + days-in-year / ; + +: daily-rate>> ( account date -- rate ) + [ interest-rate>> ] dip daily-rate ; + +: before? ( date date -- ? ) <=> 0 < ; + +: transactions-on-date ( account date -- transactions ) + [ before? ] curry subset ; + +: balance-on-date ( account date -- balance ) + transactions-on-date total ; + +: pay-interest ( account date -- ) + over unpaid-interest>> "Interest Credit" + >>transaction 0 >>unpaid-interest drop ; + +: interest-payment-day? ( account date -- ? ) + day>> swap interest-payment-day>> = ; + +: ?pay-interest ( account date -- ) + 2dup interest-payment-day? [ pay-interest ] [ 2drop ] if ; + +: unpaid-interest+ ( account amount -- account ) + over unpaid-interest>> + >>unpaid-interest ; + +: accumulate-interest ( account date -- ) + [ dupd daily-rate>> over balance>> * unpaid-interest+ ] keep + >>interest-last-paid drop ; + +: process-day ( account date -- ) + 2dup accumulate-interest ?pay-interest ; + +: each-day ( quot start end -- ) + 2dup before? [ + >r dup >r over >r swap call r> r> 1 days time+ r> each-day + ] [ + 3drop + ] if ; + +: process-to-date ( account date -- account ) + over interest-last-paid>> 1 days time+ + [ dupd process-day ] spin each-day ; + +: inserting-transactions ( account transactions -- account ) + [ [ date>> process-to-date ] keep >>transaction ] each ; From 4823509dfd2c0b0ce153e6d8a497977e0fd7a86e Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Thu, 17 Apr 2008 22:39:25 -0500 Subject: [PATCH 15/47] Delegate changes for crossreferencing; removing mimic (not enough unit tests) --- extra/delegate/delegate-docs.factor | 19 +--- extra/delegate/delegate-tests.factor | 10 +-- extra/delegate/delegate.factor | 126 +++++++++++++-------------- 3 files changed, 67 insertions(+), 88 deletions(-) diff --git a/extra/delegate/delegate-docs.factor b/extra/delegate/delegate-docs.factor index f123c3a802..e6a2ad7bf4 100644 --- a/extra/delegate/delegate-docs.factor +++ b/extra/delegate/delegate-docs.factor @@ -24,30 +24,17 @@ HELP: CONSULT: { define-consult POSTPONE: CONSULT: } related-words -HELP: define-mimic -{ $values { "group" "a protocol, generic word or tuple class" } { "mimicker" "a class" } { "mimicked" "a class" } } -{ $description "For the generic words in the group, the given mimicker copies the methods of the mimicked. This only works for the methods that have already been defined when the word is called." } -{ $notes "Usually, " { $link POSTPONE: MIMIC: } " should be used instead. This is only for runtime use." } ; - -HELP: MIMIC: -{ $syntax "MIMIC: group mimicker mimicked" } -{ $values { "group" "a protocol, generic word or tuple class" } { "mimicker" "a class" } { "mimicked" "a class" } } -{ $description "For the generic words in the group, the given mimicker copies the methods of the mimicked. This only works for the methods that have already been defined when the syntax is used. Mimicking overwrites existing methods." } ; - HELP: group-words { $values { "group" "a group" } { "words" "an array of words" } } -{ $description "Given a protocol, generic word or tuple class, this returns the corresponding generic words that this group contains." } ; +{ $description "Given a protocol or tuple class, this returns the corresponding generic words that this group contains." } ; ARTICLE: { "delegate" "intro" } "Delegation module" -"This vocabulary defines methods for consultation and mimicry, independent of the current Factor object system; it is a replacement for Factor's builtin delegation system. Fundamental to the concept of generic word groups, which can be specific protocols, generic words or tuple slot accessors. Fundamentally, a group is a word which has a method for " { $link group-words } ". To define a group as a set of words, use" +"This vocabulary defines methods for consultation and mimicry, independent of the current Factor object system; it is a replacement for Factor's builtin delegation system. Fundamental to the concept of generic word groups, which can be specific protocols, generic words or tuple slot accessors. Fundamentally, a group is a word which has a method for " { $link group-words } ". One type of group is a tuple, which consists of the slot words. To define a group as a set of words, use" { $subsection POSTPONE: PROTOCOL: } { $subsection define-protocol } "One method of object extension which this vocabulary defines is consultation. This is slightly different from the current Factor concept of delegation, in that instead of delegating for all generic words not implemented, only generic words included in a specific group are consulted. Additionally, instead of using a single hard-coded delegate slot, you can specify any quotation to execute in order to retrieve who to consult. The literal syntax and defining word are" { $subsection POSTPONE: CONSULT: } -{ $subsection define-consult } -"Another object extension mechanism is mimicry. This is the copying of methods in a group from one class to another. For certain applications, this is more appropriate than delegation, as it avoids the slicing problem. It is inappropriate for tuple slots, however. The literal syntax and defining word are" -{ $subsection POSTPONE: MIMIC: } -{ $subsection define-mimic } ; +{ $subsection define-consult } ; IN: delegate ABOUT: { "delegate" "intro" } diff --git a/extra/delegate/delegate-tests.factor b/extra/delegate/delegate-tests.factor index 497a6c5120..7f633ed4a4 100644 --- a/extra/delegate/delegate-tests.factor +++ b/extra/delegate/delegate-tests.factor @@ -2,11 +2,6 @@ USING: delegate kernel arrays tools.test words math definitions compiler.units parser generic prettyprint io.streams.string ; IN: delegate.tests -DEFER: example -[ 1 ] [ \ example 1 "prop" set-word-prop \ example "prop" word-prop ] unit-test -[ ] [ \ example "prop" [ 1+ ] change-word-prop ] unit-test -[ 2 ] [ \ example "prop" word-prop ] unit-test - TUPLE: hello this that ; C: hello @@ -30,18 +25,17 @@ GENERIC: bing ( c -- d ) PROTOCOL: bee bing ; CONSULT: hello goodbye goodbye-those ; M: hello bing hello-test ; -MIMIC: bee goodbye hello [ 1 { t 1 0 } ] [ 1 0 [ foo ] [ bar ] bi ] unit-test [ { t 1 0 } ] [ 1 0 bing ] unit-test [ 1 ] [ 1 0 f foo ] unit-test [ { t 1 0 } ] [ 1 0 f bar ] unit-test -[ { f 1 0 } ] [ f 1 0 bing ] unit-test [ 3 ] [ 1 0 2 whoa ] unit-test [ 3 ] [ 1 0 f 2 whoa ] unit-test [ ] [ 10 [ "USE: delegate IN: delegate.tests CONSULT: baz goodbye goodbye-these ;" eval ] times ] unit-test -[ V{ goodbye } ] [ baz protocol-users ] unit-test +[ H{ { goodbye [ goodbye-these ] } } ] [ baz protocol-consult ] unit-test +[ H{ } ] [ bee protocol-consult ] unit-test [ "USING: delegate ;\nIN: delegate.tests\nPROTOCOL: baz foo bar { whoa 1 } ;\n" ] [ [ baz see ] with-string-writer ] unit-test diff --git a/extra/delegate/delegate.factor b/extra/delegate/delegate.factor index f8e238b7db..59b298c242 100755 --- a/extra/delegate/delegate.factor +++ b/extra/delegate/delegate.factor @@ -1,9 +1,44 @@ ! Copyright (C) 2007 Daniel Ehrenberg ! See http://factorcode.org/license.txt for BSD license. USING: parser generic kernel classes words slots assocs sequences arrays -vectors definitions prettyprint combinators.lib math ; +vectors definitions prettyprint combinators.lib math hashtables ; IN: delegate +: protocol-words ( protocol -- words ) + \ protocol-words word-prop ; + +: protocol-consult ( protocol -- consulters ) + \ protocol-consult word-prop ; + +GENERIC: group-words ( group -- words ) + +M: tuple-class group-words + "slot-names" word-prop [ + [ reader-word ] [ writer-word ] bi + 2array [ 0 2array ] map + ] map concat ; + +! Consultation + +: consult-method ( word class quot -- ) + [ drop swap first create-method ] + [ nip swap first2 swapd [ ndip ] 2curry swap suffix ] 3bi define ; + +: change-word-prop ( word prop quot -- ) + rot word-props swap change-at ; inline + +: register-protocol ( group class quot -- ) + rot \ protocol-consult [ swapd ?set-at ] change-word-prop ; + +: define-consult ( group class quot -- ) + [ register-protocol ] [ + rot group-words -rot + [ consult-method ] 2curry each + ] 3bi ; + +: CONSULT: + scan-word scan-word parse-definition define-consult ; parsing + ! Protocols : cross-2each ( seq1 seq2 quot -- ) @@ -12,36 +47,46 @@ IN: delegate : forget-all-methods ( classes words -- ) [ 2array forget ] cross-2each ; -: protocol-words ( protocol -- words ) - "protocol-words" word-prop ; - : protocol-users ( protocol -- users ) - "protocol-users" word-prop ; + protocol-consult keys ; -: users-and-words ( protocol -- users words ) - [ protocol-users ] [ protocol-words ] bi ; +: lost-words ( protocol wordlist -- lost-words ) + >r protocol-words r> seq-diff ; : forget-old-definitions ( protocol new-wordlist -- ) - >r users-and-words r> - seq-diff forget-all-methods ; + values [ drop protocol-users ] [ lost-words ] 2bi + forget-all-methods ; -: define-protocol ( protocol wordlist -- ) - ! 2dup forget-old-definitions - { } like "protocol-words" set-word-prop ; +: added-words ( protocol wordlist -- added-words ) + swap protocol-words seq-diff ; + +: add-new-definitions ( protocol wordlist -- ) + dupd added-words >r protocol-consult >alist r> + [ first2 consult-method ] cross-2each ; + +: initialize-protocol-props ( protocol wordlist -- ) + [ drop H{ } clone \ protocol-consult set-word-prop ] + [ { } like \ protocol-words set-word-prop ] 2bi ; : fill-in-depth ( wordlist -- wordlist' ) [ dup word? [ 0 2array ] when ] map ; +: define-protocol ( protocol wordlist -- ) + fill-in-depth + [ forget-old-definitions ] + [ add-new-definitions ] + [ initialize-protocol-props ] 2tri ; + : PROTOCOL: CREATE-WORD - dup define-symbol - dup f "inline" set-word-prop - parse-definition fill-in-depth define-protocol ; parsing + [ define-symbol ] + [ f "inline" set-word-prop ] + [ parse-definition define-protocol ] tri ; parsing PREDICATE: protocol < word protocol-words ; ! Subclass of symbol? M: protocol forget* - [ users-and-words forget-all-methods ] [ call-next-method ] bi ; + [ f forget-old-definitions ] [ call-next-method ] bi ; : show-words ( wordlist' -- wordlist ) [ dup second zero? [ first ] when ] map ; @@ -52,51 +97,4 @@ M: protocol definer drop \ PROTOCOL: \ ; ; M: protocol synopsis* word-synopsis ; ! Necessary? -GENERIC: group-words ( group -- words ) - -M: protocol group-words - "protocol-words" word-prop ; - -M: tuple-class group-words - "slot-names" word-prop [ - [ reader-word ] [ writer-word ] bi - 2array [ 0 2array ] map - ] map concat ; - -! Consultation - -: define-consult-method ( word class quot -- ) - [ drop swap first create-method ] - [ nip swap first2 swapd [ ndip ] 2curry swap suffix ] 3bi define ; - -: change-word-prop ( word prop quot -- ) - >r swap word-props r> change-at ; inline - -: add ( item vector/f -- vector ) - 2dup member? [ nip ] [ ?push ] if ; - -: use-protocol ( class group -- ) - "protocol-users" [ add ] change-word-prop ; - -: define-consult ( group class quot -- ) - swapd >r 2dup use-protocol group-words swap r> - [ define-consult-method ] 2curry each ; - -: CONSULT: - scan-word scan-word parse-definition define-consult ; parsing - -! Mimic still needs to be updated - -: mimic-method ( mimicker mimicked generic -- ) - tuck method - [ [ create-method-in ] [ word-def ] bi* define ] - [ 2drop ] if* ; - -: define-mimic ( group mimicker mimicked -- ) - [ drop swap use-protocol ] [ - rot group-words -rot - [ rot first mimic-method ] 2curry each - ] 3bi ; - -: MIMIC: - scan-word scan-word scan-word define-mimic ; parsing +M: protocol group-words protocol-words ; From bd548d542347aceb76fda026bed71c2234e13ea4 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Sun, 27 Apr 2008 22:36:42 +1000 Subject: [PATCH 16/47] add openal.waves to generate tones, and code to play morse code --- extra/morse/morse-docs.factor | 4 ++ extra/morse/morse-tests.factor | 2 + extra/morse/morse.factor | 69 +++++++++++++++++++++++---- extra/openal/openal.factor | 8 +++- extra/openal/waves/waves-tests.factor | 5 ++ extra/openal/waves/waves.factor | 53 ++++++++++++++++++++ 6 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 extra/openal/waves/waves-tests.factor create mode 100644 extra/openal/waves/waves.factor diff --git a/extra/morse/morse-docs.factor b/extra/morse/morse-docs.factor index c11ba23db7..31fc7f34c2 100644 --- a/extra/morse/morse-docs.factor +++ b/extra/morse/morse-docs.factor @@ -23,3 +23,7 @@ HELP: morse> { $values { "str" "A string of morse code, in which the character '.' represents dots, '-' dashes, ' ' spaces between letters, and ' / ' spaces between words." } { "str" "The ASCII translation of the given string" } } { $description "Translates morse code into ASCII text" } { $see-also >morse morse>ch } ; + +HELP: play-as-morse +{ $values { "str" "A string of ascii characters which can be translated into morse code" } { "unit-length" "The length of a dot" } } +{ $description "Plays a string as morse code" } diff --git a/extra/morse/morse-tests.factor b/extra/morse/morse-tests.factor index 97efe1afb4..c87fa483e3 100644 --- a/extra/morse/morse-tests.factor +++ b/extra/morse/morse-tests.factor @@ -9,3 +9,5 @@ USING: arrays morse strings tools.test ; [ "-- --- .-. ... . / -.-. --- -.. ." ] [ "morse code" >morse ] unit-test [ "morse code" ] [ "-- --- .-. ... . / -.-. --- -.. ." morse> ] unit-test [ "hello, world!" ] [ "Hello, World!" >morse morse> ] unit-test +[ ] [ "sos" 0.075 play-as-morse ] unit-test +[ ] [ "Factor rocks!" 0.05 play-as-morse ] unit-test diff --git a/extra/morse/morse.factor b/extra/morse/morse.factor index f493951ed5..d0b9e4003a 100644 --- a/extra/morse/morse.factor +++ b/extra/morse/morse.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2007 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: assocs hashtables kernel lazy-lists namespaces openal -parser-combinators promises sequences strings unicode.case ; +USING: assocs combinators hashtables kernel lazy-lists math namespaces +openal openal.waves parser-combinators promises sequences strings symbols +unicode.case ; IN: morse <+> ; @@ -123,3 +124,51 @@ PRIVATE> ] map >string ] map [ [ CHAR: \s , ] [ % ] interleave ] "" make ; +r 8 22000 880 r> send-buffer* ; + +: silent-buffer ( seconds -- id ) + 8 22000 rot send-buffer* ; + +: make-buffers ( unit-length -- ) + { + [ sine-buffer dot-buffer set ] + [ 3 * sine-buffer dash-buffer set ] + [ silent-buffer intra-char-gap-buffer set ] + [ 3 * silent-buffer letter-gap-buffer set ] + } cleave ; + +: playing-morse ( quot unit-length -- ) + [ + init-openal 1 gen-sources first source set make-buffers + call + source get source-play + ] with-scope ; + +: play-char ( ch -- ) + [ intra-char-gap ] [ + { + { dot-char [ dot ] } + { dash-char [ dash ] } + { word-gap-char [ intra-char-gap ] } + } case + ] interleave ; + +PRIVATE> + +: play-as-morse ( str unit-length -- ) + [ + [ letter-gap ] [ ch>morse play-char ] interleave + ] swap playing-morse ; + diff --git a/extra/openal/openal.factor b/extra/openal/openal.factor index ff67a30ea3..c0a79d8353 100644 --- a/extra/openal/openal.factor +++ b/extra/openal/openal.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel alien system combinators alien.syntax namespaces +USING: kernel arrays alien system combinators alien.syntax namespaces alien.c-types sequences vocabs.loader shuffle combinators.lib openal.backend ; IN: openal @@ -266,6 +266,12 @@ os macosx? "openal.macosx" "openal.other" ? require gen-buffer dup rot load-wav-file [ alBufferData ] 4keep alutUnloadWAV ; +: queue-buffers ( source buffers -- ) + [ length ] [ >c-uint-array ] bi alSourceQueueBuffers ; + +: queue-buffer ( source buffer -- ) + 1array queue-buffers ; + : set-source-param ( source param value -- ) alSourcei ; diff --git a/extra/openal/waves/waves-tests.factor b/extra/openal/waves/waves-tests.factor new file mode 100644 index 0000000000..b295283aac --- /dev/null +++ b/extra/openal/waves/waves-tests.factor @@ -0,0 +1,5 @@ +USING: kernel openal openal.waves sequences tools.test ; +IN: openal.waves.tests + + +[ ] [ 8 22000 440 1 play-sine-wave ] unit-test diff --git a/extra/openal/waves/waves.factor b/extra/openal/waves/waves.factor new file mode 100644 index 0000000000..abe9f8fb69 --- /dev/null +++ b/extra/openal/waves/waves.factor @@ -0,0 +1,53 @@ +USING: accessors alien.c-types combinators kernel locals math +math.constants math.functions math.ranges openal sequences ; +IN: openal.waves + +TUPLE: buffer bits channels sample-freq seq id ; + +: ( bits sample-freq seq -- buffer ) + ! defaults to 1 channel + 1 -rot gen-buffer buffer boa ; + +: buffer-format ( buffer -- format ) + dup buffer-channels 1 = swap buffer-bits 8 = [ + AL_FORMAT_MONO8 AL_FORMAT_STEREO8 + ] [ + AL_FORMAT_MONO16 AL_FORMAT_STEREO16 + ] if ? ; + +: buffer-data ( buffer -- data size ) + #! 8 bit data is integers between 0 and 255, + #! 16 bit data is integers between -32768 and 32768 + #! size is in bytes + [ seq>> ] [ bits>> ] bi 8 = [ + [ 128 * >integer 128 + ] map [ >c-uchar-array ] [ length ] bi + ] [ + [ 32768 * >integer ] map [ >c-short-array ] [ length 2 * ] bi + ] if ; + +: send-buffer ( buffer -- ) + { [ id>> ] [ buffer-format ] [ buffer-data ] [ sample-freq>> ] } cleave + alBufferData ; + +: send-buffer* ( buffer -- id ) + [ send-buffer ] [ id>> ] bi ; + +: (sine-wave-seq) ( samples/wave n-samples -- seq ) + pi 2 * rot / [ * sin ] curry map ; + +: sine-wave-seq ( sample-freq freq seconds -- seq ) + pick * >integer [ / ] dip (sine-wave-seq) ; + +: ( bits sample-freq freq seconds -- buffer ) + >r dupd r> sine-wave-seq ; + +: ( bits sample-freq seconds -- buffer ) + dupd * >integer [ drop 0 ] map ; + +: play-sine-wave ( bits sample-freq freq seconds -- ) + init-openal + send-buffer* + 1 gen-sources first + [ AL_BUFFER rot set-source-param ] [ source-play ] bi + check-error ; + From 21c50fefe0d8f2584ff06ddcdcb30ebcd58c61fc Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Mon, 28 Apr 2008 12:17:08 +1000 Subject: [PATCH 17/47] fix morse-docs, and add authors.txt --- extra/morse/authors.txt | 1 + extra/morse/morse-docs.factor | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 extra/morse/authors.txt diff --git a/extra/morse/authors.txt b/extra/morse/authors.txt new file mode 100644 index 0000000000..e9c193bac7 --- /dev/null +++ b/extra/morse/authors.txt @@ -0,0 +1 @@ +Alex Chapman diff --git a/extra/morse/morse-docs.factor b/extra/morse/morse-docs.factor index 31fc7f34c2..f31b741c85 100644 --- a/extra/morse/morse-docs.factor +++ b/extra/morse/morse-docs.factor @@ -26,4 +26,4 @@ HELP: morse> HELP: play-as-morse { $values { "str" "A string of ascii characters which can be translated into morse code" } { "unit-length" "The length of a dot" } } -{ $description "Plays a string as morse code" } +{ $description "Plays a string as morse code" } ; From aa0daed072ca418bad4e47526c00edea6dce9481 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Mon, 28 Apr 2008 13:44:46 +1000 Subject: [PATCH 18/47] update tangle and semantic-db for latest changes to factor --- extra/semantic-db/authors.txt | 1 + extra/semantic-db/semantic-db.factor | 6 +++--- extra/tangle/authors.txt | 1 + extra/tangle/html/html.factor | 4 ++-- extra/tangle/tangle.factor | 8 ++++---- 5 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 extra/semantic-db/authors.txt create mode 100644 extra/tangle/authors.txt diff --git a/extra/semantic-db/authors.txt b/extra/semantic-db/authors.txt new file mode 100644 index 0000000000..e9c193bac7 --- /dev/null +++ b/extra/semantic-db/authors.txt @@ -0,0 +1 @@ +Alex Chapman diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index 51bd94d61c..2451d73acb 100755 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays combinators combinators.cleave combinators.lib -continuations db db.tuples db.types db.sqlite hashtables kernel math -math.parser namespaces parser sequences sequences.deep +continuations db db.tuples db.types db.sqlite kernel math +math.parser namespaces parser sets sequences sequences.deep sequences.lib strings words ; IN: semantic-db @@ -28,7 +28,7 @@ node "node" TUPLE: arc id subject object relation ; : ( subject object relation -- arc ) - arc construct-empty swap >>relation swap >>object swap >>subject ; + arc new swap >>relation swap >>object swap >>subject ; : ( id -- arc ) arc new swap >>id ; diff --git a/extra/tangle/authors.txt b/extra/tangle/authors.txt new file mode 100644 index 0000000000..e9c193bac7 --- /dev/null +++ b/extra/tangle/authors.txt @@ -0,0 +1 @@ +Alex Chapman diff --git a/extra/tangle/html/html.factor b/extra/tangle/html/html.factor index 9c55b66528..fc604f4d46 100644 --- a/extra/tangle/html/html.factor +++ b/extra/tangle/html/html.factor @@ -7,11 +7,11 @@ TUPLE: element attributes ; TUPLE: ulist < element items ; : ( items -- element ) - H{ } clone swap ulist construct-boa ; + H{ } clone swap ulist boa ; TUPLE: link < element href text ; : ( href text -- element ) - H{ } clone -rot link construct-boa ; + H{ } clone -rot link boa ; GENERIC: >html ( element -- str ) diff --git a/extra/tangle/tangle.factor b/extra/tangle/tangle.factor index cbd3b94058..c6a1faa27b 100644 --- a/extra/tangle/tangle.factor +++ b/extra/tangle/tangle.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs db db.sqlite db.postgresql http.server io kernel namespaces semantic-db sequences strings ; +USING: accessors assocs db db.sqlite db.postgresql http.server http.server.actions io kernel namespaces semantic-db sequences strings ; IN: tangle GENERIC: render* ( content templater -- output ) @@ -20,7 +20,7 @@ TUPLE: sqlite-tangle ; TUPLE: postgres-tangle ; : make-tangle ( db templater type -- tangle ) - construct-empty [ ] dip tuck set-delegate ; + new [ ] dip tuck set-delegate ; : ( db templater -- tangle ) sqlite-tangle make-tangle ; : ( db templater -- tangle ) postgres-tangle make-tangle ; @@ -40,8 +40,8 @@ M: postgres-tangle new-db ( tangle args -- tangle ) TUPLE: node-responder tangle ; C: node-responder -M: node-responder call-responder ( path responder -- response ) - "text/plain" nip request-params +M: node-responder call-responder* ( path responder -- response ) + "text/plain" nip params get [ "node-id" swap at* [ >>body ] [ drop ] if ] when* nip ; : test-tangle ( -- ) From 23608c219f02a83c07cebfff06a535e0a3a5131e Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Mon, 28 Apr 2008 14:21:48 +1000 Subject: [PATCH 19/47] update factor.vim for latest changes to vocabs --- extra/bank/authors.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 extra/bank/authors.txt diff --git a/extra/bank/authors.txt b/extra/bank/authors.txt new file mode 100644 index 0000000000..e9c193bac7 --- /dev/null +++ b/extra/bank/authors.txt @@ -0,0 +1 @@ +Alex Chapman From ffd3ae635d644a260e4c8c4ca73646836b1d2577 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Mon, 28 Apr 2008 14:23:16 +1000 Subject: [PATCH 20/47] update factor.vim (not sure what happened with that last commit) --- misc/factor.vim | 14 +++++++------- misc/factor.vim.fgen | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/misc/factor.vim b/misc/factor.vim index 93ce3d6bd5..d1c46cee0b 100644 --- a/misc/factor.vim +++ b/misc/factor.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: factor " Maintainer: Alex Chapman -" Last Change: 2007 Jan 18 +" Last Change: 2008 Apr 28 " For version 5.x: Clear all syntax items " For version 6.x: Quit when a syntax file was already loaded @@ -48,17 +48,17 @@ syn keyword factorCompileDirective inline foldable parsing " kernel vocab keywords -syn keyword factorKeyword or construct-delegate set-slots tuck while wrapper nip hashcode wrapper? both? callstack>array die dupd set-delegate callstack callstack? 3dup pick curry build >boolean ?if clone eq? = ? swapd call-clear 2over 2keep 3keep construct general-t clear 2dup when not tuple? 3compose dup call object wrapped unless* if* 2apply >r curry-quot drop when* retainstack -rot delegate with 3slip construct-boa slip compose-first compose-second 3drop construct-empty either? curry? datastack compare curry-obj over 3curry roll throw swap and 2nip set-retainstack (clone) hashcode* get-slots compose spin if <=> unless compose? tuple keep 2curry object? equal? set-datastack 2slip 2drop most null r> set-callstack dip xor rot -roll -syn keyword factorKeyword assoc? assoc-clone-like delete-any assoc= delete-at* new-assoc subassoc? assoc-size map>assoc union search-alist assoc-like key? update at* assoc-empty? at+ set-at assoc-all? assoc-hashcode intersect change-at assoc-each assoc-subset values rename-at value-at (assoc-stack) at cache assoc>map assoc-contains? assoc assoc-map assoc-pusher diff (assoc>map) assoc-push-if remove-all >alist (substitute) substitute-here clear-assoc assoc-stack substitute delete-at assoc-find keys -syn keyword factorKeyword case dispatch-case-quot with-datastack alist>quot dispatch-case hash-case-table hash-case-quot no-cond no-case? cond distribute-buckets (distribute-buckets) contiguous-range? cond>quot no-cond? no-case recursive-hashcode linear-case-quot hash-dispatch-quot case>quot -syn keyword factorKeyword byte-array>bignum sgn >bignum number= each-integer next-power-of-2 before? imaginary-part mod recip float>bits rational >float number? 2^ bignum? integer fixnum? after? fixnum before=? bignum sq neg denominator [-] (all-integers?) times find-last-integer (each-integer) bit? * + - / >= bitand find-integer complex < real > log2 integer? max number bits>double double>bits bitor 2/ zero? rem all-integers? (find-integer) real-part align bits>float float? shift between? float 1+ 1- min fp-nan? ratio? bitxor even? ratio <= /mod >integer odd? rational? bitnot real? >fixnum complex? (next-power-of-2) /i numerator after=? /f -syn keyword factorKeyword slice-to append left-trim clone-like 3sequence set-column-seq map-as reversed pad-left cut* nth sequence slice? tail-slice empty? tail* member? unclip virtual-sequence? set-length last-index* drop-prefix bounds-error? set-slice-seq set-column-col seq-diff map start open-slice midpoint@ add* set-immutable-seq move-forward fourth delete set-slice-to all-eq? monotonic? set-reversed-seq like delete-nth first4 repetition-len (open-slice) column? reverse slice padding virtual@ repetition? index 4sequence max-length set-second first2 first3 (3append) supremum unclip-slice index* move-backward tail 3append sequence-hashcode-step right-trim reversed-seq pad-right concat find* set-slice-from flip sum find-last* immutable? 2sequence delete-all start* immutable-sequence? (append) check-slice column-seq sequence? head set-slice-error-reason reduce set-bounds-error-index reverse-here sequence= halves collapse-slice interleave 2map binary-reduce virtual-seq slice-error? product bounds-check? bounds-check immutable find column remove ((append)) set-fourth peek contains? reversed? shorter? push-new find-last head-slice pop* immutable-seq tail-slice* accumulate each pusher all-equal? new-resizable cut-slice head-slice* 2reverse-each pop memq? set-nth ?nth second change-each join set-repetition-len all? virtual-sequence set-repetition-elt subseq? immutable-sequence slice-error-reason new-like length last-index seq-intersect push-if 2all? lengthen column-col joined-length copy set-bounds-error-seq cache-nth move third first slice-from repetition-elt tail? set-first bounds-error add bounds-error-seq bounds-error-index unfold exchange slice-seq cut 2reduce change-nth min-length set-third (delete) push-all head? delete-slice sum-lengths new 2each head* infimum subset slice-error subseq replace-slice repetition push trim sequence-hashcode mismatch +syn keyword factorKeyword or construct-delegate set-slots tuck 2bi 2tri while wrapper nip bi* wrapper? hashcode callstack>array both? die set-delegate dupd callstack callstack? 3dup tri@ pick curry build prepose 3bi >boolean ?if clone eq? tri* ? = swapd call-clear 2over 2keep 3keep construct clear 2dup when not tuple? 3compose dup 2bi* call object bi@ wrapped unless* if* >r curry-quot drop when* retainstack -rot 2bi@ delegate boa with 3slip slip compose-first compose-second 3drop either? bi curry? datastack curry-obj over 3curry roll throw swap and 2nip set-retainstack (clone) hashcode* get-slots compose spin if 3tri unless compose? tuple keep 2curry equal? set-datastack 2slip tri 2drop most identity-tuple? null r> new set-callstack dip xor rot -roll identity-tuple +syn keyword factorKeyword assoc? assoc-clone-like delete-any assoc= delete-at* new-assoc subassoc? assoc-size map>assoc search-alist assoc-like key? assoc-intersect update assoc-union at* assoc-empty? at+ set-enum-seq set-at assoc-all? assoc-hashcode change-at assoc-each assoc-diff zip values value-at rename-at (assoc-stack) enum? at cache assoc>map assoc-contains? assoc assoc-map assoc-pusher (assoc>map) enum assoc-push-if remove-all >alist (substitute) substitute-here clear-assoc assoc-stack substitute assoc-filter delete-at assoc-find enum-seq keys +syn keyword factorKeyword case dispatch-case-quot with-datastack no-cond no-case? 3cleave>quot (distribute-buckets) contiguous-range? 2cleave cond>quot no-cond? cleave>quot no-case recursive-hashcode case>quot 3cleave alist>quot dispatch-case hash-case-table hash-case-quot case-find cond cleave distribute-buckets 2cleave>quot linear-case-quot spread spread>quot hash-dispatch-quot +syn keyword factorKeyword byte-array>bignum sgn >bignum number= each-integer next-power-of-2 ?1+ imaginary-part mod recip float>bits rational >float number? 2^ bignum? integer fixnum? neg fixnum sq bignum (all-integers?) times denominator find-last-integer (each-integer) bit? * + power-of-2? - / >= bitand find-integer complex < real > log2 integer? number bits>double double>bits bitor 2/ zero? rem all-integers? (find-integer) real-part align bits>float float? shift float 1+ 1- fp-nan? ratio? bitxor even? ratio <= /mod >integer odd? rational? bitnot real? >fixnum complex? (next-power-of-2) /i numerator /f +syn keyword factorKeyword slice-to append left-trim find-last-from clone-like 3sequence map-as last-index-from reversed index-from pad-left cut* nth sequence slice? tail-slice empty? tail* find-from member? virtual-sequence? unclip set-length drop-prefix bounds-error? set-slice-seq map start open-slice midpoint@ set-immutable-seq move-forward rest-slice prepend fourth delete set-slice-to new-sequence follow all-eq? monotonic? set-reversed-seq like delete-nth first4 repetition-len (open-slice) reverse slice padding virtual@ repetition? index 4sequence max-length set-second first2 first3 (3append) supremum unclip-slice move-backward tail 3append sequence-hashcode-step right-trim reversed-seq pad-right suffix concat set-slice-from flip filter sum immutable? 2sequence delete-all start* immutable-sequence? (append) check-slice sequence? head set-slice-error-reason reduce set-bounds-error-index reverse-here sequence= halves collapse-slice interleave 2map binary-reduce virtual-seq slice-error? product bounds-check? bounds-check immutable find remove ((append)) set-fourth peek contains? reversed? shorter? push-new find-last head-slice pop* immutable-seq tail-slice* accumulate each pusher all-equal? new-resizable cut-slice head-slice* 2reverse-each pop memq? set-nth ?nth second change-each join set-repetition-len all? virtual-sequence set-repetition-elt subseq? immutable-sequence slice-error-reason new-like length last-index push-if 2all? lengthen joined-length copy set-bounds-error-seq cache-nth move third first slice-from repetition-elt tail? set-first prefix bounds-error bounds-error-seq bounds-error-index unfold exchange slice-seq cut 2reduce change-nth min-length set-third (delete) push-all head? delete-slice rest sum-lengths 2each head* infimum sequence-hashcode slice-error subseq replace-slice repetition push trim mismatch syn keyword factorKeyword global +@ set-namestack with-variable on set bind dec namestack get get-global change init-namespaces with-scope off set-global namespace % make , inc counter building make-assoc syn keyword factorKeyword 3array >array 4array pair? array pair 2array 1array resize-array array? syn keyword factorKeyword readln stream-read-until stream-read-partial stderr with-stream read with-stream* print contents make-span-stream write1 stream-write1 stream-format make-block-stream stream-copy with-cell stream-write format with-row stream-print stream-read with-nesting (stream-copy) bl write-object nl stream-nl write stdio flush read-until tabular-output make-cell-stream write-cell stream-flush read1 lines stream-read1 stream-write-table with-style stream-readln syn keyword factorKeyword resize-string >string 1string string string? syn keyword factorKeyword vector? ?push vector >vector 1vector -syn keyword factorKeyword rethrow-restarts restarts recover set-restart-name set-continuation-name condition-continuation ifcc continuation-name set-restart-continuation ignore-errors continuation-retain continue restart-continuation with-disposal set-continuation-catch restart-obj error thread-error-hook set-continuation-retain continuation rethrow callcc1 callcc0 condition continuation? continuation-call continuation-data set-condition-restarts set-catchstack >continuation< error-continuation cleanup restart? compute-restarts condition? error-thread set-continuation-call set-condition-continuation set-restart-obj dispose set-continuation-data throw-restarts catchstack continue-with attempt-all restart restart-name continuation-catch condition-restarts +syn keyword factorKeyword rethrow-restarts restarts recover set-restart-name set-continuation-name condition-continuation ifcc continuation-name condition-error set-restart-continuation ignore-errors continuation-retain continue restart-continuation with-disposal set-continuation-catch set-condition-error restart-obj error thread-error-hook set-continuation-retain continuation rethrow callcc1 callcc0 condition continuation? continuation-call continuation-data set-condition-restarts set-catchstack >continuation< error-continuation cleanup restart? compute-restarts condition? error-thread set-continuation-call set-condition-continuation set-restart-obj dispose set-continuation-data throw-restarts catchstack continue-with attempt-all restart restart-name continuation-catch condition-restarts syn cluster factorReal contains=factorInt,factorFloat,factorRatio,factorBinary,factorHex,factorOctal diff --git a/misc/factor.vim.fgen b/misc/factor.vim.fgen index 7bcba78cde..b0d61b8dd0 100644 --- a/misc/factor.vim.fgen +++ b/misc/factor.vim.fgen @@ -2,7 +2,7 @@ %>" Vim syntax file " Language: factor " Maintainer: Alex Chapman -" Last Change: 2007 Jan 18 +" Last Change: 2008 Apr 28 " For version 5.x: Clear all syntax items " For version 6.x: Quit when a syntax file was already loaded From 4300eeaa89b342e5b6e97d66e03f4f1a8874dfae Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Mon, 28 Apr 2008 14:24:30 +1000 Subject: [PATCH 21/47] bank account simulator --- extra/bank/bank.factor | 6 +++--- extra/bank/summary.txt | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 extra/bank/summary.txt diff --git a/extra/bank/bank.factor b/extra/bank/bank.factor index 0ea4bae2b3..35d1337afc 100644 --- a/extra/bank/bank.factor +++ b/extra/bank/bank.factor @@ -1,10 +1,10 @@ -USING: accessors calendar kernel math money sequences ; +USING: accessors calendar kernel math math.order money sequences ; IN: bank TUPLE: account name interest-rate interest-payment-day opening-date transactions unpaid-interest interest-last-paid ; : ( name interest-rate interest-payment-day opening-date -- account ) - V{ } clone 0 pick account construct-boa ; + V{ } clone 0 pick account boa ; TUPLE: transaction date amount description ; C: transaction @@ -29,7 +29,7 @@ C: transaction : before? ( date date -- ? ) <=> 0 < ; : transactions-on-date ( account date -- transactions ) - [ before? ] curry subset ; + [ before? ] curry filter ; : balance-on-date ( account date -- balance ) transactions-on-date total ; diff --git a/extra/bank/summary.txt b/extra/bank/summary.txt new file mode 100644 index 0000000000..efd88787a5 --- /dev/null +++ b/extra/bank/summary.txt @@ -0,0 +1 @@ +Bank account simulator for compound interest calculated daily and paid monthly From 19022db77fc214627f619a09ab9738c7e9b78167 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Mon, 28 Apr 2008 14:30:49 +1000 Subject: [PATCH 22/47] deleting unfinished code from this branch --- extra/new-graphs/new-graphs.factor | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 extra/new-graphs/new-graphs.factor diff --git a/extra/new-graphs/new-graphs.factor b/extra/new-graphs/new-graphs.factor deleted file mode 100644 index b82ed8a22d..0000000000 --- a/extra/new-graphs/new-graphs.factor +++ /dev/null @@ -1,21 +0,0 @@ -! Copyright (C) 2008 Alex Chapman -! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs kernel new-slots sequences vectors ; -IN: new-graphs - -TUPLE: graph edges ; -TUPLE: digraph ; -TUPLE: undigraph ; - -: ( -- graph ) - H{ } clone graph construct-boa H{ } clone over set-delegate ; - -: ( -- graph ) - digraph construct-empty tuck set-delegate ; - -: ( -- graph ) - undigraph construct-empty tuck set-delegate ; - -GENERIC: add-vertex ( key value graph -- ) -M: graph add-vertex ( key value digraph -- ) set-at ; - From 7584e02805f7ffd09543eaab896ff118c6616a92 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 30 Apr 2008 16:11:55 -0500 Subject: [PATCH 23/47] New checksum protocol --- core/bootstrap/image/image.factor | 12 +++-- core/bootstrap/primitives.factor | 17 +++++++ core/bootstrap/syntax.factor | 1 + .../byte-vectors/byte-vectors-docs.factor | 0 .../byte-vectors/byte-vectors-tests.factor | 0 .../byte-vectors/byte-vectors.factor | 19 +------ {extra => core}/byte-vectors/summary.txt | 0 {extra => core}/byte-vectors/tags.txt | 0 core/checksums/checksums-docs.factor | 51 +++++++++++++++++++ core/checksums/checksums.factor | 25 +++++++++ core/{io => checksums}/crc32/authors.txt | 0 core/checksums/crc32/crc32-docs.factor | 11 ++++ core/checksums/crc32/crc32-tests.factor | 6 +++ core/{io => checksums}/crc32/crc32.factor | 26 +++++++--- core/{io => checksums}/crc32/summary.txt | 0 core/io/crc32/crc32-docs.factor | 17 ------- core/io/crc32/crc32-tests.factor | 5 -- core/optimizer/known-words/known-words.factor | 4 +- core/prettyprint/backend/backend.factor | 13 +++-- core/source-files/source-files.factor | 6 +-- core/syntax/syntax.factor | 3 +- extra/benchmark/crc32/crc32.factor | 6 +-- extra/benchmark/md5/md5.factor | 4 +- .../reverse-complement-tests.factor | 12 ++--- extra/benchmark/sha1/sha1.factor | 4 +- .../bootstrap/image/download/download.factor | 6 +-- extra/bootstrap/image/upload/upload.factor | 9 ++-- extra/{crypto => checksums}/md5/authors.txt | 0 extra/checksums/md5/md5-docs.factor | 11 ++++ extra/checksums/md5/md5-tests.factor | 10 ++++ extra/{crypto => checksums}/md5/md5.factor | 24 +++------ extra/{crypto => checksums}/sha1/authors.txt | 0 extra/checksums/sha1/sha1-docs.factor | 11 ++++ .../sha1/sha1-tests.factor | 10 ++-- extra/{crypto => checksums}/sha1/sha1.factor | 28 ++++------ extra/{crypto => checksums}/sha2/authors.txt | 0 extra/checksums/sha2/sha2-docs.factor | 11 ++++ .../sha2/sha2-tests.factor | 14 ++--- extra/{crypto => checksums}/sha2/sha2.factor | 15 +++--- extra/crypto/common/common.factor | 8 ++- extra/crypto/hmac/hmac.factor | 7 +-- extra/crypto/md5/md5-docs.factor | 18 ------- extra/crypto/md5/md5-tests.factor | 10 ---- extra/help/handbook/handbook.factor | 3 +- .../server/auth/providers/providers.factor | 2 +- extra/tools/vocabs/vocabs.factor | 6 +-- 46 files changed, 268 insertions(+), 177 deletions(-) rename {extra => core}/byte-vectors/byte-vectors-docs.factor (100%) rename {extra => core}/byte-vectors/byte-vectors-tests.factor (100%) rename {extra => core}/byte-vectors/byte-vectors.factor (61%) rename {extra => core}/byte-vectors/summary.txt (100%) rename {extra => core}/byte-vectors/tags.txt (100%) create mode 100644 core/checksums/checksums-docs.factor create mode 100644 core/checksums/checksums.factor rename core/{io => checksums}/crc32/authors.txt (100%) create mode 100644 core/checksums/crc32/crc32-docs.factor create mode 100644 core/checksums/crc32/crc32-tests.factor rename core/{io => checksums}/crc32/crc32.factor (59%) rename core/{io => checksums}/crc32/summary.txt (100%) delete mode 100644 core/io/crc32/crc32-docs.factor delete mode 100644 core/io/crc32/crc32-tests.factor rename extra/{crypto => checksums}/md5/authors.txt (100%) create mode 100755 extra/checksums/md5/md5-docs.factor create mode 100755 extra/checksums/md5/md5-tests.factor rename extra/{crypto => checksums}/md5/md5.factor (88%) rename extra/{crypto => checksums}/sha1/authors.txt (100%) create mode 100644 extra/checksums/sha1/sha1-docs.factor rename extra/{crypto => checksums}/sha1/sha1-tests.factor (69%) rename extra/{crypto => checksums}/sha1/sha1.factor (83%) rename extra/{crypto => checksums}/sha2/authors.txt (100%) create mode 100644 extra/checksums/sha2/sha2-docs.factor rename extra/{crypto => checksums}/sha2/sha2-tests.factor (51%) rename extra/{crypto => checksums}/sha2/sha2.factor (94%) delete mode 100755 extra/crypto/md5/md5-docs.factor delete mode 100755 extra/crypto/md5/md5-tests.factor diff --git a/core/bootstrap/image/image.factor b/core/bootstrap/image/image.factor index b3be0c41e7..2f354bfee5 100755 --- a/core/bootstrap/image/image.factor +++ b/core/bootstrap/image/image.factor @@ -305,12 +305,12 @@ M: wrapper ' [ emit ] emit-object ; ! Strings -: emit-chars ( seq -- ) +: emit-bytes ( seq -- ) bootstrap-cell big-endian get [ [ be> ] map ] [ [ le> ] map ] if emit-seq ; -: pack-string ( string -- newstr ) +: pad-bytes ( seq -- newseq ) dup length bootstrap-cell align 0 pad-right ; : emit-string ( string -- ptr ) @@ -318,7 +318,7 @@ M: wrapper ' dup length emit-fixnum f ' emit f ' emit - pack-string emit-chars + pad-bytes emit-bytes ] emit-object ; M: string ' @@ -335,7 +335,11 @@ M: string ' [ 0 emit-fixnum ] emit-object ] bi* ; -M: byte-array ' byte-array emit-dummy-array ; +M: byte-array ' + byte-array type-number object tag-number [ + dup length emit-fixnum + pad-bytes emit-bytes + ] emit-object ; M: bit-array ' bit-array emit-dummy-array ; diff --git a/core/bootstrap/primitives.factor b/core/bootstrap/primitives.factor index bcd75e9854..6149e83893 100755 --- a/core/bootstrap/primitives.factor +++ b/core/bootstrap/primitives.factor @@ -59,6 +59,7 @@ num-types get f builtins set "arrays" "bit-arrays" "byte-arrays" + "byte-vectors" "classes.private" "classes.tuple" "classes.tuple.private" @@ -452,6 +453,22 @@ tuple } } define-tuple-class +"byte-vector" "byte-vectors" create +tuple +{ + { + { "byte-array" "byte-arrays" } + "underlying" + { "underlying" "growable" } + { "set-underlying" "growable" } + } { + { "array-capacity" "sequences.private" } + "fill" + { "length" "sequences" } + { "set-fill" "growable" } + } +} define-tuple-class + "curry" "kernel" create tuple { diff --git a/core/bootstrap/syntax.factor b/core/bootstrap/syntax.factor index 4b74804749..7d703d3093 100755 --- a/core/bootstrap/syntax.factor +++ b/core/bootstrap/syntax.factor @@ -16,6 +16,7 @@ IN: bootstrap.syntax "?{" "BIN:" "B{" + "BV{" "C:" "CHAR:" "DEFER:" diff --git a/extra/byte-vectors/byte-vectors-docs.factor b/core/byte-vectors/byte-vectors-docs.factor similarity index 100% rename from extra/byte-vectors/byte-vectors-docs.factor rename to core/byte-vectors/byte-vectors-docs.factor diff --git a/extra/byte-vectors/byte-vectors-tests.factor b/core/byte-vectors/byte-vectors-tests.factor similarity index 100% rename from extra/byte-vectors/byte-vectors-tests.factor rename to core/byte-vectors/byte-vectors-tests.factor diff --git a/extra/byte-vectors/byte-vectors.factor b/core/byte-vectors/byte-vectors.factor similarity index 61% rename from extra/byte-vectors/byte-vectors.factor rename to core/byte-vectors/byte-vectors.factor index a8351dc781..e80b797a8d 100755 --- a/extra/byte-vectors/byte-vectors.factor +++ b/core/byte-vectors/byte-vectors.factor @@ -1,20 +1,9 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel kernel.private math sequences -sequences.private growable byte-arrays prettyprint.backend -parser accessors ; +sequences.private growable byte-arrays ; IN: byte-vectors -TUPLE: byte-vector underlying fill ; - -M: byte-vector underlying underlying>> { byte-array } declare ; - -M: byte-vector set-underlying (>>underlying) ; - -M: byte-vector length fill>> { array-capacity } declare ; - -M: byte-vector set-fill (>>fill) ; - vector ( byte-array length -- byte-vector ) @@ -43,9 +32,3 @@ M: byte-vector equal? M: byte-array new-resizable drop ; INSTANCE: byte-vector growable - -: BV{ \ } [ >byte-vector ] parse-literal ; parsing - -M: byte-vector >pprint-sequence ; - -M: byte-vector pprint-delims drop \ BV{ \ } ; diff --git a/extra/byte-vectors/summary.txt b/core/byte-vectors/summary.txt similarity index 100% rename from extra/byte-vectors/summary.txt rename to core/byte-vectors/summary.txt diff --git a/extra/byte-vectors/tags.txt b/core/byte-vectors/tags.txt similarity index 100% rename from extra/byte-vectors/tags.txt rename to core/byte-vectors/tags.txt diff --git a/core/checksums/checksums-docs.factor b/core/checksums/checksums-docs.factor new file mode 100644 index 0000000000..c352f02af4 --- /dev/null +++ b/core/checksums/checksums-docs.factor @@ -0,0 +1,51 @@ +USING: help.markup help.syntax kernel math sequences quotations +math.private byte-arrays strings ; +IN: checksums + +HELP: checksum +{ $class-description "The class of checksum algorithms." } ; + +HELP: hex-string +{ $values { "seq" "a sequence" } { "str" "a string" } } +{ $description "Converts a sequence of values from 0-255 to a string of hex numbers from 0-ff." } +{ $examples + { $example "USING: checksums io ;" "B{ 1 2 3 4 } hex-string print" "01020304" } +} +{ $notes "Numbers are zero-padded on the left." } ; + +HELP: checksum-stream +{ $values { "stream" "an input stream" } { "checksum" "a checksum specifier" } { "value" byte-array } } +{ $contract "Computes the checksum of all data read from the stream." } +{ $side-effects "stream" } ; + +HELP: checksum-bytes +{ $values { "bytes" "a sequence of bytes" } { "checksum" "a checksum specifier" } { "value" byte-array } } +{ $contract "Computes the checksum of all data in a sequence." } ; + +HELP: checksum-lines +{ $values { "lines" "a sequence of sequences of bytes" } { "checksum" "a checksum specifier" } { "value" byte-array } } +{ $contract "Computes the checksum of all data in a sequence." } ; + +HELP: checksum-file +{ $values { "path" "a pathname specifier" } { "checksum" "a checksum specifier" } { "value" byte-array } } +{ $contract "Computes the checksum of all data in a file." } ; + +ARTICLE: "checksums" "Checksums" +"A " { $emphasis "checksum" } " is a function mapping sequences of bytes to fixed-length strings. While checksums are not one-to-one, a good checksum should have a low probability of collision. Additionally, some checksum algorithms are designed to be hard to reverse, in the sense that finding an input string which hashes to a given checksum string requires a brute-force search." +$nl +"Checksums are instances of a class:" +{ $subsection checksum } +"Operations on checksums:" +{ $subsection checksum-bytes } +{ $subsection checksum-stream } +{ $subsection checksum-lines } +"Checksums should implement at least one of " { $link checksum-bytes } " and " { $link checksum-stream } ". Implementing " { $link checksum-lines } " is optional." +$nl +"Utilities:" +{ $subsection checksum-file } +{ $subsection hex-string } +"Checksum implementations:" +{ $subsection "checksums.crc32" } +{ $vocab-subsection "MD5 checksum" "checksums.md5" } +{ $vocab-subsection "SHA1 checksum" "checksums.sha1" } +{ $vocab-subsection "SHA2 checksum" "checksums.sha2" } ; diff --git a/core/checksums/checksums.factor b/core/checksums/checksums.factor new file mode 100644 index 0000000000..849d7821dd --- /dev/null +++ b/core/checksums/checksums.factor @@ -0,0 +1,25 @@ +! Copyright (c) 2008 Slava Pestov +! See http://factorcode.org/license.txt for BSD license. +USING: sequences math.parser io io.streams.byte-array +io.encodings.binary io.files kernel ; +IN: checksums + +MIXIN: checksum + +GENERIC: checksum-bytes ( bytes checksum -- value ) + +GENERIC: checksum-stream ( stream checksum -- value ) + +GENERIC: checksum-lines ( lines checksum -- value ) + +M: checksum checksum-bytes >r binary r> checksum-stream ; + +M: checksum checksum-stream >r contents r> checksum-bytes ; + +M: checksum checksum-lines >r B{ CHAR: \n } join r> checksum-bytes ; + +: checksum-file ( path checksum -- n ) + >r binary r> checksum-stream ; + +: hex-string ( seq -- str ) + [ >hex 2 CHAR: 0 pad-left ] { } map-as concat ; diff --git a/core/io/crc32/authors.txt b/core/checksums/crc32/authors.txt similarity index 100% rename from core/io/crc32/authors.txt rename to core/checksums/crc32/authors.txt diff --git a/core/checksums/crc32/crc32-docs.factor b/core/checksums/crc32/crc32-docs.factor new file mode 100644 index 0000000000..0f277bcd16 --- /dev/null +++ b/core/checksums/crc32/crc32-docs.factor @@ -0,0 +1,11 @@ +USING: help.markup help.syntax math ; +IN: checksums.crc32 + +HELP: crc32 +{ $class-description "The CRC32 checksum algorithm." } ; + +ARTICLE: "checksums.crc32" "CRC32 checksum" +"The CRC32 checksum algorithm provides a quick but unreliable way to detect changes in data." +{ $subsection crc32 } ; + +ABOUT: "checksums.crc32" diff --git a/core/checksums/crc32/crc32-tests.factor b/core/checksums/crc32/crc32-tests.factor new file mode 100644 index 0000000000..6fe4b995ee --- /dev/null +++ b/core/checksums/crc32/crc32-tests.factor @@ -0,0 +1,6 @@ +USING: checksums checksums.crc32 kernel math tools.test namespaces ; + +[ B{ 0 0 0 0 } ] [ "" crc32 checksum-bytes ] unit-test + +[ B{ HEX: cb HEX: f4 HEX: 39 HEX: 26 } ] [ "123456789" crc32 checksum-bytes ] unit-test + diff --git a/core/io/crc32/crc32.factor b/core/checksums/crc32/crc32.factor similarity index 59% rename from core/io/crc32/crc32.factor rename to core/checksums/crc32/crc32.factor index afe7e4bfb7..e1f0b9417b 100755 --- a/core/io/crc32/crc32.factor +++ b/core/checksums/crc32/crc32.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel math sequences sequences.private namespaces words io io.binary io.files io.streams.string quotations -definitions ; -IN: io.crc32 +definitions checksums ; +IN: checksums.crc32 : crc32-polynomial HEX: edb88320 ; inline @@ -20,10 +20,20 @@ IN: io.crc32 mask-byte crc32-table nth-unsafe >bignum swap -8 shift bitxor ; inline -: crc32 ( seq -- n ) - >r HEX: ffffffff dup r> [ (crc32) ] each bitxor ; +SINGLETON: crc32 -: lines-crc32 ( seq -- n ) - HEX: ffffffff tuck [ - [ (crc32) ] each CHAR: \n (crc32) - ] reduce bitxor ; +INSTANCE: crc32 checksum + +: init-crc32 drop >r HEX: ffffffff dup r> ; inline + +: finish-crc32 bitxor 4 >be ; inline + +M: crc32 checksum-bytes + init-crc32 + [ (crc32) ] each + finish-crc32 ; + +M: crc32 checksum-lines + init-crc32 + [ [ (crc32) ] each CHAR: \n (crc32) ] each + finish-crc32 ; diff --git a/core/io/crc32/summary.txt b/core/checksums/crc32/summary.txt similarity index 100% rename from core/io/crc32/summary.txt rename to core/checksums/crc32/summary.txt diff --git a/core/io/crc32/crc32-docs.factor b/core/io/crc32/crc32-docs.factor deleted file mode 100644 index 7f85ee2b4e..0000000000 --- a/core/io/crc32/crc32-docs.factor +++ /dev/null @@ -1,17 +0,0 @@ -USING: help.markup help.syntax math ; -IN: io.crc32 - -HELP: crc32 -{ $values { "seq" "a sequence of bytes" } { "n" integer } } -{ $description "Computes the CRC32 checksum of a sequence of bytes." } ; - -HELP: lines-crc32 -{ $values { "seq" "a sequence of strings" } { "n" integer } } -{ $description "Computes the CRC32 checksum of a sequence of lines of bytes." } ; - -ARTICLE: "io.crc32" "CRC32 checksum calculation" -"The CRC32 checksum algorithm provides a quick but unreliable way to detect changes in data." -{ $subsection crc32 } -{ $subsection lines-crc32 } ; - -ABOUT: "io.crc32" diff --git a/core/io/crc32/crc32-tests.factor b/core/io/crc32/crc32-tests.factor deleted file mode 100644 index 5eafae23cb..0000000000 --- a/core/io/crc32/crc32-tests.factor +++ /dev/null @@ -1,5 +0,0 @@ -USING: io.crc32 kernel math tools.test namespaces ; - -[ 0 ] [ "" crc32 ] unit-test -[ HEX: cbf43926 ] [ "123456789" crc32 ] unit-test - diff --git a/core/optimizer/known-words/known-words.factor b/core/optimizer/known-words/known-words.factor index 6e1aacff44..d1dbefe26b 100755 --- a/core/optimizer/known-words/known-words.factor +++ b/core/optimizer/known-words/known-words.factor @@ -4,7 +4,7 @@ IN: optimizer.known-words USING: alien arrays generic hashtables inference.dataflow inference.class kernel assocs math math.private kernel.private sequences words parser vectors strings sbufs io namespaces -assocs quotations sequences.private io.binary io.crc32 +assocs quotations sequences.private io.binary io.streams.string layouts splitting math.intervals math.floats.private classes.tuple classes.tuple.private classes classes.algebra optimizer.def-use optimizer.backend @@ -126,8 +126,6 @@ sequences.private combinators ; \ >sbuf { string } "specializer" set-word-prop -\ crc32 { string } "specializer" set-word-prop - \ split, { string string } "specializer" set-word-prop \ memq? { array } "specializer" set-word-prop diff --git a/core/prettyprint/backend/backend.factor b/core/prettyprint/backend/backend.factor index e13a991e2b..f992b9ca01 100755 --- a/core/prettyprint/backend/backend.factor +++ b/core/prettyprint/backend/backend.factor @@ -1,10 +1,11 @@ ! Copyright (C) 2003, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays byte-arrays bit-arrays generic hashtables io -assocs kernel math namespaces sequences strings sbufs io.styles -vectors words prettyprint.config prettyprint.sections quotations -io io.files math.parser effects classes.tuple math.order -classes.tuple.private classes float-arrays ; +USING: arrays byte-arrays byte-vectors bit-arrays generic +hashtables io assocs kernel math namespaces sequences strings +sbufs io.styles vectors words prettyprint.config +prettyprint.sections quotations io io.files math.parser effects +classes.tuple math.order classes.tuple.private classes +float-arrays ; IN: prettyprint.backend GENERIC: pprint* ( obj -- ) @@ -140,6 +141,7 @@ M: compose pprint-delims drop \ [ \ ] ; M: array pprint-delims drop \ { \ } ; M: byte-array pprint-delims drop \ B{ \ } ; M: bit-array pprint-delims drop \ ?{ \ } ; +M: byte-vector pprint-delims drop \ BV{ \ } ; M: float-array pprint-delims drop \ F{ \ } ; M: vector pprint-delims drop \ V{ \ } ; M: hashtable pprint-delims drop \ H{ \ } ; @@ -152,6 +154,7 @@ GENERIC: >pprint-sequence ( obj -- seq ) M: object >pprint-sequence ; M: vector >pprint-sequence ; +M: byte-vector >pprint-sequence ; M: curry >pprint-sequence ; M: compose >pprint-sequence ; M: hashtable >pprint-sequence >alist ; diff --git a/core/source-files/source-files.factor b/core/source-files/source-files.factor index 5ef2d46790..36a1806e12 100755 --- a/core/source-files/source-files.factor +++ b/core/source-files/source-files.factor @@ -3,8 +3,8 @@ USING: arrays definitions generic assocs kernel math namespaces prettyprint sequences strings vectors words quotations inspector io.styles io combinators sorting splitting math.parser effects -continuations debugger io.files io.crc32 vocabs hashtables -graphs compiler.units io.encodings.utf8 accessors ; +continuations debugger io.files checksums checksums.crc32 vocabs +hashtables graphs compiler.units io.encodings.utf8 accessors ; IN: source-files SYMBOL: source-files @@ -15,7 +15,7 @@ checksum uses definitions ; : record-checksum ( lines source-file -- ) - >r lines-crc32 r> set-source-file-checksum ; + >r crc32 checksum-lines r> set-source-file-checksum ; : (xref-source) ( source-file -- pathname uses ) dup source-file-path diff --git a/core/syntax/syntax.factor b/core/syntax/syntax.factor index b2f063ddf1..2e1c46fac1 100755 --- a/core/syntax/syntax.factor +++ b/core/syntax/syntax.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien arrays bit-arrays byte-arrays +USING: alien arrays bit-arrays byte-arrays byte-vectors definitions generic hashtables kernel math namespaces parser sequences strings sbufs vectors words quotations io assocs splitting classes.tuple generic.standard @@ -79,6 +79,7 @@ IN: bootstrap.syntax "{" [ \ } [ >array ] parse-literal ] define-syntax "V{" [ \ } [ >vector ] parse-literal ] define-syntax "B{" [ \ } [ >byte-array ] parse-literal ] define-syntax + "BV{" [ \ } [ >byte-vector ] parse-literal ] define-syntax "?{" [ \ } [ >bit-array ] parse-literal ] define-syntax "F{" [ \ } [ >float-array ] parse-literal ] define-syntax "H{" [ \ } [ >hashtable ] parse-literal ] define-syntax diff --git a/extra/benchmark/crc32/crc32.factor b/extra/benchmark/crc32/crc32.factor index ec424e89c9..0e5482da30 100755 --- a/extra/benchmark/crc32/crc32.factor +++ b/extra/benchmark/crc32/crc32.factor @@ -1,10 +1,10 @@ -USING: io.crc32 io.encodings.ascii io.files kernel math ; +USING: checksums checksums.crc32 io.encodings.ascii io.files kernel math ; IN: benchmark.crc32 : crc32-primes-list ( -- ) 10 [ - "extra/math/primes/list/list.factor" resource-path - ascii file-contents crc32 drop + "resource:extra/math/primes/list/list.factor" + crc32 checksum-file drop ] times ; MAIN: crc32-primes-list diff --git a/extra/benchmark/md5/md5.factor b/extra/benchmark/md5/md5.factor index 3043725acd..8a259c1217 100644 --- a/extra/benchmark/md5/md5.factor +++ b/extra/benchmark/md5/md5.factor @@ -1,7 +1,7 @@ -USING: crypto.md5 io.files kernel ; +USING: checksums checksums.md5 io.files kernel ; IN: benchmark.md5 : md5-primes-list ( -- ) - "extra/math/primes/list/list.factor" resource-path file>md5 drop ; + "resource:extra/math/primes/list/list.factor" md5 checksum-file drop ; MAIN: md5-primes-list diff --git a/extra/benchmark/reverse-complement/reverse-complement-tests.factor b/extra/benchmark/reverse-complement/reverse-complement-tests.factor index c66de87cb5..883124105b 100755 --- a/extra/benchmark/reverse-complement/reverse-complement-tests.factor +++ b/extra/benchmark/reverse-complement/reverse-complement-tests.factor @@ -1,13 +1,13 @@ IN: benchmark.reverse-complement.tests -USING: tools.test benchmark.reverse-complement crypto.md5 +USING: tools.test benchmark.reverse-complement +checksums checksums.md5 io.files kernel ; [ "c071aa7e007a9770b2fb4304f55a17e5" ] [ - "extra/benchmark/reverse-complement/reverse-complement-test-in.txt" - "extra/benchmark/reverse-complement/reverse-complement-test-out.txt" - [ resource-path ] bi@ + "resource:extra/benchmark/reverse-complement/reverse-complement-test-in.txt" + "resource:extra/benchmark/reverse-complement/reverse-complement-test-out.txt" reverse-complement - "extra/benchmark/reverse-complement/reverse-complement-test-out.txt" - resource-path file>md5str + "resource:extra/benchmark/reverse-complement/reverse-complement-test-out.txt" + md5 checksum-file hex-string ] unit-test diff --git a/extra/benchmark/sha1/sha1.factor b/extra/benchmark/sha1/sha1.factor index 897d83ea0e..c43f780135 100644 --- a/extra/benchmark/sha1/sha1.factor +++ b/extra/benchmark/sha1/sha1.factor @@ -1,7 +1,7 @@ -USING: crypto.sha1 io.files kernel ; +USING: checksum checksums.sha1 io.files kernel ; IN: benchmark.sha1 : sha1-primes-list ( -- ) - "extra/math/primes/list/list.factor" resource-path file>sha1 drop ; + "resource:extra/math/primes/list/list.factor" sha1 checksum-file drop ; MAIN: sha1-primes-list diff --git a/extra/bootstrap/image/download/download.factor b/extra/bootstrap/image/download/download.factor index a186954ef0..46aca6cc6b 100644 --- a/extra/bootstrap/image/download/download.factor +++ b/extra/bootstrap/image/download/download.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: bootstrap.image.download -USING: http.client crypto.md5 splitting assocs kernel io.files -bootstrap.image sequences io ; +USING: http.client checksums checksums.md5 splitting assocs +kernel io.files bootstrap.image sequences io ; : url "http://factorcode.org/images/latest/" ; @@ -12,7 +12,7 @@ bootstrap.image sequences io ; : need-new-image? ( image -- ? ) dup exists? - [ dup file>md5str swap download-checksums at = not ] + [ [ md5 checksum-file hex-string ] [ download-checksums at ] bi = not ] [ drop t ] if ; : download-image ( arch -- ) diff --git a/extra/bootstrap/image/upload/upload.factor b/extra/bootstrap/image/upload/upload.factor index ab26a4ff13..30d0428744 100755 --- a/extra/bootstrap/image/upload/upload.factor +++ b/extra/bootstrap/image/upload/upload.factor @@ -1,8 +1,9 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. +USING: http.client checksums checksums.md5 splitting assocs +kernel io.files bootstrap.image sequences io namespaces +io.launcher math io.encodings.ascii ; IN: bootstrap.image.upload -USING: http.client crypto.md5 splitting assocs kernel io.files -bootstrap.image sequences io namespaces io.launcher math io.encodings.ascii ; SYMBOL: upload-images-destination @@ -17,7 +18,9 @@ SYMBOL: upload-images-destination : compute-checksums ( -- ) checksums ascii [ - boot-image-names [ dup write bl file>md5str print ] each + boot-image-names [ + [ write bl ] [ md5 checksum-file hex-string print ] bi + ] each ] with-file-writer ; : upload-images ( -- ) diff --git a/extra/crypto/md5/authors.txt b/extra/checksums/md5/authors.txt similarity index 100% rename from extra/crypto/md5/authors.txt rename to extra/checksums/md5/authors.txt diff --git a/extra/checksums/md5/md5-docs.factor b/extra/checksums/md5/md5-docs.factor new file mode 100755 index 0000000000..dca039d1d3 --- /dev/null +++ b/extra/checksums/md5/md5-docs.factor @@ -0,0 +1,11 @@ +USING: help.markup help.syntax ; +IN: checksums.md5 + +HELP: md5 +{ $description "MD5 checksum algorithm." } ; + +ARTICLE: "checksums.md5" "MD5 checksum" +"The MD5 checksum algorithm implements a one-way hash function. While it is widely used, many weaknesses are known and it should not be used in new applications (" { $url "http://www.schneier.com/blog/archives/2005/03/more_hash_funct.html" } ")." +{ $subsection md5 } ; + +ABOUT: "checksums.md5" diff --git a/extra/checksums/md5/md5-tests.factor b/extra/checksums/md5/md5-tests.factor new file mode 100755 index 0000000000..8e314f7c28 --- /dev/null +++ b/extra/checksums/md5/md5-tests.factor @@ -0,0 +1,10 @@ +USING: kernel math namespaces checksums checksums.md5 tools.test byte-arrays ; + +[ "d41d8cd98f00b204e9800998ecf8427e" ] [ "" >byte-array md5 checksum-bytes hex-string ] unit-test +[ "0cc175b9c0f1b6a831c399e269772661" ] [ "a" >byte-array md5 checksum-bytes hex-string ] unit-test +[ "900150983cd24fb0d6963f7d28e17f72" ] [ "abc" >byte-array md5 checksum-bytes hex-string ] unit-test +[ "f96b697d7cb7938d525a2f31aaf161d0" ] [ "message digest" >byte-array md5 checksum-bytes hex-string ] unit-test +[ "c3fcd3d76192e4007dfb496cca67e13b" ] [ "abcdefghijklmnopqrstuvwxyz" >byte-array md5 checksum-bytes hex-string ] unit-test +[ "d174ab98d277d9f5a5611c2c9f419d9f" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" >byte-array md5 checksum-bytes hex-string ] unit-test +[ "57edf4a22be3c955ac49da2e2107b67a" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" >byte-array md5 checksum-bytes hex-string ] unit-test + diff --git a/extra/crypto/md5/md5.factor b/extra/checksums/md5/md5.factor similarity index 88% rename from extra/crypto/md5/md5.factor rename to extra/checksums/md5/md5.factor index 45e10da74d..78494a40c0 100755 --- a/extra/crypto/md5/md5.factor +++ b/extra/checksums/md5/md5.factor @@ -3,8 +3,8 @@ USING: kernel io io.binary io.files io.streams.byte-array math math.functions math.parser namespaces splitting strings sequences crypto.common byte-arrays locals sequences.private -io.encodings.binary symbols math.bitfields.lib ; -IN: crypto.md5 +io.encodings.binary symbols math.bitfields.lib checksums ; +IN: checksums.md5 md5) ( -- ) +: stream>md5 ( -- ) 64 read [ process-md5-block ] keep - length 64 = [ (stream>md5) ] when ; + length 64 = [ stream>md5 ] when ; : get-md5 ( -- str ) [ a b c d ] [ get 4 >le ] map concat >byte-array ; PRIVATE> -: stream>md5 ( stream -- byte-array ) - [ initialize-md5 (stream>md5) get-md5 ] with-stream ; +SINGLETON: md5 -: byte-array>md5 ( byte-array -- checksum ) - binary stream>md5 ; +INSTANCE: md5 checksum -: byte-array>md5str ( byte-array -- md5-string ) - byte-array>md5 hex-string ; - -: file>md5 ( path -- byte-array ) - binary stream>md5 ; - -: file>md5str ( path -- md5-string ) - file>md5 hex-string ; +M: md5 checksum-stream ( stream -- byte-array ) + drop [ initialize-md5 stream>md5 get-md5 ] with-stream ; diff --git a/extra/crypto/sha1/authors.txt b/extra/checksums/sha1/authors.txt similarity index 100% rename from extra/crypto/sha1/authors.txt rename to extra/checksums/sha1/authors.txt diff --git a/extra/checksums/sha1/sha1-docs.factor b/extra/checksums/sha1/sha1-docs.factor new file mode 100644 index 0000000000..8b8bf1cfa9 --- /dev/null +++ b/extra/checksums/sha1/sha1-docs.factor @@ -0,0 +1,11 @@ +USING: help.markup help.syntax ; +IN: checksums.sha1 + +HELP: sha1 +{ $description "SHA1 checksum algorithm." } ; + +ARTICLE: "checksums.sha1" "SHA1 checksum" +"The SHA1 checksum algorithm implements a one-way hash function. It is generally considered to be stronger than MD5, however there is a known algorithm for finding collisions more effectively than a brute-force search (" { $url "http://www.schneier.com/blog/archives/2005/02/sha1_broken.html" } ")." +{ $subsection sha1 } ; + +ABOUT: "checksums.sha1" diff --git a/extra/crypto/sha1/sha1-tests.factor b/extra/checksums/sha1/sha1-tests.factor similarity index 69% rename from extra/crypto/sha1/sha1-tests.factor rename to extra/checksums/sha1/sha1-tests.factor index 14307355c2..808d37d1e4 100755 --- a/extra/crypto/sha1/sha1-tests.factor +++ b/extra/checksums/sha1/sha1-tests.factor @@ -1,14 +1,14 @@ -USING: arrays kernel math namespaces sequences tools.test crypto.sha1 ; +USING: arrays kernel math namespaces sequences tools.test checksums checksums.sha1 ; -[ "a9993e364706816aba3e25717850c26c9cd0d89d" ] [ "abc" byte-array>sha1str ] unit-test -[ "84983e441c3bd26ebaae4aa1f95129e5e54670f1" ] [ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" byte-array>sha1str ] unit-test +[ "a9993e364706816aba3e25717850c26c9cd0d89d" ] [ "abc" sha1 checksum-bytes hex-string ] unit-test +[ "84983e441c3bd26ebaae4aa1f95129e5e54670f1" ] [ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" sha1 checksum-bytes hex-string ] unit-test ! [ "34aa973cd4c4daa4f61eeb2bdbad27316534016f" ] [ 1000000 CHAR: a fill string>sha1str ] unit-test ! takes a long time... [ "dea356a2cddd90c7a7ecedc5ebb563934f460452" ] [ "0123456701234567012345670123456701234567012345670123456701234567" -10 swap concat byte-array>sha1str ] unit-test +10 swap concat sha1 checksum-bytes hex-string ] unit-test [ ";\u00009b\u0000fd\u0000cdK\u0000a3^s\u0000d0*\u0000e3\\\u0000b5\u000013<\u0000e8wA\u0000b2\u000083\u0000d20\u0000f1\u0000e6\u0000cc\u0000d8\u00001e\u00009c\u000004\u0000d7PT]\u0000ce,\u000001\u000012\u000080\u000096\u000099" ] [ "\u000066\u000053\u0000f1\u00000c\u00001a\u0000fa\u0000b5\u00004c\u000061\u0000c8\u000025\u000075\u0000a8\u00004a\u0000fe\u000030\u0000d8\u0000aa\u00001a\u00003a\u000096\u000096\u0000b3\u000018\u000099\u000092\u0000bf\u0000e1\u0000cb\u00007f\u0000a6\u0000a7" - byte-array>sha1-interleave + sha1-interleave ] unit-test diff --git a/extra/crypto/sha1/sha1.factor b/extra/checksums/sha1/sha1.factor similarity index 83% rename from extra/crypto/sha1/sha1.factor rename to extra/checksums/sha1/sha1.factor index 3a74d1f5db..2efab873bc 100755 --- a/extra/crypto/sha1/sha1.factor +++ b/extra/checksums/sha1/sha1.factor @@ -1,8 +1,8 @@ USING: arrays combinators crypto.common kernel io io.encodings.binary io.files io.streams.byte-array math.vectors strings sequences namespaces math parser sequences vectors -io.binary hashtables symbols math.bitfields.lib ; -IN: crypto.sha1 +io.binary hashtables symbols math.bitfields.lib checksums ; +IN: checksums.sha1 ! Implemented according to RFC 3174. @@ -99,30 +99,22 @@ SYMBOLS: h0 h1 h2 h3 h4 A B C D E w K ; [ (process-sha1-block) ] each ] if ; -: (stream>sha1) ( -- ) +: stream>sha1 ( -- ) 64 read [ process-sha1-block ] keep - length 64 = [ (stream>sha1) ] when ; + length 64 = [ stream>sha1 ] when ; : get-sha1 ( -- str ) [ [ h0 h1 h2 h3 h4 ] [ get 4 >be % ] each ] "" make ; -: stream>sha1 ( stream -- sha1 ) - [ initialize-sha1 (stream>sha1) get-sha1 ] with-stream ; +SINGLETON: sha1 -: byte-array>sha1 ( string -- sha1 ) - binary stream>sha1 ; +INSTANCE: sha1 checksum -: byte-array>sha1str ( string -- str ) - byte-array>sha1 hex-string ; +M: sha1 checksum-stream ( stream -- sha1 ) + drop [ initialize-sha1 stream>sha1 get-sha1 ] with-stream ; -: byte-array>sha1-bignum ( string -- n ) - byte-array>sha1 be> ; - -: file>sha1 ( file -- sha1 ) - binary stream>sha1 ; - -: byte-array>sha1-interleave ( string -- seq ) +: sha1-interleave ( string -- seq ) [ zero? ] left-trim dup length odd? [ rest ] when - seq>2seq [ byte-array>sha1 ] bi@ + seq>2seq [ sha1 checksum-bytes ] bi@ 2seq>seq ; diff --git a/extra/crypto/sha2/authors.txt b/extra/checksums/sha2/authors.txt similarity index 100% rename from extra/crypto/sha2/authors.txt rename to extra/checksums/sha2/authors.txt diff --git a/extra/checksums/sha2/sha2-docs.factor b/extra/checksums/sha2/sha2-docs.factor new file mode 100644 index 0000000000..c39831b266 --- /dev/null +++ b/extra/checksums/sha2/sha2-docs.factor @@ -0,0 +1,11 @@ +USING: help.markup help.syntax ; +IN: checksums.sha2 + +HELP: sha-256 +{ $description "SHA-256 checksum algorithm." } ; + +ARTICLE: "checksums.sha2" "SHA2 checksum" +"The SHA2 checksum algorithm implements a one-way hash function. It is generally considered to be pretty strong." +{ $subsection sha-256 } ; + +ABOUT: "checksums.sha2" diff --git a/extra/crypto/sha2/sha2-tests.factor b/extra/checksums/sha2/sha2-tests.factor similarity index 51% rename from extra/crypto/sha2/sha2-tests.factor rename to extra/checksums/sha2/sha2-tests.factor index 8fe655f205..2f4e3c51c4 100755 --- a/extra/crypto/sha2/sha2-tests.factor +++ b/extra/checksums/sha2/sha2-tests.factor @@ -1,7 +1,7 @@ -USING: arrays kernel math namespaces sequences tools.test crypto.sha2 ; -[ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ] [ "" byte-array>sha-256-string ] unit-test -[ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" ] [ "abc" byte-array>sha-256-string ] unit-test -[ "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" ] [ "message digest" byte-array>sha-256-string ] unit-test -[ "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73" ] [ "abcdefghijklmnopqrstuvwxyz" byte-array>sha-256-string ] unit-test -[ "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" byte-array>sha-256-string ] unit-test -[ "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" byte-array>sha-256-string ] unit-test +USING: arrays kernel math namespaces sequences tools.test checksums.sha2 checksums ; +[ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ] [ "" sha-256 checksum-bytes hex-string ] unit-test +[ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" ] [ "abc" sha-256 checksum-bytes hex-string ] unit-test +[ "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" ] [ "message digest" sha-256 checksum-bytes hex-string ] unit-test +[ "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73" ] [ "abcdefghijklmnopqrstuvwxyz" sha-256 checksum-bytes hex-string ] unit-test +[ "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" sha-256 checksum-bytes hex-string ] unit-test +[ "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" sha-256 checksum-bytes hex-string ] unit-test diff --git a/extra/crypto/sha2/sha2.factor b/extra/checksums/sha2/sha2.factor similarity index 94% rename from extra/crypto/sha2/sha2.factor rename to extra/checksums/sha2/sha2.factor index 0acc5c1388..e5f16c9c11 100755 --- a/extra/crypto/sha2/sha2.factor +++ b/extra/checksums/sha2/sha2.factor @@ -1,6 +1,6 @@ USING: crypto.common kernel splitting math sequences namespaces -io.binary symbols math.bitfields.lib ; -IN: crypto.sha2 +io.binary symbols math.bitfields.lib checksums ; +IN: checksums.sha2 -: byte-array>sha-256 ( string -- string ) - [ +SINGLETON: sha-256 + +INSTANCE: sha-256 checksum + +M: sha-256 checksum-bytes + drop [ K-256 K set initial-H-256 H set 4 word-size set 64 block-size set byte-array>sha2 ] with-scope ; - -: byte-array>sha-256-string ( string -- hexstring ) - byte-array>sha-256 hex-string ; diff --git a/extra/crypto/common/common.factor b/extra/crypto/common/common.factor index a714727ad9..efe4653eba 100644 --- a/extra/crypto/common/common.factor +++ b/extra/crypto/common/common.factor @@ -1,5 +1,6 @@ USING: arrays kernel io io.binary sbufs splitting strings sequences -namespaces math math.parser parser hints math.bitfields.lib ; +namespaces math math.parser parser hints math.bitfields.lib +assocs ; IN: crypto.common : w+ ( int int -- int ) + 32 bits ; inline @@ -39,9 +40,6 @@ SYMBOL: big-endian? : update-old-new ( old new -- ) [ get >r get r> ] 2keep >r >r w+ dup r> set r> set ; inline -: hex-string ( seq -- str ) - [ [ >hex 2 48 pad-left % ] each ] "" make ; - : slice3 ( n seq -- a b c ) >r dup 3 + r> first3 ; : seq>2seq ( seq -- seq1 seq2 ) @@ -50,7 +48,7 @@ SYMBOL: big-endian? : 2seq>seq ( seq1 seq2 -- seq ) #! { aceg } { bdfh } -> { abcdefgh } - [ 2array flip concat ] keep like ; + [ zip concat ] keep like ; : mod-nth ( n seq -- elt ) #! 5 "abcd" -> b diff --git a/extra/crypto/hmac/hmac.factor b/extra/crypto/hmac/hmac.factor index 91d404aead..9770a3a266 100755 --- a/extra/crypto/hmac/hmac.factor +++ b/extra/crypto/hmac/hmac.factor @@ -1,6 +1,7 @@ -USING: arrays combinators crypto.common crypto.md5 crypto.sha1 -crypto.md5.private io io.binary io.files io.streams.byte-array -kernel math math.vectors memoize sequences io.encodings.binary ; +USING: arrays combinators crypto.common checksums checksums.md5 +checksums.sha1 crypto.md5.private io io.binary io.files +io.streams.byte-array kernel math math.vectors memoize sequences +io.encodings.binary ; IN: crypto.hmac : sha1-hmac ( Ko Ki -- hmac ) diff --git a/extra/crypto/md5/md5-docs.factor b/extra/crypto/md5/md5-docs.factor deleted file mode 100755 index 667e0449ae..0000000000 --- a/extra/crypto/md5/md5-docs.factor +++ /dev/null @@ -1,18 +0,0 @@ -USING: help.markup help.syntax kernel math sequences quotations -crypto.common byte-arrays ; -IN: crypto.md5 - -HELP: stream>md5 -{ $values { "stream" "a stream" } { "byte-array" "md5 hash" } } -{ $description "Take the MD5 hash until end of stream." } -{ $notes "Used to implement " { $link byte-array>md5 } " and " { $link file>md5 } ". Call " { $link hex-string } " to convert to the canonical string representation." } ; - -HELP: byte-array>md5 -{ $values { "byte-array" byte-array } { "checksum" "an md5 hash" } } -{ $description "Outputs the MD5 hash of a byte array." } -{ $notes "Call " { $link hex-string } " to convert to the canonical string representation." } ; - -HELP: file>md5 -{ $values { "path" "a path" } { "byte-array" "byte-array md5 hash" } } -{ $description "Outputs the MD5 hash of a file." } -{ $notes "Call " { $link hex-string } " to convert to the canonical string representation." } ; diff --git a/extra/crypto/md5/md5-tests.factor b/extra/crypto/md5/md5-tests.factor deleted file mode 100755 index 73bd240455..0000000000 --- a/extra/crypto/md5/md5-tests.factor +++ /dev/null @@ -1,10 +0,0 @@ -USING: kernel math namespaces crypto.md5 tools.test byte-arrays ; - -[ "d41d8cd98f00b204e9800998ecf8427e" ] [ "" >byte-array byte-array>md5str ] unit-test -[ "0cc175b9c0f1b6a831c399e269772661" ] [ "a" >byte-array byte-array>md5str ] unit-test -[ "900150983cd24fb0d6963f7d28e17f72" ] [ "abc" >byte-array byte-array>md5str ] unit-test -[ "f96b697d7cb7938d525a2f31aaf161d0" ] [ "message digest" >byte-array byte-array>md5str ] unit-test -[ "c3fcd3d76192e4007dfb496cca67e13b" ] [ "abcdefghijklmnopqrstuvwxyz" >byte-array byte-array>md5str ] unit-test -[ "d174ab98d277d9f5a5611c2c9f419d9f" ] [ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" >byte-array byte-array>md5str ] unit-test -[ "57edf4a22be3c955ac49da2e2107b67a" ] [ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" >byte-array byte-array>md5str ] unit-test - diff --git a/extra/help/handbook/handbook.factor b/extra/help/handbook/handbook.factor index ce875b32d1..a9e94466c4 100755 --- a/extra/help/handbook/handbook.factor +++ b/extra/help/handbook/handbook.factor @@ -204,7 +204,8 @@ ARTICLE: "io" "Input and output" { $heading "Other features" } { $subsection "network-streams" } { $subsection "io.launcher" } -{ $subsection "io.timeouts" } ; +{ $subsection "io.timeouts" } +{ $subsection "checksums" } ; ARTICLE: "tools" "Developer tools" { $subsection "tools.vocabs" } diff --git a/extra/http/server/auth/providers/providers.factor b/extra/http/server/auth/providers/providers.factor index 512ddc5f5b..121f065292 100755 --- a/extra/http/server/auth/providers/providers.factor +++ b/extra/http/server/auth/providers/providers.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors random math.parser locals -sequences math crypto.sha2 ; +sequences math ; IN: http.server.auth.providers TUPLE: user username realname password email ticket profile deleted changed? ; diff --git a/extra/tools/vocabs/vocabs.factor b/extra/tools/vocabs/vocabs.factor index e265f233e3..effa17c179 100755 --- a/extra/tools/vocabs/vocabs.factor +++ b/extra/tools/vocabs/vocabs.factor @@ -3,8 +3,8 @@ USING: io.files kernel io.encodings.utf8 vocabs.loader vocabs sequences namespaces math.parser arrays hashtables assocs memoize inspector sorting splitting combinators source-files -io debugger continuations compiler.errors init io.crc32 -sets ; +io debugger continuations compiler.errors init +checksums checksums.crc32 sets ; IN: tools.vocabs : vocab-tests-file ( vocab -- path ) @@ -63,7 +63,7 @@ SYMBOL: failures dup source-files get at [ dup source-file-path dup exists? [ - utf8 file-lines lines-crc32 + utf8 file-lines crc32 checksum-lines swap source-file-checksum = not ] [ 2drop f From 77caac1401926034bd1063ff9a3ccca3b8927881 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 30 Apr 2008 16:12:08 -0500 Subject: [PATCH 24/47] Remove file --- extra/crypto/common/common-docs.factor | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 extra/crypto/common/common-docs.factor diff --git a/extra/crypto/common/common-docs.factor b/extra/crypto/common/common-docs.factor deleted file mode 100644 index 559c7934d0..0000000000 --- a/extra/crypto/common/common-docs.factor +++ /dev/null @@ -1,13 +0,0 @@ -USING: help.markup help.syntax kernel math sequences quotations -math.private ; -IN: crypto.common - -HELP: hex-string -{ $values { "seq" "a sequence" } { "str" "a string" } } -{ $description "Converts a sequence of values from 0-255 to a string of hex numbers from 0-ff." } -{ $examples - { $example "USING: crypto.common io ;" "B{ 1 2 3 4 } hex-string print" "01020304" } -} -{ $notes "Numbers are zero-padded on the left." } ; - - From eafdb19f903f97ae06583b9863c3f466c633c185 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 30 Apr 2008 16:12:14 -0500 Subject: [PATCH 25/47] Cleanups --- extra/opengl/opengl.factor | 2 +- extra/webapps/counter/counter.factor | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/extra/opengl/opengl.factor b/extra/opengl/opengl.factor index ab9ae38ac1..ee58a4e345 100755 --- a/extra/opengl/opengl.factor +++ b/extra/opengl/opengl.factor @@ -87,7 +87,7 @@ MACRO: all-enabled-client-state ( seq quot -- ) : adjust-points [ [ 1 + 0.5 * ] map ] bi@ ; -: scale-points 2array flip [ v* ] with map [ v+ ] with map ; +: scale-points zip [ v* ] with map [ v+ ] with map ; : circle-points ( loc dim steps -- points ) circle-steps unit-circle adjust-points scale-points ; diff --git a/extra/webapps/counter/counter.factor b/extra/webapps/counter/counter.factor index 37b4c8e5e1..3cc1eb567b 100644 --- a/extra/webapps/counter/counter.factor +++ b/extra/webapps/counter/counter.factor @@ -1,5 +1,6 @@ USING: math kernel accessors http.server http.server.actions -http.server.sessions http.server.templating.fhtml locals ; +http.server.sessions http.server.templating +http.server.templating.fhtml locals ; IN: webapps.counter SYMBOL: count @@ -15,11 +16,11 @@ M: counter-app init-session* "" f ] >>display ; +: counter-template ( -- template ) + "resource:extra/webapps/counter/counter.fhtml" ; + : ( -- action ) - [ - "text/html" - "resource:extra/webapps/counter/counter.fhtml" >>body - ] >>display ; + [ counter-template serve-template ] >>display ; : ( -- responder ) counter-app new-dispatcher From ce2412c4c84f15a01f66a20d5a47f6d9bb47b494 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Thu, 1 May 2008 10:11:19 +1000 Subject: [PATCH 26/47] early tangle working with latest git --- extra/semantic-db/semantic-db.factor | 6 ++--- extra/tangle/tangle.factor | 36 ++++++++-------------------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index 22b08322d2..1c3dd2d54e 100755 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -15,7 +15,7 @@ node "node" { "content" "content" TEXT } } define-persistent -: delete-node ( node -- ) delete-tuple ; +: delete-node ( node -- ) delete-tuples ; : create-node ( content -- node ) f swap dup insert-tuple ; : load-node ( id -- node ) f select-tuple ; @@ -33,7 +33,7 @@ TUPLE: arc id subject object relation ; : ( id -- arc ) arc new swap >>id ; -: delete-arc ( arc -- ) delete-tuple ; +: delete-arc ( arc -- ) delete-tuples ; : create-arc ( subject object relation -- ) [ id>> ] 3apply insert-tuple ; @@ -76,7 +76,7 @@ TUPLE: arc id subject object relation ; arc "arc" { - { "id" "id" +native-id+ +autoincrement+ } + { "id" "id" +db-assigned-id+ +autoincrement+ } { "relation" "relation" INTEGER +not-null+ } { "subject" "subject" INTEGER +not-null+ } { "object" "object" INTEGER +not-null+ } diff --git a/extra/tangle/tangle.factor b/extra/tangle/tangle.factor index c6a1faa27b..9dad155777 100644 --- a/extra/tangle/tangle.factor +++ b/extra/tangle/tangle.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs db db.sqlite db.postgresql http.server http.server.actions io kernel namespaces semantic-db sequences strings ; +USING: accessors assocs db db.sqlite db.postgresql http http.server http.server.actions io kernel math.parser namespaces semantic-db sequences strings ; IN: tangle GENERIC: render* ( content templater -- output ) @@ -13,37 +13,21 @@ M: echo-template render* drop ; ! METHOD: render* { string echo-template } drop ; M: object render render* write ; -TUPLE: tangle db templater ; +TUPLE: tangle db seq templater ; C: tangle -TUPLE: sqlite-tangle ; -TUPLE: postgres-tangle ; - -: make-tangle ( db templater type -- tangle ) - new [ ] dip tuck set-delegate ; - -: ( db templater -- tangle ) sqlite-tangle make-tangle ; -: ( db templater -- tangle ) postgres-tangle make-tangle ; - : with-tangle ( tangle quot -- ) - [ db>> ] dip with-db ; - -: init-db ( tangle -- tangle ) - dup [ init-semantic-db ] with-tangle ; - -GENERIC# new-db 1 ( tangle obj -- tangle ) -M: sqlite-tangle new-db ( tangle filename -- tangle ) - sqlite-db >>db init-db ; -M: postgres-tangle new-db ( tangle args -- tangle ) - postgresql-db >>db init-db ; + [ [ db>> ] [ seq>> ] bi ] dip with-db ; TUPLE: node-responder tangle ; C: node-responder +: node-response ( responder id -- responder ) + load-node [ node-content ] [ "Unknown node" ] if* >>body ; + M: node-responder call-responder* ( path responder -- response ) - "text/plain" nip params get - [ "node-id" swap at* [ >>body ] [ drop ] if ] when* nip ; - -: test-tangle ( -- ) - f f main-responder set ; + dup tangle>> [ + "text/plain" nip request get request-params + [ "node-id" swap at* [ string>number node-response ] [ drop ] if ] when* nip + ] with-tangle ; From eac64bccab46a11de5f3459fd208b4899bb6a52c Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Wed, 30 Apr 2008 19:39:54 -0500 Subject: [PATCH 27/47] Moving VALUE: into unicode.syntax.backend --- extra/unicode/breaks/breaks.factor | 2 +- extra/unicode/data/data.factor | 10 +--------- extra/unicode/syntax/backend/backend.factor | 8 ++++++++ 3 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 extra/unicode/syntax/backend/backend.factor diff --git a/extra/unicode/breaks/breaks.factor b/extra/unicode/breaks/breaks.factor index ee3c8729c4..2117567e9f 100644 --- a/extra/unicode/breaks/breaks.factor +++ b/extra/unicode/breaks/breaks.factor @@ -1,6 +1,6 @@ USING: unicode.categories kernel math combinators splitting sequences math.parser io.files io assocs arrays namespaces -math.ranges unicode.normalize +math.ranges unicode.normalize unicode.syntax.backend unicode.syntax unicode.data compiler.units alien.syntax io.encodings.ascii ; IN: unicode.breaks diff --git a/extra/unicode/data/data.factor b/extra/unicode/data/data.factor index 58d836464c..b1e6fc5f8b 100755 --- a/extra/unicode/data/data.factor +++ b/extra/unicode/data/data.factor @@ -1,16 +1,8 @@ USING: assocs math kernel sequences io.files hashtables -quotations splitting arrays math.parser hash2 +quotations splitting arrays math.parser hash2 unicode.syntax.backend byte-arrays words namespaces words compiler.units parser io.encodings.ascii ; IN: unicode.data -<< -: VALUE: - CREATE-WORD { f } clone [ first ] curry define ; parsing - -: set-value ( value word -- ) - word-def first set-first ; ->> - ! Convenience functions : ?between? ( n/f from to -- ? ) pick [ between? ] [ 3drop f ] if ; diff --git a/extra/unicode/syntax/backend/backend.factor b/extra/unicode/syntax/backend/backend.factor new file mode 100644 index 0000000000..d1065da5c8 --- /dev/null +++ b/extra/unicode/syntax/backend/backend.factor @@ -0,0 +1,8 @@ +USING: kernel parser sequences definitions ; +IN: unicode.syntax.backend + +: VALUE: + CREATE-WORD { f } clone [ first ] curry define ; parsing + +: set-value ( value word -- ) + word-def first set-first ; From b7291869866bf8b4148cd19c1963f179d72b5d37 Mon Sep 17 00:00:00 2001 From: Alex Chapman Date: Thu, 1 May 2008 11:49:55 +1000 Subject: [PATCH 28/47] morse: add a default speed to play at --- extra/morse/morse-tests.factor | 2 +- extra/morse/morse.factor | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/extra/morse/morse-tests.factor b/extra/morse/morse-tests.factor index c87fa483e3..dabb93579d 100644 --- a/extra/morse/morse-tests.factor +++ b/extra/morse/morse-tests.factor @@ -10,4 +10,4 @@ USING: arrays morse strings tools.test ; [ "morse code" ] [ "-- --- .-. ... . / -.-. --- -.. ." morse> ] unit-test [ "hello, world!" ] [ "Hello, World!" >morse morse> ] unit-test [ ] [ "sos" 0.075 play-as-morse ] unit-test -[ ] [ "Factor rocks!" 0.05 play-as-morse ] unit-test +[ ] [ "Factor rocks!" play-as-morse ] unit-test diff --git a/extra/morse/morse.factor b/extra/morse/morse.factor index d0b9e4003a..ecade14cdb 100644 --- a/extra/morse/morse.factor +++ b/extra/morse/morse.factor @@ -167,8 +167,10 @@ SYMBOLS: source dot-buffer dash-buffer intra-char-gap-buffer letter-gap-buffer ; PRIVATE> -: play-as-morse ( str unit-length -- ) +: play-as-morse* ( str unit-length -- ) [ [ letter-gap ] [ ch>morse play-char ] interleave ] swap playing-morse ; +: play-as-morse ( str -- ) + 0.05 play-as-morse* ; From 594f335dfebd4cf483d12a652f666d75d9fc1a44 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Wed, 30 Apr 2008 21:04:57 -0500 Subject: [PATCH 29/47] Adding IANA encodings table --- extra/io/encodings/iana/iana.factor | 41 ++++++++++++++++++++- extra/unicode/syntax/backend/backend.factor | 2 +- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/extra/io/encodings/iana/iana.factor b/extra/io/encodings/iana/iana.factor index 08b40f802c..1bbb80482d 100644 --- a/extra/io/encodings/iana/iana.factor +++ b/extra/io/encodings/iana/iana.factor @@ -1,7 +1,27 @@ -USING: kernel strings unicode.syntax.backend ; +USING: kernel strings unicode.syntax.backend io.files assocs +splitting sequences io namespaces sets +io.encodings.ascii io.encodings.utf8 io.encodings.utf16 io.encodings.8-bit ; +IN: io.encodings.iana VALUE: n>e-table -VALUE: e>n-table + +: e>n-table H{ + { ascii "US-ASCII" } + { utf8 "UTF-8" } + { utf16 "UTF-16" } + { utf16be "UTF-16BE" } + { utf16le "UTF-16LE" } + { latin1 "ISO-8859-1" } + { latin2 "ISO-8859-2" } + { latin3 "ISO-8859-3" } + { latin4 "ISO-8859-4" } + { latin/cyrillic "ISO-8859-5" } + { latin/arabic "ISO-8859-6" } + { latin/greek "ISO-8859-7" } + { latin/hebrew "ISO-8859-8" } + { latin5 "ISO-8859-9" } + { latin6 "ISO-8859-10" } +} ; : name>encoding ( string -- encoding ) n>e-table at ; @@ -9,4 +29,21 @@ VALUE: e>n-table : encoding>name ( encoding -- string ) e>n-table at ; +: parse-iana ( stream -- synonym-set ) + lines { "" } split [ + [ " " split ] map + [ first { "Name:" "Alias:" } member? ] filter + [ second ] map { "None" } diff + ] map ; +: make-n>e ( stream -- n>e ) ! encodings is string => symbol + parse-iana [ [ + dup [ + e>n-table value-at + [ swap [ set ] with each ] + [ drop ] if* + ] with each + ] each ] H{ } make-assoc ; + +"resource:extra/io/encodings/iana/character-sets" +ascii make-n>e \ n>e-table set-value diff --git a/extra/unicode/syntax/backend/backend.factor b/extra/unicode/syntax/backend/backend.factor index d1065da5c8..5c463e8fc4 100644 --- a/extra/unicode/syntax/backend/backend.factor +++ b/extra/unicode/syntax/backend/backend.factor @@ -1,4 +1,4 @@ -USING: kernel parser sequences definitions ; +USING: kernel parser sequences words ; IN: unicode.syntax.backend : VALUE: From ada6e4ed0b5fd51659b348c27e1f3f9ef90e0c6f Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Wed, 30 Apr 2008 21:08:18 -0500 Subject: [PATCH 30/47] Fixing delegate regression --- extra/delegate/delegate.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/delegate/delegate.factor b/extra/delegate/delegate.factor index 59e2210ae0..39eccfd194 100755 --- a/extra/delegate/delegate.factor +++ b/extra/delegate/delegate.factor @@ -54,7 +54,7 @@ M: tuple-class group-words >r protocol-words r> diff ; : forget-old-definitions ( protocol new-wordlist -- ) - >r users-and-words r> + >r [ protocol-users ] [ protocol-words ] bi r> swap diff forget-all-methods ; : added-words ( protocol wordlist -- added-words ) From 82679024ce4e19dc95c29947e7c3b6414b52da66 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Wed, 30 Apr 2008 21:09:27 -0500 Subject: [PATCH 31/47] Deleting inaccurate comment --- extra/io/encodings/iana/iana.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/io/encodings/iana/iana.factor b/extra/io/encodings/iana/iana.factor index 1bbb80482d..9d5fabd439 100644 --- a/extra/io/encodings/iana/iana.factor +++ b/extra/io/encodings/iana/iana.factor @@ -36,7 +36,7 @@ VALUE: n>e-table [ second ] map { "None" } diff ] map ; -: make-n>e ( stream -- n>e ) ! encodings is string => symbol +: make-n>e ( stream -- n>e ) parse-iana [ [ dup [ e>n-table value-at From 0bde52d63b9cf49500bcfed11bc95310ec7d71c0 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Wed, 30 Apr 2008 22:06:13 -0500 Subject: [PATCH 32/47] Docs and tests for io.encodings.iana --- extra/io/encodings/iana/authors.txt | 1 + extra/io/encodings/iana/iana-docs.factor | 12 ++++++++++++ extra/io/encodings/iana/iana-tests.factor | 5 +++++ extra/io/encodings/iana/iana.factor | 6 ++++++ extra/io/encodings/iana/summary.txt | 1 + 5 files changed, 25 insertions(+) create mode 100644 extra/io/encodings/iana/authors.txt create mode 100644 extra/io/encodings/iana/iana-docs.factor create mode 100644 extra/io/encodings/iana/iana-tests.factor create mode 100644 extra/io/encodings/iana/summary.txt diff --git a/extra/io/encodings/iana/authors.txt b/extra/io/encodings/iana/authors.txt new file mode 100644 index 0000000000..f990dd0ed2 --- /dev/null +++ b/extra/io/encodings/iana/authors.txt @@ -0,0 +1 @@ +Daniel Ehrenberg diff --git a/extra/io/encodings/iana/iana-docs.factor b/extra/io/encodings/iana/iana-docs.factor new file mode 100644 index 0000000000..3542012a85 --- /dev/null +++ b/extra/io/encodings/iana/iana-docs.factor @@ -0,0 +1,12 @@ +USING: help.syntax help.markup ; +IN: io.encodings.iana + +HELP: name>encoding +{ $values { "string" "an encoding name" } { "encoding" "an encoding descriptor" } } +{ "Given an IANA-registered encoding name, find the encoding descriptor that represents it, or " { $code f } " if it is not found (either not implemented in Factor or not registered)." } ; + +HELP: encoding>name +{ $values { "encoding" "an encoding descriptor" } { "name" "an encoding name" } } +{ "Given an encoding descriptor, return the preferred IANA name." } ; + +{ name>encoding encoding>name } related-words diff --git a/extra/io/encodings/iana/iana-tests.factor b/extra/io/encodings/iana/iana-tests.factor new file mode 100644 index 0000000000..8cee07b984 --- /dev/null +++ b/extra/io/encodings/iana/iana-tests.factor @@ -0,0 +1,5 @@ +USING: io.encodings.iana io.encodings.ascii tools.test ; + +[ ascii ] [ "US-ASCII" name>encoding ] unit-test +[ ascii ] [ "ASCII" name>encoding ] unit-test +[ "US-ASCII" ] [ ascii encoding>name ] unit-test diff --git a/extra/io/encodings/iana/iana.factor b/extra/io/encodings/iana/iana.factor index 9d5fabd439..301b027637 100644 --- a/extra/io/encodings/iana/iana.factor +++ b/extra/io/encodings/iana/iana.factor @@ -1,8 +1,11 @@ +! Copyright (C) 2008 Daniel Ehrenberg +! See http://factorcode.org/license.txt for BSD license. USING: kernel strings unicode.syntax.backend io.files assocs splitting sequences io namespaces sets io.encodings.ascii io.encodings.utf8 io.encodings.utf16 io.encodings.8-bit ; IN: io.encodings.iana +e-table : e>n-table H{ @@ -22,6 +25,7 @@ VALUE: n>e-table { latin5 "ISO-8859-9" } { latin6 "ISO-8859-10" } } ; +PRIVATE> : name>encoding ( string -- encoding ) n>e-table at ; @@ -29,6 +33,7 @@ VALUE: n>e-table : encoding>name ( encoding -- string ) e>n-table at ; +e-table [ drop ] if* ] with each ] each ] H{ } make-assoc ; +PRIVATE> "resource:extra/io/encodings/iana/character-sets" ascii make-n>e \ n>e-table set-value diff --git a/extra/io/encodings/iana/summary.txt b/extra/io/encodings/iana/summary.txt new file mode 100644 index 0000000000..c95d76344c --- /dev/null +++ b/extra/io/encodings/iana/summary.txt @@ -0,0 +1 @@ +Tables for IANA encoding names From 59e24e8ab07be0ab303a63c1eb46f90c99fdca58 Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Thu, 1 May 2008 11:54:09 +0100 Subject: [PATCH 33/47] csv: Applied patch from from Philip Fominykh to fix newline-after-quote bug --- extra/csv/csv-tests.factor | 7 +++++-- extra/csv/csv.factor | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/extra/csv/csv-tests.factor b/extra/csv/csv-tests.factor index 6ab26c7e40..7e96dbc0a6 100644 --- a/extra/csv/csv-tests.factor +++ b/extra/csv/csv-tests.factor @@ -46,9 +46,7 @@ IN: csv.tests [ "Year,Make,Model\n1997,Ford,E350\n2000,Mercury,Cougar" csv ] named-unit-test - - ! !!!!!!!! other tests [ { { "Phil Dawes" } } ] @@ -65,3 +63,8 @@ IN: csv.tests "allows setting of delimiting character" [ { { "foo" "bah" "baz" } } ] [ "foo\tbah\tbaz\n" CHAR: \t [ csv ] with-delimiter ] named-unit-test + +"Quoted field followed immediately by newline" +[ { { "foo" "bar" } + { "1" "2" } } ] +[ "foo,\"bar\"\n1,2" csv ] named-unit-test diff --git a/extra/csv/csv.factor b/extra/csv/csv.factor index 3953ce057b..b1953f5b57 100644 --- a/extra/csv/csv.factor +++ b/extra/csv/csv.factor @@ -31,6 +31,7 @@ VAR: delimiter read1 dup { { CHAR: " [ , quoted-field ] } ! " is an escaped quote { delimiter> [ ] } ! end of quoted field + { CHAR: \n [ ] } [ 2drop skip-to-field-end ] ! end of quoted field + padding } case ; From c832abae8696c6c7fb0bd34c1e29f0d4a3a6f2db Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 16:23:11 -0500 Subject: [PATCH 34/47] Fix M:: --- extra/locals/locals-tests.factor | 7 +++++++ extra/locals/locals.factor | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/extra/locals/locals-tests.factor b/extra/locals/locals-tests.factor index c13be40c8f..bb2fd9893c 100755 --- a/extra/locals/locals-tests.factor +++ b/extra/locals/locals-tests.factor @@ -230,3 +230,10 @@ DEFER: xyzzy [ "xxx" "yyy" ] [ "yyy" "xxx" let*-test-4 ] unit-test +GENERIC: next-method-test ( a -- b ) + +M: integer next-method-test 3 + ; + +M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ; + +[ 5 ] [ 1 next-method-test ] unit-test diff --git a/extra/locals/locals.factor b/extra/locals/locals.factor index 8c8fa96fa5..d18017f69b 100755 --- a/extra/locals/locals.factor +++ b/extra/locals/locals.factor @@ -279,7 +279,9 @@ M: wlet local-rewrite* : (::) CREATE-WORD parse-locals-definition ; -: (M::) CREATE-METHOD parse-locals-definition ; +: (M::) + CREATE-METHOD + [ parse-locals-definition ] with-method-definition ; PRIVATE> From d3660002c589578e3d95b304b64ec58ea95a87bc Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 16:23:35 -0500 Subject: [PATCH 35/47] Change parser so that M:: can use call-next-method --- core/parser/parser.factor | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/parser/parser.factor b/core/parser/parser.factor index 23c0c0a1a5..76c831cf13 100755 --- a/core/parser/parser.factor +++ b/core/parser/parser.factor @@ -421,14 +421,17 @@ ERROR: bad-number ; SYMBOL: current-class SYMBOL: current-generic -: (M:) - CREATE-METHOD +: with-method-definition ( quot -- parsed ) [ + >r [ "method-class" word-prop current-class set ] [ "method-generic" word-prop current-generic set ] [ ] tri - parse-definition - ] with-scope ; + r> call + ] with-scope ; inline + +: (M:) + CREATE-METHOD [ parse-definition ] with-method-definition ; : scan-object ( -- object ) scan-word dup parsing? From 0994c4f29e0c78bd8e75c593878929dab9378541 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 16:23:52 -0500 Subject: [PATCH 36/47] Tighten farkup a bit --- extra/farkup/farkup.factor | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extra/farkup/farkup.factor b/extra/farkup/farkup.factor index 527ba8b4fa..1b8e698758 100755 --- a/extra/farkup/farkup.factor +++ b/extra/farkup/farkup.factor @@ -63,8 +63,12 @@ MEMO: eq ( -- parser ) ] with-html-stream ] with-string-writer ; +: check-url ( href -- href' ) + dup { "http://" "https://" "ftp://" } [ head? ] with contains? + [ drop "/" ] unless ; + : escape-link ( href text -- href-esc text-esc ) - >r escape-quoted-string r> escape-string ; + >r check-url escape-quoted-string r> escape-string ; : make-link ( href text -- seq ) escape-link From 79f91f6b7dff5355b0076bc1c216b54c8ceca18a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 16:24:50 -0500 Subject: [PATCH 37/47] Working on user capabilities --- extra/checksums/null/null.factor | 8 +++ extra/http/http-tests.factor | 16 +++-- extra/http/http.factor | 27 ++++++-- extra/http/server/auth/admin/admin.factor | 13 +++- extra/http/server/auth/auth.factor | 8 ++- extra/http/server/auth/login/login.factor | 64 +++++++++++++------ .../auth/providers/assoc/assoc-tests.factor | 22 ++++--- .../server/auth/providers/db/db-tests.factor | 26 ++++---- extra/http/server/auth/providers/db/db.factor | 3 +- .../server/auth/providers/providers.factor | 5 +- .../server/boilerplate/boilerplate.factor | 17 ++--- .../server/callbacks/callbacks-tests.factor | 2 +- extra/http/server/components/code/code.factor | 2 +- .../http/server/components/components.factor | 46 +++++++++---- .../server/components/farkup/farkup.factor | 2 +- .../components/inspector/inspector.factor | 4 +- extra/http/server/forms/forms.factor | 4 +- extra/http/server/server.factor | 15 +++-- .../server/sessions/sessions-tests.factor | 2 +- extra/http/server/static/static.factor | 39 ++++++----- .../http/server/templating/templating.factor | 3 +- extra/webapps/pastebin/pastebin.factor | 9 ++- extra/webapps/planet/planet.factor | 9 ++- extra/webapps/todo/edit-todo.xml | 16 ++--- extra/webapps/todo/todo.factor | 2 +- extra/webapps/todo/view-todo.xml | 4 +- 26 files changed, 233 insertions(+), 135 deletions(-) create mode 100644 extra/checksums/null/null.factor diff --git a/extra/checksums/null/null.factor b/extra/checksums/null/null.factor new file mode 100644 index 0000000000..d2dc305ac2 --- /dev/null +++ b/extra/checksums/null/null.factor @@ -0,0 +1,8 @@ +USING: checksums ; +IN: checksums.null + +SINGLETON: null + +INSTANCE: null checksum + +M: null checksum-bytes ; diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 39e708c879..1f1ce361b2 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -1,6 +1,6 @@ USING: http tools.test multiline tuple-syntax io.streams.string kernel arrays splitting sequences -assocs io.sockets db db.sqlite ; +assocs io.sockets db db.sqlite continuations ; IN: http.tests [ "hello%20world" ] [ "hello world" url-encode ] unit-test @@ -93,7 +93,7 @@ Host: www.sex.com STRING: read-response-test-1 HTTP/1.1 404 not found -Content-Type: text/html +Content-Type: text/html; charset=UTF8 blah ; @@ -103,8 +103,10 @@ blah version: "1.1" code: 404 message: "not found" - header: H{ { "content-type" "text/html" } } + header: H{ { "content-type" "text/html; charset=UTF8" } } cookies: V{ } + content-type: "text/html" + content-charset: "UTF8" } ] [ read-response-test-1 lf>crlf @@ -114,7 +116,7 @@ blah STRING: read-response-test-1' HTTP/1.1 404 not found -content-type: text/html +content-type: text/html; charset=UTF8 ; @@ -140,11 +142,13 @@ accessors namespaces threads ; : add-quit-action - [ stop-server "text/html" [ "Goodbye" write ] >>body ] >>display + [ stop-server [ "Goodbye" write ] ] >>display "quit" add-responder ; : test-db "test.db" temp-file sqlite-db ; +[ test-db drop delete-file ] ignore-errors + test-db [ init-sessions-table ] with-db @@ -191,7 +195,7 @@ test-db [ [ ] [ [ - + f "" add-responder diff --git a/extra/http/http.factor b/extra/http/http.factor index 9729542ea4..c5f57d4c04 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -291,6 +291,12 @@ SYMBOL: max-post-request : extract-cookies ( request -- request ) dup "cookie" header [ parse-cookies >>cookies ] when* ; +: parse-content-type-attributes ( string -- attributes ) + " " split [ empty? not ] filter [ "=" split1 >r >lower r> ] { } map>assoc ; + +: parse-content-type ( content-type -- type encoding ) + ";" split1 parse-content-type-attributes "charset" swap at ; + : read-request ( -- request ) read-method @@ -377,6 +383,8 @@ code message header cookies +content-type +content-charset body ; : @@ -403,7 +411,10 @@ body ; : read-response-header read-header >>header - dup "set-cookie" header [ parse-cookies >>cookies ] when* ; + extract-cookies + dup "content-type" header [ + parse-content-type [ >>content-type ] [ >>content-charset ] bi* + ] when* ; : read-response ( -- response ) @@ -422,10 +433,15 @@ body ; : write-response-message ( response -- response ) dup message>> write crlf ; +: unparse-content-type ( request -- content-type ) + [ content-type>> "application/octet-stream" or ] + [ content-charset>> ] bi + [ "; charset=" swap 3append ] when* ; + : write-response-header ( response -- response ) dup header>> clone - over cookies>> f like - [ unparse-cookies "set-cookie" pick set-at ] when* + over cookies>> f like [ unparse-cookies "set-cookie" pick set-at ] when* + over unparse-content-type "content-type" pick set-at write-header ; GENERIC: write-response-body* ( body -- ) @@ -453,9 +469,6 @@ M: response write-full-response ( request response -- ) dup write-response swap method>> "HEAD" = [ write-response-body ] unless ; -: set-content-type ( request/response content-type -- request/response ) - "content-type" set-header ; - : get-cookie ( request/response name -- cookie/f ) >r cookies>> r> '[ , _ name>> = ] find nip ; @@ -466,7 +479,7 @@ M: response write-full-response ( request response -- ) [ name>> dupd get-cookie [ dupd delete-cookie ] when* ] keep over cookies>> push ; -TUPLE: raw-response +TUPLE: raw-response version code message diff --git a/extra/http/server/auth/admin/admin.factor b/extra/http/server/auth/admin/admin.factor index c9d2769292..0dc5d3560e 100644 --- a/extra/http/server/auth/admin/admin.factor +++ b/extra/http/server/auth/admin/admin.factor @@ -7,6 +7,7 @@ http.server.boilerplate http.server.auth.providers http.server.auth.providers.db http.server.auth.login +http.server.auth http.server.forms http.server.components.inspector http.server.components @@ -28,6 +29,7 @@ IN: http.server.auth.admin "new-password" t >>required add-field "verify-password" t >>required add-field "email" add-field ; + ! "capabilities" add-field ; : ( -- form ) "user"
@@ -39,6 +41,7 @@ IN: http.server.auth.admin "verify-password" add-field "email" add-field "profile" add-field ; + ! "capabilities" add-field ; : ( -- form ) "user-list" @@ -77,7 +80,7 @@ IN: http.server.auth.admin "username" value "realname" value >>realname "email" value >>email - "new-password" value >>password + "new-password" value >>encoded-password H{ } clone >>profile insert-tuple @@ -116,7 +119,7 @@ IN: http.server.auth.admin { "new-password" "verify-password" } [ value empty? ] all? [ same-password-twice - "new-password" value >>password + "new-password" value >>encoded-password ] unless update-tuple @@ -139,6 +142,10 @@ IN: http.server.auth.admin TUPLE: user-admin < dispatcher ; +SYMBOL: can-administer-users? + +can-administer-users? define-capability + :: ( -- responder ) [let | ctor [ [ ] ] | user-admin new-dispatcher @@ -148,5 +155,5 @@ TUPLE: user-admin < dispatcher ; ctor "$user-admin" "delete" add-responder "admin" admin-template >>template - + { can-administer-users? } ] ; diff --git a/extra/http/server/auth/auth.factor b/extra/http/server/auth/auth.factor index a25baf3ed2..36fcff4b2e 100755 --- a/extra/http/server/auth/auth.factor +++ b/extra/http/server/auth/auth.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs namespaces kernel +USING: accessors assocs namespaces kernel sequences http.server http.server.sessions http.server.auth.providers ; @@ -33,3 +33,9 @@ M: filter-responder init-user-profile : uchange ( quot key -- ) profile swap change-at user-changed ; inline + +SYMBOL: capabilities + +V{ } clone capabilities set-global + +: define-capability ( word -- ) capabilities get push-new ; diff --git a/extra/http/server/auth/login/login.factor b/extra/http/server/auth/login/login.factor index 453f4cc4d6..9eb79649b9 100755 --- a/extra/http/server/auth/login/login.factor +++ b/extra/http/server/auth/login/login.factor @@ -1,16 +1,23 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors quotations assocs kernel splitting -base64 io combinators sequences io.files namespaces hashtables -fry io.sockets arrays threads locals qualified continuations +combinators sequences namespaces hashtables +fry arrays threads locals qualified random +io +io.sockets +io.encodings.utf8 +io.encodings.string +io.binary +continuations destructors - +checksums +checksums.sha2 html.elements http http.server http.server.auth http.server.auth.providers -http.server.auth.providers.null +http.server.auth.providers.db http.server.actions http.server.components http.server.flows @@ -25,9 +32,24 @@ QUALIFIED: smtp SYMBOL: login-failed? -TUPLE: login < dispatcher users ; +TUPLE: login < dispatcher users checksum ; -: users login get users>> ; +: users ( -- provider ) + login get users>> ; + +: encode-password ( string salt -- bytes ) + [ utf8 encode ] [ 4 >be ] bi* append + login get checksum>> checksum-bytes ; + +: >>encoded-password ( user string -- user ) + 32 random-bits [ encode-password ] keep + [ >>password ] [ >>salt ] bi* ; inline + +: valid-login? ( password user -- ? ) + [ salt>> encode-password ] [ password>> ] bi = ; + +: check-login ( password username -- user/f ) + users get-user dup [ [ valid-login? ] keep and ] [ 2drop f ] if ; ! Destructor TUPLE: user-saver user ; @@ -72,8 +94,7 @@ M: user-saver dispose form validate-form - "password" value "username" value - users check-login [ + "password" value "username" value check-login [ successful-login ] [ login-failed? on @@ -125,7 +146,7 @@ SYMBOL: user-exists? "username" value "realname" value >>realname - "new-password" value >>password + "new-password" value >>encoded-password "email" value >>email H{ } clone >>profile @@ -179,10 +200,10 @@ SYMBOL: user-exists? [ value empty? ] all? [ same-password-twice - "password" value uid users check-login + "password" value uid check-login [ login-failed? on validation-failed ] unless - "new-password" value >>password + "new-password" value >>encoded-password ] unless "realname" value >>realname @@ -314,7 +335,7 @@ SYMBOL: lost-password-from "ticket" value "username" value users claim-ticket [ - "new-password" value >>password + "new-password" value >>encoded-password users update-user "recover-4" login-template serve-template @@ -334,7 +355,7 @@ SYMBOL: lost-password-from ! ! ! Authentication logic -TUPLE: protected < filter-responder ; +TUPLE: protected < filter-responder capabilities ; C: protected @@ -342,11 +363,17 @@ C: protected begin-flow "$login/login" f ; +: check-capabilities ( responder user -- ? ) + [ capabilities>> ] [ profile>> ] bi* '[ , at ] all? ; + M: protected call-responder* ( path responder -- response ) uid dup [ - users get-user - [ logged-in-user set ] [ save-user-after ] bi - call-next-method + users get-user 2dup check-capabilities [ + [ logged-in-user set ] [ save-user-after ] bi + call-next-method + ] [ + 3drop show-login-page + ] if ] [ 3drop show-login-page ] if ; @@ -364,12 +391,13 @@ M: login call-responder* ( path responder -- response ) swap >>default "login" add-responder "logout" add-responder - no-users >>users ; + users-in-db >>users + sha-256 >>checksum ; ! ! ! Configuration : allow-edit-profile ( login -- login ) - + f "edit-profile" add-responder ; : allow-registration ( login -- login ) diff --git a/extra/http/server/auth/providers/assoc/assoc-tests.factor b/extra/http/server/auth/providers/assoc/assoc-tests.factor index 82a2b54b0e..09022b0921 100755 --- a/extra/http/server/auth/providers/assoc/assoc-tests.factor +++ b/extra/http/server/auth/providers/assoc/assoc-tests.factor @@ -1,33 +1,35 @@ IN: http.server.auth.providers.assoc.tests -USING: http.server.auth.providers +USING: http.server.actions http.server.auth.providers http.server.auth.providers.assoc tools.test namespaces accessors kernel ; - "provider" set + + >>users +login set [ t ] [ "slava" - "foobar" >>password + "foobar" >>encoded-password "slava@factorcode.org" >>email H{ } clone >>profile - "provider" get new-user + users new-user username>> "slava" = ] unit-test [ f ] [ "slava" H{ } clone >>profile - "provider" get new-user + users new-user ] unit-test -[ f ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test +[ f ] [ "fdasf" "slava" check-login >boolean ] unit-test -[ ] [ "foobar" "slava" "provider" get check-login "user" set ] unit-test +[ ] [ "foobar" "slava" check-login "user" set ] unit-test [ t ] [ "user" get >boolean ] unit-test -[ ] [ "user" get "fdasf" >>password drop ] unit-test +[ ] [ "user" get "fdasf" >>encoded-password drop ] unit-test -[ t ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test +[ t ] [ "fdasf" "slava" check-login >boolean ] unit-test -[ f ] [ "foobar" "slava" "provider" get check-login >boolean ] unit-test +[ f ] [ "foobar" "slava" check-login >boolean ] unit-test diff --git a/extra/http/server/auth/providers/db/db-tests.factor b/extra/http/server/auth/providers/db/db-tests.factor index 1a5298f050..a6a92356b6 100755 --- a/extra/http/server/auth/providers/db/db-tests.factor +++ b/extra/http/server/auth/providers/db/db-tests.factor @@ -1,10 +1,14 @@ IN: http.server.auth.providers.db.tests -USING: http.server.auth.providers +USING: http.server.actions +http.server.auth.login +http.server.auth.providers http.server.auth.providers.db tools.test namespaces db db.sqlite db.tuples continuations io.files accessors kernel ; -users-in-db "provider" set + + users-in-db >>users +login set [ "auth-test.db" temp-file delete-file ] ignore-errors @@ -14,30 +18,30 @@ users-in-db "provider" set [ t ] [ "slava" - "foobar" >>password + "foobar" >>encoded-password "slava@factorcode.org" >>email H{ } clone >>profile - "provider" get new-user + users new-user username>> "slava" = ] unit-test [ f ] [ "slava" H{ } clone >>profile - "provider" get new-user + users new-user ] unit-test - [ f ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test + [ f ] [ "fdasf" "slava" check-login >boolean ] unit-test - [ ] [ "foobar" "slava" "provider" get check-login "user" set ] unit-test + [ ] [ "foobar" "slava" check-login "user" set ] unit-test [ t ] [ "user" get >boolean ] unit-test - [ ] [ "user" get "fdasf" >>password drop ] unit-test + [ ] [ "user" get "fdasf" >>encoded-password drop ] unit-test - [ ] [ "user" get "provider" get update-user ] unit-test + [ ] [ "user" get users update-user ] unit-test - [ t ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test + [ t ] [ "fdasf" "slava" check-login >boolean ] unit-test - [ f ] [ "foobar" "slava" "provider" get check-login >boolean ] unit-test + [ f ] [ "foobar" "slava" check-login >boolean ] unit-test ] with-db diff --git a/extra/http/server/auth/providers/db/db.factor b/extra/http/server/auth/providers/db/db.factor index 66d3a00a42..b72f94f3bd 100755 --- a/extra/http/server/auth/providers/db/db.factor +++ b/extra/http/server/auth/providers/db/db.factor @@ -9,7 +9,8 @@ user "USERS" { { "username" "USERNAME" { VARCHAR 256 } +user-assigned-id+ } { "realname" "REALNAME" { VARCHAR 256 } } - { "password" "PASSWORD" { VARCHAR 256 } +not-null+ } + { "password" "PASSWORD" BLOB +not-null+ } + { "salt" "SALT" INTEGER +not-null+ } { "email" "EMAIL" { VARCHAR 256 } } { "ticket" "TICKET" { VARCHAR 256 } } { "profile" "PROFILE" FACTOR-BLOB } diff --git a/extra/http/server/auth/providers/providers.factor b/extra/http/server/auth/providers/providers.factor index 121f065292..f4c7dbbf1d 100755 --- a/extra/http/server/auth/providers/providers.factor +++ b/extra/http/server/auth/providers/providers.factor @@ -4,7 +4,7 @@ USING: kernel accessors random math.parser locals sequences math ; IN: http.server.auth.providers -TUPLE: user username realname password email ticket profile deleted changed? ; +TUPLE: user username realname password salt email ticket profile deleted changed? ; : ( username -- user ) user new @@ -17,9 +17,6 @@ GENERIC: update-user ( user provider -- ) GENERIC: new-user ( user provider -- user/f ) -: check-login ( password username provider -- user/f ) - get-user dup [ [ password>> = ] keep and ] [ 2drop f ] if ; - ! Password recovery support :: issue-ticket ( email username provider -- user/f ) diff --git a/extra/http/server/boilerplate/boilerplate.factor b/extra/http/server/boilerplate/boilerplate.factor index 1dc5effbe2..e0a4037e31 100644 --- a/extra/http/server/boilerplate/boilerplate.factor +++ b/extra/http/server/boilerplate/boilerplate.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel namespaces boxes sequences strings -io io.streams.string arrays +io io.streams.string arrays locals html.elements http http.server @@ -47,7 +47,7 @@ SYMBOL: nested-template? SYMBOL: next-template : call-next-template ( -- ) - next-template get write ; + next-template get write-html ; M: f call-template* drop call-next-template ; @@ -68,9 +68,10 @@ M: f call-template* drop call-next-template ; bi* ] with-scope ; inline -M: boilerplate call-responder* - tuck call-next-method - dup "content-type" header "text/html" = [ - clone swap template>> - [ [ with-boilerplate ] 2curry ] curry change-body - ] [ nip ] if ; +M:: boilerplate call-responder* ( path responder -- ) + path responder call-next-method + dup content-type>> "text/html" = [ + clone [| body | + [ body responder template>> with-boilerplate ] + ] change-body + ] when ; diff --git a/extra/http/server/callbacks/callbacks-tests.factor b/extra/http/server/callbacks/callbacks-tests.factor index cca5942328..31ea164a58 100755 --- a/extra/http/server/callbacks/callbacks-tests.factor +++ b/extra/http/server/callbacks/callbacks-tests.factor @@ -24,7 +24,7 @@ splitting kernel hashtables continuations ; [ [ "hello" print - "text/html" swap '[ , write ] >>body + '[ , write ] ] show-page "byebye" print [ 123 ] show-final diff --git a/extra/http/server/components/code/code.factor b/extra/http/server/components/code/code.factor index 90b70c7bcc..8bf07700e8 100644 --- a/extra/http/server/components/code/code.factor +++ b/extra/http/server/components/code/code.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: splitting kernel io sequences xmode.code2html accessors -http.server.components ; +http.server.components xml.entities ; IN: http.server.components.code TUPLE: code-renderer < text-renderer mode ; diff --git a/extra/http/server/components/components.factor b/extra/http/server/components/components.factor index cb109fc847..eb97092fb7 100755 --- a/extra/http/server/components/components.factor +++ b/extra/http/server/components/components.factor @@ -3,7 +3,7 @@ USING: accessors namespaces kernel io math.parser assocs classes words classes.tuple arrays sequences splitting mirrors hashtables fry combinators continuations math -calendar.format html.elements +calendar.format html.elements xml.entities http.server.validators ; IN: http.server.components @@ -18,13 +18,13 @@ TUPLE: field type ; C: field -M: field render-view* drop write ; +M: field render-view* drop escape-string write ; M: field render-edit* > =type [ =id ] [ =name ] bi =value input/> ; : render-error ( message -- ) - write ; + escape-string write ; TUPLE: hidden < field ; @@ -232,7 +232,7 @@ TUPLE: text-renderer rows cols ; text-renderer new-text-renderer ; M: text-renderer render-view* - drop write ; + drop escape-string write ; M: text-renderer render-edit* ; TUPLE: text < string ; @@ -261,7 +261,7 @@ TUPLE: html-text-renderer < text-renderer ; html-text-renderer new-text-renderer ; M: html-text-renderer render-view* - drop write ; + drop escape-string write ; TUPLE: html-text < text ; @@ -286,7 +286,7 @@ GENERIC: link-href ( obj -- url ) SINGLETON: link-renderer M: link-renderer render-view* - drop link-title write ; + drop link-title escape-string write ; TUPLE: link < string ; @@ -341,15 +341,19 @@ TUPLE: choice-renderer choices ; C: choice-renderer M: choice-renderer render-view* - drop write ; + drop escape-string write ; + +: render-option ( text selected? -- ) + ; + +: render-options ( text selected -- ) + [ [ drop ] [ member? ] 2bi render-option ] curry each ; M: choice-renderer render-edit* ; TUPLE: choice < string ; @@ -357,3 +361,19 @@ TUPLE: choice < string ; : ( id choices -- component ) swap choice new-string swap >>renderer ; + +! Menu +TUPLE: menu-renderer choices size ; + +C: menu-renderer + +M: menu-renderer render-edit* + ; + +TUPLE: menu < string ; + +: ( id choices -- component ) + swap menu new-string + swap >>renderer ; diff --git a/extra/http/server/components/farkup/farkup.factor b/extra/http/server/components/farkup/farkup.factor index a8d320f82f..87b7170bbf 100755 --- a/extra/http/server/components/farkup/farkup.factor +++ b/extra/http/server/components/farkup/farkup.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: splitting kernel io sequences farkup accessors -http.server.components ; +http.server.components xml.entities ; IN: http.server.components.farkup TUPLE: farkup-renderer < text-renderer ; diff --git a/extra/http/server/components/inspector/inspector.factor b/extra/http/server/components/inspector/inspector.factor index 25ee631a06..42366b57e4 100644 --- a/extra/http/server/components/inspector/inspector.factor +++ b/extra/http/server/components/inspector/inspector.factor @@ -1,13 +1,13 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: splitting kernel io sequences inspector accessors -http.server.components ; +http.server.components xml.entities html ; IN: http.server.components.inspector SINGLETON: inspector-renderer M: inspector-renderer render-view* - drop describe ; + drop [ describe ] with-html-stream ; TUPLE: inspector < component ; diff --git a/extra/http/server/forms/forms.factor b/extra/http/server/forms/forms.factor index 60f3da25b6..92fb25bb16 100644 --- a/extra/http/server/forms/forms.factor +++ b/extra/http/server/forms/forms.factor @@ -37,9 +37,7 @@ M: form init V{ } clone >>components ; ] with-form ; : ( form template -- response ) - [ components>> components set ] - [ "text/html" swap >>body ] - bi* ; + [ components>> components set ] [ ] bi* ; : view-form ( form -- response ) dup view-template>> ; diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index ad04812c63..f6dd6c57bb 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -1,9 +1,9 @@ ! Copyright (C) 2003, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: assocs kernel namespaces io io.timeouts strings splitting -threads http sequences prettyprint io.server logging calendar -html.elements accessors math.parser combinators.lib -tools.vocabs debugger html continuations random combinators +threads sequences prettyprint io.server logging calendar +http html html.elements accessors math.parser combinators.lib +tools.vocabs debugger continuations random combinators destructors io.encodings.8-bit fry classes words ; IN: http.server @@ -22,7 +22,10 @@ GENERIC: call-responder* ( path responder -- response ) 200 >>code "Document follows" >>message - swap set-content-type ; + swap >>content-type ; + +: ( quot -- response ) + "text/html" swap >>body ; TUPLE: trivial-responder response ; @@ -38,9 +41,7 @@ M: trivial-responder call-responder* nip response>> call ; ; : ( code message -- response ) - 2dup '[ , , trivial-response-body ] - "text/html" - swap >>body + 2dup '[ , , trivial-response-body ] swap >>message swap >>code ; diff --git a/extra/http/server/sessions/sessions-tests.factor b/extra/http/server/sessions/sessions-tests.factor index b4cf0bd679..0d98bf2150 100755 --- a/extra/http/server/sessions/sessions-tests.factor +++ b/extra/http/server/sessions/sessions-tests.factor @@ -143,7 +143,7 @@ M: foo call-responder* ] with-destructors response set ] unit-test - [ "text/plain" ] [ response get "content-type" header ] unit-test + [ "text/plain" ] [ response get content-type>> ] unit-test [ f ] [ response get cookies>> empty? ] unit-test ] with-scope diff --git a/extra/http/server/static/static.factor b/extra/http/server/static/static.factor index af6018fbdc..f0a367f0fb 100755 --- a/extra/http/server/static/static.factor +++ b/extra/http/server/static/static.factor @@ -1,21 +1,20 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: calendar html io io.files kernel math math.parser http -http.server namespaces parser sequences strings assocs -hashtables debugger http.mime sorting html.elements logging -calendar.format accessors io.encodings.binary fry ; +USING: calendar html io io.files kernel math math.order +math.parser http http.server namespaces parser sequences strings +assocs hashtables debugger http.mime sorting html.elements +logging calendar.format accessors io.encodings.binary fry ; IN: http.server.static ! special maps mime types to quots with effect ( path -- ) TUPLE: file-responder root hook special ; -: file-http-date ( filename -- string ) - file-info modified>> timestamp>http-string ; - -: last-modified-matches? ( filename -- ? ) - file-http-date dup [ - request get "if-modified-since" header = - ] when ; +: modified-since? ( filename -- ? ) + request get "if-modified-since" header dup [ + [ file-info modified>> ] [ rfc822>timestamp ] bi* after? + ] [ + 2drop t + ] if ; : <304> ( -- response ) 304 "Not modified" ; @@ -26,16 +25,17 @@ TUPLE: file-responder root hook special ; : ( root -- responder ) [ - swap - [ file-info size>> "content-length" set-header ] - [ file-http-date "last-modified" set-header ] - [ '[ , binary stdio get stream-copy ] >>body ] - tri + swap [ + file-info + [ size>> "content-length" set-header ] + [ modified>> "last-modified" set-header ] bi + ] + [ '[ , binary stdio get stream-copy ] >>body ] bi ] ; : serve-static ( filename mime-type -- response ) - over last-modified-matches? - [ 2drop <304> ] [ file-responder get hook>> call ] if ; + over modified-since? + [ file-responder get hook>> call ] [ 2drop <304> ] if ; : serving-path ( filename -- filename ) file-responder get root>> right-trim-separators @@ -65,8 +65,7 @@ TUPLE: file-responder root hook special ; ] simple-html-document ; : list-directory ( directory -- response ) - "text/html" - swap '[ , directory. ] >>body ; + '[ , directory. ] ; : find-index ( filename -- path ) "index.html" append-path dup exists? [ drop f ] unless ; diff --git a/extra/http/server/templating/templating.factor b/extra/http/server/templating/templating.factor index 610ec78fed..73f6095eae 100644 --- a/extra/http/server/templating/templating.factor +++ b/extra/http/server/templating/templating.factor @@ -24,5 +24,4 @@ M: template write-response-body* call-template ; ! responder integration : serve-template ( template -- response ) - "text/html" - swap '[ , call-template ] >>body ; + '[ , call-template ] ; diff --git a/extra/webapps/pastebin/pastebin.factor b/extra/webapps/pastebin/pastebin.factor index 76e7a1464a..144900d6ec 100644 --- a/extra/webapps/pastebin/pastebin.factor +++ b/extra/webapps/pastebin/pastebin.factor @@ -8,6 +8,7 @@ http.server.actions http.server.components http.server.components.code http.server.templating.chloe +http.server.auth http.server.auth.login http.server.boilerplate http.server.validators @@ -236,13 +237,17 @@ annotation "ANNOTATION" TUPLE: pastebin < dispatcher ; +SYMBOL: can-delete-pastes? + +can-delete-pastes? define-capability + : ( -- responder ) pastebin new-dispatcher "list" add-main-responder "feed.xml" add-responder [ ] "view-paste" add-responder - [ ] "$pastebin/list" "delete-paste" add-responder - [ ] "$pastebin/view-paste" "delete-annotation" add-responder + [ ] "$pastebin/list" { can-delete-pastes? } "delete-paste" add-responder + [ ] "$pastebin/view-paste" { can-delete-pastes? } "delete-annotation" add-responder [ ] "$pastebin/view-paste" add-responder [ now >>date ] "$pastebin/view-paste" "new-paste" add-responder [ now >>date ] "$pastebin/view-paste" "annotate" add-responder diff --git a/extra/webapps/planet/planet.factor b/extra/webapps/planet/planet.factor index d3260e1c70..c8aeab35a8 100755 --- a/extra/webapps/planet/planet.factor +++ b/extra/webapps/planet/planet.factor @@ -11,7 +11,8 @@ http.server.actions http.server.boilerplate http.server.templating.chloe http.server.components -http.server.auth.login ; +http.server.auth.login +http.server.auth ; IN: webapps.planet TUPLE: planet-factor < dispatcher postings ; @@ -159,11 +160,15 @@ blog "BLOGS" blog-form blog-ctor "$planet-factor/admin" "edit-blog" add-responder ] ; +SYMBOL: can-administer-planet-factor? + +can-administer-planet-factor? define-capability + : ( -- responder ) planet-factor new-dispatcher dup "list" add-main-responder dup "feed.xml" add-responder - dup "admin" add-responder + dup { can-administer-planet-factor? } "admin" add-responder "planet" planet-template >>template ; diff --git a/extra/webapps/todo/edit-todo.xml b/extra/webapps/todo/edit-todo.xml index ef1e1fd26a..9b7e9e667a 100644 --- a/extra/webapps/todo/edit-todo.xml +++ b/extra/webapps/todo/edit-todo.xml @@ -4,22 +4,22 @@ Edit Item - - + + - - - + + +
Summary:
Priority:
Description:
Summary:
Priority:
Description:
- View + View | - - + + diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index e1ebc65bb5..8bfda1aad5 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -76,5 +76,5 @@ TUPLE: todo-list < dispatcher ; ctor "$todo-list/list" "delete" add-responder "todo" todo-template >>template - + f ] ; diff --git a/extra/webapps/todo/view-todo.xml b/extra/webapps/todo/view-todo.xml index f77396c73c..1bd73f48e1 100644 --- a/extra/webapps/todo/view-todo.xml +++ b/extra/webapps/todo/view-todo.xml @@ -5,8 +5,8 @@ View Item - - + +
Summary:
Priority:
Summary:
Priority:
From 1bd8b19ff5627851c91fb6cd099930f396fb2898 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 20:01:57 -0500 Subject: [PATCH 38/47] Rename subassoc? to assoc-subset?, add subset? word for sequences --- core/assocs/assocs-docs.factor | 4 ++-- core/assocs/assocs-tests.factor | 14 +++++++------- core/assocs/assocs.factor | 4 ++-- core/sets/sets-docs.factor | 16 +++++++++++++++- core/sets/sets.factor | 6 ++++++ 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/core/assocs/assocs-docs.factor b/core/assocs/assocs-docs.factor index de62ccd878..6170eddf52 100755 --- a/core/assocs/assocs-docs.factor +++ b/core/assocs/assocs-docs.factor @@ -68,7 +68,7 @@ ARTICLE: "assocs-lookup" "Lookup and querying of assocs" ARTICLE: "assocs-sets" "Set-theoretic operations on assocs" "It is often useful to use the keys of an associative mapping as a set, exploiting the constant or logarithmic lookup time of most implementations (" { $link "alists" } " being a notable exception)." -{ $subsection subassoc? } +{ $subsection assoc-subset? } { $subsection assoc-intersect } { $subsection update } { $subsection assoc-union } @@ -215,7 +215,7 @@ HELP: assoc-all? { $values { "assoc" assoc } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "?" "a boolean" } } { $description "Tests if all entries in the assoc satisfy a predicate by applying the quotation to each entry in turn. a predicate quotation to entry in the assoc. Iteration stops if an entry is found for which the quotation outputs " { $link f } ". If the assoc is empty, always outputs " { $link t } "." } ; -HELP: subassoc? +HELP: assoc-subset? { $values { "assoc1" assoc } { "assoc2" assoc } { "?" "a new assoc" } } { $description "Tests if " { $snippet "assoc2" } " contains all key/value pairs of " { $snippet "assoc1" } "." } ; diff --git a/core/assocs/assocs-tests.factor b/core/assocs/assocs-tests.factor index 19e323bdae..30f2ec23c4 100755 --- a/core/assocs/assocs-tests.factor +++ b/core/assocs/assocs-tests.factor @@ -3,13 +3,13 @@ USING: kernel math namespaces tools.test vectors sequences sequences.private hashtables io prettyprint assocs continuations ; -[ t ] [ H{ } dup subassoc? ] unit-test -[ f ] [ H{ { 1 3 } } H{ } subassoc? ] unit-test -[ t ] [ H{ } H{ { 1 3 } } subassoc? ] unit-test -[ t ] [ H{ { 1 3 } } H{ { 1 3 } } subassoc? ] unit-test -[ f ] [ H{ { 1 3 } } H{ { 1 "hey" } } subassoc? ] unit-test -[ f ] [ H{ { 1 f } } H{ } subassoc? ] unit-test -[ t ] [ H{ { 1 f } } H{ { 1 f } } subassoc? ] unit-test +[ t ] [ H{ } dup assoc-subset? ] unit-test +[ f ] [ H{ { 1 3 } } H{ } assoc-subset? ] unit-test +[ t ] [ H{ } H{ { 1 3 } } assoc-subset? ] unit-test +[ t ] [ H{ { 1 3 } } H{ { 1 3 } } assoc-subset? ] unit-test +[ f ] [ H{ { 1 3 } } H{ { 1 "hey" } } assoc-subset? ] unit-test +[ f ] [ H{ { 1 f } } H{ } assoc-subset? ] unit-test +[ t ] [ H{ { 1 f } } H{ { 1 f } } assoc-subset? ] unit-test ! Test some combinators [ diff --git a/core/assocs/assocs.factor b/core/assocs/assocs.factor index e68c311836..92db38573a 100755 --- a/core/assocs/assocs.factor +++ b/core/assocs/assocs.factor @@ -98,11 +98,11 @@ M: assoc assoc-clone-like ( assoc exemplar -- newassoc ) : assoc-stack ( key seq -- value ) dup length 1- swap (assoc-stack) ; -: subassoc? ( assoc1 assoc2 -- ? ) +: assoc-subset? ( assoc1 assoc2 -- ? ) [ swapd at* [ = ] [ 2drop f ] if ] curry assoc-all? ; : assoc= ( assoc1 assoc2 -- ? ) - 2dup subassoc? >r swap subassoc? r> and ; + [ assoc-subset? ] [ swap assoc-subset? ] 2bi and ; : assoc-hashcode ( n assoc -- code ) [ diff --git a/core/sets/sets-docs.factor b/core/sets/sets-docs.factor index 55ef3ccddd..f4e2557a71 100644 --- a/core/sets/sets-docs.factor +++ b/core/sets/sets-docs.factor @@ -2,7 +2,7 @@ USING: kernel help.markup help.syntax sequences ; IN: sets ARTICLE: "sets" "Set-theoretic operations on sequences" -"Set-theoretic operations on sequences are defined on the " { $vocab-link "sets" } " vocabulary. These operations use hashtables internally to achieve linear running time." +"Set-theoretic operations on sequences are defined on the " { $vocab-link "sets" } " vocabulary. All of these operations use hashtables internally to achieve linear running time." $nl "Remove duplicates:" { $subsection prune } @@ -12,8 +12,14 @@ $nl { $subsection diff } { $subsection intersect } { $subsection union } +{ $subsection subset? } +{ $subsection set= } +"A word used to implement the above:" +{ $subsection unique } { $see-also member? memq? contains? all? "assocs-sets" } ; +ABOUT: "sets" + HELP: unique { $values { "seq" "a sequence" } { "assoc" "an assoc" } } { $description "Outputs a new assoc where the keys and values are equal." } @@ -59,3 +65,11 @@ HELP: union } ; { diff intersect union } related-words + +HELP: subset? +{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } } +{ $description "Tests if every element of " { $snippet "seq1" } " is contained in " { $snippet "seq2" } "." } ; + +HELP: set= +{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } } +{ $description "Tests if both sequences contain the same elements, disregrading order and duplicates." } ; diff --git a/core/sets/sets.factor b/core/sets/sets.factor index 78a92155fc..b0d26e0f30 100644 --- a/core/sets/sets.factor +++ b/core/sets/sets.factor @@ -29,3 +29,9 @@ IN: sets : union ( seq1 seq2 -- newseq ) append prune ; + +: subset? ( seq1 seq2 -- ? ) + unique [ key? ] curry all? ; + +: set= ( seq1 seq2 -- ? ) + [ unique ] bi@ = ; From a1ea2655ed1e9e9e38873db78618dde429767eb2 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 20:02:34 -0500 Subject: [PATCH 39/47] Fix problems found by builder --- core/checksums/checksums.factor | 2 +- extra/benchmark/sha1/sha1.factor | 2 +- extra/crypto/hmac/hmac.factor | 6 +++--- extra/farkup/farkup.factor | 6 ++++-- extra/io/encodings/iana/iana-docs.factor | 2 +- extra/io/encodings/iana/iana.factor | 4 ++-- extra/xmode/code2html/responder/responder.factor | 2 +- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/core/checksums/checksums.factor b/core/checksums/checksums.factor index 849d7821dd..08a13297d1 100644 --- a/core/checksums/checksums.factor +++ b/core/checksums/checksums.factor @@ -18,7 +18,7 @@ M: checksum checksum-stream >r contents r> checksum-bytes ; M: checksum checksum-lines >r B{ CHAR: \n } join r> checksum-bytes ; -: checksum-file ( path checksum -- n ) +: checksum-file ( path checksum -- value ) >r binary r> checksum-stream ; : hex-string ( seq -- str ) diff --git a/extra/benchmark/sha1/sha1.factor b/extra/benchmark/sha1/sha1.factor index c43f780135..d5ff5673c2 100644 --- a/extra/benchmark/sha1/sha1.factor +++ b/extra/benchmark/sha1/sha1.factor @@ -1,4 +1,4 @@ -USING: checksum checksums.sha1 io.files kernel ; +USING: checksums checksums.sha1 io.files kernel ; IN: benchmark.sha1 : sha1-primes-list ( -- ) diff --git a/extra/crypto/hmac/hmac.factor b/extra/crypto/hmac/hmac.factor index 9770a3a266..fe77aa8969 100755 --- a/extra/crypto/hmac/hmac.factor +++ b/extra/crypto/hmac/hmac.factor @@ -1,19 +1,19 @@ USING: arrays combinators crypto.common checksums checksums.md5 -checksums.sha1 crypto.md5.private io io.binary io.files +checksums.sha1 checksums.md5.private io io.binary io.files io.streams.byte-array kernel math math.vectors memoize sequences io.encodings.binary ; IN: crypto.hmac : sha1-hmac ( Ko Ki -- hmac ) initialize-sha1 process-sha1-block - (stream>sha1) get-sha1 + stream>sha1 get-sha1 initialize-sha1 >r process-sha1-block r> process-sha1-block get-sha1 ; : md5-hmac ( Ko Ki -- hmac ) initialize-md5 process-md5-block - (stream>md5) get-md5 + stream>md5 get-md5 initialize-md5 >r process-md5-block r> process-md5-block get-md5 ; diff --git a/extra/farkup/farkup.factor b/extra/farkup/farkup.factor index 1b8e698758..15b7b4b72c 100755 --- a/extra/farkup/farkup.factor +++ b/extra/farkup/farkup.factor @@ -64,8 +64,10 @@ MEMO: eq ( -- parser ) ] with-string-writer ; : check-url ( href -- href' ) - dup { "http://" "https://" "ftp://" } [ head? ] with contains? - [ drop "/" ] unless ; + CHAR: : over member? [ + dup { "http://" "https://" "ftp://" } [ head? ] with contains? + [ drop "/" ] unless + ] when ; : escape-link ( href text -- href-esc text-esc ) >r check-url escape-quoted-string r> escape-string ; diff --git a/extra/io/encodings/iana/iana-docs.factor b/extra/io/encodings/iana/iana-docs.factor index 3542012a85..d4a7a65797 100644 --- a/extra/io/encodings/iana/iana-docs.factor +++ b/extra/io/encodings/iana/iana-docs.factor @@ -2,7 +2,7 @@ USING: help.syntax help.markup ; IN: io.encodings.iana HELP: name>encoding -{ $values { "string" "an encoding name" } { "encoding" "an encoding descriptor" } } +{ $values { "name" "an encoding name" } { "encoding" "an encoding descriptor" } } { "Given an IANA-registered encoding name, find the encoding descriptor that represents it, or " { $code f } " if it is not found (either not implemented in Factor or not registered)." } ; HELP: encoding>name diff --git a/extra/io/encodings/iana/iana.factor b/extra/io/encodings/iana/iana.factor index 301b027637..24badaf683 100644 --- a/extra/io/encodings/iana/iana.factor +++ b/extra/io/encodings/iana/iana.factor @@ -27,10 +27,10 @@ VALUE: n>e-table } ; PRIVATE> -: name>encoding ( string -- encoding ) +: name>encoding ( name -- encoding ) n>e-table at ; -: encoding>name ( encoding -- string ) +: encoding>name ( encoding -- name ) e>n-table at ; swap - [ file-http-date "last-modified" set-header ] + [ "last-modified" set-header ] [ '[ , From 583d036e8a30c739b2fe801ed758c3a76c870404 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 20:02:45 -0500 Subject: [PATCH 40/47] Use subset? word --- core/optimizer/def-use/def-use-tests.factor | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/optimizer/def-use/def-use-tests.factor b/core/optimizer/def-use/def-use-tests.factor index 914018437a..ef829da9f2 100755 --- a/core/optimizer/def-use/def-use-tests.factor +++ b/core/optimizer/def-use/def-use-tests.factor @@ -11,10 +11,6 @@ namespaces assocs kernel sequences math tools.test words ; dataflow compute-def-use drop compute-dead-literals keys [ value-literal ] map ; -: subset? [ member? ] curry all? ; - -: set= 2dup subset? >r swap subset? r> and ; - [ { [ + ] } ] [ [ [ 1 2 3 ] [ + ] over drop drop ] kill-set ] unit-test From 5bae9bf6efcf64c9d864e623c777d2fc7daf004d Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 1 May 2008 20:03:02 -0500 Subject: [PATCH 41/47] Implemented user capabilities --- extra/http/http-tests.factor | 6 +++ extra/http/http.factor | 38 ++++++++++---- extra/http/server/auth/admin/admin.factor | 36 ++++++++++--- extra/http/server/auth/admin/admin.xml | 2 +- extra/http/server/auth/admin/edit-user.xml | 5 ++ extra/http/server/auth/admin/new-user.xml | 5 ++ extra/http/server/auth/basic/basic.factor | 2 +- extra/http/server/auth/login/login.factor | 4 +- .../auth/providers/assoc/assoc-tests.factor | 4 +- extra/http/server/auth/providers/db/db.factor | 1 + .../server/auth/providers/providers.factor | 5 +- .../http/server/components/components.factor | 43 ++++++++++++---- extra/http/server/static/static.factor | 16 ++++-- extra/webapps/factor-website/page.css | 48 +++++++++++++++++ extra/webapps/factor-website/page.xml | 51 +------------------ extra/webapps/planet/planet.xml | 5 +- extra/webapps/todo/todo.xml | 2 +- 17 files changed, 183 insertions(+), 90 deletions(-) create mode 100644 extra/webapps/factor-website/page.css diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 1f1ce361b2..831becd264 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -24,6 +24,12 @@ IN: http.tests [ "/bar" ] [ "http://foo.com/bar" url>path ] unit-test [ "/bar" ] [ "/bar" url>path ] unit-test +[ "a=b&a=c" ] [ { { "a" { "b" "c" } } } assoc>query ] unit-test + +[ H{ { "a" "b" } } ] [ "a=b" query>assoc ] unit-test + +[ H{ { "a" { "b" "c" } } } ] [ "a=b&a=c" query>assoc ] unit-test + : lf>crlf "\n" split "\r\n" join ; STRING: read-request-test-1 diff --git a/extra/http/http.factor b/extra/http/http.factor index c5f57d4c04..315250692b 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -119,21 +119,41 @@ IN: http header-value>string check-header-string write crlf ] assoc-each crlf ; +: add-query-param ( value key assoc -- ) + [ + at [ + { + { [ dup string? ] [ swap 2array ] } + { [ dup array? ] [ swap suffix ] } + { [ dup not ] [ drop ] } + } cond + ] when* + ] 2keep set-at ; + : query>assoc ( query -- assoc ) dup [ - "&" split [ - "=" split1 [ dup [ url-decode ] when ] bi@ - ] H{ } map>assoc + "&" split H{ } clone [ + [ + >r "=" split1 [ dup [ url-decode ] when ] bi@ swap r> + add-query-param + ] curry each + ] keep ] when ; : assoc>query ( hash -- str ) [ - [ url-encode ] - [ dup number? [ number>string ] when url-encode ] - bi* - "=" swap 3append - ] { } assoc>map - "&" join ; + { + { [ dup number? ] [ number>string ] } + { [ dup string? ] [ 1array ] } + { [ dup sequence? ] [ ] } + } cond + ] assoc-map + [ + [ + >r url-encode r> + [ url-encode "=" swap 3append , ] with each + ] assoc-each + ] { } make "&" join ; TUPLE: cookie name value path domain expires max-age http-only ; diff --git a/extra/http/server/auth/admin/admin.factor b/extra/http/server/auth/admin/admin.factor index 0dc5d3560e..e762103d7b 100644 --- a/extra/http/server/auth/admin/admin.factor +++ b/extra/http/server/auth/admin/admin.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences accessors namespaces combinators -locals db.tuples +USING: kernel sequences accessors namespaces combinators words +assocs locals db.tuples arrays splitting strings qualified + http.server.templating.chloe http.server.boilerplate http.server.auth.providers @@ -10,17 +11,26 @@ http.server.auth.login http.server.auth http.server.forms http.server.components.inspector -http.server.components http.server.validators http.server.sessions http.server.actions http.server.crud http.server ; +EXCLUDE: http.server.components => string? number? ; IN: http.server.auth.admin : admin-template ( name -- template ) "resource:extra/http/server/auth/admin/" swap ".xml" 3append ; +: words>strings ( seq -- seq' ) + [ [ word-vocabulary ] [ drop ":" ] [ word-name ] tri 3append ] map ; + +: strings>words ( seq -- seq' ) + [ ":" split1 swap lookup ] map ; + +: ( id -- component ) + capabilities get words>strings ; + : ( -- form ) "user" "new-user" admin-template >>edit-template @@ -28,8 +38,8 @@ IN: http.server.auth.admin "realname" add-field "new-password" t >>required add-field "verify-password" t >>required add-field - "email" add-field ; - ! "capabilities" add-field ; + "email" add-field + "capabilities" add-field ; : ( -- form ) "user" @@ -40,8 +50,8 @@ IN: http.server.auth.admin "new-password" add-field "verify-password" add-field "email" add-field - "profile" add-field ; - ! "capabilities" add-field ; + "profile" add-field + "capabilities" add-field ; : ( -- form ) "user-list" @@ -102,6 +112,7 @@ IN: http.server.auth.admin [ realname>> "realname" set-value ] [ email>> "email" set-value ] [ profile>> "profile" set-value ] + [ capabilities>> words>strings "capabilities" set-value ] } cleave ] >>init @@ -122,6 +133,11 @@ IN: http.server.auth.admin "new-password" value >>encoded-password ] unless + "capabilities" value { + { [ dup string? ] [ 1array ] } + { [ dup array? ] [ ] } + } cond strings>words >>capabilities + update-tuple next f @@ -157,3 +173,9 @@ can-administer-users? define-capability "admin" admin-template >>template { can-administer-users? } ] ; + +: make-admin ( username -- ) + + select-tuple + [ can-administer-users? suffix ] change-capabilities + update-tuple ; diff --git a/extra/http/server/auth/admin/admin.xml b/extra/http/server/auth/admin/admin.xml index d3c0ff4c90..1864c3c4bf 100644 --- a/extra/http/server/auth/admin/admin.xml +++ b/extra/http/server/auth/admin/admin.xml @@ -2,7 +2,7 @@ - +