From 90b6b38fd132a227c848c09fb6d77651f0274451 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 19 Feb 2009 18:49:13 -0500 Subject: [PATCH 01/24] Changed math.dual to define words as dword instead of overloading generic words on dual numbers. --- basis/math/functions/functions.factor | 8 +--- .../math/derivatives/derivatives-tests.factor | 4 -- extra/math/dual/dual-docs.factor | 6 +-- extra/math/dual/dual-tests.factor | 6 +-- extra/math/dual/dual.factor | 43 +++++-------------- 5 files changed, 19 insertions(+), 48 deletions(-) delete mode 100644 extra/math/derivatives/derivatives-tests.factor diff --git a/basis/math/functions/functions.factor b/basis/math/functions/functions.factor index 3a1ce18daa..85b4d711ac 100644 --- a/basis/math/functions/functions.factor +++ b/basis/math/functions/functions.factor @@ -252,14 +252,10 @@ M: real tanh ftanh ; : -i* ( x -- y ) >rect swap neg rect> ; -GENERIC: asin ( x -- y ) foldable - -M: number asin +: asin ( x -- y ) dup [-1,1]? [ fasin ] [ i* asinh -i* ] if ; inline -GENERIC: acos ( x -- y ) foldable - -M: number acos +: acos ( x -- y ) dup [-1,1]? [ facos ] [ asin pi 2 / swap - ] if ; inline diff --git a/extra/math/derivatives/derivatives-tests.factor b/extra/math/derivatives/derivatives-tests.factor deleted file mode 100644 index f95eb43849..0000000000 --- a/extra/math/derivatives/derivatives-tests.factor +++ /dev/null @@ -1,4 +0,0 @@ -! Copyright (C) 2009 Jason W. Merrill. -! See http://factorcode.org/license.txt for BSD license. -USING: tools.test automatic-differentiation.derivatives ; -IN: automatic-differentiation.derivatives.tests diff --git a/extra/math/dual/dual-docs.factor b/extra/math/dual/dual-docs.factor index 6c287a8f1e..1f24c8217c 100644 --- a/extra/math/dual/dual-docs.factor +++ b/extra/math/dual/dual-docs.factor @@ -88,14 +88,14 @@ HELP: drecip } { $description "Reciprocal of a dual number." } ; -HELP: define-dual-method +HELP: define-dual { $values { "word" word } } -{ $description "Defines a method on the dual numbers for generic word." } +{ $description "Defines a word " { $snippet "d[word]" } " in the " { $vocab-link "math.dual" } " vocabulary that operates on dual numbers." } { $notes "Uses the derivative word-prop, which holds a list of quotations giving the partial derivatives of the word with respect to each of its arguments. This can be set using " { $link POSTPONE: DERIVATIVE: } "." } ; -{ define-dual-method dual-op POSTPONE: DERIVATIVE: } related-words +{ define-dual dual-op POSTPONE: DERIVATIVE: } related-words HELP: dual { $class-description "The class of dual numbers with non-zero epsilon part." } ; diff --git a/extra/math/dual/dual-tests.factor b/extra/math/dual/dual-tests.factor index ea46c46124..dbafe74d6a 100644 --- a/extra/math/dual/dual-tests.factor +++ b/extra/math/dual/dual-tests.factor @@ -4,13 +4,13 @@ USING: tools.test math.dual kernel accessors math math.functions math.constants ; IN: math.dual.tests -[ 0.0 1.0 ] [ 0 1 sin unpack-dual ] unit-test -[ 1.0 0.0 ] [ 0 1 cos unpack-dual ] unit-test +[ 0.0 1.0 ] [ 0 1 dsin unpack-dual ] unit-test +[ 1.0 0.0 ] [ 0 1 dcos unpack-dual ] unit-test [ 3 5 ] [ 1 5 2 d+ unpack-dual ] unit-test [ 0 -1 ] [ 1 5 1 6 d- unpack-dual ] unit-test [ 2 1 ] [ 2 3 1 -1 d* unpack-dual ] unit-test [ 1/2 -1/4 ] [ 2 1 1 swap d/ unpack-dual ] unit-test [ 2 ] [ 1 1 2 d^ epsilon-part>> ] unit-test -[ 2.0 .25 ] [ 4 1 sqrt unpack-dual ] unit-test +[ 2.0 .25 ] [ 4 1 dsqrt unpack-dual ] unit-test [ 2 -1 ] [ -2 1 dabs unpack-dual ] unit-test [ -2 -1 ] [ 2 1 dneg unpack-dual ] unit-test \ No newline at end of file diff --git a/extra/math/dual/dual.factor b/extra/math/dual/dual.factor index 36d684bc6d..c85c23e51d 100644 --- a/extra/math/dual/dual.factor +++ b/extra/math/dual/dual.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2009 Jason W. Merrill. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.functions math.derivatives accessors - macros words effects sequences generalizations fry + macros words effects vocabs sequences generalizations fry combinators.smart generic compiler.units ; IN: math.dual @@ -57,36 +57,15 @@ MACRO: dual-op ( word -- ) tri '[ _ @ @ ] ; -: define-dual-method ( word -- ) - [ \ dual swap create-method ] keep '[ _ dual-op ] define ; +: define-dual ( word -- ) + [ + [ stack-effect ] + [ name>> "d" prepend "math.dual" create ] + bi [ set-stack-effect ] keep + ] + keep + '[ _ dual-op ] define ; ! Specialize math functions to operate on dual numbers. -[ { sqrt exp log sin cos tan sinh cosh tanh acos asin atan } - [ define-dual-method ] each ] with-compilation-unit - -! Inverse methods { asinh, acosh, atanh } are not generic, so -! there is no way to specialize them for dual numbers. However, -! they are defined in terms of functions that can operate on -! dual numbers and arithmetic methods, so if it becomes -! possible to make arithmetic operators work directly on dual -! numbers, we will get these for free. - -! Arithmetic words are not generic (yet?), so we have to -! define special versions of them to operate on dual numbers. -: d+ ( x y -- x+y ) \ + dual-op ; -: d- ( x y -- x-y ) \ - dual-op ; -: d* ( x y -- x*y ) \ * dual-op ; -: d/ ( x y -- x/y ) \ / dual-op ; -: d^ ( x y -- x^y ) \ ^ dual-op ; - -: dabs ( x -- |x| ) \ abs dual-op ; - -! The following words are also not generic, but are defined in -! terms of words that can operate on dual numbers and -! arithmetic. If it becomes possible to implement arithmetic on -! dual numbers directly, these functions can be deleted. -: dneg ( x -- -x ) \ neg dual-op ; -: drecip ( x -- 1/x ) \ recip dual-op ; -: dasinh ( x -- y ) \ asinh dual-op ; -: dacosh ( x -- y ) \ acosh dual-op ; -: datanh ( x -- y ) \ atanh dual-op ; \ No newline at end of file +[ all-words [ "derivative" word-prop ] filter + [ define-dual ] each ] with-compilation-unit \ No newline at end of file From a61bac7ab5a158f07d81a71f482538ca5932328a Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 19 Feb 2009 18:26:11 -0600 Subject: [PATCH 02/24] fix sqlite foreign triggers create/delete bug ignore-errors only if there is a sql spec defined for the class until database-specific errors are implemented --- basis/db/sqlite/lib/lib.factor | 6 +- basis/db/sqlite/sqlite-tests.factor | 8 +- basis/db/sqlite/sqlite.factor | 135 ++++++++++++++++++++-------- basis/db/tuples/tuples.factor | 37 +++++--- 4 files changed, 130 insertions(+), 56 deletions(-) diff --git a/basis/db/sqlite/lib/lib.factor b/basis/db/sqlite/lib/lib.factor index b1bc9aa1a2..60141bc830 100644 --- a/basis/db/sqlite/lib/lib.factor +++ b/basis/db/sqlite/lib/lib.factor @@ -5,8 +5,7 @@ namespaces sequences db.sqlite.ffi db combinators continuations db.types calendar.format serialize io.streams.byte-array byte-arrays io.encodings.binary io.backend db.errors present urls io.encodings.utf8 -io.encodings.string accessors shuffle io prettyprint -db.private ; +io.encodings.string accessors shuffle io db.private ; IN: db.sqlite.lib ERROR: sqlite-error < db-error n string ; @@ -125,8 +124,7 @@ ERROR: sqlite-sql-error < sql-error n string ; ] if* (sqlite-bind-type) ; : sqlite-finalize ( handle -- ) sqlite3_finalize sqlite-check-result ; -: sqlite-reset ( handle -- ) -"resetting: " write dup . sqlite3_reset sqlite-check-result ; +: sqlite-reset ( handle -- ) sqlite3_reset sqlite-check-result ; : sqlite-clear-bindings ( handle -- ) sqlite3_clear_bindings sqlite-check-result ; : sqlite-#columns ( query -- int ) sqlite3_column_count ; diff --git a/basis/db/sqlite/sqlite-tests.factor b/basis/db/sqlite/sqlite-tests.factor index 5ad4b0c889..677ec17a6e 100644 --- a/basis/db/sqlite/sqlite-tests.factor +++ b/basis/db/sqlite/sqlite-tests.factor @@ -1,6 +1,7 @@ USING: io io.files io.files.temp io.directories io.launcher kernel namespaces prettyprint tools.test db.sqlite db sequences -continuations db.types db.tuples unicode.case ; +continuations db.types db.tuples unicode.case accessors arrays +sorting ; IN: db.sqlite.tests : db-path ( -- path ) "test.db" temp-file ; @@ -74,8 +75,9 @@ IN: db.sqlite.tests ] with-db ] unit-test +[ \ swap ensure-table ] must-fail + ! You don't need a primary key -USING: accessors arrays sorting ; TUPLE: things one two ; things "THINGS" { @@ -163,5 +165,3 @@ watch "WATCH" { user>> f user boa select-tuple ] with-db ] unit-test - -[ \ swap ensure-table ] must-fail diff --git a/basis/db/sqlite/sqlite.factor b/basis/db/sqlite/sqlite.factor index d006145ea8..62a1b4714f 100755 --- a/basis/db/sqlite/sqlite.factor +++ b/basis/db/sqlite/sqlite.factor @@ -1,12 +1,12 @@ ! Copyright (C) 2005, 2008 Chris Double, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: alien arrays assocs classes compiler db hashtables -io.files kernel math math.parser namespaces prettyprint +io.files kernel math math.parser namespaces prettyprint fry sequences strings classes.tuple alien.c-types continuations db.sqlite.lib db.sqlite.ffi db.tuples words db.types combinators math.intervals io nmake accessors vectors math.ranges random math.bitwise db.queries destructors db.tuples.private interpolate -io.streams.string multiline make db.private ; +io.streams.string multiline make db.private sequences.deep ; IN: db.sqlite TUPLE: sqlite-db path ; @@ -126,30 +126,6 @@ M: sqlite-statement query-results ( query -- result-set ) dup handle>> sqlite-result-set new-result-set dup advance-row ; -M: sqlite-db-connection create-sql-statement ( class -- statement ) - [ - dupd - "create table " 0% 0% - "(" 0% [ ", " 0% ] [ - dup "sql-spec" set - dup column-name>> [ "table-id" set ] [ 0% ] bi - " " 0% - dup type>> lookup-create-type 0% - modifiers 0% - ] interleave - - find-primary-key [ - ", " 0% - "primary key(" 0% - [ "," 0% ] [ column-name>> 0% ] interleave - ")" 0% - ] unless-empty - ");" 0% - ] query-make ; - -M: sqlite-db-connection drop-sql-statement ( class -- statement ) - [ "drop table " 0% 0% ";" 0% drop ] query-make ; - M: sqlite-db-connection ( tuple -- statement ) [ "insert into " 0% 0% @@ -225,7 +201,7 @@ M: sqlite-db-connection persistent-table ( -- assoc ) : insert-trigger ( -- string ) [ <" - CREATE TRIGGER fki_${table-name}_${foreign-table-name}_id + CREATE TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE INSERT ON ${table-name} FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') @@ -237,7 +213,7 @@ M: sqlite-db-connection persistent-table ( -- assoc ) : insert-trigger-not-null ( -- string ) [ <" - CREATE TRIGGER fki_${table-name}_${foreign-table-name}_id + CREATE TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE INSERT ON ${table-name} FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') @@ -247,10 +223,17 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; +: drop-insert-trigger ( -- string ) + [ + <" + DROP TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; + "> interpolate + ] with-string-writer ; + : update-trigger ( -- string ) [ <" - CREATE TRIGGER fku_${table-name}_${foreign-table-name}_id + CREATE TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE UPDATE ON ${table-name} FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') @@ -262,7 +245,7 @@ M: sqlite-db-connection persistent-table ( -- assoc ) : update-trigger-not-null ( -- string ) [ <" - CREATE TRIGGER fku_${table-name}_${foreign-table-name}_id + CREATE TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE UPDATE ON ${table-name} FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') @@ -272,10 +255,17 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; +: drop-update-trigger ( -- string ) + [ + <" + DROP TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; + "> interpolate + ] with-string-writer ; + : delete-trigger-restrict ( -- string ) [ <" - CREATE TRIGGER fkd_${table-name}_${foreign-table-name}_id + CREATE TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE DELETE ON ${foreign-table-name} FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') @@ -284,10 +274,17 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; +: drop-delete-trigger-restrict ( -- string ) + [ + <" + DROP TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; + "> interpolate + ] with-string-writer ; + : delete-trigger-cascade ( -- string ) [ <" - CREATE TRIGGER fkd_${table-name}_${foreign-table-name}_id + CREATE TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE DELETE ON ${foreign-table-name} FOR EACH ROW BEGIN DELETE from ${table-name} WHERE ${table-id} = OLD.${foreign-table-id}; @@ -295,6 +292,13 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; +: drop-delete-trigger-cascade ( -- string ) + [ + <" + DROP TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; + "> interpolate + ] with-string-writer ; + : can-be-null? ( -- ? ) "sql-spec" get modifiers>> [ +not-null+ = ] any? not ; @@ -318,14 +322,69 @@ M: sqlite-db-connection persistent-table ( -- assoc ) delete-trigger-restrict sqlite-trigger, ] if ; +: drop-sqlite-triggers ( -- ) + drop-insert-trigger sqlite-trigger, + drop-update-trigger sqlite-trigger, + delete-cascade? [ + drop-delete-trigger-cascade sqlite-trigger, + ] [ + drop-delete-trigger-restrict sqlite-trigger, + ] if ; + +: db-triggers ( sql-specs word -- ) + '[ + [ modifiers>> [ +foreign-id+ = ] deep-any? ] filter + [ + [ class>> db-table-name "db-table" set ] + [ column-name>> "table-id" set ] + [ + modifiers>> [ [ +foreign-id+ = ] deep-any? ] filter + [ + [ second db-table-name "foreign-table-name" set ] + [ third "foreign-table-id" set ] bi + _ execute + ] each + ] tri + ] each + ] call ; + +: sqlite-create-table ( sql-specs class-name -- ) + [ + "create table " 0% 0% + "(" 0% [ ", " 0% ] [ + dup "sql-spec" set + dup column-name>> [ "table-id" set ] [ 0% ] bi + " " 0% + dup type>> lookup-create-type 0% + modifiers 0% + ] interleave + ] [ + drop + find-primary-key [ + ", " 0% + "primary key(" 0% + [ "," 0% ] [ column-name>> 0% ] interleave + ")" 0% + ] unless-empty + ");" 0% + ] 2bi ; + +M: sqlite-db-connection create-sql-statement ( class -- statement ) + [ + ! specs name + [ sqlite-create-table ] + [ drop \ create-sqlite-triggers db-triggers ] 2bi + ] query-make ; + +M: sqlite-db-connection drop-sql-statement ( class -- statements ) + [ + [ nip "drop table " 0% 0% ";" 0% ] + [ drop \ drop-sqlite-triggers db-triggers ] 2bi + ] query-make ; + M: sqlite-db-connection compound ( string seq -- new-string ) over { { "default" [ first number>string " " glue ] } - { "references" [ - [ >reference-string ] keep - first2 [ db-table-name "foreign-table-name" set ] - [ "foreign-table-id" set ] bi* - create-sqlite-triggers - ] } + { "references" [ >reference-string ] } [ 2drop ] } case ; diff --git a/basis/db/tuples/tuples.factor b/basis/db/tuples/tuples.factor index 219116aefd..9edd5bac69 100644 --- a/basis/db/tuples/tuples.factor +++ b/basis/db/tuples/tuples.factor @@ -3,7 +3,8 @@ USING: arrays assocs classes db kernel namespaces classes.tuple words sequences slots math accessors math.parser io prettyprint db.types continuations -destructors mirrors sets db.types db.private ; +destructors mirrors sets db.types db.private fry +combinators.short-circuit ; IN: db.tuples HOOK: create-sql-statement db-connection ( class -- object ) @@ -29,7 +30,7 @@ GENERIC: eval-generator ( singleton -- object ) : resulting-tuple ( exemplar-tuple row out-params -- tuple ) rot class new [ - [ [ slot-name>> ] dip set-slot-named ] curry 2each + '[ slot-name>> _ set-slot-named ] 2each ] keep ; : query-tuples ( exemplar-tuple statement -- seq ) @@ -98,33 +99,49 @@ M: query >query clone ; M: tuple >query swap >>tuple ; +ERROR: no-defined-persistent object ; + +: ensure-defined-persistent ( object -- object ) + dup { [ class? ] [ "db-table" word-prop ] } 1&& [ + no-defined-persistent + ] unless ; + : create-table ( class -- ) + ensure-defined-persistent create-sql-statement [ execute-statement ] with-disposals ; : drop-table ( class -- ) + ensure-defined-persistent drop-sql-statement [ execute-statement ] with-disposals ; : recreate-table ( class -- ) + ensure-defined-persistent [ - [ drop-sql-statement [ execute-statement ] with-disposals - ] curry ignore-errors + '[ + _ drop-sql-statement [ execute-statement ] with-disposals + ] ignore-errors ] [ create-table ] bi ; -: ensure-table ( class -- ) [ create-table ] curry ignore-errors ; +: ensure-table ( class -- ) + ensure-defined-persistent + '[ _ create-table ] ignore-errors ; : ensure-tables ( classes -- ) [ ensure-table ] each ; : insert-tuple ( tuple -- ) - dup class db-columns find-primary-key db-assigned-id-spec? + dup class ensure-defined-persistent + db-columns find-primary-key db-assigned-id-spec? [ insert-db-assigned-statement ] [ insert-user-assigned-statement ] if ; : update-tuple ( tuple -- ) - dup class + dup class ensure-defined-persistent db-connection get update-statements>> [ ] cache [ bind-tuple ] keep execute-statement ; : delete-tuples ( tuple -- ) - dup dup class [ + dup + dup class ensure-defined-persistent + [ [ bind-tuple ] keep execute-statement ] with-disposal ; @@ -132,8 +149,8 @@ M: tuple >query swap >>tuple ; >query [ tuple>> ] [ query>statement ] bi do-select ; : select-tuple ( query/tuple -- tuple/f ) - >query 1 >>limit [ tuple>> ] [ query>statement ] bi do-select - [ f ] [ first ] if-empty ; + >query 1 >>limit [ tuple>> ] [ query>statement ] bi + do-select [ f ] [ first ] if-empty ; : count-tuples ( query/tuple -- n ) >query [ tuple>> ] [ ] bi do-count From dd1587c74582b08267de6d8c2278809e31265088 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Thu, 19 Feb 2009 18:52:45 -0600 Subject: [PATCH 03/24] Fixing SQLite unit tests --- basis/db/sqlite/sqlite-tests.factor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/basis/db/sqlite/sqlite-tests.factor b/basis/db/sqlite/sqlite-tests.factor index 677ec17a6e..fd730f07ae 100644 --- a/basis/db/sqlite/sqlite-tests.factor +++ b/basis/db/sqlite/sqlite-tests.factor @@ -117,7 +117,7 @@ hi "HELLO" { 1 insert-tuple f select-tuple 1 1 insert-tuple - f select-tuple + f f select-tuple hi drop-table foo drop-table ] with-db @@ -160,6 +160,7 @@ watch "WATCH" { show new insert-tuple show new select-tuple "littledan" f user boa select-tuple + swap [ username>> ] [ id>> ] bi* watch boa insert-tuple watch new select-tuple user>> f user boa select-tuple From d59415d23b606ad7d89e1a6d634d6644658f5a70 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 19 Feb 2009 22:21:31 -0500 Subject: [PATCH 04/24] Fixed help for math.dual. Help is now autogenerated where possible. --- extra/math/dual/dual-docs.factor | 79 -------------------------------- extra/math/dual/dual.factor | 30 ++++++++---- 2 files changed, 21 insertions(+), 88 deletions(-) diff --git a/extra/math/dual/dual-docs.factor b/extra/math/dual/dual-docs.factor index 1f24c8217c..67b3d6ae97 100644 --- a/extra/math/dual/dual-docs.factor +++ b/extra/math/dual/dual-docs.factor @@ -10,84 +10,6 @@ HELP: } { $description "Creates a dual number from its ordinary and epsilon parts." } ; -HELP: d* -{ $values - { "x" dual } { "y" dual } - { "x*y" dual } -} -{ $description "Multiply dual numbers." } ; - -HELP: d+ -{ $values - { "x" dual } { "y" dual } - { "x+y" dual } -} -{ $description "Add dual numbers." } ; - -HELP: d- -{ $values - { "x" dual } { "y" dual } - { "x-y" dual } -} -{ $description "Subtract dual numbers." } ; - -HELP: d/ -{ $values - { "x" dual } { "y" dual } - { "x/y" dual } -} -{ $description "Divide dual numbers." } -{ $errors "Throws an error if the ordinary part of " { $snippet "x" } " is zero." } ; - -HELP: d^ -{ $values - { "x" dual } { "y" dual } - { "x^y" dual } -} -{ $description "Raise a dual number to a (possibly dual) power" } ; - -HELP: dabs -{ $values - { "x" dual } - { "|x|" dual } -} -{ $description "Absolute value of a dual number." } ; - -HELP: dacosh -{ $values - { "x" dual } - { "y" dual } -} -{ $description "Inverse hyberbolic cosine of a dual number." } ; - -HELP: dasinh -{ $values - { "x" dual } - { "y" dual } -} -{ $description "Inverse hyberbolic sine of a dual number." } ; - -HELP: datanh -{ $values - { "x" dual } - { "y" dual } -} -{ $description "Inverse hyberbolic tangent of a dual number." } ; - -HELP: dneg -{ $values - { "x" dual } - { "-x" dual } -} -{ $description "Negative of a dual number." } ; - -HELP: drecip -{ $values - { "x" dual } - { "1/x" dual } -} -{ $description "Reciprocal of a dual number." } ; - HELP: define-dual { $values { "word" word } @@ -128,5 +50,4 @@ $nl "Dual numbers are ordered pairs " { $snippet ""} "--an ordinary part and an epsilon part--with component-wise addition and multiplication defined by "{ $snippet "* = " } ". They are analagous to complex numbers with " { $snippet "i^2 = 0" } "instead of " { $snippet "i^2 = -1" } ". For well-behaved functions " { $snippet "f" } ", " { $snippet "f() = f(o1) + e1*f'(o1)" } ", where " { $snippet "f'"} " is the derivative of " { $snippet "f" } "." ; - ABOUT: "math.dual" diff --git a/extra/math/dual/dual.factor b/extra/math/dual/dual.factor index c85c23e51d..3e0e5437b4 100644 --- a/extra/math/dual/dual.factor +++ b/extra/math/dual/dual.factor @@ -1,8 +1,9 @@ ! Copyright (C) 2009 Jason W. Merrill. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.functions math.derivatives accessors - macros words effects vocabs sequences generalizations fry - combinators.smart generic compiler.units ; + macros generic compiler.units words effects vocabs + sequences arrays assocs generalizations fry make + combinators.smart help help.markup ; IN: math.dual @@ -48,6 +49,19 @@ MACRO: chain-rule ( word -- e ) tri '[ [ @ _ @ ] sum-outputs ] ; +: set-dual-help ( word dword -- ) + [ swap + [ stack-effect [ in>> ] [ out>> ] bi append + [ dual ] { } map>assoc { $values } prepend + ] + [ [ { $description } % "Version of " , + { $link } swap suffix , + " extended to work on dual numbers." , ] + { } make + ] + bi* 2array + ] keep set-word-help ; + PRIVATE> MACRO: dual-op ( word -- ) @@ -58,13 +72,11 @@ MACRO: dual-op ( word -- ) '[ _ @ @ ] ; : define-dual ( word -- ) - [ - [ stack-effect ] - [ name>> "d" prepend "math.dual" create ] - bi [ set-stack-effect ] keep - ] - keep - '[ _ dual-op ] define ; + dup name>> "d" prepend "math.dual" create + [ [ stack-effect ] dip set-stack-effect ] + [ set-dual-help ] + [ swap '[ _ dual-op ] define ] + 2tri ; ! Specialize math functions to operate on dual numbers. [ all-words [ "derivative" word-prop ] filter From 19acf89d82b0f7f33f58b02cbe505930432a036d Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 12:12:00 -0600 Subject: [PATCH 05/24] fix find-in-program-files --- basis/io/directories/search/search.factor | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/basis/io/directories/search/search.factor b/basis/io/directories/search/search.factor index 41031f8ac3..b56fb7b6a3 100755 --- a/basis/io/directories/search/search.factor +++ b/basis/io/directories/search/search.factor @@ -57,8 +57,14 @@ PRIVATE> pusher [ [ f ] compose iterate-directory drop ] dip ] [ drop f ] recover ; inline +ERROR: file-not-found ; + : find-in-directories ( directories bfs? quot: ( obj -- ? ) -- path'/f ) - '[ _ _ find-file ] attempt-all ; + [ + '[ _ _ find-file [ file-not-found ] unless* ] attempt-all + ] [ + drop f + ] recover ; : find-all-in-directories ( directories bfs? quot: ( obj -- ? ) -- paths/f ) '[ _ _ find-all-files ] map concat ; From 394ec538a1afdd8d695b4aeb3b44e87147285006 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 12:15:26 -0600 Subject: [PATCH 06/24] make emacsw32 work on windows out of the box --- basis/editors/emacs/emacs.factor | 13 +++++++++---- basis/editors/emacs/windows/authors.txt | 1 + basis/editors/emacs/windows/windows.factor | 9 +++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100755 basis/editors/emacs/windows/authors.txt create mode 100755 basis/editors/emacs/windows/windows.factor diff --git a/basis/editors/emacs/emacs.factor b/basis/editors/emacs/emacs.factor index 79387f9820..fa78c1b429 100644 --- a/basis/editors/emacs/emacs.factor +++ b/basis/editors/emacs/emacs.factor @@ -1,12 +1,18 @@ USING: definitions io.launcher kernel parser words sequences math -math.parser namespaces editors make system ; +math.parser namespaces editors make system combinators.short-circuit ; IN: editors.emacs +SYMBOL: emacsclient-path + +HOOK: default-emacsclient os ( -- path ) + +M: object default-emacsclient ( -- path ) "emacsclient" ; + : emacsclient ( file line -- ) [ - \ emacsclient get "emacsclient" or , + { [ \ emacsclient-path get ] [ default-emacsclient ] } 0|| , os windows? [ "--no-wait" , ] unless - "+" swap number>string append , + number>string "+" prepend , , ] { } make try-process ; @@ -14,4 +20,3 @@ IN: editors.emacs where first2 emacsclient ; [ emacsclient ] edit-hook set-global - diff --git a/basis/editors/emacs/windows/authors.txt b/basis/editors/emacs/windows/authors.txt new file mode 100755 index 0000000000..7c1b2f2279 --- /dev/null +++ b/basis/editors/emacs/windows/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/basis/editors/emacs/windows/windows.factor b/basis/editors/emacs/windows/windows.factor new file mode 100755 index 0000000000..d5c1e7811c --- /dev/null +++ b/basis/editors/emacs/windows/windows.factor @@ -0,0 +1,9 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: editors.emacs io.directories.search.windows kernel sequences +system ; +IN: editors.emacs.windows + +M: windows default-emacsclient + "Emacs" t [ "emacsclient.exe" tail? ] find-in-program-files + "emacsclient.exe" or ; From 114d9bb21c2d8079b9d3ffb1f2ff14f5f21cd148 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 12:25:55 -0600 Subject: [PATCH 07/24] run with --no-wait on windows so emacsclient doesn't block, use run-detached so that errors on emacsclient exit are ignored. emacs on windows is fully usable now --- basis/editors/emacs/emacs.factor | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/basis/editors/emacs/emacs.factor b/basis/editors/emacs/emacs.factor index fa78c1b429..0aeb7bb467 100644 --- a/basis/editors/emacs/emacs.factor +++ b/basis/editors/emacs/emacs.factor @@ -1,5 +1,6 @@ USING: definitions io.launcher kernel parser words sequences math -math.parser namespaces editors make system combinators.short-circuit ; +math.parser namespaces editors make system combinators.short-circuit +fry threads ; IN: editors.emacs SYMBOL: emacsclient-path @@ -11,10 +12,10 @@ M: object default-emacsclient ( -- path ) "emacsclient" ; : emacsclient ( file line -- ) [ { [ \ emacsclient-path get ] [ default-emacsclient ] } 0|| , - os windows? [ "--no-wait" , ] unless + "--no-wait" , number>string "+" prepend , , - ] { } make try-process ; + ] { } make run-detached drop ; : emacs ( word -- ) where first2 emacsclient ; From 1b9208490bb1d29cf67fb49f043a20cf9cdb92ae Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 12:32:07 -0600 Subject: [PATCH 08/24] keep the old emacs behavior on unix systems --- basis/editors/emacs/emacs.factor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/basis/editors/emacs/emacs.factor b/basis/editors/emacs/emacs.factor index 0aeb7bb467..fa717a70fa 100644 --- a/basis/editors/emacs/emacs.factor +++ b/basis/editors/emacs/emacs.factor @@ -15,7 +15,8 @@ M: object default-emacsclient ( -- path ) "emacsclient" ; "--no-wait" , number>string "+" prepend , , - ] { } make run-detached drop ; + ] { } make + os windows? [ run-detached drop ] [ try-process ] if ; : emacs ( word -- ) where first2 emacsclient ; From 624719c18fb1894f09c278b4417f5e88475eb64e Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 12:58:19 -0600 Subject: [PATCH 09/24] emacsclient.exe is a console app, so whenever it's run a console box pops up. run emacsclientw.exe instead if it exists --- basis/editors/emacs/windows/windows.factor | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/basis/editors/emacs/windows/windows.factor b/basis/editors/emacs/windows/windows.factor index d5c1e7811c..e18c39ed60 100755 --- a/basis/editors/emacs/windows/windows.factor +++ b/basis/editors/emacs/windows/windows.factor @@ -1,9 +1,12 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: editors.emacs io.directories.search.windows kernel sequences -system ; +system combinators.short-circuit ; IN: editors.emacs.windows M: windows default-emacsclient - "Emacs" t [ "emacsclient.exe" tail? ] find-in-program-files - "emacsclient.exe" or ; + { + [ "Emacs" t [ "emacsclientw.exe" tail? ] find-in-program-files ] + [ "Emacs" t [ "emacsclient.exe" tail? ] find-in-program-files ] + [ "emacsclient.exe" ] + } 0|| ; From 8b5a2f4a0e94d91557b7ac8fe0b91285178dcfda Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 14:52:38 -0600 Subject: [PATCH 10/24] fix sqlite triggers -- NEW.table-id not NEW.foreign-table-id --- basis/db/sqlite/sqlite-tests.factor | 20 ++++++++------------ basis/db/sqlite/sqlite.factor | 27 ++++++++++++++------------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/basis/db/sqlite/sqlite-tests.factor b/basis/db/sqlite/sqlite-tests.factor index fd730f07ae..b6e756a3dd 100644 --- a/basis/db/sqlite/sqlite-tests.factor +++ b/basis/db/sqlite/sqlite-tests.factor @@ -123,12 +123,8 @@ hi "HELLO" { ] with-db ] unit-test -[ ] [ - test.db [ - hi create-table - hi drop-table - ] with-db -] unit-test + +! Test SQLite triggers TUPLE: show id ; TUPLE: user username data ; @@ -144,12 +140,12 @@ show "SHOW" { } define-persistent watch "WATCH" { - { "user" "USER" TEXT +not-null+ - { +foreign-id+ user "USERNAME" } +user-assigned-id+ } - { "show" "SHOW" BIG-INTEGER +not-null+ - { +foreign-id+ show "ID" } +user-assigned-id+ } + { "user" "USER" TEXT +not-null+ +user-assigned-id+ + { +foreign-id+ user "USERNAME" } } + { "show" "SHOW" BIG-INTEGER +not-null+ +user-assigned-id+ + { +foreign-id+ show "ID" } } } define-persistent - + [ T{ user { username "littledan" } { data "foo" } } ] [ test.db [ user create-table @@ -160,7 +156,7 @@ watch "WATCH" { show new insert-tuple show new select-tuple "littledan" f user boa select-tuple - swap [ username>> ] [ id>> ] bi* + [ id>> ] [ username>> ] bi* watch boa insert-tuple watch new select-tuple user>> f user boa select-tuple diff --git a/basis/db/sqlite/sqlite.factor b/basis/db/sqlite/sqlite.factor index 62a1b4714f..c94de27894 100755 --- a/basis/db/sqlite/sqlite.factor +++ b/basis/db/sqlite/sqlite.factor @@ -204,7 +204,7 @@ M: sqlite-db-connection persistent-table ( -- assoc ) CREATE TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE INSERT ON ${table-name} FOR EACH ROW BEGIN - SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') + SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fki_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"') WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; END; "> interpolate @@ -216,8 +216,8 @@ M: sqlite-db-connection persistent-table ( -- assoc ) CREATE TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE INSERT ON ${table-name} FOR EACH ROW BEGIN - SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') - WHERE NEW.${foreign-table-id} IS NOT NULL + SELECT RAISE(ROLLBACK, 'insert on table "${table-name}" violates foreign key constraint "fki_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"') + WHERE NEW.${table-id} IS NOT NULL AND (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; END; "> interpolate @@ -236,8 +236,8 @@ M: sqlite-db-connection persistent-table ( -- assoc ) CREATE TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE UPDATE ON ${table-name} FOR EACH ROW BEGIN - SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') - WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; + SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fku_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"') + WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; END; "> interpolate ] with-string-writer ; @@ -248,8 +248,8 @@ M: sqlite-db-connection persistent-table ( -- assoc ) CREATE TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE UPDATE ON ${table-name} FOR EACH ROW BEGIN - SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') - WHERE NEW.${foreign-table-id} IS NOT NULL + SELECT RAISE(ROLLBACK, 'update on table "${table-name}" violates foreign key constraint "fku_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"') + WHERE NEW.${table-id} IS NOT NULL AND (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; END; "> interpolate @@ -268,8 +268,8 @@ M: sqlite-db-connection persistent-table ( -- assoc ) CREATE TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id BEFORE DELETE ON ${foreign-table-name} FOR EACH ROW BEGIN - SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table-name}" violates foreign key constraint "fk_${foreign-table-name}_id"') - WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = OLD.${foreign-table-id}) IS NOT NULL; + SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table-name}" violates foreign key constraint "fkd_${table-name}_$table-id}_${foreign-table-name}_${foreign-table-id}_id"') + WHERE (SELECT ${foreign-table-id} FROM ${foreign-table-name} WHERE ${foreign-table-id} = OLD.${foreign-table-id}) IS NOT NULL; END; "> interpolate ] with-string-writer ; @@ -336,15 +336,17 @@ M: sqlite-db-connection persistent-table ( -- assoc ) [ modifiers>> [ +foreign-id+ = ] deep-any? ] filter [ [ class>> db-table-name "db-table" set ] - [ column-name>> "table-id" set ] [ + [ "sql-spec" set ] + [ column-name>> "table-id" set ] + [ ] tri modifiers>> [ [ +foreign-id+ = ] deep-any? ] filter [ [ second db-table-name "foreign-table-name" set ] [ third "foreign-table-id" set ] bi _ execute ] each - ] tri + ] bi ] each ] call ; @@ -378,8 +380,7 @@ M: sqlite-db-connection create-sql-statement ( class -- statement ) M: sqlite-db-connection drop-sql-statement ( class -- statements ) [ - [ nip "drop table " 0% 0% ";" 0% ] - [ drop \ drop-sqlite-triggers db-triggers ] 2bi + nip "drop table " 0% 0% ";" 0% ] query-make ; M: sqlite-db-connection compound ( string seq -- new-string ) From 6eaa5aee2457b0eaad5020445f13b12299f8a4fc Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 17:29:11 -0600 Subject: [PATCH 11/24] fix compile error --- basis/db/sqlite/sqlite.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basis/db/sqlite/sqlite.factor b/basis/db/sqlite/sqlite.factor index c94de27894..19cfc5d0b7 100755 --- a/basis/db/sqlite/sqlite.factor +++ b/basis/db/sqlite/sqlite.factor @@ -348,7 +348,7 @@ M: sqlite-db-connection persistent-table ( -- assoc ) ] each ] bi ] each - ] call ; + ] call ; inline : sqlite-create-table ( sql-specs class-name -- ) [ From b54833c728fa0a0bc40e236fa7287b78e609364f Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 20:11:26 -0600 Subject: [PATCH 12/24] remove a bunch of trigger deletion code -- triggers get deleted when tables are dropped --- basis/db/sqlite/sqlite.factor | 74 ++++++++--------------------------- 1 file changed, 16 insertions(+), 58 deletions(-) diff --git a/basis/db/sqlite/sqlite.factor b/basis/db/sqlite/sqlite.factor index 19cfc5d0b7..a4adba3473 100755 --- a/basis/db/sqlite/sqlite.factor +++ b/basis/db/sqlite/sqlite.factor @@ -223,13 +223,6 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; -: drop-insert-trigger ( -- string ) - [ - <" - DROP TRIGGER fki_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; - "> interpolate - ] with-string-writer ; - : update-trigger ( -- string ) [ <" @@ -255,13 +248,6 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; -: drop-update-trigger ( -- string ) - [ - <" - DROP TRIGGER fku_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; - "> interpolate - ] with-string-writer ; - : delete-trigger-restrict ( -- string ) [ <" @@ -274,13 +260,6 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; -: drop-delete-trigger-restrict ( -- string ) - [ - <" - DROP TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; - "> interpolate - ] with-string-writer ; - : delete-trigger-cascade ( -- string ) [ <" @@ -292,13 +271,6 @@ M: sqlite-db-connection persistent-table ( -- assoc ) "> interpolate ] with-string-writer ; -: drop-delete-trigger-cascade ( -- string ) - [ - <" - DROP TRIGGER fkd_${table-name}_${table-id}_${foreign-table-name}_${foreign-table-id}_id; - "> interpolate - ] with-string-writer ; - : can-be-null? ( -- ? ) "sql-spec" get modifiers>> [ +not-null+ = ] any? not ; @@ -322,33 +294,22 @@ M: sqlite-db-connection persistent-table ( -- assoc ) delete-trigger-restrict sqlite-trigger, ] if ; -: drop-sqlite-triggers ( -- ) - drop-insert-trigger sqlite-trigger, - drop-update-trigger sqlite-trigger, - delete-cascade? [ - drop-delete-trigger-cascade sqlite-trigger, - ] [ - drop-delete-trigger-restrict sqlite-trigger, - ] if ; - -: db-triggers ( sql-specs word -- ) - '[ - [ modifiers>> [ +foreign-id+ = ] deep-any? ] filter +: create-db-triggers ( sql-specs -- ) + [ modifiers>> [ +foreign-id+ = ] deep-any? ] filter + [ + [ class>> db-table-name "db-table" set ] [ - [ class>> db-table-name "db-table" set ] + [ "sql-spec" set ] + [ column-name>> "table-id" set ] + [ ] tri + modifiers>> [ [ +foreign-id+ = ] deep-any? ] filter [ - [ "sql-spec" set ] - [ column-name>> "table-id" set ] - [ ] tri - modifiers>> [ [ +foreign-id+ = ] deep-any? ] filter - [ - [ second db-table-name "foreign-table-name" set ] - [ third "foreign-table-id" set ] bi - _ execute - ] each - ] bi - ] each - ] call ; inline + [ second db-table-name "foreign-table-name" set ] + [ third "foreign-table-id" set ] bi + create-sqlite-triggers + ] each + ] bi + ] each ; : sqlite-create-table ( sql-specs class-name -- ) [ @@ -373,15 +334,12 @@ M: sqlite-db-connection persistent-table ( -- assoc ) M: sqlite-db-connection create-sql-statement ( class -- statement ) [ - ! specs name [ sqlite-create-table ] - [ drop \ create-sqlite-triggers db-triggers ] 2bi + [ drop create-db-triggers ] 2bi ] query-make ; M: sqlite-db-connection drop-sql-statement ( class -- statements ) - [ - nip "drop table " 0% 0% ";" 0% - ] query-make ; + [ nip "drop table " 0% 0% ";" 0% ] query-make ; M: sqlite-db-connection compound ( string seq -- new-string ) over { From 70d931d0b2197da63474e3f817cc8cf27e0cf5b9 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Fri, 20 Feb 2009 20:14:54 -0600 Subject: [PATCH 13/24] Creating math.bits --- basis/math/bits/authors.txt | 1 + basis/math/bits/bits-docs.factor | 26 ++++++++++++++++++++++ basis/math/bits/bits-tests.factor | 16 +++++++++++++ basis/math/bits/bits.factor | 16 +++++++++++++ basis/math/bits/summary.txt | 1 + basis/math/bitwise/bitwise.factor | 4 ++-- basis/math/functions/functions-docs.factor | 8 ------- basis/math/functions/functions.factor | 18 ++++----------- extra/crypto/passwd-md5/passwd-md5.factor | 6 ++--- 9 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 basis/math/bits/authors.txt create mode 100644 basis/math/bits/bits-docs.factor create mode 100644 basis/math/bits/bits-tests.factor create mode 100644 basis/math/bits/bits.factor create mode 100644 basis/math/bits/summary.txt diff --git a/basis/math/bits/authors.txt b/basis/math/bits/authors.txt new file mode 100644 index 0000000000..f990dd0ed2 --- /dev/null +++ b/basis/math/bits/authors.txt @@ -0,0 +1 @@ +Daniel Ehrenberg diff --git a/basis/math/bits/bits-docs.factor b/basis/math/bits/bits-docs.factor new file mode 100644 index 0000000000..6ae83f7af0 --- /dev/null +++ b/basis/math/bits/bits-docs.factor @@ -0,0 +1,26 @@ +! Copyright (C) 2009 Daniel Ehrenberg +! See http://factorcode.org/license.txt for BSD license. +USING: help.syntax help.markup math ; +IN: math.bits + +ABOUT: "math.bits" + +ARTICLE: "math.bits" "Number bits virtual sequence" +{ $subsection bits } +{ $subsection } +{ $subsection make-bits } ; + +HELP: bits +{ $class-description "Virtual sequence class of bits of a number. The first bit is the least significant bit. This can be constructed with " { $link } " or " { $link make-bits } "." } ; + +HELP: +{ $values { "number" integer } { "length" integer } { "bits" bits } } +{ $description "Creates a virtual sequence of bits of a number in little endian order, with the given length." } ; + +HELP: make-bits +{ $values { "number" integer } { "bits" bits } } +{ $description "Creates a " { $link bits } " object out of the given number, using its log base 2 as the length. This implies that the last element, corresponding to the most significant bit, will be 1." } +{ $examples + { $example "USING: math.bits prettyprint arrays ;" "BIN: 1101 make-bits >array ." "{ t f t t }" } + { $example "USING: math.bits prettyprint arrays ;" "-3 make-bits >array ." "{ t f }" } +} ; diff --git a/basis/math/bits/bits-tests.factor b/basis/math/bits/bits-tests.factor new file mode 100644 index 0000000000..0503d27f33 --- /dev/null +++ b/basis/math/bits/bits-tests.factor @@ -0,0 +1,16 @@ +! Copyright (C) 2009 Daniel Ehrenberg +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test math.bits sequences arrays ; +IN: math.bits.tests + +[ t ] [ BIN: 111111 3 second ] unit-test +[ { t t t } ] [ BIN: 111111 3 >array ] unit-test +[ f ] [ BIN: 111101 3 second ] unit-test +[ { f f t } ] [ BIN: 111100 3 >array ] unit-test +[ 3 ] [ BIN: 111111 3 length ] unit-test +[ 6 ] [ BIN: 111111 make-bits length ] unit-test +[ 0 ] [ 0 make-bits length ] unit-test +[ 2 ] [ 3 make-bits length ] unit-test +[ 2 ] [ -3 make-bits length ] unit-test +[ 1 ] [ 1 make-bits length ] unit-test +[ 1 ] [ -1 make-bits length ] unit-test diff --git a/basis/math/bits/bits.factor b/basis/math/bits/bits.factor new file mode 100644 index 0000000000..8920955df3 --- /dev/null +++ b/basis/math/bits/bits.factor @@ -0,0 +1,16 @@ +! Copyright (C) 2009 Daniel Ehrenberg +! See http://factorcode.org/license.txt for BSD license. +USING: sequences kernel math accessors sequences.private ; +IN: math.bits + +TUPLE: bits { number read-only } { length read-only } ; +C: bits + +: make-bits ( number -- bits ) + dup zero? [ drop T{ bits f 0 0 } ] [ dup abs log2 1+ ] if ; inline + +M: bits length length>> ; + +M: bits nth-unsafe number>> swap bit? ; + +INSTANCE: bits immutable-sequence diff --git a/basis/math/bits/summary.txt b/basis/math/bits/summary.txt new file mode 100644 index 0000000000..265a7b8277 --- /dev/null +++ b/basis/math/bits/summary.txt @@ -0,0 +1 @@ +Virtual sequence for bits of an integer diff --git a/basis/math/bitwise/bitwise.factor b/basis/math/bitwise/bitwise.factor index 339703c0a6..4f639c02a7 100755 --- a/basis/math/bitwise/bitwise.factor +++ b/basis/math/bitwise/bitwise.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays kernel math math.functions sequences +USING: arrays kernel math sequences accessors math.bits sequences.private words namespaces macros hints combinators fry io.binary combinators.smart ; IN: math.bitwise @@ -65,7 +65,7 @@ DEFER: byte-bit-count \ byte-bit-count 256 [ - 0 swap [ [ 1+ ] when ] each-bit + 8 0 [ [ 1+ ] when ] reduce ] B{ } map-as '[ HEX: ff bitand _ nth-unsafe ] (( byte -- table )) define-declared diff --git a/basis/math/functions/functions-docs.factor b/basis/math/functions/functions-docs.factor index b463a48e49..33a5d96fc4 100644 --- a/basis/math/functions/functions-docs.factor +++ b/basis/math/functions/functions-docs.factor @@ -278,14 +278,6 @@ HELP: mod-inv { $example "USING: math prettyprint ;" "173 815 * 1119 mod ." "1" } } ; -HELP: each-bit -{ $values { "n" integer } { "quot" { $quotation "( ? -- )" } } } -{ $description "Applies the quotation to each bit of the integer, starting from the least significant bit, and stopping at the last bit from which point on all bits are either clear (if the integer is positive) or all bits are set (if the integer is negataive)." } -{ $examples - { $example "USING: math.functions make prettyprint ;" "[ BIN: 1101 [ , ] each-bit ] { } make ." "{ t f t t }" } - { $example "USING: math.functions make prettyprint ;" "[ -3 [ , ] each-bit ] { } make ." "{ t f }" } -} ; - HELP: ~ { $values { "x" real } { "y" real } { "epsilon" real } { "?" "a boolean" } } { $description "Tests if " { $snippet "x" } " and " { $snippet "y" } " are approximately equal to each other. There are three possible comparison tests, chosen based on the sign of " { $snippet "epsilon" } ":" diff --git a/basis/math/functions/functions.factor b/basis/math/functions/functions.factor index 85b4d711ac..7e2ac0884c 100644 --- a/basis/math/functions/functions.factor +++ b/basis/math/functions/functions.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: math kernel math.constants math.private +USING: math kernel math.constants math.private math.bits math.libm combinators math.order sequences ; IN: math.functions @@ -26,16 +26,6 @@ GENERIC: sqrt ( x -- y ) foldable M: real sqrt >float dup 0.0 < [ neg fsqrt 0.0 swap rect> ] [ fsqrt ] if ; -: each-bit ( n quot: ( ? -- ) -- ) - over [ 0 = ] [ -1 = ] bi or [ - 2drop - ] [ - 2dup { [ odd? ] [ call ] [ 2/ ] [ each-bit ] } spread - ] if ; inline recursive - -: map-bits ( n quot: ( ? -- obj ) -- seq ) - accumulator [ each-bit ] dip ; inline - : factor-2s ( n -- r s ) #! factor an integer into 2^r * s dup 0 = [ 1 ] [ @@ -47,7 +37,7 @@ M: real sqrt GENERIC# ^n 1 ( z w -- z^w ) : (^n) ( z w -- z^w ) - 1 swap [ [ dupd * ] when [ sq ] dip ] each-bit nip ; inline + make-bits 1 [ [ dupd * ] when [ sq ] dip ] reduce nip ; inline M: integer ^n [ factor-2s ] dip [ (^n) ] keep rot * shift ; @@ -94,9 +84,9 @@ PRIVATE> dup zero? [ drop 0./0. ] [ 0 < 1./0. 0 ? ] if ; inline : (^mod) ( n x y -- z ) - 1 swap [ + make-bits 1 [ [ dupd * pick mod ] when [ sq over mod ] dip - ] each-bit 2nip ; inline + ] reduce 2nip ; inline : (gcd) ( b a x y -- a d ) over zero? [ diff --git a/extra/crypto/passwd-md5/passwd-md5.factor b/extra/crypto/passwd-md5/passwd-md5.factor index e292981876..286a313fda 100644 --- a/extra/crypto/passwd-md5/passwd-md5.factor +++ b/extra/crypto/passwd-md5/passwd-md5.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: kernel base64 checksums.md5 sequences checksums -locals prettyprint math math.bitwise grouping io combinators +locals prettyprint math math.bits grouping io combinators fry make combinators.short-circuit math.functions splitting ; IN: crypto.passwd-md5 @@ -22,8 +22,8 @@ PRIVATE> password length [ 16 / ceiling swap concat ] keep head-slice append - password [ length ] [ first ] bi - '[ [ CHAR: \0 _ ? , ] each-bit ] "" make append + password [ length make-bits ] [ first ] bi + '[ CHAR: \0 _ ? ] "" map-as append md5 checksum-bytes ] | 1000 [ "" swap From 985597ba6858552d22294dc40e5794170fdaa3d6 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 20 Feb 2009 20:40:17 -0600 Subject: [PATCH 14/24] add error handling to sqlite, postgresql is next. switching computers.. --- basis/db/db.factor | 8 +++-- basis/db/errors/errors.factor | 12 ++++++- basis/db/errors/postgresql/authors.txt | 1 + .../errors/postgresql/postgresql-tests.factor | 4 +++ basis/db/errors/postgresql/postgresql.factor | 7 +++++ basis/db/errors/sqlite/authors.txt | 1 + basis/db/errors/sqlite/sqlite-tests.factor | 26 ++++++++++++++++ basis/db/errors/sqlite/sqlite.factor | 31 +++++++++++++++++++ basis/db/postgresql/postgresql-tests.factor | 22 ++++++------- 9 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 basis/db/errors/postgresql/authors.txt create mode 100644 basis/db/errors/postgresql/postgresql-tests.factor create mode 100644 basis/db/errors/postgresql/postgresql.factor create mode 100644 basis/db/errors/sqlite/authors.txt create mode 100644 basis/db/errors/sqlite/sqlite-tests.factor create mode 100644 basis/db/errors/sqlite/sqlite.factor diff --git a/basis/db/db.factor b/basis/db/db.factor index 0b18044f2b..eb06f0c894 100644 --- a/basis/db/db.factor +++ b/basis/db/db.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: arrays assocs classes continuations destructors kernel math namespaces sequences classes.tuple words strings -tools.walker accessors combinators fry ; +tools.walker accessors combinators fry db.errors ; IN: db > execute-statement* ; diff --git a/basis/db/errors/errors.factor b/basis/db/errors/errors.factor index da6301639f..1d48012cf9 100644 --- a/basis/db/errors/errors.factor +++ b/basis/db/errors/errors.factor @@ -1,10 +1,20 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel ; +USING: kernel db.private ; IN: db.errors +HOOK: parse-db-error db-connection ( error -- error' ) + ERROR: db-error ; ERROR: sql-error ; ERROR: table-exists ; ERROR: bad-schema ; + +ERROR: sql-syntax-error error ; + +ERROR: sql-table-exists table ; +C: sql-table-exists + +ERROR: sql-table-missing table ; +C: sql-table-missing diff --git a/basis/db/errors/postgresql/authors.txt b/basis/db/errors/postgresql/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/basis/db/errors/postgresql/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/basis/db/errors/postgresql/postgresql-tests.factor b/basis/db/errors/postgresql/postgresql-tests.factor new file mode 100644 index 0000000000..59b9bfe4a8 --- /dev/null +++ b/basis/db/errors/postgresql/postgresql-tests.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test db.errors.postgresql ; +IN: db.errors.postgresql.tests diff --git a/basis/db/errors/postgresql/postgresql.factor b/basis/db/errors/postgresql/postgresql.factor new file mode 100644 index 0000000000..9d88c96cb1 --- /dev/null +++ b/basis/db/errors/postgresql/postgresql.factor @@ -0,0 +1,7 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: ; +IN: db.errors.postgresql + +M: postgresql-db-connection parse-db-error + ; \ No newline at end of file diff --git a/basis/db/errors/sqlite/authors.txt b/basis/db/errors/sqlite/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/basis/db/errors/sqlite/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/basis/db/errors/sqlite/sqlite-tests.factor b/basis/db/errors/sqlite/sqlite-tests.factor new file mode 100644 index 0000000000..68ae55f8a8 --- /dev/null +++ b/basis/db/errors/sqlite/sqlite-tests.factor @@ -0,0 +1,26 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators.short-circuit db db.errors +db.errors.sqlite db.sqlite io.files.unique kernel namespaces +tools.test ; +IN: db.errors.sqlite.tests + +: sqlite-error-test-db-path ( -- path ) + "sqlite" "error-test" make-unique-file ; + +sqlite-error-test-db-path [ + + [ + "insert into foo (id) values('1');" sql-command + ] [ + { [ sql-table-missing? ] [ table>> "foo" = ] } 1&& + ] must-fail-with + + [ + "create table foo(id);" sql-command + "create table foo(id);" sql-command + ] [ + { [ sql-table-exists? ] [ table>> "foo" = ] } 1&& + ] must-fail-with + +] with-db \ No newline at end of file diff --git a/basis/db/errors/sqlite/sqlite.factor b/basis/db/errors/sqlite/sqlite.factor new file mode 100644 index 0000000000..770a12b2a1 --- /dev/null +++ b/basis/db/errors/sqlite/sqlite.factor @@ -0,0 +1,31 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators db.errors db.sqlite.private kernel +sequences peg.ebnf strings ; +IN: db.errors.sqlite + +ERROR: unparsed-sqlite-error error ; + +SINGLETONS: table-exists table-missing ; + +: sqlite-table-error ( table message -- error ) + { + { table-exists [ ] } + } case ; + +EBNF: parse-sqlite-sql-error + +TableMessage = " already exists" => [[ table-exists ]] + +SqliteError = + "table " (!(TableMessage).)+:table TableMessage:message + => [[ table >string message sqlite-table-error ]] + | "no such table: " .+:table + => [[ table >string ]] +;EBNF + +M: sqlite-db-connection parse-db-error + dup n>> { + { 1 [ string>> parse-sqlite-sql-error ] } + [ drop ] + } case ; \ No newline at end of file diff --git a/basis/db/postgresql/postgresql-tests.factor b/basis/db/postgresql/postgresql-tests.factor index cf6dc903f1..e2e2cbf7c0 100644 --- a/basis/db/postgresql/postgresql-tests.factor +++ b/basis/db/postgresql/postgresql-tests.factor @@ -3,7 +3,7 @@ prettyprint sequences namespaces tools.test db db.private db.tuples db.types unicode.case accessors system ; IN: db.postgresql.tests -: test-db ( -- postgresql-db ) +: postgresql-test-db ( -- postgresql-db ) "localhost" >>host "postgres" >>username @@ -11,10 +11,10 @@ IN: db.postgresql.tests "factor-test" >>database ; os windows? cpu x86.64? and [ - [ ] [ test-db [ ] with-db ] unit-test + [ ] [ postgresql-test-db [ ] with-db ] unit-test [ ] [ - test-db [ + postgresql-test-db [ [ "drop table person;" sql-command ] ignore-errors "create table person (name varchar(30), country varchar(30));" sql-command @@ -30,7 +30,7 @@ os windows? cpu x86.64? and [ { "Jane" "New Zealand" } } ] [ - test-db [ + postgresql-test-db [ "select * from person" sql-query ] with-db ] unit-test @@ -40,11 +40,11 @@ os windows? cpu x86.64? and [ { "John" "America" } { "Jane" "New Zealand" } } - ] [ test-db [ "select * from person" sql-query ] with-db ] unit-test + ] [ postgresql-test-db [ "select * from person" sql-query ] with-db ] unit-test [ ] [ - test-db [ + postgresql-test-db [ "insert into person(name, country) values('Jimmy', 'Canada')" sql-command ] with-db @@ -56,10 +56,10 @@ os windows? cpu x86.64? and [ { "Jane" "New Zealand" } { "Jimmy" "Canada" } } - ] [ test-db [ "select * from person" sql-query ] with-db ] unit-test + ] [ postgresql-test-db [ "select * from person" sql-query ] with-db ] unit-test [ - test-db [ + postgresql-test-db [ [ "insert into person(name, country) values('Jose', 'Mexico')" sql-command "insert into person(name, country) values('Jose', 'Mexico')" sql-command @@ -69,14 +69,14 @@ os windows? cpu x86.64? and [ ] must-fail [ 3 ] [ - test-db [ + postgresql-test-db [ "select * from person" sql-query length ] with-db ] unit-test [ ] [ - test-db [ + postgresql-test-db [ [ "insert into person(name, country) values('Jose', 'Mexico')" sql-command @@ -87,7 +87,7 @@ os windows? cpu x86.64? and [ ] unit-test [ 5 ] [ - test-db [ + postgresql-test-db [ "select * from person" sql-query length ] with-db ] unit-test From a1f3e5695b9dc3dd1feec2bd6c1498ca006a4283 Mon Sep 17 00:00:00 2001 From: sheeple Date: Fri, 20 Feb 2009 22:59:01 -0600 Subject: [PATCH 15/24] fix circularity in db --- basis/db/db.factor | 5 +++-- basis/db/errors/errors.factor | 4 +--- basis/db/errors/postgresql/postgresql.factor | 3 --- basis/db/errors/sqlite/sqlite.factor | 10 ++-------- basis/db/postgresql/postgresql.factor | 7 +++++-- basis/db/sqlite/sqlite.factor | 9 ++++++++- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/basis/db/db.factor b/basis/db/db.factor index eb06f0c894..96b72b8865 100644 --- a/basis/db/db.factor +++ b/basis/db/db.factor @@ -5,14 +5,14 @@ namespaces sequences classes.tuple words strings tools.walker accessors combinators fry db.errors ; IN: db ->insert-statements @@ -23,6 +23,7 @@ PRIVATE> GENERIC: db-open ( db -- db-connection ) HOOK: db-close db-connection ( handle -- ) +HOOK: parse-db-error db-connection ( error -- error' ) : dispose-statements ( assoc -- ) values dispose-each ; diff --git a/basis/db/errors/errors.factor b/basis/db/errors/errors.factor index 1d48012cf9..9420dbbfc4 100644 --- a/basis/db/errors/errors.factor +++ b/basis/db/errors/errors.factor @@ -1,10 +1,8 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel db.private ; +USING: kernel ; IN: db.errors -HOOK: parse-db-error db-connection ( error -- error' ) - ERROR: db-error ; ERROR: sql-error ; diff --git a/basis/db/errors/postgresql/postgresql.factor b/basis/db/errors/postgresql/postgresql.factor index 9d88c96cb1..e45ff092e8 100644 --- a/basis/db/errors/postgresql/postgresql.factor +++ b/basis/db/errors/postgresql/postgresql.factor @@ -2,6 +2,3 @@ ! See http://factorcode.org/license.txt for BSD license. USING: ; IN: db.errors.postgresql - -M: postgresql-db-connection parse-db-error - ; \ No newline at end of file diff --git a/basis/db/errors/sqlite/sqlite.factor b/basis/db/errors/sqlite/sqlite.factor index 770a12b2a1..c247a36257 100644 --- a/basis/db/errors/sqlite/sqlite.factor +++ b/basis/db/errors/sqlite/sqlite.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors combinators db.errors db.sqlite.private kernel -sequences peg.ebnf strings ; +USING: accessors combinators db kernel sequences peg.ebnf +strings db.errors ; IN: db.errors.sqlite ERROR: unparsed-sqlite-error error ; @@ -23,9 +23,3 @@ SqliteError = | "no such table: " .+:table => [[ table >string ]] ;EBNF - -M: sqlite-db-connection parse-db-error - dup n>> { - { 1 [ string>> parse-sqlite-sql-error ] } - [ drop ] - } case ; \ No newline at end of file diff --git a/basis/db/postgresql/postgresql.factor b/basis/db/postgresql/postgresql.factor index 1f55dcf769..1c39166071 100644 --- a/basis/db/postgresql/postgresql.factor +++ b/basis/db/postgresql/postgresql.factor @@ -5,8 +5,8 @@ kernel math math.parser namespaces make prettyprint quotations sequences debugger db db.postgresql.lib db.postgresql.ffi db.tuples db.types tools.annotations math.ranges combinators classes locals words tools.walker db.private -nmake accessors random db.queries destructors db.tuples.private ; -USE: tools.walker +nmake accessors random db.queries destructors db.tuples.private +db.postgresql ; IN: db.postgresql TUPLE: postgresql-db host port pgopts pgtty database username password ; @@ -280,3 +280,6 @@ M: postgresql-db-connection compound ( string object -- string' ) { "references" [ >reference-string ] } [ drop no-compound-found ] } case ; + +M: postgresql-db-connection parse-db-error + ; diff --git a/basis/db/sqlite/sqlite.factor b/basis/db/sqlite/sqlite.factor index a4adba3473..5b658f36c9 100755 --- a/basis/db/sqlite/sqlite.factor +++ b/basis/db/sqlite/sqlite.factor @@ -6,7 +6,8 @@ sequences strings classes.tuple alien.c-types continuations db.sqlite.lib db.sqlite.ffi db.tuples words db.types combinators math.intervals io nmake accessors vectors math.ranges random math.bitwise db.queries destructors db.tuples.private interpolate -io.streams.string multiline make db.private sequences.deep ; +io.streams.string multiline make db.private sequences.deep +db.errors.sqlite ; IN: db.sqlite TUPLE: sqlite-db path ; @@ -347,3 +348,9 @@ M: sqlite-db-connection compound ( string seq -- new-string ) { "references" [ >reference-string ] } [ 2drop ] } case ; + +M: sqlite-db-connection parse-db-error + dup n>> { + { 1 [ string>> parse-sqlite-sql-error ] } + [ drop ] + } case ; From d6d89e0a40418f7e80d2b51cd8b1bb7b7b854524 Mon Sep 17 00:00:00 2001 From: sheeple Date: Sat, 21 Feb 2009 21:22:51 -0600 Subject: [PATCH 16/24] add parsing for postgresql errors and some unit tests --- basis/db/errors/errors.factor | 22 ++++--- .../errors/postgresql/postgresql-tests.factor | 30 +++++++++- basis/db/errors/postgresql/postgresql.factor | 58 ++++++++++++++++++- basis/db/postgresql/postgresql-tests.factor | 9 +-- basis/db/postgresql/postgresql.factor | 12 +++- basis/db/sqlite/lib/lib.factor | 7 ++- basis/db/tester/tester.factor | 38 ++++++++++-- basis/db/tuples/tuples-tests.factor | 34 +---------- 8 files changed, 153 insertions(+), 57 deletions(-) diff --git a/basis/db/errors/errors.factor b/basis/db/errors/errors.factor index 9420dbbfc4..00aa568154 100644 --- a/basis/db/errors/errors.factor +++ b/basis/db/errors/errors.factor @@ -1,18 +1,24 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel ; +USING: accessors kernel ; IN: db.errors ERROR: db-error ; -ERROR: sql-error ; +ERROR: sql-error location ; -ERROR: table-exists ; ERROR: bad-schema ; -ERROR: sql-syntax-error error ; +ERROR: sql-table-exists < sql-error table ; +: ( table -- error ) + \ sql-table-exists new + swap >>table ; -ERROR: sql-table-exists table ; -C: sql-table-exists +ERROR: sql-table-missing < sql-error table ; +: ( table -- error ) + \ sql-table-missing new + swap >>table ; -ERROR: sql-table-missing table ; -C: sql-table-missing +ERROR: sql-syntax-error < sql-error message ; +: ( message -- error ) + \ sql-syntax-error new + swap >>message ; diff --git a/basis/db/errors/postgresql/postgresql-tests.factor b/basis/db/errors/postgresql/postgresql-tests.factor index 59b9bfe4a8..770b325086 100644 --- a/basis/db/errors/postgresql/postgresql-tests.factor +++ b/basis/db/errors/postgresql/postgresql-tests.factor @@ -1,4 +1,32 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: tools.test db.errors.postgresql ; +USING: accessors combinators.short-circuit db db.errors +db.errors.postgresql db.postgresql io.files.unique kernel namespaces +tools.test db.tester ; IN: db.errors.postgresql.tests + +postgresql-test-db [ + + [ "drop table foo;" sql-command ] ignore-errors + [ "drop table ship;" sql-command ] ignore-errors + + [ + "insert into foo (id) values('1');" sql-command + ] [ + { [ sql-table-missing? ] [ table>> "foo" = ] } 1&& + ] must-fail-with + + [ + "create table ship(id integer);" sql-command + "create table ship(id integer);" sql-command + ] [ + { [ sql-table-exists? ] [ table>> "ship" = ] } 1&& + ] must-fail-with + + [ + "create table foo(id) lol;" sql-command + ] [ + sql-syntax-error? + ] must-fail-with + +] with-db diff --git a/basis/db/errors/postgresql/postgresql.factor b/basis/db/errors/postgresql/postgresql.factor index e45ff092e8..fac10d092f 100644 --- a/basis/db/errors/postgresql/postgresql.factor +++ b/basis/db/errors/postgresql/postgresql.factor @@ -1,4 +1,60 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: ; +USING: kernel db.errors peg.ebnf strings sequences math +combinators.short-circuit accessors math.parser ; IN: db.errors.postgresql + +! ERROR: relation "foo" does not exist + +: quote? ( ch -- ? ) "'\"" member? ; + +: quoted? ( str -- ? ) + { + [ length 1 > ] + [ first quote? ] + [ [ first ] [ peek ] bi = ] + } 1&& ; + +: unquote ( str -- newstr ) + dup quoted? [ but-last-slice rest-slice >string ] when ; + + +EBNF: parse-postgresql-sql-error + +Error = "ERROR:" [ ]+ + +TableError = + Error "relation " (!(" already exists").)+:table " already exists" + => [[ table >string unquote ]] + | Error "relation " (!(" does not exist").)+:table " does not exist" + => [[ table >string unquote ]] + +SyntaxError = + Error "syntax error at end of input":error + => [[ error >string ]] + | Error "syntax error at or near " .+:syntaxerror + => [[ syntaxerror >string unquote ]] + +PostgresqlSqlError = (TableError | SyntaxError) + +;EBNF + + +ERROR: parse-postgresql-location column line text ; +C: parse-postgresql-location + +EBNF: parse-postgresql-line-error + +Line = "LINE " [0-9]+:line ": " .+:sql + => [[ f line >string string>number sql >string ]] + +;EBNF + +:: set-caret-position ( error caret-line -- error ) + caret-line length + error line>> number>string length "LINE : " length + + - [ error ] dip >>column ; + +: postgresql-location ( line column -- obj ) + [ parse-postgresql-line-error ] dip + set-caret-position ; diff --git a/basis/db/postgresql/postgresql-tests.factor b/basis/db/postgresql/postgresql-tests.factor index e2e2cbf7c0..266337b8c8 100644 --- a/basis/db/postgresql/postgresql-tests.factor +++ b/basis/db/postgresql/postgresql-tests.factor @@ -1,15 +1,8 @@ USING: kernel db.postgresql alien continuations io classes prettyprint sequences namespaces tools.test db db.private -db.tuples db.types unicode.case accessors system ; +db.tuples db.types unicode.case accessors system db.tester ; IN: db.postgresql.tests -: postgresql-test-db ( -- postgresql-db ) - - "localhost" >>host - "postgres" >>username - "thepasswordistrust" >>password - "factor-test" >>database ; - os windows? cpu x86.64? and [ [ ] [ postgresql-test-db [ ] with-db ] unit-test diff --git a/basis/db/postgresql/postgresql.factor b/basis/db/postgresql/postgresql.factor index 1c39166071..9e51f41ff1 100644 --- a/basis/db/postgresql/postgresql.factor +++ b/basis/db/postgresql/postgresql.factor @@ -6,7 +6,7 @@ sequences debugger db db.postgresql.lib db.postgresql.ffi db.tuples db.types tools.annotations math.ranges combinators classes locals words tools.walker db.private nmake accessors random db.queries destructors db.tuples.private -db.postgresql ; +db.postgresql db.errors.postgresql splitting ; IN: db.postgresql TUPLE: postgresql-db host port pgopts pgtty database username password ; @@ -282,4 +282,12 @@ M: postgresql-db-connection compound ( string object -- string' ) } case ; M: postgresql-db-connection parse-db-error - ; + "\n" split dup length { + { 1 [ first parse-postgresql-sql-error ] } + { 3 [ + first3 + [ parse-postgresql-sql-error ] 2dip + postgresql-location >>location + ] } + } case ; + diff --git a/basis/db/sqlite/lib/lib.factor b/basis/db/sqlite/lib/lib.factor index 60141bc830..3565b09856 100644 --- a/basis/db/sqlite/lib/lib.factor +++ b/basis/db/sqlite/lib/lib.factor @@ -11,12 +11,17 @@ IN: db.sqlite.lib ERROR: sqlite-error < db-error n string ; ERROR: sqlite-sql-error < sql-error n string ; +: ( n string -- error ) + \ sqlite-sql-error new + swap >>string + swap >>n ; + : throw-sqlite-error ( n -- * ) dup sqlite-error-messages nth sqlite-error ; : sqlite-statement-error ( -- * ) SQLITE_ERROR - db-connection get handle>> sqlite3_errmsg sqlite-sql-error ; + db-connection get handle>> sqlite3_errmsg throw ; : sqlite-check-result ( n -- ) { diff --git a/basis/db/tester/tester.factor b/basis/db/tester/tester.factor index 490f6bbef5..fcc5abf1cf 100644 --- a/basis/db/tester/tester.factor +++ b/basis/db/tester/tester.factor @@ -2,9 +2,42 @@ ! See http://factorcode.org/license.txt for BSD license. USING: concurrency.combinators db.pools db.sqlite db.tuples db.types kernel math random threads tools.test db sequences -io prettyprint ; +io prettyprint db.postgresql db.sqlite accessors io.files.temp +namespaces fry system ; IN: db.tester +: postgresql-test-db ( -- postgresql-db ) + + "localhost" >>host + "postgres" >>username + "thepasswordistrust" >>password + "factor-test" >>database ; + +: sqlite-test-db ( -- sqlite-db ) + "tuples-test.db" temp-file ; + + +! These words leak resources, but are useful for interactivel testing +: set-sqlite-db ( -- ) + sqlite-db db-open db-connection set ; + +: set-postgresql-db ( -- ) + postgresql-db db-open db-connection set ; + + +: test-sqlite ( quot -- ) + '[ + [ ] [ sqlite-test-db _ with-db ] unit-test + ] call ; inline + +: test-postgresql ( quot -- ) + '[ + os windows? cpu x86.64? and [ + [ ] [ postgresql-test-db _ with-db ] unit-test + ] unless + ] call ; inline + + TUPLE: test-1 id a b c ; test-1 "TEST1" { @@ -23,9 +56,6 @@ test-2 "TEST2" { { "z" "Z" { VARCHAR 256 } +not-null+ } } define-persistent -: sqlite-test-db ( -- db ) "test.db" ; -: test-db ( -- db ) "test.db" ; - : db-tester ( test-db -- ) [ [ diff --git a/basis/db/tuples/tuples-tests.factor b/basis/db/tuples/tuples-tests.factor index 246946c715..af77ce6ac1 100644 --- a/basis/db/tuples/tuples-tests.factor +++ b/basis/db/tuples/tuples-tests.factor @@ -4,40 +4,10 @@ USING: io.files io.files.temp kernel tools.test db db.tuples classes db.types continuations namespaces math math.ranges prettyprint calendar sequences db.sqlite math.intervals db.postgresql accessors random math.bitwise system -math.ranges strings urls fry db.tuples.private db.private ; +math.ranges strings urls fry db.tuples.private db.private +db.tester ; IN: db.tuples.tests -: sqlite-db ( -- sqlite-db ) - "tuples-test.db" temp-file ; - -: test-sqlite ( quot -- ) - '[ - [ ] [ - "tuples-test.db" temp-file _ with-db - ] unit-test - ] call ; inline - -: postgresql-db ( -- postgresql-db ) - - "localhost" >>host - "postgres" >>username - "thepasswordistrust" >>password - "factor-test" >>database ; - -: test-postgresql ( quot -- ) - '[ - os windows? cpu x86.64? and [ - [ ] [ postgresql-db _ with-db ] unit-test - ] unless - ] call ; inline - -! These words leak resources, but are useful for interactivel testing -: sqlite-test-db ( -- ) - sqlite-db db-open db-connection set ; - -: postgresql-test-db ( -- ) - postgresql-db db-open db-connection set ; - TUPLE: person the-id the-name the-number the-real ts date time blob factor-blob url ; From 02cec3a9f41e7b89f027eea21fd05c09834a8872 Mon Sep 17 00:00:00 2001 From: sheeple Date: Sat, 21 Feb 2009 21:59:23 -0600 Subject: [PATCH 17/24] add more postgres error handling, remove usage of ignore-errors in db.tuples --- basis/db/errors/errors.factor | 32 ++++++++++++++++++- .../errors/postgresql/postgresql-tests.factor | 2 +- basis/db/errors/postgresql/postgresql.factor | 16 +++++++--- basis/db/tuples/tuples.factor | 10 +++--- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/basis/db/errors/errors.factor b/basis/db/errors/errors.factor index 00aa568154..5239086f93 100644 --- a/basis/db/errors/errors.factor +++ b/basis/db/errors/errors.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel ; +USING: accessors kernel continuations fry words ; IN: db.errors ERROR: db-error ; @@ -8,6 +8,11 @@ ERROR: sql-error location ; ERROR: bad-schema ; +ERROR: sql-unknown-error < sql-error message ; +: ( message -- error ) + \ sql-unknown-error new + swap >>message ; + ERROR: sql-table-exists < sql-error table ; : ( table -- error ) \ sql-table-exists new @@ -22,3 +27,28 @@ ERROR: sql-syntax-error < sql-error message ; : ( message -- error ) \ sql-syntax-error new swap >>message ; + +ERROR: sql-function-exists < sql-error message ; +: ( message -- error ) + \ sql-function-exists new + swap >>message ; + +ERROR: sql-function-missing < sql-error message ; +: ( message -- error ) + \ sql-function-missing new + swap >>message ; + +: ignore-error ( quot word -- ) + '[ dup _ execute [ drop ] [ rethrow ] if ] recover ; inline + +: ignore-table-exists ( quot -- ) + \ sql-table-exists? ignore-error ; inline + +: ignore-table-missing ( quot -- ) + \ sql-table-missing? ignore-error ; inline + +: ignore-function-exists ( quot -- ) + \ sql-function-exists? ignore-error ; inline + +: ignore-function-missing ( quot -- ) + \ sql-function-missing? ignore-error ; inline diff --git a/basis/db/errors/postgresql/postgresql-tests.factor b/basis/db/errors/postgresql/postgresql-tests.factor index 770b325086..9dbebe0712 100644 --- a/basis/db/errors/postgresql/postgresql-tests.factor +++ b/basis/db/errors/postgresql/postgresql-tests.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors combinators.short-circuit db db.errors db.errors.postgresql db.postgresql io.files.unique kernel namespaces -tools.test db.tester ; +tools.test db.tester continuations ; IN: db.errors.postgresql.tests postgresql-test-db [ diff --git a/basis/db/errors/postgresql/postgresql.factor b/basis/db/errors/postgresql/postgresql.factor index fac10d092f..2b79859050 100644 --- a/basis/db/errors/postgresql/postgresql.factor +++ b/basis/db/errors/postgresql/postgresql.factor @@ -4,8 +4,6 @@ USING: kernel db.errors peg.ebnf strings sequences math combinators.short-circuit accessors math.parser ; IN: db.errors.postgresql -! ERROR: relation "foo" does not exist - : quote? ( ch -- ? ) "'\"" member? ; : quoted? ( str -- ? ) @@ -24,18 +22,26 @@ EBNF: parse-postgresql-sql-error Error = "ERROR:" [ ]+ TableError = - Error "relation " (!(" already exists").)+:table " already exists" + Error ("relation "|"table ")(!(" already exists").)+:table " already exists" => [[ table >string unquote ]] - | Error "relation " (!(" does not exist").)+:table " does not exist" + | Error ("relation "|"table ")(!(" does not exist").)+:table " does not exist" => [[ table >string unquote ]] +FunctionError = + Error "function" (!(" already exists").)+:table " already exists" + => [[ table >string ]] + | Error "function" (!(" does not exist").)+:table " does not exist" + => [[ table >string ]] + SyntaxError = Error "syntax error at end of input":error => [[ error >string ]] | Error "syntax error at or near " .+:syntaxerror => [[ syntaxerror >string unquote ]] -PostgresqlSqlError = (TableError | SyntaxError) +UnknownError = .* => [[ >string ]] + +PostgresqlSqlError = (TableError | FunctionError | SyntaxError | UnknownError) ;EBNF diff --git a/basis/db/tuples/tuples.factor b/basis/db/tuples/tuples.factor index 9edd5bac69..19d4be5fc8 100644 --- a/basis/db/tuples/tuples.factor +++ b/basis/db/tuples/tuples.factor @@ -4,7 +4,7 @@ USING: arrays assocs classes db kernel namespaces classes.tuple words sequences slots math accessors math.parser io prettyprint db.types continuations destructors mirrors sets db.types db.private fry -combinators.short-circuit ; +combinators.short-circuit db.errors ; IN: db.tuples HOOK: create-sql-statement db-connection ( class -- object ) @@ -118,13 +118,15 @@ ERROR: no-defined-persistent object ; ensure-defined-persistent [ '[ - _ drop-sql-statement [ execute-statement ] with-disposals - ] ignore-errors + [ + _ drop-sql-statement [ execute-statement ] with-disposals + ] ignore-table-missing + ] ignore-function-missing ] [ create-table ] bi ; : ensure-table ( class -- ) ensure-defined-persistent - '[ _ create-table ] ignore-errors ; + '[ [ _ create-table ] ignore-table-exists ] ignore-function-exists ; : ensure-tables ( classes -- ) [ ensure-table ] each ; From 785d7ac9afb64283676e015b2e74bf4b96978249 Mon Sep 17 00:00:00 2001 From: sheeple Date: Sat, 21 Feb 2009 22:18:02 -0600 Subject: [PATCH 18/24] clean up scaffold tool a bit, don't create a -tests.factor file when scaffolding a new vocab --- basis/tools/scaffold/scaffold.factor | 50 +++++++++++++++------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor index acea984700..d1623b223a 100755 --- a/basis/tools/scaffold/scaffold.factor +++ b/basis/tools/scaffold/scaffold.factor @@ -5,7 +5,7 @@ io.encodings.utf8 hashtables kernel namespaces sequences vocabs.loader io combinators calendar accessors math.parser io.streams.string ui.tools.operations quotations strings arrays prettyprint words vocabs sorting sets classes math alien urls -splitting ascii ; +splitting ascii combinators.short-circuit ; IN: tools.scaffold SYMBOL: developer-name @@ -18,18 +18,19 @@ ERROR: no-vocab vocab ; . ; +: not-scaffolding ( path -- path ) + "Not creating scaffolding for " write dup . ; -: scaffolding ( path -- ) - "Creating scaffolding for " write . ; +: scaffolding ( path -- path ) + "Creating scaffolding for " write dup . ; : (scaffold-path) ( path string -- path ) - dupd [ file-name ] dip append append-path ; + [ dup file-name ] dip append append-path ; : scaffold-path ( path string -- path ? ) (scaffold-path) - dup exists? [ dup not-scaffolding f ] [ dup scaffolding t ] if ; + dup exists? [ not-scaffolding f ] [ scaffolding t ] if ; : scaffold-copyright ( -- ) "! Copyright (C) " write now year>> number>string write @@ -85,14 +86,14 @@ ERROR: no-vocab vocab ; : scaffold-authors ( path -- ) "authors.txt" append-path dup exists? [ - not-scaffolding + not-scaffolding drop ] [ - dup scaffolding + scaffolding developer-name get swap utf8 set-file-contents ] if ; : lookup-type ( string -- object/string ? ) - "new" ?head drop [ [ CHAR: ' = ] [ digit? ] bi or ] trim-tail + "new" ?head drop [ { [ CHAR: ' = ] [ digit? ] } 1|| ] trim-tail H{ { "object" object } { "obj" object } { "quot" quotation } @@ -134,6 +135,9 @@ ERROR: no-vocab vocab ; " }" write ] each ; +: 4bl ( -- ) + " " write ; inline + : $values. ( word -- ) "declared-effect" word-prop [ [ in>> ] [ out>> ] bi @@ -141,8 +145,8 @@ ERROR: no-vocab vocab ; 2drop ] [ "{ $values" print - [ " " write ($values.) ] - [ [ nl " " write ($values.) ] unless-empty ] bi* + [ 4bl ($values.) ] + [ [ nl 4bl ($values.) ] unless-empty ] bi* nl "}" print ] if ] when* ; @@ -159,7 +163,7 @@ ERROR: no-vocab vocab ; : interesting-words ( vocab -- array ) words - [ [ "help" word-prop ] [ predicate? ] bi or not ] filter + [ { [ "help" word-prop ] [ predicate? ] } 1|| not ] filter natural-sort ; : interesting-words. ( vocab -- ) @@ -237,7 +241,6 @@ PRIVATE> { [ drop scaffold-directory ] [ scaffold-main ] - [ scaffold-tests ] [ drop scaffold-authors ] [ nip require ] } 2cleave ; @@ -250,7 +253,7 @@ SYMBOL: examples-flag " \"\"" " \"\"" "}" - } [ examples-flag get [ " " write ] when print ] each ; + } [ examples-flag get [ 4bl ] when print ] each ; : examples ( n -- ) t \ examples-flag [ @@ -260,10 +263,11 @@ SYMBOL: examples-flag ] with-variable ; : scaffold-rc ( path -- ) + [ home ] dip append-path [ touch-file ] [ "Click to edit: " write . ] bi ; -: scaffold-factor-boot-rc ( -- ) - home ".factor-boot-rc" append-path scaffold-rc ; +: scaffold-factor-boot-rc ( -- ) ".factor-boot-rc" scaffold-rc ; -: scaffold-factor-rc ( -- ) - home ".factor-rc" append-path scaffold-rc ; +: scaffold-factor-rc ( -- ) ".factor-rc" scaffold-rc ; + +: scaffold-emacs ( -- ) ".emacs" scaffold-rc ; From 405b3dc1ad97525fd5a31aae405284bfbe2d4fea Mon Sep 17 00:00:00 2001 From: sheeple Date: Sun, 22 Feb 2009 00:19:10 -0600 Subject: [PATCH 19/24] refactor tools.scaffold -- scaffold-help -> scaffold-docs, it takes a vocab name now --- basis/tools/scaffold/scaffold.factor | 146 +++++++++++++++------------ 1 file changed, 80 insertions(+), 66 deletions(-) diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor index d1623b223a..eb7017f57f 100755 --- a/basis/tools/scaffold/scaffold.factor +++ b/basis/tools/scaffold/scaffold.factor @@ -32,10 +32,37 @@ ERROR: no-vocab vocab ; : check-root ( string -- string ) dup vocab-root? [ not-a-vocab-root ] unless ; +: check-vocab ( vocab -- vocab ) + dup find-vocab-root [ no-vocab ] unless ; + +: check-vocab-root/vocab ( vocab-root string -- vocab-root string ) + [ check-root ] [ check-vocab-name ] bi* ; + +: replace-vocab-separators ( vocab -- path ) + path-separator first CHAR: . associate substitute ; inline + +: vocab-root/vocab>path ( vocab-root vocab -- path ) + check-vocab-root/vocab + [ ] [ replace-vocab-separators ] bi* append-path ; + +: vocab>path ( vocab -- path ) + check-vocab + [ find-vocab-root ] keep vocab-root/vocab>path ; + +: vocab-root/vocab/file>path ( vocab-root vocab file -- path ) + [ vocab-root/vocab>path ] dip append-path ; + +: vocab-root/vocab/suffix>path ( vocab-root vocab suffix -- path ) + [ vocab-root/vocab>path dup file-name append-path ] dip append ; + +: vocab/suffix>path ( vocab suffix -- path ) + [ vocab>path dup file-name append-path ] dip append ; + : directory-exists ( path -- ) "Not creating a directory, it already exists: " write print ; -: scaffold-directory ( path -- ) +: scaffold-directory ( vocab-root vocab -- ) + vocab-root/vocab>path dup exists? [ directory-exists ] [ make-directories ] if ; : not-scaffolding ( path -- path ) @@ -44,11 +71,7 @@ ERROR: no-vocab vocab ; : scaffolding ( path -- path ) "Creating scaffolding for " write dup . ; -: (scaffold-path) ( path string -- path ) - [ dup file-name ] dip append append-path ; - -: scaffold-path ( path string -- path ? ) - (scaffold-path) +: scaffolding? ( path -- path ? ) dup exists? [ not-scaffolding f ] [ scaffolding t ] if ; : scaffold-copyright ( -- ) @@ -63,33 +86,21 @@ ERROR: no-vocab vocab ; "IN: " write print ] with-string-writer ; -: set-scaffold-main-file ( path vocab -- ) - main-file-string swap utf8 set-file-contents ; +: set-scaffold-main-file ( vocab path -- ) + [ main-file-string ] dip utf8 set-file-contents ; -: scaffold-main ( path vocab -- ) - [ ".factor" scaffold-path ] dip - swap [ set-scaffold-main-file ] [ 2drop ] if ; - -: tests-file-string ( vocab -- string ) - [ - scaffold-copyright - "USING: tools.test " write dup write " ;" print - "IN: " write write ".tests" print - ] with-string-writer ; - -: set-scaffold-tests-file ( path vocab -- ) - tests-file-string swap utf8 set-file-contents ; - -: scaffold-tests ( path vocab -- ) - [ "-tests.factor" scaffold-path ] dip - swap [ set-scaffold-tests-file ] [ 2drop ] if ; - -: scaffold-authors ( path -- ) - "authors.txt" append-path dup exists? [ - not-scaffolding drop +: scaffold-main ( vocab-root vocab -- ) + tuck ".factor" vocab-root/vocab/suffix>path scaffolding? [ + set-scaffold-main-file ] [ - scaffolding - developer-name get swap utf8 set-file-contents + 2drop + ] if ; + +: scaffold-authors ( vocab-root vocab -- ) + "authors.txt" vocab-root/vocab/file>path scaffolding? [ + [ developer-name get ] dip utf8 set-file-contents + ] [ + drop ] if ; : lookup-type ( string -- object/string ? ) @@ -155,11 +166,11 @@ ERROR: no-vocab vocab ; drop "{ $description \"\" } ;" print ; -: help-header. ( word -- ) +: docs-header. ( word -- ) "HELP: " write name>> print ; -: (help.) ( word -- ) - [ help-header. ] [ $values. ] [ $description. ] tri ; +: (docs.) ( word -- ) + [ docs-header. ] [ $values. ] [ $description. ] tri ; : interesting-words ( vocab -- array ) words @@ -167,9 +178,9 @@ ERROR: no-vocab vocab ; natural-sort ; : interesting-words. ( vocab -- ) - interesting-words [ (help.) nl ] each ; + interesting-words [ (docs.) nl ] each ; -: help-file-string ( vocab -- str2 ) +: docs-file-string ( vocab -- str2 ) [ { [ "IN: " write print nl ] @@ -190,61 +201,64 @@ ERROR: no-vocab vocab ; [ bl write ] each " ;" print ; -: set-scaffold-help-file ( path vocab -- ) - swap utf8 [ +: set-scaffold-docs-file ( vocab path -- ) + utf8 [ scaffold-copyright - [ help-file-string ] [ write-using ] bi + [ docs-file-string ] [ write-using ] bi write ] with-output-stream ; -: check-scaffold ( vocab-root string -- vocab-root string ) - [ check-root ] [ check-vocab-name ] bi* ; - -: vocab>scaffold-path ( vocab-root string -- path ) - path-separator first CHAR: . associate substitute - append-path ; - -: prepare-scaffold ( vocab-root string -- string path ) - check-scaffold [ vocab>scaffold-path ] keep ; - : with-scaffold ( quot -- ) [ H{ } clone using ] dip with-variable ; inline -: check-vocab ( vocab -- vocab ) - dup find-vocab-root [ no-vocab ] unless ; - PRIVATE> : link-vocab ( vocab -- ) check-vocab "Edit documentation: " write - [ find-vocab-root ] - [ vocab>scaffold-path ] bi - "-docs.factor" (scaffold-path) . ; + "-docs.factor" vocab/suffix>path . ; -: help. ( word -- ) - [ (help.) ] [ nl vocabulary>> link-vocab ] bi ; +: docs. ( word -- ) + [ (docs.) ] [ nl vocabulary>> link-vocab ] bi ; -: scaffold-help ( string -- ) +: scaffold-docs ( vocab -- ) [ - [ find-vocab-root ] [ check-vocab ] bi - prepare-scaffold - [ "-docs.factor" scaffold-path ] dip - swap [ set-scaffold-help-file ] [ 2drop ] if + dup "-docs.factor" vocab/suffix>path scaffolding? [ + set-scaffold-docs-file + ] [ + 2drop + ] if ] with-scaffold ; : scaffold-undocumented ( string -- ) [ interesting-words. ] [ link-vocab ] bi ; -: scaffold-vocab ( vocab-root string -- ) - prepare-scaffold +: scaffold-vocab ( vocab-root vocab -- ) { - [ drop scaffold-directory ] + [ scaffold-directory ] [ scaffold-main ] - [ drop scaffold-authors ] + [ scaffold-authors ] [ nip require ] } 2cleave ; +: tests-file-string ( vocab -- string ) + [ + scaffold-copyright + "USING: tools.test " write dup write " ;" print + "IN: " write write ".tests" print + ] with-string-writer ; + +: set-scaffold-tests-file ( vocab path -- ) + [ tests-file-string ] dip utf8 set-file-contents ; + +: scaffold-tests ( vocab -- ) + dup "-tests.factor" vocab/suffix>path + scaffolding? [ + set-scaffold-tests-file + ] [ + 2drop + ] if ; + SYMBOL: examples-flag : example ( -- ) From 43679966789315c76caa14a81f8dc692971d6767 Mon Sep 17 00:00:00 2001 From: sheeple Date: Sun, 22 Feb 2009 00:33:00 -0600 Subject: [PATCH 20/24] make some more words private, rename scaffold-docs back to scaffold-help --- basis/tools/scaffold/scaffold.factor | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor index eb7017f57f..5a0bf66e26 100755 --- a/basis/tools/scaffold/scaffold.factor +++ b/basis/tools/scaffold/scaffold.factor @@ -211,8 +211,6 @@ ERROR: no-vocab vocab ; : with-scaffold ( quot -- ) [ H{ } clone using ] dip with-variable ; inline -PRIVATE> - : link-vocab ( vocab -- ) check-vocab "Edit documentation: " write @@ -221,7 +219,9 @@ PRIVATE> : docs. ( word -- ) [ (docs.) ] [ nl vocabulary>> link-vocab ] bi ; -: scaffold-docs ( vocab -- ) +PRIVATE> + +: scaffold-help ( vocab -- ) [ dup "-docs.factor" vocab/suffix>path scaffolding? [ set-scaffold-docs-file @@ -233,7 +233,7 @@ PRIVATE> : scaffold-undocumented ( string -- ) [ interesting-words. ] [ link-vocab ] bi ; -: scaffold-vocab ( vocab-root vocab -- ) +: scaffold-vocab ( vocab-root string -- ) { [ scaffold-directory ] [ scaffold-main ] @@ -241,6 +241,8 @@ PRIVATE> [ nip require ] } 2cleave ; + : set-scaffold-tests-file ( vocab path -- ) [ tests-file-string ] dip utf8 set-file-contents ; +PRIVATE> + : scaffold-tests ( vocab -- ) dup "-tests.factor" vocab/suffix>path scaffolding? [ From 57bd819886d5dc36e259f327c74919eacd17924f Mon Sep 17 00:00:00 2001 From: sheeple Date: Sun, 22 Feb 2009 00:42:21 -0600 Subject: [PATCH 21/24] add quoting vocab --- basis/quoting/authors.txt | 1 + basis/quoting/quoting-docs.factor | 32 ++++++++++++++++++++++++++++++ basis/quoting/quoting-tests.factor | 10 ++++++++++ basis/quoting/quoting.factor | 16 +++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 basis/quoting/authors.txt create mode 100644 basis/quoting/quoting-docs.factor create mode 100644 basis/quoting/quoting-tests.factor create mode 100644 basis/quoting/quoting.factor diff --git a/basis/quoting/authors.txt b/basis/quoting/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/basis/quoting/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/basis/quoting/quoting-docs.factor b/basis/quoting/quoting-docs.factor new file mode 100644 index 0000000000..5fb68db719 --- /dev/null +++ b/basis/quoting/quoting-docs.factor @@ -0,0 +1,32 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax strings ; +IN: quoting + +HELP: quote? +{ $values + { "ch" "a character" } + { "?" "a boolean" } +} +{ $description "Returns true if the character is a single or double quote." } ; + +HELP: quoted? +{ $values + { "str" string } + { "?" "a boolean" } +} +{ $description "Returns true if a string is surrounded by matching single or double quotes as the first and last characters." } ; + +HELP: unquote +{ $values + { "str" string } + { "newstr" string } +} +{ $description "Removes a pair of matching single or double quotes from a string." } ; + +ARTICLE: "quoting" "Quotation marks" +"The " { $vocab-link "quoting" } " vocabulary is for removing quotes from a string." $nl +"Removing quotes:" +{ $subsection unquote } ; + +ABOUT: "quoting" diff --git a/basis/quoting/quoting-tests.factor b/basis/quoting/quoting-tests.factor new file mode 100644 index 0000000000..0cc28a1354 --- /dev/null +++ b/basis/quoting/quoting-tests.factor @@ -0,0 +1,10 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test quoting ; +IN: quoting.tests + + +[ "abc" ] [ "'abc'" unquote ] unit-test +[ "abc" ] [ "\"abc\"" unquote ] unit-test +[ "'abc" ] [ "'abc" unquote ] unit-test +[ "abc'" ] [ "abc'" unquote ] unit-test diff --git a/basis/quoting/quoting.factor b/basis/quoting/quoting.factor new file mode 100644 index 0000000000..9e25037cd9 --- /dev/null +++ b/basis/quoting/quoting.factor @@ -0,0 +1,16 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: combinators.short-circuit kernel math sequences strings ; +IN: quoting + +: quote? ( ch -- ? ) "'\"" member? ; + +: quoted? ( str -- ? ) + { + [ length 1 > ] + [ first quote? ] + [ [ first ] [ peek ] bi = ] + } 1&& ; + +: unquote ( str -- newstr ) + dup quoted? [ but-last-slice rest-slice >string ] when ; From 06f6eb98aa1b8a9009a557acfeb3b3f59b9e7e37 Mon Sep 17 00:00:00 2001 From: sheeple Date: Sun, 22 Feb 2009 00:42:35 -0600 Subject: [PATCH 22/24] use quoting vocab --- basis/db/errors/postgresql/postgresql.factor | 15 +-------------- basis/mime/multipart/multipart.factor | 15 ++------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/basis/db/errors/postgresql/postgresql.factor b/basis/db/errors/postgresql/postgresql.factor index 2b79859050..02b43ecd88 100644 --- a/basis/db/errors/postgresql/postgresql.factor +++ b/basis/db/errors/postgresql/postgresql.factor @@ -1,22 +1,9 @@ ! Copyright (C) 2009 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: kernel db.errors peg.ebnf strings sequences math -combinators.short-circuit accessors math.parser ; +combinators.short-circuit accessors math.parser quoting ; IN: db.errors.postgresql -: quote? ( ch -- ? ) "'\"" member? ; - -: quoted? ( str -- ? ) - { - [ length 1 > ] - [ first quote? ] - [ [ first ] [ peek ] bi = ] - } 1&& ; - -: unquote ( str -- newstr ) - dup quoted? [ but-last-slice rest-slice >string ] when ; - - EBNF: parse-postgresql-sql-error Error = "ERROR:" [ ]+ diff --git a/basis/mime/multipart/multipart.factor b/basis/mime/multipart/multipart.factor index 37d5e13129..0edfb05a30 100755 --- a/basis/mime/multipart/multipart.factor +++ b/basis/mime/multipart/multipart.factor @@ -3,7 +3,8 @@ USING: multiline kernel sequences io splitting fry namespaces http.parsers hashtables assocs combinators ascii io.files.unique accessors io.encodings.binary io.files byte-arrays math -io.streams.string combinators.short-circuit strings math.order ; +io.streams.string combinators.short-circuit strings math.order +quoting ; IN: mime.multipart CONSTANT: buffer-size 65536 @@ -75,18 +76,6 @@ ERROR: end-of-stream multipart ; : empty-name? ( string -- ? ) { "''" "\"\"" "" f } member? ; -: quote? ( ch -- ? ) "'\"" member? ; - -: quoted? ( str -- ? ) - { - [ length 1 > ] - [ first quote? ] - [ [ first ] [ peek ] bi = ] - } 1&& ; - -: unquote ( str -- newstr ) - dup quoted? [ but-last-slice rest-slice >string ] when ; - : save-uploaded-file ( multipart -- ) dup filename>> empty-name? [ drop From 1f5a701f6809ba7d7004fe167f6de61eed40f6af Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 22 Feb 2009 10:03:37 -0600 Subject: [PATCH 23/24] fix load error in scaffold --- basis/tools/scaffold/scaffold-docs.factor | 4 ++-- basis/tools/scaffold/scaffold.factor | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/basis/tools/scaffold/scaffold-docs.factor b/basis/tools/scaffold/scaffold-docs.factor index 9074c80986..0a75732553 100644 --- a/basis/tools/scaffold/scaffold-docs.factor +++ b/basis/tools/scaffold/scaffold-docs.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: help.markup help.syntax kernel strings words ; +USING: help.markup help.syntax kernel strings words vocabs ; IN: tools.scaffold HELP: developer-name @@ -13,7 +13,7 @@ HELP: help. { $description "Prints out scaffold help markup for a given word." } ; HELP: scaffold-help -{ $values { "string" string } } +{ $values { "vocab" vocab } } { $description "Takes an existing vocabulary and creates a help file with scaffolded help for each word. This word only works if no help file yet exists." } ; HELP: scaffold-undocumented diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor index 5a0bf66e26..16729394bf 100755 --- a/basis/tools/scaffold/scaffold.factor +++ b/basis/tools/scaffold/scaffold.factor @@ -169,7 +169,7 @@ ERROR: no-vocab vocab ; : docs-header. ( word -- ) "HELP: " write name>> print ; -: (docs.) ( word -- ) +: (help.) ( word -- ) [ docs-header. ] [ $values. ] [ $description. ] tri ; : interesting-words ( vocab -- array ) @@ -178,7 +178,7 @@ ERROR: no-vocab vocab ; natural-sort ; : interesting-words. ( vocab -- ) - interesting-words [ (docs.) nl ] each ; + interesting-words [ (help.) nl ] each ; : docs-file-string ( vocab -- str2 ) [ @@ -216,11 +216,11 @@ ERROR: no-vocab vocab ; "Edit documentation: " write "-docs.factor" vocab/suffix>path . ; -: docs. ( word -- ) - [ (docs.) ] [ nl vocabulary>> link-vocab ] bi ; - PRIVATE> +: help. ( word -- ) + [ (help.) ] [ nl vocabulary>> link-vocab ] bi ; + : scaffold-help ( vocab -- ) [ dup "-docs.factor" vocab/suffix>path scaffolding? [ From b78d8a491fd069935475cd05d245c30b1c7daea0 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 22 Feb 2009 10:27:29 -0600 Subject: [PATCH 24/24] add docs for scaffold-rc --- basis/tools/scaffold/scaffold-docs.factor | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/basis/tools/scaffold/scaffold-docs.factor b/basis/tools/scaffold/scaffold-docs.factor index 0a75732553..4d1240ad38 100644 --- a/basis/tools/scaffold/scaffold-docs.factor +++ b/basis/tools/scaffold/scaffold-docs.factor @@ -28,6 +28,21 @@ HELP: scaffold-vocab { "vocab-root" "a vocabulary root string" } { "string" string } } { $description "Creates a directory in the given root for a new vocabulary and adds a main .factor file, a tests file, and an authors.txt file." } ; +HELP: scaffold-emacs +{ $description "Touches the .emacs file in your home directory and provides a clickable link to open it in an editor." } ; + +HELP: scaffold-factor-boot-rc +{ $description "Touches the .factor-boot-rc file in your home directory and provides a clickable link to open it in an editor." } ; + +HELP: scaffold-factor-rc +{ $description "Touches the .factor-rc file in your home directory and provides a clickable link to open it in an editor." } ; + +HELP: scaffold-rc +{ $values + { "path" "a pathname string" } +} +{ $description "Touches the given path in your home directory and provides a clickable link to open it in an editor." } ; + HELP: using { $description "Stores the vocabularies that are pulled into the documentation file from looking up the stack effect types." } ; @@ -40,7 +55,12 @@ ARTICLE: "tools.scaffold" "Scaffold tool" { $subsection scaffold-help } { $subsection scaffold-undocumented } { $subsection help. } -"Types that are unrecognized by the scaffold generator will be of type " { $link null } ". The developer should change these to strings that describe the stack effect names instead." +"Types that are unrecognized by the scaffold generator will be of type " { $link null } ". The developer should change these to strings that describe the stack effect names instead." $nl +"Scaffolding a configuration file:" +{ $subsection scaffold-rc } +{ $subsection scaffold-factor-boot-rc } +{ $subsection scaffold-factor-rc } +{ $subsection scaffold-emacs } ; ABOUT: "tools.scaffold"