From b2f4217e082eaddbec37f410e23d9d34416dfb97 Mon Sep 17 00:00:00 2001 From: James Cash Date: Mon, 26 May 2008 21:22:39 -0400 Subject: [PATCH 0001/1850] Making indentation default 4 spaces, instead of 2 --- misc/factor.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misc/factor.el b/misc/factor.el index 9d90fb68f9..300c95c430 100644 --- a/misc/factor.el +++ b/misc/factor.el @@ -94,6 +94,10 @@ "SYMBOLS:" )) +(defun factor-indent-line () + "Indent current line as Factor code" + (indent-line-to (+ (current-indentation) 4))) + (defun factor-mode () "A mode for editing programs written in the Factor programming language." (interactive) @@ -107,6 +111,8 @@ (setq font-lock-defaults '(factor-font-lock-keywords nil nil nil nil)) (set-syntax-table factor-mode-syntax-table) + (make-local-variable 'indent-line-function) + (setq indent-line-function 'factor-indent-line) (run-hooks 'factor-mode-hook)) (add-to-list 'auto-mode-alist '("\\.factor\\'" . factor-mode)) From bb38d31922cb0490f4f0ab9c06039181011cd9a9 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Wed, 28 May 2008 21:59:49 -0300 Subject: [PATCH 0002/1850] irc.client: Support for listening to nicknames too. --- extra/irc/client/client.factor | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 19dca48e1d..cc0b4378c7 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -110,6 +110,9 @@ TUPLE: unhandled < irc-message ; ! Server message handling ! ====================================== +: irc-message-origin ( irc-message -- name ) + dup name>> irc-client> nick>> name>> = [ sender>> ] [ name>> ] if ; + USE: prettyprint GENERIC: handle-incoming-irc ( irc-message -- ) @@ -127,8 +130,8 @@ M: nick-in-use handle-incoming-irc ( nick-in-use -- ) name>> "_" append /NICK ; M: privmsg handle-incoming-irc ( privmsg -- ) - dup name>> irc-client> listeners>> at - [ in-messages>> mailbox-put ] [ drop ] if* ; + dup dup . irc-message-origin irc-client> listeners>> at + [ in-messages>> mailbox-put ] [ dup "drop" . . drop ] if* ; M: join handle-incoming-irc ( join -- ) irc-client> join-messages>> mailbox-put ; @@ -222,13 +225,15 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) GENERIC: add-name ( name obj -- obj ) M: object add-name nip ; M: privmsg add-name swap >>name ; - + : listener-loop ( name -- ) ! FIXME: take different values from the stack? dup irc-client> listeners>> at [ out-messages>> mailbox-get add-name irc-client> out-messages>> mailbox-put - ] [ drop ] if* ; + ] [ + drop + ] if* ; : spawn-irc-loop ( quot name -- ) [ [ irc-client> is-running>> ] compose ] dip @@ -243,17 +248,26 @@ M: privmsg add-name swap >>name ; ! Listener join request handling ! ====================================== -: make-registered-listener ( join -- listener ) - swap trailing>> - dup [ listener-loop ] curry "listener" spawn-irc-loop +: make-registered-listener ( name -- listener ) + swap dup + [ listener-loop ] curry "listener" spawn-irc-loop [ irc-client> listeners>> set-at ] curry keep ; : make-join-future ( name -- future ) [ [ swap trailing>> = ] curry ! compare name with channel name irc-client> join-messages>> 60 seconds rot mailbox-get-timeout? - make-registered-listener ] + trailing>> make-registered-listener ] curry future ; +: make-user-future ( name -- future ) + [ make-registered-listener ] curry future ; + +: maybe-join ( name password -- ? ) + over "#" head? [ /JOIN t ] [ 2drop f ] if ; + +: make-listener-future ( name channel? -- future ) + [ make-join-future ] [ make-user-future ] if ; + PRIVATE> : (connect-irc) ( irc-client -- ) @@ -268,7 +282,9 @@ PRIVATE> ] with-variable ; : listen-to ( irc-client name -- future ) - swap current-irc-client [ [ f /JOIN ] keep make-join-future ] with-variable ; + swap current-irc-client [ + dup f maybe-join make-listener-future + ] with-variable ; ! shorcut for privmsgs, etc : sender>> ( obj -- string ) From dcf89c05900d5f6e3ec4be86837de6eedc7ed05e Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Wed, 28 May 2008 22:02:09 -0300 Subject: [PATCH 0003/1850] irc.client: Remove prettyprints. --- extra/irc/client/client.factor | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index cc0b4378c7..c7b9784270 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -113,12 +113,10 @@ TUPLE: unhandled < irc-message ; : irc-message-origin ( irc-message -- name ) dup name>> irc-client> nick>> name>> = [ sender>> ] [ name>> ] if ; -USE: prettyprint - GENERIC: handle-incoming-irc ( irc-message -- ) M: irc-message handle-incoming-irc ( irc-message -- ) - . ; + drop ; M: logged-in handle-incoming-irc ( logged-in -- ) name>> irc-client> nick>> (>>name) ; @@ -130,8 +128,8 @@ M: nick-in-use handle-incoming-irc ( nick-in-use -- ) name>> "_" append /NICK ; M: privmsg handle-incoming-irc ( privmsg -- ) - dup dup . irc-message-origin irc-client> listeners>> at - [ in-messages>> mailbox-put ] [ dup "drop" . . drop ] if* ; + dup irc-message-origin irc-client> listeners>> at + [ in-messages>> mailbox-put ] [ drop ] if* ; M: join handle-incoming-irc ( join -- ) irc-client> join-messages>> mailbox-put ; From 8d0016d0e3e0508e406620f8d6bf84b74501613e Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Fri, 30 May 2008 10:03:53 -0300 Subject: [PATCH 0004/1850] irc.client: Rename word --- extra/irc/client/client.factor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index c7b9784270..86f97f37a9 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -220,13 +220,13 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) irc-client> in-messages>> mailbox-get handle-incoming-irc ; ! FIXME: Hack, this should be handled better -GENERIC: add-name ( name obj -- obj ) -M: object add-name nip ; -M: privmsg add-name swap >>name ; +GENERIC: annotate-message-with-name ( name obj -- obj ) +M: object annotate-message-with-name nip ; +M: privmsg annotate-message-with-name swap >>name ; : listener-loop ( name -- ) ! FIXME: take different values from the stack? dup irc-client> listeners>> at [ - out-messages>> mailbox-get add-name + out-messages>> mailbox-get annotate-message-with-name irc-client> out-messages>> mailbox-put ] [ From a7afae250d4de6f18fe9e98e4ae5621e0d793477 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 1 Jun 2008 00:48:38 -0500 Subject: [PATCH 0005/1850] clean up code some make \# retries user configurable --- extra/db/db.factor | 4 ++-- extra/db/queries/queries.factor | 10 +++++----- extra/db/sql/sql.factor | 4 +++- extra/db/tuples/tuples.factor | 14 ++++++++------ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/extra/db/db.factor b/extra/db/db.factor index 8d1feca6c7..889eff196c 100755 --- a/extra/db/db.factor +++ b/extra/db/db.factor @@ -35,7 +35,7 @@ HOOK: db-close db ( handle -- ) handle>> db-close ] with-variable ; -TUPLE: statement handle sql in-params out-params bind-params bound? type ; +TUPLE: statement handle sql in-params out-params bind-params bound? type retries ; TUPLE: simple-statement < statement ; TUPLE: prepared-statement < statement ; @@ -89,7 +89,7 @@ M: object execute-statement* ( statement type -- ) swap >>out-params swap >>in-params swap >>sql ; - + : sql-row ( result-set -- seq ) dup #columns [ row-column ] with map ; diff --git a/extra/db/queries/queries.factor b/extra/db/queries/queries.factor index 59ee60aa1f..d524080e57 100644 --- a/extra/db/queries/queries.factor +++ b/extra/db/queries/queries.factor @@ -2,7 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel math namespaces sequences random strings math.parser math.intervals combinators -math.bitfields.lib namespaces.lib db db.tuples db.types ; +math.bitfields.lib namespaces.lib db db.tuples db.types +sequences.lib ; IN: db.queries GENERIC: where ( specs obj -- ) @@ -99,16 +100,15 @@ M: string where ( spec obj -- ) object-where ; ] with filter ; : where-clause ( tuple specs -- ) - dupd filter-slots - dup empty? [ - 2drop + dupd filter-slots [ + drop ] [ " where " 0% [ " and " 0% ] [ 2dup slot-name>> swap get-slot-named where ] interleave drop - ] if ; + ] if-empty ; M: db ( tuple table -- sql ) [ diff --git a/extra/db/sql/sql.factor b/extra/db/sql/sql.factor index 82c6e370bd..756aeea7c0 100755 --- a/extra/db/sql/sql.factor +++ b/extra/db/sql/sql.factor @@ -5,7 +5,9 @@ IN: db.sql SYMBOLS: insert update delete select distinct columns from as where group-by having order-by limit offset is-null desc all -any count avg table values ; +any count avg table values ? ; + +! Output an s-exp sql statement and an alist of keys/values : input-spec, 1, ; : output-spec, 2, ; diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index bac141d6d2..b7bf6a7fbe 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -55,6 +55,7 @@ SINGLETON: retryable [ make-retryable ] map ] [ retryable >>type + 10 >>retries ] if ; : regenerate-params ( statement -- statement ) @@ -69,12 +70,13 @@ SINGLETON: retryable ] 2map >>bind-params ; M: retryable execute-statement* ( statement type -- ) - drop - [ - [ query-results dispose t ] - [ ] - [ regenerate-params bind-statement* f ] cleanup - ] curry 10 retry drop ; + drop [ + [ + [ query-results dispose t ] + [ ] + [ regenerate-params bind-statement* f ] cleanup + ] curry + ] [ retries>> ] bi retry drop ; : resulting-tuple ( class row out-params -- tuple ) rot class new [ From 96ce30a534f744cc160b1075bd92de6525805f9d Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 1 Jun 2008 11:25:09 -0500 Subject: [PATCH 0006/1850] add advanced-select word --- extra/db/tuples/tuples.factor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index b7bf6a7fbe..09fd63b233 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -154,3 +154,7 @@ M: retryable execute-statement* ( statement type -- ) : select-tuple ( tuple -- tuple/f ) dup dup class f f f 1 do-select ?first ; + +: advanced-select ( tuple groups order offset limit -- tuples ) + >r >r >r >r dup dup class r> r> r> r> + do-select ; From 53952c320052e097f3b778dd6e93e0e313378dc1 Mon Sep 17 00:00:00 2001 From: Matthew Willis Date: Sun, 1 Jun 2008 10:35:40 -0700 Subject: [PATCH 0007/1850] enhanced performance of pango and cairo gadgets by making the intermediate byte-arrays short-lived, and by using a global "dummy-cairo" for measuring layout-sizes --- extra/cairo/gadgets/gadgets.factor | 17 +++++++++++++---- extra/pango/cairo/cairo.factor | 7 +++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/extra/cairo/gadgets/gadgets.factor b/extra/cairo/gadgets/gadgets.factor index f5f4d3e965..69252f8303 100644 --- a/extra/cairo/gadgets/gadgets.factor +++ b/extra/cairo/gadgets/gadgets.factor @@ -2,7 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: sequences math opengl.gadgets kernel byte-arrays cairo.ffi cairo io.backend -opengl.gl arrays ; +ui.gadgets accessors opengl.gl +arrays ; IN: cairo.gadgets @@ -14,9 +15,17 @@ IN: cairo.gadgets [ cairo_image_surface_create_for_data ] 3bi r> with-cairo-from-surface ; -: ( dim quot -- ) - over 2^-bounds swap copy-cairo - GL_BGRA rot ; +TUPLE: cairo-gadget < texture-gadget quot ; + +: ( dim quot -- gadget ) + cairo-gadget construct-gadget + swap >>quot + swap >>dim ; + +M: cairo-gadget graft* ( gadget -- ) + GL_BGRA >>format dup + [ dim>> 2^-bounds ] [ quot>> copy-cairo ] bi + >>bytes call-next-method ; ! maybe also texture>png ! : cairo>png ( gadget path -- ) diff --git a/extra/pango/cairo/cairo.factor b/extra/pango/cairo/cairo.factor index 889052c385..907233a335 100644 --- a/extra/pango/cairo/cairo.factor +++ b/extra/pango/cairo/cairo.factor @@ -4,6 +4,7 @@ ! pangocairo bindings, from pango/pangocairo.h USING: cairo.ffi alien.c-types math alien.syntax system combinators alien +memoize arrays pango pango.fonts ; IN: pango.cairo @@ -111,9 +112,11 @@ M: pango-layout dispose ( alien -- ) alien>> g_object_unref ; 0 0 [ pango_layout_get_pixel_size ] 2keep [ *int ] bi@ ; +MEMO: dummy-cairo ( -- cr ) + CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create cairo_create ; + : dummy-pango ( quot -- ) - >r CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create - r> [ with-pango ] curry with-cairo-from-surface ; inline + >r dummy-cairo cairo r> [ with-pango ] curry with-variable ; inline : layout-size ( quot -- dim ) [ layout pango-layout-get-pixel-size 2array ] compose dummy-pango ; inline From 352c9b8997487c88cc2c78a27732178f7066311e Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Sun, 1 Jun 2008 20:58:53 -0300 Subject: [PATCH 0008/1850] irc.client: Clean code a bit, add some unit-tests --- extra/irc/client/client-tests.factor | 36 +++++++++ extra/irc/client/client.factor | 107 +++++++++++++-------------- 2 files changed, 86 insertions(+), 57 deletions(-) create mode 100644 extra/irc/client/client-tests.factor diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor new file mode 100644 index 0000000000..d274f3a6b1 --- /dev/null +++ b/extra/irc/client/client-tests.factor @@ -0,0 +1,36 @@ +USING: kernel ; +IN: +irc.client.private +: me? ( string -- ? ) + "factorbot" = ; + +USING: irc.client irc.client.private kernel tools.test accessors arrays ; +IN: irc.client.tests + +irc-message new + ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line + "someuser!n=user@some.where" >>prefix + "PRIVMSG" >>command + { "#factortest" } >>parameters + "hi" >>trailing 1array +[ ":someuser!n=user@some.where PRIVMSG #factortest :hi" + string>irc-message f >>timestamp ] unit-test + +privmsg new + ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line + "someuser!n=user@some.where" >>prefix + "PRIVMSG" >>command + { "#factortest" } >>parameters + "hi" >>trailing + "#factortest" >>name 1array +[ ":someuser!n=user@some.where PRIVMSG #factortest :hi" + parse-irc-line f >>timestamp ] unit-test + +{ "someuser" } [ "someuser!n=user@some.where" + parse-name ] unit-test + +{ "#factortest" } [ ":someuser!n=user@some.where PRIVMSG #factortest :hi" + parse-irc-line irc-message-origin ] unit-test + +{ "someuser" } [ ":someuser!n=user@some.where PRIVMSG factorbot :hi" + parse-irc-line irc-message-origin ] unit-test diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 86f97f37a9..5247f135fc 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -3,7 +3,7 @@ USING: arrays combinators concurrency.mailboxes concurrency.futures io io.encodings.8-bit io.sockets kernel namespaces sequences sequences.lib splitting threads calendar classes.tuple - ascii assocs accessors destructors ; + classes ascii assocs accessors destructors ; IN: irc.client ! ====================================== @@ -106,43 +106,6 @@ TUPLE: unhandled < irc-message ; : /PONG ( text -- ) "PONG " irc-write irc-print ; -! ====================================== -! Server message handling -! ====================================== - -: irc-message-origin ( irc-message -- name ) - dup name>> irc-client> nick>> name>> = [ sender>> ] [ name>> ] if ; - -GENERIC: handle-incoming-irc ( irc-message -- ) - -M: irc-message handle-incoming-irc ( irc-message -- ) - drop ; - -M: logged-in handle-incoming-irc ( logged-in -- ) - name>> irc-client> nick>> (>>name) ; - -M: ping handle-incoming-irc ( ping -- ) - trailing>> /PONG ; - -M: nick-in-use handle-incoming-irc ( nick-in-use -- ) - name>> "_" append /NICK ; - -M: privmsg handle-incoming-irc ( privmsg -- ) - dup irc-message-origin irc-client> listeners>> at - [ in-messages>> mailbox-put ] [ drop ] if* ; - -M: join handle-incoming-irc ( join -- ) - irc-client> join-messages>> mailbox-put ; - -! ====================================== -! Client message handling -! ====================================== - -GENERIC: handle-outgoing-irc ( obj -- ) - -M: privmsg handle-outgoing-irc ( privmsg -- ) - [ name>> ] [ trailing>> ] bi /PRIVMSG ; - ! ====================================== ! Message parsing ! ====================================== @@ -189,6 +152,46 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) } case [ [ tuple-slots ] [ parameters>> ] bi append ] dip prefix >tuple ; +! ====================================== +! Server message handling +! ====================================== + +: me? ( string -- ? ) + irc-client> nick>> name>> = ; + +: irc-message-origin ( irc-message -- name ) + dup name>> me? [ prefix>> parse-name ] [ name>> ] if ; + +GENERIC: handle-incoming-irc ( irc-message -- ) + +M: irc-message handle-incoming-irc ( irc-message -- ) + drop ; + +M: logged-in handle-incoming-irc ( logged-in -- ) + name>> irc-client> nick>> (>>name) ; + +M: ping handle-incoming-irc ( ping -- ) + trailing>> /PONG ; + +M: nick-in-use handle-incoming-irc ( nick-in-use -- ) + name>> "_" append /NICK ; + +M: privmsg handle-incoming-irc ( privmsg -- ) + dup irc-message-origin irc-client> listeners>> at + [ in-messages>> mailbox-put ] [ drop ] if* ; + +M: join handle-incoming-irc ( join -- ) + irc-client> join-messages>> mailbox-put ; + +! ====================================== +! Client message handling +! ====================================== + +GENERIC: handle-outgoing-irc ( obj -- ) + +M: privmsg handle-outgoing-irc ( privmsg -- ) + [ name>> ] [ trailing>> ] bi /PRIVMSG ; + ! ====================================== ! Reader/Writer ! ====================================== @@ -219,19 +222,12 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) : in-multiplexer-loop ( -- ) irc-client> in-messages>> mailbox-get handle-incoming-irc ; -! FIXME: Hack, this should be handled better -GENERIC: annotate-message-with-name ( name obj -- obj ) -M: object annotate-message-with-name nip ; -M: privmsg annotate-message-with-name swap >>name ; +: maybe-annotate-with-name ( name obj -- obj ) + dup privmsg instance? [ swap >>name ] [ nip ] if ; -: listener-loop ( name -- ) ! FIXME: take different values from the stack? - dup irc-client> listeners>> at [ - out-messages>> mailbox-get annotate-message-with-name - irc-client> out-messages>> - mailbox-put - ] [ - drop - ] if* ; +: listener-loop ( name listener -- ) + out-messages>> mailbox-get maybe-annotate-with-name + irc-client> out-messages>> mailbox-put ; : spawn-irc-loop ( quot name -- ) [ [ irc-client> is-running>> ] compose ] dip @@ -247,9 +243,10 @@ M: privmsg annotate-message-with-name swap >>name ; ! ====================================== : make-registered-listener ( name -- listener ) - swap dup - [ listener-loop ] curry "listener" spawn-irc-loop - [ irc-client> listeners>> set-at ] curry keep ; + + [ [ listener-loop ] 2curry "listener" spawn-irc-loop ] + [ swap [ irc-client> listeners>> set-at ] curry keep ] + 2bi ; : make-join-future ( name -- future ) [ [ swap trailing>> = ] curry ! compare name with channel name @@ -283,7 +280,3 @@ PRIVATE> swap current-irc-client [ dup f maybe-join make-listener-future ] with-variable ; - -! shorcut for privmsgs, etc -: sender>> ( obj -- string ) - prefix>> parse-name ; From 4b3560d06829c3878287c99735051c9400671fd8 Mon Sep 17 00:00:00 2001 From: James Cash Date: Mon, 26 May 2008 15:48:22 -0400 Subject: [PATCH 0009/1850] Spelling error, more tests --- extra/lisp/lisp-tests.factor | 25 ++++++++++++++++--------- extra/lisp/lisp.factor | 5 ++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/extra/lisp/lisp-tests.factor b/extra/lisp/lisp-tests.factor index 0312080907..e260857a37 100644 --- a/extra/lisp/lisp-tests.factor +++ b/extra/lisp/lisp-tests.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: lisp lisp.parser tools.test sequences math kernel parser ; +USING: lisp lisp.parser tools.test sequences math kernel parser arrays ; IN: lisp.test @@ -10,8 +10,11 @@ IN: lisp.test "#f" [ f ] lisp-define "#t" [ t ] lisp-define - "+" "math" "+" define-primitve - "-" "math" "-" define-primitve + "+" "math" "+" define-primitive + "-" "math" "-" define-primitive + + "list" [ >array ] lisp-define + "map" [ [ swap map ] compose call ] lisp-define { 5 } [ [ 2 3 ] "+" funcall @@ -22,26 +25,30 @@ IN: lisp.test ] unit-test { 3 } [ - "((lambda (x y) (+ x y)) 1 2)" lisp-string>factor call + "((lambda (x y) (+ x y)) 1 2)" lisp-eval ] unit-test { 42 } [ - "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-string>factor call + "((lambda (x y z) (+ x (- y z))) 40 3 1)" lisp-eval ] unit-test { 1 } [ - "(if #t 1 2)" lisp-string>factor call + "(if #t 1 2)" lisp-eval ] unit-test { "b" } [ - "(cond (#f \"a\") (#t \"b\"))" lisp-string>factor call + "(cond (#f \"a\") (#t \"b\"))" lisp-eval ] unit-test { 5 } [ - "(begin (+ 1 4))" lisp-string>factor call + "(begin (+ 1 4))" lisp-eval ] unit-test { 3 } [ - "((lambda (x) (if x (begin (+ 1 2)) (- 3 5))) #t)" lisp-string>factor call + "((lambda (x) (if x (begin (+ 1 2)) (- 3 5))) #t)" lisp-eval + ] unit-test + + { { 1 2 3 4 5 } } [ + "(list 1 2 3 4 5)" lisp-eval ] unit-test ] with-interactive-vocabs \ No newline at end of file diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 82a331f2ca..9b2691293b 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -78,6 +78,9 @@ PRIVATE> : lisp-string>factor ( str -- quot ) lisp-expr parse-result-ast convert-form lambda-rewrite call ; +: lisp-eval ( str -- * ) + lisp-string>factor call ; + ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SYMBOL: lisp-env @@ -98,5 +101,5 @@ ERROR: no-such-var var ; : funcall ( quot sym -- * ) dup lisp-symbol? [ lookup-var ] when call ; inline -: define-primitve ( name vocab word -- ) +: define-primitive ( name vocab word -- ) swap lookup 1quotation '[ , compose call ] lisp-define ; \ No newline at end of file From 904bac28088fd682f85b1b2fe636ef867ba796e2 Mon Sep 17 00:00:00 2001 From: James Cash Date: Mon, 26 May 2008 16:52:51 -0400 Subject: [PATCH 0010/1850] Don't need bake anymore, using fry instead --- extra/lisp/lisp.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 9b2691293b..3f357d4354 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. USING: kernel peg sequences arrays strings combinators.lib -namespaces combinators math bake locals locals.private accessors +namespaces combinators math locals locals.private accessors vectors syntax lisp.parser assocs parser sequences.lib words quotations fry ; IN: lisp From 1f9c6d472efd976d593a4babbff413c26d58e4ab Mon Sep 17 00:00:00 2001 From: James Cash Date: Mon, 26 May 2008 17:02:23 -0400 Subject: [PATCH 0011/1850] Removing map test, poor implementation --- extra/lisp/lisp-tests.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/lisp/lisp-tests.factor b/extra/lisp/lisp-tests.factor index e260857a37..2358fa3f7e 100644 --- a/extra/lisp/lisp-tests.factor +++ b/extra/lisp/lisp-tests.factor @@ -14,7 +14,6 @@ IN: lisp.test "-" "math" "-" define-primitive "list" [ >array ] lisp-define - "map" [ [ swap map ] compose call ] lisp-define { 5 } [ [ 2 3 ] "+" funcall @@ -51,4 +50,5 @@ IN: lisp.test { { 1 2 3 4 5 } } [ "(list 1 2 3 4 5)" lisp-eval ] unit-test -] with-interactive-vocabs \ No newline at end of file + +] with-interactive-vocabs From bf860c8529830524db626eb595acf4e842daa722 Mon Sep 17 00:00:00 2001 From: James Cash Date: Fri, 30 May 2008 01:44:54 -0400 Subject: [PATCH 0012/1850] Starting work on macros --- extra/lisp/lisp.factor | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 3f357d4354..22fc053811 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -9,6 +9,7 @@ IN: lisp DEFER: convert-form DEFER: funcall DEFER: lookup-var +DEFER: lisp-macro? ! Functions to convert s-exps to quotations ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -57,17 +58,25 @@ PRIVATE> : convert-quoted ( s-exp -- quot ) second 1quotation ; +: form-dispatch ( lisp-symbol -- quot ) + name>> + { { "lambda" [ convert-lambda ] } + { "quote" [ convert-quoted ] } + { "if" [ convert-if ] } + { "begin" [ convert-begin ] } + { "cond" [ convert-cond ] } + [ drop convert-general-form ] + } case ; + +: macro-expand ( s-exp -- quot ) + ; + : convert-list-form ( s-exp -- quot ) - dup first dup lisp-symbol? - [ name>> - { { "lambda" [ convert-lambda ] } - { "quote" [ convert-quoted ] } - { "if" [ convert-if ] } - { "begin" [ convert-begin ] } - { "cond" [ convert-cond ] } - [ drop convert-general-form ] - } case ] - [ drop convert-general-form ] if ; + dup first + { { [ dup lisp-macro? ] [ macro-expand ] } + { [ dup lisp-symbol? ] [ form-dispatch ] } + [ drop convert-general-form ] + } cond ; : convert-form ( lisp-form -- quot ) { { [ dup s-exp? ] [ body>> convert-list-form ] } From 99e546ef65fd9a2e1e71a1ee998a5b0447f59b83 Mon Sep 17 00:00:00 2001 From: James Cash Date: Sun, 1 Jun 2008 00:52:47 -0400 Subject: [PATCH 0013/1850] More work on macros --- extra/lisp/lisp.factor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 22fc053811..28a9255293 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -10,6 +10,7 @@ DEFER: convert-form DEFER: funcall DEFER: lookup-var DEFER: lisp-macro? +DEFER: looku-macro ! Functions to convert s-exps to quotations ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -69,7 +70,7 @@ PRIVATE> } case ; : macro-expand ( s-exp -- quot ) - ; + unclip-slice lookup-macro macro-call convert-form ; : convert-list-form ( s-exp -- quot ) dup first From 27586218e82c904b7edb782f73ab936e76c17a08 Mon Sep 17 00:00:00 2001 From: James Cash Date: Sun, 1 Jun 2008 18:50:22 -0400 Subject: [PATCH 0014/1850] Replacing s-exp tuple with cons cells in parser, updating tests --- extra/lisp/parser/parser-tests.factor | 45 ++++++++++++++++++++------- extra/lisp/parser/parser.factor | 23 +++++++++----- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/extra/lisp/parser/parser-tests.factor b/extra/lisp/parser/parser-tests.factor index 98a6d2a6ba..712a1f9b9e 100644 --- a/extra/lisp/parser/parser-tests.factor +++ b/extra/lisp/parser/parser-tests.factor @@ -9,38 +9,61 @@ IN: lisp.parser.tests ] unit-test { -42 } [ - "-42" "atom" \ lisp-expr rule parse parse-result-ast + "-42" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { 37/52 } [ - "37/52" "atom" \ lisp-expr rule parse parse-result-ast + "37/52" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { 123.98 } [ - "123.98" "atom" \ lisp-expr rule parse parse-result-ast + "123.98" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { "" } [ - "\"\"" "atom" \ lisp-expr rule parse parse-result-ast + "\"\"" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { "aoeu" } [ - "\"aoeu\"" "atom" \ lisp-expr rule parse parse-result-ast + "\"aoeu\"" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { "aoeu\"de" } [ - "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse parse-result-ast + "\"aoeu\\\"de\"" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { T{ lisp-symbol f "foobar" } } [ - "foobar" "atom" \ lisp-expr rule parse parse-result-ast + "foobar" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test { T{ lisp-symbol f "+" } } [ - "+" "atom" \ lisp-expr rule parse parse-result-ast + "+" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test -{ T{ s-exp f - V{ T{ lisp-symbol f "foo" } 1 2 "aoeu" } } } [ - "(foo 1 2 \"aoeu\")" lisp-expr parse-result-ast +{ T{ cons f f f } +} [ + "()" lisp-expr parse-result-ast +] unit-test + +{ T{ + cons + f + T{ lisp-symbol f "foo" } + T{ + cons + f + 1 + T{ cons f 2 T{ cons f "aoeu" T{ cons f f f } } } + } } } [ + "(foo 1 2 \"aoeu\")" lisp-expr parse-result-ast +] unit-test + +{ T{ cons f + 1 + T{ cons f + T{ cons f 3 T{ cons f 4 T{ cons f f f } } } + T{ cons f 2 T{ cons f f } } } + } +} [ + "(1 (3 4) 2)" lisp-expr parse-result-ast ] unit-test \ No newline at end of file diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor index cf5ff56331..dad6a7dc24 100644 --- a/extra/lisp/parser/parser.factor +++ b/extra/lisp/parser/parser.factor @@ -1,16 +1,22 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: kernel peg.ebnf peg.expr math.parser sequences arrays strings -combinators.lib math ; +USING: kernel peg peg.ebnf peg.expr math.parser sequences arrays strings +combinators.lib math fry accessors ; IN: lisp.parser TUPLE: lisp-symbol name ; C: lisp-symbol -TUPLE: s-exp body ; -C: s-exp +TUPLE: cons car cdr ; +: cons \ cons new ; +: ( x -- cons ) + cons swap >>car ; + +: seq>cons ( seq -- cons ) + cons [ swap >>cdr ] reduce ; + EBNF: lisp-expr _ = (" " | "\t" | "\n")* LPAREN = "(" @@ -24,8 +30,9 @@ rational = integer "/" (digit)+ => [[ first3 nip string number = float | rational | integer -id-specials = "!" | "$" | "%" | "&" | "*" | "/" | ":" | "<" | "#" - | " =" | ">" | "?" | "^" | "_" | "~" | "+" | "-" | "." | "@" +id-specials = "!" | "$" | "%" | "&" | "*" | "/" | ":" + | "<" | "#" | " =" | ">" | "?" | "^" | "_" + | "~" | "+" | "-" | "." | "@" letters = [a-zA-Z] => [[ 1array >string ]] initials = letters | id-specials numbers = [0-9] => [[ 1array >string ]] @@ -36,6 +43,6 @@ string = dquote ( escaped | !(dquote) . )* dquote => [[ second >string ]] atom = number | identifier | string -list-item = _ (atom|s-expression) _ => [[ second ]] -s-expression = LPAREN (list-item)* RPAREN => [[ second ]] +list-item = _ ( atom | s-expression ) _ => [[ second ]] +s-expression = LPAREN (list-item)* RPAREN => [[ second seq>cons ]] ;EBNF \ No newline at end of file From f0fdac5b7d253ce3858ea26d1ee1f35e0a2c6b84 Mon Sep 17 00:00:00 2001 From: James Cash Date: Sun, 1 Jun 2008 23:59:38 -0400 Subject: [PATCH 0015/1850] Starting work on converting lisp.factor to use cons cells --- extra/lisp/lisp.factor | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 28a9255293..59b0ccdff2 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -6,42 +6,45 @@ vectors syntax lisp.parser assocs parser sequences.lib words quotations fry ; IN: lisp +: uncons ( cons -- cdr car ) + [ cdr>> ] [ car>> ] bi ; + DEFER: convert-form DEFER: funcall DEFER: lookup-var DEFER: lisp-macro? -DEFER: looku-macro +DEFER: lookup-macro ! Functions to convert s-exps to quotations ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: convert-body ( s-exp -- quot ) +: convert-body ( cons -- quot ) [ ] [ convert-form compose ] reduce ; inline -: convert-if ( s-exp -- quot ) +: convert-if ( cons -- quot ) rest first3 [ convert-form ] tri@ '[ @ , , if ] ; -: convert-begin ( s-exp -- quot ) +: convert-begin ( cons -- quot ) rest [ convert-form ] [ ] map-as '[ , [ funcall ] each ] ; -: convert-cond ( s-exp -- quot ) +: convert-cond ( cons -- quot ) rest [ body>> first2 [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ] { } map-as '[ , cond ] ; -: convert-general-form ( s-exp -- quot ) - unclip convert-form swap convert-body swap '[ , @ funcall ] ; +: convert-general-form ( cons -- quot ) + uncons convert-form swap convert-body swap '[ , @ funcall ] ; ! words for convert-lambda > ] dip at swap or ] - [ dup s-exp? [ body>> localize-body ] when ] if + [ dup cons? [ body>> localize-body ] when ] if ] map ; : localize-lambda ( body vars -- newbody newvars ) make-locals dup push-locals swap [ swap localize-body convert-form swap pop-locals ] dip swap ; -: split-lambda ( s-exp -- body vars ) +: split-lambda ( cons -- body vars ) first3 -rot nip [ body>> ] bi@ [ name>> ] map ; inline : rest-lambda ( body vars -- quot ) @@ -53,11 +56,11 @@ DEFER: looku-macro localize-lambda '[ , compose ] ; PRIVATE> -: convert-lambda ( s-exp -- quot ) +: convert-lambda ( cons -- quot ) split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ; -: convert-quoted ( s-exp -- quot ) - second 1quotation ; +: convert-quoted ( cons -- quot ) + cdr>> 1quotation ; : form-dispatch ( lisp-symbol -- quot ) name>> @@ -69,20 +72,21 @@ PRIVATE> [ drop convert-general-form ] } case ; -: macro-expand ( s-exp -- quot ) - unclip-slice lookup-macro macro-call convert-form ; +: macro-expand ( cons -- quot ) + uncons lookup-macro macro-call convert-form ; -: convert-list-form ( s-exp -- quot ) - dup first +: convert-list-form ( cons -- quot ) + dup car>> { { [ dup lisp-macro? ] [ macro-expand ] } { [ dup lisp-symbol? ] [ form-dispatch ] } [ drop convert-general-form ] } cond ; : convert-form ( lisp-form -- quot ) - { { [ dup s-exp? ] [ body>> convert-list-form ] } - { [ dup lisp-symbol? ] [ '[ , lookup-var ] ] } - [ 1quotation ] + { + { [ dup cons? ] [ convert-list-form ] } + { [ dup lisp-symbol? ] [ '[ , lookup-var ] ] } + [ 1quotation ] } cond ; : lisp-string>factor ( str -- quot ) From e6a4802ff858438e33cf5d53632d587ba267fd16 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Mon, 2 Jun 2008 01:33:54 -0300 Subject: [PATCH 0016/1850] irc.client: Some fixes and improvments, more tests --- extra/irc/client/client-tests.factor | 59 ++++++++++++++++++---------- extra/irc/client/client.factor | 19 ++++++--- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor index d274f3a6b1..9916621d47 100644 --- a/extra/irc/client/client-tests.factor +++ b/extra/irc/client/client-tests.factor @@ -1,36 +1,55 @@ -USING: kernel ; -IN: -irc.client.private -: me? ( string -- ? ) - "factorbot" = ; - -USING: irc.client irc.client.private kernel tools.test accessors arrays ; +USING: kernel tools.test accessors arrays sequences qualified + io.streams.string io.streams.duplex namespaces + irc.client.private ; +EXCLUDE: irc.client => join ; IN: irc.client.tests +! Utilities +: ( lines -- stream ) + "\n" join ; + +: make-client ( lines -- irc-client ) + "someserver" irc-port "factorbot" f + swap [ 2nip f ] curry >>connect ; + +: with-dummy-client ( quot -- ) + rot with-variable ; inline + +! Parsing tests irc-message new ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line "someuser!n=user@some.where" >>prefix - "PRIVMSG" >>command - { "#factortest" } >>parameters - "hi" >>trailing 1array + "PRIVMSG" >>command + { "#factortest" } >>parameters + "hi" >>trailing +1array [ ":someuser!n=user@some.where PRIVMSG #factortest :hi" string>irc-message f >>timestamp ] unit-test privmsg new ":someuser!n=user@some.where PRIVMSG #factortest :hi" >>line "someuser!n=user@some.where" >>prefix - "PRIVMSG" >>command - { "#factortest" } >>parameters - "hi" >>trailing - "#factortest" >>name 1array + "PRIVMSG" >>command + { "#factortest" } >>parameters + "hi" >>trailing + "#factortest" >>name +1array [ ":someuser!n=user@some.where PRIVMSG #factortest :hi" parse-irc-line f >>timestamp ] unit-test -{ "someuser" } [ "someuser!n=user@some.where" - parse-name ] unit-test +{ "" } make-client dup nick>> "factorbot" >>name drop current-irc-client [ + { t } [ irc-client> nick>> name>> me? ] unit-test -{ "#factortest" } [ ":someuser!n=user@some.where PRIVMSG #factortest :hi" - parse-irc-line irc-message-origin ] unit-test + { "factorbot" } [ irc-client> nick>> name>> ] unit-test -{ "someuser" } [ ":someuser!n=user@some.where PRIVMSG factorbot :hi" - parse-irc-line irc-message-origin ] unit-test + { "someuser" } [ "someuser!n=user@some.where" parse-name ] unit-test + + { "#factortest" } [ ":someuser!n=user@some.where PRIVMSG #factortest :hi" + parse-irc-line irc-message-origin ] unit-test + + { "someuser" } [ ":someuser!n=user@some.where PRIVMSG factorbot :hi" + parse-irc-line irc-message-origin ] unit-test +] with-variable + +! Client tests +{ } [ { "" } make-client connect-irc ] unit-test \ No newline at end of file diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 5247f135fc..5c9469ddd5 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -3,7 +3,7 @@ USING: arrays combinators concurrency.mailboxes concurrency.futures io io.encodings.8-bit io.sockets kernel namespaces sequences sequences.lib splitting threads calendar classes.tuple - classes ascii assocs accessors destructors ; + classes ascii assocs accessors destructors continuations ; IN: irc.client ! ====================================== @@ -26,10 +26,11 @@ TUPLE: nick name channels log ; C: nick TUPLE: irc-client profile nick stream in-messages out-messages join-messages - listeners is-running ; + listeners is-running connect ; : ( profile -- irc-client ) f V{ } clone V{ } clone - f H{ } clone f irc-client boa ; + f H{ } clone f + [ latin1 ] irc-client boa ; TUPLE: irc-listener in-messages out-messages ; : ( -- irc-listener ) @@ -79,7 +80,7 @@ TUPLE: unhandled < irc-message ; " hostname servername :irc.factor" irc-print ; : /CONNECT ( server port -- stream ) - latin1 drop ; + irc-client> connect>> call drop ; : /JOIN ( channel password -- ) "JOIN " irc-write @@ -183,6 +184,9 @@ M: privmsg handle-incoming-irc ( privmsg -- ) M: join handle-incoming-irc ( join -- ) irc-client> join-messages>> mailbox-put ; +M: irc-end handle-incoming-irc ( irc-end -- ) + irc-client> listeners>> values [ in-messages>> mailbox-put ] with each ; + ! ====================================== ! Client message handling ! ====================================== @@ -196,6 +200,9 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) ! Reader/Writer ! ====================================== +: irc-mailbox-get ( mailbox quot -- ) + swap 5 seconds [ mailbox-get-timeout swap call ] 3curry [ drop ] recover ; + : stream-readln-or-close ( stream -- str/f ) dup stream-readln [ nip ] [ dispose f ] if* ; @@ -213,14 +220,14 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) ] if* ; : writer-loop ( -- ) - irc-client> out-messages>> mailbox-get handle-outgoing-irc ; + irc-client> out-messages>> [ handle-outgoing-irc ] irc-mailbox-get ; ! ====================================== ! Processing loops ! ====================================== : in-multiplexer-loop ( -- ) - irc-client> in-messages>> mailbox-get handle-incoming-irc ; + irc-client> in-messages>> [ handle-incoming-irc ] irc-mailbox-get ; : maybe-annotate-with-name ( name obj -- obj ) dup privmsg instance? [ swap >>name ] [ nip ] if ; From c65e299e8c9bbe2d460203e4fd38219333f286cc Mon Sep 17 00:00:00 2001 From: James Cash Date: Mon, 2 Jun 2008 01:26:10 -0400 Subject: [PATCH 0017/1850] Moving cons stuff into its own sub-vocab --- extra/lisp/conses/authors.txt | 1 + extra/lisp/conses/conses-docs.factor | 0 extra/lisp/conses/conses-tests.factor | 13 +++++++++++++ extra/lisp/conses/conses.factor | 26 ++++++++++++++++++++++++++ extra/lisp/conses/summary.txt | 1 + extra/lisp/conses/tags.txt | 4 ++++ extra/lisp/lisp.factor | 5 +---- extra/lisp/parser/parser-tests.factor | 2 +- extra/lisp/parser/parser.factor | 11 +---------- 9 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 extra/lisp/conses/authors.txt create mode 100644 extra/lisp/conses/conses-docs.factor create mode 100644 extra/lisp/conses/conses-tests.factor create mode 100644 extra/lisp/conses/conses.factor create mode 100644 extra/lisp/conses/summary.txt create mode 100644 extra/lisp/conses/tags.txt diff --git a/extra/lisp/conses/authors.txt b/extra/lisp/conses/authors.txt new file mode 100644 index 0000000000..4b7af4aac0 --- /dev/null +++ b/extra/lisp/conses/authors.txt @@ -0,0 +1 @@ +James Cash diff --git a/extra/lisp/conses/conses-docs.factor b/extra/lisp/conses/conses-docs.factor new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extra/lisp/conses/conses-tests.factor b/extra/lisp/conses/conses-tests.factor new file mode 100644 index 0000000000..e4288a2e11 --- /dev/null +++ b/extra/lisp/conses/conses-tests.factor @@ -0,0 +1,13 @@ +! Copyright (C) 2008 James Cash +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test lisp.conses math ; + +IN: lisp.conses.tests + +{ { 3 4 5 6 } } [ + T{ cons f 1 + T{ cons f 2 + T{ cons f 3 + T{ cons f 4 + T{ cons f f f } } } } } [ 2 + ] map-cons +] unit-test \ No newline at end of file diff --git a/extra/lisp/conses/conses.factor b/extra/lisp/conses/conses.factor new file mode 100644 index 0000000000..3fdbc25b0e --- /dev/null +++ b/extra/lisp/conses/conses.factor @@ -0,0 +1,26 @@ +! Copyright (C) 2008 James Cash +! See http://factorcode.org/license.txt for BSD license. +USING: kernel sequences accessors ; + +IN: lisp.conses + +TUPLE: cons car cdr ; +: cons \ cons new ; + +: uncons ( cons -- cdr car ) + [ cdr>> ] [ car>> ] bi ; + +: null? ( cons -- ? ) + uncons and not ; + +: ( x -- cons ) + cons swap >>car ; + +: seq>cons ( seq -- cons ) + cons [ swap >>cdr ] reduce ; + +: (map-cons) ( acc cons quot -- seq ) + over null? [ 2drop ] [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; + +: map-cons ( cons quot -- seq ) + [ { } clone ] 2dip (map-cons) ; \ No newline at end of file diff --git a/extra/lisp/conses/summary.txt b/extra/lisp/conses/summary.txt new file mode 100644 index 0000000000..d69b63b233 --- /dev/null +++ b/extra/lisp/conses/summary.txt @@ -0,0 +1 @@ +Cons cell helper functions for extra/lisp diff --git a/extra/lisp/conses/tags.txt b/extra/lisp/conses/tags.txt new file mode 100644 index 0000000000..a3f9681acb --- /dev/null +++ b/extra/lisp/conses/tags.txt @@ -0,0 +1,4 @@ +lisp +cons +lists +sequences diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 59b0ccdff2..3d977df97f 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -3,12 +3,9 @@ USING: kernel peg sequences arrays strings combinators.lib namespaces combinators math locals locals.private accessors vectors syntax lisp.parser assocs parser sequences.lib words quotations -fry ; +fry lisp.conses ; IN: lisp -: uncons ( cons -- cdr car ) - [ cdr>> ] [ car>> ] bi ; - DEFER: convert-form DEFER: funcall DEFER: lookup-var diff --git a/extra/lisp/parser/parser-tests.factor b/extra/lisp/parser/parser-tests.factor index 712a1f9b9e..9c33f635f9 100644 --- a/extra/lisp/parser/parser-tests.factor +++ b/extra/lisp/parser/parser-tests.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: lisp.parser tools.test peg peg.ebnf ; +USING: lisp.parser tools.test peg peg.ebnf lisp.conses ; IN: lisp.parser.tests diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor index dad6a7dc24..9679c77209 100644 --- a/extra/lisp/parser/parser.factor +++ b/extra/lisp/parser/parser.factor @@ -1,22 +1,13 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. USING: kernel peg peg.ebnf peg.expr math.parser sequences arrays strings -combinators.lib math fry accessors ; +combinators.lib math fry accessors lisp.conses ; IN: lisp.parser TUPLE: lisp-symbol name ; C: lisp-symbol -TUPLE: cons car cdr ; -: cons \ cons new ; - -: ( x -- cons ) - cons swap >>car ; - -: seq>cons ( seq -- cons ) - cons [ swap >>cdr ] reduce ; - EBNF: lisp-expr _ = (" " | "\t" | "\n")* LPAREN = "(" From 25fa0248987861d33a00c0f1bbdc6bc9fc0a38ef Mon Sep 17 00:00:00 2001 From: James Cash Date: Mon, 2 Jun 2008 14:13:48 -0400 Subject: [PATCH 0018/1850] Reduce for conses --- extra/lisp/conses/conses.factor | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/extra/lisp/conses/conses.factor b/extra/lisp/conses/conses.factor index 3fdbc25b0e..c715ac890a 100644 --- a/extra/lisp/conses/conses.factor +++ b/extra/lisp/conses/conses.factor @@ -20,7 +20,12 @@ TUPLE: cons car cdr ; cons [ swap >>cdr ] reduce ; : (map-cons) ( acc cons quot -- seq ) - over null? [ 2drop ] [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; + over null? [ 2drop ] + [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; : map-cons ( cons quot -- seq ) - [ { } clone ] 2dip (map-cons) ; \ No newline at end of file + [ { } clone ] 2dip (map-cons) ; + +: reduce-cons ( cons identity quot -- result ) + pick null? [ drop nip ] + [ [ uncons ] 2dip swapd [ call ] keep reduce-cons ] if ; \ No newline at end of file From b974133285990ffb7ffc9e427c3503bc08b42281 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 3 Jun 2008 11:01:04 +1200 Subject: [PATCH 0019/1850] Re-add jni library to unmaintained --- unmaintained/jni/jni-internals.factor | 357 ++++++++++++++++++++++++++ unmaintained/jni/jni.factor | 22 ++ unmaintained/jni/load.factor | 4 + 3 files changed, 383 insertions(+) create mode 100644 unmaintained/jni/jni-internals.factor create mode 100644 unmaintained/jni/jni.factor create mode 100644 unmaintained/jni/load.factor diff --git a/unmaintained/jni/jni-internals.factor b/unmaintained/jni/jni-internals.factor new file mode 100644 index 0000000000..49bc57b108 --- /dev/null +++ b/unmaintained/jni/jni-internals.factor @@ -0,0 +1,357 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +IN: jni-internals +USING: kernel alien arrays sequences ; + +LIBRARY: jvm + +TYPEDEF: int jint +TYPEDEF: uchar jboolean +TYPEDEF: void* JNIEnv + +C-STRUCT: jdk-init-args + { "jint" "version" } + { "void*" "properties" } + { "jint" "check-source" } + { "jint" "native-stack-size" } + { "jint" "java-stack-size" } + { "jint" "min-heap-size" } + { "jint" "max-heap-size" } + { "jint" "verify-mode" } + { "char*" "classpath" } + { "void*" "vprintf" } + { "void*" "exit" } + { "void*" "abort" } + { "jint" "enable-class-gc" } + { "jint" "enable-verbose-gc" } + { "jint" "disable-async-gc" } + { "jint" "verbose" } + { "jboolean" "debugging" } + { "jint" "debug-port" } ; + +C-STRUCT: JNIInvokeInterface + { "void*" "reserved0" } + { "void*" "reserved1" } + { "void*" "reserved2" } + { "void*" "DestroyJavaVM" } + { "void*" "AttachCurrentThread" } + { "void*" "DetachCurrentThread" } + { "void*" "GetEnv" } + { "void*" "AttachCurrentThreadAsDaemon" } ; + +C-STRUCT: JavaVM + { "JNIInvokeInterface*" "functions" } ; + +C-STRUCT: JNINativeInterface + { "void*" "reserved0" } + { "void*" "reserved1" } + { "void*" "reserved2" } + { "void*" "reserved3" } + { "void*" "GetVersion" } + { "void*" "DefineClass" } + { "void*" "FindClass" } + { "void*" "FromReflectedMethod" } + { "void*" "FromReflectedField" } + { "void*" "ToReflectedMethod" } + { "void*" "GetSuperclass" } + { "void*" "IsAssignableFrom" } + { "void*" "ToReflectedField" } + { "void*" "Throw" } + { "void*" "ThrowNew" } + { "void*" "ExceptionOccurred" } + { "void*" "ExceptionDescribe" } + { "void*" "ExceptionClear" } + { "void*" "FatalError" } + { "void*" "PushLocalFrame" } + { "void*" "PopLocalFrame" } + { "void*" "NewGlobalRef" } + { "void*" "DeleteGlobalRef" } + { "void*" "DeleteLocalRef" } + { "void*" "IsSameObject" } + { "void*" "NewLocalRef" } + { "void*" "EnsureLocalCapacity" } + { "void*" "AllocObject" } + { "void*" "NewObject" } + { "void*" "NewObjectV" } + { "void*" "NewObjectA" } + { "void*" "GetObjectClass" } + { "void*" "IsInstanceOf" } + { "void*" "GetMethodID" } + { "void*" "CallObjectMethod" } + { "void*" "CallObjectMethodV" } + { "void*" "CallObjectMethodA" } + { "void*" "CallBooleanMethod" } + { "void*" "CallBooleanMethodV" } + { "void*" "CallBooleanMethodA" } + { "void*" "CallByteMethod" } + { "void*" "CallByteMethodV" } + { "void*" "CallByteMethodA" } + { "void*" "CallCharMethod" } + { "void*" "CallCharMethodV" } + { "void*" "CallCharMethodA" } + { "void*" "CallShortMethod" } + { "void*" "CallShortMethodV" } + { "void*" "CallShortMethodA" } + { "void*" "CallIntMethod" } + { "void*" "CallIntMethodV" } + { "void*" "CallIntMethodA" } + { "void*" "CallLongMethod" } + { "void*" "CallLongMethodV" } + { "void*" "CallLongMethodA" } + { "void*" "CallFloatMethod" } + { "void*" "CallFloatMethodV" } + { "void*" "CallFloatMethodA" } + { "void*" "CallDoubleMethod" } + { "void*" "CallDoubleMethodV" } + { "void*" "CallDoubleMethodA" } + { "void*" "CallVoidMethod" } + { "void*" "CallVoidMethodV" } + { "void*" "CallVoidMethodA" } + { "void*" "CallNonvirtualObjectMethod" } + { "void*" "CallNonvirtualObjectMethodV" } + { "void*" "CallNonvirtualObjectMethodA" } + { "void*" "CallNonvirtualBooleanMethod" } + { "void*" "CallNonvirtualBooleanMethodV" } + { "void*" "CallNonvirtualBooleanMethodA" } + { "void*" "CallNonvirtualByteMethod" } + { "void*" "CallNonvirtualByteMethodV" } + { "void*" "CallNonvirtualByteMethodA" } + { "void*" "CallNonvirtualCharMethod" } + { "void*" "CallNonvirtualCharMethodV" } + { "void*" "CallNonvirtualCharMethodA" } + { "void*" "CallNonvirtualShortMethod" } + { "void*" "CallNonvirtualShortMethodV" } + { "void*" "CallNonvirtualShortMethodA" } + { "void*" "CallNonvirtualIntMethod" } + { "void*" "CallNonvirtualIntMethodV" } + { "void*" "CallNonvirtualIntMethodA" } + { "void*" "CallNonvirtualLongMethod" } + { "void*" "CallNonvirtualLongMethodV" } + { "void*" "CallNonvirtualLongMethodA" } + { "void*" "CallNonvirtualFloatMethod" } + { "void*" "CallNonvirtualFloatMethodV" } + { "void*" "CallNonvirtualFloatMethodA" } + { "void*" "CallNonvirtualDoubleMethod" } + { "void*" "CallNonvirtualDoubleMethodV" } + { "void*" "CallNonvirtualDoubleMethodA" } + { "void*" "CallNonvirtualVoidMethod" } + { "void*" "CallNonvirtualVoidMethodV" } + { "void*" "CallNonvirtualVoidMethodA" } + { "void*" "GetFieldID" } + { "void*" "GetObjectField" } + { "void*" "GetBooleanField" } + { "void*" "GetByteField" } + { "void*" "GetCharField" } + { "void*" "GetShortField" } + { "void*" "GetIntField" } + { "void*" "GetLongField" } + { "void*" "GetFloatField" } + { "void*" "GetDoubleField" } + { "void*" "SetObjectField" } + { "void*" "SetBooleanField" } + { "void*" "SetByteField" } + { "void*" "SetCharField" } + { "void*" "SetShortField" } + { "void*" "SetIntField" } + { "void*" "SetLongField" } + { "void*" "SetFloatField" } + { "void*" "SetDoubleField" } + { "void*" "GetStaticMethodID" } + { "void*" "CallStaticObjectMethod" } + { "void*" "CallStaticObjectMethodV" } + { "void*" "CallStaticObjectMethodA" } + { "void*" "CallStaticBooleanMethod" } + { "void*" "CallStaticBooleanMethodV" } + { "void*" "CallStaticBooleanMethodA" } + { "void*" "CallStaticByteMethod" } + { "void*" "CallStaticByteMethodV" } + { "void*" "CallStaticByteMethodA" } + { "void*" "CallStaticCharMethod" } + { "void*" "CallStaticCharMethodV" } + { "void*" "CallStaticCharMethodA" } + { "void*" "CallStaticShortMethod" } + { "void*" "CallStaticShortMethodV" } + { "void*" "CallStaticShortMethodA" } + { "void*" "CallStaticIntMethod" } + { "void*" "CallStaticIntMethodV" } + { "void*" "CallStaticIntMethodA" } + { "void*" "CallStaticLongMethod" } + { "void*" "CallStaticLongMethodV" } + { "void*" "CallStaticLongMethodA" } + { "void*" "CallStaticFloatMethod" } + { "void*" "CallStaticFloatMethodV" } + { "void*" "CallStaticFloatMethodA" } + { "void*" "CallStaticDoubleMethod" } + { "void*" "CallStaticDoubleMethodV" } + { "void*" "CallStaticDoubleMethodA" } + { "void*" "CallStaticVoidMethod" } + { "void*" "CallStaticVoidMethodV" } + { "void*" "CallStaticVoidMethodA" } + { "void*" "GetStaticFieldID" } + { "void*" "GetStaticObjectField" } + { "void*" "GetStaticBooleanField" } + { "void*" "GetStaticByteField" } + { "void*" "GetStaticCharField" } + { "void*" "GetStaticShortField" } + { "void*" "GetStaticIntField" } + { "void*" "GetStaticLongField" } + { "void*" "GetStaticFloatField" } + { "void*" "GetStaticDoubleField" } + { "void*" "SetStaticObjectField" } + { "void*" "SetStaticBooleanField" } + { "void*" "SetStaticByteField" } + { "void*" "SetStaticCharField" } + { "void*" "SetStaticShortField" } + { "void*" "SetStaticIntField" } + { "void*" "SetStaticLongField" } + { "void*" "SetStaticFloatField" } + { "void*" "SetStaticDoubleField" } + { "void*" "NewString" } + { "void*" "GetStringLength" } + { "void*" "GetStringChars" } + { "void*" "ReleaseStringChars" } + { "void*" "NewStringUTF" } + { "void*" "GetStringUTFLength" } + { "void*" "GetStringUTFChars" } + { "void*" "ReleaseStringUTFChars" } + { "void*" "GetArrayLength" } + { "void*" "NewObjectArray" } + { "void*" "GetObjectArrayElement" } + { "void*" "SetObjectArrayElement" } + { "void*" "NewBooleanArray" } + { "void*" "NewByteArray" } + { "void*" "NewCharArray" } + { "void*" "NewShortArray" } + { "void*" "NewIntArray" } + { "void*" "NewLongArray" } + { "void*" "NewFloatArray" } + { "void*" "NewDoubleArray" } + { "void*" "GetBooleanArrayElements" } + { "void*" "GetByteArrayElements" } + { "void*" "GetCharArrayElements" } + { "void*" "GetShortArrayElements" } + { "void*" "GetIntArrayElements" } + { "void*" "GetLongArrayElements" } + { "void*" "GetFloatArrayElements" } + { "void*" "GetDoubleArrayElements" } + { "void*" "ReleaseBooleanArrayElements" } + { "void*" "ReleaseByteArrayElements" } + { "void*" "ReleaseCharArrayElements" } + { "void*" "ReleaseShortArrayElements" } + { "void*" "ReleaseIntArrayElements" } + { "void*" "ReleaseLongArrayElements" } + { "void*" "ReleaseFloatArrayElements" } + { "void*" "ReleaseDoubleArrayElements" } + { "void*" "GetBooleanArrayRegion" } + { "void*" "GetByteArrayRegion" } + { "void*" "GetCharArrayRegion" } + { "void*" "GetShortArrayRegion" } + { "void*" "GetIntArrayRegion" } + { "void*" "GetLongArrayRegion" } + { "void*" "GetFloatArrayRegion" } + { "void*" "GetDoubleArrayRegion" } + { "void*" "SetBooleanArrayRegion" } + { "void*" "SetByteArrayRegion" } + { "void*" "SetCharArrayRegion" } + { "void*" "SetShortArrayRegion" } + { "void*" "SetIntArrayRegion" } + { "void*" "SetLongArrayRegion" } + { "void*" "SetFloatArrayRegion" } + { "void*" "SetDoubleArrayRegion" } + { "void*" "RegisterNatives" } + { "void*" "UnregisterNatives" } + { "void*" "MonitorEnter" } + { "void*" "MonitorExit" } + { "void*" "GetJavaVM" } + { "void*" "GetStringRegion" } + { "void*" "GetStringUTFRegion" } + { "void*" "GetPrimitiveArrayCritical" } + { "void*" "ReleasePrimitiveArrayCritical" } + { "void*" "GetStringCritical" } + { "void*" "ReleaseStringCritical" } + { "void*" "NewWeakGlobalRef" } + { "void*" "DeleteWeakGlobalRef" } + { "void*" "ExceptionCheck" } + { "void*" "NewDirectByteBuffer" } + { "void*" "GetDirectBufferAddress" } + { "void*" "GetDirectBufferCapacity" } ; + +C-STRUCT: JNIEnv + { "JNINativeInterface*" "functions" } ; + +FUNCTION: jint JNI_GetDefaultJavaVMInitArgs ( jdk-init-args* args ) ; +FUNCTION: jint JNI_CreateJavaVM ( void** pvm, void** penv, void* args ) ; + +: ( -- jdk-init-args ) + "jdk-init-args" HEX: 00010004 over set-jdk-init-args-version ; + +: jni1 ( -- init-args int ) + dup JNI_GetDefaultJavaVMInitArgs ; + +: jni2 ( -- vm env int ) + f f [ + jni1 drop JNI_CreateJavaVM + ] 2keep rot dup 0 = [ + >r >r 0 swap void*-nth r> 0 swap void*-nth r> + ] when ; + +: (destroy-java-vm) + "int" { "void*" } "cdecl" alien-indirect ; + +: (attach-current-thread) + "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ; + +: (detach-current-thread) + "int" { "void*" } "cdecl" alien-indirect ; + +: (get-env) + "int" { "void*" "void*" "int" } "cdecl" alien-indirect ; + +: (attach-current-thread-as-daemon) + "int" { "void*" "void*" "void*" } "cdecl" alien-indirect ; + +: destroy-java-vm ( javavm -- int ) + dup JavaVM-functions JNIInvokeInterface-DestroyJavaVM (destroy-java-vm) ; + +: (get-version) + "jint" { "JNIEnv*" } "cdecl" alien-indirect ; + +: get-version ( jnienv -- int ) + dup JNIEnv-functions JNINativeInterface-GetVersion (get-version) ; + +: (find-class) + "void*" { "JNINativeInterface*" "char*" } "cdecl" alien-indirect ; + +: find-class ( name jnienv -- int ) + dup swapd JNIEnv-functions JNINativeInterface-FindClass (find-class) ; + +: (get-static-field-id) + "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ; + +: get-static-field-id ( class name sig jnienv -- int ) + dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetStaticFieldID (get-static-field-id) ; + +: (get-static-object-field) + "void*" { "JNINativeInterface*" "void*" "void*" } "cdecl" alien-indirect ; + +: get-static-object-field ( class id jnienv -- int ) + dup >r >r 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-GetStaticObjectField (get-static-object-field) ; + +: (get-method-id) + "void*" { "JNINativeInterface*" "void*" "char*" "char*" } "cdecl" alien-indirect ; + +: get-method-id ( class name sig jnienv -- int ) + dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-GetMethodID (get-method-id) ; + +: (new-string) + "void*" { "JNINativeInterface*" "char*" "int" } "cdecl" alien-indirect ; + +: new-string ( str jnienv -- str ) + dup >r >r dup length 2array r> swap first2 r> JNIEnv-functions JNINativeInterface-NewString (new-string) ; + +: (call1) + "void" { "JNINativeInterface*" "void*" "void*" "int" } "cdecl" alien-indirect ; + +: call1 ( obj method-id jstr jnienv -- ) + dup >r >r 3array r> swap first3 r> JNIEnv-functions JNINativeInterface-CallObjectMethod (call1) ; + diff --git a/unmaintained/jni/jni.factor b/unmaintained/jni/jni.factor new file mode 100644 index 0000000000..86e1670c50 --- /dev/null +++ b/unmaintained/jni/jni.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +IN: jni +USING: kernel jni-internals namespaces ; + +! High level interface for JNI to be added here... + +: test0 ( -- ) + jni2 drop nip "env" set ; + +: test1 ( -- system ) + "java/lang/System" "env" get find-class ; + +: test2 ( system -- system.out ) + dup "out" "Ljava/io/PrintStream;" "env" get get-static-field-id + "env" get get-static-object-field ; + +: test3 ( int system.out -- ) + "java/io/PrintStream" "env" get find-class ! jstr out class + "println" "(I)V" "env" get get-method-id ! jstr out id + rot "env" get call1 ; + \ No newline at end of file diff --git a/unmaintained/jni/load.factor b/unmaintained/jni/load.factor new file mode 100644 index 0000000000..f5fd45c8d9 --- /dev/null +++ b/unmaintained/jni/load.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +PROVIDE: libs/jni +{ +files+ { "jni-internals.factor" "jni.factor" } } ; From b5279bde62b4e7b82016a19e9a81432ef8f2fed8 Mon Sep 17 00:00:00 2001 From: Matthew Willis Date: Mon, 2 Jun 2008 16:11:41 -0700 Subject: [PATCH 0020/1850] implemented texture caching for pango-gadgets --- extra/cairo/gadgets/gadgets.factor | 6 +- extra/opengl/gadgets/gadgets.factor | 8 ++- extra/pango/cairo/cairo.factor | 3 + extra/pango/cairo/gadgets/gadgets.factor | 72 ++++++++++++++++-------- extra/pango/cairo/samples/samples.factor | 23 ++++++++ 5 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 extra/pango/cairo/samples/samples.factor diff --git a/extra/cairo/gadgets/gadgets.factor b/extra/cairo/gadgets/gadgets.factor index 69252f8303..b42c47d79b 100644 --- a/extra/cairo/gadgets/gadgets.factor +++ b/extra/cairo/gadgets/gadgets.factor @@ -22,8 +22,10 @@ TUPLE: cairo-gadget < texture-gadget quot ; swap >>quot swap >>dim ; -M: cairo-gadget graft* ( gadget -- ) - GL_BGRA >>format dup +M: cairo-gadget format>> drop GL_BGRA ; + +M: cairo-gadget render* ( gadget -- ) + dup [ dim>> 2^-bounds ] [ quot>> copy-cairo ] bi >>bytes call-next-method ; diff --git a/extra/opengl/gadgets/gadgets.factor b/extra/opengl/gadgets/gadgets.factor index 1a15283048..de37969220 100644 --- a/extra/opengl/gadgets/gadgets.factor +++ b/extra/opengl/gadgets/gadgets.factor @@ -19,7 +19,9 @@ TUPLE: texture-gadget bytes format dim tex ; swap >>format swap >>bytes ; -:: render ( gadget -- ) +GENERIC: render* ( texture-gadget -- ) + +M:: texture-gadget render* ( gadget -- ) GL_ENABLE_BIT [ GL_TEXTURE_2D glEnable GL_TEXTURE_2D gadget tex>> glBindTexture @@ -63,8 +65,8 @@ M: texture-gadget draw-gadget* ( gadget -- ) ] with-translation ; M: texture-gadget graft* ( gadget -- ) - gen-texture >>tex [ render ] - [ f >>bytes f >>format drop ] bi ; + gen-texture >>tex [ render* ] + [ f >>bytes drop ] bi ; M: texture-gadget ungraft* ( gadget -- ) tex>> delete-texture ; diff --git a/extra/pango/cairo/cairo.factor b/extra/pango/cairo/cairo.factor index 907233a335..d1b536d9bc 100644 --- a/extra/pango/cairo/cairo.factor +++ b/extra/pango/cairo/cairo.factor @@ -130,5 +130,8 @@ MEMO: dummy-cairo ( -- cr ) : layout-text ( str -- ) layout swap -1 pango_layout_set_text ; +: show-layout ( -- ) + cr layout pango_cairo_show_layout ; + : families ( -- families ) pango_cairo_font_map_get_default list-families ; diff --git a/extra/pango/cairo/gadgets/gadgets.factor b/extra/pango/cairo/gadgets/gadgets.factor index 9e8a99515e..fb021e9320 100644 --- a/extra/pango/cairo/gadgets/gadgets.factor +++ b/extra/pango/cairo/gadgets/gadgets.factor @@ -1,30 +1,58 @@ ! Copyright (C) 2008 Matthew Willis. ! See http://factorcode.org/license.txt for BSD license. -USING: pango.cairo cairo cairo.ffi cairo.gadgets +USING: pango.cairo cairo cairo.ffi +cairo.gadgets namespaces arrays +fry accessors ui.gadgets assocs +sequences shuffle opengl opengl.gadgets alien.c-types kernel math ; IN: pango.cairo.gadgets -: (pango-gadget) ( setup show -- gadget ) - [ drop layout-size ] - [ compose [ with-pango ] curry ] 2bi ; +SYMBOL: textures +SYMBOL: dims +SYMBOL: refcounts -: ( quot -- gadget ) - [ cr layout pango_cairo_show_layout ] (pango-gadget) ; +: init-cache ( symbol -- ) + dup get [ drop ] [ H{ } clone swap set-global ] if ; -USING: prettyprint sequences ui.gadgets.panes -threads io.backend io.encodings.utf8 io.files ; -: hello-pango ( -- ) - 50 [ 6 + ] map [ - "Sans " swap unparse append - [ - cr 0 1 0.2 0.6 cairo_set_source_rgba - layout-font "今日ã¯ã€ Pango!" layout-text - ] curry - gadget. yield - ] each - [ - "resource:extra/pango/cairo/gadgets/gadgets.factor" - normalize-path utf8 file-contents layout-text - ] gadget. ; +textures init-cache +dims init-cache +refcounts init-cache -MAIN: hello-pango +TUPLE: pango-gadget < cairo-gadget text font ; + +: cache-key ( gadget -- key ) + [ font>> ] [ text>> ] bi 2array ; + +: refcount-change ( gadget quot -- ) + >r cache-key refcounts get + [ [ 0 ] unless* ] r> compose change-at ; + +: ( font text -- gadget ) + pango-gadget construct-gadget + swap >>text + swap >>font ; + +: setup-layout ( {font,text} -- quot ) + first2 '[ , layout-font , layout-text ] ; + +M: pango-gadget quot>> ( gadget -- quot ) + cache-key setup-layout [ show-layout ] compose + [ with-pango ] curry ; + +M: pango-gadget dim>> ( gadget -- dim ) + cache-key dims get [ setup-layout layout-size ] cache ; + +M: pango-gadget graft* ( gadget -- ) [ 1+ ] refcount-change ; + +M: pango-gadget ungraft* ( gadget -- ) [ 1- ] refcount-change ; + +M: pango-gadget render* ( gadget -- ) + [ gen-texture ] [ cache-key textures get set-at ] + [ call-next-method ] tri ; + +M: pango-gadget tex>> ( gadget -- texture ) + dup cache-key textures get at + [ ] [ render* tex>> ] ?if ; + +USE: ui.gadgets.panes +: hello "Sans 50" "hello" gadget. ; diff --git a/extra/pango/cairo/samples/samples.factor b/extra/pango/cairo/samples/samples.factor new file mode 100644 index 0000000000..644d731d70 --- /dev/null +++ b/extra/pango/cairo/samples/samples.factor @@ -0,0 +1,23 @@ +! Copyright (C) 2008 Matthew Willis. +! See http://factorcode.org/license.txt for BSD license. +USING: prettyprint sequences ui.gadgets.panes +pango.cairo.gadgets math kernel cairo cairo.ffi +pango.cairo tools.time namespaces assocs +threads io.backend io.encodings.utf8 io.files ; + +IN: pango.cairo.samples + +: hello-pango ( -- ) + "monospace 10" "resource:extra/pango/cairo/gadgets/gadgets.factor" + normalize-path utf8 file-contents + gadget. ; + +: time-pango ( -- ) + [ hello-pango ] time ; + +! clear the caches, for testing. +: clear-pango ( -- ) + dims get clear-assoc + textures get clear-assoc ; + +MAIN: time-pango From 79a120d770a928b52a330c461054f75abfe6aca8 Mon Sep 17 00:00:00 2001 From: Matthew Willis Date: Mon, 2 Jun 2008 16:31:32 -0700 Subject: [PATCH 0021/1850] fix bugs and also destroy textures whose refcounts are 0 on ungraft* --- extra/pango/cairo/gadgets/gadgets.factor | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/extra/pango/cairo/gadgets/gadgets.factor b/extra/pango/cairo/gadgets/gadgets.factor index fb021e9320..4c46b4e501 100644 --- a/extra/pango/cairo/gadgets/gadgets.factor +++ b/extra/pango/cairo/gadgets/gadgets.factor @@ -44,15 +44,21 @@ M: pango-gadget dim>> ( gadget -- dim ) M: pango-gadget graft* ( gadget -- ) [ 1+ ] refcount-change ; -M: pango-gadget ungraft* ( gadget -- ) [ 1- ] refcount-change ; +: release-texture ( gadget -- ) + cache-key textures get delete-at* [ delete-texture ] [ drop ] if ; + +M: pango-gadget ungraft* ( gadget -- ) + dup [ 1- ] refcount-change + dup cache-key refcounts get at + zero? [ release-texture ] [ drop ] if ; M: pango-gadget render* ( gadget -- ) - [ gen-texture ] [ cache-key textures get set-at ] - [ call-next-method ] tri ; + [ gen-texture ] [ cache-key textures get set-at ] bi + call-next-method ; M: pango-gadget tex>> ( gadget -- texture ) dup cache-key textures get at - [ ] [ render* tex>> ] ?if ; + [ nip ] [ dup render* tex>> ] if* ; USE: ui.gadgets.panes : hello "Sans 50" "hello" gadget. ; From d0edbccf67335762fcbca7b24d2feeba591787e3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 2 Jun 2008 21:59:23 -0500 Subject: [PATCH 0022/1850] Fix default main responder --- extra/http/server/server.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 02424ef974..756a0de0ff 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -22,7 +22,7 @@ C: trivial-responder M: trivial-responder call-responder* nip response>> clone ; -main-responder global [ <404> get-global or ] change-at +main-responder global [ <404> or ] change-at : invert-slice ( slice -- slice' ) dup slice? [ [ seq>> ] [ from>> ] bi head-slice ] [ drop { } ] if ; From cfc3381cabd9de8f82e0f1c519a52efdf5589dd9 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 01:27:06 -0400 Subject: [PATCH 0023/1850] Moving extra/lisp/conses to extra/lists --- extra/lisp/conses/summary.txt | 1 - extra/{lisp/conses => lists}/authors.txt | 0 .../conses-docs.factor => lists/lists-docs.factor} | 0 .../conses-tests.factor => lists/lists-tests.factor} | 12 ++++++++++-- .../conses/conses.factor => lists/lists.factor} | 5 ++++- extra/lists/summary.txt | 1 + extra/{lisp/conses => lists}/tags.txt | 1 - 7 files changed, 15 insertions(+), 5 deletions(-) delete mode 100644 extra/lisp/conses/summary.txt rename extra/{lisp/conses => lists}/authors.txt (100%) rename extra/{lisp/conses/conses-docs.factor => lists/lists-docs.factor} (100%) rename extra/{lisp/conses/conses-tests.factor => lists/lists-tests.factor} (52%) rename extra/{lisp/conses/conses.factor => lists/lists.factor} (84%) create mode 100644 extra/lists/summary.txt rename extra/{lisp/conses => lists}/tags.txt (80%) diff --git a/extra/lisp/conses/summary.txt b/extra/lisp/conses/summary.txt deleted file mode 100644 index d69b63b233..0000000000 --- a/extra/lisp/conses/summary.txt +++ /dev/null @@ -1 +0,0 @@ -Cons cell helper functions for extra/lisp diff --git a/extra/lisp/conses/authors.txt b/extra/lists/authors.txt similarity index 100% rename from extra/lisp/conses/authors.txt rename to extra/lists/authors.txt diff --git a/extra/lisp/conses/conses-docs.factor b/extra/lists/lists-docs.factor similarity index 100% rename from extra/lisp/conses/conses-docs.factor rename to extra/lists/lists-docs.factor diff --git a/extra/lisp/conses/conses-tests.factor b/extra/lists/lists-tests.factor similarity index 52% rename from extra/lisp/conses/conses-tests.factor rename to extra/lists/lists-tests.factor index e4288a2e11..41f2d1d356 100644 --- a/extra/lisp/conses/conses-tests.factor +++ b/extra/lists/lists-tests.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: tools.test lisp.conses math ; +USING: tools.test lists math ; -IN: lisp.conses.tests +IN: lists.tests { { 3 4 5 6 } } [ T{ cons f 1 @@ -10,4 +10,12 @@ IN: lisp.conses.tests T{ cons f 3 T{ cons f 4 T{ cons f f f } } } } } [ 2 + ] map-cons +] unit-test + +{ 10 } [ + T{ cons f 1 + T{ cons f 2 + T{ cons f 3 + T{ cons f 4 + T{ cons f f f } } } } } 0 [ + ] reduce-cons ] unit-test \ No newline at end of file diff --git a/extra/lisp/conses/conses.factor b/extra/lists/lists.factor similarity index 84% rename from extra/lisp/conses/conses.factor rename to extra/lists/lists.factor index c715ac890a..da26580305 100644 --- a/extra/lisp/conses/conses.factor +++ b/extra/lists/lists.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences accessors ; -IN: lisp.conses +IN: lists TUPLE: cons car cdr ; : cons \ cons new ; @@ -26,6 +26,9 @@ TUPLE: cons car cdr ; : map-cons ( cons quot -- seq ) [ { } clone ] 2dip (map-cons) ; +: cons>seq ( cons -- array ) + [ ] map-cons ; + : reduce-cons ( cons identity quot -- result ) pick null? [ drop nip ] [ [ uncons ] 2dip swapd [ call ] keep reduce-cons ] if ; \ No newline at end of file diff --git a/extra/lists/summary.txt b/extra/lists/summary.txt new file mode 100644 index 0000000000..60a18867ab --- /dev/null +++ b/extra/lists/summary.txt @@ -0,0 +1 @@ +Implementation of lisp-style linked lists diff --git a/extra/lisp/conses/tags.txt b/extra/lists/tags.txt similarity index 80% rename from extra/lisp/conses/tags.txt rename to extra/lists/tags.txt index a3f9681acb..e44334b2b5 100644 --- a/extra/lisp/conses/tags.txt +++ b/extra/lists/tags.txt @@ -1,4 +1,3 @@ -lisp cons lists sequences From 5361928f15a59da43e09ec843ddfc219778d6fa5 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 03:38:56 -0400 Subject: [PATCH 0024/1850] Refactoring lazy-lists to use new accessors --- extra/lazy-lists/lazy-lists-docs.factor | 2 +- extra/lazy-lists/lazy-lists-tests.factor | 2 +- extra/lazy-lists/lazy-lists.factor | 155 +++++++++-------------- extra/lists/lists.factor | 48 +++++-- 4 files changed, 97 insertions(+), 110 deletions(-) diff --git a/extra/lazy-lists/lazy-lists-docs.factor b/extra/lazy-lists/lazy-lists-docs.factor index b240b3fbc2..fb87bee10f 100644 --- a/extra/lazy-lists/lazy-lists-docs.factor +++ b/extra/lazy-lists/lazy-lists-docs.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: help.markup help.syntax sequences strings ; +USING: help.markup help.syntax sequences strings lists ; IN: lazy-lists { car cons cdr nil nil? list? uncons } related-words diff --git a/extra/lazy-lists/lazy-lists-tests.factor b/extra/lazy-lists/lazy-lists-tests.factor index 302299b452..7dd0c0f009 100644 --- a/extra/lazy-lists/lazy-lists-tests.factor +++ b/extra/lazy-lists/lazy-lists-tests.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006 Matthew Willis and Chris Double. ! See http://factorcode.org/license.txt for BSD license. ! -USING: lazy-lists tools.test kernel math io sequences ; +USING: lists lazy-lists tools.test kernel math io sequences ; IN: lazy-lists.tests [ { 1 2 3 4 } ] [ diff --git a/extra/lazy-lists/lazy-lists.factor b/extra/lazy-lists/lazy-lists.factor index 6db82ed2c1..ae123580f7 100644 --- a/extra/lazy-lists/lazy-lists.factor +++ b/extra/lazy-lists/lazy-lists.factor @@ -5,15 +5,9 @@ ! Updated by Chris Double, September 2006 ! USING: kernel sequences math vectors arrays namespaces -quotations promises combinators io ; +quotations promises combinators io lists accessors ; IN: lazy-lists -! Lazy List Protocol -MIXIN: list -GENERIC: car ( cons -- car ) -GENERIC: cdr ( cons -- cdr ) -GENERIC: nil? ( cons -- ? ) - M: promise car ( promise -- car ) force car ; @@ -22,32 +16,7 @@ M: promise cdr ( promise -- cdr ) M: promise nil? ( cons -- bool ) force nil? ; - -TUPLE: cons car cdr ; - -C: cons cons - -M: cons car ( cons -- car ) - cons-car ; - -M: cons cdr ( cons -- cdr ) - cons-cdr ; - -: nil ( -- cons ) - T{ cons f f f } ; - -M: cons nil? ( cons -- bool ) - nil eq? ; - -: 1list ( obj -- cons ) - nil cons ; - -: 2list ( a b -- cons ) - nil cons cons ; - -: 3list ( a b c -- cons ) - nil cons cons cons ; - + ! Both 'car' and 'cdr' are promises TUPLE: lazy-cons car cdr ; @@ -57,10 +26,10 @@ TUPLE: lazy-cons car cdr ; [ set-promise-value ] keep ; M: lazy-cons car ( lazy-cons -- car ) - lazy-cons-car force ; + car>> force ; M: lazy-cons cdr ( lazy-cons -- cdr ) - lazy-cons-cdr force ; + cdr>> force ; M: lazy-cons nil? ( lazy-cons -- bool ) nil eq? ; @@ -83,12 +52,8 @@ M: lazy-cons nil? ( lazy-cons -- bool ) : llength ( list -- n ) 0 (llength) ; -: uncons ( cons -- car cdr ) - #! Return the car and cdr of the lazy list - dup car swap cdr ; - : leach ( list quot -- ) - swap dup nil? [ 2drop ] [ uncons swapd over 2slip leach ] if ; inline + over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline : lreduce ( list identity quot -- result ) swapd leach ; inline @@ -106,24 +71,24 @@ TUPLE: memoized-cons original car cdr nil? ; memoized-cons boa ; M: memoized-cons car ( memoized-cons -- car ) - dup memoized-cons-car not-memoized? [ - dup memoized-cons-original car [ swap set-memoized-cons-car ] keep + dup car>> not-memoized? [ + dup original>> car [ >>car drop ] keep ] [ - memoized-cons-car + car>> ] if ; M: memoized-cons cdr ( memoized-cons -- cdr ) - dup memoized-cons-cdr not-memoized? [ - dup memoized-cons-original cdr [ swap set-memoized-cons-cdr ] keep + dup cdr>> not-memoized? [ + dup original>> cdr [ >>cdr drop ] keep ] [ - memoized-cons-cdr + cdr>> ] if ; M: memoized-cons nil? ( memoized-cons -- bool ) - dup memoized-cons-nil? not-memoized? [ - dup memoized-cons-original nil? [ swap set-memoized-cons-nil? ] keep + dup nil?>> not-memoized? [ + dup original>> nil? [ >>nil? drop ] keep ] [ - memoized-cons-nil? + nil?>> ] if ; TUPLE: lazy-map cons quot ; @@ -134,15 +99,15 @@ C: lazy-map over nil? [ 2drop nil ] [ ] if ; M: lazy-map car ( lazy-map -- car ) - [ lazy-map-cons car ] keep - lazy-map-quot call ; + [ cons>> car ] keep + quot>> call ; M: lazy-map cdr ( lazy-map -- cdr ) - [ lazy-map-cons cdr ] keep - lazy-map-quot lmap ; + [ cons>> cdr ] keep + quot>> lmap ; M: lazy-map nil? ( lazy-map -- bool ) - lazy-map-cons nil? ; + cons>> nil? ; : lmap-with ( value list quot -- result ) with lmap ; @@ -155,17 +120,17 @@ C: lazy-take over zero? [ 2drop nil ] [ ] if ; M: lazy-take car ( lazy-take -- car ) - lazy-take-cons car ; + cons>> car ; M: lazy-take cdr ( lazy-take -- cdr ) - [ lazy-take-n 1- ] keep - lazy-take-cons cdr ltake ; + [ n>> 1- ] keep + cons>> cdr ltake ; M: lazy-take nil? ( lazy-take -- bool ) - dup lazy-take-n zero? [ + dup n>> zero? [ drop t ] [ - lazy-take-cons nil? + cons>> nil? ] if ; TUPLE: lazy-until cons quot ; @@ -176,10 +141,10 @@ C: lazy-until over nil? [ drop ] [ ] if ; M: lazy-until car ( lazy-until -- car ) - lazy-until-cons car ; + cons>> car ; M: lazy-until cdr ( lazy-until -- cdr ) - [ lazy-until-cons uncons swap ] keep lazy-until-quot tuck call + [ cons>> uncons ] keep quot>> tuck call [ 2drop nil ] [ luntil ] if ; M: lazy-until nil? ( lazy-until -- bool ) @@ -193,13 +158,13 @@ C: lazy-while over nil? [ drop ] [ ] if ; M: lazy-while car ( lazy-while -- car ) - lazy-while-cons car ; + cons>> car ; M: lazy-while cdr ( lazy-while -- cdr ) - [ lazy-while-cons cdr ] keep lazy-while-quot lwhile ; + [ cons>> cdr ] keep quot>> lwhile ; M: lazy-while nil? ( lazy-while -- bool ) - [ car ] keep lazy-while-quot call not ; + [ car ] keep quot>> call not ; TUPLE: lazy-filter cons quot ; @@ -209,26 +174,25 @@ C: lazy-filter over nil? [ 2drop nil ] [ ] if ; : car-filter? ( lazy-filter -- ? ) - [ lazy-filter-cons car ] keep - lazy-filter-quot call ; + [ cons>> car ] keep + quot>> call ; : skip ( lazy-filter -- ) - [ lazy-filter-cons cdr ] keep - set-lazy-filter-cons ; + dup cons>> cdr >>cons ; M: lazy-filter car ( lazy-filter -- car ) - dup car-filter? [ lazy-filter-cons ] [ dup skip ] if car ; + dup car-filter? [ cons>> ] [ dup skip ] if car ; M: lazy-filter cdr ( lazy-filter -- cdr ) dup car-filter? [ - [ lazy-filter-cons cdr ] keep - lazy-filter-quot lfilter + [ cons>> cdr ] keep + quot>> lfilter ] [ dup skip cdr ] if ; M: lazy-filter nil? ( lazy-filter -- bool ) - dup lazy-filter-cons nil? [ + dup cons>> nil? [ drop t ] [ dup car-filter? [ @@ -252,11 +216,11 @@ C: lazy-append over nil? [ nip ] [ ] if ; M: lazy-append car ( lazy-append -- car ) - lazy-append-list1 car ; + list1>> car ; M: lazy-append cdr ( lazy-append -- cdr ) - [ lazy-append-list1 cdr ] keep - lazy-append-list2 lappend ; + [ list1>> cdr ] keep + list2>> lappend ; M: lazy-append nil? ( lazy-append -- bool ) drop f ; @@ -269,11 +233,11 @@ C: lfrom-by lazy-from-by ( n quot -- list ) [ 1+ ] lfrom-by ; M: lazy-from-by car ( lazy-from-by -- car ) - lazy-from-by-n ; + n>> ; M: lazy-from-by cdr ( lazy-from-by -- cdr ) - [ lazy-from-by-n ] keep - lazy-from-by-quot dup slip lfrom-by ; + [ n>> ] keep + quot>> dup slip lfrom-by ; M: lazy-from-by nil? ( lazy-from-by -- bool ) drop f ; @@ -287,10 +251,10 @@ C: lazy-zip [ 2drop nil ] [ ] if ; M: lazy-zip car ( lazy-zip -- car ) - [ lazy-zip-list1 car ] keep lazy-zip-list2 car 2array ; + [ list1>> car ] keep list2>> car 2array ; M: lazy-zip cdr ( lazy-zip -- cdr ) - [ lazy-zip-list1 cdr ] keep lazy-zip-list2 cdr lzip ; + [ list1>> cdr ] keep list2>> cdr lzip ; M: lazy-zip nil? ( lazy-zip -- bool ) drop f ; @@ -307,12 +271,12 @@ C: sequence-cons ] if ; M: sequence-cons car ( sequence-cons -- car ) - [ sequence-cons-index ] keep - sequence-cons-seq nth ; + [ index>> ] keep + seq>> nth ; M: sequence-cons cdr ( sequence-cons -- cdr ) - [ sequence-cons-index 1+ ] keep - sequence-cons-seq seq>list ; + [ index>> 1+ ] keep + seq>> seq>list ; M: sequence-cons nil? ( sequence-cons -- bool ) drop f ; @@ -341,18 +305,18 @@ DEFER: lconcat dup nil? [ drop nil ] [ - uncons (lconcat) + uncons swap (lconcat) ] if ; M: lazy-concat car ( lazy-concat -- car ) - lazy-concat-car car ; + car>> car ; M: lazy-concat cdr ( lazy-concat -- cdr ) - [ lazy-concat-car cdr ] keep lazy-concat-cdr (lconcat) ; + [ car>> cdr ] keep cdr>> (lconcat) ; M: lazy-concat nil? ( lazy-concat -- bool ) - dup lazy-concat-car nil? [ - lazy-concat-cdr nil? + dup car>> nil? [ + cdr>> nil? ] [ drop f ] if ; @@ -404,22 +368,22 @@ C: lazy-io f f [ stream-readln ] ; M: lazy-io car ( lazy-io -- car ) - dup lazy-io-car dup [ + dup car>> dup [ nip ] [ - drop dup lazy-io-stream over lazy-io-quot call + drop dup stream>> over quot>> call swap dupd set-lazy-io-car ] if ; M: lazy-io cdr ( lazy-io -- cdr ) - dup lazy-io-cdr dup [ + dup cdr>> dup [ nip ] [ drop dup - [ lazy-io-stream ] keep - [ lazy-io-quot ] keep + [ stream>> ] keep + [ quot>> ] keep car [ - [ f f ] dip [ swap set-lazy-io-cdr ] keep + [ f f ] dip [ >>cdr drop ] keep ] [ 3drop nil ] if @@ -428,7 +392,6 @@ M: lazy-io cdr ( lazy-io -- cdr ) M: lazy-io nil? ( lazy-io -- bool ) car not ; -INSTANCE: cons list INSTANCE: sequence-cons list INSTANCE: memoized-cons list INSTANCE: promise list diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index da26580305..4b8cc77658 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -4,23 +4,45 @@ USING: kernel sequences accessors ; IN: lists +! Lazy List Protocol +MIXIN: list +GENERIC: car ( cons -- car ) +GENERIC: cdr ( cons -- cdr ) +GENERIC: nil? ( cons -- ? ) + TUPLE: cons car cdr ; -: cons \ cons new ; + +C: cons cons + +M: cons car ( cons -- car ) + car>> ; + +M: cons cdr ( cons -- cdr ) + cdr>> ; + +: nil ( -- cons ) + T{ cons f f f } ; + +M: cons nil? ( cons -- bool ) + nil eq? ; + +: 1list ( obj -- cons ) + nil cons ; + +: 2list ( a b -- cons ) + nil cons cons ; + +: 3list ( a b c -- cons ) + nil cons cons cons ; : uncons ( cons -- cdr car ) - [ cdr>> ] [ car>> ] bi ; - -: null? ( cons -- ? ) - uncons and not ; - -: ( x -- cons ) - cons swap >>car ; + [ cdr ] [ car ] bi ; : seq>cons ( seq -- cons ) - cons [ swap >>cdr ] reduce ; + nil [ f cons swap >>cdr ] reduce ; : (map-cons) ( acc cons quot -- seq ) - over null? [ 2drop ] + over nil? [ 2drop ] [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; : map-cons ( cons quot -- seq ) @@ -30,5 +52,7 @@ TUPLE: cons car cdr ; [ ] map-cons ; : reduce-cons ( cons identity quot -- result ) - pick null? [ drop nip ] - [ [ uncons ] 2dip swapd [ call ] keep reduce-cons ] if ; \ No newline at end of file + pick nil? [ drop nip ] + [ [ uncons ] 2dip swapd [ call ] keep reduce-cons ] if ; + +INSTANCE: cons list \ No newline at end of file From 684dde97df3bcba8deb2c67b979dcd50defac1cd Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 03:42:13 -0400 Subject: [PATCH 0025/1850] Changing indentation from 2 spaces to 4 --- extra/lazy-lists/lazy-lists.factor | 332 ++++++++++++++--------------- 1 file changed, 166 insertions(+), 166 deletions(-) diff --git a/extra/lazy-lists/lazy-lists.factor b/extra/lazy-lists/lazy-lists.factor index ae123580f7..a4b5c06daf 100644 --- a/extra/lazy-lists/lazy-lists.factor +++ b/extra/lazy-lists/lazy-lists.factor @@ -9,14 +9,14 @@ quotations promises combinators io lists accessors ; IN: lazy-lists M: promise car ( promise -- car ) - force car ; + force car ; M: promise cdr ( promise -- cdr ) - force cdr ; + force cdr ; M: promise nil? ( cons -- bool ) - force nil? ; - + force nil? ; + ! Both 'car' and 'cdr' are promises TUPLE: lazy-cons car cdr ; @@ -35,258 +35,258 @@ M: lazy-cons nil? ( lazy-cons -- bool ) nil eq? ; : 1lazy-list ( a -- lazy-cons ) - [ nil ] lazy-cons ; + [ nil ] lazy-cons ; : 2lazy-list ( a b -- lazy-cons ) - 1lazy-list 1quotation lazy-cons ; + 1lazy-list 1quotation lazy-cons ; : 3lazy-list ( a b c -- lazy-cons ) - 2lazy-list 1quotation lazy-cons ; + 2lazy-list 1quotation lazy-cons ; : lnth ( n list -- elt ) - swap [ cdr ] times car ; + swap [ cdr ] times car ; : (llength) ( list acc -- n ) - over nil? [ nip ] [ [ cdr ] dip 1+ (llength) ] if ; + over nil? [ nip ] [ [ cdr ] dip 1+ (llength) ] if ; : llength ( list -- n ) - 0 (llength) ; + 0 (llength) ; : leach ( list quot -- ) - over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline + over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline : lreduce ( list identity quot -- result ) - swapd leach ; inline + swapd leach ; inline TUPLE: memoized-cons original car cdr nil? ; : not-memoized ( -- obj ) - { } ; + { } ; : not-memoized? ( obj -- bool ) - not-memoized eq? ; + not-memoized eq? ; : ( cons -- memoized-cons ) - not-memoized not-memoized not-memoized - memoized-cons boa ; + not-memoized not-memoized not-memoized + memoized-cons boa ; M: memoized-cons car ( memoized-cons -- car ) - dup car>> not-memoized? [ - dup original>> car [ >>car drop ] keep - ] [ - car>> - ] if ; + dup car>> not-memoized? [ + dup original>> car [ >>car drop ] keep + ] [ + car>> + ] if ; M: memoized-cons cdr ( memoized-cons -- cdr ) - dup cdr>> not-memoized? [ - dup original>> cdr [ >>cdr drop ] keep - ] [ - cdr>> - ] if ; + dup cdr>> not-memoized? [ + dup original>> cdr [ >>cdr drop ] keep + ] [ + cdr>> + ] if ; M: memoized-cons nil? ( memoized-cons -- bool ) - dup nil?>> not-memoized? [ - dup original>> nil? [ >>nil? drop ] keep - ] [ - nil?>> - ] if ; + dup nil?>> not-memoized? [ + dup original>> nil? [ >>nil? drop ] keep + ] [ + nil?>> + ] if ; TUPLE: lazy-map cons quot ; C: lazy-map : lmap ( list quot -- result ) - over nil? [ 2drop nil ] [ ] if ; + over nil? [ 2drop nil ] [ ] if ; M: lazy-map car ( lazy-map -- car ) - [ cons>> car ] keep - quot>> call ; + [ cons>> car ] keep + quot>> call ; M: lazy-map cdr ( lazy-map -- cdr ) - [ cons>> cdr ] keep - quot>> lmap ; + [ cons>> cdr ] keep + quot>> lmap ; M: lazy-map nil? ( lazy-map -- bool ) - cons>> nil? ; + cons>> nil? ; : lmap-with ( value list quot -- result ) - with lmap ; + with lmap ; TUPLE: lazy-take n cons ; C: lazy-take : ltake ( n list -- result ) - over zero? [ 2drop nil ] [ ] if ; + over zero? [ 2drop nil ] [ ] if ; M: lazy-take car ( lazy-take -- car ) - cons>> car ; + cons>> car ; M: lazy-take cdr ( lazy-take -- cdr ) - [ n>> 1- ] keep - cons>> cdr ltake ; + [ n>> 1- ] keep + cons>> cdr ltake ; M: lazy-take nil? ( lazy-take -- bool ) - dup n>> zero? [ - drop t - ] [ - cons>> nil? - ] if ; + dup n>> zero? [ + drop t + ] [ + cons>> nil? + ] if ; TUPLE: lazy-until cons quot ; C: lazy-until : luntil ( list quot -- result ) - over nil? [ drop ] [ ] if ; + over nil? [ drop ] [ ] if ; M: lazy-until car ( lazy-until -- car ) - cons>> car ; + cons>> car ; M: lazy-until cdr ( lazy-until -- cdr ) - [ cons>> uncons ] keep quot>> tuck call - [ 2drop nil ] [ luntil ] if ; + [ cons>> uncons ] keep quot>> tuck call + [ 2drop nil ] [ luntil ] if ; M: lazy-until nil? ( lazy-until -- bool ) - drop f ; + drop f ; TUPLE: lazy-while cons quot ; C: lazy-while : lwhile ( list quot -- result ) - over nil? [ drop ] [ ] if ; + over nil? [ drop ] [ ] if ; M: lazy-while car ( lazy-while -- car ) - cons>> car ; + cons>> car ; M: lazy-while cdr ( lazy-while -- cdr ) - [ cons>> cdr ] keep quot>> lwhile ; + [ cons>> cdr ] keep quot>> lwhile ; M: lazy-while nil? ( lazy-while -- bool ) - [ car ] keep quot>> call not ; + [ car ] keep quot>> call not ; TUPLE: lazy-filter cons quot ; C: lazy-filter : lfilter ( list quot -- result ) - over nil? [ 2drop nil ] [ ] if ; + over nil? [ 2drop nil ] [ ] if ; -: car-filter? ( lazy-filter -- ? ) - [ cons>> car ] keep - quot>> call ; +: car-filter? ( lazy-filter -- ? ) + [ cons>> car ] keep + quot>> call ; : skip ( lazy-filter -- ) - dup cons>> cdr >>cons ; + dup cons>> cdr >>cons ; M: lazy-filter car ( lazy-filter -- car ) - dup car-filter? [ cons>> ] [ dup skip ] if car ; + dup car-filter? [ cons>> ] [ dup skip ] if car ; M: lazy-filter cdr ( lazy-filter -- cdr ) - dup car-filter? [ - [ cons>> cdr ] keep - quot>> lfilter - ] [ - dup skip cdr - ] if ; + dup car-filter? [ + [ cons>> cdr ] keep + quot>> lfilter + ] [ + dup skip cdr + ] if ; M: lazy-filter nil? ( lazy-filter -- bool ) - dup cons>> nil? [ - drop t - ] [ - dup car-filter? [ - drop f + dup cons>> nil? [ + drop t ] [ - dup skip nil? - ] if - ] if ; + dup car-filter? [ + drop f + ] [ + dup skip nil? + ] if + ] if ; : list>vector ( list -- vector ) - [ [ , ] leach ] V{ } make ; + [ [ , ] leach ] V{ } make ; : list>array ( list -- array ) - [ [ , ] leach ] { } make ; + [ [ , ] leach ] { } make ; TUPLE: lazy-append list1 list2 ; C: lazy-append : lappend ( list1 list2 -- result ) - over nil? [ nip ] [ ] if ; + over nil? [ nip ] [ ] if ; M: lazy-append car ( lazy-append -- car ) - list1>> car ; + list1>> car ; M: lazy-append cdr ( lazy-append -- cdr ) - [ list1>> cdr ] keep - list2>> lappend ; + [ list1>> cdr ] keep + list2>> lappend ; M: lazy-append nil? ( lazy-append -- bool ) - drop f ; + drop f ; TUPLE: lazy-from-by n quot ; C: lfrom-by lazy-from-by ( n quot -- list ) : lfrom ( n -- list ) - [ 1+ ] lfrom-by ; + [ 1+ ] lfrom-by ; M: lazy-from-by car ( lazy-from-by -- car ) - n>> ; + n>> ; M: lazy-from-by cdr ( lazy-from-by -- cdr ) - [ n>> ] keep - quot>> dup slip lfrom-by ; + [ n>> ] keep + quot>> dup slip lfrom-by ; M: lazy-from-by nil? ( lazy-from-by -- bool ) - drop f ; + drop f ; TUPLE: lazy-zip list1 list2 ; C: lazy-zip : lzip ( list1 list2 -- lazy-zip ) - over nil? over nil? or - [ 2drop nil ] [ ] if ; + over nil? over nil? or + [ 2drop nil ] [ ] if ; M: lazy-zip car ( lazy-zip -- car ) - [ list1>> car ] keep list2>> car 2array ; + [ list1>> car ] keep list2>> car 2array ; M: lazy-zip cdr ( lazy-zip -- cdr ) - [ list1>> cdr ] keep list2>> cdr lzip ; + [ list1>> cdr ] keep list2>> cdr lzip ; M: lazy-zip nil? ( lazy-zip -- bool ) - drop f ; + drop f ; TUPLE: sequence-cons index seq ; C: sequence-cons : seq>list ( index seq -- list ) - 2dup length >= [ - 2drop nil - ] [ - - ] if ; + 2dup length >= [ + 2drop nil + ] [ + + ] if ; M: sequence-cons car ( sequence-cons -- car ) - [ index>> ] keep - seq>> nth ; + [ index>> ] keep + seq>> nth ; M: sequence-cons cdr ( sequence-cons -- cdr ) - [ index>> 1+ ] keep - seq>> seq>list ; + [ index>> 1+ ] keep + seq>> seq>list ; M: sequence-cons nil? ( sequence-cons -- bool ) - drop f ; + drop f ; : >list ( object -- list ) - { - { [ dup sequence? ] [ 0 swap seq>list ] } - { [ dup list? ] [ ] } - [ "Could not convert object to a list" throw ] - } cond ; + { + { [ dup sequence? ] [ 0 swap seq>list ] } + { [ dup list? ] [ ] } + [ "Could not convert object to a list" throw ] + } cond ; TUPLE: lazy-concat car cdr ; @@ -295,102 +295,102 @@ C: lazy-concat DEFER: lconcat : (lconcat) ( car cdr -- list ) - over nil? [ - nip lconcat - ] [ - - ] if ; + over nil? [ + nip lconcat + ] [ + + ] if ; : lconcat ( list -- result ) - dup nil? [ - drop nil - ] [ - uncons swap (lconcat) - ] if ; + dup nil? [ + drop nil + ] [ + uncons swap (lconcat) + ] if ; M: lazy-concat car ( lazy-concat -- car ) - car>> car ; + car>> car ; M: lazy-concat cdr ( lazy-concat -- cdr ) - [ car>> cdr ] keep cdr>> (lconcat) ; + [ car>> cdr ] keep cdr>> (lconcat) ; M: lazy-concat nil? ( lazy-concat -- bool ) - dup car>> nil? [ - cdr>> nil? - ] [ - drop f - ] if ; + dup car>> nil? [ + cdr>> nil? + ] [ + drop f + ] if ; : lcartesian-product ( list1 list2 -- result ) - swap [ swap [ 2array ] lmap-with ] lmap-with lconcat ; + swap [ swap [ 2array ] lmap-with ] lmap-with lconcat ; : lcartesian-product* ( lists -- result ) - dup nil? [ - drop nil - ] [ - [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [ - swap [ swap [ suffix ] lmap-with ] lmap-with lconcat - ] reduce - ] if ; + dup nil? [ + drop nil + ] [ + [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [ + swap [ swap [ suffix ] lmap-with ] lmap-with lconcat + ] reduce + ] if ; : lcomp ( list quot -- result ) - [ lcartesian-product* ] dip lmap ; + [ lcartesian-product* ] dip lmap ; : lcomp* ( list guards quot -- result ) - [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lmap ; + [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lmap ; DEFER: lmerge : (lmerge) ( list1 list2 -- result ) - over [ car ] curry -rot - [ - dup [ car ] curry -rot + over [ car ] curry -rot [ - [ cdr ] bi@ lmerge - ] 2curry lazy-cons - ] 2curry lazy-cons ; + dup [ car ] curry -rot + [ + [ cdr ] bi@ lmerge + ] 2curry lazy-cons + ] 2curry lazy-cons ; : lmerge ( list1 list2 -- result ) - { - { [ over nil? ] [ nip ] } - { [ dup nil? ] [ drop ] } - { [ t ] [ (lmerge) ] } - } cond ; + { + { [ over nil? ] [ nip ] } + { [ dup nil? ] [ drop ] } + { [ t ] [ (lmerge) ] } + } cond ; TUPLE: lazy-io stream car cdr quot ; C: lazy-io : lcontents ( stream -- result ) - f f [ stream-read1 ] ; + f f [ stream-read1 ] ; : llines ( stream -- result ) - f f [ stream-readln ] ; + f f [ stream-readln ] ; M: lazy-io car ( lazy-io -- car ) - dup car>> dup [ - nip - ] [ - drop dup stream>> over quot>> call - swap dupd set-lazy-io-car - ] if ; + dup car>> dup [ + nip + ] [ + drop dup stream>> over quot>> call + swap dupd set-lazy-io-car + ] if ; M: lazy-io cdr ( lazy-io -- cdr ) - dup cdr>> dup [ - nip - ] [ - drop dup - [ stream>> ] keep - [ quot>> ] keep - car [ - [ f f ] dip [ >>cdr drop ] keep + dup cdr>> dup [ + nip ] [ - 3drop nil - ] if - ] if ; + drop dup + [ stream>> ] keep + [ quot>> ] keep + car [ + [ f f ] dip [ >>cdr drop ] keep + ] [ + 3drop nil + ] if + ] if ; M: lazy-io nil? ( lazy-io -- bool ) - car not ; + car not ; INSTANCE: sequence-cons list INSTANCE: memoized-cons list From 887bc84d4b8ea71c65138274818cc55a45b693b7 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 03:42:56 -0400 Subject: [PATCH 0026/1850] Adding 'updated' notice --- extra/lazy-lists/lazy-lists.factor | 1 + 1 file changed, 1 insertion(+) diff --git a/extra/lazy-lists/lazy-lists.factor b/extra/lazy-lists/lazy-lists.factor index a4b5c06daf..8b3d069c40 100644 --- a/extra/lazy-lists/lazy-lists.factor +++ b/extra/lazy-lists/lazy-lists.factor @@ -3,6 +3,7 @@ ! ! Updated by Matthew Willis, July 2006 ! Updated by Chris Double, September 2006 +! Updated by James Cash, June 2008 ! USING: kernel sequences math vectors arrays namespaces quotations promises combinators io lists accessors ; From 847077f77088e244c124e076bbef9a7c8930757a Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 03:46:29 -0400 Subject: [PATCH 0027/1850] Changing lisp to reflect moving extra/lisp/conses to extra/lists --- extra/lisp/lisp.factor | 21 +++++++++++---------- extra/lisp/parser/parser-tests.factor | 2 +- extra/lisp/parser/parser.factor | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 3d977df97f..b034619d0d 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -3,7 +3,7 @@ USING: kernel peg sequences arrays strings combinators.lib namespaces combinators math locals locals.private accessors vectors syntax lisp.parser assocs parser sequences.lib words quotations -fry lisp.conses ; +fry lists ; IN: lisp DEFER: convert-form @@ -11,20 +11,21 @@ DEFER: funcall DEFER: lookup-var DEFER: lisp-macro? DEFER: lookup-macro +DEFER: macro-call ! Functions to convert s-exps to quotations ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : convert-body ( cons -- quot ) - [ ] [ convert-form compose ] reduce ; inline + [ ] [ convert-form compose ] reduce-cons ; inline : convert-if ( cons -- quot ) - rest first3 [ convert-form ] tri@ '[ @ , , if ] ; + cdr first3 [ convert-form ] tri@ '[ @ , , if ] ; : convert-begin ( cons -- quot ) - rest [ convert-form ] [ ] map-as '[ , [ funcall ] each ] ; + cdr [ convert-form ] [ ] map-as '[ , [ funcall ] each ] ; : convert-cond ( cons -- quot ) - rest [ body>> first2 [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ] + cdr [ body>> first2 [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ] { } map-as '[ , cond ] ; : convert-general-form ( cons -- quot ) @@ -34,12 +35,12 @@ DEFER: lookup-macro > ] dip at swap or ] - [ dup cons? [ body>> localize-body ] when ] if - ] map ; + [ dup cons? [ localize-body ] when ] if + ] map-cons ; : localize-lambda ( body vars -- newbody newvars ) make-locals dup push-locals swap - [ swap localize-body convert-form swap pop-locals ] dip swap ; + [ swap localize-body cons convert-form swap pop-locals ] dip swap ; : split-lambda ( cons -- body vars ) first3 -rot nip [ body>> ] bi@ [ name>> ] map ; inline @@ -57,7 +58,7 @@ PRIVATE> split-lambda "&rest" over member? [ rest-lambda ] [ normal-lambda ] if ; : convert-quoted ( cons -- quot ) - cdr>> 1quotation ; + cdr 1quotation ; : form-dispatch ( lisp-symbol -- quot ) name>> @@ -73,7 +74,7 @@ PRIVATE> uncons lookup-macro macro-call convert-form ; : convert-list-form ( cons -- quot ) - dup car>> + dup car { { [ dup lisp-macro? ] [ macro-expand ] } { [ dup lisp-symbol? ] [ form-dispatch ] } [ drop convert-general-form ] diff --git a/extra/lisp/parser/parser-tests.factor b/extra/lisp/parser/parser-tests.factor index 9c33f635f9..41254db5b3 100644 --- a/extra/lisp/parser/parser-tests.factor +++ b/extra/lisp/parser/parser-tests.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: lisp.parser tools.test peg peg.ebnf lisp.conses ; +USING: lisp.parser tools.test peg peg.ebnf lists ; IN: lisp.parser.tests diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor index 9679c77209..1e37193d3a 100644 --- a/extra/lisp/parser/parser.factor +++ b/extra/lisp/parser/parser.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. USING: kernel peg peg.ebnf peg.expr math.parser sequences arrays strings -combinators.lib math fry accessors lisp.conses ; +combinators.lib math fry accessors lists ; IN: lisp.parser From e4b88c61f396d40d793e638860070429eb8baacc Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 04:04:20 -0400 Subject: [PATCH 0028/1850] Moving extra/lazy-lists to extra/lists/lazy --- extra/{lazy-lists => lists/lazy}/authors.txt | 0 .../lazy}/examples/authors.txt | 0 .../lazy}/examples/examples-tests.factor | 0 .../lazy}/examples/examples.factor | 0 .../lazy/lazy-docs.factor} | 42 +---------------- .../lazy/lazy-tests.factor} | 4 +- .../lazy/lazy.factor} | 2 +- extra/{lazy-lists => lists/lazy}/old-doc.html | 0 extra/{lazy-lists => lists/lazy}/summary.txt | 0 extra/{lazy-lists => lists/lazy}/tags.txt | 0 extra/lists/lists-docs.factor | 45 +++++++++++++++++++ 11 files changed, 49 insertions(+), 44 deletions(-) rename extra/{lazy-lists => lists/lazy}/authors.txt (100%) rename extra/{lazy-lists => lists/lazy}/examples/authors.txt (100%) rename extra/{lazy-lists => lists/lazy}/examples/examples-tests.factor (100%) rename extra/{lazy-lists => lists/lazy}/examples/examples.factor (100%) rename extra/{lazy-lists/lazy-lists-docs.factor => lists/lazy/lazy-docs.factor} (88%) rename extra/{lazy-lists/lazy-lists-tests.factor => lists/lazy/lazy-tests.factor} (90%) rename extra/{lazy-lists/lazy-lists.factor => lists/lazy/lazy.factor} (99%) rename extra/{lazy-lists => lists/lazy}/old-doc.html (100%) rename extra/{lazy-lists => lists/lazy}/summary.txt (100%) rename extra/{lazy-lists => lists/lazy}/tags.txt (100%) diff --git a/extra/lazy-lists/authors.txt b/extra/lists/lazy/authors.txt similarity index 100% rename from extra/lazy-lists/authors.txt rename to extra/lists/lazy/authors.txt diff --git a/extra/lazy-lists/examples/authors.txt b/extra/lists/lazy/examples/authors.txt similarity index 100% rename from extra/lazy-lists/examples/authors.txt rename to extra/lists/lazy/examples/authors.txt diff --git a/extra/lazy-lists/examples/examples-tests.factor b/extra/lists/lazy/examples/examples-tests.factor similarity index 100% rename from extra/lazy-lists/examples/examples-tests.factor rename to extra/lists/lazy/examples/examples-tests.factor diff --git a/extra/lazy-lists/examples/examples.factor b/extra/lists/lazy/examples/examples.factor similarity index 100% rename from extra/lazy-lists/examples/examples.factor rename to extra/lists/lazy/examples/examples.factor diff --git a/extra/lazy-lists/lazy-lists-docs.factor b/extra/lists/lazy/lazy-docs.factor similarity index 88% rename from extra/lazy-lists/lazy-lists-docs.factor rename to extra/lists/lazy/lazy-docs.factor index fb87bee10f..1de98971f6 100644 --- a/extra/lazy-lists/lazy-lists-docs.factor +++ b/extra/lists/lazy/lazy-docs.factor @@ -2,47 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: help.markup help.syntax sequences strings lists ; -IN: lazy-lists - -{ car cons cdr nil nil? list? uncons } related-words - -HELP: cons -{ $values { "car" "the head of the lazy list" } { "cdr" "the tail of the lazy list" } { "cons" "a cons object" } } -{ $description "Constructs a cons cell." } ; - -HELP: car -{ $values { "cons" "a cons object" } { "car" "the first item in the list" } } -{ $description "Returns the first item in the list." } ; - -HELP: cdr -{ $values { "cons" "a cons object" } { "cdr" "a cons object" } } -{ $description "Returns the tail of the list." } ; - -HELP: nil -{ $values { "cons" "An empty cons" } } -{ $description "Returns a representation of an empty list" } ; - -HELP: nil? -{ $values { "cons" "a cons object" } { "?" "a boolean" } } -{ $description "Return true if the cons object is the nil cons." } ; - -HELP: list? ( object -- ? ) -{ $values { "object" "an object" } { "?" "a boolean" } } -{ $description "Returns true if the object conforms to the list protocol." } ; - -{ 1list 2list 3list } related-words - -HELP: 1list -{ $values { "obj" "an object" } { "cons" "a cons object" } } -{ $description "Create a list with 1 element." } ; - -HELP: 2list -{ $values { "a" "an object" } { "b" "an object" } { "cons" "a cons object" } } -{ $description "Create a list with 2 elements." } ; - -HELP: 3list -{ $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } } -{ $description "Create a list with 3 elements." } ; +IN: lists.lazy HELP: lazy-cons { $values { "car" "a quotation with stack effect ( -- X )" } { "cdr" "a quotation with stack effect ( -- cons )" } { "promise" "the resulting cons object" } } diff --git a/extra/lazy-lists/lazy-lists-tests.factor b/extra/lists/lazy/lazy-tests.factor similarity index 90% rename from extra/lazy-lists/lazy-lists-tests.factor rename to extra/lists/lazy/lazy-tests.factor index 7dd0c0f009..f4bb7b595b 100644 --- a/extra/lazy-lists/lazy-lists-tests.factor +++ b/extra/lists/lazy/lazy-tests.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2006 Matthew Willis and Chris Double. ! See http://factorcode.org/license.txt for BSD license. ! -USING: lists lazy-lists tools.test kernel math io sequences ; -IN: lazy-lists.tests +USING: lists lists.lazy tools.test kernel math io sequences ; +IN: lists.lazy.tests [ { 1 2 3 4 } ] [ { 1 2 3 4 } >list list>array diff --git a/extra/lazy-lists/lazy-lists.factor b/extra/lists/lazy/lazy.factor similarity index 99% rename from extra/lazy-lists/lazy-lists.factor rename to extra/lists/lazy/lazy.factor index 8b3d069c40..f8b1a6e6ef 100644 --- a/extra/lazy-lists/lazy-lists.factor +++ b/extra/lists/lazy/lazy.factor @@ -7,7 +7,7 @@ ! USING: kernel sequences math vectors arrays namespaces quotations promises combinators io lists accessors ; -IN: lazy-lists +IN: lists.lazy M: promise car ( promise -- car ) force car ; diff --git a/extra/lazy-lists/old-doc.html b/extra/lists/lazy/old-doc.html similarity index 100% rename from extra/lazy-lists/old-doc.html rename to extra/lists/lazy/old-doc.html diff --git a/extra/lazy-lists/summary.txt b/extra/lists/lazy/summary.txt similarity index 100% rename from extra/lazy-lists/summary.txt rename to extra/lists/lazy/summary.txt diff --git a/extra/lazy-lists/tags.txt b/extra/lists/lazy/tags.txt similarity index 100% rename from extra/lazy-lists/tags.txt rename to extra/lists/lazy/tags.txt diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor index e69de29bb2..94407765fc 100644 --- a/extra/lists/lists-docs.factor +++ b/extra/lists/lists-docs.factor @@ -0,0 +1,45 @@ +! Copyright (C) 2006 Chris Double. +! See http://factorcode.org/license.txt for BSD license. + +IN: lists +USING: help.markup help.syntax ; + +{ car cons cdr nil nil? list? uncons } related-words + +HELP: cons +{ $values { "car" "the head of the lazy list" } { "cdr" "the tail of the lazy list" } { "cons" "a cons object" } } +{ $description "Constructs a cons cell." } ; + +HELP: car +{ $values { "cons" "a cons object" } { "car" "the first item in the list" } } +{ $description "Returns the first item in the list." } ; + +HELP: cdr +{ $values { "cons" "a cons object" } { "cdr" "a cons object" } } +{ $description "Returns the tail of the list." } ; + +HELP: nil +{ $values { "cons" "An empty cons" } } +{ $description "Returns a representation of an empty list" } ; + +HELP: nil? +{ $values { "cons" "a cons object" } { "?" "a boolean" } } +{ $description "Return true if the cons object is the nil cons." } ; + +HELP: list? ( object -- ? ) +{ $values { "object" "an object" } { "?" "a boolean" } } +{ $description "Returns true if the object conforms to the list protocol." } ; + +{ 1list 2list 3list } related-words + +HELP: 1list +{ $values { "obj" "an object" } { "cons" "a cons object" } } +{ $description "Create a list with 1 element." } ; + +HELP: 2list +{ $values { "a" "an object" } { "b" "an object" } { "cons" "a cons object" } } +{ $description "Create a list with 2 elements." } ; + +HELP: 3list +{ $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } } +{ $description "Create a list with 3 elements." } ; \ No newline at end of file From 1818a743bd36902060686662a40e40c74b540322 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 04:27:25 -0400 Subject: [PATCH 0029/1850] Updating libraries that uses lazy-lists to use lists/lazy --- extra/globs/globs.factor | 2 +- extra/json/reader/reader.factor | 2 +- extra/math/erato/erato-tests.factor | 2 +- extra/math/erato/erato.factor | 2 +- extra/math/primes/factors/factors.factor | 2 +- extra/math/primes/primes-tests.factor | 2 +- extra/math/primes/primes.factor | 2 +- extra/monads/monads-tests.factor | 2 +- extra/monads/monads.factor | 2 +- extra/morse/morse.factor | 2 +- extra/parser-combinators/parser-combinators-docs.factor | 2 +- extra/parser-combinators/parser-combinators-tests.factor | 2 +- extra/parser-combinators/parser-combinators.factor | 2 +- extra/parser-combinators/simple/simple-docs.factor | 8 ++++---- extra/parser-combinators/simple/simple.factor | 2 +- extra/project-euler/007/007.factor | 2 +- extra/project-euler/134/134.factor | 2 +- extra/regexp/regexp.factor | 2 +- extra/tetris/game/game.factor | 2 +- extra/tetris/piece/piece.factor | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/extra/globs/globs.factor b/extra/globs/globs.factor index 4fa56bcf93..db1921d86d 100755 --- a/extra/globs/globs.factor +++ b/extra/globs/globs.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: parser-combinators regexp lazy-lists sequences kernel +USING: parser-combinators regexp lists lists.lazy sequences kernel promises strings unicode.case ; IN: globs diff --git a/extra/json/reader/reader.factor b/extra/json/reader/reader.factor index 5e6b16dc2f..9d6155ea78 100755 --- a/extra/json/reader/reader.factor +++ b/extra/json/reader/reader.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel parser-combinators namespaces sequences promises strings assocs math math.parser math.vectors math.functions math.order - lazy-lists hashtables ascii ; + lists lists.lazy hashtables ascii ; IN: json.reader ! Grammar for JSON from RFC 4627 diff --git a/extra/math/erato/erato-tests.factor b/extra/math/erato/erato-tests.factor index 9244fa62e2..1f59659fa9 100644 --- a/extra/math/erato/erato-tests.factor +++ b/extra/math/erato/erato-tests.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: lazy-lists math.erato tools.test ; +USING: lists lists.lazy math.erato tools.test ; IN: math.erato.tests [ { 2 3 5 7 11 13 17 19 } ] [ 20 lerato list>array ] unit-test diff --git a/extra/math/erato/erato.factor b/extra/math/erato/erato.factor index 40de92e3b1..292cec8def 100644 --- a/extra/math/erato/erato.factor +++ b/extra/math/erato/erato.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: bit-arrays kernel lazy-lists math math.functions math.primes.list +USING: bit-arrays kernel lists lists.lazy math math.functions math.primes.list math.ranges sequences ; IN: math.erato diff --git a/extra/math/primes/factors/factors.factor b/extra/math/primes/factors/factors.factor index 2f70ab24b4..7413f9701b 100644 --- a/extra/math/primes/factors/factors.factor +++ b/extra/math/primes/factors/factors.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays kernel lazy-lists math math.primes namespaces sequences ; +USING: arrays kernel lists lists.lazy math math.primes namespaces sequences ; IN: math.primes.factors Date: Tue, 3 Jun 2008 04:41:36 -0400 Subject: [PATCH 0030/1850] Some files only need lists.lazy, not lists as well --- extra/math/erato/erato-tests.factor | 2 +- extra/math/erato/erato.factor | 2 +- extra/math/primes/primes-tests.factor | 2 +- extra/math/primes/primes.factor | 2 +- extra/parser-combinators/parser-combinators-tests.factor | 2 +- extra/parser-combinators/simple/simple.factor | 2 +- extra/project-euler/007/007.factor | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/extra/math/erato/erato-tests.factor b/extra/math/erato/erato-tests.factor index 1f59659fa9..041cb8dc3a 100644 --- a/extra/math/erato/erato-tests.factor +++ b/extra/math/erato/erato-tests.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: lists lists.lazy math.erato tools.test ; +USING: lists.lazy math.erato tools.test ; IN: math.erato.tests [ { 2 3 5 7 11 13 17 19 } ] [ 20 lerato list>array ] unit-test diff --git a/extra/math/erato/erato.factor b/extra/math/erato/erato.factor index 292cec8def..b9d997c038 100644 --- a/extra/math/erato/erato.factor +++ b/extra/math/erato/erato.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: bit-arrays kernel lists lists.lazy math math.functions math.primes.list +USING: bit-arrays kernel lists.lazy math math.functions math.primes.list math.ranges sequences ; IN: math.erato diff --git a/extra/math/primes/primes-tests.factor b/extra/math/primes/primes-tests.factor index 2db98af893..186acc9b11 100644 --- a/extra/math/primes/primes-tests.factor +++ b/extra/math/primes/primes-tests.factor @@ -1,4 +1,4 @@ -USING: arrays math.primes tools.test lists lists.lazy ; +USING: arrays math.primes tools.test lists.lazy ; { 1237 } [ 1234 next-prime ] unit-test { f t } [ 1234 prime? 1237 prime? ] unit-test diff --git a/extra/math/primes/primes.factor b/extra/math/primes/primes.factor index e42bb8d82d..59aebbf0dd 100644 --- a/extra/math/primes/primes.factor +++ b/extra/math/primes/primes.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators kernel lists lists.lazy math math.functions math.miller-rabin +USING: combinators kernel lists.lazy math math.functions math.miller-rabin math.order math.primes.list math.ranges sequences sorting ; IN: math.primes diff --git a/extra/parser-combinators/parser-combinators-tests.factor b/extra/parser-combinators/parser-combinators-tests.factor index 062277ec4d..70698daa0b 100755 --- a/extra/parser-combinators/parser-combinators-tests.factor +++ b/extra/parser-combinators/parser-combinators-tests.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2005 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel lists lists.lazy tools.test strings math +USING: kernel lists.lazy tools.test strings math sequences parser-combinators arrays math.parser unicode.categories ; IN: parser-combinators.tests diff --git a/extra/parser-combinators/simple/simple.factor b/extra/parser-combinators/simple/simple.factor index 5182260e98..f7a696ca35 100755 --- a/extra/parser-combinators/simple/simple.factor +++ b/extra/parser-combinators/simple/simple.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2006 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel strings math sequences lists lists.lazy words +USING: kernel strings math sequences lists.lazy words math.parser promises parser-combinators unicode.categories ; IN: parser-combinators.simple diff --git a/extra/project-euler/007/007.factor b/extra/project-euler/007/007.factor index 10e95bd2b5..40178c4291 100644 --- a/extra/project-euler/007/007.factor +++ b/extra/project-euler/007/007.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: lists lists.lazy math math.primes ; +USING: lists.lazy math math.primes ; IN: project-euler.007 ! http://projecteuler.net/index.php?section=problems&id=7 From 1bd222228c95753fa3e5f18f6eb5d21a13b31790 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 05:06:52 -0400 Subject: [PATCH 0031/1850] Making sure that vocabs only have lists or lists.lazy if they need them --- extra/json/reader/reader.factor | 2 +- extra/math/primes/factors/factors.factor | 2 +- extra/monads/monads-tests.factor | 2 +- extra/morse/morse.factor | 2 +- extra/parser-combinators/parser-combinators-docs.factor | 2 +- extra/parser-combinators/simple/simple-docs.factor | 8 ++++---- extra/regexp/regexp.factor | 2 +- extra/tetris/game/game.factor | 2 +- extra/tetris/piece/piece.factor | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/extra/json/reader/reader.factor b/extra/json/reader/reader.factor index 9d6155ea78..6bd6905804 100755 --- a/extra/json/reader/reader.factor +++ b/extra/json/reader/reader.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel parser-combinators namespaces sequences promises strings assocs math math.parser math.vectors math.functions math.order - lists lists.lazy hashtables ascii ; + lists hashtables ascii ; IN: json.reader ! Grammar for JSON from RFC 4627 diff --git a/extra/math/primes/factors/factors.factor b/extra/math/primes/factors/factors.factor index 7413f9701b..b38a7926d2 100644 --- a/extra/math/primes/factors/factors.factor +++ b/extra/math/primes/factors/factors.factor @@ -17,7 +17,7 @@ IN: math.primes.factors dup empty? [ drop ] [ first , ] if ; : (factors) ( quot list n -- ) - dup 1 > [ swap uncons >r pick call r> swap (factors) ] [ 3drop ] if ; + dup 1 > [ swap uncons swap >r pick call r> swap (factors) ] [ 3drop ] if ; : (decompose) ( n quot -- seq ) [ lprimes rot (factors) ] { } make ; diff --git a/extra/monads/monads-tests.factor b/extra/monads/monads-tests.factor index 98cc403910..d0014b5abe 100644 --- a/extra/monads/monads-tests.factor +++ b/extra/monads/monads-tests.factor @@ -1,4 +1,4 @@ -USING: tools.test monads math kernel sequences lists lists.lazy promises ; +USING: tools.test monads math kernel sequences lists promises ; IN: monads.tests [ 5 ] [ 1 identity-monad return [ 4 + ] fmap run-identity ] unit-test diff --git a/extra/morse/morse.factor b/extra/morse/morse.factor index 71b7249351..591915b317 100644 --- a/extra/morse/morse.factor +++ b/extra/morse/morse.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs combinators hashtables kernel lists lists.lazy math namespaces openal parser-combinators promises sequences strings symbols synth synth.buffers unicode.case ; +USING: accessors assocs combinators hashtables kernel lists math namespaces openal parser-combinators promises sequences strings symbols synth synth.buffers unicode.case ; IN: morse Date: Tue, 3 Jun 2008 05:18:36 -0400 Subject: [PATCH 0032/1850] Fix for changed effect of uncons --- extra/project-euler/134/134.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/project-euler/134/134.factor b/extra/project-euler/134/134.factor index ddba76d5a0..4e54a18f19 100644 --- a/extra/project-euler/134/134.factor +++ b/extra/project-euler/134/134.factor @@ -39,7 +39,7 @@ IN: project-euler.134 PRIVATE> : euler134 ( -- answer ) - 0 5 lprimes-from uncons [ 1000000 > ] luntil + 0 5 lprimes-from uncons swap [ 1000000 > ] luntil [ [ s + ] keep ] leach drop ; ! [ euler134 ] 10 ave-time From 707226859a945656ead5d161719ca1106343145b Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 16:28:02 -0400 Subject: [PATCH 0033/1850] Renaming map-cons to lmap and lmap to lazy-map --- extra/lists/lazy/lazy-docs.factor | 2 ++ extra/lists/lazy/lazy.factor | 31 ++++++----------------- extra/lists/lists-docs.factor | 26 ++++++++++++++++++-- extra/lists/lists.factor | 41 ++++++++++++++++++++++--------- extra/monads/monads.factor | 2 +- 5 files changed, 64 insertions(+), 38 deletions(-) diff --git a/extra/lists/lazy/lazy-docs.factor b/extra/lists/lazy/lazy-docs.factor index 1de98971f6..0e6c93766d 100644 --- a/extra/lists/lazy/lazy-docs.factor +++ b/extra/lists/lazy/lazy-docs.factor @@ -107,6 +107,8 @@ HELP: >list { $values { "object" "an object" } { "list" "a list" } } { $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." } { $see-also seq>list } ; + +{ leach lreduce lmap lmap-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lreduce lwhile luntil } related-words HELP: lconcat { $values { "list" "a list of lists" } { "result" "a list" } } diff --git a/extra/lists/lazy/lazy.factor b/extra/lists/lazy/lazy.factor index f8b1a6e6ef..7ab5bbb84e 100644 --- a/extra/lists/lazy/lazy.factor +++ b/extra/lists/lazy/lazy.factor @@ -44,21 +44,6 @@ M: lazy-cons nil? ( lazy-cons -- bool ) : 3lazy-list ( a b c -- lazy-cons ) 2lazy-list 1quotation lazy-cons ; -: lnth ( n list -- elt ) - swap [ cdr ] times car ; - -: (llength) ( list acc -- n ) - over nil? [ nip ] [ [ cdr ] dip 1+ (llength) ] if ; - -: llength ( list -- n ) - 0 (llength) ; - -: leach ( list quot -- ) - over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline - -: lreduce ( list identity quot -- result ) - swapd leach ; inline - TUPLE: memoized-cons original car cdr nil? ; : not-memoized ( -- obj ) @@ -96,7 +81,7 @@ TUPLE: lazy-map cons quot ; C: lazy-map -: lmap ( list quot -- result ) +: lazy-map ( list quot -- result ) over nil? [ 2drop nil ] [ ] if ; M: lazy-map car ( lazy-map -- car ) @@ -105,13 +90,13 @@ M: lazy-map car ( lazy-map -- car ) M: lazy-map cdr ( lazy-map -- cdr ) [ cons>> cdr ] keep - quot>> lmap ; + quot>> lazy-map ; M: lazy-map nil? ( lazy-map -- bool ) cons>> nil? ; -: lmap-with ( value list quot -- result ) - with lmap ; +: lazy-map-with ( value list quot -- result ) + with lazy-map ; TUPLE: lazy-take n cons ; @@ -323,22 +308,22 @@ M: lazy-concat nil? ( lazy-concat -- bool ) ] if ; : lcartesian-product ( list1 list2 -- result ) - swap [ swap [ 2array ] lmap-with ] lmap-with lconcat ; + swap [ swap [ 2array ] lazy-map-with ] lazy-map-with lconcat ; : lcartesian-product* ( lists -- result ) dup nil? [ drop nil ] [ [ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [ - swap [ swap [ suffix ] lmap-with ] lmap-with lconcat + swap [ swap [ suffix ] lazy-map-with ] lazy-map-with lconcat ] reduce ] if ; : lcomp ( list quot -- result ) - [ lcartesian-product* ] dip lmap ; + [ lcartesian-product* ] dip lazy-map ; : lcomp* ( list guards quot -- result ) - [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lmap ; + [ [ lcartesian-product* ] dip [ lfilter ] each ] dip lazy-map ; DEFER: lmerge diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor index 94407765fc..8a691cd4e2 100644 --- a/extra/lists/lists-docs.factor +++ b/extra/lists/lists-docs.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2006 Chris Double. ! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax ; IN: lists -USING: help.markup help.syntax ; { car cons cdr nil nil? list? uncons } related-words @@ -42,4 +42,26 @@ HELP: 2list HELP: 3list { $values { "a" "an object" } { "b" "an object" } { "c" "an object" } { "cons" "a cons object" } } -{ $description "Create a list with 3 elements." } ; \ No newline at end of file +{ $description "Create a list with 3 elements." } ; + +HELP: lnth +{ $values { "n" "an integer index" } { "list" "a cons object" } { "elt" "the element at the nth index" } } +{ $description "Outputs the nth element of the list." } +{ $see-also llength cons car cdr } ; + +HELP: llength +{ $values { "list" "a cons object" } { "n" "a non-negative integer" } } +{ $description "Outputs the length of the list. This should not be called on an infinite list." } +{ $see-also lnth cons car cdr } ; + +HELP: uncons +{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } } +{ $description "Put the head and tail of the list on the stack." } ; + +HELP: leach +{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } } +{ $description "Call the quotation for each item in the list." } ; + +HELP: lreduce +{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } } +{ $description "Combines successive elements of the list using a binary operation, and outputs the final result." } ; diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index 4b8cc77658..d9af80a2bc 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -1,10 +1,10 @@ -! Copyright (C) 2008 James Cash +! Copyright (C) 2008 Chris Double & James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences accessors ; +USING: kernel sequences accessors math ; IN: lists -! Lazy List Protocol +! List Protocol MIXIN: list GENERIC: car ( cons -- car ) GENERIC: cdr ( cons -- cdr ) @@ -28,31 +28,48 @@ M: cons nil? ( cons -- bool ) : 1list ( obj -- cons ) nil cons ; - + : 2list ( a b -- cons ) nil cons cons ; : 3list ( a b c -- cons ) nil cons cons cons ; +: 2car ( cons -- car caar ) + [ car ] [ cdr car ] bi ; + +: 3car ( cons -- car caar caaar ) + [ car ] [ cdr car ] [ cdr cdr car ] tri ; + : uncons ( cons -- cdr car ) [ cdr ] [ car ] bi ; +: lnth ( n list -- elt ) + swap [ cdr ] times car ; + +: (llength) ( list acc -- n ) + over nil? [ nip ] [ [ cdr ] dip 1+ (llength) ] if ; + +: llength ( list -- n ) + 0 (llength) ; + +: leach ( list quot -- ) + over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline + +: lreduce ( list identity quot -- result ) + swapd leach ; inline + : seq>cons ( seq -- cons ) nil [ f cons swap >>cdr ] reduce ; -: (map-cons) ( acc cons quot -- seq ) +: (lmap) ( acc cons quot -- seq ) over nil? [ 2drop ] - [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; + [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; inline -: map-cons ( cons quot -- seq ) - [ { } clone ] 2dip (map-cons) ; +: lmap ( cons quot -- seq ) + [ { } clone ] 2dip (map-cons) ; inline : cons>seq ( cons -- array ) [ ] map-cons ; -: reduce-cons ( cons identity quot -- result ) - pick nil? [ drop nip ] - [ [ uncons ] 2dip swapd [ call ] keep reduce-cons ] if ; - INSTANCE: cons list \ No newline at end of file diff --git a/extra/monads/monads.factor b/extra/monads/monads.factor index 18820d1b53..c1ab4400ba 100644 --- a/extra/monads/monads.factor +++ b/extra/monads/monads.factor @@ -124,7 +124,7 @@ M: list-monad fail 2drop nil ; M: list monad-of drop list-monad ; -M: list >>= '[ , _ lmap lconcat ] ; +M: list >>= '[ , _ lazy-map lconcat ] ; ! State SINGLETON: state-monad From 53daf5504a5e2faec4afc21e415d058370c3a546 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 16:31:38 -0400 Subject: [PATCH 0034/1850] Reorganizing docs for lists and lists.lazy to reflect words moving between the vocabs --- extra/lists/lazy/lazy-docs.factor | 26 ++------------------------ extra/lists/lists-docs.factor | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/extra/lists/lazy/lazy-docs.factor b/extra/lists/lazy/lazy-docs.factor index 0e6c93766d..f410b99317 100644 --- a/extra/lists/lazy/lazy-docs.factor +++ b/extra/lists/lazy/lazy-docs.factor @@ -28,31 +28,9 @@ HELP: { $description "Constructs a cons object that wraps an existing cons object. Requests for the car, cdr and nil? will be remembered after the first call, and the previous result returned on subsequent calls." } { $see-also cons car cdr nil nil? } ; -HELP: lnth -{ $values { "n" "an integer index" } { "list" "a cons object" } { "elt" "the element at the nth index" } } -{ $description "Outputs the nth element of the list." } -{ $see-also llength cons car cdr } ; +{ lazy-map lazy-map-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words -HELP: llength -{ $values { "list" "a cons object" } { "n" "a non-negative integer" } } -{ $description "Outputs the length of the list. This should not be called on an infinite list." } -{ $see-also lnth cons car cdr } ; - -HELP: uncons -{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } } -{ $description "Put the head and tail of the list on the stack." } ; - -{ leach lreduce lmap lmap-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lreduce lwhile luntil } related-words - -HELP: leach -{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } } -{ $description "Call the quotation for each item in the list." } ; - -HELP: lreduce -{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } } -{ $description "Combines successive elements of the list using a binary operation, and outputs the final result." } ; - -HELP: lmap +HELP: lazy-map { $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- X )" } { "result" "resulting cons object" } } { $description "Perform a similar functionality to that of the " { $link map } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ; diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor index 8a691cd4e2..1e5a5fd396 100644 --- a/extra/lists/lists-docs.factor +++ b/extra/lists/lists-docs.factor @@ -65,3 +65,18 @@ HELP: leach HELP: lreduce { $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } } { $description "Combines successive elements of the list using a binary operation, and outputs the final result." } ; + +HELP: uncons +{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } } +{ $description "Put the head and tail of the list on the stack." } ; + +{ leach lreduce lmap } related-words + +HELP: leach +{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } } +{ $description "Call the quotation for each item in the list." } ; + +HELP: lreduce +{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } } +{ $description "Combines successive elements of the list using a binary operation, and outputs the final result." } ; + From 0ca627051ea6d5bef5b1d18713653ee38bad2c8b Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 16:57:29 -0400 Subject: [PATCH 0035/1850] Changing vocabs USING: to reflect which words are in lists and lists.lazy --- extra/globs/globs.factor | 2 +- extra/lists/lazy/examples/examples.factor | 2 +- extra/lists/lazy/lazy-docs.factor | 6 +++--- extra/lists/lazy/lazy-tests.factor | 2 +- extra/lists/lists-tests.factor | 4 ++-- extra/math/primes/factors/factors.factor | 2 +- extra/parser-combinators/parser-combinators.factor | 8 ++++---- extra/project-euler/007/007.factor | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extra/globs/globs.factor b/extra/globs/globs.factor index db1921d86d..d131946ffb 100755 --- a/extra/globs/globs.factor +++ b/extra/globs/globs.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: parser-combinators regexp lists lists.lazy sequences kernel +USING: parser-combinators regexp lists sequences kernel promises strings unicode.case ; IN: globs diff --git a/extra/lists/lazy/examples/examples.factor b/extra/lists/lazy/examples/examples.factor index 844ae31085..9e8fb77439 100644 --- a/extra/lists/lazy/examples/examples.factor +++ b/extra/lists/lazy/examples/examples.factor @@ -11,5 +11,5 @@ IN: lazy-lists.examples : odds 1 lfrom [ 2 mod 1 = ] lfilter ; : powers-of-2 1 [ 2 * ] lfrom-by ; : ones 1 [ ] lfrom-by ; -: squares naturals [ dup * ] lmap ; +: squares naturals [ dup * ] lazy-map ; : first-five-squares 5 squares ltake list>array ; diff --git a/extra/lists/lazy/lazy-docs.factor b/extra/lists/lazy/lazy-docs.factor index f410b99317..f2b03fe108 100644 --- a/extra/lists/lazy/lazy-docs.factor +++ b/extra/lists/lazy/lazy-docs.factor @@ -34,9 +34,9 @@ HELP: lazy-map { $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- X )" } { "result" "resulting cons object" } } { $description "Perform a similar functionality to that of the " { $link map } " word, but in a lazy manner. No evaluation of the list elements occurs initially but a " { $link } " object is returned which conforms to the list protocol. Calling " { $link car } ", " { $link cdr } " or " { $link nil? } " on this will evaluate elements as required." } ; -HELP: lmap-with +HELP: lazy-map-with { $values { "value" "an object" } { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj elt -- X )" } { "result" "resulting cons object" } } -{ $description "Variant of " { $link lmap } " which pushes a retained object on each invocation of the quotation." } ; +{ $description "Variant of " { $link lazy-map } " which pushes a retained object on each invocation of the quotation." } ; HELP: ltake { $values { "n" "a non negative integer" } { "list" "a cons object" } { "result" "resulting cons object" } } @@ -86,7 +86,7 @@ HELP: >list { $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." } { $see-also seq>list } ; -{ leach lreduce lmap lmap-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lreduce lwhile luntil } related-words +{ leach lreduce lazy-map lazy-map-with ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lreduce lwhile luntil } related-words HELP: lconcat { $values { "list" "a list of lists" } { "result" "a list" } } diff --git a/extra/lists/lazy/lazy-tests.factor b/extra/lists/lazy/lazy-tests.factor index f4bb7b595b..5749f94364 100644 --- a/extra/lists/lazy/lazy-tests.factor +++ b/extra/lists/lazy/lazy-tests.factor @@ -25,5 +25,5 @@ IN: lists.lazy.tests ] unit-test [ { 4 5 6 } ] [ - 3 { 1 2 3 } >list [ + ] lmap-with list>array + 3 { 1 2 3 } >list [ + ] lazy-map-with list>array ] unit-test diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor index 41f2d1d356..718b4bff4e 100644 --- a/extra/lists/lists-tests.factor +++ b/extra/lists/lists-tests.factor @@ -9,7 +9,7 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - T{ cons f f f } } } } } [ 2 + ] map-cons + T{ cons f f f } } } } } [ 2 + ] lmap ] unit-test { 10 } [ @@ -17,5 +17,5 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - T{ cons f f f } } } } } 0 [ + ] reduce-cons + T{ cons f f f } } } } } 0 [ + ] lreduce ] unit-test \ No newline at end of file diff --git a/extra/math/primes/factors/factors.factor b/extra/math/primes/factors/factors.factor index b38a7926d2..aba7e90bc9 100644 --- a/extra/math/primes/factors/factors.factor +++ b/extra/math/primes/factors/factors.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Samuel Tardieu. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays kernel lists lists.lazy math math.primes namespaces sequences ; +USING: arrays kernel lists math math.primes namespaces sequences ; IN: math.primes.factors r parse-result-parsed r> [ parse-result-parsed 2array ] keep parse-result-unparsed - ] lmap-with - ] lmap-with lconcat ; + ] lazy-map-with + ] lazy-map-with lconcat ; M: and-parser parse ( input parser -- list ) #! Parse 'input' by sequentially combining the @@ -171,7 +171,7 @@ M: or-parser parse ( input parser1 -- list ) #! of parser1 and parser2 being applied to the same #! input. This implements the choice parsing operator. or-parser-parsers 0 swap seq>list - [ parse ] lmap-with lconcat ; + [ parse ] lazy-map-with lconcat ; : left-trim-slice ( string -- string ) #! Return a new string without any leading whitespace @@ -216,7 +216,7 @@ M: apply-parser parse ( input parser -- result ) -rot parse [ [ parse-result-parsed swap call ] keep parse-result-unparsed - ] lmap-with ; + ] lazy-map-with ; TUPLE: some-parser p1 ; diff --git a/extra/project-euler/007/007.factor b/extra/project-euler/007/007.factor index 40178c4291..04686a8328 100644 --- a/extra/project-euler/007/007.factor +++ b/extra/project-euler/007/007.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: lists.lazy math math.primes ; +USING: lists math math.primes ; IN: project-euler.007 ! http://projecteuler.net/index.php?section=problems&id=7 From 63089a21247d93389be2d2684fece06a50bc673b Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Tue, 3 Jun 2008 19:53:27 -0300 Subject: [PATCH 0036/1850] irc.client: Improve tests a bit --- extra/irc/client/client-tests.factor | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor index 9916621d47..968330ee3b 100644 --- a/extra/irc/client/client-tests.factor +++ b/extra/irc/client/client-tests.factor @@ -1,6 +1,6 @@ USING: kernel tools.test accessors arrays sequences qualified - io.streams.string io.streams.duplex namespaces - irc.client.private ; + io.streams.string io.streams.duplex namespaces threads + calendar irc.client.private ; EXCLUDE: irc.client => join ; IN: irc.client.tests @@ -12,6 +12,9 @@ IN: irc.client.tests "someserver" irc-port "factorbot" f swap [ 2nip f ] curry >>connect ; +: set-nick ( irc-client nickname -- ) + [ nick>> ] dip >>name drop ; + : with-dummy-client ( quot -- ) rot with-variable ; inline @@ -37,7 +40,7 @@ privmsg new [ ":someuser!n=user@some.where PRIVMSG #factortest :hi" parse-irc-line f >>timestamp ] unit-test -{ "" } make-client dup nick>> "factorbot" >>name drop current-irc-client [ +{ "" } make-client dup "factorbot" set-nick current-irc-client [ { t } [ irc-client> nick>> name>> me? ] unit-test { "factorbot" } [ irc-client> nick>> name>> ] unit-test @@ -51,5 +54,26 @@ privmsg new parse-irc-line irc-message-origin ] unit-test ] with-variable -! Client tests -{ } [ { "" } make-client connect-irc ] unit-test \ No newline at end of file +! Test login and nickname set +{ "factorbot" } [ { "NOTICE AUTH :*** Looking up your hostname..." + "NOTICE AUTH :*** Checking ident" + "NOTICE AUTH :*** Found your hostname" + "NOTICE AUTH :*** No identd (auth) response" + ":some.where 001 factorbot :Welcome factorbot" + } make-client + [ connect-irc ] keep 1 seconds sleep + nick>> name>> ] unit-test + +! TODO: Channel join messages +! { ":factorbot!n=factorbo@some.where JOIN :#factortest" +! ":ircserver.net MODE #factortest +ns" +! ":ircserver.net 353 factorbot @ #factortest :@factorbot " +! ":ircserver.net 366 factorbot #factortest :End of /NAMES list." +! ":ircserver.net 477 factorbot #factortest :[ircserver-info] blah blah" +! } make-client dup "factorbot" set-nick +! TODO: user join +! ":somedude!n=user@isp.net JOIN :#factortest" +! TODO: channel message +! ":somedude!n=user@isp.net PRIVMSG #factortest :hello" +! TODO: direct private message +! ":somedude!n=user@isp.net PRIVMSG factorbot2 :hello" \ No newline at end of file From b5405f69ae8e48c7495cddff6348bf9819929f3b Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 20:11:03 -0400 Subject: [PATCH 0037/1850] adding map-as, fixing seq>cons --- extra/lists/lists.factor | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index d9af80a2bc..0af026edd1 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Chris Double & James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences accessors math ; +USING: kernel sequences accessors math arrays vectors classes ; IN: lists @@ -55,21 +55,27 @@ M: cons nil? ( cons -- bool ) : leach ( list quot -- ) over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline - + : lreduce ( list identity quot -- result ) swapd leach ; inline -: seq>cons ( seq -- cons ) - nil [ f cons swap >>cdr ] reduce ; - : (lmap) ( acc cons quot -- seq ) over nil? [ 2drop ] - [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (map-cons) ] if ; inline + [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap) ] if ; inline : lmap ( cons quot -- seq ) - [ { } clone ] 2dip (map-cons) ; inline + [ { } clone ] 2dip (lmap) ; inline + +: lmap-as ( cons quot exemplar -- seq ) + [ lmap ] dip like ; + +: same? ( obj1 obj2 -- ? ) + [ class ] bi@ = ; + +: seq>cons ( seq -- cons ) + [ ] keep nil [ tuck same? [ seq>cons ] when f cons swap >>cdr ] with reduce ; : cons>seq ( cons -- array ) - [ ] map-cons ; + [ ] lmap ; INSTANCE: cons list \ No newline at end of file From b3808a08d5cc83cf4e685dfc5e89f3790efeae3b Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 20:11:27 -0400 Subject: [PATCH 0038/1850] Removing duplicate entries in lists-docs --- extra/lists/lists-docs.factor | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor index 1e5a5fd396..4fae52f5b4 100644 --- a/extra/lists/lists-docs.factor +++ b/extra/lists/lists-docs.factor @@ -58,18 +58,6 @@ HELP: uncons { $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } } { $description "Put the head and tail of the list on the stack." } ; -HELP: leach -{ $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } } -{ $description "Call the quotation for each item in the list." } ; - -HELP: lreduce -{ $values { "list" "a cons object" } { "identity" "an object" } { "quot" "a quotation with stack effect ( prev elt -- next )" } { "result" "the final result" } } -{ $description "Combines successive elements of the list using a binary operation, and outputs the final result." } ; - -HELP: uncons -{ $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } } -{ $description "Put the head and tail of the list on the stack." } ; - { leach lreduce lmap } related-words HELP: leach From 65f9fd92315ad53f7ffa44bfd46c18d555e6678e Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 20:11:45 -0400 Subject: [PATCH 0039/1850] Adding more tests for lists --- extra/lists/lists-tests.factor | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor index 718b4bff4e..8e78872a52 100644 --- a/extra/lists/lists-tests.factor +++ b/extra/lists/lists-tests.factor @@ -9,13 +9,34 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - T{ cons f f f } } } } } [ 2 + ] lmap + nil } } } } [ 2 + ] lmap ] unit-test { 10 } [ - T{ cons f 1 + T{ cons f 1 T{ cons f 2 T{ cons f 3 T{ cons f 4 - T{ cons f f f } } } } } 0 [ + ] lreduce + nil } } } } 0 [ + ] lreduce +] unit-test + +T{ + cons + f + 1 + T{ + cons + f + 2 + T{ + cons + f + T{ cons f 3 T{ cons f 4 T{ cons f 5 nil } } } + T{ cons f f f } + } } } [ + { 1 2 { 3 4 { 5 } } } seq>cons +] unit-test + +{ { 1 2 { 3 4 { 5 } } } } [ + { 1 2 { 3 4 { 5 } } } seq>cons cons>seq ] unit-test \ No newline at end of file From ed0468b8f520d4d0f568e3ca3f01fe985ab77bef Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 23:38:56 -0400 Subject: [PATCH 0040/1850] Fixing typo in lists-tests --- extra/lists/lists-tests.factor | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor index 8e78872a52..16bc65ebb3 100644 --- a/extra/lists/lists-tests.factor +++ b/extra/lists/lists-tests.factor @@ -9,7 +9,7 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - nil } } } } [ 2 + ] lmap + T{ cons f f f } } } } } [ 2 + ] lmap ] unit-test { 10 } [ @@ -17,23 +17,23 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - nil } } } } 0 [ + ] lreduce + T{ cons f f f } } } } } 0 [ + ] lreduce ] unit-test -T{ - cons - f - 1 - T{ - cons - f - 2 - T{ - cons - f - T{ cons f 3 T{ cons f 4 T{ cons f 5 nil } } } - T{ cons f f f } - } } } [ +{ T{ cons f + 1 + T{ cons f + 2 + T{ cons f + T{ cons f + 3 + T{ cons f + 4 + T{ cons f + T{ cons f 5 T{ cons f f f } } + T{ cons f f f } } } } + T{ cons f f f } } } } +} [ { 1 2 { 3 4 { 5 } } } seq>cons ] unit-test From f63e6f1e35a7332fb50385c74c3157f28cfcfbfc Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 23:39:45 -0400 Subject: [PATCH 0041/1850] Fixing some bugs/oddities in lists implementations --- extra/lists/lists.factor | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index 0af026edd1..b7e5e6523f 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -22,10 +22,13 @@ M: cons cdr ( cons -- cdr ) : nil ( -- cons ) T{ cons f f f } ; + +: uncons ( cons -- cdr car ) + [ cdr ] [ car ] bi ; -M: cons nil? ( cons -- bool ) - nil eq? ; - +M: cons nil? ( cons -- ? ) + uncons and not ; + : 1list ( obj -- cons ) nil cons ; @@ -40,9 +43,6 @@ M: cons nil? ( cons -- bool ) : 3car ( cons -- car caar caaar ) [ car ] [ cdr car ] [ cdr cdr car ] tri ; - -: uncons ( cons -- cdr car ) - [ cdr ] [ car ] bi ; : lnth ( n list -- elt ) swap [ cdr ] times car ; @@ -57,14 +57,15 @@ M: cons nil? ( cons -- bool ) over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline : lreduce ( list identity quot -- result ) - swapd leach ; inline + pick nil? [ drop nip ] + [ [ uncons ] 2dip swapd [ call ] keep lreduce ] if ; inline : (lmap) ( acc cons quot -- seq ) over nil? [ 2drop ] [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap) ] if ; inline : lmap ( cons quot -- seq ) - [ { } clone ] 2dip (lmap) ; inline + { } -rot (lmap) ; inline : lmap-as ( cons quot exemplar -- seq ) [ lmap ] dip like ; @@ -76,6 +77,6 @@ M: cons nil? ( cons -- bool ) [ ] keep nil [ tuck same? [ seq>cons ] when f cons swap >>cdr ] with reduce ; : cons>seq ( cons -- array ) - [ ] lmap ; + [ dup cons? [ cons>seq ] when ] lmap ; INSTANCE: cons list \ No newline at end of file From 138fff1c2b9404e2d148780cc93f96424d1afbf2 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 23:40:30 -0400 Subject: [PATCH 0042/1850] Temporarily removing test for 'list' in lisp-tests, while switching to cons cells --- extra/lisp/lisp-tests.factor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/lisp/lisp-tests.factor b/extra/lisp/lisp-tests.factor index 2358fa3f7e..2603a75cb0 100644 --- a/extra/lisp/lisp-tests.factor +++ b/extra/lisp/lisp-tests.factor @@ -13,7 +13,7 @@ IN: lisp.test "+" "math" "+" define-primitive "-" "math" "-" define-primitive - "list" [ >array ] lisp-define +! "list" [ >array ] lisp-define { 5 } [ [ 2 3 ] "+" funcall @@ -47,8 +47,8 @@ IN: lisp.test "((lambda (x) (if x (begin (+ 1 2)) (- 3 5))) #t)" lisp-eval ] unit-test - { { 1 2 3 4 5 } } [ - "(list 1 2 3 4 5)" lisp-eval - ] unit-test +! { { 1 2 3 4 5 } } [ +! "(list 1 2 3 4 5)" lisp-eval +! ] unit-test ] with-interactive-vocabs From 09d11546415d78912a2054722bef1fada8acc000 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 3 Jun 2008 23:41:05 -0400 Subject: [PATCH 0043/1850] Lisp now passes all tests using conses --- extra/lisp/lisp.factor | 45 ++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index b034619d0d..fdcea0eca1 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -3,7 +3,7 @@ USING: kernel peg sequences arrays strings combinators.lib namespaces combinators math locals locals.private accessors vectors syntax lisp.parser assocs parser sequences.lib words quotations -fry lists ; +fry lists inspector ; IN: lisp DEFER: convert-form @@ -16,36 +16,36 @@ DEFER: macro-call ! Functions to convert s-exps to quotations ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : convert-body ( cons -- quot ) - [ ] [ convert-form compose ] reduce-cons ; inline + [ ] [ convert-form compose ] lreduce ; inline : convert-if ( cons -- quot ) - cdr first3 [ convert-form ] tri@ '[ @ , , if ] ; + cdr 3car [ convert-form ] tri@ '[ @ , , if ] ; : convert-begin ( cons -- quot ) - cdr [ convert-form ] [ ] map-as '[ , [ funcall ] each ] ; + cdr [ convert-form ] [ ] lmap-as '[ , [ funcall ] each ] ; : convert-cond ( cons -- quot ) - cdr [ body>> first2 [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ] - { } map-as '[ , cond ] ; + cdr [ 2car [ convert-form ] bi@ [ '[ @ funcall ] ] dip 2array ] + { } lmap-as '[ , cond ] ; : convert-general-form ( cons -- quot ) - uncons convert-form swap convert-body swap '[ , @ funcall ] ; + uncons [ convert-body ] [ convert-form ] bi* '[ , @ funcall ] ; ! words for convert-lambda > ] dip at swap or ] - [ dup cons? [ localize-body ] when ] if - ] map-cons ; + dupd [ dup lisp-symbol? [ tuck name>> swap at swap or ] + [ dup cons? [ localize-body ] when nip ] if + ] with lmap ; : localize-lambda ( body vars -- newbody newvars ) make-locals dup push-locals swap - [ swap localize-body cons convert-form swap pop-locals ] dip swap ; + [ swap localize-body seq>cons convert-form swap pop-locals ] dip swap ; -: split-lambda ( cons -- body vars ) - first3 -rot nip [ body>> ] bi@ [ name>> ] map ; inline +: split-lambda ( cons -- body-cons vars-seq ) + 3car -rot nip [ name>> ] lmap ; inline -: rest-lambda ( body vars -- quot ) +: rest-lambda ( body vars -- quot ) "&rest" swap [ index ] [ remove ] 2bi localize-lambda '[ , cut '[ @ , ] , compose ] ; @@ -97,15 +97,20 @@ PRIVATE> SYMBOL: lisp-env ERROR: no-such-var var ; + +SYMBOL: macro-env + +M: no-such-var summary drop "No such variable" ; : init-env ( -- ) - H{ } clone lisp-env set ; + H{ } clone lisp-env set + H{ } clone macro-env set ; : lisp-define ( name quot -- ) swap lisp-env get set-at ; : lisp-get ( name -- word ) - dup lisp-env get at [ ] [ no-such-var throw ] ?if ; + dup lisp-env get at [ ] [ no-such-var ] ?if ; : lookup-var ( lisp-symbol -- quot ) name>> lisp-get ; @@ -114,4 +119,10 @@ ERROR: no-such-var var ; dup lisp-symbol? [ lookup-var ] when call ; inline : define-primitive ( name vocab word -- ) - swap lookup 1quotation '[ , compose call ] lisp-define ; \ No newline at end of file + swap lookup 1quotation '[ , compose call ] lisp-define ; + +: lookup-macro ( lisp-symbol -- macro ) + name>> macro-env get at ; + +: lisp-macro? ( car -- ? ) + dup lisp-symbol? [ name>> macro-env get key? ] [ drop f ] if ; \ No newline at end of file From 8a7dfd76da4dbda2731f63d85efcd514d5106ed7 Mon Sep 17 00:00:00 2001 From: James Cash Date: Wed, 4 Jun 2008 00:02:29 -0400 Subject: [PATCH 0044/1850] Fixing implementation of leach --- extra/lists/lists.factor | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index b7e5e6523f..f9b7b89e5b 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -54,11 +54,10 @@ M: cons nil? ( cons -- ? ) 0 (llength) ; : leach ( list quot -- ) - over nil? [ 2drop ] [ [ uncons ] dip tuck call leach ] if ; inline + over nil? [ 2drop ] [ [ uncons swap ] dip tuck [ call ] 2dip leach ] if ; inline : lreduce ( list identity quot -- result ) - pick nil? [ drop nip ] - [ [ uncons ] 2dip swapd [ call ] keep lreduce ] if ; inline + swapd leach ; inline : (lmap) ( acc cons quot -- seq ) over nil? [ 2drop ] From ed18f7d37b24789fc07ba00ac2399344dbb20be9 Mon Sep 17 00:00:00 2001 From: James Cash Date: Wed, 4 Jun 2008 00:56:06 -0400 Subject: [PATCH 0045/1850] Fixing implementation of nil --- extra/lisp/parser/parser-tests.factor | 9 +++---- extra/lists/lists-docs.factor | 2 +- extra/lists/lists-tests.factor | 16 +++++++----- extra/lists/lists.factor | 36 ++++++++++++++++----------- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/extra/lisp/parser/parser-tests.factor b/extra/lisp/parser/parser-tests.factor index 41254db5b3..4aa8154690 100644 --- a/extra/lisp/parser/parser-tests.factor +++ b/extra/lisp/parser/parser-tests.factor @@ -40,8 +40,7 @@ IN: lisp.parser.tests "+" "atom" \ lisp-expr rule parse parse-result-ast ] unit-test -{ T{ cons f f f } -} [ +{ +nil+ } [ "()" lisp-expr parse-result-ast ] unit-test @@ -53,7 +52,7 @@ IN: lisp.parser.tests cons f 1 - T{ cons f 2 T{ cons f "aoeu" T{ cons f f f } } } + T{ cons f 2 T{ cons f "aoeu" +nil+ } } } } } [ "(foo 1 2 \"aoeu\")" lisp-expr parse-result-ast ] unit-test @@ -61,8 +60,8 @@ IN: lisp.parser.tests { T{ cons f 1 T{ cons f - T{ cons f 3 T{ cons f 4 T{ cons f f f } } } - T{ cons f 2 T{ cons f f } } } + T{ cons f 3 T{ cons f 4 +nil+ } } + T{ cons f 2 +nil+ } } } } [ "(1 (3 4) 2)" lisp-expr parse-result-ast diff --git a/extra/lists/lists-docs.factor b/extra/lists/lists-docs.factor index 4fae52f5b4..51b068d979 100644 --- a/extra/lists/lists-docs.factor +++ b/extra/lists/lists-docs.factor @@ -58,7 +58,7 @@ HELP: uncons { $values { "cons" "a cons object" } { "car" "the head of the list" } { "cdr" "the tail of the list" } } { $description "Put the head and tail of the list on the stack." } ; -{ leach lreduce lmap } related-words +{ leach lreduce lmap>array } related-words HELP: leach { $values { "list" "a cons object" } { "quot" "a quotation with stack effect ( obj -- )" } } diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor index 16bc65ebb3..534c20245b 100644 --- a/extra/lists/lists-tests.factor +++ b/extra/lists/lists-tests.factor @@ -9,7 +9,7 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - T{ cons f f f } } } } } [ 2 + ] lmap + +nil+ } } } } [ 2 + ] lmap>array ] unit-test { 10 } [ @@ -17,7 +17,7 @@ IN: lists.tests T{ cons f 2 T{ cons f 3 T{ cons f 4 - T{ cons f f f } } } } } 0 [ + ] lreduce + +nil+ } } } } 0 [ + ] lreduce ] unit-test { T{ cons f @@ -30,13 +30,17 @@ IN: lists.tests T{ cons f 4 T{ cons f - T{ cons f 5 T{ cons f f f } } - T{ cons f f f } } } } - T{ cons f f f } } } } + T{ cons f 5 +nil+ } + +nil+ } } } + +nil+ } } } } [ { 1 2 { 3 4 { 5 } } } seq>cons ] unit-test { { 1 2 { 3 4 { 5 } } } } [ { 1 2 { 3 4 { 5 } } } seq>cons cons>seq -] unit-test \ No newline at end of file +] unit-test + +! { { 3 4 { 5 6 { 7 } } } } [ +! { 1 2 { 3 4 { 5 } } } seq>cons [ 2 + ] traverse cons>seq +! ] unit-test \ No newline at end of file diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index f9b7b89e5b..388bfb5bd7 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Chris Double & James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences accessors math arrays vectors classes ; +USING: kernel sequences accessors math arrays vectors classes words ; IN: lists @@ -8,8 +8,8 @@ IN: lists MIXIN: list GENERIC: car ( cons -- car ) GENERIC: cdr ( cons -- cdr ) -GENERIC: nil? ( cons -- ? ) - +GENERIC: nil? ( cons -- ? ) + TUPLE: cons car cdr ; C: cons cons @@ -19,15 +19,15 @@ M: cons car ( cons -- car ) M: cons cdr ( cons -- cdr ) cdr>> ; + +SYMBOL: +nil+ +M: word nil? +nil+ eq? ; +M: object nil? drop f ; -: nil ( -- cons ) - T{ cons f f f } ; +: nil ( -- +nil+ ) +nil+ ; : uncons ( cons -- cdr car ) [ cdr ] [ car ] bi ; - -M: cons nil? ( cons -- ? ) - uncons and not ; : 1list ( obj -- cons ) nil cons ; @@ -59,15 +59,18 @@ M: cons nil? ( cons -- ? ) : lreduce ( list identity quot -- result ) swapd leach ; inline -: (lmap) ( acc cons quot -- seq ) - over nil? [ 2drop ] - [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap) ] if ; inline +! : lmap ( cons quot -- newcons ) -: lmap ( cons quot -- seq ) - { } -rot (lmap) ; inline + +: (lmap>array) ( acc cons quot -- newcons ) + over nil? [ 2drop ] + [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap>array) ] if ; inline + +: lmap>array ( cons quot -- newcons ) + { } -rot (lmap>array) ; inline : lmap-as ( cons quot exemplar -- seq ) - [ lmap ] dip like ; + [ lmap>array ] dip like ; : same? ( obj1 obj2 -- ? ) [ class ] bi@ = ; @@ -76,6 +79,9 @@ M: cons nil? ( cons -- ? ) [ ] keep nil [ tuck same? [ seq>cons ] when f cons swap >>cdr ] with reduce ; : cons>seq ( cons -- array ) - [ dup cons? [ cons>seq ] when ] lmap ; + [ dup cons? [ cons>seq ] when ] lmap>array ; + +: traverse ( list quot -- newlist ) + [ over list? [ traverse ] [ call ] if ] curry ; INSTANCE: cons list \ No newline at end of file From fb247829346f513d047a897fa72d36edc6f0932d Mon Sep 17 00:00:00 2001 From: James Cash Date: Wed, 4 Jun 2008 00:56:30 -0400 Subject: [PATCH 0046/1850] Fixing indentation in lists/lazy --- extra/lists/lazy/lazy.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/lists/lazy/lazy.factor b/extra/lists/lazy/lazy.factor index 7ab5bbb84e..03e5b0f8cc 100644 --- a/extra/lists/lazy/lazy.factor +++ b/extra/lists/lazy/lazy.factor @@ -82,7 +82,7 @@ TUPLE: lazy-map cons quot ; C: lazy-map : lazy-map ( list quot -- result ) - over nil? [ 2drop nil ] [ ] if ; + over nil? [ 2drop nil ] [ ] if ; M: lazy-map car ( lazy-map -- car ) [ cons>> car ] keep @@ -265,7 +265,7 @@ M: sequence-cons cdr ( sequence-cons -- cdr ) seq>> seq>list ; M: sequence-cons nil? ( sequence-cons -- bool ) - drop f ; + drop f ; : >list ( object -- list ) { From 3ec7d8c20d7fa4987a13e02357a35e98dd06fd4a Mon Sep 17 00:00:00 2001 From: James Cash Date: Wed, 4 Jun 2008 00:58:02 -0400 Subject: [PATCH 0047/1850] Changing names of lmap to lmap>array --- extra/lisp/lisp.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index fdcea0eca1..616efcbb1d 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -36,14 +36,14 @@ DEFER: macro-call : localize-body ( assoc body -- assoc newbody ) dupd [ dup lisp-symbol? [ tuck name>> swap at swap or ] [ dup cons? [ localize-body ] when nip ] if - ] with lmap ; + ] with lmap>array ; : localize-lambda ( body vars -- newbody newvars ) make-locals dup push-locals swap [ swap localize-body seq>cons convert-form swap pop-locals ] dip swap ; : split-lambda ( cons -- body-cons vars-seq ) - 3car -rot nip [ name>> ] lmap ; inline + 3car -rot nip [ name>> ] lmap>array ; inline : rest-lambda ( body vars -- quot ) "&rest" swap [ index ] [ remove ] 2bi From bb050c9f4c6f9581be9b6407737c5a271082b0c1 Mon Sep 17 00:00:00 2001 From: James Cash Date: Wed, 4 Jun 2008 01:40:51 -0400 Subject: [PATCH 0048/1850] Adding lmap and traverse to extra/lists --- extra/lists/lists-tests.factor | 4 ++++ extra/lists/lists.factor | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/extra/lists/lists-tests.factor b/extra/lists/lists-tests.factor index 534c20245b..0abb8befeb 100644 --- a/extra/lists/lists-tests.factor +++ b/extra/lists/lists-tests.factor @@ -41,6 +41,10 @@ IN: lists.tests { 1 2 { 3 4 { 5 } } } seq>cons cons>seq ] unit-test +{ T{ cons f 2 T{ cons f 3 T{ cons f 4 T{ cons f 5 +nil+ } } } } } [ + { 1 2 3 4 } seq>cons [ 1+ ] lmap +] unit-test + ! { { 3 4 { 5 6 { 7 } } } } [ ! { 1 2 { 3 4 { 5 } } } seq>cons [ 2 + ] traverse cons>seq ! ] unit-test \ No newline at end of file diff --git a/extra/lists/lists.factor b/extra/lists/lists.factor index 388bfb5bd7..b0fd41fe75 100644 --- a/extra/lists/lists.factor +++ b/extra/lists/lists.factor @@ -59,9 +59,6 @@ M: object nil? drop f ; : lreduce ( list identity quot -- result ) swapd leach ; inline -! : lmap ( cons quot -- newcons ) - - : (lmap>array) ( acc cons quot -- newcons ) over nil? [ 2drop ] [ [ uncons ] dip [ call ] keep swapd [ suffix ] 2dip (lmap>array) ] if ; inline @@ -72,6 +69,9 @@ M: object nil? drop f ; : lmap-as ( cons quot exemplar -- seq ) [ lmap>array ] dip like ; +: lmap ( list quot -- newlist ) + lmap>array nil [ swap cons ] reduce ; + : same? ( obj1 obj2 -- ? ) [ class ] bi@ = ; @@ -82,6 +82,6 @@ M: object nil? drop f ; [ dup cons? [ cons>seq ] when ] lmap>array ; : traverse ( list quot -- newlist ) - [ over list? [ traverse ] [ call ] if ] curry ; + [ over list? [ traverse ] [ call ] if ] curry lmap ; INSTANCE: cons list \ No newline at end of file From 180c7d317878c0d3f7c7b8f2f411e7854d4142c7 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 4 Jun 2008 19:14:20 -0500 Subject: [PATCH 0049/1850] Fix doublec's http.client bugs --- extra/http/client/client.factor | 9 ++++----- extra/openssl/openssl.factor | 8 ++++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/extra/http/client/client.factor b/extra/http/client/client.factor index e6c8791e20..7b48bf93af 100755 --- a/extra/http/client/client.factor +++ b/extra/http/client/client.factor @@ -22,7 +22,7 @@ DEFER: http-request SYMBOL: redirects : redirect-url ( request url -- request ) - '[ , >url derive-url ensure-port ] change-url ; + '[ , >url ensure-port derive-url ensure-port ] change-url ; : do-redirect ( response data -- response data ) over code>> 300 399 between? [ @@ -100,12 +100,11 @@ M: download-failed error. : download ( url -- ) dup download-name download-to ; -: ( content-type content url -- request ) +: ( post-data url -- request ) "POST" >>method swap >url ensure-port >>url - swap >>post-data - swap >>post-data-type ; + swap >>post-data ; -: http-post ( content-type content url -- response data ) +: http-post ( post-data url -- response data ) http-request ; diff --git a/extra/openssl/openssl.factor b/extra/openssl/openssl.factor index 03343820db..28fa49dfce 100755 --- a/extra/openssl/openssl.factor +++ b/extra/openssl/openssl.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors byte-arrays kernel debugger sequences namespaces math math.order combinators init alien alien.c-types alien.strings libc -continuations destructors debugger inspector +continuations destructors debugger inspector splitting locals unicode.case openssl.libcrypto openssl.libssl io.backend io.ports io.files io.encodings.8-bit io.sockets.secure @@ -188,8 +188,12 @@ M: ssl-handle dispose* [ 256 X509_NAME_get_text_by_NID ] keep swap -1 = [ drop f ] [ latin1 alien>string ] if ; +: common-names-match? ( expected actual -- ? ) + [ >lower ] bi@ "*." ?head [ tail? ] [ = ] if ; + : check-common-name ( host ssl-handle -- ) - SSL_get_peer_certificate common-name 2dup [ >lower ] bi@ = + SSL_get_peer_certificate common-name + 2dup common-names-match? [ 2drop ] [ common-name-verify-error ] if ; M: openssl check-certificate ( host ssl -- ) From 7cc553c4b6d4f2b0470242f815a6588e0852867b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 4 Jun 2008 19:33:30 -0500 Subject: [PATCH 0050/1850] Documentation improvements --- core/kernel/kernel-docs.factor | 15 ++++++++++++--- core/syntax/syntax-docs.factor | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/kernel/kernel-docs.factor b/core/kernel/kernel-docs.factor index c39010f228..82f0db1364 100755 --- a/core/kernel/kernel-docs.factor +++ b/core/kernel/kernel-docs.factor @@ -219,6 +219,16 @@ $nl { $example "t \\ t eq? ." "t" } "Many words which search collections confuse the case of no element being present with an element being found equal to " { $link f } ". If this distinction is imporant, there is usually an alternative word which can be used; for example, compare " { $link at } " with " { $link at* } "." ; +ARTICLE: "conditionals-boolean-equivalence" "Expressing conditionals with boolean logic" +"Certain simple conditional forms can be expressed in a simpler manner using boolean logic." +$nl +"The following two lines are equivalent:" +{ $code "[ drop f ] unless" "swap and" } +"The following two lines are equivalent:" +{ $code "[ ] [ ] ?if" "swap or" } +"The following two lines are equivalent, where " { $snippet "L" } " is a literal:" +{ $code "[ L ] unless*" "L or" } ; + ARTICLE: "conditionals" "Conditionals and logic" "The basic conditionals:" { $subsection if } @@ -238,6 +248,7 @@ ARTICLE: "conditionals" "Conditionals and logic" { $subsection and } { $subsection or } { $subsection xor } +{ $subsection "conditionals-boolean-equivalence" } "See " { $link "combinators" } " for forms which abstract away common patterns involving multiple nested branches." { $see-also "booleans" "bitwise-arithmetic" both? either? } ; @@ -720,9 +731,7 @@ HELP: unless* { $description "Variant of " { $link if* } " with no true quotation." } { $notes "The following two lines are equivalent:" -{ $code "X [ Y ] unless*" "X dup [ ] [ drop Y ] if" } -"The following two lines are equivalent, where " { $snippet "L" } " is a literal:" -{ $code "[ L ] unless*" "L or" } } ; +{ $code "X [ Y ] unless*" "X dup [ ] [ drop Y ] if" } } ; HELP: ?if { $values { "default" object } { "cond" "a generalized boolean" } { "true" "a quotation with stack effect " { $snippet "( cond -- )" } } { "false" "a quotation with stack effect " { $snippet "( default -- )" } } } diff --git a/core/syntax/syntax-docs.factor b/core/syntax/syntax-docs.factor index 0dc834ad6b..18595aaab3 100755 --- a/core/syntax/syntax-docs.factor +++ b/core/syntax/syntax-docs.factor @@ -346,7 +346,7 @@ HELP: \ { $syntax "\\ word" } { $values { "word" "a word" } } { $description "Reads the next word from the input and appends a wrapper holding the word to the parse tree. When the evaluator encounters a wrapper, it pushes the wrapped word literally on the data stack." } -{ $examples "The following two lines are equivalent:" { $code "0 \\ execute\n0 " } } ; +{ $examples "The following two lines are equivalent:" { $code "0 \\ execute\n0 " } "If " { $snippet "foo" } " is a symbol, the following two lines are equivalent:" { $code "foo" "\\ foo" } } ; HELP: DEFER: { $syntax "DEFER: word" } From ab5843d83174469fd2120c5e83aac77346dc88e4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 4 Jun 2008 19:33:43 -0500 Subject: [PATCH 0051/1850] Don't need MEMO: there anymore according to doublec --- extra/io/unix/launcher/parser/parser.factor | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/extra/io/unix/launcher/parser/parser.factor b/extra/io/unix/launcher/parser/parser.factor index f3bb82343a..e5e83ab4e9 100755 --- a/extra/io/unix/launcher/parser/parser.factor +++ b/extra/io/unix/launcher/parser/parser.factor @@ -1,7 +1,6 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: peg peg.parsers kernel sequences strings words -memoize ; +USING: peg peg.parsers kernel sequences strings words ; IN: io.unix.launcher.parser ! Our command line parser. Supported syntax: @@ -9,20 +8,20 @@ IN: io.unix.launcher.parser ! foo\ bar -- escaping the space ! 'foo bar' -- quotation ! "foo bar" -- quotation -MEMO: 'escaped-char' ( -- parser ) - "\\" token [ drop t ] satisfy 2seq [ second ] action ; +: 'escaped-char' ( -- parser ) + "\\" token any-char 2seq [ second ] action ; -MEMO: 'quoted-char' ( delimiter -- parser' ) +: 'quoted-char' ( delimiter -- parser' ) 'escaped-char' swap [ member? not ] curry satisfy 2choice ; inline -MEMO: 'quoted' ( delimiter -- parser ) +: 'quoted' ( delimiter -- parser ) dup 'quoted-char' repeat0 swap dup surrounded-by ; -MEMO: 'unquoted' ( -- parser ) " '\"" 'quoted-char' repeat1 ; +: 'unquoted' ( -- parser ) " '\"" 'quoted-char' repeat1 ; -MEMO: 'argument' ( -- parser ) +: 'argument' ( -- parser ) "\"" 'quoted' "'" 'quoted' 'unquoted' 3choice From 9861146d8d38fdb34ec8005c830c50c25e42cb37 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 4 Jun 2008 19:54:05 -0500 Subject: [PATCH 0052/1850] Implement flash scopes, improved validation and login page, improved http-post --- extra/furnace/actions/actions.factor | 92 ++++++++++++------- extra/furnace/asides/asides.factor | 73 +++++++++++++++ extra/furnace/auth/login/login.factor | 48 +++++++--- extra/furnace/auth/login/login.xml | 13 +++ extra/furnace/flash/flash.factor | 38 ++++++++ extra/furnace/flows/flows.factor | 78 ---------------- extra/furnace/furnace-tests.factor | 7 +- extra/furnace/furnace.factor | 57 ++++++------ extra/furnace/sessions/sessions.factor | 13 +-- extra/html/components/components.factor | 22 +++-- extra/html/templates/chloe/chloe-tests.factor | 20 ++++ extra/html/templates/chloe/chloe.factor | 13 ++- extra/html/templates/chloe/test/test10.xml | 3 + extra/html/templates/chloe/test/test11.xml | 14 +++ extra/http/http-tests.factor | 71 ++++++++++++-- extra/http/http.factor | 72 +++++++++------ extra/http/server/cgi/cgi.factor | 8 +- extra/http/server/server-tests.factor | 4 + extra/http/server/server.factor | 2 +- .../factor-website/factor-website.factor | 6 +- extra/webapps/pastebin/paste.xml | 6 +- extra/webapps/pastebin/pastebin-common.xml | 4 +- extra/webapps/pastebin/pastebin.factor | 14 ++- extra/webapps/planet/planet-common.xml | 4 +- extra/webapps/planet/planet.factor | 5 +- extra/webapps/todo/todo.factor | 3 +- extra/webapps/todo/todo.xml | 4 +- extra/webapps/user-admin/user-admin.factor | 16 +--- extra/webapps/user-admin/user-admin.xml | 4 +- extra/webapps/wiki/changes.xml | 2 +- extra/webapps/wiki/wiki-common.xml | 4 +- extra/webapps/wiki/wiki.factor | 13 ++- extra/xml-rpc/example.factor | 4 +- extra/xml-rpc/xml-rpc.factor | 3 +- 34 files changed, 486 insertions(+), 254 deletions(-) create mode 100644 extra/furnace/asides/asides.factor create mode 100644 extra/furnace/flash/flash.factor delete mode 100644 extra/furnace/flows/flows.factor create mode 100644 extra/html/templates/chloe/test/test10.xml create mode 100644 extra/html/templates/chloe/test/test11.xml create mode 100644 extra/http/server/server-tests.factor diff --git a/extra/furnace/actions/actions.factor b/extra/furnace/actions/actions.factor index 5e237b02a8..7340a532e9 100755 --- a/extra/furnace/actions/actions.factor +++ b/extra/furnace/actions/actions.factor @@ -2,13 +2,15 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors sequences kernel assocs combinators validators http hashtables namespaces fry continuations locals -io arrays math boxes +io arrays math boxes splitting urls xml.entities http.server http.server.responses furnace +furnace.flash html.elements html.components +html.components html.templates.chloe html.templates.chloe.syntax ; IN: furnace.actions @@ -39,48 +41,68 @@ TUPLE: action rest-param init display validate submit ; : ( -- action ) action new-action ; +: flashed-variables ( -- seq ) + { validation-messages named-validation-messages } ; + : handle-get ( action -- response ) - blank-values - [ init>> call ] - [ display>> call ] - bi ; + '[ + , + [ init>> call ] + [ drop flashed-variables restore-flash ] + [ display>> call ] + tri + ] with-exit-continuation ; : validation-failed ( -- * ) - request get method>> "POST" = - [ action get display>> call ] [ <400> ] if exit-with ; + request get method>> "POST" = [ f ] [ <400> ] if exit-with ; -: handle-post ( action -- response ) - init-validation - blank-values - [ validate>> call ] - [ submit>> call ] bi ; - -: handle-rest-param ( arg -- ) - dup length 1 > action get rest-param>> not or - [ <404> exit-with ] [ - action get rest-param>> associate rest-param set - ] if ; - -M: action call-responder* ( path action -- response ) - dup action set - '[ - , dup empty? [ drop ] [ handle-rest-param ] if - - init-validation - , - request get - [ request-params rest-param get assoc-union params set ] - [ method>> ] bi - { - { "GET" [ handle-get ] } - { "HEAD" [ handle-get ] } - { "POST" [ handle-post ] } - } case - ] with-exit-continuation ; +: (handle-post) ( action -- response ) + [ validate>> call ] [ submit>> call ] bi ; : param ( name -- value ) params get at ; +: revalidate-url-key "__u" ; + +: check-url ( url -- ? ) + request get url>> + [ [ protocol>> ] [ host>> ] [ port>> ] tri 3array ] bi@ = ; + +: revalidate-url ( -- url/f ) + revalidate-url-key param dup [ >url dup check-url swap and ] when ; + +: handle-post ( action -- response ) + '[ + form-nesting-key params get at " " split + [ , (handle-post) ] + [ swap '[ , , nest-values ] ] reduce + call + ] with-exit-continuation + [ + revalidate-url + [ flashed-variables ] [ <403> ] if* + ] unless* ; + +: handle-rest-param ( path action -- assoc ) + rest-param>> dup [ associate ] [ 2drop f ] if ; + +: init-action ( path action -- ) + blank-values + init-validation + handle-rest-param + request get request-params assoc-union params set ; + +M: action call-responder* ( path action -- response ) + [ init-action ] keep + request get method>> { + { "GET" [ handle-get ] } + { "HEAD" [ handle-get ] } + { "POST" [ handle-post ] } + } case ; + +M: action modify-form + drop request get url>> revalidate-url-key hidden-form-field ; + : check-validation ( -- ) validation-failed? [ validation-failed ] when ; diff --git a/extra/furnace/asides/asides.factor b/extra/furnace/asides/asides.factor new file mode 100644 index 0000000000..f6b4e2c15f --- /dev/null +++ b/extra/furnace/asides/asides.factor @@ -0,0 +1,73 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors namespaces sequences arrays kernel +assocs assocs.lib hashtables math.parser urls combinators +furnace http http.server http.server.filters furnace.sessions +html.elements html.templates.chloe.syntax ; +IN: furnace.asides + +TUPLE: asides < filter-responder ; + +C: asides + +: begin-aside* ( -- id ) + request get + [ url>> ] [ post-data>> ] [ method>> ] tri 3array + asides sget set-at-unique + session-changed ; + +: end-aside-post ( url post-data -- response ) + request [ + clone + swap >>post-data + swap >>url + ] change + request get url>> path>> split-path + asides get responder>> call-responder ; + +ERROR: end-aside-in-get-error ; + +: end-aside* ( url id -- response ) + request get method>> "POST" = [ end-aside-in-get-error ] unless + asides sget at [ + first3 { + { "GET" [ drop ] } + { "HEAD" [ drop ] } + { "POST" [ end-aside-post ] } + } case + ] [ ] ?if ; + +SYMBOL: aside-id + +: aside-id-key "__a" ; + +: begin-aside ( -- ) + begin-aside* aside-id set ; + +: end-aside ( default -- response ) + aside-id [ f ] change end-aside* ; + +M: asides call-responder* + dup asides set + aside-id-key request get request-params at aside-id set + call-next-method ; + +M: asides init-session* + H{ } clone asides sset + call-next-method ; + +M: asides link-attr ( tag -- ) + drop + "aside" optional-attr { + { "none" [ aside-id off ] } + { "begin" [ begin-aside ] } + { "current" [ ] } + { f [ ] } + } case ; + +M: asides modify-query ( query responder -- query' ) + drop + aside-id get [ aside-id-key associate assoc-union ] when* ; + +M: asides modify-form ( responder -- ) + drop aside-id get aside-id-key hidden-form-field ; diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 58ab47e3e1..d0c4e00953 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors quotations assocs kernel splitting combinators sequences namespaces hashtables sets -fry arrays threads qualified random validators +fry arrays threads qualified random validators words io io.sockets io.encodings.utf8 @@ -26,14 +26,29 @@ furnace.auth furnace.auth.providers furnace.auth.providers.db furnace.actions -furnace.flows +furnace.asides +furnace.flash furnace.sessions furnace.boilerplate ; QUALIFIED: smtp IN: furnace.auth.login +: word>string ( word -- string ) + [ word-vocabulary ] [ drop ":" ] [ word-name ] tri 3append ; + +: words>strings ( seq -- seq' ) + [ word>string ] map ; + +: string>word ( string -- word ) + ":" split1 swap lookup ; + +: strings>words ( seq -- seq' ) + [ string>word ] map ; + TUPLE: login < dispatcher users checksum ; +TUPLE: protected < filter-responder description capabilities ; + : users ( -- provider ) login get users>> ; @@ -64,7 +79,7 @@ M: user-saver dispose ! ! ! Login : successful-login ( user -- response ) - username>> set-uid URL" $login" end-flow ; + username>> set-uid URL" $login" end-aside ; : login-failed ( -- * ) "invalid username or password" validation-error @@ -72,6 +87,13 @@ M: user-saver dispose : ( -- action ) + [ + protected fget [ + [ description>> "description" set-value ] + [ capabilities>> words>strings "capabilities" set-value ] bi + ] when* + ] >>init + { login "login" } >>template [ @@ -177,7 +199,7 @@ M: user-saver dispose drop - URL" $login" end-flow + URL" $login" end-aside ] >>submit ; ! ! ! Password recovery @@ -290,23 +312,23 @@ SYMBOL: lost-password-from [ f set-uid - URL" $login" end-flow + URL" $login" end-aside ] >>submit ; ! ! ! Authentication logic - -TUPLE: protected < filter-responder capabilities ; - -C: protected +: ( responder -- protected ) + protected new + swap >>responder ; : show-login-page ( -- response ) - begin-flow - URL" $login/login" ; + begin-aside + URL" $login/login" { protected } ; : check-capabilities ( responder user -- ? ) [ capabilities>> ] bi@ subset? ; M: protected call-responder* ( path responder -- response ) + dup protected set uid dup [ users get-user 2dup check-capabilities [ [ logged-in-user set ] [ save-user-after ] bi @@ -337,7 +359,9 @@ M: login call-responder* ( path responder -- response ) ! ! ! Configuration : allow-edit-profile ( login -- login ) - f + + "edit your profile" >>description + "edit-profile" add-responder ; : allow-registration ( login -- login ) diff --git a/extra/furnace/auth/login/login.xml b/extra/furnace/auth/login/login.xml index a52aed59d7..a7ac92bf44 100644 --- a/extra/furnace/auth/login/login.xml +++ b/extra/furnace/auth/login/login.xml @@ -4,6 +4,19 @@ Login + +

You must log in to .

+
+ + +

Your user must have the following capabilities:

+
    + +
  • +
    +
+
+ diff --git a/extra/furnace/flash/flash.factor b/extra/furnace/flash/flash.factor new file mode 100644 index 0000000000..21fd20ccb4 --- /dev/null +++ b/extra/furnace/flash/flash.factor @@ -0,0 +1,38 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: namespaces assocs assocs.lib kernel sequences urls +http http.server http.server.filters http.server.redirection +furnace furnace.sessions ; +IN: furnace.flash + +: flash-id-key "__f" ; + +TUPLE: flash-scopes < filter-responder ; + +C: flash-scopes + +SYMBOL: flash-scope + +: fget ( key -- value ) flash-scope get at ; + +M: flash-scopes call-responder* + flash-id-key + request get request-params at + flash-scopes sget at flash-scope set + call-next-method ; + +M: flash-scopes init-session* + H{ } clone flash-scopes sset + call-next-method ; + +: make-flash-scope ( seq -- id ) + [ dup get ] H{ } map>assoc flash-scopes sget set-at-unique + session-changed ; + +: ( url seq -- response ) + make-flash-scope + [ clone ] dip flash-id-key set-query-param + ; + +: restore-flash ( seq -- ) + [ flash-scope get key? ] filter [ [ fget ] keep set ] each ; diff --git a/extra/furnace/flows/flows.factor b/extra/furnace/flows/flows.factor deleted file mode 100644 index eb98c1a26b..0000000000 --- a/extra/furnace/flows/flows.factor +++ /dev/null @@ -1,78 +0,0 @@ -! Copyright (C) 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: accessors namespaces sequences arrays kernel -assocs assocs.lib hashtables math.parser urls combinators -furnace http http.server http.server.filters furnace.sessions -html.elements html.templates.chloe.syntax ; -IN: furnace.flows - -TUPLE: flows < filter-responder ; - -C: flows - -: begin-flow* ( -- id ) - request get - [ url>> ] [ post-data>> ] [ method>> ] tri 3array - flows sget set-at-unique - session-changed ; - -: end-flow-post ( url post-data -- response ) - request [ - clone - "POST" >>method - swap >>post-data - swap >>url - ] change - request get url>> path>> split-path - flows get responder>> call-responder ; - -: end-flow* ( url id -- response ) - flows sget at [ - first3 { - { "GET" [ drop ] } - { "HEAD" [ drop ] } - { "POST" [ end-flow-post ] } - } case - ] [ ] ?if ; - -SYMBOL: flow-id - -: flow-id-key "factorflowid" ; - -: begin-flow ( -- ) - begin-flow* flow-id set ; - -: end-flow ( default -- response ) - flow-id get end-flow* ; - -M: flows call-responder* - dup flows set - flow-id-key request get request-params at flow-id set - call-next-method ; - -M: flows init-session* - H{ } clone flows sset - call-next-method ; - -M: flows link-attr ( tag -- ) - drop - "flow" optional-attr { - { "none" [ flow-id off ] } - { "begin" [ begin-flow ] } - { "current" [ ] } - { f [ ] } - } case ; - -M: flows modify-query ( query responder -- query' ) - drop - flow-id get [ flow-id-key associate assoc-union ] when* ; - -M: flows hidden-form-field ( responder -- ) - drop - flow-id get [ - - ] when* ; diff --git a/extra/furnace/furnace-tests.factor b/extra/furnace/furnace-tests.factor index 5cf2dad9ad..f07fe620d8 100644 --- a/extra/furnace/furnace-tests.factor +++ b/extra/furnace/furnace-tests.factor @@ -1,6 +1,7 @@ IN: furnace.tests USING: http.server.dispatchers http.server.responses -http.server furnace tools.test kernel namespaces accessors ; +http.server furnace tools.test kernel namespaces accessors +io.streams.string ; TUPLE: funny-dispatcher < dispatcher ; : funny-dispatcher new-dispatcher ; @@ -28,3 +29,7 @@ M: base-path-check-responder call-responder* V{ } responder-nesting set "a/b/c" split-path main-responder get call-responder body>> ] unit-test + +[ "" ] +[ [ "&&&" "foo" hidden-form-field ] with-string-writer ] +unit-test diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index 370c4f84a3..f61ec5ff40 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -6,6 +6,7 @@ vocabs.loader classes fry urls multiline xml xml.data +xml.entities xml.writer xml.utilities html.components @@ -64,15 +65,19 @@ M: object modify-query drop ; { "POST" [ ] } } case ; -GENERIC: hidden-form-field ( responder -- ) +GENERIC: modify-form ( responder -- ) -M: object hidden-form-field drop ; +M: object modify-form drop ; : request-params ( request -- assoc ) dup method>> { { "GET" [ url>> query>> ] } { "HEAD" [ url>> query>> ] } - { "POST" [ post-data>> ] } + { "POST" [ + post-data>> + dup content-type>> "application/x-www-form-urlencoded" = + [ content>> ] [ drop f ] if + ] } } case ; SYMBOL: exit-continuation @@ -128,20 +133,34 @@ CHLOE: a [ drop ] tri ; +: hidden-form-field ( value name -- ) + over [ + string =value + input/> + ] [ 2drop ] if ; + +: form-nesting-key "factorformnesting" ; + +: form-magic ( tag -- ) + [ modify-form ] each-responder + nested-values get " " join f like form-nesting-key hidden-form-field + "for" optional-attr [ hidden render ] when* ; + : form-start-tag ( tag -- ) [ [
- ] [ - [ hidden-form-field ] each-responder - "for" optional-attr [ hidden render ] when* - ] bi + ] + [ form-magic ] bi ] with-scope ; CHLOE: form @@ -167,17 +186,3 @@ CHLOE: button [ [ children>string 1array ] dip "button" tag-named set-tag-children ] [ nip ] } 2cleave process-chloe-tag ; - -: attr>word ( value -- word/f ) - dup ":" split1 swap lookup - [ ] [ "No such word: " swap append throw ] ?if ; - -: attr>var ( value -- word/f ) - attr>word dup symbol? [ - "Must be a symbol: " swap append throw - ] unless ; - -: if-satisfied? ( tag -- ? ) - "code" required-attr attr>word execute ; - -CHLOE: if dup if-satisfied? [ process-tag-children ] [ drop ] if ; diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 5ea389c87e..16fefe42fc 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -109,14 +109,14 @@ M: session-saver dispose [ session set ] [ save-session-after ] bi sessions get responder>> call-responder ; -: session-id-key "factorsessid" ; +: session-id-key "__s" ; : cookie-session-id ( request -- id/f ) session-id-key get-cookie dup [ value>> string>number ] when ; : post-session-id ( request -- id/f ) - session-id-key swap post-data>> at string>number ; + session-id-key swap request-params at string>number ; : request-session-id ( -- id/f ) request get dup method>> { @@ -137,13 +137,8 @@ M: session-saver dispose : put-session-cookie ( response -- response' ) session get id>> number>string put-cookie ; -M: sessions hidden-form-field ( responder -- ) - drop - > number>string =value - input/> ; +M: sessions modify-form ( responder -- ) + drop session get id>> session-id-key hidden-form-field ; M: sessions call-responder* ( path responder -- response ) sessions set diff --git a/extra/html/components/components.factor b/extra/html/components/components.factor index c013007a14..90a00ed4ef 100644 --- a/extra/html/components/components.factor +++ b/extra/html/components/components.factor @@ -29,22 +29,30 @@ SYMBOL: values : deposit-slots ( destination names -- ) [ ] dip deposit-values ; -: with-each-index ( seq quot -- ) - '[ +: with-each-index ( name quot -- ) + [ value ] dip '[ [ - values [ clone ] change + blank-values 1+ "index" set-value @ ] with-scope ] each-index ; inline -: with-each-value ( seq quot -- ) +: with-each-value ( name quot -- ) '[ "value" set-value @ ] with-each-index ; inline -: with-each-object ( seq quot -- ) +: with-each-object ( name quot -- ) '[ from-object @ ] with-each-index ; inline -: with-values ( object quot -- ) - '[ blank-values , from-object @ ] with-scope ; inline +SYMBOL: nested-values + +: with-values ( name quot -- ) + '[ + , + [ nested-values [ swap prefix ] change ] + [ value blank-values from-object ] + bi + @ + ] with-scope ; inline : nest-values ( name quot -- ) swap [ diff --git a/extra/html/templates/chloe/chloe-tests.factor b/extra/html/templates/chloe/chloe-tests.factor index d4c02061b2..e50f65141e 100644 --- a/extra/html/templates/chloe/chloe-tests.factor +++ b/extra/html/templates/chloe/chloe-tests.factor @@ -148,3 +148,23 @@ TUPLE: person first-name last-name ; "test9" test-template call-template ] run-template ] unit-test + +[ ] [ H{ { "a" H{ { "b" "c" } } } } values set ] unit-test + +[ "" ] [ + [ + "test10" test-template call-template + ] run-template +] unit-test + +[ ] [ blank-values ] unit-test + +[ ] [ + H{ { "first-name" "RBaxter" } { "last-name" "Unknown" } } "person" set-value +] unit-test + +[ "
RBaxterUnknown
" ] [ + [ + "test11" test-template call-template + ] run-template [ blank? not ] filter +] unit-test diff --git a/extra/html/templates/chloe/chloe.factor b/extra/html/templates/chloe/chloe.factor index 9e0aa3fe1d..cb56bd71ce 100644 --- a/extra/html/templates/chloe/chloe.factor +++ b/extra/html/templates/chloe/chloe.factor @@ -68,7 +68,7 @@ CHLOE: odd "index" value odd? [ process-tag-children ] [ drop ] if ; : (bind-tag) ( tag quot -- ) [ - [ "name" required-attr value ] keep + [ "name" required-attr ] keep '[ , process-tag-children ] ] dip call ; inline @@ -85,6 +85,17 @@ CHLOE: comment drop ; CHLOE: call-next-template drop call-next-template ; +: attr>word ( value -- word/f ) + dup ":" split1 swap lookup + [ ] [ "No such word: " swap append throw ] ?if ; + +: if-satisfied? ( tag -- ? ) + [ "code" optional-attr [ attr>word execute ] [ t ] if* ] + [ "value" optional-attr [ value ] [ t ] if* ] + bi and ; + +CHLOE: if dup if-satisfied? [ process-tag-children ] [ drop ] if ; + CHLOE-SINGLETON: label CHLOE-SINGLETON: link CHLOE-SINGLETON: farkup diff --git a/extra/html/templates/chloe/test/test10.xml b/extra/html/templates/chloe/test/test10.xml new file mode 100644 index 0000000000..33fe2008a5 --- /dev/null +++ b/extra/html/templates/chloe/test/test10.xml @@ -0,0 +1,3 @@ + + + diff --git a/extra/html/templates/chloe/test/test11.xml b/extra/html/templates/chloe/test/test11.xml new file mode 100644 index 0000000000..f74256bd84 --- /dev/null +++ b/extra/html/templates/chloe/test/test11.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + +
+ +
diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 471d7e276b..c1d5b46aa4 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -1,15 +1,16 @@ USING: http tools.test multiline tuple-syntax io.streams.string kernel arrays splitting sequences -assocs io.sockets db db.sqlite continuations urls ; +assocs io.sockets db db.sqlite continuations urls hashtables ; IN: http.tests : lf>crlf "\n" split "\r\n" join ; STRING: read-request-test-1 -GET http://foo/bar HTTP/1.1 +POST http://foo/bar HTTP/1.1 Some-Header: 1 Some-Header: 2 Content-Length: 4 +Content-type: application/octet-stream blah ; @@ -17,10 +18,10 @@ blah [ TUPLE{ request url: TUPLE{ url protocol: "http" port: 80 path: "/bar" } - method: "GET" + method: "POST" version: "1.1" - header: H{ { "some-header" "1; 2" } { "content-length" "4" } } - post-data: "blah" + header: H{ { "some-header" "1; 2" } { "content-length" "4" } { "content-type" "application/octet-stream" } } + post-data: TUPLE{ post-data content: "blah" raw: "blah" content-type: "application/octet-stream" } cookies: V{ } } ] [ @@ -30,8 +31,9 @@ blah ] unit-test STRING: read-request-test-1' -GET /bar HTTP/1.1 +POST /bar HTTP/1.1 content-length: 4 +content-type: application/octet-stream some-header: 1; 2 blah @@ -87,7 +89,7 @@ blah code: 404 message: "not found" header: H{ { "content-type" "text/html; charset=UTF8" } } - cookies: V{ } + cookies: { } content-type: "text/html" content-charset: "UTF8" } @@ -172,7 +174,7 @@ test-db [ [ ] [ [ - f + "" add-responder @@ -219,3 +221,56 @@ test-db [ [ "Hi" ] [ "http://localhost:1237/" http-get ] unit-test [ "Goodbye" ] [ "http://localhost:1237/quit" http-get ] unit-test + +USING: html.components html.elements xml xml.utilities validators +furnace furnace.flash ; + +SYMBOL: a + +[ ] [ + [ + + + [ a get-global "a" set-value ] >>init + [ [ "a" render ] "text/html" ] >>display + [ { { "a" [ v-integer ] } } validate-params ] >>validate + [ "a" value a set-global URL" " ] >>submit + + + >>default + add-quit-action + test-db + main-responder set + + [ 1237 httpd ] "HTTPD test" spawn drop + ] with-scope +] unit-test + +[ ] [ 100 sleep ] unit-test + +3 a set-global + +: test-a string>xml "input" tag-named "value" swap at ; + +[ "3" ] [ + "http://localhost:1237/" http-get* + swap dup cookies>> "cookies" set session-id-key get-cookie + value>> "session-id" set test-a +] unit-test + +[ "4" ] [ + H{ { "a" "4" } { "__u" "http://localhost:1237/" } } "session-id" get session-id-key associate assoc-union + "http://localhost:1237/" "cookies" get >>cookies http-request nip test-a +] unit-test + +[ 4 ] [ a get-global ] unit-test + +! Test flash scope +[ "xyz" ] [ + H{ { "a" "xyz" } { "__u" "http://localhost:1237/" } } "session-id" get session-id-key associate assoc-union + "http://localhost:1237/" "cookies" get >>cookies http-request nip test-a +] unit-test + +[ 4 ] [ a get-global ] unit-test + +[ "Goodbye" ] [ "http://localhost:1237/quit" http-get ] unit-test diff --git a/extra/http/http.factor b/extra/http/http.factor index e8f7189f75..7499796b77 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -10,7 +10,7 @@ io io.server io.sockets.secure unicode.case unicode.categories qualified -urls html.templates ; +urls html.templates xml xml.data xml.writer ; EXCLUDE: fry => , ; @@ -132,7 +132,6 @@ url version header post-data -post-data-type cookies ; : set-header ( request/response value key -- request/response ) @@ -177,19 +176,27 @@ cookies ; : header ( request/response key -- value ) swap header>> at ; -SYMBOL: max-post-request +TUPLE: post-data raw content content-type ; -1024 256 * max-post-request set-global +: ( raw content-type -- post-data ) + post-data new + swap >>content-type + swap >>raw ; -: content-length ( header -- n ) - "content-length" swap at string>number dup [ - dup max-post-request get > [ - "content-length > max-post-request" throw - ] when - ] when ; +: parse-post-data ( post-data -- post-data ) + [ ] [ raw>> ] [ content-type>> ] tri { + { "application/x-www-form-urlencoded" [ query>assoc ] } + { "text/xml" [ string>xml ] } + [ drop ] + } case >>content ; : read-post-data ( request -- request ) - dup header>> content-length [ read >>post-data ] when* ; + dup method>> "POST" = [ + [ ] + [ "content-length" header string>number read ] + [ "content-type" header ] tri + parse-post-data >>post-data + ] when ; : extract-host ( request -- request ) [ ] [ url>> ] [ "host" header parse-host ] tri @@ -197,13 +204,6 @@ SYMBOL: max-post-request ensure-port drop ; -: extract-post-data-type ( request -- request ) - dup "content-type" header >>post-data-type ; - -: parse-post-data ( request -- request ) - dup post-data-type>> "application/x-www-form-urlencoded" = - [ dup post-data>> query>assoc >>post-data ] when ; - : extract-cookies ( request -- request ) dup "cookie" header [ parse-cookies >>cookies ] when* ; @@ -225,8 +225,6 @@ SYMBOL: max-post-request read-post-data detect-protocol extract-host - extract-post-data-type - parse-post-data extract-cookies ; : write-method ( request -- request ) @@ -238,12 +236,6 @@ SYMBOL: max-post-request : write-version ( request -- request ) "HTTP/" write dup request-version write crlf ; -: unparse-post-data ( request -- request ) - dup post-data>> dup sequence? [ drop ] [ - assoc>query >>post-data - "application/x-www-form-urlencoded" >>post-data-type - ] if ; - : url-host ( url -- string ) [ host>> ] [ port>> ] bi dup "http" protocol-port = [ drop ] [ ":" swap number>string 3append ] if ; @@ -251,13 +243,33 @@ SYMBOL: max-post-request : write-request-header ( request -- request ) dup header>> >hashtable over url>> host>> [ over url>> url-host "host" pick set-at ] when - over post-data>> [ length "content-length" pick set-at ] when* - over post-data-type>> [ "content-type" pick set-at ] when* + over post-data>> [ + [ raw>> length "content-length" pick set-at ] + [ content-type>> "content-type" pick set-at ] + bi + ] when* over cookies>> f like [ unparse-cookies "cookie" pick set-at ] when* write-header ; +GENERIC: >post-data ( object -- post-data ) + +M: post-data >post-data ; + +M: string >post-data "application/octet-stream" ; + +M: byte-array >post-data "application/octet-stream" ; + +M: xml >post-data xml>string "text/xml" ; + +M: assoc >post-data assoc>query "application/x-www-form-urlencoded" ; + +M: f >post-data ; + +: unparse-post-data ( request -- request ) + [ >post-data ] change-post-data ; + : write-post-data ( request -- request ) - dup post-data>> [ write ] when* ; + dup method>> "POST" = [ dup post-data>> raw>> write ] when ; : write-request ( request -- ) unparse-post-data @@ -307,7 +319,7 @@ body ; : read-response-header read-header >>header - extract-cookies + dup "set-cookie" header parse-cookies >>cookies dup "content-type" header [ parse-content-type [ >>content-type ] [ >>content-charset ] bi* ] when* ; diff --git a/extra/http/server/cgi/cgi.factor b/extra/http/server/cgi/cgi.factor index cf8a35f141..a6d8948790 100755 --- a/extra/http/server/cgi/cgi.factor +++ b/extra/http/server/cgi/cgi.factor @@ -35,8 +35,10 @@ IN: http.server.cgi request get "accept" header "HTTP_ACCEPT" set post? [ - request get post-data-type>> "CONTENT_TYPE" set - request get post-data>> length number>string "CONTENT_LENGTH" set + request get post-data>> raw>> + [ "CONTENT_TYPE" set ] + [ length number>string "CONTENT_LENGTH" set ] + bi ] when ] H{ } make-assoc ; @@ -51,7 +53,7 @@ IN: http.server.cgi "CGI output follows" >>message swap '[ , output-stream get swap [ - post? [ request get post-data>> write flush ] when + post? [ request get post-data>> raw>> write flush ] when input-stream get swap (stream-copy) ] with-stream ] >>body ; diff --git a/extra/http/server/server-tests.factor b/extra/http/server/server-tests.factor new file mode 100644 index 0000000000..c29912b8c7 --- /dev/null +++ b/extra/http/server/server-tests.factor @@ -0,0 +1,4 @@ +USING: http http.server math sequences continuations tools.test ; +IN: http.server.tests + +[ t ] [ [ \ + first ] [ <500> ] recover response? ] unit-test diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 756a0de0ff..10d6070f7b 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -40,7 +40,7 @@ main-responder global [ <404> or ] change-at : <500> ( error -- response ) 500 "Internal server error" - development-mode get [ swap '[ , http-error. ] >>body ] [ drop ] if ; + swap development-mode get [ '[ , http-error. ] >>body ] [ drop ] if ; : do-response ( response -- ) dup write-response diff --git a/extra/webapps/factor-website/factor-website.factor b/extra/webapps/factor-website/factor-website.factor index 853af6e845..cd6dde255c 100644 --- a/extra/webapps/factor-website/factor-website.factor +++ b/extra/webapps/factor-website/factor-website.factor @@ -6,7 +6,8 @@ namespaces db db.sqlite smtp http.server http.server.dispatchers furnace.db -furnace.flows +furnace.asides +furnace.flash furnace.sessions furnace.auth.login furnace.auth.providers.db @@ -53,8 +54,7 @@ TUPLE: factor-website < dispatcher ; allow-edit-profile { factor-website "page" } >>template - - + test-db ; : init-factor-website ( -- ) diff --git a/extra/webapps/pastebin/paste.xml b/extra/webapps/pastebin/paste.xml index 9f35d83fd8..453f7b590b 100644 --- a/extra/webapps/pastebin/paste.xml +++ b/extra/webapps/pastebin/paste.xml @@ -28,7 +28,7 @@
- Delete Annotation + Delete Annotation @@ -36,13 +36,13 @@

New Annotation

- + - + diff --git a/extra/webapps/pastebin/pastebin-common.xml b/extra/webapps/pastebin/pastebin-common.xml index 5ef44ad6ce..a27a1290dd 100644 --- a/extra/webapps/pastebin/pastebin-common.xml +++ b/extra/webapps/pastebin/pastebin-common.xml @@ -14,10 +14,10 @@ - | Edit Profile + | Edit Profile - | Logout + | Logout diff --git a/extra/webapps/pastebin/pastebin.factor b/extra/webapps/pastebin/pastebin.factor index 69650b4d73..06cdd5adf0 100644 --- a/extra/webapps/pastebin/pastebin.factor +++ b/extra/webapps/pastebin/pastebin.factor @@ -132,7 +132,7 @@ M: annotation entity-link "id" value "new-annotation" [ - "id" set-value + "parent" set-value mode-names "modes" set-value "factor" "mode" set-value ] nest-values @@ -212,12 +212,12 @@ M: annotation entity-link ] >>display [ - { { "id" [ v-integer ] } } validate-params + { { "parent" [ v-integer ] } } validate-params validate-entity ] >>validate [ - "id" value f + "parent" value f [ deposit-entity-slots ] [ insert-tuple ] [ entity-link ] @@ -246,9 +246,13 @@ can-delete-pastes? define-capability "paste" add-responder "paste.atom" add-responder "new-paste" add-responder - { can-delete-pastes? } "delete-paste" add-responder + + "delete pastes" >>description + { can-delete-pastes? } >>capabilities "delete-paste" add-responder "new-annotation" add-responder - { can-delete-pastes? } "delete-annotation" add-responder + + "delete annotations" >>description + { can-delete-pastes? } >>capabilities "delete-annotation" add-responder { pastebin "pastebin-common" } >>template ; diff --git a/extra/webapps/planet/planet-common.xml b/extra/webapps/planet/planet-common.xml index e92f88c2c2..34ee73da67 100644 --- a/extra/webapps/planet/planet-common.xml +++ b/extra/webapps/planet/planet-common.xml @@ -11,10 +11,10 @@ - | Edit Profile + | Edit Profile - | Logout + | Logout diff --git a/extra/webapps/planet/planet.factor b/extra/webapps/planet/planet.factor index c5fa5e25d4..3c0e2ad267 100755 --- a/extra/webapps/planet/planet.factor +++ b/extra/webapps/planet/planet.factor @@ -198,7 +198,10 @@ can-administer-planet-factor? define-capability planet-factor new-dispatcher "list" add-main-responder "feed.xml" add-responder - { can-administer-planet-factor? } "admin" add-responder + + "administer Planet Factor" >>description + { can-administer-planet-factor? } >>capabilities + "admin" add-responder { planet-factor "planet-common" } >>template ; diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index 3600e2f874..1cecbc1094 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -122,4 +122,5 @@ todo "TODO" "delete" add-responder { todo-list "todo" } >>template - f ; + + "view your todo list" >>description ; diff --git a/extra/webapps/todo/todo.xml b/extra/webapps/todo/todo.xml index 3dd0b9a7d1..e087fbfcfc 100644 --- a/extra/webapps/todo/todo.xml +++ b/extra/webapps/todo/todo.xml @@ -9,10 +9,10 @@ | Add Item - | Edit Profile + | Edit Profile - | Logout + | Logout

diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index b8687274f0..78c972fa34 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -18,18 +18,6 @@ IN: webapps.user-admin TUPLE: user-admin < dispatcher ; -: word>string ( word -- string ) - [ word-vocabulary ] [ drop ":" ] [ word-name ] tri 3append ; - -: words>strings ( seq -- seq' ) - [ word>string ] map ; - -: string>word ( string -- word ) - ":" split1 swap lookup ; - -: strings>words ( seq -- seq' ) - [ string>word ] map ; - : ( -- action ) [ f select-tuples "users" set-value ] >>init @@ -156,7 +144,9 @@ can-administer-users? define-capability "delete" add-responder { user-admin "user-admin" } >>template - { can-administer-users? } ; + + "administer users" >>description + { can-administer-users? } >>capabilities ; : make-admin ( username -- ) diff --git a/extra/webapps/user-admin/user-admin.xml b/extra/webapps/user-admin/user-admin.xml index 93a701a696..9cb9ef0a0a 100644 --- a/extra/webapps/user-admin/user-admin.xml +++ b/extra/webapps/user-admin/user-admin.xml @@ -7,10 +7,10 @@ | Add User - | Edit Profile + | Edit Profile - | Logout + | Logout

diff --git a/extra/webapps/wiki/changes.xml b/extra/webapps/wiki/changes.xml index 95fb0de2fe..5b3e9de2c4 100644 --- a/extra/webapps/wiki/changes.xml +++ b/extra/webapps/wiki/changes.xml @@ -7,7 +7,7 @@
  • - + on by diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml index 67a5b91c93..c3d203cd2e 100644 --- a/extra/webapps/wiki/wiki-common.xml +++ b/extra/webapps/wiki/wiki-common.xml @@ -13,10 +13,10 @@ - | Edit Profile + | Edit Profile - | Logout + | Logout diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 6dcf89e208..dd2e1291f9 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -214,6 +214,10 @@ revision "REVISIONS" { { wiki "user-edits" } >>template ; +SYMBOL: can-delete-wiki-articles? + +can-delete-wiki-articles? define-capability + : ( -- dispatcher ) wiki new-dispatcher @@ -222,7 +226,9 @@ revision "REVISIONS" { "revision" add-responder "revisions" add-responder "diff" add-responder - { } "edit" add-responder + + "edit wiki articles" >>description + "edit" add-responder { wiki "page-common" } >>template >>default @@ -230,6 +236,9 @@ revision "REVISIONS" { "user-edits" add-responder "articles" add-responder "changes" add-responder - { } "delete" add-responder + + "delete wiki articles" >>description + { can-delete-wiki-articles? } >>capabilities + "delete" add-responder { wiki "wiki-common" } >>template ; diff --git a/extra/xml-rpc/example.factor b/extra/xml-rpc/example.factor index 0223dfde69..836a85d52d 100644 --- a/extra/xml-rpc/example.factor +++ b/extra/xml-rpc/example.factor @@ -22,6 +22,6 @@ USING: kernel hashtables xml-rpc xml calendar sequences put-http-response ; : test-rpc-arith - "add" { 1 2 } send-rpc xml>string - "text/xml" swap "http://localhost:8080/responder/rpc/" + "add" { 1 2 } send-rpc + "http://localhost:8080/responder/rpc/" http-post ; diff --git a/extra/xml-rpc/xml-rpc.factor b/extra/xml-rpc/xml-rpc.factor index d41f66739c..4b96d13316 100755 --- a/extra/xml-rpc/xml-rpc.factor +++ b/extra/xml-rpc/xml-rpc.factor @@ -158,8 +158,7 @@ TAG: array xml>item : post-rpc ( rpc url -- rpc ) ! This needs to do something in the event of an error - >r "text/xml" swap send-rpc xml>string r> http-post - 2nip string>xml receive-rpc ; + >r send-rpc r> http-post nip string>xml receive-rpc ; : invoke-method ( params method url -- ) >r swap r> post-rpc ; From 99b23348a8cab1c0c3ab4d70c5204257b374be79 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jun 2008 00:18:36 -0500 Subject: [PATCH 0053/1850] Various furnace improvements; add present vocabulary for converting objects to human-readable strings --- extra/furnace/actions/actions-tests.factor | 18 +++++++ extra/furnace/actions/actions.factor | 10 ++-- extra/furnace/furnace-tests.factor | 2 +- extra/furnace/furnace.factor | 14 ++++-- extra/html/components/components-tests.factor | 2 - extra/html/components/components.factor | 48 ++++++++++++------- extra/html/elements/elements.factor | 15 +----- extra/html/templates/chloe/chloe-tests.factor | 14 +++++- extra/html/templates/chloe/chloe.factor | 4 +- extra/html/templates/chloe/test/test12.xml | 3 ++ extra/http/http.factor | 10 ++-- .../server/dispatchers/dispatchers.factor | 9 ++-- .../redirection/redirection-tests.factor | 18 +++---- extra/present/present.factor | 15 ++++++ extra/rss/rss.factor | 6 +-- extra/urls/urls-tests.factor | 6 ++- extra/urls/urls.factor | 34 +++++++++---- 17 files changed, 149 insertions(+), 79 deletions(-) create mode 100644 extra/html/templates/chloe/test/test12.xml create mode 100644 extra/present/present.factor diff --git a/extra/furnace/actions/actions-tests.factor b/extra/furnace/actions/actions-tests.factor index 8aa0f92b97..60a526fb24 100755 --- a/extra/furnace/actions/actions-tests.factor +++ b/extra/furnace/actions/actions-tests.factor @@ -21,3 +21,21 @@ blah init-request { } "action-1" get call-responder ] unit-test + + + "a" >>rest + [ "a" param string>number sq ] >>display +"action-2" set + +STRING: action-request-test-2 +GET http://foo/bar/123 HTTP/1.1 + +blah +; + +[ 25 ] [ + action-request-test-2 lf>crlf + [ read-request ] with-string-reader + init-request + { "5" } "action-2" get call-responder +] unit-test diff --git a/extra/furnace/actions/actions.factor b/extra/furnace/actions/actions.factor index 7340a532e9..1cef8e24e5 100755 --- a/extra/furnace/actions/actions.factor +++ b/extra/furnace/actions/actions.factor @@ -17,7 +17,7 @@ IN: furnace.actions SYMBOL: params -SYMBOL: rest-param +SYMBOL: rest : render-validation-messages ( -- ) validation-messages get @@ -29,7 +29,7 @@ SYMBOL: rest-param CHLOE: validation-messages drop render-validation-messages ; -TUPLE: action rest-param init display validate submit ; +TUPLE: action rest init display validate submit ; : new-action ( class -- action ) new @@ -83,13 +83,13 @@ TUPLE: action rest-param init display validate submit ; [ flashed-variables ] [ <403> ] if* ] unless* ; -: handle-rest-param ( path action -- assoc ) - rest-param>> dup [ associate ] [ 2drop f ] if ; +: handle-rest ( path action -- assoc ) + rest>> dup [ [ "/" join ] dip associate ] [ 2drop f ] if ; : init-action ( path action -- ) blank-values init-validation - handle-rest-param + handle-rest request get request-params assoc-union params set ; M: action call-responder* ( path action -- response ) diff --git a/extra/furnace/furnace-tests.factor b/extra/furnace/furnace-tests.factor index f07fe620d8..223b20455d 100644 --- a/extra/furnace/furnace-tests.factor +++ b/extra/furnace/furnace-tests.factor @@ -30,6 +30,6 @@ M: base-path-check-responder call-responder* "a/b/c" split-path main-responder get call-responder body>> ] unit-test -[ "" ] +[ "" ] [ [ "&&&" "foo" hidden-form-field ] with-string-writer ] unit-test diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index f61ec5ff40..4859d8b0f6 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays kernel combinators assocs continuations namespaces sequences splitting words -vocabs.loader classes -fry urls multiline +vocabs.loader classes strings +fry urls multiline present xml xml.data xml.entities @@ -52,12 +52,16 @@ GENERIC: modify-query ( query responder -- query' ) M: object modify-query drop ; -: adjust-url ( url -- url' ) +GENERIC: adjust-url ( url -- url' ) + +M: url adjust-url clone [ [ modify-query ] each-responder ] change-query [ resolve-base-path ] change-path relative-to-request ; +M: string adjust-url ; + : ( url -- response ) adjust-url request get method>> { { "GET" [ ] } @@ -138,11 +142,11 @@ CHLOE: a string =value + present =value input/> ] [ 2drop ] if ; -: form-nesting-key "factorformnesting" ; +: form-nesting-key "__n" ; : form-magic ( tag -- ) [ modify-form ] each-responder diff --git a/extra/html/components/components-tests.factor b/extra/html/components/components-tests.factor index 1f77768115..2ae120b527 100644 --- a/extra/html/components/components-tests.factor +++ b/extra/html/components/components-tests.factor @@ -17,8 +17,6 @@ TUPLE: color red green blue ; [ ] [ "jimmy" "red" set-value ] unit-test -[ "123.5" ] [ 123.5 object>string ] unit-test - [ "jimmy" ] [ [ "red" label render diff --git a/extra/html/components/components.factor b/extra/html/components/components.factor index 90a00ed4ef..72dabad84e 100644 --- a/extra/html/components/components.factor +++ b/extra/html/components/components.factor @@ -5,7 +5,7 @@ classes.tuple words arrays sequences sequences.lib splitting mirrors hashtables combinators continuations math strings fry locals calendar calendar.format xml.entities validators html.elements html.streams xmode.code2html farkup inspector -lcs.diff2html urls ; +lcs.diff2html urls present ; IN: html.components SYMBOL: values @@ -29,19 +29,25 @@ SYMBOL: values : deposit-slots ( destination names -- ) [ ] dip deposit-values ; -: with-each-index ( name quot -- ) +: with-each-value ( name quot -- ) [ value ] dip '[ [ - blank-values - 1+ "index" set-value @ + values [ clone ] change + 1+ "index" set-value + "value" set-value + @ ] with-scope ] each-index ; inline -: with-each-value ( name quot -- ) - '[ "value" set-value @ ] with-each-index ; inline - : with-each-object ( name quot -- ) - '[ from-object @ ] with-each-index ; inline + [ value ] dip '[ + [ + blank-values + 1+ "index" set-value + from-object + @ + ] with-scope + ] each-index ; inline SYMBOL: nested-values @@ -75,13 +81,13 @@ GENERIC: render* ( value name render -- ) string =value input/> ; + ; PRIVATE> SINGLETON: label -M: label render* 2drop object>string escape-string write ; +M: label render* 2drop present escape-string write ; SINGLETON: hidden @@ -90,9 +96,9 @@ M: hidden render* drop "hidden" render-input ; : render-field ( value name size type -- ) string =size ] when* + [ present =size ] when* =name - object>string =value + present =value input/> ; TUPLE: field size ; @@ -119,11 +125,11 @@ TUPLE: textarea rows cols ; M: textarea render* ; ! Choice @@ -134,7 +140,7 @@ TUPLE: choice size multiple choices ; : render-option ( text selected? -- ) ; : render-options ( options selected -- ) @@ -143,7 +149,7 @@ TUPLE: choice size multiple choices ; M: choice render* " ] [ +[ "
    " ] [ [ "test10" test-template call-template ] run-template @@ -168,3 +168,15 @@ TUPLE: person first-name last-name ; "test11" test-template call-template ] run-template [ blank? not ] filter ] unit-test + +[ ] [ + blank-values + { "a" "b" } "choices" set-value + "true" "b" set-value +] unit-test + +[ "ab" ] [ + [ + "test12" test-template call-template + ] run-template +] unit-test diff --git a/extra/html/templates/chloe/chloe.factor b/extra/html/templates/chloe/chloe.factor index cb56bd71ce..08d6b873fc 100644 --- a/extra/html/templates/chloe/chloe.factor +++ b/extra/html/templates/chloe/chloe.factor @@ -3,7 +3,7 @@ USING: accessors kernel sequences combinators kernel namespaces classes.tuple assocs splitting words arrays memoize io io.files io.encodings.utf8 io.streams.string -unicode.case tuple-syntax mirrors fry math urls +unicode.case tuple-syntax mirrors fry math urls present multiline xml xml.data xml.writer xml.utilities html.elements html.components @@ -127,7 +127,7 @@ CHLOE-TUPLE: code : expand-attrs ( tag -- tag ) dup [ tag? ] is? [ clone [ - [ "@" ?head [ value object>string ] when ] assoc-map + [ "@" ?head [ value present ] when ] assoc-map ] change-attrs ] when ; diff --git a/extra/html/templates/chloe/test/test12.xml b/extra/html/templates/chloe/test/test12.xml new file mode 100644 index 0000000000..b26778c96e --- /dev/null +++ b/extra/html/templates/chloe/test/test12.xml @@ -0,0 +1,3 @@ + + + diff --git a/extra/http/http.factor b/extra/http/http.factor index 7499796b77..abbf79f860 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -4,7 +4,7 @@ USING: accessors kernel combinators math namespaces assocs sequences splitting sorting sets debugger strings vectors hashtables quotations arrays byte-arrays -math.parser calendar calendar.format +math.parser calendar calendar.format present io io.server io.sockets.secure @@ -54,11 +54,9 @@ IN: http : header-value>string ( value -- string ) { - { [ dup number? ] [ number>string ] } { [ dup timestamp? ] [ timestamp>http-string ] } - { [ dup url? ] [ url>string ] } - { [ dup string? ] [ ] } - { [ dup sequence? ] [ [ header-value>string ] map "; " join ] } + { [ dup array? ] [ [ header-value>string ] map "; " join ] } + [ present ] } cond ; : check-header-string ( str -- str ) @@ -231,7 +229,7 @@ TUPLE: post-data raw content content-type ; dup method>> write bl ; : write-request-url ( request -- request ) - dup url>> relative-url url>string write bl ; + dup url>> relative-url present write bl ; : write-version ( request -- request ) "HTTP/" write dup request-version write crlf ; diff --git a/extra/http/server/dispatchers/dispatchers.factor b/extra/http/server/dispatchers/dispatchers.factor index 36eb447fc3..2da2695992 100644 --- a/extra/http/server/dispatchers/dispatchers.factor +++ b/extra/http/server/dispatchers/dispatchers.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel namespaces sequences assocs accessors -http http.server http.server.responses ; +USING: kernel namespaces sequences assocs accessors splitting +unicode.case http http.server http.server.responses ; IN: http.server.dispatchers TUPLE: dispatcher default responders ; @@ -31,8 +31,11 @@ TUPLE: vhost-dispatcher default responders ; : ( -- dispatcher ) vhost-dispatcher new-dispatcher ; +: canonical-host ( host -- host' ) + >lower "www." ?head drop "." ?tail drop ; + : find-vhost ( dispatcher -- responder ) - request get url>> host>> over responders>> at* + request get url>> host>> canonical-host over responders>> at* [ nip ] [ drop default>> ] if ; M: vhost-dispatcher call-responder* ( path dispatcher -- response ) diff --git a/extra/http/server/redirection/redirection-tests.factor b/extra/http/server/redirection/redirection-tests.factor index 0b88231855..04af89ec98 100644 --- a/extra/http/server/redirection/redirection-tests.factor +++ b/extra/http/server/redirection/redirection-tests.factor @@ -1,6 +1,6 @@ IN: http.server.redirection.tests USING: http http.server.redirection urls accessors -namespaces tools.test ; +namespaces tools.test present ; \ relative-to-request must-infer @@ -15,34 +15,34 @@ namespaces tools.test ; request set [ "http://www.apple.com:80/xxx/bar" ] [ - relative-to-request url>string + relative-to-request present ] unit-test [ "http://www.apple.com:80/xxx/baz" ] [ - "baz" >>path relative-to-request url>string + "baz" >>path relative-to-request present ] unit-test [ "http://www.apple.com:80/xxx/baz?c=d" ] [ - "baz" >>path { { "c" "d" } } >>query relative-to-request url>string + "baz" >>path { { "c" "d" } } >>query relative-to-request present ] unit-test [ "http://www.apple.com:80/xxx/bar?c=d" ] [ - { { "c" "d" } } >>query relative-to-request url>string + { { "c" "d" } } >>query relative-to-request present ] unit-test [ "http://www.apple.com:80/flip" ] [ - "/flip" >>path relative-to-request url>string + "/flip" >>path relative-to-request present ] unit-test [ "http://www.apple.com:80/flip?c=d" ] [ - "/flip" >>path { { "c" "d" } } >>query relative-to-request url>string + "/flip" >>path { { "c" "d" } } >>query relative-to-request present ] unit-test [ "http://www.jedit.org:80/" ] [ - "http://www.jedit.org" >url relative-to-request url>string + "http://www.jedit.org" >url relative-to-request present ] unit-test [ "http://www.jedit.org:80/?a=b" ] [ - "http://www.jedit.org" >url { { "a" "b" } } >>query relative-to-request url>string + "http://www.jedit.org" >url { { "a" "b" } } >>query relative-to-request present ] unit-test ] with-scope diff --git a/extra/present/present.factor b/extra/present/present.factor new file mode 100644 index 0000000000..1fae84184a --- /dev/null +++ b/extra/present/present.factor @@ -0,0 +1,15 @@ +USING: math math.parser calendar calendar.format strings words +kernel ; +IN: present + +GENERIC: present ( object -- string ) + +M: real present number>string ; + +M: timestamp present timestamp>string ; + +M: string present ; + +M: word present word-name ; + +M: f present drop "" ; diff --git a/extra/rss/rss.factor b/extra/rss/rss.factor index 5183af5145..1dd66ff5d4 100644 --- a/extra/rss/rss.factor +++ b/extra/rss/rss.factor @@ -4,7 +4,7 @@ USING: xml.utilities kernel assocs xml.generator math.order strings sequences xml.data xml.writer io.streams.string combinators xml xml.entities io.files io http.client namespaces xml.generator hashtables - calendar.format accessors continuations urls ; + calendar.format accessors continuations urls present ; IN: rss : any-tag-named ( tag names -- tag-inside ) @@ -104,7 +104,7 @@ C: entry : entry, ( entry -- ) "entry" [ dup title>> "title" { { "type" "html" } } simple-tag*, - "link" over link>> dup url? [ url>string ] when "href" associate contained*, + "link" over link>> dup url? [ present ] when "href" associate contained*, dup pub-date>> timestamp>rfc3339 "published" simple-tag, description>> [ "content" { { "type" "html" } } simple-tag*, ] when* ] tag, ; @@ -112,6 +112,6 @@ C: entry : feed>xml ( feed -- xml ) "feed" { { "xmlns" "http://www.w3.org/2005/Atom" } } [ dup title>> "title" simple-tag, - "link" over link>> dup url? [ url>string ] when "href" associate contained*, + "link" over link>> dup url? [ present ] when "href" associate contained*, entries>> [ entry, ] each ] make-xml* ; diff --git a/extra/urls/urls-tests.factor b/extra/urls/urls-tests.factor index 080352449b..a718989476 100644 --- a/extra/urls/urls-tests.factor +++ b/extra/urls/urls-tests.factor @@ -1,5 +1,7 @@ IN: urls.tests -USING: urls tools.test tuple-syntax arrays kernel assocs ; +USING: urls urls.private tools.test +tuple-syntax arrays kernel assocs +present ; [ "hello%20world" ] [ "hello world" url-encode ] unit-test [ "hello world" ] [ "hello%20world" url-decode ] unit-test @@ -110,7 +112,7 @@ urls [ ] assoc-each urls [ - swap [ 1array ] [ [ url>string ] curry ] bi* unit-test + swap [ 1array ] [ [ present ] curry ] bi* unit-test ] assoc-each [ "b" ] [ "a" "b" url-append-path ] unit-test diff --git a/extra/urls/urls.factor b/extra/urls/urls.factor index 5c89205d5b..bb4d17e1f5 100644 --- a/extra/urls/urls.factor +++ b/extra/urls/urls.factor @@ -4,7 +4,7 @@ USING: kernel unicode.categories combinators sequences splitting fry namespaces assocs arrays strings io.sockets io.sockets.secure io.encodings.string io.encodings.utf8 math math.parser accessors mirrors parser -prettyprint.backend hashtables ; +prettyprint.backend hashtables present ; IN: urls : url-quotable? ( ch -- ? ) @@ -14,19 +14,25 @@ IN: urls { [ dup letter? ] [ t ] } { [ dup LETTER? ] [ t ] } { [ dup digit? ] [ t ] } - { [ dup "/_-.:" member? ] [ t ] } + { [ dup "/_-." member? ] [ t ] } [ f ] } cond nip ; foldable +hex 2 CHAR: 0 pad-left % ] each ; +PRIVATE> + : url-encode ( str -- str ) [ [ dup url-quotable? [ , ] [ push-utf8 ] if ] each ] "" make ; += [ 2drop @@ -51,9 +57,13 @@ IN: urls ] if url-decode-iter ] if ; +PRIVATE> + : url-decode ( str -- str ) [ 0 swap url-decode-iter ] "" make utf8 decode ; + + : query>assoc ( query -- assoc ) dup [ "&" split H{ } clone [ @@ -77,11 +89,7 @@ IN: urls : assoc>query ( hash -- str ) [ - { - { [ dup number? ] [ number>string 1array ] } - { [ dup string? ] [ 1array ] } - { [ dup sequence? ] [ ] } - } cond + dup array? [ [ present ] map ] [ present 1array ] if ] assoc-map [ [ @@ -108,6 +116,8 @@ TUPLE: url protocol username password host port path query anchor ; ] when ] bi* ; +>protocol ] [ "//" ?head [ "Invalid URL" throw ] unless @@ -121,6 +131,8 @@ TUPLE: url protocol username password host port path query anchor ; ] [ "/" prepend ] bi* ] bi* ; +PRIVATE> + GENERIC: >url ( obj -- url ) M: url >url ; @@ -135,6 +147,8 @@ M: string >url ] [ url-decode >>anchor ] bi* ; +> dup [ % password>> [ ":" % % ] when* "@" % @@ -150,7 +164,7 @@ M: string >url [ path>> "/" head? [ "/" % ] unless ] } cleave ; -: url>string ( url -- string ) +M: url present [ { [ dup protocol>> dup [ unparse-host-part ] [ 2drop ] if ] @@ -169,6 +183,8 @@ M: string >url [ [ "/" last-split1 drop "/" ] dip 3append ] } cond ; +PRIVATE> + : derive-url ( base url -- url' ) [ clone dup ] dip 2dup [ path>> ] bi@ url-append-path @@ -199,4 +215,4 @@ M: string >url ! Literal syntax : URL" lexer get skip-blank parse-string >url parsed ; parsing -M: url pprint* dup url>string "URL\" " "\"" pprint-string ; +M: url pprint* dup present "URL\" " "\"" pprint-string ; From 19044920dc71550cecac50c5ea01eb38c8645b95 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jun 2008 01:12:22 -0500 Subject: [PATCH 0054/1850] Clean up RSS library --- extra/rss/rss-tests.factor | 10 ++-- extra/rss/rss.factor | 97 ++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/extra/rss/rss-tests.factor b/extra/rss/rss-tests.factor index 0e6bb0b9c1..4ecb7fc965 100755 --- a/extra/rss/rss-tests.factor +++ b/extra/rss/rss-tests.factor @@ -1,5 +1,5 @@ USING: rss io kernel io.files tools.test io.encodings.utf8 -calendar ; +calendar urls ; IN: rss.tests : load-news-file ( filename -- feed ) @@ -11,13 +11,13 @@ IN: rss.tests feed f "Meerkat" - "http://meerkat.oreillynet.com" + URL" http://meerkat.oreillynet.com" { T{ entry f "XML: A Disruptive Technology" - "http://c.moreover.com/click/here.pl?r123" + URL" http://c.moreover.com/click/here.pl?r123" "\n XML is placing increasingly heavy loads on the existing technical\n infrastructure of the Internet.\n " f } @@ -27,13 +27,13 @@ IN: rss.tests feed f "dive into mark" - "http://example.org/" + URL" http://example.org/" { T{ entry f "Atom draft-07 snapshot" - "http://example.org/2005/04/02/atom" + URL" http://example.org/2005/04/02/atom" "\n
    \n

    [Update: The Atom draft is finished.]

    \n
    \n " T{ timestamp f 2003 12 13 8 29 29 T{ duration f 0 0 0 -4 0 0 } } diff --git a/extra/rss/rss.factor b/extra/rss/rss.factor index 1dd66ff5d4..4aa92abc67 100644 --- a/extra/rss/rss.factor +++ b/extra/rss/rss.factor @@ -10,75 +10,89 @@ IN: rss : any-tag-named ( tag names -- tag-inside ) f -rot [ tag-named nip dup ] with find 2drop ; -TUPLE: feed title link entries ; +TUPLE: feed title url entries ; -C: feed +: ( -- feed ) feed new ; -TUPLE: entry title link description pub-date ; +TUPLE: entry title url description pub-date ; -C: entry +: set-entries ( feed entries -- feed ) + [ dup url>> ] dip + [ [ derive-url ] change-url ] with map + >>entries ; + +: ( -- entry ) entry new ; : try-parsing-timestamp ( string -- timestamp ) [ rfc822>timestamp ] [ drop rfc3339>timestamp ] recover ; : rss1.0-entry ( tag -- entry ) - { - [ "title" tag-named children>string ] - [ "link" tag-named children>string ] - [ "description" tag-named children>string ] + entry new + swap { + [ "title" tag-named children>string >>title ] + [ "link" tag-named children>string >url >>url ] + [ "description" tag-named children>string >>description ] [ f "date" "http://purl.org/dc/elements/1.1/" tag-named dup [ children>string try-parsing-timestamp ] when + >>pub-date ] - } cleave ; + } cleave ; : rss1.0 ( xml -- feed ) - [ + feed new + swap [ "channel" tag-named - [ "title" tag-named children>string ] - [ "link" tag-named children>string ] bi - ] [ "item" tags-named [ rss1.0-entry ] map ] bi - ; + [ "title" tag-named children>string >>title ] + [ "link" tag-named children>string >url >>url ] bi + ] [ "item" tags-named [ rss1.0-entry ] map set-entries ] bi ; : rss2.0-entry ( tag -- entry ) - { - [ "title" tag-named children>string ] - [ { "link" "guid" } any-tag-named children>string ] - [ "description" tag-named children>string ] + entry new + swap { + [ "title" tag-named children>string >>title ] + [ { "link" "guid" } any-tag-named children>string >url >>url ] + [ "description" tag-named children>string >>description ] [ { "date" "pubDate" } any-tag-named - children>string try-parsing-timestamp + children>string try-parsing-timestamp >>pub-date ] - } cleave ; + } cleave ; : rss2.0 ( xml -- feed ) + feed new + swap "channel" tag-named - [ "title" tag-named children>string ] - [ "link" tag-named children>string ] - [ "item" tags-named [ rss2.0-entry ] map ] - tri ; + [ "title" tag-named children>string >>title ] + [ "link" tag-named children>string >>link ] + [ "item" tags-named [ rss2.0-entry ] map set-entries ] + tri ; : atom1.0-entry ( tag -- entry ) - { - [ "title" tag-named children>string ] - [ "link" tag-named "href" swap at ] + entry new + swap { + [ "title" tag-named children>string >>title ] + [ "link" tag-named "href" swap at >url >>url ] [ { "content" "summary" } any-tag-named dup tag-children [ string? not ] contains? [ tag-children [ write-chunk ] with-string-writer ] - [ children>string ] if + [ children>string ] if >>description ] [ { "published" "updated" "issued" "modified" } any-tag-named children>string try-parsing-timestamp + >>pub-date ] - } cleave ; + } cleave ; : atom1.0 ( xml -- feed ) - [ "title" tag-named children>string ] - [ "link" tag-named "href" swap at ] - [ "entry" tags-named [ atom1.0-entry ] map ] - tri ; + feed new + swap + [ "title" tag-named children>string >>title ] + [ "link" tag-named "href" swap at >url >>url ] + [ "entry" tags-named [ atom1.0-entry ] map set-entries ] + tri ; : xml>feed ( xml -- feed ) dup name-tag { @@ -103,15 +117,18 @@ C: entry : entry, ( entry -- ) "entry" [ - dup title>> "title" { { "type" "html" } } simple-tag*, - "link" over link>> dup url? [ present ] when "href" associate contained*, - dup pub-date>> timestamp>rfc3339 "published" simple-tag, - description>> [ "content" { { "type" "html" } } simple-tag*, ] when* + { + [ title>> "title" { { "type" "html" } } simple-tag*, ] + [ url>> present "href" associate "link" swap contained*, ] + [ pub-date>> timestamp>rfc3339 "published" simple-tag, ] + [ description>> [ "content" { { "type" "html" } } simple-tag*, ] when* ] + } cleave ] tag, ; : feed>xml ( feed -- xml ) "feed" { { "xmlns" "http://www.w3.org/2005/Atom" } } [ - dup title>> "title" simple-tag, - "link" over link>> dup url? [ present ] when "href" associate contained*, - entries>> [ entry, ] each + [ title>> "title" simple-tag, ] + [ url>> present "href" associate "link" swap contained*, ] + [ entries>> [ entry, ] each ] + tri ] make-xml* ; From 608276fe9aa6d249344aa46cee24376fe6bf2ad0 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jun 2008 01:48:31 -0500 Subject: [PATCH 0055/1850] Improve furnace RSS support --- extra/furnace/furnace.factor | 4 +-- extra/furnace/rss/rss.factor | 48 ++++++++++++++++++++++++++++++++---- extra/rss/rss-tests.factor | 3 +++ extra/rss/rss.factor | 12 ++++----- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index 4859d8b0f6..862ed80e11 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -8,7 +8,6 @@ xml xml.data xml.entities xml.writer -xml.utilities html.components html.elements html.templates @@ -20,6 +19,7 @@ http.server.redirection http.server.responses qualified ; QUALIFIED-WITH: assocs a +EXCLUDE: xml.utilities => children>string ; IN: furnace : nested-responders ( -- seq ) @@ -97,7 +97,7 @@ SYMBOL: exit-continuation [ drop f ] [ "," split [ dup value ] H{ } map>assoc ] if ; CHLOE: atom - [ "title" required-attr ] + [ children>string ] [ "href" required-attr ] [ "query" optional-attr parse-query-attr ] tri diff --git a/extra/furnace/rss/rss.factor b/extra/furnace/rss/rss.factor index a94ef4fe51..c2163eda66 100644 --- a/extra/furnace/rss/rss.factor +++ b/extra/furnace/rss/rss.factor @@ -1,14 +1,52 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel fry -rss http.server.responses furnace.actions ; +USING: accessors kernel sequences fry sequences.lib +combinators rss http.server.responses http.server.redirection +furnace furnace.actions ; IN: furnace.rss +GENERIC: feed-entry-title ( object -- string ) + +GENERIC: feed-entry-date ( object -- timestamp ) + +GENERIC: feed-entry-url ( object -- url ) + +GENERIC: feed-entry-description ( object -- description ) + +M: object feed-entry-description drop f ; + +GENERIC: >entry ( object -- entry ) + +M: entry >entry ; + +M: object >entry + + swap { + [ feed-entry-title >>title ] + [ feed-entry-date >>date ] + [ feed-entry-url >>url ] + [ feed-entry-description >>description ] + } cleave ; + +: process-entries ( seq -- seq' ) + 20 short head-slice [ + >entry clone + [ adjust-url relative-to-request ] change-url + ] map ; + : ( body -- response ) feed>xml "application/atom+xml" ; -TUPLE: feed-action < action feed ; +TUPLE: feed-action < action title url entries ; -: ( -- feed ) +: ( -- action ) feed-action new-action - dup '[ , feed>> call ] >>display ; + dup '[ + feed new + , + [ title>> call >>title ] + [ url>> call adjust-url relative-to-request >>url ] + [ entries>> call process-entries >>entries ] + tri + + ] >>display ; diff --git a/extra/rss/rss-tests.factor b/extra/rss/rss-tests.factor index 4ecb7fc965..81a0bf9e1a 100755 --- a/extra/rss/rss-tests.factor +++ b/extra/rss/rss-tests.factor @@ -2,6 +2,9 @@ USING: rss io kernel io.files tools.test io.encodings.utf8 calendar urls ; IN: rss.tests +\ download-feed must-infer +\ feed>xml must-infer + : load-news-file ( filename -- feed ) #! Load an news syndication file and process it, returning #! it as an feed tuple. diff --git a/extra/rss/rss.factor b/extra/rss/rss.factor index 4aa92abc67..7696a7c220 100644 --- a/extra/rss/rss.factor +++ b/extra/rss/rss.factor @@ -14,7 +14,7 @@ TUPLE: feed title url entries ; : ( -- feed ) feed new ; -TUPLE: entry title url description pub-date ; +TUPLE: entry title url description date ; : set-entries ( feed entries -- feed ) [ dup url>> ] dip @@ -35,7 +35,7 @@ TUPLE: entry title url description pub-date ; [ f "date" "http://purl.org/dc/elements/1.1/" tag-named dup [ children>string try-parsing-timestamp ] when - >>pub-date + >>date ] } cleave ; @@ -55,7 +55,7 @@ TUPLE: entry title url description pub-date ; [ "description" tag-named children>string >>description ] [ { "date" "pubDate" } any-tag-named - children>string try-parsing-timestamp >>pub-date + children>string try-parsing-timestamp >>date ] } cleave ; @@ -64,7 +64,7 @@ TUPLE: entry title url description pub-date ; swap "channel" tag-named [ "title" tag-named children>string >>title ] - [ "link" tag-named children>string >>link ] + [ "link" tag-named children>string >url >>url ] [ "item" tags-named [ rss2.0-entry ] map set-entries ] tri ; @@ -82,7 +82,7 @@ TUPLE: entry title url description pub-date ; [ { "published" "updated" "issued" "modified" } any-tag-named children>string try-parsing-timestamp - >>pub-date + >>date ] } cleave ; @@ -120,7 +120,7 @@ TUPLE: entry title url description pub-date ; { [ title>> "title" { { "type" "html" } } simple-tag*, ] [ url>> present "href" associate "link" swap contained*, ] - [ pub-date>> timestamp>rfc3339 "published" simple-tag, ] + [ date>> timestamp>rfc3339 "published" simple-tag, ] [ description>> [ "content" { { "type" "html" } } simple-tag*, ] when* ] } cleave ] tag, ; From 465f460834faa9b3bc667487340a607947053657 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jun 2008 01:50:26 -0500 Subject: [PATCH 0056/1850] Port old Wee-URL web app to new framework --- extra/webapps/wee-url/shorten.xml | 10 ++++ extra/webapps/wee-url/show.xml | 11 +++++ extra/webapps/wee-url/wee-url.factor | 74 ++++++++++++++++++++++++++++ extra/webapps/wee-url/wee-url.xml | 13 +++++ 4 files changed, 108 insertions(+) create mode 100644 extra/webapps/wee-url/shorten.xml create mode 100644 extra/webapps/wee-url/show.xml create mode 100644 extra/webapps/wee-url/wee-url.factor create mode 100644 extra/webapps/wee-url/wee-url.xml diff --git a/extra/webapps/wee-url/shorten.xml b/extra/webapps/wee-url/shorten.xml new file mode 100644 index 0000000000..8df7774fba --- /dev/null +++ b/extra/webapps/wee-url/shorten.xml @@ -0,0 +1,10 @@ + + + + + +

    Shorten URL:

    + +
    + +
    diff --git a/extra/webapps/wee-url/show.xml b/extra/webapps/wee-url/show.xml new file mode 100644 index 0000000000..ba44629bb1 --- /dev/null +++ b/extra/webapps/wee-url/show.xml @@ -0,0 +1,11 @@ + + + + +

    The URL:

    +
    +

    has been shortened to:

    +
    +

    enjoy!

    + +
    diff --git a/extra/webapps/wee-url/wee-url.factor b/extra/webapps/wee-url/wee-url.factor new file mode 100644 index 0000000000..afdacf9add --- /dev/null +++ b/extra/webapps/wee-url/wee-url.factor @@ -0,0 +1,74 @@ +! Copyright (C) 2007 Doug Coleman. +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: math.ranges sequences random accessors combinators.lib +kernel namespaces fry db.types db.tuples urls validators +html.components http http.server.dispatchers furnace +furnace.actions furnace.boilerplate ; +IN: webapps.wee-url + +TUPLE: wee-url < dispatcher ; + +TUPLE: short-url short url ; + +short-url "SHORT_URLS" { + { "short" "SHORT" TEXT +user-assigned-id+ } + { "url" "URL" TEXT +not-null+ } +} define-persistent + +: init-short-url-table ( -- ) + short-url ensure-table ; + +: letter-bank ( -- seq ) + CHAR: a CHAR: z [a,b] + CHAR: A CHAR: Z [a,b] + CHAR: 1 CHAR: 0 [a,b] + 3append ; foldable + +: random-url ( -- string ) + 1 6 [a,b] random [ drop letter-bank random ] "" map-as ; + +: insert-short-url ( short-url -- short-url ) + '[ , dup random-url >>short insert-tuple ] 10 retry ; + +: shorten ( url -- short ) + short-url new swap >>url dup select-tuple + [ ] [ insert-short-url ] ?if short>> ; + +: short>url ( short -- url ) + "$wee-url/go/" prepend >url adjust-url ; + +: expand-url ( string -- url ) + short-url new swap >>short select-tuple url>> ; + +: ( -- action ) + + { wee-url "shorten" } >>template + [ { { "url" [ v-url ] } } validate-params ] >>validate + [ + "$wee-url/show/" "url" value shorten append >url + ] >>submit ; + +: ( -- action ) + + "short" >>rest + [ + { { "short" [ v-one-word ] } } validate-params + "short" value expand-url "url" set-value + "short" value short>url "short" set-value + ] >>init + { wee-url "show" } >>template ; + +: ( -- action ) + + "short" >>rest + [ { { "short" [ v-one-word ] } } validate-params ] >>init + [ "short" value expand-url ] >>display ; + +: ( -- wee-url ) + wee-url new-dispatcher + "" add-responder + "show" add-responder + "go" add-responder + + { wee-url "wee-url" } >>template ; diff --git a/extra/webapps/wee-url/wee-url.xml b/extra/webapps/wee-url/wee-url.xml new file mode 100644 index 0000000000..98d1095ed6 --- /dev/null +++ b/extra/webapps/wee-url/wee-url.xml @@ -0,0 +1,13 @@ + + + + + WeeURL! + + + +

    + + + +
    From 89feb17f321c04ff9d8dd72ff4fed944b102dd08 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jun 2008 01:50:47 -0500 Subject: [PATCH 0057/1850] Add wee-url to website dispatcher --- extra/webapps/factor-website/factor-website.factor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extra/webapps/factor-website/factor-website.factor b/extra/webapps/factor-website/factor-website.factor index cd6dde255c..44899cba31 100644 --- a/extra/webapps/factor-website/factor-website.factor +++ b/extra/webapps/factor-website/factor-website.factor @@ -16,6 +16,7 @@ webapps.pastebin webapps.planet webapps.todo webapps.wiki +webapps.wee-url webapps.user-admin ; IN: webapps.factor-website @@ -36,6 +37,8 @@ IN: webapps.factor-website init-articles-table init-revisions-table + + init-short-url-table ] with-db ; TUPLE: factor-website < dispatcher ; @@ -46,6 +49,7 @@ TUPLE: factor-website < dispatcher ; "pastebin" add-responder "planet" add-responder "wiki" add-responder + "wee-url" add-responder "user-admin" add-responder users-in-db >>users From 1074bdb3303acebaeb715ce8d8312c99247c46d7 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jun 2008 01:50:59 -0500 Subject: [PATCH 0058/1850] Update wiki, pastebin, planet for new furnace.rss code --- extra/webapps/pastebin/paste.xml | 4 +- extra/webapps/pastebin/pastebin-common.xml | 2 +- extra/webapps/pastebin/pastebin.factor | 87 +++++-------- extra/webapps/planet/admin.xml | 4 +- extra/webapps/planet/mini-planet.xml | 2 +- extra/webapps/planet/planet.factor | 28 ++-- extra/webapps/planet/planet.xml | 4 +- extra/webapps/user-admin/user-admin.factor | 2 +- extra/webapps/wiki/page-common.xml | 4 + extra/webapps/wiki/user-edits.xml | 4 + extra/webapps/wiki/wiki-common.xml | 4 + extra/webapps/wiki/wiki.factor | 145 +++++++++++++-------- 12 files changed, 153 insertions(+), 137 deletions(-) diff --git a/extra/webapps/pastebin/paste.xml b/extra/webapps/pastebin/paste.xml index 453f7b590b..ea69c7bf7d 100644 --- a/extra/webapps/pastebin/paste.xml +++ b/extra/webapps/pastebin/paste.xml @@ -2,7 +2,9 @@ - + + Paste: + Paste: diff --git a/extra/webapps/pastebin/pastebin-common.xml b/extra/webapps/pastebin/pastebin-common.xml index a27a1290dd..47f7666b22 100644 --- a/extra/webapps/pastebin/pastebin-common.xml +++ b/extra/webapps/pastebin/pastebin-common.xml @@ -2,7 +2,7 @@ - + Pastebin diff --git a/extra/webapps/pastebin/pastebin.factor b/extra/webapps/pastebin/pastebin.factor index 06cdd5adf0..882e7cf438 100644 --- a/extra/webapps/pastebin/pastebin.factor +++ b/extra/webapps/pastebin/pastebin.factor @@ -35,6 +35,14 @@ entity f { "contents" "CONTENTS" TEXT +not-null+ } } define-persistent +GENERIC: entity-url ( entity -- url ) + +M: entity feed-entry-title summary>> ; + +M: entity feed-entry-date date>> ; + +M: entity feed-entry-url entity-url ; + TUPLE: paste < entity annotations ; \ paste "PASTES" { } define-persistent @@ -58,39 +66,31 @@ annotation "ANNOTATIONS" swap >>id swap >>parent ; -: fetch-annotations ( paste -- paste ) - dup annotations>> [ - dup id>> f select-tuples >>annotations - ] unless ; - : paste ( id -- paste ) - select-tuple fetch-annotations ; + [ select-tuple ] + [ f select-tuples ] + bi >>annotations ; ! ! ! ! LINKS, ETC ! ! ! -: pastebin-link ( -- url ) +: pastebin-url ( -- url ) URL" $pastebin/list" ; -GENERIC: entity-link ( entity -- url ) +: paste-url ( id -- url ) + "$pastebin/paste" >url swap "id" set-query-param ; -: paste-link ( id -- url ) - - "$pastebin/paste" >>path - swap "id" set-query-param ; +M: paste entity-url + id>> paste-url ; -M: paste entity-link - id>> paste-link ; - -: annotation-link ( parent id -- url ) - - "$pastebin/paste" >>path +: annotation-url ( parent id -- url ) + "$pastebin/paste" >url swap number>string >>anchor swap "id" set-query-param ; -M: annotation entity-link - [ parent>> ] [ id>> ] bi annotation-link ; +M: annotation entity-url + [ parent>> ] [ id>> ] bi annotation-url ; ! ! ! ! PASTE LIST @@ -101,24 +101,11 @@ M: annotation entity-link [ pastes "pastes" set-value ] >>init { pastebin "pastebin" } >>template ; -: pastebin-feed-entries ( seq -- entries ) - 20 short head [ - entry new - swap - [ summary>> >>title ] - [ date>> >>pub-date ] - [ entity-link adjust-url relative-to-request >>link ] - tri - ] map ; - -: pastebin-feed ( -- feed ) - feed new - "Factor Pastebin" >>title - pastebin-link >>link - pastes pastebin-feed-entries >>entries ; - : ( -- action ) - [ pastebin-feed ] >>feed ; + + [ pastebin-url ] >>url + [ "Factor Pastebin" ] >>title + [ pastes ] >>entries ; ! ! ! ! PASTES @@ -140,21 +127,12 @@ M: annotation entity-link { pastebin "paste" } >>template ; -: paste-feed-entries ( paste -- entries ) - fetch-annotations annotations>> pastebin-feed-entries ; - -: paste-feed ( paste -- feed ) - feed new - swap - [ "Paste " swap id>> number>string append >>title ] - [ entity-link adjust-url relative-to-request >>link ] - [ paste-feed-entries >>entries ] - tri ; - : ( -- action ) [ validate-integer-id ] >>init - [ "id" value paste paste-feed ] >>feed ; + [ "id" value paste-url ] >>url + [ "Paste " "id" value number>string append ] >>title + [ "id" value f select-tuples ] >>entries ; : validate-entity ( -- ) { @@ -186,7 +164,7 @@ M: annotation entity-link f [ deposit-entity-slots ] [ insert-tuple ] - [ id>> paste-link ] + [ id>> paste-url ] tri ] >>submit ; @@ -206,11 +184,6 @@ M: annotation entity-link : ( -- action ) - [ - { { "id" [ v-integer ] } } validate-params - "id" value paste-link - ] >>display - [ { { "parent" [ v-integer ] } } validate-params validate-entity @@ -220,7 +193,7 @@ M: annotation entity-link "parent" value f [ deposit-entity-slots ] [ insert-tuple ] - [ entity-link ] + [ entity-url ] tri ] >>submit ; @@ -231,7 +204,7 @@ M: annotation entity-link [ f "id" value select-tuple [ delete-tuples ] - [ parent>> paste-link ] + [ parent>> paste-url ] bi ] >>submit ; diff --git a/extra/webapps/planet/admin.xml b/extra/webapps/planet/admin.xml index 26a3e6f206..192592489e 100644 --- a/extra/webapps/planet/admin.xml +++ b/extra/webapps/planet/admin.xml @@ -14,9 +14,9 @@
-

+

Add Blog | Update -

+
diff --git a/extra/webapps/planet/mini-planet.xml b/extra/webapps/planet/mini-planet.xml index 8de7216b0e..661c2dc0f7 100644 --- a/extra/webapps/planet/mini-planet.xml +++ b/extra/webapps/planet/mini-planet.xml @@ -5,7 +5,7 @@

-
+
Read More...

diff --git a/extra/webapps/planet/planet.factor b/extra/webapps/planet/planet.factor index 3c0e2ad267..0237e14faa 100755 --- a/extra/webapps/planet/planet.factor +++ b/extra/webapps/planet/planet.factor @@ -34,16 +34,15 @@ blog "BLOGS" { "feed-url" "FEEDURL" { VARCHAR 256 } +not-null+ } } define-persistent -! TUPLE: posting < entry id ; -TUPLE: posting id title link description pub-date ; +TUPLE: posting < entry id ; posting "POSTINGS" { { "id" "ID" INTEGER +db-assigned-id+ } { "title" "TITLE" { VARCHAR 256 } +not-null+ } - { "link" "LINK" { VARCHAR 256 } +not-null+ } + { "url" "LINK" { VARCHAR 256 } +not-null+ } { "description" "DESCRIPTION" TEXT +not-null+ } - { "pub-date" "DATE" TIMESTAMP +not-null+ } + { "date" "DATE" TIMESTAMP +not-null+ } } define-persistent : init-blog-table blog ensure-table ; @@ -60,7 +59,7 @@ posting "POSTINGS" : postings ( -- seq ) posting new select-tuples - [ [ pub-date>> ] compare invert-comparison ] sort ; + [ [ date>> ] compare invert-comparison ] sort ; : ( -- action ) @@ -76,21 +75,18 @@ posting "POSTINGS" { planet-factor "planet" } >>template ; -: planet-feed ( -- feed ) - feed new - "Planet Factor" >>title - "http://planet.factorcode.org" >>link - postings >>entries ; - : ( -- action ) - [ planet-feed ] >>feed ; + + [ "Planet Factor" ] >>title + [ URL" $planet-factor" ] >>url + [ postings ] >>entries ; :: ( entry name -- entry' ) posting new name ": " entry title>> 3append >>title - entry link>> >>link + entry url>> >>url entry description>> >>description - entry pub-date>> >>pub-date ; + entry date>> >>date ; : fetch-feed ( url -- feed ) download-feed entries>> ; @@ -102,7 +98,7 @@ posting "POSTINGS" [ '[ , ] map ] 2map concat ; : sort-entries ( entries -- entries' ) - [ [ pub-date>> ] compare invert-comparison ] sort ; + [ [ date>> ] compare invert-comparison ] sort ; : update-cached-postings ( -- ) blogroll fetch-blogroll sort-entries 8 short head [ @@ -197,7 +193,7 @@ can-administer-planet-factor? define-capability : ( -- responder ) planet-factor new-dispatcher "list" add-main-responder - "feed.xml" add-responder + "feed.xml" add-responder "administer Planet Factor" >>description { can-administer-planet-factor? } >>capabilities diff --git a/extra/webapps/planet/planet.xml b/extra/webapps/planet/planet.xml index 213c314d7a..96343bc5fa 100644 --- a/extra/webapps/planet/planet.xml +++ b/extra/webapps/planet/planet.xml @@ -11,7 +11,7 @@

- +

@@ -19,7 +19,7 @@

- +

diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index 78c972fa34..19153e1354 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -83,7 +83,7 @@ TUPLE: user-admin < dispatcher ; [ from-object ] [ capabilities>> [ "true" swap word>string set-value ] each ] bi - capabilities get words>strings "capabilities" set-value + init-capabilities ] >>init { user-admin "edit-user" } >>template diff --git a/extra/webapps/wiki/page-common.xml b/extra/webapps/wiki/page-common.xml index 1d4b507320..675cb8cd65 100644 --- a/extra/webapps/wiki/page-common.xml +++ b/extra/webapps/wiki/page-common.xml @@ -2,6 +2,10 @@ + + Revisions of + +
Summary:
Author:
Mode:
Body:
Body:
Captcha:
+
diff --git a/extra/webapps/planet/planet.xml b/extra/webapps/planet/planet.xml index 96343bc5fa..fe4d23bd3b 100644 --- a/extra/webapps/planet/planet.xml +++ b/extra/webapps/planet/planet.xml @@ -19,7 +19,7 @@

- +

diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index 1cecbc1094..a588b880d3 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -51,6 +51,9 @@ todo "TODO" { "description" [ v-required ] } } validate-params ; +: view-todo-url ( id -- url ) + "$todo-list/view" >>path swap "id" set-query-param ; + : ( -- action ) [ 0 "priority" set-value ] >>init @@ -62,14 +65,7 @@ todo "TODO" [ f dup { "summary" "priority" "description" } deposit-slots - [ insert-tuple ] - [ - - "$todo-list/view" >>path - swap id>> "id" set-query-param - - ] - bi + [ insert-tuple ] [ id>> view-todo-url ] bi ] >>submit ; : ( -- action ) @@ -89,23 +85,19 @@ todo "TODO" [ f dup { "id" "summary" "priority" "description" } deposit-slots - [ update-tuple ] - [ - - "$todo-list/view" >>path - swap id>> "id" set-query-param - - ] - bi + [ update-tuple ] [ id>> view-todo-url ] bi ] >>submit ; +: todo-list-url ( -- url ) + URL" $todo-list/list" ; + : ( -- action ) [ validate-integer-id ] >>validate [ "id" get delete-tuples - URL" $todo-list/list" + todo-list-url ] >>submit ; : ( -- action ) diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 611bba4c70..1dc6ef4ae8 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -15,14 +15,14 @@ validators db.types db.tuples lcs farkup urls ; IN: webapps.wiki -: title-url ( title action -- url ) - "$wiki/" prepend >url swap "title" set-query-param ; +: view-url ( title -- url ) + "$wiki/view/" prepend >url ; -: view-url ( title -- url ) "view" title-url ; +: edit-url ( title -- url ) + "$wiki/edit" >url swap "title" set-query-param ; -: edit-url ( title -- url ) "edit" title-url ; - -: revisions-url ( title -- url ) "revisions" title-url ; +: revisions-url ( title -- url ) + "$wiki/revisions" >url swap "title" set-query-param ; : revision-url ( id -- url ) "$wiki/revision" >url swap "id" set-query-param ; From 460ce213afcd9fc4668b55da5e19bc5be89091c7 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 6 Jun 2008 18:57:37 -0500 Subject: [PATCH 0087/1850] Fix inference again --- extra/cairo/gadgets/gadgets.factor | 8 ++++---- extra/help/html/html.factor | 5 +++++ extra/opengl/gadgets/gadgets-tests.factor | 4 ++++ extra/pango/cairo/cairo.factor | 2 +- extra/pango/cairo/gadgets/gadgets.factor | 2 +- 5 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 extra/help/html/html.factor create mode 100644 extra/opengl/gadgets/gadgets-tests.factor diff --git a/extra/cairo/gadgets/gadgets.factor b/extra/cairo/gadgets/gadgets.factor index 691bcb866e..c9fef618f8 100644 --- a/extra/cairo/gadgets/gadgets.factor +++ b/extra/cairo/gadgets/gadgets.factor @@ -25,11 +25,11 @@ TUPLE: cairo-gadget < texture-gadget dim quot ; M: cairo-gadget cache-key* [ dim>> ] [ quot>> ] bi 2array ; : render-cairo ( dim quot -- bytes format ) - >r 2^-bounds r> copy-cairo GL_BGRA ; + >r 2^-bounds r> copy-cairo GL_BGRA ; inline -M: cairo-gadget render* - [ dim>> dup ] [ quot>> ] bi - render-cairo render-bytes* ; +! M: cairo-gadget render* +! [ dim>> dup ] [ quot>> ] bi +! render-cairo render-bytes* ; ! maybe also texture>png ! : cairo>png ( gadget path -- ) diff --git a/extra/help/html/html.factor b/extra/help/html/html.factor new file mode 100644 index 0000000000..b1bf8958a8 --- /dev/null +++ b/extra/help/html/html.factor @@ -0,0 +1,5 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +IN: help.html + + diff --git a/extra/opengl/gadgets/gadgets-tests.factor b/extra/opengl/gadgets/gadgets-tests.factor new file mode 100644 index 0000000000..499ec9730a --- /dev/null +++ b/extra/opengl/gadgets/gadgets-tests.factor @@ -0,0 +1,4 @@ +IN: opengl.gadgets.tests +USING: tools.test opengl.gadgets ; + +\ render* must-infer diff --git a/extra/pango/cairo/cairo.factor b/extra/pango/cairo/cairo.factor index f6c1ee498d..1ff5328ee0 100644 --- a/extra/pango/cairo/cairo.factor +++ b/extra/pango/cairo/cairo.factor @@ -100,7 +100,7 @@ destructors accessors namespaces kernel cairo ; >r alien>> pango-layout r> with-variable ; inline : with-pango-cairo ( quot -- ) - cr pango_cairo_create_layout swap with-layout ; + cr pango_cairo_create_layout swap with-layout ; inline MEMO: dummy-cairo ( -- cr ) CAIRO_FORMAT_ARGB32 0 0 cairo_image_surface_create cairo_create ; diff --git a/extra/pango/cairo/gadgets/gadgets.factor b/extra/pango/cairo/gadgets/gadgets.factor index 5fb579c1a1..a21affc364 100644 --- a/extra/pango/cairo/gadgets/gadgets.factor +++ b/extra/pango/cairo/gadgets/gadgets.factor @@ -18,7 +18,7 @@ M: pango-cairo-backend construct-pango : setup-layout ( gadget -- quot ) [ font>> ] [ text>> ] bi - '[ , layout-font , layout-text ] ; + '[ , layout-font , layout-text ] ; inline M: pango-cairo-gadget render* ( gadget -- ) setup-layout [ layout-size dup ] From 39d3769df808e50c305775c25c6c0c7239be5aaf Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Fri, 6 Jun 2008 19:49:42 -0500 Subject: [PATCH 0088/1850] Add dns.server --- extra/dns/server/server.factor | 139 +++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 extra/dns/server/server.factor diff --git a/extra/dns/server/server.factor b/extra/dns/server/server.factor new file mode 100644 index 0000000000..7c33265d39 --- /dev/null +++ b/extra/dns/server/server.factor @@ -0,0 +1,139 @@ + +USING: kernel + combinators + sequences + math + io.sockets + unicode.case + accessors + combinators.cleave + newfx + dns ; + +IN: dns.server + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: records ( -- vector ) V{ } ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: filter-by-name ( records name -- records ) swap [ name>> = ] with filter ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: {name-type-class} ( obj -- array ) + { [ name>> >lower ] [ type>> ] [ class>> ] } ; + +: rr=query? ( obj obj -- ? ) [ {name-type-class} ] bi@ = ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: matching-rrs ( query -- rrs ) records [ rr=query? ] with filter ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: matching-rrs? ( query -- query rrs/f ? ) dup matching-rrs dup empty? not ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: matching-cname? ( query -- query rr/f ? ) + dup clone CNAME >>type matching-rrs + dup empty? [ drop f f ] [ 1st t ] if ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +DEFER: query->rrs + +: query-canonical ( query rr -- rrs ) + tuck [ clone ] [ rdata>> ] bi* >>name query->rrs prefix-on ; + +: query->rrs ( query -- rrs/f ) + { + { [ matching-rrs? ] [ nip ] } + { [ drop matching-cname? ] [ query-canonical ] } + { [ drop t ] [ drop f ] } + } + cond ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: cdr-name ( name -- name ) dup CHAR: . index 1+ tail ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: delegate-servers? ( name -- name rrs ? ) + dup NS IN query boa matching-rrs dup empty? not ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: delegate-servers ( name -- rrs ) + { + { [ dup "" = ] [ drop { } ] } + { [ delegate-servers? ] [ nip ] } + { [ drop t ] [ cdr-name delegate-servers ] } + } + cond ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: delegate-addresses ( rrs-ns -- rrs-a ) + [ rdata>> A IN query boa matching-rrs ] map concat ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: have-delegates? ( query -- query rrs-ns ? ) + dup name>> delegate-servers dup empty? not ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: fill-additional ( message -- message ) + dup authority-section>> delegate-addresses >>additional-section ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: no-records-with-name? ( query -- query ? ) + dup name>> records [ name>> = ] with filter empty? ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: find-answer ( message -- message ) + dup message-query ! message query + { + { [ dup query->rrs dup ] [ nip >>answer-section 1 >>aa ] } + { [ drop have-delegates? ] [ nip >>authority-section fill-additional ] } + { [ drop no-records-with-name? ] [ drop NAME-ERROR >>rcode ] } + { [ drop t ] [ ] } + } + cond ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: (socket) ( -- vec ) V{ f } ; + +: socket ( -- socket ) (socket) 1st ; + +: init-socket-on-port ( port -- ) + f swap 0 (socket) as-mutate ; + +: init-socket ( -- ) 53 init-socket-on-port ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: loop ( -- ) + socket receive + swap + parse-message + find-answer + message->ba + swap + socket send + loop ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: start ( -- ) init-socket loop ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +MAIN: start \ No newline at end of file From 014d2ea31cd523285b7d052a02d76ee31db17cf4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 6 Jun 2008 20:47:09 -0500 Subject: [PATCH 0089/1850] Cleaning up and debugging corss-referencing --- core/compiler/compiler.factor | 2 +- core/compiler/units/units.factor | 4 +-- core/definitions/definitions.factor | 12 ++++++- core/generic/generic.factor | 6 ++++ .../standard/engines/tuple/tuple.factor | 7 ++-- core/generic/standard/standard-tests.factor | 24 +++++++++++++- core/inference/backend/backend.factor | 24 +++++++++++++- core/inference/inference-tests.factor | 32 ++++++++++++++++--- core/words/words.factor | 25 ++------------- extra/editors/editors.factor | 2 +- extra/tools/crossref/crossref.factor | 2 +- extra/tools/profiler/profiler-docs.factor | 2 +- extra/tools/profiler/profiler.factor | 2 +- extra/ui/tools/search/search.factor | 2 +- 14 files changed, 106 insertions(+), 40 deletions(-) diff --git a/core/compiler/compiler.factor b/core/compiler/compiler.factor index ef00e94dd5..8c653b866e 100755 --- a/core/compiler/compiler.factor +++ b/core/compiler/compiler.factor @@ -35,7 +35,7 @@ IN: compiler [ swap save-effect ] [ compiled-unxref ] [ - dup compiled-crossref? + dup crossref? [ dependencies get compiled-xref ] [ drop ] if ] tri ; diff --git a/core/compiler/units/units.factor b/core/compiler/units/units.factor index c2e84429cf..6acd3a6415 100755 --- a/core/compiler/units/units.factor +++ b/core/compiler/units/units.factor @@ -66,7 +66,7 @@ GENERIC: definitions-changed ( assoc obj -- ) : compile ( words -- ) recompile-hook get call - dup [ drop compiled-crossref? ] assoc-contains? + dup [ drop crossref? ] assoc-contains? modify-code-heap ; SYMBOL: outdated-tuples @@ -82,7 +82,7 @@ SYMBOL: update-tuples-hook : finish-compilation-unit ( -- ) call-recompile-hook call-update-tuples-hook - dup [ drop compiled-crossref? ] assoc-contains? modify-code-heap + dup [ drop crossref? ] assoc-contains? modify-code-heap ; : with-nested-compilation-unit ( quot -- ) diff --git a/core/definitions/definitions.factor b/core/definitions/definitions.factor index 459512b83a..122205eb26 100755 --- a/core/definitions/definitions.factor +++ b/core/definitions/definitions.factor @@ -47,7 +47,17 @@ M: object uses drop f ; : xref ( defspec -- ) dup uses crossref get add-vertex ; -: usage ( defspec -- seq ) \ f or crossref get at keys ; +: usage ( defspec -- seq ) crossref get at keys ; + +GENERIC: irrelevant? ( defspec -- ? ) + +M: object irrelevant? drop f ; + +GENERIC: smart-usage ( defspec -- seq ) + +M: f smart-usage drop \ f smart-usage ; + +M: object smart-usage usage [ irrelevant? not ] filter ; : unxref ( defspec -- ) dup uses crossref get remove-vertex ; diff --git a/core/generic/generic.factor b/core/generic/generic.factor index b9a556e316..c99de94ded 100755 --- a/core/generic/generic.factor +++ b/core/generic/generic.factor @@ -117,6 +117,9 @@ M: method-spec definition M: method-spec forget* first2 method forget* ; +M: method-spec smart-usage + second smart-usage ; + M: method-body definer drop \ M: \ ; ; @@ -134,6 +137,9 @@ M: method-body forget* [ t "forgotten" set-word-prop ] bi ] if ; +M: method-body smart-usage + "method-generic" word-prop smart-usage ; + : implementors* ( classes -- words ) all-words [ "methods" word-prop keys diff --git a/core/generic/standard/engines/tuple/tuple.factor b/core/generic/standard/engines/tuple/tuple.factor index 51ea4f8225..24fb8ba4f4 100644 --- a/core/generic/standard/engines/tuple/tuple.factor +++ b/core/generic/standard/engines/tuple/tuple.factor @@ -4,7 +4,7 @@ USING: kernel classes.tuple.private hashtables assocs sorting accessors combinators sequences slots.private math.parser words effects namespaces generic generic.standard.engines classes.algebra math math.private kernel.private -quotations arrays ; +quotations arrays definitions ; IN: generic.standard.engines.tuple TUPLE: echelon-dispatch-engine n methods ; @@ -64,8 +64,9 @@ M: engine-word stack-effect [ extra-values ] [ stack-effect ] bi dup [ clone [ length + ] change-in ] [ 2drop f ] if ; -M: engine-word compiled-crossref? - drop t ; +M: engine-word crossref? drop t ; + +M: engine-word irrelevant? drop t ; : remember-engine ( word -- ) generic get "engines" word-prop push ; diff --git a/core/generic/standard/standard-tests.factor b/core/generic/standard/standard-tests.factor index 1bff9ae15d..66f191a93f 100644 --- a/core/generic/standard/standard-tests.factor +++ b/core/generic/standard/standard-tests.factor @@ -3,7 +3,8 @@ USING: tools.test math math.functions math.constants generic.standard strings sequences arrays kernel accessors words float-arrays byte-arrays bit-arrays parser namespaces quotations inference vectors growable hashtables sbufs -prettyprint byte-vectors bit-vectors float-vectors ; +prettyprint byte-vectors bit-vectors float-vectors definitions +generic sets graphs assocs ; GENERIC: lo-tag-test @@ -287,3 +288,24 @@ M: sbuf no-stack-effect-decl ; [ ] [ \ no-stack-effect-decl see ] unit-test [ ] [ \ no-stack-effect-decl word-def . ] unit-test + +! Cross-referencing with generic words +TUPLE: xref-tuple-1 ; +TUPLE: xref-tuple-2 < xref-tuple-1 ; + +: (xref-test) drop ; + +GENERIC: xref-test ( obj -- ) + +M: xref-tuple-1 xref-test (xref-test) ; +M: xref-tuple-2 xref-test (xref-test) ; + +[ t ] [ + \ xref-test + \ xref-tuple-1 \ xref-test method [ usage unique ] closure key? +] unit-test + +[ t ] [ + \ xref-test + \ xref-tuple-2 \ xref-test method [ usage unique ] closure key? +] unit-test diff --git a/core/inference/backend/backend.factor b/core/inference/backend/backend.factor index c49e7fda8a..9a0f4c772e 100755 --- a/core/inference/backend/backend.factor +++ b/core/inference/backend/backend.factor @@ -4,7 +4,7 @@ USING: inference.dataflow inference.state arrays generic io io.streams.string kernel math namespaces parser prettyprint sequences strings vectors words quotations effects classes continuations debugger assocs combinators compiler.errors -generic.standard.engines.tuple accessors math.order ; +generic.standard.engines.tuple accessors math.order definitions ; IN: inference.backend : recursive-label ( word -- label/f ) @@ -21,6 +21,28 @@ M: engine-word inline? M: word inline? "inline" word-prop ; +SYMBOL: visited + +: reset-on-redefine { "inferred-effect" "no-effect" } ; inline + +: (redefined) ( word -- ) + dup visited get key? [ drop ] [ + [ reset-on-redefine reset-props ] + [ dup visited get set-at ] + [ + crossref get at keys + [ word? ] filter + [ + [ reset-on-redefine [ word-prop ] with contains? ] + [ inline? ] + bi or + ] filter + [ (redefined) ] each + ] tri + ] if ; + +M: word redefined H{ } clone visited [ (redefined) ] with-variable ; + : local-recursive-state ( -- assoc ) recursive-state get dup keys [ dup word? [ inline? ] when not ] find drop diff --git a/core/inference/inference-tests.factor b/core/inference/inference-tests.factor index 0d3eb03cf4..4ce354bdcc 100755 --- a/core/inference/inference-tests.factor +++ b/core/inference/inference-tests.factor @@ -549,10 +549,34 @@ ERROR: custom-error ; { 1 0 } [ [ ] map-children ] must-infer-as ! Corner case -! [ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail +[ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail -! [ [ [ f dup ] [ ] [ ] while ] infer ] must-fail +[ [ [ f dup ] [ ] [ ] while ] infer ] must-fail -! : erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline +: erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline -! [ [ erg's-inference-bug ] infer ] must-fail +[ [ erg's-inference-bug ] infer ] must-fail + +: inference-invalidation-a ; +: inference-invalidation-b [ inference-invalidation-a ] dip call ; inline +: inference-invalidation-c [ + ] inference-invalidation-b ; + +[ 7 ] [ 4 3 inference-invalidation-c ] unit-test + +{ 2 1 } [ inference-invalidation-c ] must-infer-as + +[ ] [ "IN: inference.tests : inference-invalidation-a 1 2 ;" eval ] unit-test + +[ 3 ] [ inference-invalidation-c ] unit-test + +{ 0 1 } [ inference-invalidation-c ] must-infer-as + +GENERIC: inference-invalidation-d ( obj -- ) + +M: object inference-invalidation-d inference-invalidation-c 2drop ; + +\ inference-invalidation-d must-infer + +[ ] [ "IN: inference.tests : inference-invalidation-a ;" eval ] unit-test + +[ [ inference-invalidation-d ] infer ] must-fail diff --git a/core/words/words.factor b/core/words/words.factor index 5549f98010..bc4b2ede72 100755 --- a/core/words/words.factor +++ b/core/words/words.factor @@ -102,7 +102,7 @@ SYMBOL: compiled-crossref compiled-crossref global [ H{ } assoc-like ] change-at : compiled-xref ( word dependencies -- ) - [ drop compiled-crossref? ] assoc-filter + [ drop crossref? ] assoc-filter 2dup "compiled-uses" set-word-prop compiled-crossref get add-vertex* ; @@ -125,28 +125,9 @@ SYMBOL: +called+ compiled-usage [ nip +inlined+ eq? ] assoc-filter update ] with each keys ; - - -: redefined ( word -- ) - H{ } clone visited [ (redefined) ] with-variable ; +M: object redefined drop ; : define ( word def -- ) [ ] like diff --git a/extra/editors/editors.factor b/extra/editors/editors.factor index a15a12830c..25bd560d42 100755 --- a/extra/editors/editors.factor +++ b/extra/editors/editors.factor @@ -53,7 +53,7 @@ M: object find-parse-error : fix ( word -- ) [ "Fixing " write pprint " and all usages..." print nl ] - [ [ usage ] keep prefix ] bi + [ [ smart-usage ] keep prefix ] bi [ [ "Editing " write . ] [ diff --git a/extra/tools/crossref/crossref.factor b/extra/tools/crossref/crossref.factor index f4515a9ebe..3ff22cb0c6 100755 --- a/extra/tools/crossref/crossref.factor +++ b/extra/tools/crossref/crossref.factor @@ -7,7 +7,7 @@ sorting hashtables vocabs parser source-files ; IN: tools.crossref : usage. ( word -- ) - usage sorted-definitions. ; + smart-usage sorted-definitions. ; : words-matching ( str -- seq ) all-words [ dup word-name ] { } map>assoc completions ; diff --git a/extra/tools/profiler/profiler-docs.factor b/extra/tools/profiler/profiler-docs.factor index 50bbc527d1..69edf1a7e0 100755 --- a/extra/tools/profiler/profiler-docs.factor +++ b/extra/tools/profiler/profiler-docs.factor @@ -44,7 +44,7 @@ HELP: vocab-profile. HELP: usage-profile. { $values { "word" word } } { $description "Prints a table of call counts from the most recent invocation of " { $link profile } ", for words which directly call " { $snippet "word" } " only." } -{ $notes "This word obtains the list of static usages with the " { $link usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." } +{ $notes "This word obtains the list of static usages with the " { $link smart-usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." } { $examples { $code "\\ + usage-profile." } } ; HELP: vocabs-profile. diff --git a/extra/tools/profiler/profiler.factor b/extra/tools/profiler/profiler.factor index 6a5fce6281..4ae3666829 100755 --- a/extra/tools/profiler/profiler.factor +++ b/extra/tools/profiler/profiler.factor @@ -58,7 +58,7 @@ M: method-body (profile.) "Call counts for words which call " write dup pprint ":" print - usage [ word? ] filter counters counters. ; + smart-usage [ word? ] filter counters counters. ; : vocabs-profile. ( -- ) "Call counts for all vocabularies:" print diff --git a/extra/ui/tools/search/search.factor b/extra/ui/tools/search/search.factor index b18c0c1ad6..695727e314 100755 --- a/extra/ui/tools/search/search.factor +++ b/extra/ui/tools/search/search.factor @@ -94,7 +94,7 @@ M: live-search pref-dim* drop { 400 200 } ; "Words in " rot vocab-name append show-titled-popup ; : show-word-usage ( workspace word -- ) - "" over usage f + "" over smart-usage f "Words and methods using " rot word-name append show-titled-popup ; From b1e761509eae5d75b94c56cc5545eafae0de193f Mon Sep 17 00:00:00 2001 From: Matthew Willis Date: Fri, 6 Jun 2008 20:12:16 -0700 Subject: [PATCH 0090/1850] pango.cairo.samples failed to load --- extra/pango/cairo/samples/samples.factor | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/extra/pango/cairo/samples/samples.factor b/extra/pango/cairo/samples/samples.factor index 644d731d70..f081650943 100644 --- a/extra/pango/cairo/samples/samples.factor +++ b/extra/pango/cairo/samples/samples.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: prettyprint sequences ui.gadgets.panes pango.cairo.gadgets math kernel cairo cairo.ffi -pango.cairo tools.time namespaces assocs +pango.cairo pango.gadgets tools.time namespaces assocs threads io.backend io.encodings.utf8 io.files ; IN: pango.cairo.samples @@ -10,14 +10,9 @@ IN: pango.cairo.samples : hello-pango ( -- ) "monospace 10" "resource:extra/pango/cairo/gadgets/gadgets.factor" normalize-path utf8 file-contents - gadget. ; + gadget. ; : time-pango ( -- ) [ hello-pango ] time ; -! clear the caches, for testing. -: clear-pango ( -- ) - dims get clear-assoc - textures get clear-assoc ; - MAIN: time-pango From f383c9a734ba2c2e2b817c7ee00cf1b679aabee2 Mon Sep 17 00:00:00 2001 From: James Cash Date: Fri, 6 Jun 2008 14:35:34 -0400 Subject: [PATCH 0091/1850] Removing commented-out junk --- extra/lisp/lisp-tests.factor | 6 ------ 1 file changed, 6 deletions(-) diff --git a/extra/lisp/lisp-tests.factor b/extra/lisp/lisp-tests.factor index c4090e1098..14b91aa58b 100644 --- a/extra/lisp/lisp-tests.factor +++ b/extra/lisp/lisp-tests.factor @@ -13,8 +13,6 @@ IN: lisp.test "+" "math" "+" define-primitive "-" "math" "-" define-primitive -! "list" [ >array ] lisp-define - { 5 } [ [ 2 3 ] "+" funcall ] unit-test @@ -55,8 +53,4 @@ IN: lisp.test "((lambda (x) (if x (begin (+ 1 2)) (- 3 5))) #t)" lisp-eval ] unit-test -! { { 1 2 3 4 5 } } [ -! "(list 1 2 3 4 5)" lisp-eval -! ] unit-test - ] with-interactive-vocabs From 5d7fb45c576b5de3e4262e186632f543589e5d01 Mon Sep 17 00:00:00 2001 From: James Cash Date: Sat, 7 Jun 2008 00:27:17 -0400 Subject: [PATCH 0092/1850] Converting another lazy-list to lists.lazy --- extra/lists/lazy/examples/examples-tests.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/lists/lazy/examples/examples-tests.factor b/extra/lists/lazy/examples/examples-tests.factor index d4e3ed79b8..c088f1d9a7 100644 --- a/extra/lists/lazy/examples/examples-tests.factor +++ b/extra/lists/lazy/examples/examples-tests.factor @@ -1,5 +1,5 @@ -USING: lazy-lists.examples lazy-lists tools.test ; -IN: lazy-lists.examples.tests +USING: lists.lazy.examples lazy-lists tools.test ; +IN: lists.lazy.examples.tests [ { 1 3 5 7 } ] [ 4 odds ltake list>array ] unit-test [ { 0 1 4 9 16 } ] [ first-five-squares ] unit-test From a126ad755a9da7603c3234caeb6bee2599a2a37d Mon Sep 17 00:00:00 2001 From: James Cash Date: Sat, 7 Jun 2008 00:27:33 -0400 Subject: [PATCH 0093/1850] More work on macros --- extra/lisp/lisp.factor | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index e865a2e3ed..425ee27bb7 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -59,10 +59,23 @@ PRIVATE> : convert-unquoted ( cons -- quot ) "unquote not valid outside of quasiquote!" throw ; -: convert-quasiquoted ( cons -- newcons ) +: convert-unquoted-splicing ( cons -- quot ) + "unquote-splicing not valid outside of quasiquote!" throw ; + +> "unquote" equal? dup ] } && nip ] [ cadr ] traverse ; +: quasiquote-unquote-splicing ( cons -- newcons ) + [ { [ dup list? ] [ dup cdr [ cons? ] [ car cons? ] bi and ] + [ dup cadr car lisp-symbol? ] [ cadr car name>> "unquote-splicing" equal? dup ] } && nip ] + [ dup cadr cdr >>cdr ] traverse ; +PRIVATE> + +: convert-quasiquoted ( cons -- newcons ) + quasiquote-unquote quasiquote-unquote-splicing ; + : convert-defmacro ( cons -- quot ) cdr [ car ] keep [ convert-lambda ] [ car name>> ] bi define-lisp-macro 1quotation ; @@ -72,6 +85,7 @@ PRIVATE> { "defmacro" [ convert-defmacro ] } { "quote" [ convert-quoted ] } { "unquote" [ convert-unquoted ] } + { "unquote-splicing" [ convert-unquoted-splicing ] } { "quasiquote" [ convert-quasiquoted ] } { "begin" [ convert-begin ] } { "cond" [ convert-cond ] } @@ -99,7 +113,7 @@ PRIVATE> call ; inline : macro-expand ( cons -- quot ) - uncons [ list>seq [ ] like ] [ lookup-macro macro-call compile-form ] bi* call ; + uncons [ list>seq [ ] like ] [ lookup-macro macro-call compile-form ] bi* ; : lisp-string>factor ( str -- quot ) lisp-expr parse-result-ast compile-form ; From 1ccab34cfa59bdcf3d566ad0e838ab5562638801 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 7 Jun 2008 04:19:23 -0500 Subject: [PATCH 0094/1850] Fix inference bug erg found a while ago --- core/inference/backend/backend-docs.factor | 2 +- core/inference/backend/backend.factor | 151 ++++++++++++--------- core/inference/errors/errors.factor | 20 ++- core/inference/inference-docs.factor | 2 +- 4 files changed, 98 insertions(+), 77 deletions(-) diff --git a/core/inference/backend/backend-docs.factor b/core/inference/backend/backend-docs.factor index 91314d1312..ccfa490318 100755 --- a/core/inference/backend/backend-docs.factor +++ b/core/inference/backend/backend-docs.factor @@ -61,7 +61,7 @@ HELP: effect-error { $description "Throws an " { $link effect-error } "." } { $error-description "Thrown when a word's inferred stack effect does not match its declared stack effect." } ; -HELP: recursive-declare-error +HELP: no-recursive-declaration { $error-description "Thrown when inference encounters a recursive call to a word lacking a stack effect declaration. Recursive words must declare a stack effect in order to compile. Due to implementation detail, generic words are recursive, and thus the same restriction applies." } ; HELP: recursive-quotation-error diff --git a/core/inference/backend/backend.factor b/core/inference/backend/backend.factor index 9a0f4c772e..42a1c1dd19 100755 --- a/core/inference/backend/backend.factor +++ b/core/inference/backend/backend.factor @@ -90,8 +90,9 @@ M: object value-literal \ literal-expected inference-warning ; meta-d [ add-inputs ] change d-in [ + ] change ; : current-effect ( -- effect ) - d-in get meta-d get length - terminated? get over set-effect-terminated? ; + d-in get + meta-d get length + terminated? get >>terminated? ; : init-inference ( -- ) terminated? off @@ -115,13 +116,13 @@ M: wrapper apply-object terminated? on #terminate node, ; : infer-quot ( quot rstate -- ) - recursive-state get >r - recursive-state set - [ apply-object terminated? get not ] all? drop - r> recursive-state set ; + recursive-state get [ + recursive-state set + [ apply-object terminated? get not ] all? drop + ] dip recursive-state set ; : infer-quot-recursive ( quot word label -- ) - recursive-state get -rot 2array prefix infer-quot ; + 2array recursive-state get swap prefix infer-quot ; : time-bomb ( error -- ) [ throw ] curry recursive-state get infer-quot ; @@ -136,9 +137,9 @@ TUPLE: recursive-quotation-error quot ; value-literal recursive-quotation-error inference-error ] [ dup value-literal callable? [ - dup value-literal - over value-recursion - rot f 2array prefix infer-quot + [ value-literal ] + [ [ value-recursion ] keep f 2array prefix ] + bi infer-quot ] [ drop bad-call ] if @@ -191,26 +192,26 @@ TUPLE: too-many-r> ; meta-d get push-all ; : if-inline ( word true false -- ) - >r >r dup inline? r> r> if ; inline + [ dup inline? ] 2dip if ; inline : consume/produce ( effect node -- ) - over effect-in over consume-values - over effect-out over produce-values - node, - effect-terminated? [ terminate ] when ; + [ [ in>> ] dip consume-values ] + [ [ out>> ] dip produce-values ] + [ node, terminated?>> [ terminate ] when ] + 2tri ; GENERIC: constructor ( value -- word/f ) GENERIC: infer-uncurry ( value -- ) M: curried infer-uncurry - drop pop-d dup curried-obj push-d curried-quot push-d ; + drop pop-d [ obj>> push-d ] [ quot>> push-d ] bi ; M: curried constructor drop \ curry ; M: composed infer-uncurry - drop pop-d dup composed-quot1 push-d composed-quot2 push-d ; + drop pop-d [ quot1>> push-d ] [ quot2>> push-d ] bi ; M: composed constructor drop \ compose ; @@ -255,13 +256,13 @@ M: object constructor drop f ; DEFER: unify-values : unify-curries ( seq -- value ) - dup [ curried-obj ] map unify-values - swap [ curried-quot ] map unify-values + [ [ obj>> ] map unify-values ] + [ [ quot>> ] map unify-values ] bi ; : unify-composed ( seq -- value ) - dup [ composed-quot1 ] map unify-values - swap [ composed-quot2 ] map unify-values + [ [ quot1>> ] map unify-values ] + [ [ quot2>> ] map unify-values ] bi ; TUPLE: cannot-unify-specials ; @@ -292,7 +293,7 @@ TUPLE: unbalanced-branches-error quots in out ; : unify-inputs ( max-d-in d-in meta-d -- meta-d ) dup [ - [ >r - r> length + ] keep add-inputs nip + [ [ - ] dip length + ] keep add-inputs nip ] [ 2nip ] if ; @@ -318,21 +319,24 @@ TUPLE: unbalanced-branches-error quots in out ; [ swap at ] curry map ; : datastack-effect ( seq -- ) - dup quotation branch-variable - over d-in branch-variable - rot meta-d active-variable - unify-effect meta-d set d-in set ; + [ quotation branch-variable ] + [ d-in branch-variable ] + [ meta-d active-variable ] tri + unify-effect + [ d-in set ] [ meta-d set ] bi* ; : retainstack-effect ( seq -- ) - dup quotation branch-variable - over length 0 - rot meta-r active-variable - unify-effect meta-r set drop ; + [ quotation branch-variable ] + [ length 0 ] + [ meta-r active-variable ] tri + unify-effect + [ drop ] [ meta-r set ] bi* ; : unify-effects ( seq -- ) - dup datastack-effect - dup retainstack-effect - [ terminated? swap at ] all? terminated? set ; + [ datastack-effect ] + [ retainstack-effect ] + [ [ terminated? swap at ] all? terminated? set ] + tri ; : unify-dataflow ( effects -- nodes ) dataflow-graph branch-variable ; @@ -347,14 +351,17 @@ TUPLE: unbalanced-branches-error quots in out ; : infer-branch ( last value -- namespace ) [ copy-inference - dup value-literal quotation set - infer-quot-value + + [ value-literal quotation set ] + [ infer-quot-value ] + bi + terminated? get [ drop ] [ call node, ] if ] H{ } make-assoc ; inline : (infer-branches) ( last branches -- list ) [ infer-branch ] with map - dup unify-effects unify-dataflow ; inline + [ unify-effects ] [ unify-dataflow ] bi ; inline : infer-branches ( last branches node -- ) #! last is a quotation which provides a #return or a #values @@ -390,9 +397,10 @@ TUPLE: effect-error word effect ; : finish-word ( word -- ) current-effect - 2dup check-effect - over recorded get push - "inferred-effect" set-word-prop ; + [ check-effect ] + [ drop recorded get push ] + [ "inferred-effect" set-word-prop ] + 2tri ; : infer-word ( word -- effect ) [ @@ -408,8 +416,7 @@ TUPLE: effect-error word effect ; : custom-infer ( word -- ) #! Customized inference behavior - dup +inlined+ depends-on - "infer" word-prop call ; + [ +inlined+ depends-on ] [ "infer" word-prop call ] bi ; : cached-infer ( word -- ) dup "inferred-effect" word-prop make-call-node ; @@ -422,13 +429,13 @@ TUPLE: effect-error word effect ; [ dup infer-word make-call-node ] } cond ; -TUPLE: recursive-declare-error word ; +TUPLE: no-recursive-declaration word ; : declared-infer ( word -- ) dup stack-effect [ make-call-node ] [ - \ recursive-declare-error inference-error + \ no-recursive-declaration inference-error ] if* ; GENERIC: collect-label-info* ( label node -- ) @@ -463,40 +470,56 @@ M: #return collect-label-info* : inline-block ( word -- #label data ) [ copy-inference nest-node - dup word-def swap + [ word-def ] [ ] bi [ infer-quot-recursive ] 2keep #label unnest-node dup collect-label-info ] H{ } make-assoc ; : join-values ( #label -- ) - calls>> [ node-in-d ] map meta-d get suffix + calls>> [ in-d>> ] map meta-d get suffix unify-lengths unify-stacks meta-d [ length tail* ] change ; : splice-node ( node -- ) - dup node-successor [ - dup node, penultimate-node f over set-node-successor - dup current-node set - ] when drop ; + dup successor>> [ + [ node, ] [ penultimate-node ] bi + f >>successor + current-node set + ] [ drop ] if ; -: apply-infer ( hash -- ) - { meta-d meta-r d-in terminated? } - [ swap [ at ] curry map ] keep - [ set ] 2each ; +: apply-infer ( data -- ) + { meta-d meta-r d-in terminated? } swap extract-keys + namespace swap update ; + +: current-stack-height ( -- n ) + meta-d get length d-in get - ; + +: word-stack-height ( word -- n ) + stack-effect [ in>> length ] [ out>> length ] bi - ; + +: bad-recursive-declaration ( word inferred -- ) + dup 0 < [ 0 ] [ 0 swap ] if effect-error ; + +: check-stack-height ( word height -- ) + over word-stack-height over = + [ 2drop ] [ bad-recursive-declaration ] if ; + +: inline-recursive-word ( word #label -- ) + current-stack-height [ + flatten-meta-d [ join-values inline-block apply-infer ] dip >>in-d + [ node, ] + [ calls>> [ [ flatten-curries ] modify-values ] each ] + [ word>> ] + tri + ] dip + current-stack-height - + check-stack-height ; : inline-word ( word -- ) - dup inline-block over recursive-label? [ - flatten-meta-d >r - drop join-values inline-block apply-infer - r> over set-node-in-d - dup node, - calls>> [ - [ flatten-curries ] modify-values - ] each - ] [ - apply-infer node-child node-successor splice-node drop - ] if ; + dup inline-block over recursive-label? + [ drop inline-recursive-word ] + [ apply-infer node-child successor>> splice-node drop ] if ; M: word apply-object [ diff --git a/core/inference/errors/errors.factor b/core/inference/errors/errors.factor index f565420cac..3c6680bcde 100644 --- a/core/inference/errors/errors.factor +++ b/core/inference/errors/errors.factor @@ -15,10 +15,8 @@ M: inference-error error-help drop f ; M: unbalanced-branches-error error. "Unbalanced branches:" print - dup unbalanced-branches-error-quots - over unbalanced-branches-error-in - rot unbalanced-branches-error-out [ length ] map - 3array flip [ [ bl ] [ pprint ] interleave nl ] each ; + [ quots>> ] [ in>> ] [ out>> [ length ] map ] tri 3array flip + [ [ bl ] [ pprint ] interleave nl ] each ; M: literal-expected summary drop "Literal value expected" ; @@ -32,24 +30,24 @@ M: too-many-r> summary "Quotation pops retain stack elements which it did not push" ; M: no-effect error. - "Unable to infer stack effect of " write no-effect-word . ; + "Unable to infer stack effect of " write word>> . ; -M: recursive-declare-error error. +M: no-recursive-declaration error. "The recursive word " write - recursive-declare-error-word pprint + word>> pprint " must declare a stack effect" print ; M: effect-error error. "Stack effects of the word " write - dup effect-error-word pprint + dup word>> pprint " do not match." print "Declared: " write - dup effect-error-word stack-effect effect>string . - "Inferred: " write effect-error-effect effect>string . ; + dup word>> stack-effect effect>string . + "Inferred: " write effect>> effect>string . ; M: recursive-quotation-error error. "The quotation " write - recursive-quotation-error-quot pprint + quot>> pprint " calls itself." print "Stack effect inference is undecidable when quotation-level recursion is permitted." print ; diff --git a/core/inference/inference-docs.factor b/core/inference/inference-docs.factor index d79c82ed65..acc9329670 100755 --- a/core/inference/inference-docs.factor +++ b/core/inference/inference-docs.factor @@ -89,7 +89,7 @@ ARTICLE: "inference-errors" "Inference errors" { $subsection too-many-r> } { $subsection unbalanced-branches-error } { $subsection effect-error } -{ $subsection recursive-declare-error } ; +{ $subsection no-recursive-declaration } ; ARTICLE: "inference" "Stack effect inference" "The stack effect inference tool is used to check correctness of code before it is run. It is also used by the compiler to build a dataflow graph on which optimizations can be performed. Only words for which a stack effect can be inferred will compile." From 5bae4c6e89bd2a33011892cde66943ceac5c34a0 Mon Sep 17 00:00:00 2001 From: "U-SLAVA-DFB8FF805\\Slava" Date: Sat, 7 Jun 2008 07:22:09 -0500 Subject: [PATCH 0095/1850] Windows C runtime library doesn't have inverse hyperbolic functions --- extra/math/functions/functions-tests.factor | 3 +++ extra/math/functions/functions.factor | 6 ++--- extra/math/libm/libm.factor | 25 +++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) mode change 100644 => 100755 extra/math/libm/libm.factor diff --git a/extra/math/functions/functions-tests.factor b/extra/math/functions/functions-tests.factor index 6176c12d21..232fdb25b3 100755 --- a/extra/math/functions/functions-tests.factor +++ b/extra/math/functions/functions-tests.factor @@ -44,7 +44,10 @@ IN: math.functions.tests [ t ] [ 10 asin sin 10 1.e-10 ~ ] unit-test [ t ] [ -1 sqrt neg dup acos cos 1.e-10 ~ ] unit-test +[ t ] [ -100 atan tan -100 1.e-10 ~ ] unit-test [ t ] [ 10 asinh sinh 10 1.e-10 ~ ] unit-test +[ t ] [ 10 atanh tanh 10 1.e-10 ~ ] unit-test +[ t ] [ 0.5 atanh tanh 0.5 1.e-10 ~ ] unit-test [ 100 ] [ 100 100 gcd nip ] unit-test [ 100 ] [ 1000 100 gcd nip ] unit-test diff --git a/extra/math/functions/functions.factor b/extra/math/functions/functions.factor index bb43e4a721..4dcb215138 100755 --- a/extra/math/functions/functions.factor +++ b/extra/math/functions/functions.factor @@ -182,17 +182,17 @@ M: number (^) : coth ( x -- y ) tanh recip ; inline : acosh ( x -- y ) - dup >=1? [ facosh ] [ dup sq 1- sqrt + log ] if ; inline + dup sq 1- sqrt + log ; inline : asech ( x -- y ) recip acosh ; inline : asinh ( x -- y ) - dup complex? [ dup sq 1+ sqrt + log ] [ fasinh ] if ; inline + dup sq 1+ sqrt + log ; inline : acosech ( x -- y ) recip asinh ; inline : atanh ( x -- y ) - dup [-1,1]? [ fatanh ] [ dup 1+ swap 1- neg / log 2 / ] if ; inline + dup 1+ swap 1- neg / log 2 / ; inline : acoth ( x -- y ) recip atanh ; inline diff --git a/extra/math/libm/libm.factor b/extra/math/libm/libm.factor old mode 100644 new mode 100755 index f70c8d2a77..8bda6a6dd0 --- a/extra/math/libm/libm.factor +++ b/extra/math/libm/libm.factor @@ -15,18 +15,6 @@ IN: math.libm "double" "libm" "atan" { "double" } alien-invoke ; foldable -: facosh ( x -- y ) - "double" "libm" "acosh" { "double" } alien-invoke ; - foldable - -: fasinh ( x -- y ) - "double" "libm" "asinh" { "double" } alien-invoke ; - foldable - -: fatanh ( x -- y ) - "double" "libm" "atanh" { "double" } alien-invoke ; - foldable - : fatan2 ( x y -- z ) "double" "libm" "atan2" { "double" "double" } alien-invoke ; foldable @@ -70,3 +58,16 @@ IN: math.libm : fsqrt ( x -- y ) "double" "libm" "sqrt" { "double" } alien-invoke ; foldable + +! Windows doesn't have these... +: facosh ( x -- y ) + "double" "libm" "acosh" { "double" } alien-invoke ; + foldable + +: fasinh ( x -- y ) + "double" "libm" "asinh" { "double" } alien-invoke ; + foldable + +: fatanh ( x -- y ) + "double" "libm" "atanh" { "double" } alien-invoke ; + foldable From 2e39bed5ec45d0d10a658c60cfd6367a2895ee18 Mon Sep 17 00:00:00 2001 From: "U-SLAVA-DFB8FF805\\Slava" Date: Sat, 7 Jun 2008 07:22:38 -0500 Subject: [PATCH 0096/1850] Trim some fat from tree-shaken images on Windows --- extra/ui/windows/windows.factor | 4 ++-- extra/unicode/data/data.factor | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/ui/windows/windows.factor b/extra/ui/windows/windows.factor index 5e17d02542..d42c679b22 100755 --- a/extra/ui/windows/windows.factor +++ b/extra/ui/windows/windows.factor @@ -3,7 +3,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types alien.strings arrays assocs ui ui.gadgets ui.backend ui.clipboards ui.gadgets.worlds -ui.gestures io kernel math math.vectors namespaces prettyprint +ui.gestures io kernel math math.vectors namespaces sequences strings vectors words windows.kernel32 windows.gdi32 windows.user32 windows.opengl32 windows.messages windows.types windows.nt windows threads libc combinators continuations @@ -380,7 +380,7 @@ SYMBOL: trace-messages? "uint" { "void*" "uint" "long" "long" } "stdcall" [ [ pick - trace-messages? get-global [ dup windows-message-name . ] when + trace-messages? get-global [ dup windows-message-name word-name print flush ] when wm-handlers get-global at* [ call ] [ drop DefWindowProc ] if ] ui-try ] alien-callback ; diff --git a/extra/unicode/data/data.factor b/extra/unicode/data/data.factor index f9e5667947..125442e17f 100755 --- a/extra/unicode/data/data.factor +++ b/extra/unicode/data/data.factor @@ -46,11 +46,11 @@ VALUE: properties : (process-data) ( index data -- newdata ) filter-comments - [ [ nth ] keep first swap 2array ] with map + [ [ nth ] keep first swap ] with { } map>assoc [ >r hex> r> ] assoc-map ; : process-data ( index data -- hash ) - (process-data) [ hex> ] assoc-map >hashtable ; + (process-data) [ hex> ] assoc-map [ nip ] assoc-filter >hashtable ; : (chain-decomposed) ( hash value -- newvalue ) [ From 4ca59470ce8ef6907e6d6efad2cb719d7a9e4976 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 7 Jun 2008 10:40:40 -0500 Subject: [PATCH 0097/1850] Minor cleanup --- core/kernel/kernel.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/kernel/kernel.factor b/core/kernel/kernel.factor index 9112dbf25e..61f687c95a 100755 --- a/core/kernel/kernel.factor +++ b/core/kernel/kernel.factor @@ -72,7 +72,7 @@ DEFER: if >r keep r> call ; inline : tri ( x p q r -- ) - >r pick >r bi r> r> call ; inline + >r >r keep r> keep r> call ; inline ! Double cleavers : 2bi ( x y p q -- ) @@ -93,7 +93,7 @@ DEFER: if >r dip r> call ; inline : tri* ( x y z p q r -- ) - >r rot >r bi* r> r> call ; inline + >r >r 2dip r> dip r> call ; inline ! Double spreaders : 2bi* ( w x y z p q -- ) From 313bd9b15453e1965e50f00eeb420c4ca089a56c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 7 Jun 2008 10:40:47 -0500 Subject: [PATCH 0098/1850] Minor web framework fixes --- extra/http/server/server.factor | 9 +++++++-- extra/webapps/blogs/blogs-common.xml | 2 +- extra/webapps/blogs/view-post.xml | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 10d6070f7b..fc50432030 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -44,8 +44,13 @@ main-responder global [ <404> or ] change-at : do-response ( response -- ) dup write-response - request get method>> "HEAD" = - [ drop ] [ '[ , write-response-body ] [ http-error. ] recover ] if ; + request get method>> "HEAD" = [ drop ] [ + '[ , write-response-body ] + [ + development-mode get + [ http-error. ] [ drop "Response error" ] if + ] recover + ] if ; LOG: httpd-hit NOTICE diff --git a/extra/webapps/blogs/blogs-common.xml b/extra/webapps/blogs/blogs-common.xml index 38005e6f1c..965f059abd 100644 --- a/extra/webapps/blogs/blogs-common.xml +++ b/extra/webapps/blogs/blogs-common.xml @@ -24,7 +24,7 @@ -

+

diff --git a/extra/webapps/blogs/view-post.xml b/extra/webapps/blogs/view-post.xml index 3489f1e331..23bf513946 100644 --- a/extra/webapps/blogs/view-post.xml +++ b/extra/webapps/blogs/view-post.xml @@ -6,11 +6,11 @@ : - + Recent Posts by - + :

From 95663e56ce0c57cf7ee7ccb2a67e823e66b4f135 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sat, 7 Jun 2008 10:48:05 -0500 Subject: [PATCH 0099/1850] commit local changes --- extra/db/queries/queries.factor | 47 ++++++++++++++++++++++++++--- extra/db/sql/sql.factor | 32 ++++++++++++-------- extra/db/tuples/tuples-tests.factor | 6 ++-- extra/db/tuples/tuples.factor | 22 +++++++++++--- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/extra/db/queries/queries.factor b/extra/db/queries/queries.factor index d524080e57..29abe9bddc 100644 --- a/extra/db/queries/queries.factor +++ b/extra/db/queries/queries.factor @@ -3,7 +3,7 @@ USING: accessors kernel math namespaces sequences random strings math.parser math.intervals combinators math.bitfields.lib namespaces.lib db db.tuples db.types -sequences.lib ; +sequences.lib db.sql classes words shuffle arrays ; IN: db.queries GENERIC: where ( specs obj -- ) @@ -146,7 +146,7 @@ M: db ( tuple class -- statement ) number>string " limit " prepend append ] curry change-sql drop ; -: make-advanced-statement ( tuple advanced -- tuple' ) +: make-query ( tuple query -- tuple' ) dupd { [ group>> [ do-group ] [ drop ] if* ] @@ -155,6 +155,43 @@ M: db ( tuple class -- statement ) [ offset>> [ do-offset ] [ drop ] if* ] } 2cleave ; -M: db ( tuple class group order limit offset -- tuple ) - advanced-statement boa - [ ] dip make-advanced-statement ; +M: db ( tuple class group order limit offset -- tuple ) + \ query boa + [ ] dip make-query ; + +! select ID, NAME, SCORE from EXAM limit 1 offset 3 + +: select-tuples* ( tuple -- statement ) + dup + [ + select 0, + dup class db-columns [ ", " 0, ] + [ dup column-name>> 0, 2, ] interleave + from 0, + class word-name 0, + ] { { } { } { } } nmake + >r >r parse-sql 4drop r> r> + maybe-make-retryable do-select ; + +M: db ( tuple class groups -- statement ) + f f f \ query boa + [ [ "select count(*) from " 0% 0% where-clause ] query-make ] + dip make-query ; + +: where-clause* ( tuple specs -- ) + dupd filter-slots [ + drop + ] [ + \ where 0, + [ 2dup slot-name>> swap get-slot-named where ] map 2array 0, + drop + ] if-empty ; + +: delete-tuple* ( tuple -- sql ) + dup + [ + delete 0, from 0, dup class db-table 0, + dup class db-columns where-clause* + ] { { } { } { } } nmake + >r >r parse-sql 4drop r> r> + maybe-make-retryable do-select ; diff --git a/extra/db/sql/sql.factor b/extra/db/sql/sql.factor index 756aeea7c0..dc8b5d1fb1 100755 --- a/extra/db/sql/sql.factor +++ b/extra/db/sql/sql.factor @@ -5,7 +5,7 @@ IN: db.sql SYMBOLS: insert update delete select distinct columns from as where group-by having order-by limit offset is-null desc all -any count avg table values ? ; +any count avg table values ; ! Output an s-exp sql statement and an alist of keys/values @@ -25,12 +25,27 @@ DEFER: sql% : sql-function, ( seq function -- ) sql% "(" sql% unclip sql% ")" sql% [ sql% ] each ; +: sql-where ( seq -- ) +B + [ + [ second 0, ] + [ first 0, ] + [ third 1, \ ? 0, ] tri + ] each ; + : sql-array% ( array -- ) +B unclip { + { \ create [ "create table" sql% ] } + { \ drop [ "drop table" sql% ] } + { \ insert [ "insert into" sql% ] } + { \ update [ "update" sql% ] } + { \ delete [ "delete" sql% ] } + { \ select [ B "select" sql% "," (sql-interleave) ] } { \ columns [ "," (sql-interleave) ] } { \ from [ "from" "," sql-interleave ] } - { \ where [ "where" "and" sql-interleave ] } + { \ where [ B "where" 0, sql-where ] } { \ group-by [ "group by" "," sql-interleave ] } { \ having [ "having" "," sql-interleave ] } { \ order-by [ "order by" "," sql-interleave ] } @@ -51,7 +66,7 @@ DEFER: sql% ERROR: no-sql-match ; : sql% ( obj -- ) { - { [ dup string? ] [ " " 0% 0% ] } + { [ dup string? ] [ 0, ] } { [ dup array? ] [ sql-array% ] } { [ dup number? ] [ number>string sql% ] } { [ dup symbol? ] [ unparse sql% ] } @@ -61,13 +76,4 @@ ERROR: no-sql-match ; } cond ; : parse-sql ( obj -- sql in-spec out-spec in out ) - [ - unclip { - { \ create [ "create table" sql% ] } - { \ drop [ "drop table" sql% ] } - { \ insert [ "insert into" sql% ] } - { \ update [ "update" sql% ] } - { \ delete [ "delete" sql% ] } - { \ select [ "select" sql% ] } - } case [ sql% ] each - ] { "" { } { } { } { } } nmake ; + [ [ sql% ] each ] { { } { } { } } nmake ; diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index f9a597e814..665afa6a51 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -227,7 +227,7 @@ TUPLE: exam id name score ; : random-exam ( -- exam ) f - 6 [ CHAR: a CHAR: b [a,b] random ] replicate >string + 6 [ CHAR: a CHAR: z [a,b] random ] replicate >string 100 random exam boa ; @@ -340,7 +340,9 @@ TUPLE: exam id name score ; } ] [ T{ exam } select-tuples - ] unit-test ; + ] unit-test + + [ 4 ] [ T{ exam } count-tuples ] unit-test ; TUPLE: bignum-test id m n o ; : ( m n o -- obj ) diff --git a/extra/db/tuples/tuples.factor b/extra/db/tuples/tuples.factor index 09fd63b233..d121e06445 100755 --- a/extra/db/tuples/tuples.factor +++ b/extra/db/tuples/tuples.factor @@ -42,8 +42,9 @@ HOOK: db ( class -- obj ) HOOK: db ( class -- obj ) HOOK: db ( tuple class -- obj ) HOOK: db ( tuple class -- tuple ) -TUPLE: advanced-statement group order offset limit ; -HOOK: db ( tuple class group order offset limit -- tuple ) +TUPLE: query group order offset limit ; +HOOK: db ( tuple class group order offset limit -- tuple ) +HOOK: db ( tuple class -- n ) HOOK: insert-tuple* db ( tuple statement -- ) @@ -152,9 +153,20 @@ M: retryable execute-statement* ( statement type -- ) dup dup class do-select ; : select-tuple ( tuple -- tuple/f ) - dup dup class f f f 1 + dup dup class f f f 1 do-select ?first ; -: advanced-select ( tuple groups order offset limit -- tuples ) +: query ( tuple groups order offset limit -- tuples ) >r >r >r >r dup dup class r> r> r> r> - do-select ; + do-select ; + +: do-count ( exemplar-tuple statement -- tuples ) + [ + [ bind-tuple ] [ nip default-query ] 2bi + ] with-disposal ; + +: count-tuples ( tuple groups -- n ) + >r dup dup class r> do-count + dup length 1 = [ first first string>number ] [ + [ first string>number ] map + ] if ; From 3480a93fd5e92d3d632111a863f2f3b554209874 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Sat, 7 Jun 2008 01:15:42 -0300 Subject: [PATCH 0100/1850] irc.client: Some small changes, and replace listen-to by listener objects of different types. --- extra/irc/client/client.factor | 64 +++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 5c9469ddd5..6598a0f08b 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -33,14 +33,30 @@ TUPLE: irc-client profile nick stream in-messages out-messages join-messages [ latin1 ] irc-client boa ; TUPLE: irc-listener in-messages out-messages ; -: ( -- irc-listener ) - irc-listener boa ; +TUPLE: irc-server-listener < irc-listener ; +TUPLE: irc-channel-listener < irc-listener name password timeout ; +TUPLE: irc-nick-listener < irc-listener name ; +UNION: irc-named-listener irc-nick-listener irc-channel-listener ; + +: ( -- irc-listener ) irc-listener boa ; + +: ( -- irc-server-listener ) + irc-server-listener boa ; + +: ( name -- irc-channel-listener ) + rot f 60 seconds irc-channel-listener boa ; + +: ( name -- irc-nick-listener ) + rot irc-nick-listener boa ; ! ====================================== ! Message objects ! ====================================== -SINGLETON: irc-end ! Message used when the client isn't running anymore +SINGLETON: irc-end ! Message sent when the client isn't running anymore +SINGLETON: irc-lost ! Message sent when connection was lost +SINGLETON: irc-restore ! Message sent when connection was restored +UNION: irc-broadcasted-message irc-end irc-lost irc-restore ; TUPLE: irc-message line prefix command parameters trailing timestamp ; TUPLE: logged-in < irc-message name ; @@ -163,6 +179,9 @@ TUPLE: unhandled < irc-message ; : irc-message-origin ( irc-message -- name ) dup name>> me? [ prefix>> parse-name ] [ name>> ] if ; +: broadcast-message-to-listeners ( message -- ) + irc-client> listeners>> values [ in-messages>> mailbox-put ] with each ; + GENERIC: handle-incoming-irc ( irc-message -- ) M: irc-message handle-incoming-irc ( irc-message -- ) @@ -184,8 +203,8 @@ M: privmsg handle-incoming-irc ( privmsg -- ) M: join handle-incoming-irc ( join -- ) irc-client> join-messages>> mailbox-put ; -M: irc-end handle-incoming-irc ( irc-end -- ) - irc-client> listeners>> values [ in-messages>> mailbox-put ] with each ; +M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- ) + broadcast-message-to-listeners ; ! ====================================== ! Client message handling @@ -249,26 +268,22 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) ! Listener join request handling ! ====================================== -: make-registered-listener ( name -- listener ) - +: set+run-listener ( name irc-listener -- ) [ [ listener-loop ] 2curry "listener" spawn-irc-loop ] - [ swap [ irc-client> listeners>> set-at ] curry keep ] + [ swap irc-client> listeners>> set-at ] 2bi ; -: make-join-future ( name -- future ) - [ [ swap trailing>> = ] curry ! compare name with channel name - irc-client> join-messages>> 60 seconds rot mailbox-get-timeout? - trailing>> make-registered-listener ] - curry future ; +GENERIC: (add-listener) ( irc-listener -- ) +M: irc-channel-listener (add-listener) ( irc-channel-listener -- ) + [ [ name>> ] [ password>> ] bi /JOIN ] + [ [ [ drop irc-client> join-messages>> ] + [ timeout>> ] + [ name>> [ swap trailing>> = ] curry ] + tri mailbox-get-timeout? trailing>> ] keep set+run-listener + ] bi ; -: make-user-future ( name -- future ) - [ make-registered-listener ] curry future ; - -: maybe-join ( name password -- ? ) - over "#" head? [ /JOIN t ] [ 2drop f ] if ; - -: make-listener-future ( name channel? -- future ) - [ make-join-future ] [ make-user-future ] if ; +M: irc-nick-listener (add-listener) ( irc-nick-listener -- ) + [ name>> ] keep set+run-listener ; PRIVATE> @@ -283,7 +298,6 @@ PRIVATE> spawn-irc ] with-variable ; -: listen-to ( irc-client name -- future ) - swap current-irc-client [ - dup f maybe-join make-listener-future - ] with-variable ; +GENERIC: add-listener ( irc-client irc-listener -- ) +M: irc-listener add-listener ( irc-client irc-listener -- ) + current-irc-client swap [ (add-listener) ] curry with-variable ; From 7126469eac652757dc8e51da6d64612f672cc739 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Sat, 7 Jun 2008 21:04:27 -0300 Subject: [PATCH 0101/1850] irc.client: remove unused concurrency.futures import --- extra/irc/client/client.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 6598a0f08b..3c45ad4d32 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Doug Coleman, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays combinators concurrency.mailboxes concurrency.futures io +USING: arrays combinators concurrency.mailboxes io io.encodings.8-bit io.sockets kernel namespaces sequences sequences.lib splitting threads calendar classes.tuple classes ascii assocs accessors destructors continuations ; From 6943230bf516516cf5e44105a3cf3d6bfe2dad72 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Sun, 8 Jun 2008 16:06:19 -0300 Subject: [PATCH 0102/1850] irc.client: better handling of disconnects --- extra/irc/client/client-tests.factor | 4 +- extra/irc/client/client.factor | 81 +++++++++++++++++----------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor index 968330ee3b..304ab25402 100644 --- a/extra/irc/client/client-tests.factor +++ b/extra/irc/client/client-tests.factor @@ -41,9 +41,9 @@ privmsg new parse-irc-line f >>timestamp ] unit-test { "" } make-client dup "factorbot" set-nick current-irc-client [ - { t } [ irc-client> nick>> name>> me? ] unit-test + { t } [ irc> nick>> name>> me? ] unit-test - { "factorbot" } [ irc-client> nick>> name>> ] unit-test + { "factorbot" } [ irc> nick>> name>> ] unit-test { "someuser" } [ "someuser!n=user@some.where" parse-name ] unit-test diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 3c45ad4d32..4a646e9fd8 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -26,11 +26,11 @@ TUPLE: nick name channels log ; C: nick TUPLE: irc-client profile nick stream in-messages out-messages join-messages - listeners is-running connect ; + listeners is-running connect reconnect-time ; : ( profile -- irc-client ) f V{ } clone V{ } clone f H{ } clone f - [ latin1 ] irc-client boa ; + [ latin1 ] 15 seconds irc-client boa ; TUPLE: irc-listener in-messages out-messages ; TUPLE: irc-server-listener < irc-listener ; @@ -53,10 +53,10 @@ UNION: irc-named-listener irc-nick-listener irc-channel-listener ; ! Message objects ! ====================================== -SINGLETON: irc-end ! Message sent when the client isn't running anymore -SINGLETON: irc-lost ! Message sent when connection was lost -SINGLETON: irc-restore ! Message sent when connection was restored -UNION: irc-broadcasted-message irc-end irc-lost irc-restore ; +SINGLETON: irc-end ! sent when the client isn't running anymore +SINGLETON: irc-disconnected ! sent when connection is lost +SINGLETON: irc-connected ! sent when connection is instantiated +UNION: irc-broadcasted-message irc-end irc-disconnected irc-connected ; TUPLE: irc-message line prefix command parameters trailing timestamp ; TUPLE: logged-in < irc-message name ; @@ -72,14 +72,20 @@ TUPLE: notice < irc-message type ; TUPLE: mode < irc-message name channel mode ; TUPLE: unhandled < irc-message ; +: terminate-irc ( irc-client -- ) + [ stream>> dispose ] + [ in-messages>> irc-end swap mailbox-put ] + [ f >>is-running drop ] + tri ; + ( -- irc-client ) current-irc-client get ; -: irc-stream> ( -- stream ) irc-client> stream>> ; +: irc> ( -- irc-client ) current-irc-client get ; +: irc-stream> ( -- stream ) irc> stream>> ; : irc-write ( s -- ) irc-stream> stream-write ; : irc-print ( s -- ) irc-stream> [ stream-print ] keep stream-flush ; @@ -96,7 +102,7 @@ TUPLE: unhandled < irc-message ; " hostname servername :irc.factor" irc-print ; : /CONNECT ( server port -- stream ) - irc-client> connect>> call drop ; + irc> connect>> call drop ; : /JOIN ( channel password -- ) "JOIN " irc-write @@ -174,13 +180,13 @@ TUPLE: unhandled < irc-message ; ! ====================================== : me? ( string -- ? ) - irc-client> nick>> name>> = ; + irc> nick>> name>> = ; : irc-message-origin ( irc-message -- name ) dup name>> me? [ prefix>> parse-name ] [ name>> ] if ; : broadcast-message-to-listeners ( message -- ) - irc-client> listeners>> values [ in-messages>> mailbox-put ] with each ; + irc> listeners>> values [ in-messages>> mailbox-put ] with each ; GENERIC: handle-incoming-irc ( irc-message -- ) @@ -188,7 +194,7 @@ M: irc-message handle-incoming-irc ( irc-message -- ) drop ; M: logged-in handle-incoming-irc ( logged-in -- ) - name>> irc-client> nick>> (>>name) ; + name>> irc> nick>> (>>name) ; M: ping handle-incoming-irc ( ping -- ) trailing>> /PONG ; @@ -197,11 +203,11 @@ M: nick-in-use handle-incoming-irc ( nick-in-use -- ) name>> "_" append /NICK ; M: privmsg handle-incoming-irc ( privmsg -- ) - dup irc-message-origin irc-client> listeners>> at + dup irc-message-origin irc> listeners>> at [ in-messages>> mailbox-put ] [ drop ] if* ; M: join handle-incoming-irc ( join -- ) - irc-client> join-messages>> mailbox-put ; + irc> join-messages>> mailbox-put ; M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- ) broadcast-message-to-listeners ; @@ -226,37 +232,47 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) dup stream-readln [ nip ] [ dispose f ] if* ; : handle-reader-message ( irc-message -- ) - irc-client> in-messages>> mailbox-put ; + irc> in-messages>> mailbox-put ; -: handle-stream-close ( -- ) - irc-client> f >>is-running in-messages>> irc-end swap mailbox-put ; +DEFER: (connect-irc) +: handle-disconnect ( error -- ) + drop irc> + [ in-messages>> irc-disconnected swap mailbox-put ] + [ reconnect-time>> sleep (connect-irc) ] + [ profile>> nickname>> /LOGIN ] + tri ; + +: (reader-loop) ( -- ) + irc> stream>> [ + |dispose stream-readln [ + parse-irc-line handle-reader-message + ] [ + irc> terminate-irc + ] if* + ] with-destructors ; : reader-loop ( -- ) - irc-client> stream>> stream-readln-or-close [ - parse-irc-line handle-reader-message - ] [ - handle-stream-close - ] if* ; + [ (reader-loop) ] [ handle-disconnect ] recover ; : writer-loop ( -- ) - irc-client> out-messages>> [ handle-outgoing-irc ] irc-mailbox-get ; + irc> out-messages>> [ handle-outgoing-irc ] irc-mailbox-get ; ! ====================================== ! Processing loops ! ====================================== : in-multiplexer-loop ( -- ) - irc-client> in-messages>> [ handle-incoming-irc ] irc-mailbox-get ; + irc> in-messages>> [ handle-incoming-irc ] irc-mailbox-get ; : maybe-annotate-with-name ( name obj -- obj ) dup privmsg instance? [ swap >>name ] [ nip ] if ; : listener-loop ( name listener -- ) out-messages>> mailbox-get maybe-annotate-with-name - irc-client> out-messages>> mailbox-put ; + irc> out-messages>> mailbox-put ; : spawn-irc-loop ( quot name -- ) - [ [ irc-client> is-running>> ] compose ] dip + [ [ irc> is-running>> ] compose ] dip spawn-server drop ; : spawn-irc ( -- ) @@ -270,13 +286,13 @@ M: privmsg handle-outgoing-irc ( privmsg -- ) : set+run-listener ( name irc-listener -- ) [ [ listener-loop ] 2curry "listener" spawn-irc-loop ] - [ swap irc-client> listeners>> set-at ] + [ swap irc> listeners>> set-at ] 2bi ; GENERIC: (add-listener) ( irc-listener -- ) M: irc-channel-listener (add-listener) ( irc-channel-listener -- ) [ [ name>> ] [ password>> ] bi /JOIN ] - [ [ [ drop irc-client> join-messages>> ] + [ [ [ drop irc> join-messages>> ] [ timeout>> ] [ name>> [ swap trailing>> = ] curry ] tri mailbox-get-timeout? trailing>> ] keep set+run-listener @@ -285,12 +301,13 @@ M: irc-channel-listener (add-listener) ( irc-channel-listener -- ) M: irc-nick-listener (add-listener) ( irc-nick-listener -- ) [ name>> ] keep set+run-listener ; -PRIVATE> - : (connect-irc) ( irc-client -- ) [ profile>> [ server>> ] keep port>> /CONNECT ] keep - swap >>stream - t >>is-running drop ; + swap >>stream + t >>is-running + in-messages>> irc-connected swap mailbox-put ; + +PRIVATE> : connect-irc ( irc-client -- ) dup current-irc-client [ From 3733624dcf0363bd3453da4152e5edc42ee2b654 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 8 Jun 2008 15:30:58 -0500 Subject: [PATCH 0103/1850] Virtual sequence concatenation --- extra/cords/authors.txt | 1 + extra/cords/cords-tests.factor | 5 +++ extra/cords/cords.factor | 70 ++++++++++++++++++++++++++++++++++ extra/cords/summary.txt | 1 + extra/cords/tags.txt | 1 + 5 files changed, 78 insertions(+) create mode 100644 extra/cords/authors.txt create mode 100644 extra/cords/cords-tests.factor create mode 100644 extra/cords/cords.factor create mode 100644 extra/cords/summary.txt create mode 100644 extra/cords/tags.txt diff --git a/extra/cords/authors.txt b/extra/cords/authors.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/extra/cords/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/extra/cords/cords-tests.factor b/extra/cords/cords-tests.factor new file mode 100644 index 0000000000..0058c8f07a --- /dev/null +++ b/extra/cords/cords-tests.factor @@ -0,0 +1,5 @@ +IN: cords.tests +USING: cords strings tools.test kernel sequences ; + +[ "hello world" ] [ "hello" " world" cord-append dup like ] unit-test +[ "hello world" ] [ { "he" "llo" " world" } cord-concat dup like ] unit-test diff --git a/extra/cords/cords.factor b/extra/cords/cords.factor new file mode 100644 index 0000000000..f5cc89f8d5 --- /dev/null +++ b/extra/cords/cords.factor @@ -0,0 +1,70 @@ +! Copysecond (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs sequences sorting math math.order +arrays combinators kernel ; +IN: cords + +> length ] [ second>> length ] bi + ; + +M: simple-cord virtual-seq first>> ; + +M: simple-cord virtual@ + 2dup first>> length < + [ first>> ] [ [ first>> length - ] [ second>> ] bi ] if ; + +TUPLE: multi-cord count seqs ; + +M: multi-cord length count>> ; + +M: multi-cord virtual@ + dupd + seqs>> [ first <=> ] binsearch* + [ first - ] [ second ] bi ; + +M: multi-cord virtual-seq + seqs>> dup empty? [ drop f ] [ first second ] if ; + +: ( seqs -- cord ) + dup length 2 = [ + first2 simple-cord boa + ] [ + [ 0 [ length + ] accumulate ] keep zip multi-cord boa + ] if ; + +PRIVATE> + +UNION: cord simple-cord multi-cord ; + +INSTANCE: cord virtual-sequence + +INSTANCE: multi-cord virtual-sequence + +: cord-append ( seq1 seq2 -- cord ) + { + { [ over empty? ] [ nip ] } + { [ dup empty? ] [ drop ] } + { [ 2dup [ cord? ] both? ] [ [ seqs>> values ] bi@ append ] } + { [ over cord? ] [ [ seqs>> values ] dip suffix ] } + { [ dup cord? ] [ seqs>> values swap prefix ] } + [ 2array ] + } cond ; + +: cord-concat ( seqs -- cord ) + { + { [ dup empty? ] [ drop f ] } + { [ dup length 1 = ] [ first ] } + [ + [ + { + { [ dup cord? ] [ seqs>> values ] } + { [ dup empty? ] [ drop { } ] } + [ 1array ] + } cond + ] map concat + ] + } cond ; diff --git a/extra/cords/summary.txt b/extra/cords/summary.txt new file mode 100644 index 0000000000..3c69862b71 --- /dev/null +++ b/extra/cords/summary.txt @@ -0,0 +1 @@ +Virtual sequence concatenation diff --git a/extra/cords/tags.txt b/extra/cords/tags.txt new file mode 100644 index 0000000000..42d711b32b --- /dev/null +++ b/extra/cords/tags.txt @@ -0,0 +1 @@ +collections From 9dd5c9919fb44ecd39724128e693e588db6660ba Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 8 Jun 2008 15:32:55 -0500 Subject: [PATCH 0104/1850] Mandatory stack effect annotations --- core/alien/c-types/c-types.factor | 8 +- core/alien/compiler/compiler.factor | 3 +- .../remote-control/remote-control.factor | 6 +- core/bootstrap/compiler/compiler.factor | 3 +- core/bootstrap/image/image.factor | 19 +-- core/bootstrap/syntax.factor | 1 + core/classes/algebra/algebra-tests.factor | 21 ++-- core/classes/classes-tests.factor | 4 +- core/classes/classes.factor | 2 +- core/classes/tuple/tuple-tests.factor | 18 +-- core/command-line/command-line.factor | 2 +- core/compiler/constants/constants.factor | 28 +++-- core/compiler/errors/errors.factor | 6 +- core/compiler/tests/intrinsics.factor | 8 +- core/compiler/tests/simple.factor | 44 +++---- core/compiler/tests/stack-trace.factor | 12 +- core/compiler/tests/templates.factor | 12 +- core/continuations/continuations.factor | 2 +- core/cpu/architecture/architecture.factor | 6 +- core/cpu/ppc/bootstrap.factor | 4 +- core/cpu/x86/32/32.factor | 16 +-- core/cpu/x86/allot/allot.factor | 2 +- core/cpu/x86/architecture/architecture.factor | 24 ++-- core/cpu/x86/assembler/assembler.factor | 118 +++++++++--------- core/cpu/x86/bootstrap.factor | 6 +- core/cpu/x86/intrinsics/intrinsics.factor | 14 +-- core/debugger/debugger.factor | 22 ++-- core/effects/effects.factor | 27 ++-- core/generator/generator.factor | 4 +- core/generator/registers/registers.factor | 8 +- core/generic/generic-tests.factor | 4 +- core/generic/standard/engines/tag/tag.factor | 2 +- .../standard/engines/tuple/tuple.factor | 4 +- core/generic/standard/standard-tests.factor | 20 +-- core/inference/backend/backend-docs.factor | 8 +- core/inference/backend/backend.factor | 56 ++++++--- core/inference/class/class-tests.factor | 2 +- core/inference/class/class.factor | 10 +- core/inference/dataflow/dataflow.factor | 10 +- core/inference/errors/errors.factor | 14 +-- core/inference/inference-docs.factor | 4 +- core/inference/inference-tests.factor | 75 +++++------ core/inference/inference.factor | 4 +- core/inference/known-words/known-words.factor | 2 +- core/inference/state/state.factor | 12 +- .../transforms/transforms-tests.factor | 27 ++-- core/io/files/files-tests.factor | 2 + core/io/files/files.factor | 3 +- core/io/streams/string/string.factor | 3 +- core/math/bitfields/bitfields-tests.factor | 2 +- core/math/integers/integers-tests.factor | 4 +- core/math/intervals/intervals-tests.factor | 8 +- core/math/intervals/intervals.factor | 7 +- core/math/parser/parser.factor | 2 +- core/optimizer/control/control.factor | 5 +- core/parser/parser-docs.factor | 6 +- core/parser/parser.factor | 18 +-- core/prettyprint/backend/backend.factor | 25 ++-- core/prettyprint/prettyprint.factor | 53 ++++---- core/prettyprint/sections/sections.factor | 6 +- core/slots/slots.factor | 16 +-- core/syntax/syntax-docs.factor | 8 +- core/syntax/syntax.factor | 6 +- core/threads/threads.factor | 4 +- core/vocabs/loader/loader.factor | 8 +- core/words/words-docs.factor | 2 +- core/words/words.factor | 5 +- extra/bootstrap/help/help.factor | 2 +- extra/calendar/calendar.factor | 7 +- extra/cocoa/messages/messages.factor | 5 +- extra/concurrency/mailboxes/mailboxes.factor | 3 +- extra/concurrency/messaging/messaging.factor | 2 +- .../core-foundation/fsevents/fsevents.factor | 3 +- extra/documents/documents.factor | 8 +- extra/editors/editors.factor | 9 +- extra/fry/fry.factor | 6 +- extra/help/help.factor | 26 ++-- extra/help/markup/markup.factor | 31 +++-- extra/html/elements/elements.factor | 18 ++- extra/io/encodings/8-bit/8-bit.factor | 2 +- extra/io/pipes/pipes.factor | 7 +- extra/io/sockets/sockets.factor | 2 +- extra/io/unix/launcher/launcher.factor | 3 +- extra/io/unix/select/select.factor | 4 +- extra/locals/locals.factor | 8 +- extra/macros/macros.factor | 4 +- extra/match/match.factor | 4 +- extra/math/functions/functions-tests.factor | 2 +- extra/memoize/memoize.factor | 2 +- extra/models/models.factor | 2 +- extra/opengl/opengl.factor | 25 ++-- extra/openssl/openssl.factor | 4 +- extra/optimizer/debugger/debugger.factor | 35 +++--- extra/qualified/qualified.factor | 2 +- extra/sequences/lib/lib.factor | 6 +- extra/tools/deploy/backend/backend.factor | 16 ++- extra/tools/deploy/config/config.factor | 14 +-- extra/tools/disassembler/disassembler.factor | 4 +- extra/tools/walker/walker.factor | 8 +- extra/ui/clipboards/clipboards.factor | 6 +- extra/ui/commands/commands-docs.factor | 25 ++-- extra/ui/gadgets/buttons/buttons.factor | 24 ++-- extra/ui/gadgets/editors/editors.factor | 78 +++++++----- extra/ui/gadgets/frames/frames.factor | 2 +- extra/ui/gadgets/gadgets.factor | 8 +- extra/ui/gadgets/grids/grids.factor | 2 +- extra/ui/gadgets/labelled/labelled.factor | 2 +- extra/ui/gadgets/panes/panes.factor | 30 +++-- extra/ui/gadgets/paragraphs/paragraphs.factor | 2 +- extra/ui/gadgets/scrollers/scrollers.factor | 12 +- extra/ui/gadgets/sliders/sliders.factor | 26 ++-- extra/ui/gadgets/theme/theme.factor | 13 +- extra/ui/gadgets/viewports/viewports.factor | 3 +- extra/ui/gadgets/worlds/worlds.factor | 2 +- extra/ui/render/render.factor | 2 +- extra/ui/tools/browser/browser.factor | 31 +++-- extra/ui/tools/debugger/debugger.factor | 2 +- extra/ui/tools/deploy/deploy.factor | 19 +-- extra/ui/tools/inspector/inspector.factor | 2 +- extra/ui/tools/listener/listener.factor | 2 +- extra/ui/tools/operations/operations.factor | 22 ++-- extra/ui/tools/profiler/profiler.factor | 2 +- extra/ui/tools/search/search.factor | 6 +- extra/ui/tools/tools.factor | 8 +- extra/ui/tools/walker/walker.factor | 2 +- extra/ui/tools/workspace/workspace.factor | 3 +- extra/unix/stat/macosx/macosx.factor | 6 +- extra/values/values.factor | 5 +- 128 files changed, 793 insertions(+), 725 deletions(-) diff --git a/core/alien/c-types/c-types.factor b/core/alien/c-types/c-types.factor index 44c0112c77..87fa553dc3 100755 --- a/core/alien/c-types/c-types.factor +++ b/core/alien/c-types/c-types.factor @@ -5,7 +5,7 @@ assocs kernel kernel.private libc math namespaces parser sequences strings words assocs splitting math.parser cpu.architecture alien alien.accessors quotations layouts system compiler.units io.files io.encodings.binary -accessors combinators ; +accessors combinators effects ; IN: alien.c-types DEFER: @@ -214,7 +214,8 @@ M: long-long-type box-return ( type -- ) >r ">c-" swap "-array" 3append r> create ; : define-to-array ( type vocab -- ) - [ to-array-word ] 2keep >c-array-quot define ; + [ to-array-word ] 2keep >c-array-quot + (( array -- byte-array )) define-declared ; : c-array>quot ( type vocab -- quot ) [ @@ -227,7 +228,8 @@ M: long-long-type box-return ( type -- ) >r "c-" swap "-array>" 3append r> create ; : define-from-array ( type vocab -- ) - [ from-array-word ] 2keep c-array>quot define ; + [ from-array-word ] 2keep c-array>quot + (( c-ptr n -- array )) define-declared ; : define-primitive-type ( type name -- ) "alien.c-types" diff --git a/core/alien/compiler/compiler.factor b/core/alien/compiler/compiler.factor index 67665b4d7e..ac1895e37e 100755 --- a/core/alien/compiler/compiler.factor +++ b/core/alien/compiler/compiler.factor @@ -216,7 +216,8 @@ M: alien-invoke-error summary drop "Words calling ``alien-invoke'' must be compiled with the optimizing compiler." ; -: pop-parameters pop-literal nip [ expand-constants ] map ; +: pop-parameters ( -- seq ) + pop-literal nip [ expand-constants ] map ; : stdcall-mangle ( symbol node -- symbol ) "@" diff --git a/core/alien/remote-control/remote-control.factor b/core/alien/remote-control/remote-control.factor index 1d713f6edd..027663a645 100755 --- a/core/alien/remote-control/remote-control.factor +++ b/core/alien/remote-control/remote-control.factor @@ -4,14 +4,14 @@ USING: alien alien.c-types alien.strings parser threads words kernel.private kernel io.encodings.utf8 ; IN: alien.remote-control -: eval-callback +: eval-callback ( -- callback ) "void*" { "char*" } "cdecl" [ eval>string utf8 malloc-string ] alien-callback ; -: yield-callback +: yield-callback ( -- callback ) "void" { } "cdecl" [ yield ] alien-callback ; -: sleep-callback +: sleep-callback ( -- callback ) "void" { "long" } "cdecl" [ sleep ] alien-callback ; : ?callback ( word -- alien ) diff --git a/core/bootstrap/compiler/compiler.factor b/core/bootstrap/compiler/compiler.factor index 7ad1c6978b..4753d9b1b4 100755 --- a/core/bootstrap/compiler/compiler.factor +++ b/core/bootstrap/compiler/compiler.factor @@ -18,7 +18,8 @@ IN: bootstrap.compiler enable-compiler -: compile-uncompiled [ compiled? not ] filter compile ; +: compile-uncompiled ( words -- ) + [ compiled? not ] filter compile ; nl "Compiling..." write flush diff --git a/core/bootstrap/image/image.factor b/core/bootstrap/image/image.factor index aa7377adbf..183c7d1888 100755 --- a/core/bootstrap/image/image.factor +++ b/core/bootstrap/image/image.factor @@ -85,13 +85,6 @@ SYMBOL: objects : 1-offset 8 ; inline : -1-offset 9 ; inline -: array-start 2 bootstrap-cells object tag-number - ; -: scan@ array-start bootstrap-cell - ; -: wrapper@ bootstrap-cell object tag-number - ; -: word-xt@ 8 bootstrap-cells object tag-number - ; -: quot-array@ bootstrap-cell object tag-number - ; -: quot-xt@ 3 bootstrap-cells object tag-number - ; - : jit-define ( quot rc rt offset name -- ) >r { [ { } make ] [ ] [ ] [ ] } spread 4array r> set ; @@ -203,9 +196,9 @@ GENERIC: ' ( obj -- ptr ) ! Bignums -: bignum-bits bootstrap-cell-bits 2 - ; +: bignum-bits ( -- n ) bootstrap-cell-bits 2 - ; -: bignum-radix bignum-bits 2^ 1- ; +: bignum-radix ( -- n ) bignum-bits 2^ 1- ; : bignum>seq ( n -- seq ) #! n is positive or zero. @@ -248,15 +241,15 @@ M: float ' ! Padded with fixnums for 8-byte alignment -: t, t t-offset fixup ; +: t, ( -- ) t t-offset fixup ; M: f ' #! f is #define F RETAG(0,F_TYPE) drop \ f tag-number ; -: 0, 0 >bignum ' 0-offset fixup ; -: 1, 1 >bignum ' 1-offset fixup ; -: -1, -1 >bignum ' -1-offset fixup ; +: 0, ( -- ) 0 >bignum ' 0-offset fixup ; +: 1, ( -- ) 1 >bignum ' 1-offset fixup ; +: -1, ( -- ) -1 >bignum ' -1-offset fixup ; ! Words diff --git a/core/bootstrap/syntax.factor b/core/bootstrap/syntax.factor index d995cc3176..f3d7707878 100755 --- a/core/bootstrap/syntax.factor +++ b/core/bootstrap/syntax.factor @@ -10,6 +10,7 @@ IN: bootstrap.syntax "\"" "#!" "(" + "((" ":" ";" "r class-and r> class= ; +: class-and* ( cls1 cls2 cls3 -- ? ) >r class-and r> class= ; -: class-or* >r class-or r> class= ; +: class-or* ( cls1 cls2 cls3 -- ? ) >r class-or r> class= ; [ t ] [ object object object class-and* ] unit-test [ t ] [ fixnum object fixnum class-and* ] unit-test @@ -193,9 +193,9 @@ UNION: z1 b1 c1 ; [ f ] [ null { number fixnum null } min-class ] unit-test ! Test for hangs? -: random-class classes random ; +: random-class ( -- class ) classes random ; -: random-op +: random-op ( -- word ) { class-and class-or @@ -211,13 +211,13 @@ UNION: z1 b1 c1 ; ] unit-test ] times -: random-boolean +: random-boolean ( -- ? ) { t f } random ; -: boolean>class +: boolean>class ( ? -- class ) object null ? ; -: random-boolean-op +: random-boolean-op ( -- word ) { and or @@ -225,9 +225,10 @@ UNION: z1 b1 c1 ; xor } random ; -: class-xor [ class-or ] 2keep class-and class-not class-and ; +: class-xor ( cls1 cls2 -- cls3 ) + [ class-or ] 2keep class-and class-not class-and ; -: boolean-op>class-op +: boolean-op>class-op ( word -- word' ) { { and class-and } { or class-or } diff --git a/core/classes/classes-tests.factor b/core/classes/classes-tests.factor index eb55b5fccd..a03fed7fcb 100755 --- a/core/classes/classes-tests.factor +++ b/core/classes/classes-tests.factor @@ -79,7 +79,7 @@ INSTANCE: integer mx1 [ \ mx1 forget ] with-compilation-unit ! Empty unions were causing problems -GENERIC: empty-union-test +GENERIC: empty-union-test ( obj -- obj ) UNION: empty-union-1 ; @@ -162,7 +162,7 @@ TUPLE: flat-mx-2-1 ; INSTANCE: flat-mx-2-1 flat-mx-2 [ t ] [ "hi" \ hi-tag instance? ] unit-test ! Regression -GENERIC: method-forget-test +GENERIC: method-forget-test ( obj -- obj ) TUPLE: method-forget-class ; M: method-forget-class method-forget-test ; diff --git a/core/classes/classes.factor b/core/classes/classes.factor index 2c9e1d4787..91fc4c60a7 100755 --- a/core/classes/classes.factor +++ b/core/classes/classes.factor @@ -38,7 +38,7 @@ PREDICATE: tuple-class < class : predicate-word ( word -- predicate ) [ word-name "?" append ] keep word-vocabulary create ; -: predicate-effect 1 { "?" } ; +: predicate-effect T{ effect f 1 { "?" } } ; PREDICATE: predicate < word "predicating" word-prop >boolean ; diff --git a/core/classes/tuple/tuple-tests.factor b/core/classes/tuple/tuple-tests.factor index ab6c139f7b..dc99734ce5 100755 --- a/core/classes/tuple/tuple-tests.factor +++ b/core/classes/tuple/tuple-tests.factor @@ -8,7 +8,7 @@ columns math.order classes.private ; IN: classes.tuple.tests TUPLE: rect x y w h ; -: rect boa ; +: ( x y w h -- rect ) rect boa ; : move ( x rect -- rect ) [ + ] change-x ; @@ -69,7 +69,7 @@ C: predicate-test PREDICATE: silly-pred < tuple class \ rect = ; -GENERIC: area +GENERIC: area ( obj -- n ) M: silly-pred area dup w>> swap h>> * ; TUPLE: circle radius ; @@ -164,7 +164,7 @@ C: t4 [ 1 ] [ 1 m2 ] unit-test ! another combination issue -GENERIC: silly +GENERIC: silly ( obj -- obj obj ) UNION: my-union slice repetition column array vector reversed ; @@ -208,8 +208,8 @@ C: erg's-reshape-problem ! We want to make sure constructors are recompiled when ! tuples are reshaped -: cons-test-1 \ erg's-reshape-problem new ; -: cons-test-2 \ erg's-reshape-problem boa ; +: cons-test-1 ( -- tuple ) \ erg's-reshape-problem new ; +: cons-test-2 ( a b c d -- tuple ) \ erg's-reshape-problem boa ; "IN: classes.tuple.tests TUPLE: erg's-reshape-problem a b c d e f ;" eval @@ -242,7 +242,7 @@ C: laptop [ t ] [ "laptop" get computer? ] unit-test [ t ] [ "laptop" get tuple? ] unit-test -: test-laptop-slot-values +: test-laptop-slot-values ( -- ) [ laptop ] [ "laptop" get class ] unit-test [ "Pentium" ] [ "laptop" get cpu>> ] unit-test [ 128 ] [ "laptop" get ram>> ] unit-test @@ -275,7 +275,7 @@ C: server [ t ] [ "server" get computer? ] unit-test [ t ] [ "server" get tuple? ] unit-test -: test-server-slot-values +: test-server-slot-values ( -- ) [ server ] [ "server" get class ] unit-test [ "PowerPC" ] [ "server" get cpu>> ] unit-test [ 64 ] [ "server" get ram>> ] unit-test @@ -375,7 +375,7 @@ C: test2 "a" "b" "test" set -: test-a/b +: test-a/b ( -- ) [ "a" ] [ "test" get a>> ] unit-test [ "b" ] [ "test" get b>> ] unit-test ; @@ -403,7 +403,7 @@ TUPLE: move-up-2 < move-up-1 c ; T{ move-up-2 f "a" "b" "c" } "move-up" set -: test-move-up +: test-move-up ( -- ) [ "a" ] [ "move-up" get a>> ] unit-test [ "b" ] [ "move-up" get b>> ] unit-test [ "c" ] [ "move-up" get c>> ] unit-test ; diff --git a/core/command-line/command-line.factor b/core/command-line/command-line.factor index 84020abca0..fb4fd374a7 100644 --- a/core/command-line/command-line.factor +++ b/core/command-line/command-line.factor @@ -36,7 +36,7 @@ SYMBOL: main-vocab-hook main-vocab-hook get [ call ] [ "listener" ] if* ] if ; -: default-cli-args +: default-cli-args ( -- ) global [ "quiet" off "script" off diff --git a/core/compiler/constants/constants.factor b/core/compiler/constants/constants.factor index 8610f490ec..622c63d7f0 100755 --- a/core/compiler/constants/constants.factor +++ b/core/compiler/constants/constants.factor @@ -6,18 +6,20 @@ IN: compiler.constants ! These constants must match vm/memory.h : card-bits 8 ; : deck-bits 18 ; -: card-mark HEX: 40 HEX: 80 bitor ; +: card-mark ( -- n ) HEX: 40 HEX: 80 bitor ; ! These constants must match vm/layouts.h -: header-offset object tag-number neg ; -: float-offset 8 float tag-number - ; -: string-offset 4 bootstrap-cells object tag-number - ; -: profile-count-offset 7 bootstrap-cells object tag-number - ; -: byte-array-offset 2 bootstrap-cells object tag-number - ; -: alien-offset 3 bootstrap-cells object tag-number - ; -: underlying-alien-offset bootstrap-cell object tag-number - ; -: tuple-class-offset bootstrap-cell tuple tag-number - ; -: class-hash-offset bootstrap-cell object tag-number - ; -: word-xt-offset 8 bootstrap-cells object tag-number - ; -: word-code-offset 9 bootstrap-cells object tag-number - ; -: compiled-header-size 4 bootstrap-cells ; +: header-offset ( -- n ) object tag-number neg ; +: float-offset ( -- n ) 8 float tag-number - ; +: string-offset ( -- n ) 4 bootstrap-cells object tag-number - ; +: profile-count-offset ( -- n ) 7 bootstrap-cells object tag-number - ; +: byte-array-offset ( -- n ) 2 bootstrap-cells object tag-number - ; +: alien-offset ( -- n ) 3 bootstrap-cells object tag-number - ; +: underlying-alien-offset ( -- n ) bootstrap-cell object tag-number - ; +: tuple-class-offset ( -- n ) bootstrap-cell tuple tag-number - ; +: class-hash-offset ( -- n ) bootstrap-cell object tag-number - ; +: word-xt-offset ( -- n ) 8 bootstrap-cells object tag-number - ; +: quot-xt-offset ( -- n ) 3 bootstrap-cells object tag-number - ; +: word-code-offset ( -- n ) 9 bootstrap-cells object tag-number - ; +: array-start-offset ( -- n ) 2 bootstrap-cells object tag-number - ; +: compiled-header-size ( -- n ) 4 bootstrap-cells ; diff --git a/core/compiler/errors/errors.factor b/core/compiler/errors/errors.factor index e7dc5156e4..2bea6ad974 100755 --- a/core/compiler/errors/errors.factor +++ b/core/compiler/errors/errors.factor @@ -59,11 +59,11 @@ PRIVATE> [ set-at ] [ delete-at drop ] if ] [ 2drop ] if ; -: :errors +error+ compiler-errors. ; +: :errors ( -- ) +error+ compiler-errors. ; -: :warnings +warning+ compiler-errors. ; +: :warnings ( -- ) +warning+ compiler-errors. ; -: :linkage +linkage+ compiler-errors. ; +: :linkage ( -- ) +linkage+ compiler-errors. ; : with-compiler-errors ( quot -- ) with-compiler-errors? get "quiet" get or [ call ] [ diff --git a/core/compiler/tests/intrinsics.factor b/core/compiler/tests/intrinsics.factor index 6fb6afe0c6..0e5c96eca0 100755 --- a/core/compiler/tests/intrinsics.factor +++ b/core/compiler/tests/intrinsics.factor @@ -252,7 +252,7 @@ cell 8 = [ ! Some randomized tests : compiled-fixnum* fixnum* ; -: test-fixnum* +: test-fixnum* ( -- ) 32 random-bits >fixnum 32 random-bits >fixnum 2dup [ fixnum* ] 2keep compiled-fixnum* = @@ -262,7 +262,7 @@ cell 8 = [ : compiled-fixnum>bignum fixnum>bignum ; -: test-fixnum>bignum +: test-fixnum>bignum ( -- ) 32 random-bits >fixnum dup [ fixnum>bignum ] keep compiled-fixnum>bignum = [ drop ] [ "Oops" throw ] if ; @@ -271,7 +271,7 @@ cell 8 = [ : compiled-bignum>fixnum bignum>fixnum ; -: test-bignum>fixnum +: test-bignum>fixnum ( -- ) 5 random [ drop 32 random-bits ] map product >bignum dup [ bignum>fixnum ] keep compiled-bignum>fixnum = [ drop ] [ "Oops" throw ] if ; @@ -377,7 +377,7 @@ cell 8 = [ [ 252 ] [ B{ 1 2 3 -4 5 } 3 [ { byte-array fixnum } declare alien-unsigned-1 ] compile-call ] unit-test [ -4 ] [ B{ 1 2 3 -4 5 } 3 [ { byte-array fixnum } declare alien-signed-1 ] compile-call ] unit-test -: xword-def word-def [ { fixnum } declare ] prepend ; +: xword-def ( word -- def ) word-def [ { fixnum } declare ] prepend ; [ -100 ] [ -100 [ { byte-array } declare *char ] compile-call ] unit-test [ 156 ] [ -100 [ { byte-array } declare *uchar ] compile-call ] unit-test diff --git a/core/compiler/tests/simple.factor b/core/compiler/tests/simple.factor index bc9c56864c..49f11c0d11 100755 --- a/core/compiler/tests/simple.factor +++ b/core/compiler/tests/simple.factor @@ -69,31 +69,31 @@ IN: compiler.tests ! Regression -: empty ; +: empty ( -- ) ; [ "b" ] [ 1 [ empty { [ "a" ] [ "b" ] } dispatch ] compile-call ] unit-test -: dummy-if-1 t [ ] [ ] if ; +: dummy-if-1 ( -- ) t [ ] [ ] if ; [ ] [ dummy-if-1 ] unit-test -: dummy-if-2 f [ ] [ ] if ; +: dummy-if-2 ( -- ) f [ ] [ ] if ; [ ] [ dummy-if-2 ] unit-test -: dummy-if-3 t [ 1 ] [ 2 ] if ; +: dummy-if-3 ( -- ) t [ 1 ] [ 2 ] if ; [ 1 ] [ dummy-if-3 ] unit-test -: dummy-if-4 f [ 1 ] [ 2 ] if ; +: dummy-if-4 ( -- ) f [ 1 ] [ 2 ] if ; [ 2 ] [ dummy-if-4 ] unit-test -: dummy-if-5 0 dup 1 fixnum<= [ drop 1 ] [ ] if ; +: dummy-if-5 ( -- n ) 0 dup 1 fixnum<= [ drop 1 ] [ ] if ; [ 1 ] [ dummy-if-5 ] unit-test -: dummy-if-6 +: dummy-if-6 ( n -- n ) dup 1 fixnum<= [ drop 1 ] [ @@ -102,7 +102,7 @@ IN: compiler.tests [ 17 ] [ 10 dummy-if-6 ] unit-test -: dead-code-rec +: dead-code-rec ( -- obj ) t [ 3.2 ] [ @@ -111,11 +111,11 @@ IN: compiler.tests [ 3.2 ] [ dead-code-rec ] unit-test -: one-rec [ f one-rec ] [ "hi" ] if ; +: one-rec ( ? -- obj ) [ f one-rec ] [ "hi" ] if ; [ "hi" ] [ t one-rec ] unit-test -: after-if-test +: after-if-test ( -- n ) t [ ] [ ] if 5 ; [ 5 ] [ after-if-test ] unit-test @@ -127,37 +127,37 @@ DEFER: countdown-b [ ] [ 10 countdown-b ] unit-test -: dummy-when-1 t [ ] when ; +: dummy-when-1 ( -- ) t [ ] when ; [ ] [ dummy-when-1 ] unit-test -: dummy-when-2 f [ ] when ; +: dummy-when-2 ( -- ) f [ ] when ; [ ] [ dummy-when-2 ] unit-test -: dummy-when-3 dup [ dup fixnum* ] when ; +: dummy-when-3 ( a -- b ) dup [ dup fixnum* ] when ; [ 16 ] [ 4 dummy-when-3 ] unit-test [ f ] [ f dummy-when-3 ] unit-test -: dummy-when-4 dup [ dup dup fixnum* fixnum* ] when swap ; +: dummy-when-4 ( a -- b c ) dup [ dup dup fixnum* fixnum* ] when swap ; [ 64 f ] [ f 4 dummy-when-4 ] unit-test [ f t ] [ t f dummy-when-4 ] unit-test -: dummy-when-5 f [ dup fixnum* ] when ; +: dummy-when-5 ( -- ) f [ dup fixnum* ] when ; [ f ] [ f dummy-when-5 ] unit-test -: dummy-unless-1 t [ ] unless ; +: dummy-unless-1 ( -- ) t [ ] unless ; [ ] [ dummy-unless-1 ] unit-test -: dummy-unless-2 f [ ] unless ; +: dummy-unless-2 ( -- ) f [ ] unless ; [ ] [ dummy-unless-2 ] unit-test -: dummy-unless-3 dup [ drop 3 ] unless ; +: dummy-unless-3 ( a -- b ) dup [ drop 3 ] unless ; [ 3 ] [ f dummy-unless-3 ] unit-test [ 4 ] [ 4 dummy-unless-3 ] unit-test @@ -201,7 +201,7 @@ DEFER: countdown-b ] compile-call ] unit-test -GENERIC: single-combination-test +GENERIC: single-combination-test ( obj1 obj2 -- obj ) M: object single-combination-test drop ; M: f single-combination-test nip ; @@ -214,13 +214,13 @@ M: integer single-combination-test drop ; DEFER: single-combination-test-2 -: single-combination-test-4 +: single-combination-test-4 ( obj -- obj ) dup [ single-combination-test-2 ] when ; -: single-combination-test-3 +: single-combination-test-3 ( obj -- obj ) drop 3 ; -GENERIC: single-combination-test-2 +GENERIC: single-combination-test-2 ( obj -- obj ) M: object single-combination-test-2 single-combination-test-3 ; M: f single-combination-test-2 single-combination-test-4 ; diff --git a/core/compiler/tests/stack-trace.factor b/core/compiler/tests/stack-trace.factor index 9ee774d81d..878f4230cd 100755 --- a/core/compiler/tests/stack-trace.factor +++ b/core/compiler/tests/stack-trace.factor @@ -7,9 +7,9 @@ words splitting sorting ; error-continuation get continuation-call callstack>array 2 group flip first ; -: foo 3 throw 7 ; -: bar foo 4 ; -: baz bar 5 ; +: foo ( -- * ) 3 throw 7 ; +: bar ( -- * ) foo 4 ; +: baz ( -- * ) bar 5 ; [ baz ] [ 3 = ] must-fail-with [ t ] [ symbolic-stack-trace @@ -17,9 +17,9 @@ words splitting sorting ; { baz bar foo throw } tail? ] unit-test -: bleh [ 3 + ] map [ 0 > ] filter ; +: bleh ( seq -- seq' ) [ 3 + ] map [ 0 > ] filter ; -: stack-trace-contains? symbolic-stack-trace memq? ; +: stack-trace-contains? ( word -- ? ) symbolic-stack-trace memq? ; [ t ] [ [ { 1 "hi" } bleh ] ignore-errors \ + stack-trace-contains? @@ -31,7 +31,7 @@ words splitting sorting ; \ > stack-trace-contains? ] unit-test -: quux { 1 2 3 } [ "hi" throw ] sort ; +: quux ( -- seq ) { 1 2 3 } [ "hi" throw ] sort ; [ t ] [ [ 10 quux ] ignore-errors diff --git a/core/compiler/tests/templates.factor b/core/compiler/tests/templates.factor index 14d75cdc03..65ef68deb8 100755 --- a/core/compiler/tests/templates.factor +++ b/core/compiler/tests/templates.factor @@ -31,7 +31,7 @@ unit-test [ 2 ] [ 1 2 [ swap fixnum/i ] compile-call ] unit-test -: foo ; +: foo ( -- ) ; [ 5 5 ] [ 1.2 [ tag [ foo ] keep ] compile-call ] @@ -103,10 +103,10 @@ unit-test ! Test how dispatch handles the end of a basic block -: try-breaking-dispatch +: try-breaking-dispatch ( n a b -- a b str ) float+ swap { [ "hey" ] [ "bye" ] } dispatch ; -: try-breaking-dispatch-2 +: try-breaking-dispatch-2 ( -- ? ) 1 1.0 2.5 try-breaking-dispatch "bye" = >r 3.5 = r> and ; [ t ] [ @@ -143,7 +143,7 @@ unit-test ] unit-test ! Regression -: foox +: foox ( obj -- obj ) dup not [ drop 3 ] [ dup tuple? [ drop 4 ] [ drop 5 ] if ] if ; @@ -189,7 +189,7 @@ TUPLE: my-tuple ; ] unit-test ! Regression -: a-dummy drop "hi" print ; +: a-dummy ( -- ) drop "hi" print ; [ ] [ 1 [ @@ -203,7 +203,7 @@ TUPLE: my-tuple ; ] compile-call ] unit-test -: float-spill-bug +: float-spill-bug ( a -- b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b ) { [ dup float+ ] [ dup float+ ] diff --git a/core/continuations/continuations.factor b/core/continuations/continuations.factor index 76f2cdef7a..087661dff4 100755 --- a/core/continuations/continuations.factor +++ b/core/continuations/continuations.factor @@ -26,7 +26,7 @@ SYMBOL: restarts #! with a declaration. f { object } declare ; -: init-catchstack V{ } clone 1 setenv ; +: init-catchstack ( -- ) V{ } clone 1 setenv ; PRIVATE> diff --git a/core/cpu/architecture/architecture.factor b/core/cpu/architecture/architecture.factor index 338c5341bc..42bf37d17f 100755 --- a/core/cpu/architecture/architecture.factor +++ b/core/cpu/architecture/architecture.factor @@ -41,12 +41,12 @@ HOOK: stack-frame cpu ( frame-size -- n ) ! Set up caller stack frame HOOK: %prologue cpu ( n -- ) -: %prologue-later \ %prologue-later , ; +: %prologue-later ( -- ) \ %prologue-later , ; ! Tear down stack frame HOOK: %epilogue cpu ( n -- ) -: %epilogue-later \ %epilogue-later , ; +: %epilogue-later ( -- ) \ %epilogue-later , ; ! Store word XT in stack frame HOOK: %save-word-xt cpu ( -- ) @@ -195,7 +195,7 @@ HOOK: %unbox-any-c-ptr cpu ( dst src -- ) HOOK: %box-alien cpu ( dst src -- ) ! GC check -HOOK: %gc cpu +HOOK: %gc cpu ( -- ) : operand ( var -- op ) get v>operand ; inline diff --git a/core/cpu/ppc/bootstrap.factor b/core/cpu/ppc/bootstrap.factor index 18c7e8b92e..cf380d69f1 100755 --- a/core/cpu/ppc/bootstrap.factor +++ b/core/cpu/ppc/bootstrap.factor @@ -72,7 +72,7 @@ big-endian on ] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define : jit-call-quot ( -- ) - temp-reg quot-reg quot-xt@ LWZ ! load quotation-xt + temp-reg quot-reg quot-xt-offset LWZ ! load quotation-xt temp-reg MTCTR ! jump to quotation-xt BCTR ; @@ -93,7 +93,7 @@ big-endian on temp-reg ds-reg 0 LWZ ! load index temp-reg dup 1 SRAWI ! turn it into an array offset quot-reg dup temp-reg ADD ! compute quotation location - quot-reg dup array-start LWZ ! load quotation + quot-reg dup array-start-offset LWZ ! load quotation ds-reg dup 4 SUBI ! pop index jit-call-quot ] rc-absolute-ppc-2/2 rt-literal 1 jit-dispatch jit-define diff --git a/core/cpu/x86/32/32.factor b/core/cpu/x86/32/32.factor index 9ef8177cf3..3c6e4963e1 100755 --- a/core/cpu/x86/32/32.factor +++ b/core/cpu/x86/32/32.factor @@ -31,21 +31,23 @@ M: int-regs return-reg drop EAX ; M: int-regs param-regs drop { } ; M: int-regs vregs drop { EAX ECX EDX EBP } ; M: int-regs push-return-reg return-reg PUSH ; -: load/store-int-return return-reg stack-reg rot [+] ; +: load/store-int-return ( n reg-class -- src dst ) + return-reg stack-reg rot [+] ; M: int-regs load-return-reg load/store-int-return MOV ; M: int-regs store-return-reg load/store-int-return swap MOV ; M: float-regs param-regs drop { } ; M: float-regs vregs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; -: FSTP 4 = [ FSTPS ] [ FSTPL ] if ; +: FSTP ( operand size -- ) 4 = [ FSTPS ] [ FSTPL ] if ; M: float-regs push-return-reg stack-reg swap reg-size [ SUB stack-reg [] ] keep FSTP ; -: FLD 4 = [ FLDS ] [ FLDL ] if ; +: FLD ( operand size -- ) 4 = [ FLDS ] [ FLDL ] if ; -: load/store-float-return reg-size >r stack@ r> ; +: load/store-float-return ( n reg-class -- op size ) + [ stack@ ] [ reg-size ] bi* ; M: float-regs load-return-reg load/store-float-return FLD ; M: float-regs store-return-reg load/store-float-return FSTP ; @@ -151,7 +153,7 @@ M: x86.32 %box ( n reg-class func -- ) >r (%box) r> f %alien-invoke ] with-aligned-stack ; -: (%box-long-long) +: (%box-long-long) ( n -- ) #! If n is f, push the return registers onto the stack; we #! are boxing a return value of a C function. If n is an #! integer, push [ESP+n]:[ESP+n+4] on the stack; we are @@ -166,7 +168,7 @@ M: x86.32 %box ( n reg-class func -- ) M: x86.32 %box-long-long ( n func -- ) 8 [ - >r (%box-long-long) r> f %alien-invoke + [ (%box-long-long) ] [ f %alien-invoke ] bi* ] with-aligned-stack ; M: x86.32 %box-large-struct ( n size -- ) @@ -260,7 +262,7 @@ os windows? [ 4 "double" c-type set-c-type-align ] unless -: sse2? "Intrinsic" throw ; +: sse2? ( -- ? ) "Intrinsic" throw ; \ sse2? [ { EAX EBX ECX EDX } [ PUSH ] each diff --git a/core/cpu/x86/allot/allot.factor b/core/cpu/x86/allot/allot.factor index 63870f94cd..144a9560d7 100755 --- a/core/cpu/x86/allot/allot.factor +++ b/core/cpu/x86/allot/allot.factor @@ -6,7 +6,7 @@ sequences generic arrays generator generator.fixup generator.registers system layouts alien ; IN: cpu.x86.allot -: allot-reg +: allot-reg ( -- reg ) #! We temporarily use the datastack register, since it won't #! be accessed inside the quotation given to %allot in any #! case. diff --git a/core/cpu/x86/architecture/architecture.factor b/core/cpu/x86/architecture/architecture.factor index 88881b19a8..2a3d16694e 100755 --- a/core/cpu/x86/architecture/architecture.factor +++ b/core/cpu/x86/architecture/architecture.factor @@ -7,12 +7,12 @@ generator generator.registers generator.fixup system layouts combinators compiler.constants math.order ; IN: cpu.x86.architecture -HOOK: ds-reg cpu -HOOK: rs-reg cpu -HOOK: stack-reg cpu -HOOK: stack-save-reg cpu +HOOK: ds-reg cpu ( -- reg ) +HOOK: rs-reg cpu ( -- reg ) +HOOK: stack-reg cpu ( -- reg ) +HOOK: stack-save-reg cpu ( -- reg ) -: stack@ stack-reg swap [+] ; +: stack@ ( n -- op ) stack-reg swap [+] ; : reg-stack ( n reg -- op ) swap cells neg [+] ; @@ -36,14 +36,14 @@ GENERIC: load-return-reg ( stack@ reg-class -- ) GENERIC: store-return-reg ( stack@ reg-class -- ) ! Only used by inline allocation -HOOK: temp-reg-1 cpu -HOOK: temp-reg-2 cpu +HOOK: temp-reg-1 cpu ( -- reg ) +HOOK: temp-reg-2 cpu ( -- reg ) HOOK: address-operand cpu ( address -- operand ) -HOOK: fixnum>slot@ cpu +HOOK: fixnum>slot@ cpu ( op -- ) -HOOK: prepare-division cpu +HOOK: prepare-division cpu ( -- ) M: immediate load-literal v>operand swap v>operand MOV ; @@ -53,7 +53,7 @@ M: x86 stack-frame ( n -- i ) M: x86 %save-word-xt ( -- ) temp-reg v>operand 0 MOV rc-absolute-cell rel-this ; -: factor-area-size 4 cells ; +: factor-area-size ( -- n ) 4 cells ; M: x86 %prologue ( n -- ) dup cell + PUSH @@ -120,7 +120,7 @@ M: x86 %peek [ v>operand ] bi@ MOV ; M: x86 %replace swap %peek ; -: (%inc) swap cells dup 0 > [ ADD ] [ neg SUB ] if ; +: (%inc) ( n reg -- ) swap cells dup 0 > [ ADD ] [ neg SUB ] if ; M: x86 %inc-d ( n -- ) ds-reg (%inc) ; @@ -139,7 +139,7 @@ M: x86 small-enough? ( n -- ? ) : %tag-fixnum ( reg -- ) tag-bits get SHL ; -: temp@ stack-reg \ stack-frame get rot - [+] ; +: temp@ ( n -- op ) stack-reg \ stack-frame get rot - [+] ; : struct-return@ ( size n -- n ) [ diff --git a/core/cpu/x86/assembler/assembler.factor b/core/cpu/x86/assembler/assembler.factor index bc6a12d167..452a102341 100755 --- a/core/cpu/x86/assembler/assembler.factor +++ b/core/cpu/x86/assembler/assembler.factor @@ -22,7 +22,7 @@ IN: cpu.x86.assembler : define-registers ( names size -- ) >r dup length r> [ define-register ] curry 2each ; -: REGISTERS: +: REGISTERS: ( -- ) scan-word ";" parse-tokens swap define-registers ; parsing >> @@ -76,31 +76,31 @@ TUPLE: indirect base index scale displacement ; M: indirect extended? base>> extended? ; -: canonicalize-EBP +: canonicalize-EBP ( indirect -- indirect ) #! { EBP } ==> { EBP 0 } dup base>> { EBP RBP R13 } member? [ dup displacement>> [ 0 >>displacement ] unless - ] when drop ; + ] when ; -: canonicalize-ESP +: canonicalize-ESP ( indirect -- indirect ) #! { ESP } ==> { ESP ESP } - dup base>> { ESP RSP R12 } member? [ ESP >>index ] when drop ; + dup base>> { ESP RSP R12 } member? [ ESP >>index ] when ; -: canonicalize ( indirect -- ) +: canonicalize ( indirect -- indirect ) #! Modify the indirect to work around certain addressing mode #! quirks. - [ canonicalize-EBP ] [ canonicalize-ESP ] bi ; + canonicalize-EBP canonicalize-ESP ; : ( base index scale displacement -- indirect ) - indirect boa dup canonicalize ; + indirect boa canonicalize ; -: reg-code "register" word-prop 7 bitand ; +: reg-code ( reg -- n ) "register" word-prop 7 bitand ; -: indirect-base* base>> EBP or reg-code ; +: indirect-base* ( op -- n ) base>> EBP or reg-code ; -: indirect-index* index>> ESP or reg-code ; +: indirect-index* ( op -- n ) index>> ESP or reg-code ; -: indirect-scale* scale>> 0 or ; +: indirect-scale* ( op -- n ) scale>> 0 or ; GENERIC: sib-present? ( op -- ? ) @@ -145,10 +145,10 @@ GENERIC# n, 1 ( value n -- ) M: integer n, >le % ; M: byte n, >r value>> r> n, ; -: 1, 1 n, ; inline -: 4, 4 n, ; inline -: 2, 2 n, ; inline -: cell, bootstrap-cell n, ; inline +: 1, ( n -- ) 1 n, ; inline +: 4, ( n -- ) 4 n, ; inline +: 2, ( n -- ) 2 n, ; inline +: cell, ( n -- ) bootstrap-cell n, ; inline : mod-r/m, ( reg# indirect -- ) [ 3 shift ] [ [ modifier 6 shift ] [ r/m ] bi ] bi* bitor bitor , ; @@ -196,10 +196,10 @@ M: object operand-64? drop f ; [ nip operand-64? ] } cond and ; -: rex.r +: rex.r ( m op -- n ) extended? [ BIN: 00000100 bitor ] when ; -: rex.b +: rex.b ( m op -- n ) [ extended? [ BIN: 00000001 bitor ] when ] keep dup indirect? [ index>> extended? [ BIN: 00000010 bitor ] when @@ -225,7 +225,7 @@ M: object operand-64? drop f ; #! the opcode. >r dupd prefix-1 reg-code r> + , ; -: opcode, dup array? [ % ] [ , ] if ; +: opcode, ( opcode -- ) dup array? [ % ] [ , ] if ; : extended-opcode ( opcode -- opcode' ) OCT: 17 swap 2array ; @@ -240,7 +240,7 @@ M: object operand-64? drop f ; #! 'reg' field of the mod-r/m byte. first3 >r >r over r> prefix-1 r> opcode, swap addressing ; -: immediate-operand-size-bit +: immediate-operand-size-bit ( imm dst reg,rex.w,opcode -- imm dst reg,rex.w,opcode ) pick integer? [ first3 BIN: 1 opcode-or 3array ] when ; : immediate-1 ( imm dst reg,rex.w,opcode -- ) @@ -249,7 +249,7 @@ M: object operand-64? drop f ; : immediate-4 ( imm dst reg,rex.w,opcode -- ) immediate-operand-size-bit 1-operand 4, ; -: immediate-fits-in-size-bit +: immediate-fits-in-size-bit ( imm dst reg,rex.w,opcode -- imm dst reg,rex.w,opcode ) pick integer? [ first3 BIN: 10 opcode-or 3array ] when ; : immediate-1/4 ( imm dst reg,rex.w,opcode -- ) @@ -320,38 +320,38 @@ M: operand MOV HEX: 88 2-operand ; ! Control flow GENERIC: JMP ( op -- ) -: (JMP) HEX: e9 , 0 4, rc-relative ; +: (JMP) ( -- rel-class ) HEX: e9 , 0 4, rc-relative ; M: callable JMP (JMP) rel-word ; M: label JMP (JMP) label-fixup ; M: operand JMP { BIN: 100 t HEX: ff } 1-operand ; GENERIC: CALL ( op -- ) -: (CALL) HEX: e8 , 0 4, rc-relative ; +: (CALL) ( -- rel-class ) HEX: e8 , 0 4, rc-relative ; M: callable CALL (CALL) rel-word ; M: label CALL (CALL) label-fixup ; M: operand CALL { BIN: 010 t HEX: ff } 1-operand ; GENERIC# JUMPcc 1 ( addr opcode -- ) -: (JUMPcc) extended-opcode, 0 4, rc-relative ; +: (JUMPcc) ( n -- rel-class ) extended-opcode, 0 4, rc-relative ; M: callable JUMPcc (JUMPcc) rel-word ; M: label JUMPcc (JUMPcc) label-fixup ; -: JO HEX: 80 JUMPcc ; -: JNO HEX: 81 JUMPcc ; -: JB HEX: 82 JUMPcc ; -: JAE HEX: 83 JUMPcc ; -: JE HEX: 84 JUMPcc ; ! aka JZ -: JNE HEX: 85 JUMPcc ; -: JBE HEX: 86 JUMPcc ; -: JA HEX: 87 JUMPcc ; -: JS HEX: 88 JUMPcc ; -: JNS HEX: 89 JUMPcc ; -: JP HEX: 8a JUMPcc ; -: JNP HEX: 8b JUMPcc ; -: JL HEX: 8c JUMPcc ; -: JGE HEX: 8d JUMPcc ; -: JLE HEX: 8e JUMPcc ; -: JG HEX: 8f JUMPcc ; +: JO ( dst -- ) HEX: 80 JUMPcc ; +: JNO ( dst -- ) HEX: 81 JUMPcc ; +: JB ( dst -- ) HEX: 82 JUMPcc ; +: JAE ( dst -- ) HEX: 83 JUMPcc ; +: JE ( dst -- ) HEX: 84 JUMPcc ; ! aka JZ +: JNE ( dst -- ) HEX: 85 JUMPcc ; +: JBE ( dst -- ) HEX: 86 JUMPcc ; +: JA ( dst -- ) HEX: 87 JUMPcc ; +: JS ( dst -- ) HEX: 88 JUMPcc ; +: JNS ( dst -- ) HEX: 89 JUMPcc ; +: JP ( dst -- ) HEX: 8a JUMPcc ; +: JNP ( dst -- ) HEX: 8b JUMPcc ; +: JL ( dst -- ) HEX: 8c JUMPcc ; +: JGE ( dst -- ) HEX: 8d JUMPcc ; +: JLE ( dst -- ) HEX: 8e JUMPcc ; +: JG ( dst -- ) HEX: 8f JUMPcc ; : LEAVE ( -- ) HEX: c9 , ; @@ -399,8 +399,8 @@ M: operand CMP OCT: 070 2-operand ; : DIV ( dst -- ) { BIN: 110 t HEX: f7 } 1-operand ; : IDIV ( src -- ) { BIN: 111 t HEX: f7 } 1-operand ; -: CDQ HEX: 99 , ; -: CQO HEX: 48 , CDQ ; +: CDQ ( -- ) HEX: 99 , ; +: CQO ( -- ) HEX: 48 , CDQ ; : ROL ( dst n -- ) swap { BIN: 000 t HEX: c0 } immediate-1 ; : ROR ( dst n -- ) swap { BIN: 001 t HEX: c0 } immediate-1 ; @@ -423,26 +423,26 @@ M: operand IMUL2 OCT: 257 extended-opcode (2-operand) ; ! Conditional move : MOVcc ( dst src cc -- ) extended-opcode swapd (2-operand) ; -: CMOVO HEX: 40 MOVcc ; -: CMOVNO HEX: 41 MOVcc ; -: CMOVB HEX: 42 MOVcc ; -: CMOVAE HEX: 43 MOVcc ; -: CMOVE HEX: 44 MOVcc ; ! aka CMOVZ -: CMOVNE HEX: 45 MOVcc ; -: CMOVBE HEX: 46 MOVcc ; -: CMOVA HEX: 47 MOVcc ; -: CMOVS HEX: 48 MOVcc ; -: CMOVNS HEX: 49 MOVcc ; -: CMOVP HEX: 4a MOVcc ; -: CMOVNP HEX: 4b MOVcc ; -: CMOVL HEX: 4c MOVcc ; -: CMOVGE HEX: 4d MOVcc ; -: CMOVLE HEX: 4e MOVcc ; -: CMOVG HEX: 4f MOVcc ; +: CMOVO ( dst src -- ) HEX: 40 MOVcc ; +: CMOVNO ( dst src -- ) HEX: 41 MOVcc ; +: CMOVB ( dst src -- ) HEX: 42 MOVcc ; +: CMOVAE ( dst src -- ) HEX: 43 MOVcc ; +: CMOVE ( dst src -- ) HEX: 44 MOVcc ; ! aka CMOVZ +: CMOVNE ( dst src -- ) HEX: 45 MOVcc ; +: CMOVBE ( dst src -- ) HEX: 46 MOVcc ; +: CMOVA ( dst src -- ) HEX: 47 MOVcc ; +: CMOVS ( dst src -- ) HEX: 48 MOVcc ; +: CMOVNS ( dst src -- ) HEX: 49 MOVcc ; +: CMOVP ( dst src -- ) HEX: 4a MOVcc ; +: CMOVNP ( dst src -- ) HEX: 4b MOVcc ; +: CMOVL ( dst src -- ) HEX: 4c MOVcc ; +: CMOVGE ( dst src -- ) HEX: 4d MOVcc ; +: CMOVLE ( dst src -- ) HEX: 4e MOVcc ; +: CMOVG ( dst src -- ) HEX: 4f MOVcc ; ! CPU Identification -: CPUID HEX: a2 extended-opcode, ; +: CPUID ( -- ) HEX: a2 extended-opcode, ; ! x87 Floating Point Unit diff --git a/core/cpu/x86/bootstrap.factor b/core/cpu/x86/bootstrap.factor index ea4cadd51b..bd1b0f2871 100755 --- a/core/cpu/x86/bootstrap.factor +++ b/core/cpu/x86/bootstrap.factor @@ -60,7 +60,7 @@ big-endian off arg0 \ f tag-number CMP ! compare it with f arg0 arg1 [] CMOVNE ! load true branch if not equal arg0 arg1 bootstrap-cell [+] CMOVE ! load false branch if equal - arg0 quot-xt@ [+] JMP ! jump to quotation-xt + arg0 quot-xt-offset [+] JMP ! jump to quotation-xt ] rc-absolute-cell rt-literal 1 rex-length + jit-if-jump jit-define [ @@ -70,8 +70,8 @@ big-endian off fixnum>slot@ ! turn it into an array offset ds-reg bootstrap-cell SUB ! pop index arg0 arg1 ADD ! compute quotation location - arg0 arg0 array-start [+] MOV ! load quotation - arg0 quot-xt@ [+] JMP ! execute branch + arg0 arg0 array-start-offset [+] MOV ! load quotation + arg0 quot-xt-offset [+] JMP ! execute branch ] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define [ diff --git a/core/cpu/x86/intrinsics/intrinsics.factor b/core/cpu/x86/intrinsics/intrinsics.factor index 667f08c053..0ee8a0a1d9 100755 --- a/core/cpu/x86/intrinsics/intrinsics.factor +++ b/core/cpu/x86/intrinsics/intrinsics.factor @@ -20,16 +20,16 @@ IN: cpu.x86.intrinsics } define-intrinsic ! Slots -: %slot-literal-known-tag +: %slot-literal-known-tag ( -- op ) "obj" operand "n" get cells "obj" get operand-tag - [+] ; -: %slot-literal-any-tag +: %slot-literal-any-tag ( -- op ) "obj" operand %untag "obj" operand "n" get cells [+] ; -: %slot-any +: %slot-any ( -- op ) "obj" operand %untag "n" operand fixnum>slot@ "obj" operand "n" operand [+] ; @@ -399,15 +399,15 @@ IN: cpu.x86.intrinsics { +clobber+ { "offset" } } } ; -: define-getter +: define-getter ( word quot reg -- ) [ %alien-integer-get ] 2curry alien-integer-get-template define-intrinsic ; -: define-unsigned-getter +: define-unsigned-getter ( word reg -- ) [ small-reg dup XOR MOV ] swap define-getter ; -: define-signed-getter +: define-signed-getter ( word reg -- ) [ [ >r MOV small-reg r> MOVSX ] curry ] keep define-getter ; : %alien-integer-set ( quot reg -- ) @@ -429,7 +429,7 @@ IN: cpu.x86.intrinsics { +clobber+ { "value" "offset" } } } ; -: define-setter +: define-setter ( word reg -- ) [ swap MOV ] swap [ %alien-integer-set ] 2curry alien-integer-set-template diff --git a/core/debugger/debugger.factor b/core/debugger/debugger.factor index 17219ba92b..cfad144737 100755 --- a/core/debugger/debugger.factor +++ b/core/debugger/debugger.factor @@ -36,12 +36,12 @@ M: string error. print ; : :vars ( -- ) error-continuation get continuation-name namestack. ; -: :res ( n -- ) +: :res ( n -- * ) 1- restarts get-global nth f restarts set-global restart ; -: :1 1 :res ; -: :2 2 :res ; -: :3 3 :res ; +: :1 ( -- * ) 1 :res ; +: :2 ( -- * ) 2 :res ; +: :3 ( -- * ) 3 :res ; : restart. ( restart n -- ) [ @@ -143,15 +143,15 @@ M: relative-overflow summary : stack-overflow. ( obj name -- ) write " stack overflow" print drop ; -: datastack-underflow. "Data" stack-underflow. ; -: datastack-overflow. "Data" stack-overflow. ; -: retainstack-underflow. "Retain" stack-underflow. ; -: retainstack-overflow. "Retain" stack-overflow. ; +: datastack-underflow. ( obj -- ) "Data" stack-underflow. ; +: datastack-overflow. ( obj -- ) "Data" stack-overflow. ; +: retainstack-underflow. ( obj -- ) "Retain" stack-underflow. ; +: retainstack-overflow. ( obj -- ) "Retain" stack-overflow. ; -: memory-error. +: memory-error. ( error -- ) "Memory protection fault at address " write third .h ; -: primitive-error. +: primitive-error. ( error -- ) "Unimplemented primitive" print drop ; PREDICATE: kernel-error < array @@ -161,7 +161,7 @@ PREDICATE: kernel-error < array [ second 0 15 between? ] } cond ; -: kernel-errors +: kernel-errors ( error -- n errors ) second { { 0 [ expired-error. ] } { 1 [ io-error. ] } diff --git a/core/effects/effects.factor b/core/effects/effects.factor index 80a4f679c0..099260f111 100755 --- a/core/effects/effects.factor +++ b/core/effects/effects.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math namespaces sequences strings words assocs -combinators ; +combinators accessors ; IN: effects TUPLE: effect in out terminated? ; @@ -11,14 +11,13 @@ TUPLE: effect in out terminated? ; effect boa ; : effect-height ( effect -- n ) - dup effect-out length swap effect-in length - ; + [ out>> length ] [ in>> length ] bi - ; : effect<= ( eff1 eff2 -- ? ) { - { [ dup not ] [ t ] } - { [ over effect-terminated? ] [ t ] } - { [ dup effect-terminated? ] [ f ] } - { [ 2dup [ effect-in length ] bi@ > ] [ f ] } + { [ over terminated?>> ] [ t ] } + { [ dup terminated?>> ] [ f ] } + { [ 2dup [ in>> length ] bi@ > ] [ f ] } { [ 2dup [ effect-height ] bi@ = not ] [ f ] } [ t ] } cond 2nip ; @@ -34,10 +33,10 @@ M: integer (stack-picture) drop "object" ; : effect>string ( effect -- string ) [ "( " % - dup effect-in stack-picture % - "-- " % - dup effect-out stack-picture % - effect-terminated? [ "* " % ] when + [ in>> stack-picture % "-- " % ] + [ out>> stack-picture % ] + [ terminated?>> [ "* " % ] when ] + tri ")" % ] "" make ; @@ -50,16 +49,16 @@ M: word stack-effect swap word-props [ at ] curry map [ ] find nip ; M: effect clone - [ effect-in clone ] keep effect-out clone ; + [ in>> clone ] keep effect-out clone ; : split-shuffle ( stack shuffle -- stack1 stack2 ) - effect-in length cut* ; + in>> length cut* ; : load-shuffle ( stack shuffle -- ) - effect-in [ set ] 2each ; + in>> [ set ] 2each ; : shuffled-values ( shuffle -- values ) - effect-out [ get ] map ; + out>> [ get ] map ; : shuffle* ( stack shuffle -- newstack ) [ [ load-shuffle ] keep shuffled-values ] with-scope ; diff --git a/core/generator/generator.factor b/core/generator/generator.factor index b8de9c3517..684c058913 100755 --- a/core/generator/generator.factor +++ b/core/generator/generator.factor @@ -72,8 +72,8 @@ GENERIC: generate-node ( node -- next ) : word-dataflow ( word -- effect dataflow ) [ - dup "no-effect" word-prop [ no-effect ] when - dup "no-compile" word-prop [ no-effect ] when + dup "cannot-infer" word-prop [ cannot-infer-effect ] when + dup "no-compile" word-prop [ cannot-infer-effect ] when dup specialized-def over dup 2array 1array infer-quot finish-word ] with-infer ; diff --git a/core/generator/registers/registers.factor b/core/generator/registers/registers.factor index c5e1ea54a6..ded1c82ee4 100755 --- a/core/generator/registers/registers.factor +++ b/core/generator/registers/registers.factor @@ -67,7 +67,7 @@ INSTANCE: temp-reg value ! A data stack location. TUPLE: ds-loc n class ; -: f ds-loc boa ; +: ( n -- loc ) f ds-loc boa ; M: ds-loc minimal-ds-loc* ds-loc-n min ; M: ds-loc operand-class* ds-loc-class ; @@ -78,7 +78,7 @@ M: ds-loc live-loc? ! A retain stack location. TUPLE: rs-loc n class ; -: f rs-loc boa ; +: ( n -- loc ) f rs-loc boa ; M: rs-loc operand-class* rs-loc-class ; M: rs-loc set-operand-class set-rs-loc-class ; M: rs-loc live-loc? @@ -177,7 +177,7 @@ INSTANCE: constant value r 0 V{ } clone r> boa ; inline -: (loc) +: (loc) ( m stack -- n ) #! Utility for methods on height>> - ; diff --git a/core/generic/generic-tests.factor b/core/generic/generic-tests.factor index 600f422274..9d968a3a98 100755 --- a/core/generic/generic-tests.factor +++ b/core/generic/generic-tests.factor @@ -156,7 +156,7 @@ M: integer generic-forget-test-1 / ; [ word-name "generic-forget-test-1/integer" = ] contains? ] unit-test -GENERIC: generic-forget-test-2 +GENERIC: generic-forget-test-2 ( a b -- c ) M: sequence generic-forget-test-2 = ; @@ -174,7 +174,7 @@ M: sequence generic-forget-test-2 = ; [ word-name "generic-forget-test-2/sequence" = ] contains? ] unit-test -GENERIC: generic-forget-test-3 +GENERIC: generic-forget-test-3 ( a -- b ) M: f generic-forget-test-3 ; diff --git a/core/generic/standard/engines/tag/tag.factor b/core/generic/standard/engines/tag/tag.factor index 6344bec536..c1e72a65de 100644 --- a/core/generic/standard/engines/tag/tag.factor +++ b/core/generic/standard/engines/tag/tag.factor @@ -38,7 +38,7 @@ C: hi-tag-dispatch-engine \ hi-tag bootstrap-word \ convert-methods ; -: num-hi-tags num-types get num-tags get - ; +: num-hi-tags ( -- n ) num-types get num-tags get - ; : hi-tag-number ( class -- n ) "type" word-prop num-tags get - ; diff --git a/core/generic/standard/engines/tuple/tuple.factor b/core/generic/standard/engines/tuple/tuple.factor index 24fb8ba4f4..9a780383b5 100644 --- a/core/generic/standard/engines/tuple/tuple.factor +++ b/core/generic/standard/engines/tuple/tuple.factor @@ -44,7 +44,7 @@ M: trivial-tuple-dispatch-engine engine>quot >alist V{ } clone [ hashcode 1array ] distribute-buckets [ ] map ; -: word-hashcode% [ 1 slot ] % ; +: word-hashcode% ( -- ) [ 1 slot ] % ; : class-hash-dispatch-quot ( methods -- quot ) [ @@ -78,7 +78,7 @@ M: engine-word irrelevant? drop t ; : define-engine-word ( quot -- word ) >r dup r> define ; -: array-nth% 2 + , [ slot { word } declare ] % ; +: array-nth% ( n -- ) 2 + , [ slot { word } declare ] % ; : tuple-layout-superclasses ( obj -- array ) { tuple } declare diff --git a/core/generic/standard/standard-tests.factor b/core/generic/standard/standard-tests.factor index 66f191a93f..93956fec00 100644 --- a/core/generic/standard/standard-tests.factor +++ b/core/generic/standard/standard-tests.factor @@ -6,7 +6,7 @@ quotations inference vectors growable hashtables sbufs prettyprint byte-vectors bit-vectors float-vectors definitions generic sets graphs assocs ; -GENERIC: lo-tag-test +GENERIC: lo-tag-test ( obj -- obj' ) M: integer lo-tag-test 3 + ; @@ -21,7 +21,7 @@ M: complex lo-tag-test sq ; [ -1/2 ] [ 1+1/2 lo-tag-test ] unit-test [ -16 ] [ C{ 0 4 } lo-tag-test ] unit-test -GENERIC: hi-tag-test +GENERIC: hi-tag-test ( obj -- obj' ) M: string hi-tag-test ", in bed" append ; @@ -53,7 +53,7 @@ TUPLE: circle < shape radius ; C: circle -GENERIC: area +GENERIC: area ( shape -- n ) M: abstract-rectangle area [ width>> ] [ height>> ] bi * ; @@ -63,15 +63,15 @@ M: circle area radius>> sq pi * ; [ 12 ] [ 4 3 2 area ] unit-test [ t ] [ 2 area 4 pi * = ] unit-test -GENERIC: perimiter +GENERIC: perimiter ( shape -- n ) -: rectangle-perimiter + 2 * ; +: rectangle-perimiter ( n -- n ) + 2 * ; M: rectangle perimiter [ width>> ] [ height>> ] bi rectangle-perimiter ; -: hypotenuse [ sq ] bi@ + sqrt ; +: hypotenuse ( a b -- c ) [ sq ] bi@ + sqrt ; M: parallelogram perimiter [ width>> ] @@ -83,7 +83,7 @@ M: circle perimiter 2 * pi * ; [ 14 ] [ 4 3 perimiter ] unit-test [ 30 ] [ 10 4 3 perimiter ] unit-test -GENERIC: big-mix-test +GENERIC: big-mix-test ( obj -- obj' ) M: object big-mix-test drop "object" ; @@ -125,7 +125,7 @@ M: circle big-mix-test drop "circle" ; [ "tuple" ] [ H{ } big-mix-test ] unit-test [ "object" ] [ \ + big-mix-test ] unit-test -GENERIC: small-lo-tag +GENERIC: small-lo-tag ( obj -- obj ) M: fixnum small-lo-tag drop "fixnum" ; @@ -226,7 +226,7 @@ M: b funky* "b" , call-next-method ; M: c funky* "c" , call-next-method ; -: funky [ funky* ] { } make ; +: funky ( obj -- seq ) [ funky* ] { } make ; [ { "b" "x" "z" } ] [ T{ b } funky ] unit-test @@ -293,7 +293,7 @@ M: sbuf no-stack-effect-decl ; TUPLE: xref-tuple-1 ; TUPLE: xref-tuple-2 < xref-tuple-1 ; -: (xref-test) drop ; +: (xref-test) ( obj -- ) drop ; GENERIC: xref-test ( obj -- ) diff --git a/core/inference/backend/backend-docs.factor b/core/inference/backend/backend-docs.factor index ccfa490318..24f64eaab1 100755 --- a/core/inference/backend/backend-docs.factor +++ b/core/inference/backend/backend-docs.factor @@ -43,9 +43,9 @@ HELP: consume/produce { $values { "node" "a dataflow node" } { "effect" "an instance of " { $link effect } } } { $description "Adds a node to the dataflow graph that calls " { $snippet "word" } " with a stack effect of " { $snippet "effect" } "." } ; -HELP: no-effect +HELP: cannot-infer-effect { $values { "word" word } } -{ $description "Throws a " { $link no-effect } " error." } +{ $description "Throws a " { $link cannot-infer-effect } " error." } { $error-description "Thrown when inference encounters a call to a word which is already known not to have a static stack effect, due to a prior inference attempt failing." } ; HELP: inline-word @@ -61,8 +61,8 @@ HELP: effect-error { $description "Throws an " { $link effect-error } "." } { $error-description "Thrown when a word's inferred stack effect does not match its declared stack effect." } ; -HELP: no-recursive-declaration -{ $error-description "Thrown when inference encounters a recursive call to a word lacking a stack effect declaration. Recursive words must declare a stack effect in order to compile. Due to implementation detail, generic words are recursive, and thus the same restriction applies." } ; +HELP: missing-effect +{ $error-description "Thrown when inference encounters a word lacking a stack effect declaration. Words not declared " { $link POSTPONE: inline } " must declare a stack effect in order to compile." } ; HELP: recursive-quotation-error { $error-description "Thrown when a quotation calls itself, directly or indirectly, within the same word. Stack effect inference becomes equivalent to the halting problem if quotation recursion has to be taken into account, hence it is not permitted." } diff --git a/core/inference/backend/backend.factor b/core/inference/backend/backend.factor index 42a1c1dd19..080e77af02 100755 --- a/core/inference/backend/backend.factor +++ b/core/inference/backend/backend.factor @@ -23,7 +23,7 @@ M: word inline? SYMBOL: visited -: reset-on-redefine { "inferred-effect" "no-effect" } ; inline +: reset-on-redefine { "inferred-effect" "cannot-infer" } ; inline : (redefined) ( word -- ) dup visited get key? [ drop ] [ @@ -382,18 +382,36 @@ TUPLE: unbalanced-branches-error quots in out ; #call consume/produce ] if ; -TUPLE: no-effect word ; +TUPLE: cannot-infer-effect word ; -: no-effect ( word -- * ) \ no-effect inference-warning ; +: cannot-infer-effect ( word -- * ) + \ cannot-infer-effect inference-warning ; -TUPLE: effect-error word effect ; +TUPLE: effect-error word inferred declared ; -: effect-error ( word effect -- * ) +: effect-error ( word inferred declared -- * ) \ effect-error inference-error ; +TUPLE: missing-effect word ; + +: effect-required? ( word -- ? ) + { + { [ dup inline? ] [ drop f ] } + { [ dup deferred? ] [ drop f ] } + { [ dup crossref? not ] [ drop f ] } + [ word-def [ [ word? ] [ primitive? not ] bi and ] contains? ] + } cond ; + +: ?missing-effect ( word -- ) + dup effect-required? + [ missing-effect inference-error ] [ drop ] if ; + : check-effect ( word effect -- ) - dup pick stack-effect effect<= - [ 2drop ] [ effect-error ] if ; + over stack-effect { + { [ dup not ] [ 2drop ?missing-effect ] } + { [ 2dup effect<= ] [ 3drop ] } + [ effect-error ] + } cond ; : finish-word ( word -- ) current-effect @@ -412,7 +430,7 @@ TUPLE: effect-error word effect ; finish-word current-effect ] with-scope - ] [ ] [ t "no-effect" set-word-prop ] cleanup ; + ] [ ] [ t "cannot-infer" set-word-prop ] cleanup ; : custom-infer ( word -- ) #! Customized inference behavior @@ -424,18 +442,16 @@ TUPLE: effect-error word effect ; : apply-word ( word -- ) { { [ dup "infer" word-prop ] [ custom-infer ] } - { [ dup "no-effect" word-prop ] [ no-effect ] } + { [ dup "cannot-infer" word-prop ] [ cannot-infer-effect ] } { [ dup "inferred-effect" word-prop ] [ cached-infer ] } [ dup infer-word make-call-node ] } cond ; -TUPLE: no-recursive-declaration word ; - -: declared-infer ( word -- ) +: declared-infer ( word -- ) dup stack-effect [ make-call-node ] [ - \ no-recursive-declaration inference-error + \ missing-effect inference-error ] if* ; GENERIC: collect-label-info* ( label node -- ) @@ -463,9 +479,11 @@ M: #return collect-label-info* dup node-param #return node, dataflow-graph get 1array over set-node-children ; -: inlined-block? "inlined-block" word-prop ; +: inlined-block? ( word -- ? ) + "inlined-block" word-prop ; -: gensym dup t "inlined-block" set-word-prop ; +: ( -- word ) + gensym dup t "inlined-block" set-word-prop ; : inline-block ( word -- #label data ) [ @@ -493,13 +511,15 @@ M: #return collect-label-info* namespace swap update ; : current-stack-height ( -- n ) - meta-d get length d-in get - ; + d-in get meta-d get length - ; : word-stack-height ( word -- n ) - stack-effect [ in>> length ] [ out>> length ] bi - ; + stack-effect effect-height ; : bad-recursive-declaration ( word inferred -- ) - dup 0 < [ 0 ] [ 0 swap ] if effect-error ; + dup 0 < [ 0 swap ] [ 0 ] if + over stack-effect + effect-error ; : check-stack-height ( word height -- ) over word-stack-height over = diff --git a/core/inference/class/class-tests.factor b/core/inference/class/class-tests.factor index e6ce2cfa0b..770763bfb6 100755 --- a/core/inference/class/class-tests.factor +++ b/core/inference/class/class-tests.factor @@ -142,7 +142,7 @@ M: object xyz ; [ f ] [ [ length ] \ slot inlined? ] unit-test ! We don't want to use = to compare literals -: foo reverse ; +: foo ( seq -- seq' ) reverse ; \ foo [ [ diff --git a/core/inference/class/class.factor b/core/inference/class/class.factor index dc632425fe..2f7058ba96 100755 --- a/core/inference/class/class.factor +++ b/core/inference/class/class.factor @@ -41,11 +41,11 @@ C: interval-constraint GENERIC: apply-constraint ( constraint -- ) GENERIC: constraint-satisfied? ( constraint -- ? ) -: `input node get in-d>> nth ; -: `output node get out-d>> nth ; -: class, , ; -: literal, , ; -: interval, , ; +: `input ( n -- value ) node get in-d>> nth ; +: `output ( n -- value ) node get out-d>> nth ; +: class, ( class value -- ) , ; +: literal, ( literal value -- ) , ; +: interval, ( interval value -- ) , ; M: f apply-constraint drop ; diff --git a/core/inference/dataflow/dataflow.factor b/core/inference/dataflow/dataflow.factor index d7e3e78308..734c1c551c 100755 --- a/core/inference/dataflow/dataflow.factor +++ b/core/inference/dataflow/dataflow.factor @@ -6,7 +6,7 @@ inference.state accessors combinators ; IN: inference.dataflow ! Computed value -: \ counter ; +: ( -- value ) \ counter ; ! Literal value TUPLE: value < identity-tuple literal uid recursion ; @@ -88,7 +88,7 @@ M: object flatten-curry , ; : r-tail ( n -- seq ) dup zero? [ drop f ] [ meta-r get swap tail* ] if ; -: node-child node-children first ; +: node-child ( node -- child ) node-children first ; TUPLE: #label < node word loop? returns calls ; @@ -217,9 +217,9 @@ M: #call-label calls-label* param>> eq? ; SYMBOL: node-stack -: >node node-stack get push ; -: node> node-stack get pop ; -: node@ node-stack get peek ; +: >node ( node -- ) node-stack get push ; +: node> ( -- node ) node-stack get pop ; +: node@ ( -- node ) node-stack get peek ; : iterate-next ( -- node ) node@ successor>> ; diff --git a/core/inference/errors/errors.factor b/core/inference/errors/errors.factor index 3c6680bcde..9c28d49dd8 100644 --- a/core/inference/errors/errors.factor +++ b/core/inference/errors/errors.factor @@ -29,21 +29,19 @@ M: too-many-r> summary drop "Quotation pops retain stack elements which it did not push" ; -M: no-effect error. +M: cannot-infer-effect error. "Unable to infer stack effect of " write word>> . ; -M: no-recursive-declaration error. - "The recursive word " write +M: missing-effect error. + "The word " write word>> pprint " must declare a stack effect" print ; M: effect-error error. "Stack effects of the word " write - dup word>> pprint - " do not match." print - "Declared: " write - dup word>> stack-effect effect>string . - "Inferred: " write effect>> effect>string . ; + [ word>> pprint " do not match." print ] + [ "Inferred: " write inferred>> effect>string . ] + [ "Declared: " write declared>> effect>string . ] tri ; M: recursive-quotation-error error. "The quotation " write diff --git a/core/inference/inference-docs.factor b/core/inference/inference-docs.factor index acc9329670..7858077bef 100755 --- a/core/inference/inference-docs.factor +++ b/core/inference/inference-docs.factor @@ -83,13 +83,13 @@ ARTICLE: "inference-errors" "Inference errors" "Main wrapper for all inference errors:" { $subsection inference-error } "Specific inference errors:" -{ $subsection no-effect } +{ $subsection cannot-infer-effect } { $subsection literal-expected } { $subsection too-many->r } { $subsection too-many-r> } { $subsection unbalanced-branches-error } { $subsection effect-error } -{ $subsection no-recursive-declaration } ; +{ $subsection missing-effect } ; ARTICLE: "inference" "Stack effect inference" "The stack effect inference tool is used to check correctness of code before it is run. It is also used by the compiler to build a dataflow graph on which optimizations can be performed. Only words for which a stack effect can be inferred will compile." diff --git a/core/inference/inference-tests.factor b/core/inference/inference-tests.factor index 4ce354bdcc..7f073bfad9 100755 --- a/core/inference/inference-tests.factor +++ b/core/inference/inference-tests.factor @@ -48,20 +48,12 @@ IN: inference.tests ] must-fail ! Test inference of termination of control flow -: termination-test-1 - "foo" throw ; +: termination-test-1 ( -- * ) "foo" throw ; -: termination-test-2 [ termination-test-1 ] [ 3 ] if ; +: termination-test-2 ( ? -- x ) [ termination-test-1 ] [ 3 ] if ; { 1 1 } [ termination-test-2 ] must-infer-as -: infinite-loop infinite-loop ; - -[ [ infinite-loop ] infer ] must-fail - -: no-base-case-1 dup [ no-base-case-1 ] [ no-base-case-1 ] if ; -[ [ no-base-case-1 ] infer ] must-fail - : simple-recursion-1 ( obj -- obj ) dup [ simple-recursion-1 ] [ ] if ; @@ -131,7 +123,7 @@ SYMBOL: sym-test { 0 1 } [ sym-test ] must-infer-as -: terminator-branch +: terminator-branch ( a -- b ) dup [ length ] [ @@ -198,11 +190,10 @@ DEFER: blah4 [ [ [ 1 ] [ ] bad-combinator ] infer ] must-fail ! Regression -: bad-input# +{ 2 2 } [ dup string? [ 2array throw ] unless - over string? [ 2array throw ] unless ; - -{ 2 2 } [ bad-input# ] must-infer-as + over string? [ 2array throw ] unless +] must-infer-as ! Regression @@ -224,7 +215,7 @@ DEFER: do-crap* { 2 1 } [ too-deep ] must-infer-as ! Error reporting is wrong -MATH: xyz +MATH: xyz ( a b -- c ) M: fixnum xyz 2array ; M: float xyz [ 3 ] bi@ swapd >r 2array swap r> 2array swap ; @@ -448,7 +439,7 @@ DEFER: bar ! Incorrect stack declarations on inline recursive words should ! be caught : fooxxx ( a b -- c ) over [ foo ] when ; inline -: barxxx fooxxx ; +: barxxx ( a b -- c ) fooxxx ; [ [ barxxx ] infer ] must-fail @@ -472,9 +463,7 @@ M: string my-hook "a string" ; DEFER: deferred-word -: calls-deferred-word [ deferred-word ] [ 3 ] if ; - -{ 1 1 } [ calls-deferred-word ] must-infer-as +{ 1 1 } [ [ deferred-word ] [ 3 ] if ] must-infer-as USE: inference.dataflow @@ -557,26 +546,26 @@ ERROR: custom-error ; [ [ erg's-inference-bug ] infer ] must-fail -: inference-invalidation-a ; -: inference-invalidation-b [ inference-invalidation-a ] dip call ; inline -: inference-invalidation-c [ + ] inference-invalidation-b ; - -[ 7 ] [ 4 3 inference-invalidation-c ] unit-test - -{ 2 1 } [ inference-invalidation-c ] must-infer-as - -[ ] [ "IN: inference.tests : inference-invalidation-a 1 2 ;" eval ] unit-test - -[ 3 ] [ inference-invalidation-c ] unit-test - -{ 0 1 } [ inference-invalidation-c ] must-infer-as - -GENERIC: inference-invalidation-d ( obj -- ) - -M: object inference-invalidation-d inference-invalidation-c 2drop ; - -\ inference-invalidation-d must-infer - -[ ] [ "IN: inference.tests : inference-invalidation-a ;" eval ] unit-test - -[ [ inference-invalidation-d ] infer ] must-fail +! : inference-invalidation-a ( -- ); +! : inference-invalidation-b ( quot -- ) [ inference-invalidation-a ] dip call ; inline +! : inference-invalidation-c ( a b -- c ) [ + ] inference-invalidation-b ; +! +! [ 7 ] [ 4 3 inference-invalidation-c ] unit-test +! +! { 2 1 } [ [ + ] inference-invalidation-b ] must-infer-as +! +! [ ] [ "IN: inference.tests : inference-invalidation-a 1 2 ;" eval ] unit-test +! +! [ 3 ] [ inference-invalidation-c ] unit-test +! +! { 0 1 } [ inference-invalidation-c ] must-infer-as +! +! GENERIC: inference-invalidation-d ( obj -- ) +! +! M: object inference-invalidation-d inference-invalidation-c 2drop ; +! +! \ inference-invalidation-d must-infer +! +! [ ] [ "IN: inference.tests : inference-invalidation-a ;" eval ] unit-test +! +! [ [ inference-invalidation-d ] infer ] must-fail diff --git a/core/inference/inference.factor b/core/inference/inference.factor index 3f52eaadf4..d73e43cdfc 100755 --- a/core/inference/inference.factor +++ b/core/inference/inference.factor @@ -29,6 +29,6 @@ M: callable dataflow-with : forget-errors ( -- ) all-words [ - dup subwords [ f "no-effect" set-word-prop ] each - f "no-effect" set-word-prop + dup subwords [ f "cannot-infer" set-word-prop ] each + f "cannot-infer" set-word-prop ] each ; diff --git a/core/inference/known-words/known-words.factor b/core/inference/known-words/known-words.factor index 2d45ce0d0c..3282cbb5e2 100755 --- a/core/inference/known-words/known-words.factor +++ b/core/inference/known-words/known-words.factor @@ -583,7 +583,7 @@ set-primitive-effect \ (set-os-envs) { array } { } set-primitive-effect -\ do-primitive [ \ do-primitive no-effect ] "infer" set-word-prop +\ do-primitive [ \ do-primitive cannot-infer-effect ] "infer" set-word-prop \ dll-valid? { object } { object } set-primitive-effect diff --git a/core/inference/state/state.factor b/core/inference/state/state.factor index 6f0eecf2d9..9cc1b80f9a 100755 --- a/core/inference/state/state.factor +++ b/core/inference/state/state.factor @@ -12,16 +12,16 @@ SYMBOL: d-in ! Compile-time data stack SYMBOL: meta-d -: push-d meta-d get push ; -: pop-d meta-d get pop ; -: peek-d meta-d get peek ; +: push-d ( obj -- ) meta-d get push ; +: pop-d ( -- obj ) meta-d get pop ; +: peek-d ( -- obj ) meta-d get peek ; ! Compile-time retain stack SYMBOL: meta-r -: push-r meta-r get push ; -: pop-r meta-r get pop ; -: peek-r meta-r get peek ; +: push-r ( obj -- ) meta-r get push ; +: pop-r ( -- obj ) meta-r get pop ; +: peek-r ( -- obj ) meta-r get peek ; ! Head of dataflow IR SYMBOL: dataflow-graph diff --git a/core/inference/transforms/transforms-tests.factor b/core/inference/transforms/transforms-tests.factor index a5b898315a..0e79ed2632 100755 --- a/core/inference/transforms/transforms-tests.factor +++ b/core/inference/transforms/transforms-tests.factor @@ -3,10 +3,10 @@ USING: sequences inference.transforms tools.test math kernel quotations inference accessors combinators words arrays classes ; -: compose-n-quot >quotation ; -: compose-n compose-n-quot call ; +: compose-n-quot ( word -- quot' ) >quotation ; +: compose-n ( quot -- ) compose-n-quot call ; \ compose-n [ compose-n-quot ] 2 define-transform -: compose-n-test 2 \ + compose-n ; +: compose-n-test ( -- x ) 2 \ + compose-n ; [ 6 ] [ 1 2 3 compose-n-test ] unit-test @@ -20,25 +20,12 @@ classes ; [ 512 ] [ 1 { { 1+ 8 } } bitfield-quot call ] unit-test -\ new must-infer - -TUPLE: a-tuple x y z ; - -: set-slots-test ( x y z -- ) - { set-a-tuple-x set-a-tuple-y } set-slots ; - -\ set-slots-test must-infer - -: set-slots-test-2 - { set-a-tuple-x set-a-tuple-x } set-slots ; - -[ [ set-slots-test-2 ] infer ] must-fail - TUPLE: color r g b ; C: color -: cleave-test { [ r>> ] [ g>> ] [ b>> ] } cleave ; +: cleave-test ( color -- r g b ) + { [ r>> ] [ g>> ] [ b>> ] } cleave ; { 1 3 } [ cleave-test ] must-infer-as @@ -46,13 +33,13 @@ C: color [ 1 2 3 ] [ 1 2 3 \ cleave-test word-def call ] unit-test -: 2cleave-test { [ 2array ] [ + ] [ - ] } 2cleave ; +: 2cleave-test ( a b -- c d e ) { [ 2array ] [ + ] [ - ] } 2cleave ; [ { 1 2 } 3 -1 ] [ 1 2 2cleave-test ] unit-test [ { 1 2 } 3 -1 ] [ 1 2 \ 2cleave-test word-def call ] unit-test -: spread-test { [ sq ] [ neg ] [ recip ] } spread ; +: spread-test ( a b c -- d e f ) { [ sq ] [ neg ] [ recip ] } spread ; [ 16 -3 1/6 ] [ 4 3 6 spread-test ] unit-test diff --git a/core/io/files/files-tests.factor b/core/io/files/files-tests.factor index f10bcef8a9..e201d663a6 100755 --- a/core/io/files/files-tests.factor +++ b/core/io/files/files-tests.factor @@ -5,6 +5,8 @@ strings accessors io.encodings.utf8 math destructors ; \ exists? must-infer \ (exists?) must-infer +\ file-info must-infer +\ link-info must-infer [ ] [ "blahblah" temp-file dup exists? [ delete-directory ] [ drop ] if ] unit-test [ ] [ "blahblah" temp-file make-directory ] unit-test diff --git a/core/io/files/files.factor b/core/io/files/files.factor index ff265e43b1..56a9a461cf 100755 --- a/core/io/files/files.factor +++ b/core/io/files/files.factor @@ -260,7 +260,8 @@ HOOK: delete-directory io-backend ( path -- ) delete-file ] if ; -: to-directory over file-name append-path ; +: to-directory ( from to -- from to' ) + over file-name append-path ; ! Moving and renaming files HOOK: move-file io-backend ( from to -- ) diff --git a/core/io/streams/string/string.factor b/core/io/streams/string/string.factor index 355e913b14..d2b092abe8 100755 --- a/core/io/streams/string/string.factor +++ b/core/io/streams/string/string.factor @@ -26,7 +26,8 @@ M: growable stream-read1 dup empty? [ drop f ] [ pop ] if ; : growable-read-until ( growable n -- str ) >fixnum dupd tail-slice swap harden-as dup reverse-here ; -: find-last-sep swap [ memq? ] curry find-last drop ; +: find-last-sep ( seq seps -- n ) + swap [ memq? ] curry find-last drop ; M: growable stream-read-until [ find-last-sep ] keep over [ diff --git a/core/math/bitfields/bitfields-tests.factor b/core/math/bitfields/bitfields-tests.factor index 6dfc51f440..70533ac33f 100755 --- a/core/math/bitfields/bitfields-tests.factor +++ b/core/math/bitfields/bitfields-tests.factor @@ -10,7 +10,7 @@ IN: math.bitfields.tests : a 1 ; inline : b 2 ; inline -: foo { a b } flags ; +: foo ( -- flags ) { a b } flags ; [ 3 ] [ foo ] unit-test [ 3 ] [ { a b } flags ] unit-test diff --git a/core/math/integers/integers-tests.factor b/core/math/integers/integers-tests.factor index db50d262ad..f428df33ae 100755 --- a/core/math/integers/integers-tests.factor +++ b/core/math/integers/integers-tests.factor @@ -192,7 +192,7 @@ unit-test [ f ] [ 0 power-of-2? ] unit-test [ t ] [ 1 power-of-2? ] unit-test -: ratio>float [ >bignum ] bi@ /f ; +: ratio>float ( a b -- f ) [ >bignum ] bi@ /f ; [ 5. ] [ 5 1 ratio>float ] unit-test [ 4. ] [ 4 1 ratio>float ] unit-test @@ -206,7 +206,7 @@ unit-test [ HEX: 3fe553522d230931 ] [ 61967020039 92984792073 ratio>float double>bits ] unit-test -: random-integer +: random-integer ( -- n ) 32 random-bits 1 random zero? [ neg ] when 1 random zero? [ >bignum ] when ; diff --git a/core/math/intervals/intervals-tests.factor b/core/math/intervals/intervals-tests.factor index ba728e67c0..82ec51b3f1 100755 --- a/core/math/intervals/intervals-tests.factor +++ b/core/math/intervals/intervals-tests.factor @@ -177,7 +177,7 @@ IN: math.intervals.tests { 3 [ (a,b] ] } } case ; -: random-op +: random-op ( -- pair ) { { + interval+ } { - interval- } @@ -192,7 +192,7 @@ IN: math.intervals.tests ] when random ; -: interval-test +: interval-test ( -- ? ) random-interval random-interval random-op ! 3dup . . . 0 pick interval-contains? over first { / /i } member? and [ 3drop t @@ -204,7 +204,7 @@ IN: math.intervals.tests [ t ] [ 40000 [ drop interval-test ] all? ] unit-test -: random-comparison +: random-comparison ( -- pair ) { { < interval< } { <= interval<= } @@ -212,7 +212,7 @@ IN: math.intervals.tests { >= interval>= } } random ; -: comparison-test +: comparison-test ( -- ? ) random-interval random-interval random-comparison [ >r [ random-element ] bi@ r> first execute ] 3keep second execute dup incomparable eq? [ diff --git a/core/math/intervals/intervals.factor b/core/math/intervals/intervals.factor index 324d628fd1..7d05196007 100755 --- a/core/math/intervals/intervals.factor +++ b/core/math/intervals/intervals.factor @@ -8,9 +8,9 @@ TUPLE: interval from to ; C: interval -: open-point f 2array ; +: open-point ( n -- endpoint ) f 2array ; -: closed-point t 2array ; +: closed-point ( n -- endpoint ) t 2array ; : [a,b] ( a b -- interval ) >r closed-point r> closed-point ; @@ -197,7 +197,8 @@ SYMBOL: incomparable [ interval-to ] bi@ = and and ; -: (interval<) over interval-from over interval-from endpoint< ; +: (interval<) ( i1 i2 -- i1 i2 ? ) + over interval-from over interval-from endpoint< ; : interval< ( i1 i2 -- ? ) { diff --git a/core/math/parser/parser.factor b/core/math/parser/parser.factor index d1b8e6fd37..5d048f0b8e 100755 --- a/core/math/parser/parser.factor +++ b/core/math/parser/parser.factor @@ -43,7 +43,7 @@ DEFER: base> SYMBOL: radix SYMBOL: negative? -: sign negative? get "-" "+" ? ; +: sign ( -- str ) negative? get "-" "+" ? ; : with-radix ( radix quot -- ) radix swap with-variable ; inline diff --git a/core/optimizer/control/control.factor b/core/optimizer/control/control.factor index 7ab0ffc806..f3f9f51991 100755 --- a/core/optimizer/control/control.factor +++ b/core/optimizer/control/control.factor @@ -161,7 +161,8 @@ SYMBOL: potential-loops } cond ] if ; -: fold-if-branch? dup node-in-d first known-boolean-value? ; +: fold-if-branch? ( node -- value ? ) + dup node-in-d first known-boolean-value? ; : fold-if-branch ( node value -- node' ) over drop-inputs >r @@ -214,7 +215,7 @@ SYMBOL: potential-loops : clone-node ( node -- newnode ) clone dup [ clone ] modify-values ; -: lift-branch +: lift-branch ( node tail -- ) over last-node clone-node dup node-in-d \ #merge out-node diff --git a/core/parser/parser-docs.factor b/core/parser/parser-docs.factor index 418278baee..1dc47432d3 100755 --- a/core/parser/parser-docs.factor +++ b/core/parser/parser-docs.factor @@ -188,7 +188,7 @@ $nl ABOUT: "parser" -: $parsing-note +: $parsing-note ( children -- ) drop "This word should only be called from parsing words." $notes ; @@ -431,9 +431,9 @@ HELP: lexer-factory { $var-description "A variable holding a quotation with stack effect " { $snippet "( lines -- lexer )" } ". This quotation is called by the parser to create " { $link lexer } " instances. This variable can be rebound to a quotation which outputs a custom tuple delegating to " { $link lexer } " to customize syntax." } ; HELP: parse-effect -{ $values { "effect" "an instance of " { $link effect } } } +{ $values { "end" string } { "effect" "an instance of " { $link effect } } } { $description "Parses a stack effect from the current input line." } -{ $examples "This word is used by " { $link POSTPONE: ( } " to parse stack effect declarations." } +{ $examples "This word is used by " { $link POSTPONE: ( } " and " { $link POSTPONE: (( } " to parse stack effect declarations." } $parsing-note ; HELP: parse-base diff --git a/core/parser/parser.factor b/core/parser/parser.factor index 46e93753b5..4484c2ae54 100755 --- a/core/parser/parser.factor +++ b/core/parser/parser.factor @@ -221,6 +221,8 @@ ERROR: unexpected want got ; PREDICATE: unexpected-eof < unexpected unexpected-got not ; +M: parsing-word stack-effect drop (( parsed -- parsed )) ; + : unexpected-eof ( word -- * ) f unexpected ; : (parse-tokens) ( accum end -- accum ) @@ -366,7 +368,7 @@ M: staging-violation summary { [ 2dup eq? ] [ 2drop f ] } { [ dup not ] [ drop unexpected-eof t ] } { [ dup delimiter? ] [ unexpected t ] } - { [ dup parsing? ] [ nip execute-parsing t ] } + { [ dup parsing-word? ] [ nip execute-parsing t ] } [ pick push drop t ] } cond ; @@ -393,15 +395,15 @@ SYMBOL: lexer-factory lexer-factory get call (parse-lines) ; ! Parsing word utilities -: parse-effect ( -- effect ) - ")" parse-tokens "(" over member? [ - "Stack effect declaration must not contain (" throw - ] [ +: parse-effect ( end -- effect ) + parse-tokens dup { "(" "((" } intersect empty? [ { "--" } split1 dup [ ] [ "Stack effect declaration must contain --" throw ] if + ] [ + "Stack effect declaration must not contain ( or ((" throw ] if ; ERROR: bad-number ; @@ -415,7 +417,7 @@ ERROR: bad-number ; : parse-definition ( -- quot ) \ ; parse-until >quotation ; -: (:) CREATE-WORD parse-definition ; +: (:) ( -- word def ) CREATE-WORD parse-definition ; SYMBOL: current-class SYMBOL: current-generic @@ -429,11 +431,11 @@ SYMBOL: current-generic r> call ] with-scope ; inline -: (M:) +: (M:) ( method def -- ) CREATE-METHOD [ parse-definition ] with-method-definition ; : scan-object ( -- object ) - scan-word dup parsing? + scan-word dup parsing-word? [ V{ } clone swap execute first ] when ; GENERIC: expected>string ( obj -- str ) diff --git a/core/prettyprint/backend/backend.factor b/core/prettyprint/backend/backend.factor index f992b9ca01..3df408cb10 100755 --- a/core/prettyprint/backend/backend.factor +++ b/core/prettyprint/backend/backend.factor @@ -5,11 +5,13 @@ hashtables io assocs kernel math namespaces sequences strings sbufs io.styles vectors words prettyprint.config prettyprint.sections quotations io io.files math.parser effects classes.tuple math.order classes.tuple.private classes -float-arrays ; +float-arrays combinators ; IN: prettyprint.backend GENERIC: pprint* ( obj -- ) +M: effect pprint* effect>string "(" swap ")" 3append text ; + : ?effect-height ( word -- n ) stack-effect [ effect-height ] [ 0 ] if* ; @@ -26,9 +28,11 @@ GENERIC: pprint* ( obj -- ) : word-style ( word -- style ) dup "word-style" word-prop >hashtable [ [ - dup presented set - dup parsing? over delimiter? rot t eq? or or - [ bold font-style set ] when + [ presented set ] + [ + [ parsing-word? ] [ delimiter? ] [ t eq? ] tri or or + [ bold font-style set ] when + ] bi ] bind ] keep ; @@ -43,13 +47,16 @@ GENERIC: pprint* ( obj -- ) ; inline M: word pprint* - dup parsing? [ + dup parsing-word? [ \ POSTPONE: [ pprint-word ] pprint-prefix ] [ - dup "break-before" word-prop line-break - dup pprint-word - dup ?start-group dup ?end-group - "break-after" word-prop line-break + { + [ "break-before" word-prop line-break ] + [ pprint-word ] + [ ?start-group ] + [ ?end-group ] + [ "break-after" word-prop line-break ] + } cleave ] if ; M: real pprint* number>string text ; diff --git a/core/prettyprint/prettyprint.factor b/core/prettyprint/prettyprint.factor index a3c3f4926b..1da7247a46 100755 --- a/core/prettyprint/prettyprint.factor +++ b/core/prettyprint/prettyprint.factor @@ -8,7 +8,7 @@ prettyprint.config sorting splitting math.parser vocabs definitions effects classes.builtin classes.tuple io.files classes continuations hashtables classes.mixin classes.union classes.intersection classes.predicate classes.singleton -combinators quotations sets ; +combinators quotations sets accessors ; : make-pprint ( obj quot -- block in use ) [ @@ -145,46 +145,51 @@ GENERIC: see ( defspec -- ) definer drop pprint-word ; : stack-effect. ( word -- ) - dup parsing? over symbol? or not swap stack-effect and + [ [ parsing-word? ] [ symbol? ] bi or not ] [ stack-effect ] bi and [ effect>string comment. ] when* ; : word-synopsis ( word -- ) - dup seeing-word - dup definer. - dup pprint-word - stack-effect. ; + { + [ seeing-word ] + [ definer. ] + [ pprint-word ] + [ stack-effect. ] + } cleave ; M: word synopsis* word-synopsis ; M: simple-generic synopsis* word-synopsis ; M: standard-generic synopsis* - dup definer. - dup seeing-word - dup pprint-word - dup dispatch# pprint* - stack-effect. ; + { + [ definer. ] + [ seeing-word ] + [ pprint-word ] + [ dispatch# pprint* ] + [ stack-effect. ] + } cleave ; M: hook-generic synopsis* - dup definer. - dup seeing-word - dup pprint-word - dup "combination" word-prop hook-combination-var pprint* - stack-effect. ; + { + [ definer. ] + [ seeing-word ] + [ pprint-word ] + [ "combination" word-prop hook-combination-var pprint* ] + [ stack-effect. ] + } cleave ; M: method-spec synopsis* first2 method synopsis* ; M: method-body synopsis* - dup dup - definer. - "method-class" word-prop pprint-word - "method-generic" word-prop pprint-word ; + [ definer. ] + [ "method-class" word-prop pprint-word ] + [ "method-generic" word-prop pprint-word ] tri ; M: mixin-instance synopsis* - dup definer. - dup mixin-instance-class pprint-word - mixin-instance-mixin pprint-word ; + [ definer. ] + [ class>> pprint-word ] + [ mixin>> pprint-word ] tri ; M: pathname synopsis* pprint* ; @@ -220,7 +225,7 @@ M: word declarations. POSTPONE: flushable } [ declaration. ] with each ; -: pprint-; \ ; pprint-word ; +: pprint-; ( -- ) \ ; pprint-word ; : (see) ( spec -- ) r dup empty-block? [ drop ] r> if ; inline -: ( ( ( ( slot-spec >r "accessors" create dup r> "declared-effect" set-word-prop ; -: reader-effect T{ effect f { "object" } { "value" } } ; inline - : reader-word ( name -- word ) - ">>" append reader-effect create-accessor ; + ">>" append (( object -- value )) create-accessor ; : define-reader ( class slot name -- ) reader-word object reader-quot define-slot-word ; -: writer-effect T{ effect f { "value" "object" } { } } ; inline - : writer-word ( name -- word ) - "(>>" swap ")" 3append writer-effect create-accessor ; + "(>>" swap ")" 3append (( value object -- )) create-accessor ; : define-writer ( class slot name -- ) writer-word [ set-slot ] define-slot-word ; -: setter-effect T{ effect f { "object" "value" } { "object" } } ; inline - : setter-word ( name -- word ) - ">>" prepend setter-effect create-accessor ; + ">>" prepend (( object value -- object )) create-accessor ; : define-setter ( name -- ) dup setter-word dup deferred? [ [ \ over , swap writer-word , ] [ ] make define-inline ] [ 2drop ] if ; -: changer-effect T{ effect f { "object" "quot" } { "object" } } ; inline - : changer-word ( name -- word ) - "change-" prepend changer-effect create-accessor ; + "change-" prepend (( object quot -- object )) create-accessor ; : define-changer ( name -- ) dup changer-word dup deferred? [ diff --git a/core/syntax/syntax-docs.factor b/core/syntax/syntax-docs.factor index 314d9697e7..d3db241575 100755 --- a/core/syntax/syntax-docs.factor +++ b/core/syntax/syntax-docs.factor @@ -413,7 +413,13 @@ HELP: ( { $syntax "( inputs -- outputs )" } { $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } } { $description "Declares the stack effect of the most recently defined word, storing a new " { $link effect } " instance in the " { $snippet "\"declared-effect\"" } " word property." } -{ $notes "Recursive words must have a declared stack effect to compile. See " { $link "effect-declaration" } " for details." } ; +{ $notes "Words must have a declared stack effect to compile. See " { $link "effect-declaration" } " for details." } ; + +HELP: (( +{ $syntax "(( inputs -- outputs ))" } +{ $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } } +{ $description "Literal stack effect syntax." } +{ $notes "Useful for meta-programming with " { $link define-declared } "." } ; HELP: ! { $syntax "! comment..." } diff --git a/core/syntax/syntax.factor b/core/syntax/syntax.factor index 27c8609a99..a0d601e2ad 100755 --- a/core/syntax/syntax.factor +++ b/core/syntax/syntax.factor @@ -182,10 +182,14 @@ IN: bootstrap.syntax ] define-syntax "(" [ - parse-effect word + ")" parse-effect word [ swap "declared-effect" set-word-prop ] [ drop ] if* ] define-syntax + "((" [ + "))" parse-effect parsed + ] define-syntax + "MAIN:" [ scan-word in get vocab set-vocab-main ] define-syntax "<<" [ diff --git a/core/threads/threads.factor b/core/threads/threads.factor index a1c7e208dc..c23ced42b9 100755 --- a/core/threads/threads.factor +++ b/core/threads/threads.factor @@ -37,11 +37,11 @@ mailbox variables sleep-entry ; : thread-registered? ( thread -- ? ) id>> threads key? ; -: check-unregistered +: check-unregistered ( thread -- thread ) dup thread-registered? [ "Thread already stopped" throw ] when ; -: check-registered +: check-registered ( thread -- thread ) dup thread-registered? [ "Thread is not running" throw ] unless ; diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor index 1489750154..04cf9a2ac1 100755 --- a/core/vocabs/loader/loader.factor +++ b/core/vocabs/loader/loader.factor @@ -50,18 +50,18 @@ H{ } clone root-cache set-global SYMBOL: load-help? -: source-was-loaded t swap set-vocab-source-loaded? ; +: source-was-loaded ( vocab -- ) t swap set-vocab-source-loaded? ; -: source-wasn't-loaded f swap set-vocab-source-loaded? ; +: source-wasn't-loaded ( vocab -- ) f swap set-vocab-source-loaded? ; : load-source ( vocab -- ) [ source-wasn't-loaded ] keep [ vocab-source-path [ bootstrap-file ] when* ] keep source-was-loaded ; -: docs-were-loaded t swap set-vocab-docs-loaded? ; +: docs-were-loaded ( vocab -- ) t swap set-vocab-docs-loaded? ; -: docs-weren't-loaded f swap set-vocab-docs-loaded? ; +: docs-weren't-loaded ( vocab -- ) f swap set-vocab-docs-loaded? ; : load-docs ( vocab -- ) load-help? get [ diff --git a/core/words/words-docs.factor b/core/words/words-docs.factor index 14e6197683..9699844192 100755 --- a/core/words/words-docs.factor +++ b/core/words/words-docs.factor @@ -334,7 +334,7 @@ HELP: bootstrap-word { $values { "word" word } { "target" word } } { $description "Looks up a word with the same name and vocabulary as the given word, performing a transformation to handle parsing words in the target dictionary. Used during bootstrap to transfer host words to the target dictionary." } ; -HELP: parsing? +HELP: parsing-word? { $values { "obj" object } { "?" "a boolean" } } { $description "Tests if an object is a parsing word declared by " { $link POSTPONE: parsing } "." } { $notes "Outputs " { $link f } " if the object is not a word." } ; diff --git a/core/words/words.factor b/core/words/words.factor index bc4b2ede72..7111c2789b 100755 --- a/core/words/words.factor +++ b/core/words/words.factor @@ -201,8 +201,7 @@ ERROR: bad-create name vocab ; : constructor-word ( name vocab -- word ) >r "<" swap ">" 3append r> create ; -: parsing? ( obj -- ? ) - dup word? [ "parsing" word-prop ] [ drop f ] if ; +PREDICATE: parsing-word < word "parsing" word-prop ; : delimiter? ( obj -- ? ) dup word? [ "delimiter" word-prop ] [ drop f ] if ; @@ -225,6 +224,6 @@ M: word hashcode* M: word literalize ; -: ?word-name dup word? [ word-name ] when ; +: ?word-name ( word -- name ) dup word? [ word-name ] when ; : xref-words ( -- ) all-words [ xref ] each ; diff --git a/extra/bootstrap/help/help.factor b/extra/bootstrap/help/help.factor index 9dd4fd04b2..e2a2288988 100755 --- a/extra/bootstrap/help/help.factor +++ b/extra/bootstrap/help/help.factor @@ -3,7 +3,7 @@ help.definitions io io.files kernel namespaces vocabs sequences parser vocabs.loader ; IN: bootstrap.help -: load-help +: load-help ( -- ) "alien.syntax" require "compiler" require diff --git a/extra/calendar/calendar.factor b/extra/calendar/calendar.factor index 0e21876fe9..f33e975c9a 100755 --- a/extra/calendar/calendar.factor +++ b/extra/calendar/calendar.factor @@ -3,7 +3,8 @@ USING: arrays kernel math math.functions namespaces sequences strings system vocabs.loader calendar.backend threads -accessors combinators locals classes.tuple math.order ; +accessors combinators locals classes.tuple math.order +memoize ; IN: calendar TUPLE: timestamp year month day hour minute second gmt-offset ; @@ -89,7 +90,7 @@ PRIVATE> : >time< ( timestamp -- hour minute second ) [ hour>> ] [ minute>> ] [ second>> ] tri ; -: instant ( -- dt ) 0 0 0 0 0 0 ; +MEMO: instant ( -- dt ) 0 0 0 0 0 0 ; : years ( n -- dt ) instant swap >>year ; : months ( n -- dt ) instant swap >>month ; : days ( n -- dt ) instant swap >>day ; @@ -273,7 +274,7 @@ M: timestamp time- M: duration time- before time+ ; -: 0 0 0 0 0 0 instant ; +MEMO: ( -- timestamp ) 0 0 0 0 0 0 instant ; : valid-timestamp? ( timestamp -- ? ) clone instant >>gmt-offset diff --git a/extra/cocoa/messages/messages.factor b/extra/cocoa/messages/messages.factor index f917e20bc4..624a6d802b 100755 --- a/extra/cocoa/messages/messages.factor +++ b/extra/cocoa/messages/messages.factor @@ -4,7 +4,7 @@ USING: alien alien.c-types alien.strings alien.compiler arrays assocs combinators compiler inference.transforms kernel math namespaces parser prettyprint prettyprint.sections quotations sequences strings words cocoa.runtime io macros -memoize debugger io.encodings.ascii ; +memoize debugger io.encodings.ascii effects ; IN: cocoa.messages : make-sender ( method function -- quot ) @@ -196,7 +196,8 @@ H{ : define-objc-class-word ( name quot -- ) [ over , , \ unless-defined , dup , \ objc-class , - ] [ ] make >r "cocoa.classes" create r> define ; + ] [ ] make >r "cocoa.classes" create r> + (( -- class )) define-declared ; : import-objc-class ( name quot -- ) 2dup unless-defined diff --git a/extra/concurrency/mailboxes/mailboxes.factor b/extra/concurrency/mailboxes/mailboxes.factor index 1f94e018c9..aa03d3d8ee 100755 --- a/extra/concurrency/mailboxes/mailboxes.factor +++ b/extra/concurrency/mailboxes/mailboxes.factor @@ -84,7 +84,8 @@ M: linked-error error. C: linked-error -: ?linked dup linked-error? [ rethrow ] when ; +: ?linked ( message -- message ) + dup linked-error? [ rethrow ] when ; TUPLE: linked-thread < thread supervisor ; diff --git a/extra/concurrency/messaging/messaging.factor b/extra/concurrency/messaging/messaging.factor index 66c5e421fa..e77760408c 100755 --- a/extra/concurrency/messaging/messaging.factor +++ b/extra/concurrency/messaging/messaging.factor @@ -17,7 +17,7 @@ GENERIC: send ( message thread -- ) M: thread send ( message thread -- ) check-registered mailbox-of mailbox-put ; -: my-mailbox self mailbox-of ; +: my-mailbox ( -- mailbox ) self mailbox-of ; : receive ( -- message ) my-mailbox mailbox-get ?linked ; diff --git a/extra/core-foundation/fsevents/fsevents.factor b/extra/core-foundation/fsevents/fsevents.factor index 261e1d045a..f14dba6433 100644 --- a/extra/core-foundation/fsevents/fsevents.factor +++ b/extra/core-foundation/fsevents/fsevents.factor @@ -149,7 +149,8 @@ FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef SYMBOL: event-stream-callbacks -: event-stream-counter \ event-stream-counter counter ; +: event-stream-counter ( -- n ) + \ event-stream-counter counter ; [ event-stream-callbacks global diff --git a/extra/documents/documents.factor b/extra/documents/documents.factor index 435a0aca55..c13f08c293 100755 --- a/extra/documents/documents.factor +++ b/extra/documents/documents.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006, 2007 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: arrays io kernel math models namespaces sequences strings -splitting combinators unicode.categories math.order ; +splitting combinators unicode.categories math.order accessors ; IN: documents : +col ( loc n -- newloc ) >r first2 r> + 2array ; @@ -20,9 +20,9 @@ TUPLE: document locs ; V{ "" } clone V{ } clone { set-delegate set-document-locs } document construct ; -: add-loc document-locs push ; +: add-loc ( loc document -- ) locs>> push ; -: remove-loc document-locs delete ; +: remove-loc ( loc document -- ) locs>> delete ; : update-locs ( loc document -- ) document-locs [ set-model ] with each ; @@ -178,7 +178,7 @@ M: one-char-elt next-elt 2drop ; >r >r first2 swap r> doc-line r> call r> =col ; inline -: ((word-elt)) [ ?nth blank? ] 2keep ; +: ((word-elt)) ( n seq -- ? n seq ) [ ?nth blank? ] 2keep ; : break-detector ( ? -- quot ) [ >r blank? r> xor ] curry ; inline diff --git a/extra/editors/editors.factor b/extra/editors/editors.factor index 25bd560d42..ec8313363e 100755 --- a/extra/editors/editors.factor +++ b/extra/editors/editors.factor @@ -51,9 +51,7 @@ M: object find-parse-error [ file>> path>> ] [ line>> ] bi edit-location ] when* ; -: fix ( word -- ) - [ "Fixing " write pprint " and all usages..." print nl ] - [ [ smart-usage ] keep prefix ] bi +: edit-each ( seq -- ) [ [ "Editing " write . ] [ @@ -63,3 +61,8 @@ M: object find-parse-error readln ] bi ] all? drop ; + +: fix ( word -- ) + [ "Fixing " write pprint " and all usages..." print nl ] + [ [ smart-usage ] keep prefix ] bi + edit-each ; diff --git a/extra/fry/fry.factor b/extra/fry/fry.factor index 4581c048fd..f15a6b24c2 100755 --- a/extra/fry/fry.factor +++ b/extra/fry/fry.factor @@ -5,9 +5,9 @@ quotations arrays namespaces qualified ; QUALIFIED: namespaces IN: fry -: , "Only valid inside a fry" throw ; -: @ "Only valid inside a fry" throw ; -: _ "Only valid inside a fry" throw ; +: , ( -- * ) "Only valid inside a fry" throw ; +: @ ( -- * ) "Only valid inside a fry" throw ; +: _ ( -- * ) "Only valid inside a fry" throw ; DEFER: (shallow-fry) diff --git a/extra/help/help.factor b/extra/help/help.factor index 75a14e645b..e7ad29a741 100755 --- a/extra/help/help.factor +++ b/extra/help/help.factor @@ -46,12 +46,12 @@ M: predicate word-help* drop \ $predicate ; M: word article-name word-name ; M: word article-title - dup parsing? over symbol? or [ + dup [ parsing-word? ] [ symbol? ] bi or [ word-name ] [ - dup word-name - swap stack-effect - [ effect>string " " swap 3append ] when* + [ word-name ] + [ stack-effect [ effect>string " " prepend ] [ "" if ] if* ] bi + append ] if ; M: word article-content @@ -114,15 +114,7 @@ M: word set-article-parent swap "help-parent" set-word-prop ; : $about ( element -- ) first vocab-help [ 1array $subsection ] when* ; -: (:help-multi) - "This error has multiple delegates:" print - ($index) nl - "Use \\ ... help to get help about a specific delegate." print ; - -: (:help-none) - drop "No help for this error. " print ; - -: (:help-debugger) +: :help-debugger ( -- ) nl "Debugger commands:" print nl @@ -135,12 +127,8 @@ M: word set-article-parent swap "help-parent" set-word-prop ; ":vars - list all variables at error time" print ; : :help ( -- ) - error get delegates [ error-help ] map sift - { - { [ dup empty? ] [ (:help-none) ] } - { [ dup length 1 = ] [ first help ] } - [ (:help-multi) ] - } cond (:help-debugger) ; + error get error-help [ help ] [ "No help for this error. " print ] if + :help-debugger ; : remove-article ( name -- ) dup articles get key? [ diff --git a/extra/help/markup/markup.factor b/extra/help/markup/markup.factor index 378dd1e2fe..32e4084150 100755 --- a/extra/help/markup/markup.factor +++ b/extra/help/markup/markup.factor @@ -22,8 +22,8 @@ SYMBOL: span SYMBOL: block SYMBOL: table -: last-span? last-element get span eq? ; -: last-block? last-element get block eq? ; +: last-span? ( -- ? ) last-element get span eq? ; +: last-block? ( -- ? ) last-element get block eq? ; : ($span) ( quot -- ) last-block? [ nl ] when @@ -58,18 +58,23 @@ M: f print-element drop ; ! Some spans -: $snippet [ snippet-style get print-element* ] ($span) ; +: $snippet ( children -- ) + [ snippet-style get print-element* ] ($span) ; -: $emphasis [ emphasis-style get print-element* ] ($span) ; +: $emphasis ( children -- ) + [ emphasis-style get print-element* ] ($span) ; -: $strong [ strong-style get print-element* ] ($span) ; +: $strong ( children -- ) + [ strong-style get print-element* ] ($span) ; -: $url [ url-style get print-element* ] ($span) ; +: $url ( children -- ) + [ url-style get print-element* ] ($span) ; -: $nl nl nl drop ; +: $nl ( children -- ) + nl nl drop ; ! Some blocks -: ($heading) +: ($heading) ( children quot -- ) last-element get [ nl ] when ($block) ; inline : $heading ( element -- ) @@ -230,7 +235,7 @@ M: word ($instance) M: string ($instance) dup a/an write bl $snippet ; -: $instance first ($instance) ; +: $instance ( children -- ) first ($instance) ; : values-row ( seq -- seq ) unclip \ $snippet swap ?word-name 2array @@ -278,18 +283,18 @@ M: string ($instance) drop "Shuffle word. Re-arranges the stack according to the stack effect pattern." $description ; -: $low-level-note +: $low-level-note ( children -- ) drop "Calling this word directly is not necessary in most cases. Higher-level words call it automatically." $notes ; -: $values-x/y +: $values-x/y ( children -- ) drop { { "x" number } { "y" number } } $values ; -: $io-error +: $io-error ( children -- ) drop "Throws an error if the I/O operation fails." $errors ; -: $prettyprinting-note +: $prettyprinting-note ( children -- ) drop { "This word should only be called from inside the " { $link with-pprint } " combinator." diff --git a/extra/html/elements/elements.factor b/extra/html/elements/elements.factor index 1c56ee8031..5fe26c2843 100644 --- a/extra/html/elements/elements.factor +++ b/extra/html/elements/elements.factor @@ -67,13 +67,11 @@ SYMBOL: html : "<" swap ">" 3append ; -: empty-effect T{ effect f 0 0 } ; - : def-for-html-word- ( name -- ) #! Return the name and code for the patterned #! word. dup swap [ write-html ] curry - empty-effect html-word ; + (( -- )) html-word ; : ">" append ; : def-for-html-word-foo> ( name -- ) #! Return the name and code for the foo> patterned #! word. - foo> [ ">" write-html ] empty-effect html-word ; + foo> [ ">" write-html ] (( -- )) html-word ; : "" 3append ; : def-for-html-word- ( name -- ) #! Return the name and code for the patterned #! word. - dup [ write-html ] curry empty-effect html-word ; + dup [ write-html ] curry (( -- )) html-word ; : "<" swap "/>" 3append ; @@ -103,14 +101,14 @@ SYMBOL: html #! Return the name and code for the patterned #! word. dup swap [ write-html ] curry - empty-effect html-word ; + (( -- )) html-word ; : foo/> "/>" append ; : def-for-html-word-foo/> ( name -- ) #! Return the name and code for the foo/> patterned #! word. - foo/> [ "/>" write-html ] empty-effect html-word ; + foo/> [ "/>" write-html ] (( -- )) html-word ; : define-closed-html-word ( name -- ) #! Given an HTML tag name, define the words for @@ -134,11 +132,9 @@ SYMBOL: html present escape-quoted-string write-html "'" write-html ; -: attribute-effect T{ effect f { "string" } 0 } ; - : define-attribute-word ( name -- ) dup "=" prepend swap - [ write-attr ] curry attribute-effect html-word ; + [ write-attr ] curry (( string -- )) html-word ; ! Define some closed HTML tags [ diff --git a/extra/io/encodings/8-bit/8-bit.factor b/extra/io/encodings/8-bit/8-bit.factor index a8cd1fea91..d4e6122321 100755 --- a/extra/io/encodings/8-bit/8-bit.factor +++ b/extra/io/encodings/8-bit/8-bit.factor @@ -68,7 +68,7 @@ M: 8-bit decode-char decode>> decode-8-bit ; : make-8-bit ( word byte>ch ch>byte -- ) - [ 8-bit boa ] 2curry dupd curry define ; + [ 2drop ] [ 8-bit boa ] 3bi [ ] curry define ; : define-8-bit-encoding ( name stream -- ) >r in get create r> parse-file make-8-bit ; diff --git a/extra/io/pipes/pipes.factor b/extra/io/pipes/pipes.factor index f98fa4b0d4..efdf999152 100644 --- a/extra/io/pipes/pipes.factor +++ b/extra/io/pipes/pipes.factor @@ -22,8 +22,11 @@ HOOK: (pipe) io-backend ( -- pipe ) &dispose ] [ input-stream get ] if* ; -: ?writer [ &dispose ] [ output-stream get ] if* ; +: ?reader ( handle/f -- stream ) + [ &dispose ] [ input-stream get ] if* ; + +: ?writer ( handle/f -- stream ) + [ &dispose ] [ output-stream get ] if* ; GENERIC: run-pipeline-element ( input-fd output-fd obj -- quot ) diff --git a/extra/io/sockets/sockets.factor b/extra/io/sockets/sockets.factor index c5dbded093..e94ca22660 100755 --- a/extra/io/sockets/sockets.factor +++ b/extra/io/sockets/sockets.factor @@ -80,7 +80,7 @@ M: inet4 make-sockaddr ( inet -- sockaddr ) SYMBOL: port-override -: (port) port-override get swap or ; +: (port) ( port -- port' ) port-override get swap or ; PRIVATE> diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 3b9c8fc7af..7f6b3396a1 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -62,7 +62,8 @@ USE: unix [ >r >r underlying-handle r> r> redirect ] } cond ; -: ?closed dup +closed+ eq? [ drop "/dev/null" ] when ; +: ?closed ( obj -- obj' ) + dup +closed+ eq? [ drop "/dev/null" ] when ; : setup-redirection ( process -- process ) dup stdin>> ?closed read-flags 0 redirect diff --git a/extra/io/unix/select/select.factor b/extra/io/unix/select/select.factor index fea5f4e9ae..5f127995c5 100755 --- a/extra/io/unix/select/select.factor +++ b/extra/io/unix/select/select.factor @@ -30,10 +30,10 @@ TUPLE: select-mx < mx read-fdset write-fdset ; : init-fdset ( fds fdset -- ) [ >r t swap munge r> set-nth ] curry each ; -: read-fdset/tasks +: read-fdset/tasks ( mx -- seq fdset ) [ reads>> keys ] [ read-fdset>> ] bi ; -: write-fdset/tasks +: write-fdset/tasks ( mx -- seq fdset ) [ writes>> keys ] [ write-fdset>> ] bi ; : max-fd ( assoc -- n ) diff --git a/extra/locals/locals.factor b/extra/locals/locals.factor index e74d0b6078..028502560f 100755 --- a/extra/locals/locals.factor +++ b/extra/locals/locals.factor @@ -146,7 +146,7 @@ GENERIC: lambda-rewrite* ( obj -- ) GENERIC: local-rewrite* ( obj -- ) -: lambda-rewrite +: lambda-rewrite ( quot -- quot' ) [ local-rewrite* ] [ ] make [ [ lambda-rewrite* ] each ] [ ] make ; @@ -273,7 +273,7 @@ M: wlet local-rewrite* let-rewrite ; : parse-locals ( -- vars assoc ) - parse-effect + ")" parse-effect word [ over "declared-effect" set-word-prop ] when* effect-in make-locals dup push-locals ; @@ -282,9 +282,9 @@ M: wlet local-rewrite* 2dup "lambda" set-word-prop lambda-rewrite first ; -: (::) CREATE-WORD parse-locals-definition ; +: (::) ( -- word def ) CREATE-WORD parse-locals-definition ; -: (M::) +: (M::) ( -- word def ) CREATE-METHOD [ parse-locals-definition ] with-method-definition ; diff --git a/extra/macros/macros.factor b/extra/macros/macros.factor index 88bfd01fbe..ccfc932406 100755 --- a/extra/macros/macros.factor +++ b/extra/macros/macros.factor @@ -30,6 +30,6 @@ M: macro reset-word : n*quot ( n seq -- seq' ) concat >quotation ; -: saver \ >r >quotation ; +: saver ( n -- quot ) \ >r >quotation ; -: restorer \ r> >quotation ; +: restorer ( n -- quot ) \ r> >quotation ; diff --git a/extra/match/match.factor b/extra/match/match.factor index c5a063ab98..8a174034ba 100755 --- a/extra/match/match.factor +++ b/extra/match/match.factor @@ -3,7 +3,7 @@ ! ! Based on pattern matching code from Paul Graham's book 'On Lisp'. USING: parser kernel words namespaces sequences classes.tuple -combinators macros assocs math ; +combinators macros assocs math effects ; IN: match SYMBOL: _ @@ -11,7 +11,7 @@ SYMBOL: _ : define-match-var ( name -- ) create-in dup t "match-var" set-word-prop - dup [ get ] curry define ; + dup [ get ] curry (( -- value )) define-declared ; : define-match-vars ( seq -- ) [ define-match-var ] each ; diff --git a/extra/math/functions/functions-tests.factor b/extra/math/functions/functions-tests.factor index 232fdb25b3..f2d26e330d 100755 --- a/extra/math/functions/functions-tests.factor +++ b/extra/math/functions/functions-tests.factor @@ -73,7 +73,7 @@ IN: math.functions.tests gcd nip ] unit-test -: verify-gcd +: verify-gcd ( a b -- ? ) 2dup gcd >r rot * swap rem r> = ; diff --git a/extra/memoize/memoize.factor b/extra/memoize/memoize.factor index 1c0491a7ab..aa6ebb532c 100755 --- a/extra/memoize/memoize.factor +++ b/extra/memoize/memoize.factor @@ -59,5 +59,5 @@ M: memoized reset-word : reset-memoized ( word -- ) "memoize" word-prop clear-assoc ; -: invalidate-memoized ! ( inputs... word ) +: invalidate-memoized ( inputs... word -- ) [ #in packer call ] [ "memoize" word-prop delete-at ] bi ; diff --git a/extra/models/models.factor b/extra/models/models.factor index 7a0b4b532a..2caf6e9940 100755 --- a/extra/models/models.factor +++ b/extra/models/models.factor @@ -156,7 +156,7 @@ TUPLE: history back forward ; : ( value -- history ) history construct-model dup reset-history ; -: (add-history) +: (add-history) ( history to -- ) swap model-value dup [ swap push ] [ 2drop ] if ; : go-back/forward ( history to from -- ) diff --git a/extra/opengl/opengl.factor b/extra/opengl/opengl.factor index 79470131f3..5fed709253 100755 --- a/extra/opengl/opengl.factor +++ b/extra/opengl/opengl.factor @@ -8,9 +8,11 @@ math.parser opengl.gl opengl.glu combinators arrays sequences splitting words byte-arrays assocs combinators.lib ; IN: opengl -: coordinates [ first2 ] bi@ ; +: coordinates ( point1 point2 -- x1 y2 x2 y2 ) + [ first2 ] bi@ ; -: fix-coordinates [ first2 [ >fixnum ] bi@ ] bi@ ; +: fix-coordinates ( point1 point2 -- x1 y2 x2 y2 ) + [ first2 [ >fixnum ] bi@ ] bi@ ; : gl-color ( color -- ) first4 glColor4d ; inline @@ -73,7 +75,8 @@ MACRO: all-enabled-client-state ( seq quot -- ) >r { 0.5 0.5 } v+ r> { 0.5 0.5 } v- gl-fill-rect GL_FRONT_AND_BACK GL_FILL glPolygonMode ; -: (gl-poly) [ [ gl-vertex ] each ] do-state ; +: (gl-poly) ( points state -- ) + [ [ gl-vertex ] each ] do-state ; : gl-fill-poly ( points -- ) dup length 2 > GL_POLYGON GL_LINES ? (gl-poly) ; @@ -81,13 +84,17 @@ MACRO: all-enabled-client-state ( seq quot -- ) : gl-poly ( points -- ) GL_LINE_LOOP (gl-poly) ; -: circle-steps dup length v/n 2 pi * v*n ; +: circle-steps ( steps -- angles ) + dup length v/n 2 pi * v*n ; -: unit-circle dup [ sin ] map swap [ cos ] map ; +: unit-circle ( angles -- points1 points2 ) + [ [ sin ] map ] [ [ cos ] map ] bi ; -: adjust-points [ [ 1 + 0.5 * ] map ] bi@ ; +: adjust-points ( points1 points2 -- points1' points2' ) + [ [ 1 + 0.5 * ] map ] bi@ ; -: scale-points zip [ v* ] with map [ v+ ] with map ; +: scale-points ( loc dim points1 points2 -- points ) + zip [ v* ] with map [ v+ ] with map ; : circle-points ( loc dim steps -- points ) circle-steps unit-circle adjust-points scale-points ; @@ -161,9 +168,9 @@ TUPLE: sprite loc dim dim2 dlist texture ; : ( loc dim dim2 -- sprite ) f f sprite boa ; -: sprite-size2 sprite-dim2 first2 ; +: sprite-size2 ( sprite -- w h ) sprite-dim2 first2 ; -: sprite-width sprite-dim first ; +: sprite-width ( sprite -- w ) sprite-dim first ; : gray-texture ( sprite pixmap -- id ) gen-texture [ diff --git a/extra/openssl/openssl.factor b/extra/openssl/openssl.factor index 28fa49dfce..b2dbda7d2e 100755 --- a/extra/openssl/openssl.factor +++ b/extra/openssl/openssl.factor @@ -105,7 +105,7 @@ TUPLE: openssl-context < secure-context aliens ; TUPLE: bio handle disposed ; -: f bio boa ; +: ( handle -- bio ) f bio boa ; M: bio dispose* handle>> BIO_free ssl-error ; @@ -121,7 +121,7 @@ M: bio dispose* handle>> BIO_free ssl-error ; TUPLE: rsa handle disposed ; -: f rsa boa ; +: ( handle -- rsa ) f rsa boa ; M: rsa dispose* handle>> RSA_free ; diff --git a/extra/optimizer/debugger/debugger.factor b/extra/optimizer/debugger/debugger.factor index fa35534439..ac7080d451 100755 --- a/extra/optimizer/debugger/debugger.factor +++ b/extra/optimizer/debugger/debugger.factor @@ -4,7 +4,7 @@ USING: classes inference inference.dataflow io kernel kernel.private math.parser namespaces optimizer prettyprint prettyprint.backend sequences words arrays match macros assocs sequences.private optimizer.specializers generic -combinators sorting math quotations ; +combinators sorting math quotations accessors ; IN: optimizer.debugger ! A simple tool for turning dataflow IR into quotations, for @@ -33,11 +33,11 @@ M: comment pprint* : effect-str ( node -- str ) [ - " " over node-in-d values% - " r: " over node-in-r values% + " " over in-d>> values% + " r: " over in-r>> values% " --" % - " " over node-out-d values% - " r: " swap node-out-r values% + " " over out-d>> values% + " r: " swap out-r>> values% ] "" make rest ; MACRO: match-choose ( alist -- ) @@ -63,18 +63,19 @@ MATCH-VARS: ?a ?b ?c ; } match-choose ; M: #shuffle node>quot - dup node-in-d over node-out-d pretty-shuffle + dup [ in-d>> ] [ out-d>> ] bi pretty-shuffle [ , ] [ >r drop t r> ] if* dup effect-str "#shuffle: " prepend comment, ; -: pushed-literals node-out-d [ value-literal literalize ] map ; +: pushed-literals ( node -- seq ) + out-d>> [ value-literal literalize ] map ; M: #push node>quot nip pushed-literals % ; DEFER: dataflow>quot : #call>quot ( ? node -- ) - dup node-param dup , + dup param>> dup , [ dup effect-str ] [ "empty call" ] if comment, ; M: #call node>quot #call>quot ; @@ -83,38 +84,38 @@ M: #call-label node>quot #call>quot ; M: #label node>quot [ - dup node-param literalize , + dup param>> literalize , dup #label-loop? "#loop: " "#label: " ? - over node-param word-name append comment, + over param>> word-name append comment, ] 2keep node-child swap dataflow>quot , \ call , ; M: #if node>quot [ "#if" comment, ] 2keep - node-children swap [ dataflow>quot ] curry map % + children>> swap [ dataflow>quot ] curry map % \ if , ; M: #dispatch node>quot [ "#dispatch" comment, ] 2keep - node-children swap [ dataflow>quot ] curry map , + children>> swap [ dataflow>quot ] curry map , \ dispatch , ; -M: #>r node>quot nip node-in-d length \ >r % ; +M: #>r node>quot nip in-d>> length \ >r % ; -M: #r> node>quot nip node-out-d length \ r> % ; +M: #r> node>quot nip out-d>> length \ r> % ; M: object node>quot [ dup class word-name % " " % - dup node-param unparse % + dup param>> unparse % " " % dup effect-str % ] "" make comment, ; : (dataflow>quot) ( ? node -- ) dup [ - 2dup node>quot node-successor (dataflow>quot) + 2dup node>quot successor>> (dataflow>quot) ] [ 2drop ] if ; @@ -145,7 +146,7 @@ SYMBOL: node-count 0 swap [ >r 1+ r> dup #call? [ - node-param { + param>> { { [ dup "intrinsics" word-prop over "if-intrinsics" word-prop or ] [ intrinsics-called ] } { [ dup generic? ] [ generics-called ] } { [ dup method-body? ] [ methods-called ] } diff --git a/extra/qualified/qualified.factor b/extra/qualified/qualified.factor index 3ce6d30819..5810a03f80 100644 --- a/extra/qualified/qualified.factor +++ b/extra/qualified/qualified.factor @@ -15,7 +15,7 @@ IN: qualified #! Syntax: QUALIFIED-WITH: vocab prefix scan scan define-qualified ; parsing -: expect=> scan "=>" assert= ; +: expect=> ( -- ) scan "=>" assert= ; : partial-vocab ( words name -- assoc ) dupd [ diff --git a/extra/sequences/lib/lib.factor b/extra/sequences/lib/lib.factor index 5c34b7315b..265cd5b592 100755 --- a/extra/sequences/lib/lib.factor +++ b/extra/sequences/lib/lib.factor @@ -102,9 +102,9 @@ MACRO: firstn ( n -- ) ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: ,, building get peek push ; -: v, V{ } clone , ; -: ,v building get dup peek empty? [ dup pop* ] when drop ; +: ,, ( obj -- ) building get peek push ; +: v, ( -- ) V{ } clone , ; +: ,v ( -- ) building get dup peek empty? [ dup pop* ] when drop ; : monotonic-split ( seq quot -- newseq ) [ diff --git a/extra/tools/deploy/backend/backend.factor b/extra/tools/deploy/backend/backend.factor index 6c5f7e7775..8973b2ea2a 100755 --- a/extra/tools/deploy/backend/backend.factor +++ b/extra/tools/deploy/backend/backend.factor @@ -40,16 +40,14 @@ IN: tools.deploy.backend my-boot-image-name resource-path exists? [ my-arch make-image ] unless ; -: ?, [ , ] [ drop ] if ; - : bootstrap-profile ( -- profile ) - [ - "math" deploy-math? get ?, - "compiler" deploy-compiler? get ?, - "ui" deploy-ui? get ?, - "io" native-io? ?, - "random" deploy-random? get ?, - ] { } make ; + { + { "math" deploy-math? } + { "compiler" deploy-compiler? } + { "ui" deploy-ui? } + { "random" deploy-random? } + } [ nip get ] assoc-filter keys + native-io? [ "io" suffix ] when ; : staging-image-name ( profile -- name ) "staging." diff --git a/extra/tools/deploy/config/config.factor b/extra/tools/deploy/config/config.factor index 589d6c613b..065db4d8c1 100755 --- a/extra/tools/deploy/config/config.factor +++ b/extra/tools/deploy/config/config.factor @@ -22,9 +22,9 @@ SYMBOL: deploy-io { 3 "Level 3 - Non-blocking streams and networking" } } ; -: strip-io? deploy-io get 1 = ; +: strip-io? ( -- ? ) deploy-io get 1 = ; -: native-io? deploy-io get 3 = ; +: native-io? ( -- ? ) deploy-io get 3 = ; SYMBOL: deploy-reflection @@ -38,11 +38,11 @@ SYMBOL: deploy-reflection { 6 "Level 6 - Full environment" } } ; -: strip-word-names? deploy-reflection get 2 < ; -: strip-prettyprint? deploy-reflection get 3 < ; -: strip-debugger? deploy-reflection get 4 < ; -: strip-dictionary? deploy-reflection get 5 < ; -: strip-globals? deploy-reflection get 6 < ; +: strip-word-names? ( -- ? ) deploy-reflection get 2 < ; +: strip-prettyprint? ( -- ? ) deploy-reflection get 3 < ; +: strip-debugger? ( -- ? ) deploy-reflection get 4 < ; +: strip-dictionary? ( -- ? ) deploy-reflection get 5 < ; +: strip-globals? ( -- ? ) deploy-reflection get 6 < ; SYMBOL: deploy-word-props? SYMBOL: deploy-word-defs? diff --git a/extra/tools/disassembler/disassembler.factor b/extra/tools/disassembler/disassembler.factor index 39ee85b07a..a7d9da4840 100755 --- a/extra/tools/disassembler/disassembler.factor +++ b/extra/tools/disassembler/disassembler.factor @@ -6,9 +6,9 @@ system math generator.fixup io.encodings.ascii accessors generic ; IN: tools.disassembler -: in-file "gdb-in.txt" temp-file ; +: in-file ( -- path ) "gdb-in.txt" temp-file ; -: out-file "gdb-out.txt" temp-file ; +: out-file ( -- path ) "gdb-out.txt" temp-file ; GENERIC: make-disassemble-cmd ( obj -- ) diff --git a/extra/tools/walker/walker.factor b/extra/tools/walker/walker.factor index 2417e7ac39..41f9f8066d 100755 --- a/extra/tools/walker/walker.factor +++ b/extra/tools/walker/walker.factor @@ -64,9 +64,9 @@ M: object add-breakpoint ; : (step-into-quot) ( quot -- ) add-breakpoint call ; -: (step-into-if) ? (step-into-quot) ; +: (step-into-if) ( true false ? -- ) ? (step-into-quot) ; -: (step-into-dispatch) nth (step-into-quot) ; +: (step-into-dispatch) ( array n -- ) nth (step-into-quot) ; : (step-into-execute) ( word -- ) { @@ -80,7 +80,7 @@ M: object add-breakpoint ; \ (step-into-execute) t "step-into?" set-word-prop -: (step-into-continuation) +: (step-into-continuation) ( -- ) continuation callstack >>call break ; ! Messages sent to walker thread @@ -260,4 +260,4 @@ SYMBOL: +stopped+ ! For convenience IN: syntax -: B break ; +: B ( -- ) break ; diff --git a/extra/ui/clipboards/clipboards.factor b/extra/ui/clipboards/clipboards.factor index ab6cc35d8c..4ee54cd833 100644 --- a/extra/ui/clipboards/clipboards.factor +++ b/extra/ui/clipboards/clipboards.factor @@ -5,7 +5,7 @@ IN: ui.clipboards ! Two text transfer buffers TUPLE: clipboard contents ; -: "" clipboard boa ; +: ( -- clipboard ) "" clipboard boa ; GENERIC: paste-clipboard ( gadget clipboard -- ) @@ -26,6 +26,6 @@ SYMBOL: selection 2drop ] if ; -: com-copy clipboard get gadget-copy ; +: com-copy ( gadget -- ) clipboard get gadget-copy ; -: com-copy-selection selection get gadget-copy ; +: com-copy-selection ( gadget -- ) selection get gadget-copy ; diff --git a/extra/ui/commands/commands-docs.factor b/extra/ui/commands/commands-docs.factor index 5ff0752c19..83628cc171 100644 --- a/extra/ui/commands/commands-docs.factor +++ b/extra/ui/commands/commands-docs.factor @@ -3,13 +3,17 @@ hashtables quotations words classes sequences namespaces arrays assocs ; IN: ui.commands -: command-map-row +: command-map-row ( children -- seq ) [ - dup first gesture>string , - second dup command-name , - dup command-word \ $link swap 2array , - command-description , - ] [ ] make ; + [ first gesture>string , ] + [ + second + [ command-name , ] + [ command-word \ $link swap 2array , ] + [ command-description , ] + tri + ] bi + ] { } make ; : command-map. ( command-map -- ) [ command-map-row ] map @@ -18,10 +22,11 @@ IN: ui.commands $table ; : $command-map ( element -- ) - first2 - dup (command-name) " commands" append $heading - swap command-map - dup command-map-blurb print-element command-map. ; + [ second (command-name) " commands" append $heading ] + [ + first2 swap command-map + [ command-map-blurb print-element ] [ command-map. ] bi + ] bi ; : $command ( element -- ) reverse first3 command-map value-at gesture>string $snippet ; diff --git a/extra/ui/gadgets/buttons/buttons.factor b/extra/ui/gadgets/buttons/buttons.factor index 9910082ebf..e452e6c455 100755 --- a/extra/ui/gadgets/buttons/buttons.factor +++ b/extra/ui/gadgets/buttons/buttons.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays ui.commands ui.gadgets ui.gadgets.borders +USING: accessors arrays ui.commands ui.gadgets ui.gadgets.borders ui.gadgets.labels ui.gadgets.theme ui.gadgets.tracks ui.gadgets.packs ui.gadgets.worlds ui.gestures ui.render kernel math models namespaces sequences strings @@ -48,7 +48,8 @@ TUPLE: button-paint plain rollover pressed selected ; C: button-paint -: find-button [ [ button? ] is? ] find-parent ; +: find-button ( gadget -- button ) + [ [ button? ] is? ] find-parent ; : button-paint ( button paint -- button paint ) over find-button { @@ -126,10 +127,11 @@ M: checkmark-paint draw-interior : toggle-model ( model -- ) [ not ] change-model ; -: checkbox-theme - f over set-gadget-interior - { 5 5 } over set-pack-gap - 1/2 swap set-pack-align ; +: checkbox-theme ( gadget -- ) + f >>interior + { 5 5 } >>gap + 1/2 >>align + drop ; TUPLE: checkbox ; @@ -187,16 +189,18 @@ M: radio-control model-changed #! quot has stack effect ( value model label -- ) swapd [ swapd call gadget, ] 2curry assoc-each ; inline -: radio-button-theme - { 5 5 } over set-pack-gap 1/2 swap set-pack-align ; +: radio-button-theme ( gadget -- ) + { 5 5 } >>gap + 1/2 >>align + drop ; : ( value model label -- gadget ) label-on-right [ +

- Delete + Delete diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index 19153e1354..5859d616ee 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -2,6 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences accessors namespaces combinators words assocs db.tuples arrays splitting strings validators urls +html.forms html.elements html.components furnace @@ -26,10 +27,19 @@ TUPLE: user-admin < dispatcher ; : init-capabilities ( -- ) capabilities get words>strings "capabilities" set-value ; -: selected-capabilities ( -- seq ) +: validate-capabilities ( -- ) "capabilities" value - [ param empty? not ] filter - [ string>word ] map ; + [ [ param empty? not ] keep set-value ] each ; + +: selected-capabilities ( -- seq ) + "capabilities" value [ value ] filter [ string>word ] map ; + +: validate-user ( -- ) + { + { "username" [ v-username ] } + { "realname" [ [ v-one-line ] v-optional ] } + { "email" [ [ v-email ] v-optional ] } + } validate-params ; : ( -- action ) @@ -42,14 +52,13 @@ TUPLE: user-admin < dispatcher ; [ init-capabilities + validate-capabilities + + validate-user { - { "username" [ v-username ] } - { "realname" [ v-one-line ] } { "new-password" [ v-password ] } { "verify-password" [ v-password ] } - { "email" [ [ v-email ] v-optional ] } - { "capabilities" [ ] } } validate-params same-password-twice @@ -74,14 +83,16 @@ TUPLE: user-admin < dispatcher ; : validate-username ( -- ) { { "username" [ v-username ] } } validate-params ; +: select-capabilities ( seq -- ) + [ t swap word>string set-value ] each ; + : ( -- action ) [ validate-username "username" value select-tuple - [ from-object ] - [ capabilities>> [ "true" swap word>string set-value ] each ] bi + [ from-object ] [ capabilities>> select-capabilities ] bi init-capabilities ] >>init @@ -89,14 +100,17 @@ TUPLE: user-admin < dispatcher ; { user-admin "edit-user" } >>template [ + "username" value select-tuple + [ from-object ] [ capabilities>> select-capabilities ] bi + init-capabilities + validate-capabilities + + validate-user { - { "username" [ v-username ] } - { "realname" [ v-one-line ] } { "new-password" [ [ v-password ] v-optional ] } { "verify-password" [ [ v-password ] v-optional ] } - { "email" [ [ v-email ] v-optional ] } } validate-params "new-password" "verify-password" From ac4f180857d4dab42ee4123ee4236c34fb239849 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 03:25:36 -0500 Subject: [PATCH 0225/1850] Fix load errors --- extra/webapps/wee-url/wee-url.factor | 2 +- extra/webapps/wiki/wiki.factor | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/extra/webapps/wee-url/wee-url.factor b/extra/webapps/wee-url/wee-url.factor index 29c4a60bef..2396e98b2a 100644 --- a/extra/webapps/wee-url/wee-url.factor +++ b/extra/webapps/wee-url/wee-url.factor @@ -3,7 +3,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: math.ranges sequences random accessors combinators.lib kernel namespaces fry db.types db.tuples urls validators -html.components http http.server.dispatchers furnace +html.components html.forms http http.server.dispatchers furnace furnace.actions furnace.boilerplate ; IN: webapps.wee-url diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 8dd62c8761..3183b48da9 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -2,7 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel hashtables calendar namespaces splitting sequences sorting math.order present -html.components syndication +syndication +html.components html.forms http.server http.server.dispatchers furnace From 10a87fc0afd0c671350f7cbedd9f1dd57a8cdf2f Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 03:25:41 -0500 Subject: [PATCH 0226/1850] Fix compile errors --- extra/xmode/catalog/catalog.factor | 2 +- extra/xmode/loader/loader.factor | 8 ++++---- extra/xmode/loader/syntax/syntax.factor | 2 +- extra/xmode/utilities/utilities.factor | 3 +-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/extra/xmode/catalog/catalog.factor b/extra/xmode/catalog/catalog.factor index 8c6025f726..98276caf83 100755 --- a/extra/xmode/catalog/catalog.factor +++ b/extra/xmode/catalog/catalog.factor @@ -5,7 +5,7 @@ IN: xmode.catalog TUPLE: mode file file-name-glob first-line-glob ; -r diff --git a/extra/xmode/loader/loader.factor b/extra/xmode/loader/loader.factor index 5cf3675941..8039db0ac9 100755 --- a/extra/xmode/loader/loader.factor +++ b/extra/xmode/loader/loader.factor @@ -7,15 +7,15 @@ IN: xmode.loader ! Based on org.gjt.sp.jedit.XModeHandler ! RULES and its children -number swap set-rule-set-terminate-char ; RULE: SEQ seq-rule diff --git a/extra/xmode/loader/syntax/syntax.factor b/extra/xmode/loader/syntax/syntax.factor index 175c8ed22f..b3adf5cb60 100644 --- a/extra/xmode/loader/syntax/syntax.factor +++ b/extra/xmode/loader/syntax/syntax.factor @@ -75,7 +75,7 @@ SYMBOL: ignore-case? [ parse-literal-matcher swap set-rule-end ] , ; ! SPAN's children - tag-handler-word get tag-handlers get >alist [ >r dup name-tag r> case ] curry - (( tag -- )) define-declared ; parsing + define ; parsing From 2b413f1eb7e1453c6fdc9384fe1ade468d77c0e0 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 04:56:15 -0500 Subject: [PATCH 0227/1850] Add request timing --- extra/http/server/server.factor | 27 ++++++++++++++++++--------- extra/io/server/server.factor | 10 +++++----- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 03822ec854..dc66cb1507 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors sequences arrays namespaces splitting vocabs.loader destructors assocs debugger continuations -combinators tools.vocabs math +combinators tools.vocabs tools.time math io io.server io.sockets @@ -26,7 +26,9 @@ SYMBOL: responder-nesting SYMBOL: main-responder -SYMBOL: development-mode +SYMBOL: development? + +SYMBOL: benchmark? ! path is a sequence of path component strings GENERIC: call-responder* ( path responder -- response ) @@ -55,7 +57,7 @@ main-responder global [ <404> or ] change-at : <500> ( error -- response ) 500 "Internal server error" - swap development-mode get [ '[ , http-error. ] >>body ] [ drop ] if ; + swap development? get [ '[ , http-error. ] >>body ] [ drop ] if ; : do-response ( response -- ) [ write-response ] @@ -69,7 +71,7 @@ main-responder global [ <404> or ] change-at ] [ utf8 [ - development-mode get + development? get [ http-error. ] [ drop "Response error" rethrow ] if ] with-encoded-output ] recover @@ -84,7 +86,7 @@ LOG: httpd-header NOTICE tuck header 2array httpd-header ; : log-request ( request -- ) - [ [ method>> ] [ url>> [ host>> ] [ path>> ] bi ] bi 3array httpd-hit ] + [ [ method>> ] [ url>> ] bi 2array httpd-hit ] [ { "user-agent" "x-forwarded-for" } [ log-header ] with each ] bi ; @@ -121,13 +123,20 @@ LOG: httpd-header NOTICE ] [ [ \ do-request log-error ] [ <500> ] bi ] recover ; : ?refresh-all ( -- ) - development-mode get-global - [ global [ refresh-all ] bind ] when ; + development? get-global [ global [ refresh-all ] bind ] when ; : setup-limits ( -- ) 1 minutes timeouts 64 1024 * limit-input ; +LOG: httpd-benchmark DEBUG + +: ?benchmark ( quot -- ) + benchmark? get [ + [ benchmark ] [ first ] bi request get url>> rot 3array + httpd-benchmark + ] [ call ] if ; inline + : handle-client ( -- ) [ setup-limits @@ -135,8 +144,8 @@ LOG: httpd-header NOTICE ascii encode-output ?refresh-all read-request - do-request - do-response + [ do-request ] ?benchmark + [ do-response ] ?benchmark ] with-destructors ; : httpd ( port -- ) diff --git a/extra/io/server/server.factor b/extra/io/server/server.factor index c855fba6be..e975880a14 100755 --- a/extra/io/server/server.factor +++ b/extra/io/server/server.factor @@ -4,7 +4,7 @@ USING: io io.sockets io.sockets.secure io.files io.streams.duplex logging continuations destructors kernel math math.parser namespaces parser sequences strings prettyprint debugger quotations calendar threads concurrency.combinators -assocs fry accessors ; +assocs fry accessors arrays ; IN: io.server SYMBOL: servers @@ -17,13 +17,13 @@ LOG: accepted-connection NOTICE : with-connection ( client remote local quot -- ) '[ - , [ remote-address set ] [ accepted-connection ] bi - , local-address set + , , + [ [ remote-address set ] [ local-address set ] bi* ] + [ 2array accepted-connection ] + 2bi @ ] with-stream ; inline -\ with-connection DEBUG add-error-logging - : accept-loop ( server quot -- ) [ [ [ accept ] [ addr>> ] bi ] dip From 52297bcfeb0df86b332f907b590a0842709d49ae Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 04:56:35 -0500 Subject: [PATCH 0228/1850] Add some simple markup inheritance --- extra/furnace/boilerplate/boilerplate.factor | 13 ++++++++++--- extra/webapps/wiki/wiki-common.xml | 19 ++++++++++++++++++- extra/webapps/wiki/wiki.factor | 9 +++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/extra/furnace/boilerplate/boilerplate.factor b/extra/furnace/boilerplate/boilerplate.factor index 7c5b7a0c81..a976199661 100644 --- a/extra/furnace/boilerplate/boilerplate.factor +++ b/extra/furnace/boilerplate/boilerplate.factor @@ -1,19 +1,26 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel namespaces -html.templates html.templates.chloe +html.forms +html.templates +html.templates.chloe locals http.server http.server.filters furnace ; IN: furnace.boilerplate -TUPLE: boilerplate < filter-responder template ; +TUPLE: boilerplate < filter-responder template init ; -: ( responder -- boilerplate ) f boilerplate boa ; +: ( responder -- boilerplate ) + boilerplate new + swap >>responder + [ ] >>init ; M:: boilerplate call-responder* ( path responder -- ) + begin-form path responder call-next-method + responder init>> call dup content-type>> "text/html" = [ clone [| body | [ diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml index 4c6d1a5b5c..1d08d3832d 100644 --- a/extra/webapps/wiki/wiki-common.xml +++ b/extra/webapps/wiki/wiki-common.xml @@ -28,6 +28,23 @@

- + + + + + + + +
+ +

+ + + +

+ + +
+
diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 3183b48da9..ebaa60777f 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -78,6 +78,10 @@ M: revision feed-entry-url id>> revision-url ; [ "Front Page" view-url ] >>display ; +: latest-revision ( title -- revision/f ) +
select-tuple + dup [ revision>> select-tuple ] when ; + : ( -- action ) @@ -88,8 +92,8 @@ M: revision feed-entry-url id>> revision-url ; ] >>init [ - "title" value dup
select-tuple [ - revision>> select-tuple from-object + "title" value dup latest-revision [ + from-object { wiki "view" } ] [ edit-url @@ -297,4 +301,5 @@ M: revision feed-entry-url id>> revision-url ; "changes.atom" add-responder "delete" add-responder + [ "sidebar" [ "Sidebar" latest-revision from-object ] nest-form ] >>init { wiki "wiki-common" } >>template ; From 56bb1604f0dd1baba733a6e49def22551022f8a2 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 18:29:10 -0500 Subject: [PATCH 0229/1850] Fix load errors --- extra/html/templates/chloe/chloe-tests.factor | 6 +++--- extra/webapps/counter/counter.factor | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/html/templates/chloe/chloe-tests.factor b/extra/html/templates/chloe/chloe-tests.factor index 87ba37ed9e..4048836cfe 100644 --- a/extra/html/templates/chloe/chloe-tests.factor +++ b/extra/html/templates/chloe/chloe-tests.factor @@ -1,7 +1,7 @@ USING: html.templates html.templates.chloe tools.test io.streams.string kernel sequences ascii boxes -namespaces xml html.components -splitting unicode.categories furnace ; +namespaces xml html.components html.forms +splitting unicode.categories furnace accessors ; IN: html.templates.chloe.tests [ f ] [ f parse-query-attr ] unit-test @@ -160,7 +160,7 @@ TUPLE: person first-name last-name ; [ ] [ begin-form ] unit-test [ ] [ - H{ { "first-name" "RBaxter" } { "last-name" "Unknown" } } "person" set-value + H{ { "first-name" "RBaxter" } { "last-name" "Unknown" } } >>values "person" set-value ] unit-test [ "
RBaxterUnknown
" ] [ diff --git a/extra/webapps/counter/counter.factor b/extra/webapps/counter/counter.factor index da646fb76f..30c5d403de 100644 --- a/extra/webapps/counter/counter.factor +++ b/extra/webapps/counter/counter.factor @@ -1,6 +1,6 @@ USING: math kernel accessors http.server http.server.dispatchers furnace furnace.actions furnace.sessions -html.components html.templates.chloe +html.components html.forms html.templates.chloe fry urls ; IN: webapps.counter From dbe095a84d6b3dbd954aff510116df2ac04c352c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 21:57:41 -0500 Subject: [PATCH 0230/1850] Fix revisions --- extra/webapps/wiki/wiki.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index ebaa60777f..34bad6db18 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -236,8 +236,8 @@ M: revision feed-entry-url id>> revision-url ; "old-id" "new-id" [ value select-tuple ] bi@ [ - [ [ title>> "title" set-value ] [ "old" set-value ] bi ] - [ "new" set-value ] bi* + [ [ title>> "title" set-value ] [ "old" [ from-object ] nest-form ] bi ] + [ "new" [ from-object ] nest-form ] bi* ] [ [ content>> string-lines ] bi@ diff "diff" set-value ] 2bi From 71d65880e57de7a8e763259c37ef618fccee38cd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 22:49:54 -0500 Subject: [PATCH 0231/1850] SSL session resumption --- .../unix/sockets/secure/secure-tests.factor | 4 +- extra/io/unix/sockets/secure/secure.factor | 24 ++- extra/openssl/libssl/libssl.factor | 154 ++++++++++++------ extra/openssl/openssl.factor | 32 +++- 4 files changed, 154 insertions(+), 60 deletions(-) diff --git a/extra/io/unix/sockets/secure/secure-tests.factor b/extra/io/unix/sockets/secure/secure-tests.factor index cbda002354..dca8fbbbc7 100644 --- a/extra/io/unix/sockets/secure/secure-tests.factor +++ b/extra/io/unix/sockets/secure/secure-tests.factor @@ -9,7 +9,7 @@ concurrency.promises byte-arrays locals calendar io.timeouts ; [ ] [ "port" set ] unit-test -: with-test-context +: with-test-context ( quot -- ) "resource:extra/openssl/test/server.pem" >>key-file "resource:extra/openssl/test/dh1024.pem" >>dh-file @@ -28,7 +28,7 @@ concurrency.promises byte-arrays locals calendar io.timeouts ; ] with-test-context ] "SSL server test" spawn drop ; -: client-test +: client-test ( -- string ) [ "127.0.0.1" "port" get ?promise ascii drop contents ] with-secure-context ; diff --git a/extra/io/unix/sockets/secure/secure.factor b/extra/io/unix/sockets/secure/secure.factor index 946e0e7be5..a0acbebb3a 100755 --- a/extra/io/unix/sockets/secure/secure.factor +++ b/extra/io/unix/sockets/secure/secure.factor @@ -118,13 +118,27 @@ M: secure (get-local-address) addrspec>> (get-local-address) ; dup dup handle>> SSL_connect check-connect-response dup [ dupd wait-for-fd do-ssl-connect ] [ 2drop ] if ; +: resume-session ( ssl-handle ssl-session -- ) + [ [ handle>> ] dip SSL_set_session ssl-error ] + [ drop do-ssl-connect ] + 2bi ; + +: begin-session ( ssl-handle addrspec -- ) + [ drop do-ssl-connect ] + [ [ handle>> SSL_get1_session ] dip save-session ] + 2bi ; + +: secure-connection ( ssl-handle addrspec -- ) + dup get-session [ resume-session ] [ begin-session ] ?if ; + M: secure establish-connection ( client-out remote -- ) - [ addrspec>> establish-connection ] + addrspec>> + [ establish-connection ] [ - drop handle>> - [ [ do-ssl-connect ] with-timeout ] - [ t >>connected drop ] - bi + [ handle>> ] dip + [ [ secure-connection ] curry with-timeout ] + [ drop t >>connected drop ] + 2bi ] 2bi ; M: secure (server) addrspec>> (server) ; diff --git a/extra/openssl/libssl/libssl.factor b/extra/openssl/libssl/libssl.factor index 3218d67b5c..dced2e5c0c 100755 --- a/extra/openssl/libssl/libssl.factor +++ b/extra/openssl/libssl/libssl.factor @@ -1,12 +1,8 @@ ! Copyright (C) 2007 Elie CHAFTARI +! Portions copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -! -! Tested with OpenSSL 0.9.8a_0 on Mac OS X 10.4.9 PowerPC -! -! export LD_LIBRARY_PATH=/opt/local/lib - USING: alien alien.syntax combinators kernel system namespaces -assocs parser sequences words quotations ; +assocs parser sequences words quotations math.bitfields ; IN: openssl.libssl @@ -24,11 +20,47 @@ IN: openssl.libssl : SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 ; inline : SSL_FILETYPE_PEM X509_FILETYPE_PEM ; inline -: SSL_CTRL_NEED_TMP_RSA 1 ; inline -: SSL_CTRL_SET_TMP_RSA 2 ; inline -: SSL_CTRL_SET_TMP_DH 3 ; inline -: SSL_CTRL_SET_TMP_RSA_CB 4 ; inline -: SSL_CTRL_SET_TMP_DH_CB 5 ; inline +: SSL_CTRL_NEED_TMP_RSA 1 ; inline +: SSL_CTRL_SET_TMP_RSA 2 ; inline +: SSL_CTRL_SET_TMP_DH 3 ; inline +: SSL_CTRL_SET_TMP_RSA_CB 4 ; inline +: SSL_CTRL_SET_TMP_DH_CB 5 ; inline + +: SSL_CTRL_GET_SESSION_REUSED 6 ; inline +: SSL_CTRL_GET_CLIENT_CERT_REQUEST 7 ; inline +: SSL_CTRL_GET_NUM_RENEGOTIATIONS 8 ; inline +: SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 9 ; inline +: SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 10 ; inline +: SSL_CTRL_GET_FLAGS 11 ; inline +: SSL_CTRL_EXTRA_CHAIN_CERT 12 ; inline + +: SSL_CTRL_SET_MSG_CALLBACK 13 ; inline +: SSL_CTRL_SET_MSG_CALLBACK_ARG 14 ; inline + +: SSL_CTRL_SESS_NUMBER 20 ; inline +: SSL_CTRL_SESS_CONNECT 21 ; inline +: SSL_CTRL_SESS_CONNECT_GOOD 22 ; inline +: SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 ; inline +: SSL_CTRL_SESS_ACCEPT 24 ; inline +: SSL_CTRL_SESS_ACCEPT_GOOD 25 ; inline +: SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 ; inline +: SSL_CTRL_SESS_HIT 27 ; inline +: SSL_CTRL_SESS_CB_HIT 28 ; inline +: SSL_CTRL_SESS_MISSES 29 ; inline +: SSL_CTRL_SESS_TIMEOUTS 30 ; inline +: SSL_CTRL_SESS_CACHE_FULL 31 ; inline +: SSL_CTRL_OPTIONS 32 ; inline +: SSL_CTRL_MODE 33 ; inline + +: SSL_CTRL_GET_READ_AHEAD 40 ; inline +: SSL_CTRL_SET_READ_AHEAD 41 ; inline +: SSL_CTRL_SET_SESS_CACHE_SIZE 42 ; inline +: SSL_CTRL_GET_SESS_CACHE_SIZE 43 ; inline +: SSL_CTRL_SET_SESS_CACHE_MODE 44 ; inline +: SSL_CTRL_GET_SESS_CACHE_MODE 45 ; inline + +: SSL_CTRL_GET_MAX_CERT_LIST 50 ; inline +: SSL_CTRL_SET_MAX_CERT_LIST 51 ; inline : SSL_ERROR_NONE 0 ; inline : SSL_ERROR_SSL 1 ; inline @@ -55,8 +87,9 @@ IN: openssl.libssl } ; TYPEDEF: void* ssl-method -TYPEDEF: void* ssl-ctx -TYPEDEF: void* ssl-pointer +TYPEDEF: void* SSL_CTX* +TYPEDEF: void* SSL_SESSION* +TYPEDEF: void* SSL* LIBRARY: libssl @@ -64,7 +97,7 @@ LIBRARY: libssl ! ssl.h ! =============================================== -FUNCTION: char* SSL_get_version ( ssl-pointer ssl ) ; +FUNCTION: char* SSL_get_version ( SSL* ssl ) ; ! Maps OpenSSL errors to strings FUNCTION: void SSL_load_error_strings ( ) ; @@ -94,42 +127,50 @@ FUNCTION: ssl-method TLSv1_server_method ( ) ; FUNCTION: ssl-method TLSv1_method ( ) ; ! Creates the context -FUNCTION: ssl-ctx SSL_CTX_new ( ssl-method method ) ; +FUNCTION: SSL_CTX* SSL_CTX_new ( ssl-method method ) ; ! Load the certificates and private keys into the SSL_CTX -FUNCTION: int SSL_CTX_use_certificate_chain_file ( ssl-ctx ctx, +FUNCTION: int SSL_CTX_use_certificate_chain_file ( SSL_CTX* ctx, char* file ) ; ! PEM type -FUNCTION: ssl-pointer SSL_new ( ssl-ctx ctx ) ; +FUNCTION: SSL* SSL_new ( SSL_CTX* ctx ) ; -FUNCTION: int SSL_set_fd ( ssl-pointer ssl, int fd ) ; +FUNCTION: int SSL_set_fd ( SSL* ssl, int fd ) ; -FUNCTION: void SSL_set_bio ( ssl-pointer ssl, void* rbio, void* wbio ) ; +FUNCTION: void SSL_set_bio ( SSL* ssl, void* rbio, void* wbio ) ; -FUNCTION: int SSL_get_error ( ssl-pointer ssl, int ret ) ; +FUNCTION: int SSL_set_session ( SSL* to, SSL_SESSION* session ) ; -FUNCTION: void SSL_set_connect_state ( ssl-pointer ssl ) ; +FUNCTION: int SSL_get_error ( SSL* ssl, int ret ) ; -FUNCTION: void SSL_set_accept_state ( ssl-pointer ssl ) ; +FUNCTION: void SSL_set_connect_state ( SSL* ssl ) ; -FUNCTION: int SSL_connect ( ssl-pointer ssl ) ; +FUNCTION: void SSL_set_accept_state ( SSL* ssl ) ; -FUNCTION: int SSL_accept ( ssl-pointer ssl ) ; +FUNCTION: int SSL_connect ( SSL* ssl ) ; -FUNCTION: int SSL_write ( ssl-pointer ssl, void* buf, int num ) ; +FUNCTION: int SSL_accept ( SSL* ssl ) ; -FUNCTION: int SSL_read ( ssl-pointer ssl, void* buf, int num ) ; +FUNCTION: int SSL_write ( SSL* ssl, void* buf, int num ) ; -FUNCTION: int SSL_shutdown ( ssl-pointer ssl ) ; +FUNCTION: int SSL_read ( SSL* ssl, void* buf, int num ) ; + +FUNCTION: int SSL_shutdown ( SSL* ssl ) ; : SSL_SENT_SHUTDOWN 1 ; : SSL_RECEIVED_SHUTDOWN 2 ; -FUNCTION: int SSL_get_shutdown ( ssl-pointer ssl ) ; +FUNCTION: int SSL_get_shutdown ( SSL* ssl ) ; -FUNCTION: void SSL_free ( ssl-pointer ssl ) ; +FUNCTION: int SSL_CTX_set_session_id_context ( SSL_CTX* ctx, char* sid_ctx, uint len ) ; -FUNCTION: int SSL_want ( ssl-pointer ssl ) ; +FUNCTION: SSL_SESSION* SSL_get1_session ( SSL* ssl ) ; + +FUNCTION: void SSL_free ( SSL* ssl ) ; + +FUNCTION: void SSL_SESSION_free ( SSL_SESSION* ses ) ; + +FUNCTION: int SSL_want ( SSL* ssl ) ; : SSL_NOTHING 1 ; inline : SSL_WRITING 2 ; inline @@ -140,55 +181,55 @@ FUNCTION: long SSL_get_verify_result ( SSL* ssl ) ; FUNCTION: X509* SSL_get_peer_certificate ( SSL* s ) ; -FUNCTION: void SSL_CTX_free ( ssl-ctx ctx ) ; +FUNCTION: void SSL_CTX_free ( SSL_CTX* ctx ) ; FUNCTION: void RAND_seed ( void* buf, int num ) ; -FUNCTION: int SSL_set_cipher_list ( ssl-pointer ssl, char* str ) ; +FUNCTION: int SSL_set_cipher_list ( SSL* ssl, char* str ) ; -FUNCTION: int SSL_use_RSAPrivateKey_file ( ssl-pointer ssl, char* str ) ; +FUNCTION: int SSL_use_RSAPrivateKey_file ( SSL* ssl, char* str ) ; -FUNCTION: int SSL_CTX_use_RSAPrivateKey_file ( ssl-ctx ctx, int type ) ; +FUNCTION: int SSL_CTX_use_RSAPrivateKey_file ( SSL_CTX* ctx, int type ) ; -FUNCTION: int SSL_use_certificate_file ( ssl-pointer ssl, +FUNCTION: int SSL_use_certificate_file ( SSL* ssl, char* str, int type ) ; -FUNCTION: int SSL_CTX_load_verify_locations ( ssl-ctx ctx, char* CAfile, +FUNCTION: int SSL_CTX_load_verify_locations ( SSL_CTX* ctx, char* CAfile, char* CApath ) ; -FUNCTION: int SSL_CTX_set_default_verify_paths ( ssl-ctx ctx ) ; +FUNCTION: int SSL_CTX_set_default_verify_paths ( SSL_CTX* ctx ) ; : SSL_VERIFY_NONE 0 ; inline : SSL_VERIFY_PEER 1 ; inline : SSL_VERIFY_FAIL_IF_NO_PEER_CERT 2 ; inline : SSL_VERIFY_CLIENT_ONCE 4 ; inline -FUNCTION: void SSL_CTX_set_verify ( ssl-ctx ctx, int mode, void* callback ) ; +FUNCTION: void SSL_CTX_set_verify ( SSL_CTX* ctx, int mode, void* callback ) ; -FUNCTION: void SSL_CTX_set_client_CA_list ( ssl-ctx ctx, ssl-pointer list ) ; +FUNCTION: void SSL_CTX_set_client_CA_list ( SSL_CTX* ctx, SSL* list ) ; -FUNCTION: ssl-pointer SSL_load_client_CA_file ( char* file ) ; +FUNCTION: SSL* SSL_load_client_CA_file ( char* file ) ; ! Used to manipulate settings of the SSL_CTX and SSL objects. ! This function should never be called directly -FUNCTION: long SSL_CTX_ctrl ( ssl-ctx ctx, int cmd, long larg, void* parg ) ; +FUNCTION: long SSL_CTX_ctrl ( SSL_CTX* ctx, int cmd, long larg, void* parg ) ; -FUNCTION: void SSL_CTX_set_default_passwd_cb ( ssl-ctx ctx, void* cb ) ; +FUNCTION: void SSL_CTX_set_default_passwd_cb ( SSL_CTX* ctx, void* cb ) ; -FUNCTION: void SSL_CTX_set_default_passwd_cb_userdata ( ssl-ctx ctx, +FUNCTION: void SSL_CTX_set_default_passwd_cb_userdata ( SSL_CTX* ctx, void* u ) ; -FUNCTION: int SSL_CTX_use_PrivateKey_file ( ssl-ctx ctx, char* file, +FUNCTION: int SSL_CTX_use_PrivateKey_file ( SSL_CTX* ctx, char* file, int type ) ; -! Sets the maximum depth for the allowed ctx certificate chain verification -FUNCTION: void SSL_CTX_set_verify_depth ( ssl-ctx ctx, int depth ) ; +! Sets the maximum depth for the allowed ctx certificate chain verification +FUNCTION: void SSL_CTX_set_verify_depth ( SSL_CTX* ctx, int depth ) ; ! Sets DH parameters to be used to be dh. ! The key is inherited by all ssl objects created from ctx -FUNCTION: void SSL_CTX_set_tmp_dh_callback ( ssl-ctx ctx, void* dh ) ; +FUNCTION: void SSL_CTX_set_tmp_dh_callback ( SSL_CTX* ctx, void* dh ) ; -FUNCTION: void SSL_CTX_set_tmp_rsa_callback ( ssl-ctx ctx, void* rsa ) ; +FUNCTION: void SSL_CTX_set_tmp_rsa_callback ( SSL_CTX* ctx, void* rsa ) ; FUNCTION: void* BIO_f_ssl ( ) ; @@ -198,6 +239,23 @@ FUNCTION: void* BIO_f_ssl ( ) ; : SSL_CTX_set_tmp_dh ( ctx dh -- n ) >r SSL_CTRL_SET_TMP_DH 0 r> SSL_CTX_ctrl ; +: SSL_CTX_set_session_cache_mode ( ctx mode -- n ) + >r SSL_CTRL_SET_SESS_CACHE_MODE r> f SSL_CTX_ctrl ; + +: SSL_SESS_CACHE_OFF HEX: 0000 ; inline +: SSL_SESS_CACHE_CLIENT HEX: 0001 ; inline +: SSL_SESS_CACHE_SERVER HEX: 0002 ; inline + +: SSL_SESS_CACHE_BOTH ( -- n ) + { SSL_SESS_CACHE_CLIENT SSL_SESS_CACHE_SERVER } flags ; inline + +: SSL_SESS_CACHE_NO_AUTO_CLEAR HEX: 0080 ; inline +: SSL_SESS_CACHE_NO_INTERNAL_LOOKUP HEX: 0100 ; inline +: SSL_SESS_CACHE_NO_INTERNAL_STORE HEX: 0200 ; inline + +: SSL_SESS_CACHE_NO_INTERNAL ( -- n ) + { SSL_SESS_CACHE_NO_INTERNAL_LOOKUP SSL_SESS_CACHE_NO_INTERNAL_STORE } flags ; inline + ! =============================================== ! x509.h ! =============================================== diff --git a/extra/openssl/openssl.factor b/extra/openssl/openssl.factor index b2dbda7d2e..6d750bd8e0 100755 --- a/extra/openssl/openssl.factor +++ b/extra/openssl/openssl.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors byte-arrays kernel debugger sequences namespaces math math.order combinators init alien alien.c-types alien.strings libc -continuations destructors debugger inspector splitting -locals unicode.case +continuations destructors debugger inspector splitting assocs +random math.parser locals unicode.case openssl.libcrypto openssl.libssl io.backend io.ports io.files io.encodings.8-bit io.sockets.secure io.timeouts ; @@ -48,7 +48,13 @@ SYMBOL: ssl-initialized? [ f ssl-initialized? set-global ] "openssl" add-init-hook -TUPLE: openssl-context < secure-context aliens ; +TUPLE: openssl-context < secure-context aliens sessions ; + +: set-session-cache ( ctx -- ) + handle>> + [ SSL_SESS_CACHE_BOTH SSL_CTX_set_session_cache_mode ssl-error ] + [ 32 random-bits >hex dup length SSL_CTX_set_session_id_context ssl-error ] + bi ; : load-certificate-chain ( ctx -- ) dup config>> key-file>> [ @@ -133,12 +139,20 @@ M: rsa dispose* handle>> RSA_free ; ] bi SSL_CTX_set_tmp_rsa ssl-error ; +: ( config ctx -- context ) + openssl-context new + swap >>handle + swap >>config + V{ } clone >>aliens + H{ } clone >>sessions ; + M: openssl ( config -- context ) maybe-init-ssl [ dup method>> ssl-method SSL_CTX_new - dup ssl-error f V{ } clone openssl-context boa |dispose + dup ssl-error |dispose { + [ set-session-cache ] [ load-certificate-chain ] [ set-default-password ] [ use-private-key-file ] @@ -152,8 +166,9 @@ M: openssl ( config -- context ) M: openssl-context dispose* [ aliens>> [ free ] each ] + [ sessions>> values [ SSL_SESSION_free ] each ] [ handle>> SSL_CTX_free ] - bi ; + tri ; TUPLE: ssl-handle file handle connected disposed ; @@ -204,4 +219,11 @@ M: openssl check-certificate ( host ssl -- ) 2bi ] [ 2drop ] if ; +: get-session ( addrspec -- session/f ) + current-secure-context sessions>> at + dup expired? [ drop f ] when ; + +: save-session ( session addrspec -- ) + current-secure-context sessions>> set-at ; + openssl secure-socket-backend set-global From 00e97257299fe80e1d8f82a3dc9707c44195dfad Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 15 Jun 2008 23:04:17 -0500 Subject: [PATCH 0232/1850] Fix load error --- extra/tangle/sandbox/sandbox.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/tangle/sandbox/sandbox.factor b/extra/tangle/sandbox/sandbox.factor index b6e110ada5..b44acb7617 100644 --- a/extra/tangle/sandbox/sandbox.factor +++ b/extra/tangle/sandbox/sandbox.factor @@ -12,7 +12,7 @@ IN: tangle.sandbox ] with-tangle ; : new-sandbox ( -- ) - development-mode on + development? on delete-db sandbox-db f [ make-sandbox ] [ ] bi main-responder set ; From a943a237d956b8c1cb051224ad555484384ab4c3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 01:35:06 -0500 Subject: [PATCH 0233/1850] Fix information leakage --- extra/http/http-tests.factor | 4 ++++ extra/http/http.factor | 14 ++++++++++++-- extra/http/server/server.factor | 25 +++++++++---------------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 88d42d9796..d092e5008f 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -276,3 +276,7 @@ SYMBOL: a [ 4 ] [ a get-global ] unit-test [ "Goodbye" ] [ "http://localhost:1237/quit" http-get nip ] unit-test + +! Test cloning +[ f ] [ <404> dup clone "b" "a" set-header drop "a" header ] unit-test +[ f ] [ <404> dup clone "b" "a" put-cookie drop "a" get-cookie ] unit-test diff --git a/extra/http/http.factor b/extra/http/http.factor index 521c18c703..25bf20429d 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -6,7 +6,8 @@ assocs sequences splitting sorting sets debugger strings vectors hashtables quotations arrays byte-arrays math.parser calendar calendar.format present -io io.encodings.iana io.encodings.binary io.encodings.8-bit +io io.encodings io.encodings.iana io.encodings.binary +io.encodings.8-bit unicode.case unicode.categories qualified @@ -298,6 +299,11 @@ body ; latin1 >>content-charset V{ } clone >>cookies ; +M: response clone + call-next-method + [ clone ] change-header + [ clone ] change-cookies ; + : read-response-version ( response -- response ) " \t" read-until [ "Bad response: version" throw ] unless @@ -363,7 +369,11 @@ M: response write-response ( respose -- ) M: response write-full-response ( request response -- ) dup write-response - swap method>> "HEAD" = [ write-response-body ] unless ; + swap method>> "HEAD" = [ + [ content-charset>> encode-output ] + [ write-response-body ] + bi + ] unless ; : get-cookie ( request/response name -- cookie/f ) [ cookies>> ] dip '[ , _ name>> = ] find nip ; diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index dc66cb1507..f709939e21 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -60,23 +60,16 @@ main-responder global [ <404> or ] change-at swap development? get [ '[ , http-error. ] >>body ] [ drop ] if ; : do-response ( response -- ) - [ write-response ] + [ request get swap write-full-response ] [ - request get method>> "HEAD" = [ drop ] [ - '[ - , - [ content-charset>> encode-output ] - [ write-response-body ] - bi - ] - [ - utf8 [ - development? get - [ http-error. ] [ drop "Response error" rethrow ] if - ] with-encoded-output - ] recover - ] if - ] bi ; + [ \ do-response log-error ] + [ + utf8 [ + development? get + [ http-error. ] [ drop "Response error" write ] if + ] with-encoded-output + ] bi + ] recover ; LOG: httpd-hit NOTICE From 39d8bec7ef41228902ec00e829aa0505ff269528 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 03:34:17 -0500 Subject: [PATCH 0234/1850] Refactoring furnace.auth --- extra/furnace/auth/auth.factor | 100 ++++- extra/furnace/auth/basic/basic.factor | 44 +- .../furnace/auth/{login => }/boilerplate.xml | 0 .../edit-profile/edit-profile-tests.factor | 4 + .../features/edit-profile/edit-profile.factor | 67 ++++ .../edit-profile}/edit-profile.xml | 0 .../recover-password}/recover-1.xml | 0 .../recover-password}/recover-2.xml | 0 .../recover-password}/recover-3.xml | 0 .../recover-password}/recover-4.xml | 0 .../recover-password-tests.factor | 4 + .../recover-password/recover-password.factor | 123 ++++++ .../registration}/register.xml | 0 .../registration/registration-tests.factor | 4 + .../features/registration/registration.factor | 43 ++ extra/furnace/auth/login/login-tests.factor | 4 +- extra/furnace/auth/login/login.factor | 379 ++---------------- .../furnace/auth/providers/db/db-tests.factor | 5 +- extra/furnace/db/db.factor | 3 +- extra/furnace/sessions/sessions.factor | 9 - extra/furnace/utilities/utilities.factor | 19 + extra/http/client/client-tests.factor | 4 +- extra/http/http-tests.factor | 6 +- extra/http/http.factor | 3 +- extra/webapps/blogs/blogs.factor | 14 +- .../factor-website/factor-website.factor | 11 +- extra/webapps/todo/todo.factor | 3 +- extra/webapps/user-admin/user-admin.factor | 8 +- 28 files changed, 426 insertions(+), 431 deletions(-) rename extra/furnace/auth/{login => }/boilerplate.xml (100%) create mode 100644 extra/furnace/auth/features/edit-profile/edit-profile-tests.factor create mode 100644 extra/furnace/auth/features/edit-profile/edit-profile.factor rename extra/furnace/auth/{login => features/edit-profile}/edit-profile.xml (100%) rename extra/furnace/auth/{login => features/recover-password}/recover-1.xml (100%) rename extra/furnace/auth/{login => features/recover-password}/recover-2.xml (100%) rename extra/furnace/auth/{login => features/recover-password}/recover-3.xml (100%) rename extra/furnace/auth/{login => features/recover-password}/recover-4.xml (100%) create mode 100644 extra/furnace/auth/features/recover-password/recover-password-tests.factor create mode 100644 extra/furnace/auth/features/recover-password/recover-password.factor rename extra/furnace/auth/{login => features/registration}/register.xml (100%) create mode 100644 extra/furnace/auth/features/registration/registration-tests.factor create mode 100644 extra/furnace/auth/features/registration/registration.factor create mode 100644 extra/furnace/utilities/utilities.factor diff --git a/extra/furnace/auth/auth.factor b/extra/furnace/auth/auth.factor index f78cea3835..d10ba48ce5 100755 --- a/extra/furnace/auth/auth.factor +++ b/extra/furnace/auth/auth.factor @@ -1,11 +1,18 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs namespaces kernel sequences sets +destructors combinators +io.encodings.utf8 io.encodings.string io.binary random +checksums checksums.sha2 +html.forms http.server http.server.filters http.server.dispatchers -furnace.sessions -furnace.auth.providers ; +furnace +furnace.actions +furnace.boilerplate +furnace.auth.providers +furnace.auth.providers.db ; IN: furnace.auth SYMBOL: logged-in-user @@ -20,6 +27,9 @@ M: dispatcher init-user-profile M: filter-responder init-user-profile responder>> init-user-profile ; +: have-capability? ( capability -- ? ) + logged-in-user get capabilities>> member? ; + : profile ( -- assoc ) logged-in-user get profile>> ; : user-changed ( -- ) @@ -41,3 +51,89 @@ SYMBOL: capabilities V{ } clone capabilities set-global : define-capability ( word -- ) capabilities get adjoin ; + +TUPLE: realm < dispatcher name users checksum ; + +GENERIC: login-required* ( realm -- response ) + +GENERIC: logged-in-username ( realm -- username ) + +: login-required ( -- * ) realm get login-required* exit-with ; + +: new-realm ( responder name class -- realm ) + new-dispatcher + swap >>name + swap >>default + users-in-db >>users + sha-256 >>checksum ; inline + +: users ( -- provider ) + realm get users>> ; + +TUPLE: user-saver user ; + +C: user-saver + +M: user-saver dispose + user>> dup changed?>> [ users update-user ] [ drop ] if ; + +: save-user-after ( user -- ) + &dispose drop ; + +: init-user ( realm -- ) + logged-in-username [ + users get-user + [ logged-in-user set ] [ save-user-after ] bi + ] when* ; + +M: realm call-responder* ( path responder -- response ) + dup realm set + dup init-user + call-next-method ; + +: encode-password ( string salt -- bytes ) + [ utf8 encode ] [ 4 >be ] bi* append + realm get checksum>> checksum-bytes ; + +: >>encoded-password ( user string -- user ) + 32 random-bits [ encode-password ] keep + [ >>password ] [ >>salt ] bi* ; inline + +: valid-login? ( password user -- ? ) + [ salt>> encode-password ] [ password>> ] bi = ; + +: check-login ( password username -- user/f ) + users get-user dup [ [ valid-login? ] keep and ] [ 2drop f ] if ; + +TUPLE: protected < filter-responder description capabilities ; + +: ( responder -- protected ) + protected new + swap >>responder ; + +: check-capabilities ( responder user/f -- ? ) + { + { [ dup not ] [ 2drop f ] } + { [ dup deleted>> ] [ 2drop f ] } + [ [ capabilities>> ] bi@ subset? ] + } cond ; + +M: protected call-responder* ( path responder -- response ) + dup protected set + dup logged-in-user get check-capabilities + [ call-next-method ] [ 2drop realm get login-required* ] if ; + +: ( responder -- responder' ) + { realm "boilerplate" } >>template ; + +: password-mismatch ( -- * ) + "passwords do not match" validation-error + validation-failed ; + +: same-password-twice ( -- ) + "new-password" value "verify-password" value = + [ password-mismatch ] unless ; + +: user-exists ( -- * ) + "username taken" validation-error + validation-failed ; diff --git a/extra/furnace/auth/basic/basic.factor b/extra/furnace/auth/basic/basic.factor index c8d542c219..ae9cbb82c1 100755 --- a/extra/furnace/auth/basic/basic.factor +++ b/extra/furnace/auth/basic/basic.factor @@ -1,41 +1,27 @@ ! Copyright (c) 2007 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors quotations assocs kernel splitting -base64 html.elements io combinators sequences -http http.server.filters http.server.responses http.server -furnace.auth.providers furnace.auth.login ; +USING: accessors kernel splitting base64 namespaces +http http.server.responses furnace.auth ; IN: furnace.auth.basic -TUPLE: basic-auth < filter-responder realm provider ; +TUPLE: basic-auth-realm < realm ; -C: basic-auth +C: basic-auth-realm -: authorization-ok? ( provider header -- ? ) - #! Given the realm and the 'Authorization' header, - #! authenticate the user. +: parse-basic-auth ( header -- username/f password/f ) dup [ " " split1 swap "Basic" = [ - base64> ":" split1 spin check-login - ] [ - 2drop f - ] if - ] [ - 2drop f - ] if ; + base64> ":" split1 + ] [ drop f f ] if + ] [ drop f f ] if ; : <401> ( realm -- response ) - 401 "Unauthorized" - "Basic realm=\"" rot "\"" 3append - "WWW-Authenticate" set-header - [ - - "Username or Password is invalid" write - - ] >>body ; + 401 "Invalid username or password" + [ "Basic realm=\"" % swap % "\"" % ] "" make "WWW-Authenticate" set-header ; -: logged-in? ( request responder -- ? ) - provider>> swap "authorization" header authorization-ok? ; +M: basic-auth-realm login-required* ( realm -- response ) + name>> <401> ; -M: basic-auth call-responder* ( request path responder -- response ) - pick over logged-in? - [ call-next-method ] [ 2nip realm>> <401> ] if ; +M: basic-auth-realm logged-in-username ( realm -- uid ) + request get "authorization" header parse-basic-auth + dup [ over realm get check-login swap and ] [ 2drop f ] if ; diff --git a/extra/furnace/auth/login/boilerplate.xml b/extra/furnace/auth/boilerplate.xml similarity index 100% rename from extra/furnace/auth/login/boilerplate.xml rename to extra/furnace/auth/boilerplate.xml diff --git a/extra/furnace/auth/features/edit-profile/edit-profile-tests.factor b/extra/furnace/auth/features/edit-profile/edit-profile-tests.factor new file mode 100644 index 0000000000..d0fdf22c27 --- /dev/null +++ b/extra/furnace/auth/features/edit-profile/edit-profile-tests.factor @@ -0,0 +1,4 @@ +IN: furnace.auth.features.edit-profile.tests +USING: tools.test furnace.auth.features.edit-profile ; + +\ allow-edit-profile must-infer diff --git a/extra/furnace/auth/features/edit-profile/edit-profile.factor b/extra/furnace/auth/features/edit-profile/edit-profile.factor new file mode 100644 index 0000000000..4edb4ac364 --- /dev/null +++ b/extra/furnace/auth/features/edit-profile/edit-profile.factor @@ -0,0 +1,67 @@ +! Copyright (c) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors namespaces sequences assocs +validators urls +html.forms +http.server.dispatchers +furnace.auth +furnace.asides +furnace.actions ; +IN: furnace.auth.features.edit-profile + +: ( -- action ) + + [ + logged-in-user get + [ username>> "username" set-value ] + [ realname>> "realname" set-value ] + [ email>> "email" set-value ] + tri + ] >>init + + { realm "features/edit-profile/edit-profile" } >>template + + [ + logged-in-user get username>> "username" set-value + + { + { "realname" [ [ v-one-line ] v-optional ] } + { "password" [ ] } + { "new-password" [ [ v-password ] v-optional ] } + { "verify-password" [ [ v-password ] v-optional ] } + { "email" [ [ v-email ] v-optional ] } + } validate-params + + { "password" "new-password" "verify-password" } + [ value empty? not ] contains? [ + "password" value logged-in-user get username>> check-login + [ "incorrect password" validation-error ] unless + + same-password-twice + ] when + ] >>validate + + [ + logged-in-user get + + "new-password" value dup empty? + [ drop ] [ >>encoded-password ] if + + "realname" value >>realname + "email" value >>email + + t >>changed? + + drop + + URL" $login" end-aside + ] >>submit + + + "edit your profile" >>description ; + +: allow-edit-profile ( login -- login ) + "edit-profile" add-responder ; + +: allow-edit-profile? ( -- ? ) + realm get get responders>> "edit-profile" swap key? ; diff --git a/extra/furnace/auth/login/edit-profile.xml b/extra/furnace/auth/features/edit-profile/edit-profile.xml similarity index 100% rename from extra/furnace/auth/login/edit-profile.xml rename to extra/furnace/auth/features/edit-profile/edit-profile.xml diff --git a/extra/furnace/auth/login/recover-1.xml b/extra/furnace/auth/features/recover-password/recover-1.xml similarity index 100% rename from extra/furnace/auth/login/recover-1.xml rename to extra/furnace/auth/features/recover-password/recover-1.xml diff --git a/extra/furnace/auth/login/recover-2.xml b/extra/furnace/auth/features/recover-password/recover-2.xml similarity index 100% rename from extra/furnace/auth/login/recover-2.xml rename to extra/furnace/auth/features/recover-password/recover-2.xml diff --git a/extra/furnace/auth/login/recover-3.xml b/extra/furnace/auth/features/recover-password/recover-3.xml similarity index 100% rename from extra/furnace/auth/login/recover-3.xml rename to extra/furnace/auth/features/recover-password/recover-3.xml diff --git a/extra/furnace/auth/login/recover-4.xml b/extra/furnace/auth/features/recover-password/recover-4.xml similarity index 100% rename from extra/furnace/auth/login/recover-4.xml rename to extra/furnace/auth/features/recover-password/recover-4.xml diff --git a/extra/furnace/auth/features/recover-password/recover-password-tests.factor b/extra/furnace/auth/features/recover-password/recover-password-tests.factor new file mode 100644 index 0000000000..b589c52624 --- /dev/null +++ b/extra/furnace/auth/features/recover-password/recover-password-tests.factor @@ -0,0 +1,4 @@ +IN: furnace.auth.features.recover-password +USING: tools.test furnace.auth.features.recover-password ; + +\ allow-password-recovery must-infer diff --git a/extra/furnace/auth/features/recover-password/recover-password.factor b/extra/furnace/auth/features/recover-password/recover-password.factor new file mode 100644 index 0000000000..1e8d163e99 --- /dev/null +++ b/extra/furnace/auth/features/recover-password/recover-password.factor @@ -0,0 +1,123 @@ +! Copyright (c) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: namespaces accessors kernel assocs arrays io.sockets threads +fry urls smtp validators html.forms +http http.server.responses http.server.dispatchers +furnace furnace.actions furnace.auth furnace.auth.providers ; +IN: furnace.auth.features.recover-password + +SYMBOL: lost-password-from + +: current-host ( -- string ) + request get url>> host>> host-name or ; + +: new-password-url ( user -- url ) + "recover-3" + swap [ + [ username>> "username" set ] + [ ticket>> "ticket" set ] + bi + ] H{ } make-assoc + derive-url ; + +: password-email ( user -- email ) + + [ "[ " % current-host % " ] password recovery" % ] "" make >>subject + lost-password-from get >>from + over email>> 1array >>to + [ + "This e-mail was sent by the application server on " % current-host % "\n" % + "because somebody, maybe you, clicked on a ``recover password'' link in the\n" % + "login form, and requested a new password for the user named ``" % + over username>> % "''.\n" % + "\n" % + "If you believe that this request was legitimate, you may click the below link in\n" % + "your browser to set a new password for your account:\n" % + "\n" % + swap new-password-url % + "\n\n" % + "Love,\n" % + "\n" % + " FactorBot\n" % + ] "" make >>body ; + +: send-password-email ( user -- ) + '[ , password-email send-email ] + "E-mail send thread" spawn drop ; + +: ( -- action ) + + { realm "recover-1" } >>template + + [ + { + { "username" [ v-username ] } + { "email" [ v-email ] } + { "captcha" [ v-captcha ] } + } validate-params + ] >>validate + + [ + "email" value "username" value + users issue-ticket [ + send-password-email + ] when* + + URL" $login/recover-2" + ] >>submit ; + +: ( -- action ) + + { realm "recover-2" } >>template ; + +: ( -- action ) + + [ + { + { "username" [ v-username ] } + { "ticket" [ v-required ] } + } validate-params + ] >>init + + { realm "recover-3" } >>template + + [ + { + { "username" [ v-username ] } + { "ticket" [ v-required ] } + { "new-password" [ v-password ] } + { "verify-password" [ v-password ] } + } validate-params + + same-password-twice + ] >>validate + + [ + "ticket" value + "username" value + users claim-ticket [ + "new-password" value >>encoded-password + users update-user + + URL" $login/recover-4" + ] [ + <403> + ] if* + ] >>submit ; + +: ( -- action ) + + { realm "recover-4" } >>template ; + +: allow-password-recovery ( login -- login ) + + "recover-password" add-responder + + "recover-2" add-responder + + "recover-3" add-responder + + "recover-4" add-responder ; + +: allow-password-recovery? ( -- ? ) + realm get responders>> "recover-password" swap key? ; diff --git a/extra/furnace/auth/login/register.xml b/extra/furnace/auth/features/registration/register.xml similarity index 100% rename from extra/furnace/auth/login/register.xml rename to extra/furnace/auth/features/registration/register.xml diff --git a/extra/furnace/auth/features/registration/registration-tests.factor b/extra/furnace/auth/features/registration/registration-tests.factor new file mode 100644 index 0000000000..e770f35586 --- /dev/null +++ b/extra/furnace/auth/features/registration/registration-tests.factor @@ -0,0 +1,4 @@ +IN: furnace.auth.features.registration.tests +USING: tools.test furnace.auth.features.registration ; + +\ allow-registration must-infer diff --git a/extra/furnace/auth/features/registration/registration.factor b/extra/furnace/auth/features/registration/registration.factor new file mode 100644 index 0000000000..3deead4869 --- /dev/null +++ b/extra/furnace/auth/features/registration/registration.factor @@ -0,0 +1,43 @@ +! Copyright (c) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs kernel namespaces validators html.forms urls +http.server.dispatchers +furnace furnace.auth furnace.auth.providers furnace.actions ; +IN: furnace.auth.features.registration + +: ( -- action ) + + { realm "register" } >>template + + [ + { + { "username" [ v-username ] } + { "realname" [ [ v-one-line ] v-optional ] } + { "new-password" [ v-password ] } + { "verify-password" [ v-password ] } + { "email" [ [ v-email ] v-optional ] } + { "captcha" [ v-captcha ] } + } validate-params + + same-password-twice + ] >>validate + + [ + "username" value + "realname" value >>realname + "new-password" value >>encoded-password + "email" value >>email + H{ } clone >>profile + + users new-user [ user-exists ] unless* + + realm get init-user-profile + + URL" $realm" + ] >>submit ; + +: allow-registration ( login -- login ) + "register" add-responder ; + +: allow-registration? ( -- ? ) + realm get responders>> "register" swap key? ; diff --git a/extra/furnace/auth/login/login-tests.factor b/extra/furnace/auth/login/login-tests.factor index 5095ebdb85..64f7bd3b96 100755 --- a/extra/furnace/auth/login/login-tests.factor +++ b/extra/furnace/auth/login/login-tests.factor @@ -1,6 +1,4 @@ IN: furnace.auth.login.tests USING: tools.test furnace.auth.login ; -\ must-infer -\ allow-registration must-infer -\ allow-password-recovery must-infer +\ must-infer diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 80005c452a..1f81c488cc 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -1,103 +1,35 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: accessors quotations assocs kernel splitting -combinators sequences namespaces hashtables sets -fry arrays threads qualified random validators words -io -io.sockets -io.encodings.utf8 -io.encodings.string -io.binary -continuations -destructors -checksums -checksums.sha2 -validators +USING: kernel accessors namespaces validators urls html.forms -html.components -html.elements -urls -http -http.server http.server.dispatchers -http.server.filters -http.server.responses -furnace furnace.auth -furnace.auth.providers -furnace.auth.providers.db -furnace.actions -furnace.asides furnace.flash +furnace.asides +furnace.actions furnace.sessions -furnace.boilerplate ; -QUALIFIED: smtp +furnace.utilities ; IN: furnace.auth.login -: word>string ( word -- string ) - [ word-vocabulary ] [ word-name ] bi ":" swap 3append ; +TUPLE: login-realm < realm ; -: words>strings ( seq -- seq' ) - [ word>string ] map ; +: set-uid ( username -- ) + session get [ (>>uid) ] [ (session-changed) ] bi ; -ERROR: no-such-word name vocab ; - -: string>word ( string -- word ) - ":" split1 swap 2dup lookup dup - [ 2nip ] [ drop no-such-word ] if ; - -: strings>words ( seq -- seq' ) - [ string>word ] map ; - -TUPLE: login < dispatcher users checksum ; - -TUPLE: protected < filter-responder description capabilities ; - -: ( responder -- protected ) - protected new - swap >>responder ; - -: users ( -- provider ) - login get users>> ; - -: encode-password ( string salt -- bytes ) - [ utf8 encode ] [ 4 >be ] bi* append - login get checksum>> checksum-bytes ; - -: >>encoded-password ( user string -- user ) - 32 random-bits [ encode-password ] keep - [ >>password ] [ >>salt ] bi* ; inline - -: valid-login? ( password user -- ? ) - [ salt>> encode-password ] [ password>> ] bi = ; - -: check-login ( password username -- user/f ) - users get-user dup [ [ valid-login? ] keep and ] [ 2drop f ] if ; - -! Destructor -TUPLE: user-saver user ; - -C: user-saver - -M: user-saver dispose - user>> dup changed?>> [ users update-user ] [ drop ] if ; - -: save-user-after ( user -- ) - &dispose drop ; - -! ! ! Login : successful-login ( user -- response ) - username>> set-uid URL" $login" end-aside ; + username>> set-uid URL" $realm" end-aside ; -: login-failed ( -- * ) - "invalid username or password" validation-error - validation-failed ; +: logout ( -- ) f set-uid ; SYMBOL: description SYMBOL: capabilities : flashed-variables { description capabilities } ; +: login-failed ( -- * ) + "invalid username or password" validation-error + validation-failed ; + : ( -- action ) [ @@ -106,7 +38,7 @@ SYMBOL: capabilities capabilities get words>strings "capabilities" set-value ] >>init - { login "login" } >>template + { login-realm "login" } >>template [ { @@ -119,286 +51,21 @@ SYMBOL: capabilities [ successful-login ] [ login-failed ] if* ] >>submit ; -! ! ! New user registration - -: user-exists ( -- * ) - "username taken" validation-error - validation-failed ; - -: password-mismatch ( -- * ) - "passwords do not match" validation-error - validation-failed ; - -: same-password-twice ( -- ) - "new-password" value "verify-password" value = - [ password-mismatch ] unless ; - -: ( -- action ) - - { login "register" } >>template - - [ - { - { "username" [ v-username ] } - { "realname" [ [ v-one-line ] v-optional ] } - { "new-password" [ v-password ] } - { "verify-password" [ v-password ] } - { "email" [ [ v-email ] v-optional ] } - { "captcha" [ v-captcha ] } - } validate-params - - same-password-twice - ] >>validate - - [ - "username" value - "realname" value >>realname - "new-password" value >>encoded-password - "email" value >>email - H{ } clone >>profile - - users new-user [ user-exists ] unless* - - login get init-user-profile - - successful-login - ] >>submit ; - -! ! ! Editing user profile - -: ( -- action ) - - [ - logged-in-user get - [ username>> "username" set-value ] - [ realname>> "realname" set-value ] - [ email>> "email" set-value ] - tri - ] >>init - - { login "edit-profile" } >>template - - [ - uid "username" set-value - - { - { "realname" [ [ v-one-line ] v-optional ] } - { "password" [ ] } - { "new-password" [ [ v-password ] v-optional ] } - { "verify-password" [ [ v-password ] v-optional ] } - { "email" [ [ v-email ] v-optional ] } - } validate-params - - { "password" "new-password" "verify-password" } - [ value empty? not ] contains? [ - "password" value uid check-login - [ "incorrect password" validation-error ] unless - - same-password-twice - ] when - ] >>validate - - [ - logged-in-user get - - "new-password" value dup empty? - [ drop ] [ >>encoded-password ] if - - "realname" value >>realname - "email" value >>email - - t >>changed? - - drop - - URL" $login" end-aside - ] >>submit - - - "edit your profile" >>description ; - -! ! ! Password recovery - -SYMBOL: lost-password-from - -: current-host ( -- string ) - request get url>> host>> host-name or ; - -: new-password-url ( user -- url ) - "recover-3" - swap [ - [ username>> "username" set ] - [ ticket>> "ticket" set ] - bi - ] H{ } make-assoc - derive-url ; - -: password-email ( user -- email ) - smtp: - [ "[ " % current-host % " ] password recovery" % ] "" make >>subject - lost-password-from get >>from - over email>> 1array >>to - [ - "This e-mail was sent by the application server on " % current-host % "\n" % - "because somebody, maybe you, clicked on a ``recover password'' link in the\n" % - "login form, and requested a new password for the user named ``" % - over username>> % "''.\n" % - "\n" % - "If you believe that this request was legitimate, you may click the below link in\n" % - "your browser to set a new password for your account:\n" % - "\n" % - swap new-password-url % - "\n\n" % - "Love,\n" % - "\n" % - " FactorBot\n" % - ] "" make >>body ; - -: send-password-email ( user -- ) - '[ , password-email smtp:send-email ] - "E-mail send thread" spawn drop ; - -: ( -- action ) - - { login "recover-1" } >>template - - [ - { - { "username" [ v-username ] } - { "email" [ v-email ] } - { "captcha" [ v-captcha ] } - } validate-params - ] >>validate - - [ - "email" value "username" value - users issue-ticket [ - send-password-email - ] when* - - URL" $login/recover-2" - ] >>submit ; - -: ( -- action ) - - { login "recover-2" } >>template ; - -: ( -- action ) - - [ - { - { "username" [ v-username ] } - { "ticket" [ v-required ] } - } validate-params - ] >>init - - { login "recover-3" } >>template - - [ - { - { "username" [ v-username ] } - { "ticket" [ v-required ] } - { "new-password" [ v-password ] } - { "verify-password" [ v-password ] } - } validate-params - - same-password-twice - ] >>validate - - [ - "ticket" value - "username" value - users claim-ticket [ - "new-password" value >>encoded-password - users update-user - - URL" $login/recover-4" - ] [ - <403> - ] if* - ] >>submit ; - -: ( -- action ) - - { login "recover-4" } >>template ; - -! ! ! Logout : ( -- action ) - [ - f set-uid - URL" $login" end-aside - ] >>submit ; + [ logout URL" $login-realm" end-aside ] >>submit ; -! ! ! Authentication logic -: show-login-page ( -- response ) +M: login-realm login-required* + drop begin-aside protected get description>> description set protected get capabilities>> capabilities set URL" $login/login" flashed-variables ; -: login-required ( -- * ) - show-login-page exit-with ; +M: login-realm logged-in-username + drop session get uid>> ; -: have-capability? ( capability -- ? ) - logged-in-user get capabilities>> member? ; - -: check-capabilities ( responder user/f -- ? ) - dup [ [ capabilities>> ] bi@ subset? ] [ 2drop f ] if ; - -M: protected call-responder* ( path responder -- response ) - dup protected set - dup logged-in-user get check-capabilities - [ call-next-method ] [ 2drop show-login-page ] if ; - -: init-user ( -- ) - uid [ - users get-user - [ logged-in-user set ] - [ save-user-after ] bi - ] when* ; - -M: login call-responder* ( path responder -- response ) - dup login set - init-user - call-next-method ; - -: ( responder -- responder' ) - - { login "boilerplate" } >>template ; - -: ( responder -- auth ) - login new-dispatcher - swap >>default - "login" add-responder - "logout" add-responder - users-in-db >>users - sha-256 >>checksum ; - -! ! ! Configuration - -: allow-edit-profile ( login -- login ) - "edit-profile" add-responder ; - -: allow-registration ( login -- login ) - - "register" add-responder ; - -: allow-password-recovery ( login -- login ) - - "recover-password" add-responder - - "recover-2" add-responder - - "recover-3" add-responder - - "recover-4" add-responder ; - -: allow-edit-profile? ( -- ? ) - login get responders>> "edit-profile" swap key? ; - -: allow-registration? ( -- ? ) - login get responders>> "register" swap key? ; - -: allow-password-recovery? ( -- ? ) - login get responders>> "recover-password" swap key? ; +: ( responder name -- auth ) + login-realm new-realm + "login" add-responder + "logout" add-responder ; diff --git a/extra/furnace/auth/providers/db/db-tests.factor b/extra/furnace/auth/providers/db/db-tests.factor index e5914c7ab3..fac5c23e4a 100755 --- a/extra/furnace/auth/providers/db/db-tests.factor +++ b/extra/furnace/auth/providers/db/db-tests.factor @@ -1,14 +1,13 @@ IN: furnace.auth.providers.db.tests USING: furnace.actions +furnace.auth furnace.auth.login furnace.auth.providers furnace.auth.providers.db tools.test namespaces db db.sqlite db.tuples continuations io.files accessors kernel ; - - users-in-db >>users -login set + "test" realm set [ "auth-test.db" temp-file delete-file ] ignore-errors diff --git a/extra/furnace/db/db.factor b/extra/furnace/db/db.factor index 8487b4b3fc..b4a4386015 100755 --- a/extra/furnace/db/db.factor +++ b/extra/furnace/db/db.factor @@ -1,8 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors continuations namespaces destructors -db db.pools io.pools http.server http.server.filters -furnace.sessions ; +db db.pools io.pools http.server http.server.filters ; IN: furnace.db TUPLE: db-persistence < filter-responder pool ; diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 4be7403e39..fe8053fc9c 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -57,12 +57,6 @@ TUPLE: sessions < server-state-manager domain verify? ; [ namespace>> swap change-at ] keep (session-changed) ; inline -: uid ( -- uid ) - session get uid>> ; - -: set-uid ( uid -- ) - session get [ (>>uid) ] [ (session-changed) ] bi ; - : init-session ( session -- ) session [ sessions get init-session* ] with-variable ; @@ -147,6 +141,3 @@ M: sessions call-responder* ( path responder -- response ) sessions set request-session [ begin-session ] unless* existing-session put-session-cookie ; - -: logout-all-sessions ( uid -- ) - session new swap >>uid delete-tuples ; diff --git a/extra/furnace/utilities/utilities.factor b/extra/furnace/utilities/utilities.factor new file mode 100644 index 0000000000..20c05d459f --- /dev/null +++ b/extra/furnace/utilities/utilities.factor @@ -0,0 +1,19 @@ +! Copyright (c) 2008 Slava Pestov +! See http://factorcode.org/license.txt for BSD license. +USING: words kernel sequences splitting ; +IN: furnace.utilities + +: word>string ( word -- string ) + [ word-vocabulary ] [ word-name ] bi ":" swap 3append ; + +: words>strings ( seq -- seq' ) + [ word>string ] map ; + +ERROR: no-such-word name vocab ; + +: string>word ( string -- word ) + ":" split1 swap 2dup lookup dup + [ 2nip ] [ drop no-such-word ] if ; + +: strings>words ( seq -- seq' ) + [ string>word ] map ; diff --git a/extra/http/client/client-tests.factor b/extra/http/client/client-tests.factor index daf4ad88d3..28a605174a 100755 --- a/extra/http/client/client-tests.factor +++ b/extra/http/client/client-tests.factor @@ -14,7 +14,7 @@ tuple-syntax namespaces urls ; method: "GET" version: "1.1" cookies: V{ } - header: H{ { "connection" "close" } { "user-agent" "Factor http.client vocabulary" } } + header: H{ { "connection" "close" } { "user-agent" "Factor http.client" } } } ] [ "http://www.apple.com/index.html" @@ -27,7 +27,7 @@ tuple-syntax namespaces urls ; method: "GET" version: "1.1" cookies: V{ } - header: H{ { "connection" "close" } { "user-agent" "Factor http.client vocabulary" } } + header: H{ { "connection" "close" } { "user-agent" "Factor http.client" } } } ] [ "https://www.amazon.com/index.html" diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index d092e5008f..73d26aa327 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -122,7 +122,7 @@ read-response-test-1' 1array [ ! Live-fire exercise USING: http.server http.server.static furnace.sessions furnace.alloy -furnace.actions furnace.auth.login furnace.db http.client +furnace.actions furnace.auth furnace.auth.login furnace.db http.client io.server io.files io io.encodings.ascii accessors namespaces threads http.server.responses http.server.redirection @@ -176,7 +176,7 @@ test-db [ [ - + "Test" "" add-responder add-quit-action @@ -206,7 +206,7 @@ test-db [ [ [ [ "Hi" write ] "text/plain" ] >>display - + "Test" "" add-responder add-quit-action diff --git a/extra/http/http.factor b/extra/http/http.factor index 25bf20429d..d2a0b0f922 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -147,7 +147,7 @@ cookies ; H{ } clone >>header V{ } clone >>cookies "close" "connection" set-header - "Factor http.client vocabulary" "user-agent" set-header ; + "Factor http.client" "user-agent" set-header ; : read-method ( request -- request ) " " read-until [ "Bad request: method" throw ] unless @@ -296,6 +296,7 @@ body ; H{ } clone >>header "close" "connection" set-header now timestamp>http-string "date" set-header + "Factor http.server" "server" set-header latin1 >>content-charset V{ } clone >>cookies ; diff --git a/extra/webapps/blogs/blogs.factor b/extra/webapps/blogs/blogs.factor index 760951eec6..aa1aa5edc7 100644 --- a/extra/webapps/blogs/blogs.factor +++ b/extra/webapps/blogs/blogs.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors sequences sorting math.order math.parser -urls validators db db.types db.tuples calendar present +urls validators db db.types db.tuples calendar present namespaces html.forms html.components http.server.dispatchers @@ -10,7 +10,6 @@ furnace.actions furnace.auth furnace.auth.login furnace.boilerplate -furnace.sessions furnace.syndication ; IN: webapps.blogs @@ -160,13 +159,13 @@ M: comment entity-url [ validate-post - uid "author" set-value + logged-in-user get username>> "author" set-value ] >>validate [ f dup { "title" "content" } to-object - uid >>author + logged-in-user get username>> >>author now >>date [ insert-tuple ] [ entity-url ] bi ] >>submit @@ -177,7 +176,8 @@ M: comment entity-url "make a new blog post" >>description ; : authorize-author ( author -- ) - uid = can-administer-blogs? have-capability? or + logged-in-user get username>> = + can-administer-blogs? have-capability? or [ login-required ] unless ; : do-post-action ( -- ) @@ -253,13 +253,13 @@ M: comment entity-url [ validate-comment - uid "author" set-value + logged-in-user get username>> "author" set-value ] >>validate [ "parent" value f "content" value >>content - uid >>author + logged-in-user get username>> >>author now >>date [ insert-tuple ] [ entity-url ] bi ] >>submit diff --git a/extra/webapps/factor-website/factor-website.factor b/extra/webapps/factor-website/factor-website.factor index 04fc0487b8..c0bd856d5d 100644 --- a/extra/webapps/factor-website/factor-website.factor +++ b/extra/webapps/factor-website/factor-website.factor @@ -7,12 +7,11 @@ logging.insomniac http.server http.server.dispatchers furnace.alloy -furnace.db -furnace.asides -furnace.flash -furnace.sessions furnace.auth.login furnace.auth.providers.db +furnace.auth.features.edit-profile +furnace.auth.features.recover-password +furnace.auth.features.registration furnace.boilerplate webapps.blogs webapps.pastebin @@ -50,8 +49,8 @@ TUPLE: factor-website < dispatcher ; "wiki" add-responder "wee-url" add-responder "user-admin" add-responder - - users-in-db >>users + "Factor website" + "Factor website" >>name allow-registration allow-password-recovery allow-edit-profile diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index dba10184f4..4b1b59e80f 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -8,7 +8,6 @@ html.templates.chloe http.server http.server.dispatchers furnace -furnace.sessions furnace.boilerplate furnace.auth furnace.actions @@ -32,7 +31,7 @@ todo "TODO" : ( id -- todo ) todo new swap >>id - uid >>uid ; + logged-in-user get username>> >>uid ; : ( -- action ) diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index 5859d616ee..8c7b1b21c9 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -11,8 +11,8 @@ furnace.auth.providers furnace.auth.providers.db furnace.auth.login furnace.auth -furnace.sessions furnace.actions +furnace.utilities http.server http.server.dispatchers ; IN: webapps.user-admin @@ -138,11 +138,7 @@ TUPLE: user-admin < dispatcher ; [ validate-username - - [ select-tuple 1 >>deleted update-tuple ] - [ logout-all-sessions ] - bi - + select-tuple 1 >>deleted update-tuple URL" $user-admin" ] >>submit ; From 65b8e375df14cf33eb8563e71861ed1001280ee1 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 03:34:23 -0500 Subject: [PATCH 0235/1850] Documentation fix --- core/inference/inference-docs.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/inference/inference-docs.factor b/core/inference/inference-docs.factor index 5900e5a844..7d43187f54 100755 --- a/core/inference/inference-docs.factor +++ b/core/inference/inference-docs.factor @@ -92,7 +92,7 @@ ARTICLE: "inference-errors" "Inference errors" { $subsection missing-effect } ; ARTICLE: "inference" "Stack effect inference" -"The stack effect inference tool is used to check correctness of code before it is run. It is also used by the compiler to build a dataflow graph on which optimizations can be performed. Only words for which a stack effect can be inferred will compile." +"The stack effect inference tool is used to check correctness of code before it is run. It is also used by the optimizing compiler to build a dataflow graph on which optimizations can be performed. Only words for which a stack effect can be inferred will compile with the optimizing compiler; all other words will be compiled with the non-optimizing compiler (see " { $link "compiler" } ")." $nl "The main entry point is a single word which takes a quotation and prints its stack effect and variable usage:" { $subsection infer. } From 73105cc043b425ce92ee283cb65a60fa4579bd05 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 03:46:54 -0500 Subject: [PATCH 0236/1850] Debugging furnace.auth refactoring --- extra/furnace/auth/auth.factor | 4 +++- .../auth/features/edit-profile/edit-profile.factor | 2 +- .../auth/features/edit-profile/edit-profile.xml | 2 +- extra/furnace/auth/login/login.factor | 12 ++++++------ extra/furnace/auth/login/login.xml | 4 ++-- extra/furnace/furnace.factor | 2 +- extra/webapps/blogs/blogs-common.xml | 8 ++++---- extra/webapps/pastebin/pastebin-common.xml | 8 ++++---- extra/webapps/planet/planet-common.xml | 8 ++++---- extra/webapps/todo/todo.xml | 6 +++--- extra/webapps/user-admin/user-admin.xml | 6 +++--- extra/webapps/wiki/wiki-common.xml | 8 ++++---- 12 files changed, 36 insertions(+), 34 deletions(-) diff --git a/extra/furnace/auth/auth.factor b/extra/furnace/auth/auth.factor index d10ba48ce5..9bb7ea105e 100755 --- a/extra/furnace/auth/auth.factor +++ b/extra/furnace/auth/auth.factor @@ -17,6 +17,8 @@ IN: furnace.auth SYMBOL: logged-in-user +: logged-in? ( -- ? ) logged-in-user get >boolean ; + GENERIC: init-user-profile ( responder -- ) M: object init-user-profile drop ; @@ -114,7 +116,7 @@ TUPLE: protected < filter-responder description capabilities ; : check-capabilities ( responder user/f -- ? ) { { [ dup not ] [ 2drop f ] } - { [ dup deleted>> ] [ 2drop f ] } + { [ dup deleted>> 1 = ] [ 2drop f ] } [ [ capabilities>> ] bi@ subset? ] } cond ; diff --git a/extra/furnace/auth/features/edit-profile/edit-profile.factor b/extra/furnace/auth/features/edit-profile/edit-profile.factor index 4edb4ac364..e03fca99a5 100644 --- a/extra/furnace/auth/features/edit-profile/edit-profile.factor +++ b/extra/furnace/auth/features/edit-profile/edit-profile.factor @@ -64,4 +64,4 @@ IN: furnace.auth.features.edit-profile "edit-profile" add-responder ; : allow-edit-profile? ( -- ? ) - realm get get responders>> "edit-profile" swap key? ; + realm get responders>> "edit-profile" swap key? ; diff --git a/extra/furnace/auth/features/edit-profile/edit-profile.xml b/extra/furnace/auth/features/edit-profile/edit-profile.xml index 6beaf5de6d..011cc2bdf8 100644 --- a/extra/furnace/auth/features/edit-profile/edit-profile.xml +++ b/extra/furnace/auth/features/edit-profile/edit-profile.xml @@ -4,7 +4,7 @@ Edit Profile - + diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 1f81c488cc..6a59c01c63 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -13,13 +13,16 @@ IN: furnace.auth.login TUPLE: login-realm < realm ; +M: login-realm logged-in-username + drop session get uid>> ; + : set-uid ( username -- ) session get [ (>>uid) ] [ (session-changed) ] bi ; : successful-login ( user -- response ) username>> set-uid URL" $realm" end-aside ; -: logout ( -- ) f set-uid ; +: logout ( -- ) f set-uid URL" $realm" end-aside ; SYMBOL: description SYMBOL: capabilities @@ -53,17 +56,14 @@ SYMBOL: capabilities : ( -- action ) - [ logout URL" $login-realm" end-aside ] >>submit ; + [ logout ] >>submit ; M: login-realm login-required* drop begin-aside protected get description>> description set protected get capabilities>> capabilities set - URL" $login/login" flashed-variables ; - -M: login-realm logged-in-username - drop session get uid>> ; + URL" $realm/login" flashed-variables ; : ( responder name -- auth ) login-realm new-realm diff --git a/extra/furnace/auth/login/login.xml b/extra/furnace/auth/login/login.xml index a7ac92bf44..81f9520e76 100644 --- a/extra/furnace/auth/login/login.xml +++ b/extra/furnace/auth/login/login.xml @@ -43,11 +43,11 @@

- + Register | - + Recover Password

diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index e9d1b29da8..6b47bc681b 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -31,7 +31,7 @@ IN: furnace : base-path ( string -- pair ) dup responder-nesting get - [ second class word-name = ] with find nip + [ second class superclasses [ word-name = ] with contains? ] with find nip [ first ] [ "No such responder: " swap append throw ] ?if ; : resolve-base-path ( string -- string' ) diff --git a/extra/webapps/blogs/blogs-common.xml b/extra/webapps/blogs/blogs-common.xml index 965f059abd..e809c0e7f5 100644 --- a/extra/webapps/blogs/blogs-common.xml +++ b/extra/webapps/blogs/blogs-common.xml @@ -12,13 +12,13 @@ | My Posts | New Post - + - - | Edit Profile + + | Edit Profile - | Logout + | Logout diff --git a/extra/webapps/pastebin/pastebin-common.xml b/extra/webapps/pastebin/pastebin-common.xml index 47f7666b22..b95f3f7b64 100644 --- a/extra/webapps/pastebin/pastebin-common.xml +++ b/extra/webapps/pastebin/pastebin-common.xml @@ -11,13 +11,13 @@ Pastes | New Paste - + - - | Edit Profile + + | Edit Profile - | Logout + | Logout diff --git a/extra/webapps/planet/planet-common.xml b/extra/webapps/planet/planet-common.xml index 34ee73da67..6c0affd17f 100644 --- a/extra/webapps/planet/planet-common.xml +++ b/extra/webapps/planet/planet-common.xml @@ -9,12 +9,12 @@ | Atom Feed | Admin - - - | Edit Profile + + + | Edit Profile - | Logout + | Logout diff --git a/extra/webapps/todo/todo.xml b/extra/webapps/todo/todo.xml index e087fbfcfc..f7500cdad2 100644 --- a/extra/webapps/todo/todo.xml +++ b/extra/webapps/todo/todo.xml @@ -8,11 +8,11 @@ List Items | Add Item - - | Edit Profile + + | Edit Profile - | Logout + | Logout

diff --git a/extra/webapps/user-admin/user-admin.xml b/extra/webapps/user-admin/user-admin.xml index 9cb9ef0a0a..2141fdc1d9 100644 --- a/extra/webapps/user-admin/user-admin.xml +++ b/extra/webapps/user-admin/user-admin.xml @@ -6,11 +6,11 @@ List Users | Add User - - | Edit Profile + + | Edit Profile - | Logout + | Logout

diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml index 1d08d3832d..0abd36a7cd 100644 --- a/extra/webapps/wiki/wiki-common.xml +++ b/extra/webapps/wiki/wiki-common.xml @@ -14,13 +14,13 @@ | All Articles | Recent Changes - + - - | Edit Profile + + | Edit Profile - | Logout + | Logout From c5a96c093b1a628300a669dc2cc0cfad02b34e42 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 05:16:21 -0500 Subject: [PATCH 0237/1850] Clean up base64 add add more tets --- extra/base64/base64-tests.factor | 20 +++++++++++++++----- extra/base64/base64.factor | 27 ++++++++++++--------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/extra/base64/base64-tests.factor b/extra/base64/base64-tests.factor index d867351f8b..86c58af505 100644 --- a/extra/base64/base64-tests.factor +++ b/extra/base64/base64-tests.factor @@ -1,8 +1,18 @@ USING: kernel tools.test base64 strings ; -[ "abcdefghijklmnopqrstuvwxyz" ] [ "abcdefghijklmnopqrstuvwxyz" >base64 base64> +[ "abcdefghijklmnopqrstuvwxyz" ] [ "abcdefghijklmnopqrstuvwxyz" >base64 base64> >string ] unit-test -[ "" ] [ "" >base64 base64> ] unit-test -[ "a" ] [ "a" >base64 base64> ] unit-test -[ "ab" ] [ "ab" >base64 base64> ] unit-test -[ "abc" ] [ "abc" >base64 base64> ] unit-test +[ "" ] [ "" >base64 base64> >string ] unit-test +[ "a" ] [ "a" >base64 base64> >string ] unit-test +[ "ab" ] [ "ab" >base64 base64> >string ] unit-test +[ "abc" ] [ "abc" >base64 base64> >string ] unit-test + +! From http://en.wikipedia.org/wiki/Base64 +[ "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=" ] +[ + "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure." + >base64 >string +] unit-test + +\ >base64 must-infer +\ base64> must-infer diff --git a/extra/base64/base64.factor b/extra/base64/base64.factor index 600a8f4c3d..d48abc2014 100644 --- a/extra/base64/base64.factor +++ b/extra/base64/base64.factor @@ -1,11 +1,10 @@ -USING: kernel math sequences namespaces io.binary splitting -grouping strings hashtables ; +USING: kernel math sequences io.binary splitting grouping ; IN: base64 r [ length ] keep r> find-last drop dup [ - 1- ] [ 2drop 0 ] if ; + >r [ length ] keep r> find-last drop dup [ - 1- ] [ 2drop 0 ] if ; inline : ch>base64 ( ch -- ch ) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" nth ; @@ -20,28 +19,26 @@ IN: base64 } nth ; : encode3 ( seq -- seq ) - be> 4 [ 3 swap - -6 * shift HEX: 3f bitand ch>base64 ] with map ; + be> 4 [ -6 * shift HEX: 3f bitand ch>base64 ] with B{ } map-as ; : decode4 ( str -- str ) - [ base64>ch ] map 0 [ swap 6 shift bitor ] reduce 3 >be ; + 0 [ base64>ch swap 6 shift bitor ] reduce 3 >be ; : >base64-rem ( str -- str ) - [ 3 0 pad-right encode3 ] keep length 1+ head 4 CHAR: = pad-right ; + [ 3 0 pad-right encode3 ] [ length 1+ ] bi head 4 CHAR: = pad-right ; PRIVATE> : >base64 ( seq -- base64 ) #! cut string into two pieces, convert 3 bytes at a time #! pad string with = when not enough bits - dup length dup 3 mod - cut swap - [ - 3 [ encode3 % ] each - dup empty? [ drop ] [ >base64-rem % ] if - ] "" make ; + dup length dup 3 mod - cut + [ 3 [ encode3 ] map concat ] + [ dup empty? [ drop "" ] [ >base64-rem ] if ] + bi* append ; : base64> ( base64 -- str ) #! input length must be a multiple of 4 - [ - [ 4 [ decode4 % ] each ] keep [ CHAR: = = not ] count-end - ] SBUF" " make swap [ dup pop* ] times >string ; - + [ 4 [ decode4 ] map concat ] + [ [ CHAR: = = not ] count-end ] + bi head* ; From e47e7ec30c1b980a13118df8b0919476ca34680a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 05:16:51 -0500 Subject: [PATCH 0238/1850] Login authentication is now stored outside of the session, allowing multiple independent login realms per site --- extra/furnace/alloy/alloy.factor | 5 +- extra/furnace/auth/auth-tests.factor | 6 ++ extra/furnace/auth/auth.factor | 9 +-- extra/furnace/auth/basic/basic.factor | 10 ++-- .../features/registration/registration.factor | 2 +- extra/furnace/auth/login/login.factor | 56 +++++++++++++++---- .../furnace/auth/login/permits/permits.factor | 30 ++++++++++ .../auth/providers/assoc/assoc-tests.factor | 6 +- extra/furnace/furnace.factor | 13 +++++ extra/furnace/sessions/sessions.factor | 24 ++------ extra/http/http.factor | 12 +++- extra/http/server/static/static.factor | 2 +- extra/webapps/wiki/wiki.factor | 7 ++- 13 files changed, 131 insertions(+), 51 deletions(-) create mode 100644 extra/furnace/auth/auth-tests.factor create mode 100644 extra/furnace/auth/login/permits/permits.factor diff --git a/extra/furnace/alloy/alloy.factor b/extra/furnace/alloy/alloy.factor index 14ffbaba9d..28c34e6715 100644 --- a/extra/furnace/alloy/alloy.factor +++ b/extra/furnace/alloy/alloy.factor @@ -7,7 +7,8 @@ furnace.flash furnace.sessions furnace.referrer furnace.db -furnace.auth.providers ; +furnace.auth.providers +furnace.auth.login.permits ; IN: furnace.alloy : ( responder db params -- responder' ) @@ -19,7 +20,7 @@ IN: furnace.alloy ] call ; -: state-classes { session flash-scope aside } ; inline +: state-classes { session flash-scope aside permit } ; inline : init-furnace-tables ( -- ) state-classes ensure-tables diff --git a/extra/furnace/auth/auth-tests.factor b/extra/furnace/auth/auth-tests.factor new file mode 100644 index 0000000000..220a8cd04c --- /dev/null +++ b/extra/furnace/auth/auth-tests.factor @@ -0,0 +1,6 @@ +USING: furnace.auth tools.test ; +IN: furnace.auth.tests + +\ logged-in-username must-infer +\ must-infer +\ new-realm must-infer diff --git a/extra/furnace/auth/auth.factor b/extra/furnace/auth/auth.factor index 9bb7ea105e..d9f517aaf4 100755 --- a/extra/furnace/auth/auth.factor +++ b/extra/furnace/auth/auth.factor @@ -82,15 +82,12 @@ M: user-saver dispose : save-user-after ( user -- ) &dispose drop ; -: init-user ( realm -- ) - logged-in-username [ - users get-user - [ logged-in-user set ] [ save-user-after ] bi - ] when* ; +: init-user ( user -- ) + [ [ logged-in-user set ] [ save-user-after ] bi ] when* ; M: realm call-responder* ( path responder -- response ) dup realm set - dup init-user + dup logged-in-username dup [ users get-user ] when init-user call-next-method ; : encode-password ( string salt -- bytes ) diff --git a/extra/furnace/auth/basic/basic.factor b/extra/furnace/auth/basic/basic.factor index ae9cbb82c1..e478f70dcc 100755 --- a/extra/furnace/auth/basic/basic.factor +++ b/extra/furnace/auth/basic/basic.factor @@ -1,17 +1,18 @@ ! Copyright (c) 2007 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel splitting base64 namespaces +USING: accessors kernel splitting base64 namespaces strings http http.server.responses furnace.auth ; IN: furnace.auth.basic TUPLE: basic-auth-realm < realm ; -C: basic-auth-realm +: ( responder name -- realm ) + basic-auth-realm new-realm ; : parse-basic-auth ( header -- username/f password/f ) dup [ " " split1 swap "Basic" = [ - base64> ":" split1 + base64> >string ":" split1 ] [ drop f f ] if ] [ drop f f ] if ; @@ -23,5 +24,6 @@ M: basic-auth-realm login-required* ( realm -- response ) name>> <401> ; M: basic-auth-realm logged-in-username ( realm -- uid ) + drop request get "authorization" header parse-basic-auth - dup [ over realm get check-login swap and ] [ 2drop f ] if ; + dup [ over check-login swap and ] [ 2drop f ] if ; diff --git a/extra/furnace/auth/features/registration/registration.factor b/extra/furnace/auth/features/registration/registration.factor index 3deead4869..2bc7688b10 100644 --- a/extra/furnace/auth/features/registration/registration.factor +++ b/extra/furnace/auth/features/registration/registration.factor @@ -7,7 +7,7 @@ IN: furnace.auth.features.registration : ( -- action ) - { realm "register" } >>template + { realm "features/registration/register" } >>template [ { diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 6a59c01c63..e2b208de3a 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -1,28 +1,57 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: kernel accessors namespaces validators urls -html.forms -http.server.dispatchers +USING: kernel accessors namespaces sequences math.parser +calendar validators urls html.forms +http http.server http.server.dispatchers +furnace furnace.auth furnace.flash furnace.asides furnace.actions furnace.sessions -furnace.utilities ; +furnace.utilities +furnace.auth.login.permits ; IN: furnace.auth.login -TUPLE: login-realm < realm ; +SYMBOL: permit-id + +: permit-id-key ( realm -- string ) + [ >hex 2 CHAR: 0 pad-left ] { } map-as concat + "__p_" prepend ; + +: client-permit-id ( realm -- id/f ) + permit-id-key client-state dup [ string>number ] when ; + +TUPLE: login-realm < realm timeout domain ; + +M: login-realm call-responder* + [ name>> client-permit-id permit-id set ] + [ call-next-method ] + bi ; M: login-realm logged-in-username - drop session get uid>> ; + drop permit-id get dup [ get-permit-uid ] when ; -: set-uid ( username -- ) - session get [ (>>uid) ] [ (session-changed) ] bi ; +M: login-realm modify-form ( responder -- ) + drop permit-id get realm get name>> permit-id-key hidden-form-field ; + +: ( -- cookie ) + permit-id get realm get name>> permit-id-key + "$login-realm" resolve-base-path >>path + realm get timeout>> from-now >>expires + realm get domain>> >>domain ; + +: put-permit-cookie ( response -- response' ) + put-cookie ; : successful-login ( user -- response ) - username>> set-uid URL" $realm" end-aside ; + [ username>> make-permit permit-id set ] [ init-user ] bi + URL" $realm" end-aside + put-permit-cookie ; -: logout ( -- ) f set-uid URL" $realm" end-aside ; +: logout ( -- ) + permit-id get [ delete-permit ] when* + URL" $realm" end-aside ; SYMBOL: description SYMBOL: capabilities @@ -56,7 +85,9 @@ SYMBOL: capabilities : ( -- action ) - [ logout ] >>submit ; + [ logout ] >>submit + + "logout" >>description ; M: login-realm login-required* drop @@ -68,4 +99,5 @@ M: login-realm login-required* : ( responder name -- auth ) login-realm new-realm "login" add-responder - "logout" add-responder ; + "logout" add-responder + 20 minutes >>timeout ; diff --git a/extra/furnace/auth/login/permits/permits.factor b/extra/furnace/auth/login/permits/permits.factor new file mode 100644 index 0000000000..49cf98e0e3 --- /dev/null +++ b/extra/furnace/auth/login/permits/permits.factor @@ -0,0 +1,30 @@ +USING: accessors namespaces combinators.lib kernel +db.tuples db.types +furnace.auth furnace.sessions furnace.cache ; +IN: furnace.auth.login.permits + +TUPLE: permit < server-state session uid ; + +permit "PERMITS" { + { "session" "SESSION" BIG-INTEGER +not-null+ } + { "uid" "UID" { VARCHAR 255 } +not-null+ } +} define-persistent + +: touch-permit ( permit -- ) + realm get touch-state ; + +: get-permit-uid ( id -- uid ) + permit get-state { + [ ] + [ session>> session get id>> = ] + [ [ touch-permit ] [ uid>> ] bi ] + } 1&& ; + +: make-permit ( uid -- id ) + permit new + swap >>uid + session get id>> >>session + [ touch-permit ] [ insert-tuple ] [ id>> ] tri ; + +: delete-permit ( id -- ) + permit new-server-state delete-tuples ; diff --git a/extra/furnace/auth/providers/assoc/assoc-tests.factor b/extra/furnace/auth/providers/assoc/assoc-tests.factor index 8f9eeaa7a5..8fe1dd4dd4 100755 --- a/extra/furnace/auth/providers/assoc/assoc-tests.factor +++ b/extra/furnace/auth/providers/assoc/assoc-tests.factor @@ -1,11 +1,11 @@ IN: furnace.auth.providers.assoc.tests -USING: furnace.actions furnace.auth.providers +USING: furnace.actions furnace.auth furnace.auth.providers furnace.auth.providers.assoc furnace.auth.login tools.test namespaces accessors kernel ; - + "Test" >>users -login set +realm set [ t ] [ "slava" diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index 6b47bc681b..521f8a3bc1 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -96,6 +96,19 @@ M: object modify-form drop ; request get url>> [ [ protocol>> ] [ host>> ] [ port>> ] tri 3array ] bi@ = ; +: cookie-client-state ( key request -- value/f ) + swap get-cookie dup [ value>> ] when ; + +: post-client-state ( key request -- value/f ) + request-params at ; + +: client-state ( key -- value/f ) + request get dup method>> { + { "GET" [ cookie-client-state ] } + { "HEAD" [ cookie-client-state ] } + { "POST" [ post-client-state ] } + } case ; + SYMBOL: exit-continuation : exit-with ( value -- ) diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index fe8053fc9c..bb0a844269 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -98,20 +98,6 @@ M: session-saver dispose : session-id-key "__s" ; -: cookie-session-id ( request -- id/f ) - session-id-key get-cookie - dup [ value>> string>number ] when ; - -: post-session-id ( request -- id/f ) - session-id-key swap request-params at string>number ; - -: request-session-id ( -- id/f ) - request get dup method>> { - { "GET" [ cookie-session-id ] } - { "HEAD" [ cookie-session-id ] } - { "POST" [ post-session-id ] } - } case ; - : verify-session ( session -- session ) sessions get verify?>> [ dup [ @@ -123,16 +109,18 @@ M: session-saver dispose ] when ; : request-session ( -- session/f ) - request-session-id get-session verify-session ; + session-id-key + client-state dup [ string>number ] when + get-session verify-session ; -: ( id -- cookie ) - session-id-key +: ( -- cookie ) + session get id>> session-id-key "$sessions" resolve-base-path >>path sessions get timeout>> from-now >>expires sessions get domain>> >>domain ; : put-session-cookie ( response -- response' ) - session get id>> number>string put-cookie ; + put-cookie ; M: sessions modify-form ( responder -- ) drop session get id>> session-id-key hidden-form-field ; diff --git a/extra/http/http.factor b/extra/http/http.factor index d2a0b0f922..025e2c8441 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -99,23 +99,29 @@ TUPLE: cookie name value path domain expires max-age http-only ; drop ] { } make ; +: check-cookie-string ( string -- string' ) + dup "=;'\"" intersect empty? + [ "Bad cookie name or value" throw ] unless ; + : (unparse-cookie) ( key value -- ) { { f [ drop ] } - { t [ , ] } + { t [ check-cookie-string , ] } [ { { [ dup timestamp? ] [ timestamp>cookie-string ] } { [ dup duration? ] [ dt>seconds number>string ] } + { [ dup real? ] [ number>string ] } [ ] } cond - "=" swap 3append , + check-cookie-string "=" swap check-cookie-string 3append , ] } case ; : unparse-cookie ( cookie -- strings ) [ - dup name>> >lower over value>> (unparse-cookie) + dup name>> check-cookie-string >lower + over value>> (unparse-cookie) "path" over path>> (unparse-cookie) "domain" over domain>> (unparse-cookie) "expires" over expires>> (unparse-cookie) diff --git a/extra/http/server/static/static.factor b/extra/http/server/static/static.factor index 9d76c82e4a..83fcf6f4a9 100755 --- a/extra/http/server/static/static.factor +++ b/extra/http/server/static/static.factor @@ -82,7 +82,7 @@ TUPLE: file-responder root hook special allow-listings ; "index.html" append-path dup exists? [ drop f ] unless ; : serve-directory ( filename -- response ) - request get path>> "/" tail? [ + request get url>> path>> "/" tail? [ dup find-index [ serve-file ] [ list-directory ] ?if ] [ diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 34bad6db18..13c445b0a8 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -284,6 +284,11 @@ M: revision feed-entry-url id>> revision-url ; { wiki "page-common" } >>template ; +: init-sidebar ( -- ) + "Sidebar" latest-revision [ + "sidebar" [ from-object ] nest-form + ] when* ; + : ( -- dispatcher ) wiki new-dispatcher "" add-responder @@ -301,5 +306,5 @@ M: revision feed-entry-url id>> revision-url ; "changes.atom" add-responder "delete" add-responder - [ "sidebar" [ "Sidebar" latest-revision from-object ] nest-form ] >>init + [ init-sidebar ] >>init { wiki "wiki-common" } >>template ; From 12b79b287ff23805a089dfe3aca723a1982ebeb5 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Jun 2008 05:17:26 -0500 Subject: [PATCH 0239/1850] Remove unused slot --- extra/furnace/sessions/sessions.factor | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index bb0a844269..863b8f87cb 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -9,14 +9,13 @@ html.elements furnace furnace.cache ; IN: furnace.sessions -TUPLE: session < server-state uid namespace user-agent client changed? ; +TUPLE: session < server-state namespace user-agent client changed? ; : ( id -- session ) session new-server-state ; session "SESSIONS" { - { "uid" "UID" { VARCHAR 255 } } { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ } { "user-agent" "USER_AGENT" TEXT +not-null+ } { "client" "CLIENT" TEXT +not-null+ } From 285c34696f85b8d2840b9399c9ba7801e248a490 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Mon, 16 Jun 2008 16:28:49 -0500 Subject: [PATCH 0240/1850] dns: minor addition --- extra/dns/dns.factor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extra/dns/dns.factor b/extra/dns/dns.factor index 48380a0d57..214b45ce0c 100644 --- a/extra/dns/dns.factor +++ b/extra/dns/dns.factor @@ -424,6 +424,10 @@ SYMBOLS: NO-ERROR FORMAT-ERROR SERVER-FAILURE NAME-ERROR NOT-IMPLEMENTED } 2cleave message boa ; +: ba->message ( ba -- message ) parse-message ; + +: with-message-bytes ( ba quot -- ) >r ba->message r> call message->ba ; inline + ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : send-receive-udp ( ba server -- ba ) From e60f25fe2b01ed56e42a1ae40bcb479cd6423084 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Mon, 16 Jun 2008 16:29:11 -0500 Subject: [PATCH 0241/1850] dns.util: packet abstraction --- extra/dns/util/util.factor | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/extra/dns/util/util.factor b/extra/dns/util/util.factor index 5933216a3c..35af74b92a 100644 --- a/extra/dns/util/util.factor +++ b/extra/dns/util/util.factor @@ -16,4 +16,15 @@ MACRO: 1if ( test then else -- ) '[ dup @ , , if ] ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: longer? ( seq seq -- ? ) [ length ] bi@ > ; \ No newline at end of file +: longer? ( seq seq -- ? ) [ length ] bi@ > ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +USING: io.sockets accessors ; + +TUPLE: packet data addr socket ; + +: receive-packet ( socket -- packet ) [ receive ] keep packet boa ; + +: respond ( packet -- ) [ data>> ] [ addr>> ] [ socket>> ] tri send ; + From aa1708d0b586d29b1500a2ea24f0770b91993119 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Mon, 16 Jun 2008 16:29:49 -0500 Subject: [PATCH 0242/1850] dns.server: new networking code --- extra/dns/server/server.factor | 38 ++++++++-------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/extra/dns/server/server.factor b/extra/dns/server/server.factor index b556780805..3d59f0c3a6 100644 --- a/extra/dns/server/server.factor +++ b/extra/dns/server/server.factor @@ -1,6 +1,6 @@ -USING: kernel combinators sequences sets math threads - io.sockets unicode.case accessors +USING: kernel combinators sequences sets math threads namespaces continuations + debugger io io.sockets unicode.case accessors destructors combinators.cleave combinators.lib newfx fry dns dns.util dns.misc ; @@ -193,34 +193,14 @@ DEFER: query->rrs ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: (socket) ( -- vec ) V{ f } ; +: (handle-request) ( packet -- ) + [ [ find-answer ] with-message-bytes ] change-data respond ; -: socket ( -- socket ) (socket) 1st ; +: handle-request ( packet -- ) [ (handle-request) ] curry in-thread ; -: init-socket-on-port ( port -- ) - f swap 0 (socket) as-mutate ; +: receive-loop ( socket -- ) + [ receive-packet handle-request ] [ receive-loop ] bi ; -: init-socket ( -- ) 53 init-socket-on-port ; +: loop ( addr-spec -- ) + [ '[ , [ receive-loop ] with-disposal ] try ] [ loop ] bi ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -: (handle-request) ( byte-array addr-spec -- ) - >r - parse-message - find-answer - message->ba - r> - socket send ; - -: handle-request ( byte-array addr-spec -- ) - '[ , , (handle-request) ] in-thread ; - -: loop ( -- ) socket receive handle-request loop ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -: start ( -- ) init-socket loop ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -MAIN: start From 61fb8a538eb515d12c1b03b8af2a6c5b17fe43e8 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Mon, 16 Jun 2008 16:37:52 -0500 Subject: [PATCH 0243/1850] dns.server: Use a variable for records --- extra/dns/server/server.factor | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extra/dns/server/server.factor b/extra/dns/server/server.factor index 3d59f0c3a6..04b3ecfbee 100644 --- a/extra/dns/server/server.factor +++ b/extra/dns/server/server.factor @@ -9,7 +9,9 @@ IN: dns.server ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: records ( -- vector ) V{ } ; +SYMBOL: records-var + +: records ( -- records ) records-var get ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! From 0a436e1184a2c6e56315ac8efb4e1937d6e4aad4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 00:04:18 -0500 Subject: [PATCH 0244/1850] New threaded-server --- extra/io/server/server-docs.factor | 10 -- extra/io/server/server-tests.factor | 7 - extra/io/server/server.factor | 76 ---------- extra/io/server/summary.txt | 1 - .../connection}/authors.txt | 0 .../servers/connection/connection-docs.factor | 2 + .../connection/connection-tests.factor | 47 +++++++ extra/io/servers/connection/connection.factor | 131 ++++++++++++++++++ extra/io/servers/connection/summary.txt | 1 + .../{server => servers/connection}/tags.txt | 0 extra/io/servers/packet/authors.txt | 1 + extra/io/servers/packet/datagram.factor | 21 +++ extra/io/servers/packet/summary.txt | 1 + extra/io/servers/packet/tags.txt | 1 + extra/io/sockets/secure/secure-tests.factor | 5 +- extra/io/sockets/secure/secure.factor | 13 +- extra/io/sockets/sockets-docs.factor | 20 +-- extra/io/sockets/sockets-tests.factor | 2 +- extra/io/sockets/sockets.factor | 27 ++-- 19 files changed, 245 insertions(+), 121 deletions(-) delete mode 100755 extra/io/server/server-docs.factor delete mode 100755 extra/io/server/server-tests.factor delete mode 100755 extra/io/server/server.factor delete mode 100644 extra/io/server/summary.txt rename extra/io/{server => servers/connection}/authors.txt (100%) mode change 100755 => 100644 create mode 100755 extra/io/servers/connection/connection-docs.factor create mode 100755 extra/io/servers/connection/connection-tests.factor create mode 100755 extra/io/servers/connection/connection.factor create mode 100644 extra/io/servers/connection/summary.txt rename extra/io/{server => servers/connection}/tags.txt (100%) create mode 100755 extra/io/servers/packet/authors.txt create mode 100644 extra/io/servers/packet/datagram.factor create mode 100644 extra/io/servers/packet/summary.txt create mode 100644 extra/io/servers/packet/tags.txt diff --git a/extra/io/server/server-docs.factor b/extra/io/server/server-docs.factor deleted file mode 100755 index 50f38cb146..0000000000 --- a/extra/io/server/server-docs.factor +++ /dev/null @@ -1,10 +0,0 @@ -USING: help help.syntax help.markup io ; -IN: io.server - -HELP: with-server -{ $values { "seq" "a sequence of address specifiers" } { "service" "a string or " { $link f } } { "encoding" "an encoding to use for client connections" } { "quot" "a quotation" } } -{ $description "Starts a TCP/IP server. The quotation is called in a new thread for each client connection, with the client connection being both the " { $link input-stream } " and " { $link output-stream } "." } ; - -HELP: with-datagrams -{ $values { "seq" "a sequence of address specifiers" } { "service" "a string or " { $link f } } { "quot" "a quotation" } } -{ $description "Starts a UDP/IP server. The quotation is called for each datagram packet received." } ; diff --git a/extra/io/server/server-tests.factor b/extra/io/server/server-tests.factor deleted file mode 100755 index 965a70718b..0000000000 --- a/extra/io/server/server-tests.factor +++ /dev/null @@ -1,7 +0,0 @@ -IN: io.server.tests -USING: tools.test io.server io.server.private kernel ; - -{ 2 0 } [ [ ] server-loop ] must-infer-as -{ 3 0 } [ [ ] with-connection ] must-infer-as -{ 1 0 } [ [ ] swap datagram-loop ] must-infer-as -{ 2 0 } [ [ ] with-datagrams ] must-infer-as diff --git a/extra/io/server/server.factor b/extra/io/server/server.factor deleted file mode 100755 index e975880a14..0000000000 --- a/extra/io/server/server.factor +++ /dev/null @@ -1,76 +0,0 @@ -! Copyright (C) 2003, 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: io io.sockets io.sockets.secure io.files -io.streams.duplex logging continuations destructors kernel math -math.parser namespaces parser sequences strings prettyprint -debugger quotations calendar threads concurrency.combinators -assocs fry accessors arrays ; -IN: io.server - -SYMBOL: servers - -SYMBOL: remote-address - -> ] bi ] dip - '[ , , , , with-connection ] "Client" spawn drop - ] 2keep accept-loop ; inline - -: server-loop ( addrspec encoding quot -- ) - >r dup servers get push r> - '[ , accept-loop ] with-disposal ; inline - -\ server-loop NOTICE add-error-logging - -PRIVATE> - -: local-server ( port -- seq ) - "localhost" swap t resolve-host ; - -: internet-server ( port -- seq ) - f swap t resolve-host ; - -: secure-server ( port -- seq ) - internet-server [ ] map ; - -: with-server ( seq service encoding quot -- ) - V{ } clone servers [ - '[ , [ , , server-loop ] with-logging ] parallel-each - ] with-variable ; inline - -: stop-server ( -- ) - servers get dispose-each ; - - [ datagram-loop ] with-disposal ; inline - -\ spawn-datagrams NOTICE add-input-logging - -PRIVATE> - -: with-datagrams ( seq service quot -- ) - '[ [ , _ spawn-datagrams ] parallel-each ] with-logging ; inline diff --git a/extra/io/server/summary.txt b/extra/io/server/summary.txt deleted file mode 100644 index e791b704eb..0000000000 --- a/extra/io/server/summary.txt +++ /dev/null @@ -1 +0,0 @@ -TCP/IP and UDP/IP servers diff --git a/extra/io/server/authors.txt b/extra/io/servers/connection/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from extra/io/server/authors.txt rename to extra/io/servers/connection/authors.txt diff --git a/extra/io/servers/connection/connection-docs.factor b/extra/io/servers/connection/connection-docs.factor new file mode 100755 index 0000000000..b033ec287c --- /dev/null +++ b/extra/io/servers/connection/connection-docs.factor @@ -0,0 +1,2 @@ +USING: help help.syntax help.markup io ; +IN: io.servers.connection diff --git a/extra/io/servers/connection/connection-tests.factor b/extra/io/servers/connection/connection-tests.factor new file mode 100755 index 0000000000..bb87d67917 --- /dev/null +++ b/extra/io/servers/connection/connection-tests.factor @@ -0,0 +1,47 @@ +IN: io.servers.connection +USING: tools.test io.servers.connection io.sockets namespaces +io.servers.connection.private kernel accessors sequences +concurrency.promises io.encodings.ascii io threads calendar ; + +[ t ] [ listen-on empty? ] unit-test + +[ f ] [ + + 25 internet-server >>insecure + listen-on + empty? +] unit-test + +[ t ] [ + T{ inet4 "1.2.3.4" 1234 } T{ inet4 "1.2.3.5" 1235 } + [ log-connection ] 2keep + [ remote-address get = ] [ local-address get = ] bi* + and +] unit-test + +[ ] [ init-server drop ] unit-test + +[ 10 ] [ + + 10 >>max-connections + init-server semaphore>> count>> +] unit-test + +[ ] [ "p" set ] unit-test + +[ ] [ + [ + + 5 >>max-connections + 1237 >>insecure + [ "Hello world." write stop-server ] >>handler + start-server + t "p" get fulfill + ] in-thread +] unit-test + +[ ] [ 100 sleep ] unit-test + +[ "Hello world." ] [ "localhost" 1237 ascii drop contents ] unit-test + +[ t ] [ "p" get 2 seconds ?promise-timeout ] unit-test diff --git a/extra/io/servers/connection/connection.factor b/extra/io/servers/connection/connection.factor new file mode 100755 index 0000000000..f01112a70f --- /dev/null +++ b/extra/io/servers/connection/connection.factor @@ -0,0 +1,131 @@ +! Copyright (C) 2003, 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: continuations destructors kernel math math.parser +namespaces parser sequences strings prettyprint debugger +quotations combinators combinators.lib logging calendar assocs +fry accessors arrays io io.sockets io.encodings.ascii +io.sockets.secure io.files io.streams.duplex io.timeouts +io.encodings threads concurrency.combinators +concurrency.semaphores ; +IN: io.servers.connection + +TUPLE: threaded-server +name +secure insecure +secure-config +sockets +max-connections +semaphore +timeout +encoding +handler ; + +: local-server ( port -- addrspec ) "localhost" swap ; + +: internet-server ( port -- addrspec ) f swap ; + +: new-threaded-server ( class -- threaded-server ) + new + "server" >>name + ascii >>encoding + 1 minutes >>timeout + V{ } clone >>sockets + >>secure-config + [ "No handler quotation" throw ] >>handler ; inline + +: ( -- threaded-server ) + threaded-server new-threaded-server ; + +SYMBOL: remote-address + +GENERIC: handle-client* ( server -- ) + +insecure ( addrspec -- addrspec' ) + dup { [ integer? ] [ string? ] } 1|| [ internet-server ] when ; + +: >secure ( addrspec -- addrspec' ) + >insecure + dup { [ secure? ] [ not ] } 1|| [ ] unless ; + +: listen-on ( threaded-server -- addrspecs ) + [ secure>> >secure ] [ insecure>> >insecure ] bi + [ resolve-host ] bi@ append ; + +LOG: accepted-connection NOTICE + +: log-connection ( remote local -- ) + [ [ remote-address set ] [ local-address set ] bi* ] + [ 2array accepted-connection ] + 2bi ; + +M: threaded-server handle-client* handler>> call ; + +: handle-client ( client remote local -- ) + '[ + , , log-connection + threaded-server get + [ timeout>> timeouts ] [ handle-client* ] bi + ] with-stream ; + +: thread-name ( server-name addrspec -- string ) + unparse " connection from " swap 3append ; + +: accept-connection ( server -- ) + [ accept ] [ addr>> ] bi + [ '[ , , , handle-client ] ] + [ drop threaded-server get name>> swap thread-name ] 2bi + spawn drop ; + +: accept-loop ( server -- ) + [ + threaded-server get semaphore>> + [ [ accept-connection ] with-semaphore ] + [ accept-connection ] + if* + ] [ accept-loop ] bi ; inline + +\ accept-loop ERROR add-error-logging + +: start-accept-loop ( server -- ) + threaded-server get encoding>> + [ threaded-server get sockets>> push ] + [ [ accept-loop ] with-disposal ] + bi ; + +: init-server ( threaded-server -- threaded-server ) + dup semaphore>> [ + dup max-connections>> [ + >>semaphore + ] when* + ] unless ; + +PRIVATE> + +: start-server ( threaded-server -- ) + init-server + dup secure-config>> [ + dup threaded-server [ + dup name>> [ + listen-on [ + start-accept-loop + ] parallel-each + ] with-logging + ] with-variable + ] with-secure-context ; + +: stop-server ( -- ) + threaded-server get [ f ] change-sockets drop dispose-each ; + +GENERIC: port ( addrspec -- n ) + +M: integer port ; + +M: object port port>> ; + +: secure-port ( -- n ) + threaded-server get dup [ secure>> port ] when ; + +: insecure-port ( -- n ) + threaded-server get dup [ insecure>> port ] when ; diff --git a/extra/io/servers/connection/summary.txt b/extra/io/servers/connection/summary.txt new file mode 100644 index 0000000000..8269ecfc38 --- /dev/null +++ b/extra/io/servers/connection/summary.txt @@ -0,0 +1 @@ +Multi-threaded TCP/IP servers diff --git a/extra/io/server/tags.txt b/extra/io/servers/connection/tags.txt similarity index 100% rename from extra/io/server/tags.txt rename to extra/io/servers/connection/tags.txt diff --git a/extra/io/servers/packet/authors.txt b/extra/io/servers/packet/authors.txt new file mode 100755 index 0000000000..1901f27a24 --- /dev/null +++ b/extra/io/servers/packet/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/extra/io/servers/packet/datagram.factor b/extra/io/servers/packet/datagram.factor new file mode 100644 index 0000000000..03596ee43c --- /dev/null +++ b/extra/io/servers/packet/datagram.factor @@ -0,0 +1,21 @@ +IN: io.servers.datagram + + [ datagram-loop ] with-disposal ; inline + +\ spawn-datagrams NOTICE add-input-logging + +PRIVATE> + +: with-datagrams ( seq service quot -- ) + '[ [ , _ spawn-datagrams ] parallel-each ] with-logging ; inline diff --git a/extra/io/servers/packet/summary.txt b/extra/io/servers/packet/summary.txt new file mode 100644 index 0000000000..29247a2937 --- /dev/null +++ b/extra/io/servers/packet/summary.txt @@ -0,0 +1 @@ +Multi-threaded UDP/IP servers diff --git a/extra/io/servers/packet/tags.txt b/extra/io/servers/packet/tags.txt new file mode 100644 index 0000000000..992ae12982 --- /dev/null +++ b/extra/io/servers/packet/tags.txt @@ -0,0 +1 @@ +network diff --git a/extra/io/sockets/secure/secure-tests.factor b/extra/io/sockets/secure/secure-tests.factor index 9b9436a8db..75ac39e190 100644 --- a/extra/io/sockets/secure/secure-tests.factor +++ b/extra/io/sockets/secure/secure-tests.factor @@ -1 +1,4 @@ -! No unit tests here, until Windows SSL is implemented +IN: io.sockets.secure.tests +USING: io.sockets.secure tools.test ; + +[ "hello" 24 ] [ "hello" 24 [ host>> ] [ port>> ] bi ] unit-test diff --git a/extra/io/sockets/secure/secure.factor b/extra/io/sockets/secure/secure.factor index 448a5cdda0..10aec22ee5 100644 --- a/extra/io/sockets/secure/secure.factor +++ b/extra/io/sockets/secure/secure.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel symbols namespaces continuations -destructors io.sockets sequences inspector calendar ; +destructors io.sockets sequences inspector calendar delegate ; IN: io.sockets.secure SYMBOL: secure-socket-timeout @@ -42,8 +42,10 @@ TUPLE: secure addrspec ; C: secure -: resolve-secure-host ( host port passive? -- seq ) - resolve-host [ ] map ; +CONSULT: inet secure addrspec>> ; + +M: secure resolve-host ( secure -- seq ) + addrspec>> resolve-host [ ] map ; HOOK: check-certificate secure-socket-backend ( host handle -- ) @@ -53,9 +55,8 @@ PREDICATE: secure-inet < secure addrspec>> inet? ; M: secure-inet (client) [ - addrspec>> - [ [ host>> ] [ port>> ] bi f resolve-secure-host (client) >r |dispose r> ] keep - host>> pick handle>> check-certificate + [ resolve-host (client) [ |dispose ] dip ] keep + addrspec>> host>> pick handle>> check-certificate ] with-destructors ; PRIVATE> diff --git a/extra/io/sockets/sockets-docs.factor b/extra/io/sockets/sockets-docs.factor index 78cddd5d3b..6aa46ccdbc 100755 --- a/extra/io/sockets/sockets-docs.factor +++ b/extra/io/sockets/sockets-docs.factor @@ -27,7 +27,7 @@ $nl { { $link inet4 } " - a TCP/IP connection to an IPv4 address and port number; no name lookup is performed" } { { $link inet6 } " - a TCP/IP connection to an IPv6 address and port number; no name lookup is performed" } } -"The " { $vocab-link "io.server" } " library defines a nice high-level wrapper around " { $link } " which makes it easy to listen for IPv4 and IPv6 connections simultaneously, perform logging, and optionally only allow connections from the loopback interface." +"The " { $vocab-link "io.servers.connection" } " library defines high-level wrappers around " { $link } " which makes it easy to listen for IPv4, IPv6 and secure socket connections simultaneously, perform logging, and optionally only allow connections from the loopback interface." { $see-also "io.sockets.secure" } ; ARTICLE: "network-packet" "Packet-oriented networking" @@ -79,7 +79,7 @@ HELP: inet HELP: inet4 { $class-description "IPv4 address/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the IPv4 address and port number, respectively. New instances are created by calling " { $link } "." } { $notes -"New instances should not be created directly; instead, use " { $link resolve-host } " to look up the address associated to a host name. Also, try to support IPv6 where possible." +"Most applications do not operate on IPv4 addresses directly, and instead should use " { $link resolve-host } " to look up the address associated to a host name. Also, try to support IPv6 where possible." } { $examples { $code "\"127.0.0.1\" 8080 " } @@ -88,7 +88,7 @@ HELP: inet4 HELP: inet6 { $class-description "IPv6 address/port number specifier for TCP/IP and UDP/IP connections. The " { $snippet "host" } " and " { $snippet "port" } " slots hold the IPv6 address and port number, respectively. New instances are created by calling " { $link } "." } { $notes -"New instances should not be created directly; instead, use " { $link resolve-host } " to look up the address associated to a host name." } +"Most applications do not operate on IPv6 addresses directly, and instead should use " { $link resolve-host } " to look up the address associated to a host name." } { $examples { $code "\"::1\" 8080 " } } ; @@ -118,10 +118,10 @@ HELP: } { $notes "To start a TCP/IP server which listens for connections from any host, use an address specifier returned by the following code, where 1234 is the desired port number:" - { $code "f 1234 t resolve-host" } + { $code "f 1234 resolve-host" } "To start a server which listens for connections from the loopback interface only, use an address specifier returned by the following code, where 1234 is the desired port number:" - { $code "\"localhost\" 1234 t resolve-host" } - "Since " { $link resolve-host } " can return multiple address specifiers, your server code must listen on them all to work properly. The " { $vocab-link "io.server" } " vocabulary can be used to help with this." + { $code "\"localhost\" 1234 resolve-host" } + "Since " { $link resolve-host } " can return multiple address specifiers, your server code must listen on them all to work properly. The " { $vocab-link "io.servers.connection" } " vocabulary can be used to help with this." $nl "To start a TCP/IP server which listens for connections on a randomly-assigned port, set the port number in the address specifier to 0, and then read the " { $snippet "addr" } " slot of the server instance to obtain the actual port number it is listening on:" { $unchecked-example @@ -148,9 +148,9 @@ HELP: } { $notes "To accept UDP/IP packets from any host, use an address specifier returned by the following code, where 1234 is the desired port number:" - { $code "f 1234 t resolve-host" } + { $code "f 1234 resolve-host" } "To accept UDP/IP packets from the loopback interface only, use an address specifier returned by the following code, where 1234 is the desired port number:" - { $code "\"localhost\" 1234 t resolve-host" } + { $code "\"localhost\" 1234 resolve-host" } "Since " { $link resolve-host } " can return multiple address specifiers, your code must create a datagram socket for each one and co-ordinate packet sending accordingly." "Datagrams are low-level binary ports that don't map onto streams, so the constructor does not use an encoding" } @@ -165,3 +165,7 @@ HELP: send { $values { "packet" byte-array } { "addrspec" "an address specifier" } { "datagram" "a datagram socket" } } { $description "Sends a packet to the given address." } { $errors "Throws an error if the packet could not be sent." } ; + +HELP: resolve-host +{ $values { "addrspec" "an address specifier" } { "seq" "a sequence of address specifiers" } } +{ $description "Resolves host names to IP addresses." } ; diff --git a/extra/io/sockets/sockets-tests.factor b/extra/io/sockets/sockets-tests.factor index 8264bec032..4b95a31512 100755 --- a/extra/io/sockets/sockets-tests.factor +++ b/extra/io/sockets/sockets-tests.factor @@ -45,7 +45,7 @@ concurrency.promises threads io.streams.string ; [ "1:2:0:0:0:0:3:4" ] [ B{ 0 1 0 2 0 0 0 0 0 0 0 0 0 3 0 4 } T{ inet6 } inet-ntop ] unit-test -[ t ] [ "localhost" 80 f resolve-host length 1 >= ] unit-test +[ t ] [ "localhost" 80 resolve-host length 1 >= ] unit-test ! Smoke-test UDP [ ] [ "127.0.0.1" 0 "datagram1" set ] unit-test diff --git a/extra/io/sockets/sockets.factor b/extra/io/sockets/sockets.factor index 4efd30c65e..a9278c8357 100755 --- a/extra/io/sockets/sockets.factor +++ b/extra/io/sockets/sockets.factor @@ -259,20 +259,26 @@ HOOK: (send) io-backend ( packet addrspec datagram -- ) [ addrinfo>addrspec ] map sift ; -: prepare-resolve-host ( host serv passive? -- host' serv' flags ) +: prepare-resolve-host ( addrspec -- host' serv' flags ) #! If the port is a number, we resolve for 'http' then #! change it later. This is a workaround for a FreeBSD #! getaddrinfo() limitation -- on Windows, Linux and Mac, #! we can convert a number to a string and pass that as the #! service name, but on FreeBSD this gives us an unknown #! service error. - >r - dup integer? [ port-override set "http" ] when - r> AI_PASSIVE 0 ? ; + [ host>> ] + [ port>> dup integer? [ port-override set "http" ] when ] bi + over 0 AI_PASSIVE ? ; HOOK: addrinfo-error io-backend ( n -- ) -: resolve-host ( host serv passive? -- seq ) +GENERIC: resolve-host ( addrspec -- seq ) + +TUPLE: inet host port ; + +C: inet + +M: inet resolve-host [ prepare-resolve-host "addrinfo" @@ -284,17 +290,16 @@ HOOK: addrinfo-error io-backend ( n -- ) freeaddrinfo ] with-scope ; +M: f resolve-host drop { } ; + +M: object resolve-host 1array ; + : host-name ( -- string ) 256 dup dup length gethostname zero? [ "gethostname failed" throw ] unless ascii alien>string ; -TUPLE: inet host port ; - -C: inet - -M: inet (client) - [ host>> ] [ port>> ] bi f resolve-host (client) ; +M: inet (client) resolve-host (client) ; ERROR: invalid-inet-server addrspec ; From 24e9149a2e9528e5b1f8b1952953b5e3cfe05331 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 00:08:50 -0500 Subject: [PATCH 0245/1850] Updating code for new io.servers code --- .../distributed/distributed.factor | 21 +++++++++---------- extra/eval-server/authors.txt | 1 - extra/eval-server/eval-server.factor | 11 ---------- extra/eval-server/summary.txt | 1 - extra/eval-server/tags.txt | 4 ---- extra/smtp/server/server.factor | 2 +- extra/tty-server/tty-server.factor | 16 +++++++------- 7 files changed, 20 insertions(+), 36 deletions(-) delete mode 100644 extra/eval-server/authors.txt delete mode 100644 extra/eval-server/eval-server.factor delete mode 100644 extra/eval-server/summary.txt delete mode 100644 extra/eval-server/tags.txt diff --git a/extra/concurrency/distributed/distributed.factor b/extra/concurrency/distributed/distributed.factor index c637f4baa3..c9257eb27e 100755 --- a/extra/concurrency/distributed/distributed.factor +++ b/extra/concurrency/distributed/distributed.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2005 Chris Double. All Rights Reserved. ! See http://factorcode.org/license.txt for BSD license. USING: serialize sequences concurrency.messaging threads io -io.server qualified arrays namespaces kernel io.encodings.binary -accessors ; +io.servers.connection io.encodings.binary +qualified arrays namespaces kernel accessors ; FROM: io.sockets => host-name with-client ; IN: concurrency.distributed @@ -10,21 +10,20 @@ SYMBOL: local-node : handle-node-client ( -- ) deserialize - [ first2 get-process send ] - [ stop-server ] if* ; + [ first2 get-process send ] [ stop-server ] if* ; -: (start-node) ( addrspecs addrspec -- ) +: (start-node) ( addrspec addrspec -- ) local-node set-global [ - "concurrency.distributed" - binary - [ handle-node-client ] with-server + + swap >>insecure + binary >>encoding + "concurrency.distributed" >>name + [ handle-node-client ] >>handler ] curry "Distributed concurrency server" spawn drop ; : start-node ( port -- ) - [ internet-server ] - [ host-name swap ] bi - (start-node) ; + host-name over (start-node) ; TUPLE: remote-process id node ; diff --git a/extra/eval-server/authors.txt b/extra/eval-server/authors.txt deleted file mode 100644 index 1901f27a24..0000000000 --- a/extra/eval-server/authors.txt +++ /dev/null @@ -1 +0,0 @@ -Slava Pestov diff --git a/extra/eval-server/eval-server.factor b/extra/eval-server/eval-server.factor deleted file mode 100644 index 3bfae616a2..0000000000 --- a/extra/eval-server/eval-server.factor +++ /dev/null @@ -1,11 +0,0 @@ -! Copyright (C) 2007 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: listener io.server strings parser byte-arrays ; -IN: eval-server - -: eval-server ( -- ) - 9998 local-server "eval-server" [ - >string eval>string >byte-array - ] with-datagrams ; - -MAIN: eval-server diff --git a/extra/eval-server/summary.txt b/extra/eval-server/summary.txt deleted file mode 100644 index b75930ac9f..0000000000 --- a/extra/eval-server/summary.txt +++ /dev/null @@ -1 +0,0 @@ -Listens for UDP packets on localhost:9998, evaluates them and sends back result diff --git a/extra/eval-server/tags.txt b/extra/eval-server/tags.txt deleted file mode 100644 index f628c95985..0000000000 --- a/extra/eval-server/tags.txt +++ /dev/null @@ -1,4 +0,0 @@ -demos -network -tools -applications diff --git a/extra/smtp/server/server.factor b/extra/smtp/server/server.factor index 824651030d..a6a8bb2cca 100755 --- a/extra/smtp/server/server.factor +++ b/extra/smtp/server/server.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007 Elie CHAFTARI ! See http://factorcode.org/license.txt for BSD license. -USING: combinators kernel prettyprint io io.timeouts io.server +USING: combinators kernel prettyprint io io.timeouts sequences namespaces io.sockets continuations calendar io.encodings.ascii io.streams.duplex destructors ; IN: smtp.server diff --git a/extra/tty-server/tty-server.factor b/extra/tty-server/tty-server.factor index d4b1a34e76..e155c2068d 100644 --- a/extra/tty-server/tty-server.factor +++ b/extra/tty-server/tty-server.factor @@ -1,11 +1,13 @@ -USING: listener io.server io.encodings.utf8 ; +USING: listener io.servers.connection io.encodings.utf8 ; IN: tty-server -: tty-server ( port -- ) - local-server - "tty-server" - utf8 [ listener ] with-server ; +: ( port -- ) + + "tty-server" >>name + utf8 >>encoding + swap local-server >>insecure + [ listener ] >>handler ; -: default-tty-server ( -- ) 9999 tty-server ; +: tty-server ( -- ) 9999 tty-server ; -MAIN: default-tty-server +MAIN: tty-server From dc7b414f5718423d1f6d91109fa11c26c4cf7e47 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 00:10:09 -0500 Subject: [PATCH 0246/1850] More flexible io.streams.limited, works with encoded streams --- extra/io/streams/limited/limited-tests.factor | 8 ++++++++ extra/io/streams/limited/limited.factor | 13 +++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/extra/io/streams/limited/limited-tests.factor b/extra/io/streams/limited/limited-tests.factor index d160a3f756..eb5b921260 100644 --- a/extra/io/streams/limited/limited-tests.factor +++ b/extra/io/streams/limited/limited-tests.factor @@ -30,3 +30,11 @@ namespaces tools.test strings kernel ; [ "abc" CHAR: \n ] [ "\n" "limited" get stream-read-until [ >string ] dip ] unit-test [ "\n" "limited" get stream-read-until ] [ limit-exceeded? ] must-fail-with + +[ "he" CHAR: l ] [ + B{ CHAR: h CHAR: e CHAR: l CHAR: l CHAR: o } + ascii [ + 5 limit-input + "l" read-until + ] with-input-stream +] unit-test diff --git a/extra/io/streams/limited/limited.factor b/extra/io/streams/limited/limited.factor index 669240d28b..e89b31a884 100644 --- a/extra/io/streams/limited/limited.factor +++ b/extra/io/streams/limited/limited.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math io destructors accessors sequences -namespaces ; +USING: kernel math io io.encodings destructors accessors +sequences namespaces ; IN: io.streams.limited TUPLE: limited-stream stream count limit ; @@ -12,8 +12,13 @@ TUPLE: limited-stream stream count limit ; swap >>stream 0 >>count ; -: limit-input ( limit -- ) - input-stream [ swap ] change ; +GENERIC# limit 1 ( stream limit -- stream' ) + +M: decoder limit [ clone ] dip [ limit ] curry change-stream ; + +M: object limit ; + +: limit-input ( limit -- ) input-stream [ swap limit ] change ; ERROR: limit-exceeded ; From 5809df329a6f351d187eadd59b2abfbf5196ae5e Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 00:10:18 -0500 Subject: [PATCH 0247/1850] Add a unit test --- extra/io/unix/sockets/secure/secure-tests.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/io/unix/sockets/secure/secure-tests.factor b/extra/io/unix/sockets/secure/secure-tests.factor index dca8fbbbc7..dee5c32349 100644 --- a/extra/io/unix/sockets/secure/secure-tests.factor +++ b/extra/io/unix/sockets/secure/secure-tests.factor @@ -14,7 +14,7 @@ concurrency.promises byte-arrays locals calendar io.timeouts ; "resource:extra/openssl/test/server.pem" >>key-file "resource:extra/openssl/test/dh1024.pem" >>dh-file "password" >>password - swap with-secure-context ; + swap with-secure-context ; inline :: server-test ( quot -- ) [ From cc605060b20d0928c0e9b803b1ab154b6ef33e1b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 00:10:46 -0500 Subject: [PATCH 0248/1850] Working on https server support --- extra/furnace/asides/asides.factor | 2 +- .../recover-password/recover-password.factor | 3 +- .../features/registration/registration.factor | 3 +- extra/furnace/auth/login/login.factor | 3 +- extra/furnace/flash/flash.factor | 2 +- extra/furnace/furnace.factor | 7 -- extra/furnace/redirection/redirection.factor | 29 ++++++ extra/furnace/sessions/sessions-tests.factor | 2 +- extra/furnace/sessions/sessions.factor | 7 +- extra/http/http-tests.factor | 2 +- extra/http/server/server.factor | 32 +++---- extra/webapps/blogs/blogs.factor | 1 + extra/webapps/pastebin/pastebin.factor | 1 + extra/webapps/planet/planet.factor | 1 + extra/webapps/todo/todo.factor | 1 + extra/webapps/user-admin/user-admin.factor | 1 + extra/webapps/wee-url/wee-url.factor | 2 +- extra/webapps/wiki/wiki.factor | 1 + .../concatenative/concatenative.factor | 88 +++++++++++++++++++ extra/websites/concatenative/page.css | 78 ++++++++++++++++ extra/websites/concatenative/page.xml | 28 ++++++ 21 files changed, 257 insertions(+), 37 deletions(-) create mode 100644 extra/furnace/redirection/redirection.factor create mode 100644 extra/websites/concatenative/concatenative.factor create mode 100644 extra/websites/concatenative/page.css create mode 100644 extra/websites/concatenative/page.xml diff --git a/extra/furnace/asides/asides.factor b/extra/furnace/asides/asides.factor index 15d1c1df0b..9f1411188c 100644 --- a/extra/furnace/asides/asides.factor +++ b/extra/furnace/asides/asides.factor @@ -4,7 +4,7 @@ USING: accessors namespaces sequences arrays kernel assocs assocs.lib hashtables math.parser urls combinators html.elements html.templates.chloe.syntax db.types db.tuples http http.server http.server.filters -furnace furnace.cache furnace.sessions ; +furnace furnace.cache furnace.sessions furnace.redirection ; IN: furnace.asides TUPLE: aside < server-state session method url post-data ; diff --git a/extra/furnace/auth/features/recover-password/recover-password.factor b/extra/furnace/auth/features/recover-password/recover-password.factor index 1e8d163e99..806df024f0 100644 --- a/extra/furnace/auth/features/recover-password/recover-password.factor +++ b/extra/furnace/auth/features/recover-password/recover-password.factor @@ -3,7 +3,8 @@ USING: namespaces accessors kernel assocs arrays io.sockets threads fry urls smtp validators html.forms http http.server.responses http.server.dispatchers -furnace furnace.actions furnace.auth furnace.auth.providers ; +furnace furnace.actions furnace.auth furnace.auth.providers +furnace.redirection ; IN: furnace.auth.features.recover-password SYMBOL: lost-password-from diff --git a/extra/furnace/auth/features/registration/registration.factor b/extra/furnace/auth/features/registration/registration.factor index 2bc7688b10..5c1851fb64 100644 --- a/extra/furnace/auth/features/registration/registration.factor +++ b/extra/furnace/auth/features/registration/registration.factor @@ -2,7 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs kernel namespaces validators html.forms urls http.server.dispatchers -furnace furnace.auth furnace.auth.providers furnace.actions ; +furnace furnace.auth furnace.auth.providers furnace.actions +furnace.redirection ; IN: furnace.auth.features.registration : ( -- action ) diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index e2b208de3a..4c53cb9c89 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -10,6 +10,7 @@ furnace.asides furnace.actions furnace.sessions furnace.utilities +furnace.redirection furnace.auth.login.permits ; IN: furnace.auth.login @@ -94,7 +95,7 @@ M: login-realm login-required* begin-aside protected get description>> description set protected get capabilities>> capabilities set - URL" $realm/login" flashed-variables ; + URL" $realm/login" >secure-url flashed-variables ; : ( responder name -- auth ) login-realm new-realm diff --git a/extra/furnace/flash/flash.factor b/extra/furnace/flash/flash.factor index e06cdac090..2149e4fcd7 100644 --- a/extra/furnace/flash/flash.factor +++ b/extra/furnace/flash/flash.factor @@ -3,7 +3,7 @@ USING: namespaces assocs assocs.lib kernel sequences accessors urls db.types db.tuples math.parser fry http http.server http.server.filters http.server.redirection -furnace furnace.cache furnace.sessions ; +furnace furnace.cache furnace.sessions furnace.redirection ; IN: furnace.flash TUPLE: flash-scope < server-state session namespace ; diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index 521f8a3bc1..90b529e385 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -63,13 +63,6 @@ M: url adjust-url M: string adjust-url ; -: ( url -- response ) - adjust-url request get method>> { - { "GET" [ ] } - { "HEAD" [ ] } - { "POST" [ ] } - } case ; - GENERIC: modify-form ( responder -- ) M: object modify-form drop ; diff --git a/extra/furnace/redirection/redirection.factor b/extra/furnace/redirection/redirection.factor new file mode 100644 index 0000000000..7f87c677b9 --- /dev/null +++ b/extra/furnace/redirection/redirection.factor @@ -0,0 +1,29 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors combinators namespaces +io.servers.connection +http http.server http.server.redirection +furnace ; +IN: furnace.redirection + +: ( url -- response ) + adjust-url request get method>> { + { "GET" [ ] } + { "HEAD" [ ] } + { "POST" [ ] } + } case ; + +: >secure-url ( url -- url' ) + clone + "https" >>protocol + secure-port >>port ; + +: ( url -- response ) + >secure-url ; + +TUPLE: redirect-responder to ; + +: ( url -- responder ) + redirect-responder boa ; + +M: redirect-responder call-responder* nip to>> ; diff --git a/extra/furnace/sessions/sessions-tests.factor b/extra/furnace/sessions/sessions-tests.factor index a97ba091c0..98d1bbdfc9 100755 --- a/extra/furnace/sessions/sessions-tests.factor +++ b/extra/furnace/sessions/sessions-tests.factor @@ -1,7 +1,7 @@ IN: furnace.sessions.tests USING: tools.test http furnace.sessions furnace.actions http.server http.server.responses -math namespaces kernel accessors io.sockets io.server +math namespaces kernel accessors io.sockets io.servers.connection prettyprint io.streams.string io.files splitting destructors sequences db db.tuples db.sqlite continuations urls math.parser furnace ; diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 863b8f87cb..6e50417ea1 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -1,8 +1,9 @@ ! Copyright (C) 2008 Doug Coleman, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: assocs kernel math.intervals math.parser namespaces -random accessors quotations hashtables sequences continuations -fry calendar combinators combinators.lib destructors alarms io.server +strings random accessors quotations hashtables sequences continuations +fry calendar combinators combinators.lib destructors alarms +io.servers.connection db db.tuples db.types http http.server http.server.dispatchers http.server.filters html.elements @@ -109,7 +110,7 @@ M: session-saver dispose : request-session ( -- session/f ) session-id-key - client-state dup [ string>number ] when + client-state dup string? [ string>number ] when get-session verify-session ; : ( -- cookie ) diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 73d26aa327..b5ed144579 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -123,7 +123,7 @@ read-response-test-1' 1array [ ! Live-fire exercise USING: http.server http.server.static furnace.sessions furnace.alloy furnace.actions furnace.auth furnace.auth.login furnace.db http.client -io.server io.files io io.encodings.ascii +io.servers.connection io.files io io.encodings.ascii accessors namespaces threads http.server.responses http.server.redirection http.server.dispatchers db.tuples ; diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index f709939e21..0312e62e8d 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -4,7 +4,6 @@ USING: kernel accessors sequences arrays namespaces splitting vocabs.loader destructors assocs debugger continuations combinators tools.vocabs tools.time math io -io.server io.sockets io.sockets.secure io.encodings @@ -12,6 +11,7 @@ io.encodings.utf8 io.encodings.ascii io.encodings.binary io.streams.limited +io.servers.connection io.timeouts fry logging logging.insomniac calendar urls http @@ -118,10 +118,6 @@ LOG: httpd-header NOTICE : ?refresh-all ( -- ) development? get-global [ global [ refresh-all ] bind ] when ; -: setup-limits ( -- ) - 1 minutes timeouts - 64 1024 * limit-input ; - LOG: httpd-benchmark DEBUG : ?benchmark ( quot -- ) @@ -130,25 +126,23 @@ LOG: httpd-benchmark DEBUG httpd-benchmark ] [ call ] if ; inline -: handle-client ( -- ) +TUPLE: http-server < threaded-server ; + +M: http-server handle-client* + drop [ - setup-limits - ascii decode-input - ascii encode-output + 64 1024 * limit-input ?refresh-all read-request [ do-request ] ?benchmark [ do-response ] ?benchmark ] with-destructors ; -: httpd ( port -- ) - dup integer? [ internet-server ] when - "http.server" binary [ handle-client ] with-server ; +: ( -- server ) + http-server new-threaded-server + "http.server" >>name + "http" protocol-port >>insecure + "https" protocol-port >>secure ; -: httpd-main ( -- ) - 8888 httpd ; - -: httpd-insomniac ( -- ) - "http.server" { httpd-hit } schedule-insomniac ; - -MAIN: httpd-main +: http-insomniac ( -- ) + "http.server" { "httpd-hit" } schedule-insomniac ; diff --git a/extra/webapps/blogs/blogs.factor b/extra/webapps/blogs/blogs.factor index aa1aa5edc7..10e0ab54c0 100644 --- a/extra/webapps/blogs/blogs.factor +++ b/extra/webapps/blogs/blogs.factor @@ -7,6 +7,7 @@ html.components http.server.dispatchers furnace furnace.actions +furnace.redirection furnace.auth furnace.auth.login furnace.boilerplate diff --git a/extra/webapps/pastebin/pastebin.factor b/extra/webapps/pastebin/pastebin.factor index 251872d1ac..3aeb21420f 100644 --- a/extra/webapps/pastebin/pastebin.factor +++ b/extra/webapps/pastebin/pastebin.factor @@ -12,6 +12,7 @@ http.server.dispatchers http.server.redirection furnace furnace.actions +furnace.redirection furnace.auth furnace.auth.login furnace.boilerplate diff --git a/extra/webapps/planet/planet.factor b/extra/webapps/planet/planet.factor index b472881e73..ca74b7e642 100755 --- a/extra/webapps/planet/planet.factor +++ b/extra/webapps/planet/planet.factor @@ -10,6 +10,7 @@ http.server http.server.dispatchers furnace furnace.actions +furnace.redirection furnace.boilerplate furnace.auth.login furnace.auth diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index 4b1b59e80f..0fb7e7dc89 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -11,6 +11,7 @@ furnace furnace.boilerplate furnace.auth furnace.actions +furnace.redirection furnace.db furnace.auth.login ; IN: webapps.todo diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index 8c7b1b21c9..359730d4b2 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -12,6 +12,7 @@ furnace.auth.providers.db furnace.auth.login furnace.auth furnace.actions +furnace.redirection furnace.utilities http.server http.server.dispatchers ; diff --git a/extra/webapps/wee-url/wee-url.factor b/extra/webapps/wee-url/wee-url.factor index 2396e98b2a..27187c4352 100644 --- a/extra/webapps/wee-url/wee-url.factor +++ b/extra/webapps/wee-url/wee-url.factor @@ -4,7 +4,7 @@ USING: math.ranges sequences random accessors combinators.lib kernel namespaces fry db.types db.tuples urls validators html.components html.forms http http.server.dispatchers furnace -furnace.actions furnace.boilerplate ; +furnace.actions furnace.boilerplate furnace.redirection ; IN: webapps.wee-url TUPLE: wee-url < dispatcher ; diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 13c445b0a8..77ee242668 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -8,6 +8,7 @@ http.server http.server.dispatchers furnace furnace.actions +furnace.redirection furnace.auth furnace.auth.login furnace.boilerplate diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor new file mode 100644 index 0000000000..fcf98b08da --- /dev/null +++ b/extra/websites/concatenative/concatenative.factor @@ -0,0 +1,88 @@ +! Copyright (c) 2008 Slava Pestov +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel sequences assocs io.files io.sockets +io.sockets.secure io.servers.connection +namespaces db db.tuples db.sqlite smtp urls +logging.insomniac +http.server +http.server.dispatchers +http.server.redirection +furnace.alloy +furnace.auth.login +furnace.auth.providers.db +furnace.auth.features.edit-profile +furnace.auth.features.recover-password +furnace.auth.features.registration +furnace.boilerplate +furnace.redirection +webapps.blogs +webapps.pastebin +webapps.planet +webapps.todo +webapps.wiki +webapps.wee-url +webapps.user-admin ; +IN: websites.concatenative + +: test-db ( -- db params ) "resource:test.db" sqlite-db ; + +: init-factor-db ( -- ) + test-db [ + init-furnace-tables + + { + post comment + paste annotation + blog posting + todo + short-url + article revision + } ensure-tables + ] with-db ; + +TUPLE: factor-website < dispatcher ; + +: ( -- responder ) + factor-website new-dispatcher + "blogs" add-responder + "todo" add-responder + "pastebin" add-responder + "planet" add-responder + "wiki" add-responder + "wee-url" add-responder + "user-admin" add-responder + URL" /wiki/view/Front Page" "" add-responder + "Factor website" + "Factor website" >>name + allow-registration + allow-password-recovery + allow-edit-profile + + { factor-website "page" } >>template + test-db ; + +: init-factor-website ( -- ) + "factorcode.org" 25 smtp-server set-global + "todo@factorcode.org" lost-password-from set-global + "website@factorcode.org" insomniac-sender set-global + "slava@factorcode.org" insomniac-recipients set-global + init-factor-db + main-responder set-global ; + +: ( -- config ) + + "resource:extra/openssl/test/server.pem" >>key-file + "resource:extra/openssl/test/dh1024.pem" >>dh-file + "password" >>password ; + +: ( -- threaded-server ) + + >>secure-config + 8080 >>insecure + 8431 >>secure ; + +: start-factor-website ( -- ) + test-db start-expiring + test-db start-update-task + http-insomniac + start-server ; diff --git a/extra/websites/concatenative/page.css b/extra/websites/concatenative/page.css new file mode 100644 index 0000000000..49e26883ad --- /dev/null +++ b/extra/websites/concatenative/page.css @@ -0,0 +1,78 @@ +body, button { + font:9pt "Lucida Grande", "Lucida Sans Unicode", verdana, geneva, sans-serif; + color:#444; +} + +.link-button { + padding: 0px; + background: none; + border: none; +} + +a, .link { + color: #222; + border-bottom:1px dotted #666; + text-decoration:none; +} + +a:hover, .link:hover { + border-bottom:1px solid #66a; +} + +.error { color: #a00; } + +.errors li { color: #a00; } + +.field-label { + text-align: right; +} + +.inline { + display: inline; +} + +.navbar { + background-color: #eee; + padding: 5px; + border: 1px solid #ccc; +} + +.big-field-label { + vertical-align: top; +} + +.description { + padding: 5px; + color: #000; +} + +.description pre { + border: 1px dashed #ccc; + background-color: #f5f5f5; +} + +.description p:first-child { + margin-top: 0px; +} + +.description p:last-child { + margin-bottom: 0px; +} + +.description table, .description td { + border-color: #666; + border-style: solid; +} + +.description table { + border-width: 0 0 1px 1px; + border-spacing: 0; + border-collapse: collapse; +} + +.description td { + margin: 0; + padding: 4px; + border-width: 1px 1px 0 0; +} + diff --git a/extra/websites/concatenative/page.xml b/extra/websites/concatenative/page.xml new file mode 100644 index 0000000000..464a3d9c5d --- /dev/null +++ b/extra/websites/concatenative/page.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + From 44112e32e6d66429a0a344f56efd520b5bf5b177 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 05:21:45 -0500 Subject: [PATCH 0249/1850] Fix build errors --- .../distributed/distributed-tests.factor | 10 ++- .../distributed/distributed.factor | 1 + extra/io/servers/connection/connection.factor | 4 +- extra/io/sockets/secure/secure-tests.factor | 2 +- extra/tty-server/tty-server.factor | 8 +- extra/webapps/counter/counter.factor | 2 +- .../factor-website/factor-website.factor | 73 ----------------- extra/webapps/factor-website/page.css | 78 ------------------- extra/webapps/factor-website/page.xml | 28 ------- 9 files changed, 16 insertions(+), 190 deletions(-) delete mode 100644 extra/webapps/factor-website/factor-website.factor delete mode 100644 extra/webapps/factor-website/page.css delete mode 100644 extra/webapps/factor-website/page.xml diff --git a/extra/concurrency/distributed/distributed-tests.factor b/extra/concurrency/distributed/distributed-tests.factor index ca1da0deaa..dc20e7ad5c 100755 --- a/extra/concurrency/distributed/distributed-tests.factor +++ b/extra/concurrency/distributed/distributed-tests.factor @@ -1,9 +1,9 @@ IN: concurrency.distributed.tests USING: tools.test concurrency.distributed kernel io.files arrays io.sockets system combinators threads math sequences -concurrency.messaging continuations ; +concurrency.messaging continuations accessors prettyprint ; -: test-node +: test-node ( -- addrspec ) { { [ os unix? ] [ "distributed-concurrency-test" temp-file ] } { [ os windows? ] [ "127.0.0.1" 1238 ] } @@ -11,9 +11,9 @@ concurrency.messaging continuations ; [ ] [ [ "distributed-concurrency-test" temp-file delete-file ] ignore-errors ] unit-test -[ ] [ test-node dup 1array swap (start-node) ] unit-test +[ ] [ test-node dup (start-node) ] unit-test -[ ] [ 100 sleep ] unit-test +[ ] [ 1000 sleep ] unit-test [ ] [ [ @@ -30,4 +30,6 @@ concurrency.messaging continuations ; receive ] unit-test +[ ] [ 1000 sleep ] unit-test + [ ] [ test-node stop-node ] unit-test diff --git a/extra/concurrency/distributed/distributed.factor b/extra/concurrency/distributed/distributed.factor index c9257eb27e..9ae2627505 100755 --- a/extra/concurrency/distributed/distributed.factor +++ b/extra/concurrency/distributed/distributed.factor @@ -20,6 +20,7 @@ SYMBOL: local-node binary >>encoding "concurrency.distributed" >>name [ handle-node-client ] >>handler + start-server ] curry "Distributed concurrency server" spawn drop ; : start-node ( port -- ) diff --git a/extra/io/servers/connection/connection.factor b/extra/io/servers/connection/connection.factor index f01112a70f..b062322142 100755 --- a/extra/io/servers/connection/connection.factor +++ b/extra/io/servers/connection/connection.factor @@ -86,14 +86,14 @@ M: threaded-server handle-client* handler>> call ; if* ] [ accept-loop ] bi ; inline -\ accept-loop ERROR add-error-logging - : start-accept-loop ( server -- ) threaded-server get encoding>> [ threaded-server get sockets>> push ] [ [ accept-loop ] with-disposal ] bi ; +\ start-accept-loop ERROR add-error-logging + : init-server ( threaded-server -- threaded-server ) dup semaphore>> [ dup max-connections>> [ diff --git a/extra/io/sockets/secure/secure-tests.factor b/extra/io/sockets/secure/secure-tests.factor index 75ac39e190..78de43d379 100644 --- a/extra/io/sockets/secure/secure-tests.factor +++ b/extra/io/sockets/secure/secure-tests.factor @@ -1,4 +1,4 @@ IN: io.sockets.secure.tests -USING: io.sockets.secure tools.test ; +USING: accessors kernel io.sockets io.sockets.secure tools.test ; [ "hello" 24 ] [ "hello" 24 [ host>> ] [ port>> ] bi ] unit-test diff --git a/extra/tty-server/tty-server.factor b/extra/tty-server/tty-server.factor index e155c2068d..4ba38ad06a 100644 --- a/extra/tty-server/tty-server.factor +++ b/extra/tty-server/tty-server.factor @@ -1,4 +1,5 @@ -USING: listener io.servers.connection io.encodings.utf8 ; +USING: listener io.servers.connection io.encodings.utf8 +accessors kernel ; IN: tty-server : ( port -- ) @@ -6,8 +7,9 @@ IN: tty-server "tty-server" >>name utf8 >>encoding swap local-server >>insecure - [ listener ] >>handler ; + [ listener ] >>handler + start-server ; -: tty-server ( -- ) 9999 tty-server ; +: tty-server ( -- ) 9999 ; MAIN: tty-server diff --git a/extra/webapps/counter/counter.factor b/extra/webapps/counter/counter.factor index 30c5d403de..a14d6d9823 100644 --- a/extra/webapps/counter/counter.factor +++ b/extra/webapps/counter/counter.factor @@ -1,5 +1,5 @@ USING: math kernel accessors http.server http.server.dispatchers -furnace furnace.actions furnace.sessions +furnace furnace.actions furnace.sessions furnace.redirection html.components html.forms html.templates.chloe fry urls ; IN: webapps.counter diff --git a/extra/webapps/factor-website/factor-website.factor b/extra/webapps/factor-website/factor-website.factor deleted file mode 100644 index c0bd856d5d..0000000000 --- a/extra/webapps/factor-website/factor-website.factor +++ /dev/null @@ -1,73 +0,0 @@ -! Copyright (c) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel sequences assocs io.files io.sockets -io.server -namespaces db db.tuples db.sqlite smtp -logging.insomniac -http.server -http.server.dispatchers -furnace.alloy -furnace.auth.login -furnace.auth.providers.db -furnace.auth.features.edit-profile -furnace.auth.features.recover-password -furnace.auth.features.registration -furnace.boilerplate -webapps.blogs -webapps.pastebin -webapps.planet -webapps.todo -webapps.wiki -webapps.wee-url -webapps.user-admin ; -IN: webapps.factor-website - -: test-db ( -- db params ) "resource:test.db" sqlite-db ; - -: init-factor-db ( -- ) - test-db [ - init-furnace-tables - - { - post comment - paste annotation - blog posting - todo - short-url - article revision - } ensure-tables - ] with-db ; - -TUPLE: factor-website < dispatcher ; - -: ( -- responder ) - factor-website new-dispatcher - "blogs" add-responder - "todo" add-responder - "pastebin" add-responder - "planet" add-responder - "wiki" add-responder - "wee-url" add-responder - "user-admin" add-responder - "Factor website" - "Factor website" >>name - allow-registration - allow-password-recovery - allow-edit-profile - - { factor-website "page" } >>template - test-db ; - -: init-factor-website ( -- ) - "factorcode.org" 25 smtp-server set-global - "todo@factorcode.org" lost-password-from set-global - "website@factorcode.org" insomniac-sender set-global - "slava@factorcode.org" insomniac-recipients set-global - init-factor-db - main-responder set-global ; - -: start-factor-website ( -- ) - test-db start-expiring - test-db start-update-task - httpd-insomniac - 8812 httpd ; diff --git a/extra/webapps/factor-website/page.css b/extra/webapps/factor-website/page.css deleted file mode 100644 index 49e26883ad..0000000000 --- a/extra/webapps/factor-website/page.css +++ /dev/null @@ -1,78 +0,0 @@ -body, button { - font:9pt "Lucida Grande", "Lucida Sans Unicode", verdana, geneva, sans-serif; - color:#444; -} - -.link-button { - padding: 0px; - background: none; - border: none; -} - -a, .link { - color: #222; - border-bottom:1px dotted #666; - text-decoration:none; -} - -a:hover, .link:hover { - border-bottom:1px solid #66a; -} - -.error { color: #a00; } - -.errors li { color: #a00; } - -.field-label { - text-align: right; -} - -.inline { - display: inline; -} - -.navbar { - background-color: #eee; - padding: 5px; - border: 1px solid #ccc; -} - -.big-field-label { - vertical-align: top; -} - -.description { - padding: 5px; - color: #000; -} - -.description pre { - border: 1px dashed #ccc; - background-color: #f5f5f5; -} - -.description p:first-child { - margin-top: 0px; -} - -.description p:last-child { - margin-bottom: 0px; -} - -.description table, .description td { - border-color: #666; - border-style: solid; -} - -.description table { - border-width: 0 0 1px 1px; - border-spacing: 0; - border-collapse: collapse; -} - -.description td { - margin: 0; - padding: 4px; - border-width: 1px 1px 0 0; -} - diff --git a/extra/webapps/factor-website/page.xml b/extra/webapps/factor-website/page.xml deleted file mode 100644 index 32e1223c58..0000000000 --- a/extra/webapps/factor-website/page.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From 27c89d75d46120df04769c3a375a7af2aa626443 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 05:22:33 -0500 Subject: [PATCH 0250/1850] I/O micro-optimizations; 12% improvement on reverse-complement --- core/io/encodings/encodings.factor | 102 ++++++++++-------- core/optimizer/known-words/known-words.factor | 20 ++-- extra/io/encodings/ascii/ascii.factor | 7 +- 3 files changed, 70 insertions(+), 59 deletions(-) diff --git a/core/io/encodings/encodings.factor b/core/io/encodings/encodings.factor index 4a9f90cb32..942476616f 100755 --- a/core/io/encodings/encodings.factor +++ b/core/io/encodings/encodings.factor @@ -28,23 +28,62 @@ ERROR: encode-error ; ! Decoding - f decoder boa ; +>cr drop ; inline + +: cr- f >>cr drop ; inline + : >decoder< ( decoder -- stream encoding ) - [ stream>> ] [ code>> ] bi ; + [ stream>> ] [ code>> ] bi ; inline -: cr+ t swap set-decoder-cr ; inline +: fix-read1 ( stream char -- char ) + over cr>> [ + over cr- + dup CHAR: \n = [ + drop dup stream-read1 + ] when + ] when nip ; inline -: cr- f swap set-decoder-cr ; inline +M: decoder stream-read1 + dup >decoder< decode-char fix-read1 ; + +: fix-read ( stream string -- string ) + over cr>> [ + over cr- + "\n" ?head [ + over stream-read1 [ suffix ] when* + ] when + ] when nip ; inline + +: (read) ( n quot -- n string ) + over 0 [ + [ + >r call dup + [ swap r> set-nth-unsafe f ] [ r> 3drop t ] if + ] 2curry find-integer + ] keep ; inline + +: finish-read ( n string -- string/f ) + { + { [ over 0 = ] [ 2drop f ] } + { [ over not ] [ nip ] } + [ swap head ] + } cond ; inline + +M: decoder stream-read + tuck >decoder< [ decode-char ] 2curry (read) finish-read fix-read ; + +M: decoder stream-read-partial stream-read ; : line-ends/eof ( stream str -- str ) f like swap cr- ; inline : line-ends\r ( stream str -- str ) swap cr+ ; inline : line-ends\n ( stream str -- str ) - over decoder-cr over empty? and + over cr>> over empty? and [ drop dup cr- stream-readln ] [ swap cr- ] if ; inline : handle-readln ( stream str ch -- str ) @@ -52,61 +91,30 @@ M: object f decoder boa ; { f [ line-ends/eof ] } { CHAR: \r [ line-ends\r ] } { CHAR: \n [ line-ends\n ] } - } case ; + } case ; inline -: fix-read ( stream string -- string ) - over decoder-cr [ - over cr- - "\n" ?head [ - over stream-read1 [ suffix ] when* - ] when - ] when nip ; - -: read-loop ( n stream -- string ) - SBUF" " clone [ - [ - >r nip stream-read1 dup - [ r> push f ] [ r> 2drop t ] if - ] 2curry find-integer drop - ] keep "" like f like ; - -M: decoder stream-read - tuck read-loop fix-read ; - -M: decoder stream-read-partial stream-read ; - -: (read-until) ( buf quot -- string/f sep/f ) +: ((read-until)) ( buf quot -- string/f sep/f ) ! quot: -- char stop? dup call [ >r drop "" like r> ] - [ pick push (read-until) ] if ; inline + [ pick push ((read-until)) ] if ; inline -M: decoder stream-read-until +: (read-until) ( seps stream -- string/f sep/f ) SBUF" " clone -rot >decoder< - [ decode-char [ dup rot memq? ] [ drop f t ] if* ] 3curry - (read-until) ; + [ decode-char dup [ dup rot member? ] [ 2drop f t ] if ] 3curry + ((read-until)) ; inline -: fix-read1 ( stream char -- char ) - over decoder-cr [ - over cr- - dup CHAR: \n = [ - drop dup stream-read1 - ] when - ] when nip ; +M: decoder stream-read-until (read-until) ; -M: decoder stream-read1 - dup >decoder< decode-char fix-read1 ; +M: decoder stream-readln "\r\n" over (read-until) handle-readln ; -M: decoder stream-readln ( stream -- str ) - "\r\n" over stream-read-until handle-readln ; - -M: decoder dispose decoder-stream dispose ; +M: decoder dispose stream>> dispose ; ! Encoding M: object encoder boa ; : >encoder< ( encoder -- stream encoding ) - [ stream>> ] [ code>> ] bi ; + [ stream>> ] [ code>> ] bi ; inline M: encoder stream-write1 >encoder< encode-char ; diff --git a/core/optimizer/known-words/known-words.factor b/core/optimizer/known-words/known-words.factor index d1dbefe26b..970b69a18a 100755 --- a/core/optimizer/known-words/known-words.factor +++ b/core/optimizer/known-words/known-words.factor @@ -9,7 +9,7 @@ io.streams.string layouts splitting math.intervals math.floats.private classes.tuple classes.tuple.private classes classes.algebra optimizer.def-use optimizer.backend optimizer.pattern-match optimizer.inlining float-arrays -sequences.private combinators ; +sequences.private combinators byte-arrays byte-vectors ; { } [ [ @@ -59,15 +59,19 @@ sequences.private combinators ; node-in-d peek dup value? [ value-literal sequence? ] [ drop f ] if ; -: member-quot ( seq -- newquot ) - [ literalize [ t ] ] { } map>assoc - [ drop f ] suffix [ nip case ] curry ; +: member-quot ( seq predicate -- newquot ) + [ curry [ dup ] prepose [ drop t ] ] curry { } map>assoc + [ drop f ] suffix [ nip cond ] curry ; -: expand-member ( #call -- ) - dup node-in-d peek value-literal member-quot f splice-quot ; +: expand-member ( #call predicate -- ) + >r dup node-in-d peek value-literal r> member-quot f splice-quot ; \ member? { - { [ dup literal-member? ] [ expand-member ] } + { [ dup literal-member? ] [ [ = ] expand-member ] } +} define-optimizers + +\ memq? { + { [ dup literal-member? ] [ [ eq? ] expand-member ] } } define-optimizers ! if the result of eq? is t and the second input is a literal, @@ -97,7 +101,7 @@ sequences.private combinators ; ] each \ push-all -{ { string sbuf } { array vector } } +{ { string sbuf } { array vector } { byte-array byte-vector } } "specializer" set-word-prop \ append diff --git a/extra/io/encodings/ascii/ascii.factor b/extra/io/encodings/ascii/ascii.factor index 9ff120c5fa..08dc8d07d9 100755 --- a/extra/io/encodings/ascii/ascii.factor +++ b/extra/io/encodings/ascii/ascii.factor @@ -5,12 +5,11 @@ IN: io.encodings.ascii [ drop replacement-char ] unless ] - [ drop f ] if* ; + nip swap stream-read1 dup + [ tuck > [ drop replacement-char ] unless ] [ 2drop f ] if ; inline PRIVATE> SINGLETON: ascii From d17470b5fbf6f51f7d3f32a8f398b170e6f60e94 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 17 Jun 2008 05:25:21 -0500 Subject: [PATCH 0251/1850] HTTPd test fixes --- extra/http/http-tests.factor | 2 +- extra/http/server/server.factor | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index b5ed144579..a02382f083 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -125,7 +125,7 @@ USING: http.server http.server.static furnace.sessions furnace.alloy furnace.actions furnace.auth furnace.auth.login furnace.db http.client io.servers.connection io.files io io.encodings.ascii accessors namespaces threads -http.server.responses http.server.redirection +http.server.responses http.server.redirection furnace.redirection http.server.dispatchers db.tuples ; : add-quit-action diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 0312e62e8d..21ab074907 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -144,5 +144,11 @@ M: http-server handle-client* "http" protocol-port >>insecure "https" protocol-port >>secure ; +: httpd ( port -- ) + + swap >>insecure + f >>secure + start-server ; + : http-insomniac ( -- ) "http.server" { "httpd-hit" } schedule-insomniac ; From 0c0aaceedb84a947d0127a404a4bdee07b858840 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:32:38 -0500 Subject: [PATCH 0252/1850] Better compilation of member? when the sequence contains small integers only --- core/optimizer/known-words/known-words.factor | 60 +++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/core/optimizer/known-words/known-words.factor b/core/optimizer/known-words/known-words.factor index 970b69a18a..7f882d85d0 100755 --- a/core/optimizer/known-words/known-words.factor +++ b/core/optimizer/known-words/known-words.factor @@ -2,9 +2,9 @@ ! See http://factorcode.org/license.txt for BSD license. IN: optimizer.known-words USING: alien arrays generic hashtables inference.dataflow -inference.class kernel assocs math math.private kernel.private -sequences words parser vectors strings sbufs io namespaces -assocs quotations sequences.private io.binary +inference.class kernel assocs math math.order math.private +kernel.private sequences words parser vectors strings sbufs io +namespaces assocs quotations sequences.private io.binary io.streams.string layouts splitting math.intervals math.floats.private classes.tuple classes.tuple.private classes classes.algebra optimizer.def-use optimizer.backend @@ -59,19 +59,59 @@ sequences.private combinators byte-arrays byte-vectors ; node-in-d peek dup value? [ value-literal sequence? ] [ drop f ] if ; -: member-quot ( seq predicate -- newquot ) - [ curry [ dup ] prepose [ drop t ] ] curry { } map>assoc - [ drop f ] suffix [ nip cond ] curry ; +: expand-member ( #call quot -- ) + >r dup node-in-d peek value-literal r> call f splice-quot ; -: expand-member ( #call predicate -- ) - >r dup node-in-d peek value-literal r> member-quot f splice-quot ; +: bit-member-n 256 ; inline + +: bit-member? ( seq -- ? ) + #! Can we use a fast byte array test here? + { + { [ dup length 8 < ] [ f ] } + { [ dup [ integer? not ] contains? ] [ f ] } + { [ dup [ 0 < ] contains? ] [ f ] } + { [ dup [ bit-member-n >= ] contains? ] [ f ] } + [ t ] + } cond nip ; + +: bit-member-seq ( seq -- flags ) + bit-member-n swap [ member? 1 0 ? ] curry B{ } map-as ; + +: exact-float? ( f -- ? ) + dup float? [ dup >integer >float = ] [ drop f ] if ; inline + +: bit-member-quot ( seq -- newquot ) + [ + [ drop ] % ! drop the sequence itself; we don't use it at run time + bit-member-seq , + [ + { + { [ over fixnum? ] [ ?nth 1 eq? ] } + { [ over bignum? ] [ ?nth 1 eq? ] } + { [ over exact-float? ] [ ?nth 1 eq? ] } + [ 2drop f ] + } cond + ] % + ] [ ] make ; + +: member-quot ( seq -- newquot ) + dup bit-member? [ + bit-member-quot + ] [ + [ [ t ] ] { } map>assoc + [ drop f ] suffix [ nip case ] curry + ] if ; \ member? { - { [ dup literal-member? ] [ [ = ] expand-member ] } + { [ dup literal-member? ] [ [ member-quot ] expand-member ] } } define-optimizers +: memq-quot ( seq -- newquot ) + [ [ dupd eq? ] curry [ drop t ] ] { } map>assoc + [ drop f ] suffix [ nip cond ] curry ; + \ memq? { - { [ dup literal-member? ] [ [ eq? ] expand-member ] } + { [ dup literal-member? ] [ [ memq-quot ] expand-member ] } } define-optimizers ! if the result of eq? is t and the second input is a literal, From dc3929f3db12a47e20798567aba8c2754a24459b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:35:19 -0500 Subject: [PATCH 0253/1850] Improve PEG: word --- extra/peg/parsers/parsers.factor | 2 -- extra/peg/peg.factor | 25 ++++++++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/extra/peg/parsers/parsers.factor b/extra/peg/parsers/parsers.factor index 443b9fc61d..da44c12e8f 100755 --- a/extra/peg/parsers/parsers.factor +++ b/extra/peg/parsers/parsers.factor @@ -24,11 +24,9 @@ MEMO: just ( parser -- parser ) : 1token ( ch -- parser ) 1string token ; -r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq [ unclip 1vector swap first append ] action ; -PRIVATE> : list-of ( items separator -- parser ) hide f (list-of) ; diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index b420574a3b..05f84afedb 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007, 2008 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences strings fry namespaces math assocs shuffle +USING: kernel sequences strings fry namespaces math assocs shuffle debugger io vectors arrays math.parser math.order unicode.categories compiler.units parser words quotations effects memoize accessors locals effects splitting ; @@ -563,11 +563,22 @@ PRIVATE> #! to fix boxes so this isn't needed... box-parser boa next-id f over set-delegate [ ] action ; +ERROR: parse-failed input word ; + +M: parse-failed error. + "The " write dup word>> pprint " word could not parse the following input:" print nl + input>> . ; + : PEG: - (:) [ + (:) + [let* | def [ ] word [ ] compiled-def [ def call compile ] | [ - call compile [ compiled-parse ] curry - [ dup [ parse-result-ast ] [ "Parse failed" throw ] if ] - append define - ] with-compilation-unit - ] 2curry over push-all ; parsing + [ + [ + dup compiled-def compiled-parse + [ ast>> ] [ word parse-failed ] ?if + ] + word swap define + ] with-compilation-unit + ] over push-all + ] ; parsing From c19d83e13f5b9330a09a7d74b5b7a01a3e403fba Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:35:34 -0500 Subject: [PATCH 0254/1850] Use fry in html --- extra/html/elements/elements.factor | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extra/html/elements/elements.factor b/extra/html/elements/elements.factor index 5fc4bd19ae..35e01227b5 100644 --- a/extra/html/elements/elements.factor +++ b/extra/html/elements/elements.factor @@ -5,7 +5,7 @@ USING: io kernel namespaces prettyprint quotations sequences strings words xml.entities compiler.units effects -urls math math.parser combinators present ; +urls math math.parser combinators present fry ; IN: html.elements @@ -70,7 +70,7 @@ SYMBOL: html : def-for-html-word- ( name -- ) #! Return the name and code for the patterned #! word. - dup swap [ write-html ] curry + dup swap '[ , write-html ] (( -- )) html-word ; : ( str -- foo> ) ">" append ; @@ -93,14 +93,14 @@ SYMBOL: html : def-for-html-word- ( name -- ) #! Return the name and code for the patterned #! word. - dup [ write-html ] curry (( -- )) html-word ; + dup '[ , write-html ] (( -- )) html-word ; : ( str -- ) "<" swap "/>" 3append ; : def-for-html-word- ( name -- ) #! Return the name and code for the patterned #! word. - dup swap [ write-html ] curry + dup swap '[ , write-html ] (( -- )) html-word ; : foo/> ( str -- str/> ) "/>" append ; @@ -134,7 +134,7 @@ SYMBOL: html : define-attribute-word ( name -- ) dup "=" prepend swap - [ write-attr ] curry (( string -- )) html-word ; + '[ , write-attr ] (( string -- )) html-word ; ! Define some closed HTML tags [ From 9674541cebfbb6bddfc135f3b3c9af892615236a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:36:20 -0500 Subject: [PATCH 0255/1850] New http request/response parsers using pegs --- extra/http/http-tests.factor | 49 ++++++- extra/http/http.factor | 224 ++++++++++++++---------------- extra/http/parsers/parsers.factor | 166 ++++++++++++++++++++++ 3 files changed, 315 insertions(+), 124 deletions(-) create mode 100644 extra/http/parsers/parsers.factor diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index a02382f083..522d0c1845 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -1,7 +1,8 @@ USING: http tools.test multiline tuple-syntax io.streams.string io.encodings.utf8 io.encodings.string kernel arrays splitting sequences -assocs io.sockets db db.sqlite continuations urls hashtables ; +assocs io.sockets db db.sqlite continuations urls hashtables +accessors ; IN: http.tests : lf>crlf "\n" split "\r\n" join ; @@ -73,10 +74,21 @@ GET nested HTTP/1.0 ; -[ read-request-test-3 [ read-request ] with-string-reader ] +[ read-request-test-3 lf>crlf [ read-request ] with-string-reader ] [ "Bad request: URL" = ] must-fail-with +STRING: read-request-test-4 +GET /blah HTTP/1.0 +Host: "www.amazon.com" +; + +[ "www.amazon.com" ] +[ + read-request-test-4 lf>crlf [ read-request ] with-string-reader + "host" header +] unit-test + STRING: read-response-test-1 HTTP/1.1 404 not found Content-Type: text/html; charset=UTF-8 @@ -117,7 +129,38 @@ read-response-test-1' 1array [ [ t ] [ "rmid=732423sdfs73242; path=/; domain=.example.net; expires=Fri, 31-Dec-2010 23:59:59 GMT" - dup parse-cookies unparse-cookies = + dup parse-set-cookie first unparse-set-cookie = +] unit-test + +[ t ] [ + "a=" + dup parse-set-cookie first unparse-set-cookie = +] unit-test + +STRING: read-response-test-2 +HTTP/1.1 200 Content follows +Set-Cookie: oo="bar; a=b"; httponly=yes; sid=123456 + + +; + +[ 2 ] [ + read-response-test-2 lf>crlf + [ read-response ] with-string-reader + cookies>> length +] unit-test + +STRING: read-response-test-3 +HTTP/1.1 200 Content follows +Set-Cookie: oo="bar; a=b"; comment="your mom"; httponly=yes + + +; + +[ 1 ] [ + read-response-test-3 lf>crlf + [ read-response ] with-string-reader + cookies>> length ] unit-test ! Live-fire exercise diff --git a/extra/http/http.factor b/extra/http/http.factor index 025e2c8441..4001301cb1 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -1,8 +1,7 @@ ! Copyright (C) 2003, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel combinators math namespaces - -assocs sequences splitting sorting sets debugger +assocs assocs.lib sequences splitting sorting sets debugger strings vectors hashtables quotations arrays byte-arrays math.parser calendar calendar.format present @@ -11,7 +10,9 @@ io.encodings.8-bit unicode.case unicode.categories qualified -urls html.templates xml xml.data xml.writer ; +urls html.templates xml xml.data xml.writer + +http.parsers ; EXCLUDE: fry => , ; @@ -19,40 +20,20 @@ IN: http : crlf ( -- ) "\r\n" write ; -: add-header ( value key assoc -- ) - [ at dup [ "; " rot 3append ] [ drop ] if ] 2keep set-at ; - -: header-line ( line -- ) - dup first blank? [ - [ blank? ] left-trim - "last-header" get - "header" get - add-header - ] [ - ":" split1 dup [ - [ blank? ] left-trim - swap >lower dup "last-header" set - "header" get add-header - ] [ - 2drop - ] if - ] if ; - -: read-lf ( -- bytes ) - "\n" read-until CHAR: \n assert= ; - : read-crlf ( -- bytes ) "\r" read-until [ CHAR: \r assert= read1 CHAR: \n assert= ] when* ; -: (read-header) ( -- ) - read-crlf dup - empty? [ drop ] [ header-line (read-header) ] if ; +: (read-header) ( -- alist ) + [ read-crlf dup f like ] [ parse-header-line ] [ drop ] unfold ; + +: process-header ( alist -- assoc ) + f swap [ [ swap or dup ] dip swap ] assoc-map nip + [ ?push ] histogram [ "; " join ] assoc-map + >hashtable ; : read-header ( -- assoc ) - H{ } clone [ - "header" [ (read-header) ] with-variable - ] keep ; + (read-header) process-header ; : header-value>string ( value -- string ) { @@ -63,47 +44,62 @@ IN: http : check-header-string ( str -- str ) #! http://en.wikipedia.org/wiki/HTTP_Header_Injection - dup "\r\n" intersect empty? + dup "\r\n\"" intersect empty? [ "Header injection attack" throw ] unless ; : write-header ( assoc -- ) >alist sort-keys [ - swap - check-header-string write ": " write - header-value>string check-header-string write crlf + [ check-header-string write ": " write ] + [ header-value>string check-header-string write crlf ] bi* ] assoc-each crlf ; -TUPLE: cookie name value path domain expires max-age http-only ; +TUPLE: cookie name value version comment path domain expires max-age http-only secure ; : ( value name -- cookie ) cookie new swap >>name swap >>value ; -: parse-cookies ( string -- seq ) +: parse-set-cookie ( string -- seq ) [ f swap - - ";" split [ - [ blank? ] trim "=" split1 swap >lower { + (parse-set-cookie) + [ + swap { + { "version" [ >>version ] } + { "comment" [ >>comment ] } { "expires" [ cookie-string>timestamp >>expires ] } { "max-age" [ string>number seconds >>max-age ] } { "domain" [ >>domain ] } { "path" [ >>path ] } { "httponly" [ drop t >>http-only ] } - { "" [ drop ] } + { "secure" [ drop t >>secure ] } [ dup , nip ] } case - ] each + ] assoc-each + drop + ] { } make ; +: parse-cookie ( string -- seq ) + [ + f swap + (parse-cookie) + [ + swap { + { "$version" [ >>version ] } + { "$domain" [ >>domain ] } + { "$path" [ >>path ] } + [ dup , nip ] + } case + ] assoc-each drop ] { } make ; : check-cookie-string ( string -- string' ) - dup "=;'\"" intersect empty? + dup "=;'\"\r\n" intersect empty? [ "Bad cookie name or value" throw ] unless ; -: (unparse-cookie) ( key value -- ) +: unparse-cookie-value ( key value -- ) { { f [ drop ] } { t [ check-cookie-string , ] } @@ -118,20 +114,30 @@ TUPLE: cookie name value path domain expires max-age http-only ; ] } case ; -: unparse-cookie ( cookie -- strings ) +: (unparse-cookie) ( cookie -- strings ) [ dup name>> check-cookie-string >lower - over value>> (unparse-cookie) - "path" over path>> (unparse-cookie) - "domain" over domain>> (unparse-cookie) - "expires" over expires>> (unparse-cookie) - "max-age" over max-age>> (unparse-cookie) - "httponly" over http-only>> (unparse-cookie) + over value>> unparse-cookie-value + "$path" over path>> unparse-cookie-value + "$domain" over domain>> unparse-cookie-value drop ] { } make ; -: unparse-cookies ( cookies -- string ) - [ unparse-cookie ] map concat "; " join ; +: unparse-cookie ( cookies -- string ) + [ (unparse-cookie) ] map concat "; " join ; + +: unparse-set-cookie ( cookie -- string ) + [ + dup name>> check-cookie-string >lower + over value>> unparse-cookie-value + "path" over path>> unparse-cookie-value + "domain" over domain>> unparse-cookie-value + "expires" over expires>> unparse-cookie-value + "max-age" over max-age>> unparse-cookie-value + "httponly" over http-only>> unparse-cookie-value + "secure" over secure>> unparse-cookie-value + drop + ] { } make "; " join ; TUPLE: request method @@ -141,6 +147,13 @@ header post-data cookies ; +: check-url ( string -- url ) + >url dup path>> "/" head? [ "Bad request: URL" throw ] unless ; inline + +: read-request-line ( request -- request ) + read-crlf parse-request-line first3 + [ >>method ] [ check-url >>url ] [ >>version ] tri* ; + : set-header ( request/response value key -- request/response ) pick header>> set-at ; @@ -155,27 +168,9 @@ cookies ; "close" "connection" set-header "Factor http.client" "user-agent" set-header ; -: read-method ( request -- request ) - " " read-until [ "Bad request: method" throw ] unless - >>method ; - : check-absolute ( url -- url ) dup path>> "/" head? [ "Bad request: URL" throw ] unless ; inline -: read-url ( request -- request ) - " " read-until [ - dup empty? [ drop read-url ] [ >url check-absolute >>url ] if - ] [ "Bad request: URL" throw ] if ; - -: parse-version ( string -- version ) - "HTTP/" ?head [ "Bad request: version" throw ] unless - dup { "1.0" "1.1" } member? [ "Bad request: version" throw ] unless ; - -: read-request-version ( request -- request ) - read-crlf [ CHAR: \s = ] left-trim - parse-version - >>version ; - : read-request-header ( request -- request ) read-header >>header ; @@ -210,7 +205,7 @@ TUPLE: post-data raw content content-type ; drop ; : extract-cookies ( request -- request ) - dup "cookie" header [ parse-cookies >>cookies ] when* ; + dup "cookie" header [ parse-cookie >>cookies ] when* ; : parse-content-type-attributes ( string -- attributes ) " " split harvest [ "=" split1 [ >lower ] dip ] { } map>assoc ; @@ -220,22 +215,18 @@ TUPLE: post-data raw content content-type ; : read-request ( -- request ) - read-method - read-url - read-request-version + read-request-line read-request-header read-post-data extract-host extract-cookies ; -: write-method ( request -- request ) - dup method>> write bl ; - -: write-request-url ( request -- request ) - dup url>> relative-url present write bl ; - -: write-version ( request -- request ) - "HTTP/" write dup request-version write crlf ; +: write-request-line ( request -- request ) + dup + [ method>> write bl ] + [ url>> relative-url present write bl ] + [ "HTTP/" write version>> write crlf ] + tri ; : url-host ( url -- string ) [ host>> ] [ port>> ] bi dup "http" protocol-port = @@ -249,7 +240,7 @@ TUPLE: post-data raw content content-type ; [ content-type>> "content-type" pick set-at ] bi ] when* - over cookies>> f like [ unparse-cookies "cookie" pick set-at ] when* + over cookies>> f like [ unparse-cookie "cookie" pick set-at ] when* write-header ; GENERIC: >post-data ( object -- post-data ) @@ -274,9 +265,7 @@ M: f >post-data ; : write-request ( request -- ) unparse-post-data - write-method - write-request-url - write-version + write-request-line write-request-header write-post-data flush @@ -311,23 +300,13 @@ M: response clone [ clone ] change-header [ clone ] change-cookies ; -: read-response-version ( response -- response ) - " \t" read-until - [ "Bad response: version" throw ] unless - parse-version - >>version ; - -: read-response-code ( response -- response ) - " \t" read-until [ "Bad response: code" throw ] unless - string>number [ "Bad response: code" throw ] unless* - >>code ; - -: read-response-message ( response -- response ) - read-crlf >>message ; +: read-response-line ( response -- response ) + read-crlf parse-response-line first3 + [ >>version ] [ >>code ] [ >>message ] tri* ; : read-response-header ( response -- response ) read-header >>header - dup "set-cookie" header parse-cookies >>cookies + dup "set-cookie" header parse-set-cookie >>cookies dup "content-type" header [ parse-content-type [ >>content-type ] @@ -336,20 +315,15 @@ M: response clone : read-response ( -- response ) - read-response-version - read-response-code - read-response-message + read-response-line read-response-header ; -: write-response-version ( response -- response ) - "HTTP/" write - dup version>> write bl ; - -: write-response-code ( response -- response ) - dup code>> number>string write bl ; - -: write-response-message ( response -- response ) - dup message>> write crlf ; +: write-response-line ( response -- response ) + dup + [ "HTTP/" write version>> write bl ] + [ code>> present write bl ] + [ message>> write crlf ] + tri ; : unparse-content-type ( request -- content-type ) [ content-type>> "application/octet-stream" or ] @@ -357,19 +331,29 @@ M: response clone bi [ "; charset=" swap 3append ] when* ; +: ensure-domain ( cookie -- cookie ) + [ + request get url>> + host>> dup "localhost" = + [ drop ] [ or ] if + ] change-domain ; + : write-response-header ( response -- response ) - dup header>> clone - over cookies>> f like [ unparse-cookies "set-cookie" pick set-at ] when* + #! We send one set-cookie header per cookie, because that's + #! what Firefox expects. + dup header>> >alist >vector over unparse-content-type "content-type" pick set-at + over cookies>> [ + ensure-domain unparse-set-cookie + "set-cookie" swap 2array over push + ] each write-header ; : write-response-body ( response -- response ) dup body>> call-template ; M: response write-response ( respose -- ) - write-response-version - write-response-code - write-response-message + write-response-line write-response-header flush drop ; @@ -403,9 +387,7 @@ body ; "1.1" >>version ; M: raw-response write-response ( respose -- ) - write-response-version - write-response-code - write-response-message + write-response-line write-response-body drop ; diff --git a/extra/http/parsers/parsers.factor b/extra/http/parsers/parsers.factor new file mode 100644 index 0000000000..33bfa4b202 --- /dev/null +++ b/extra/http/parsers/parsers.factor @@ -0,0 +1,166 @@ +USING: math math.order math.parser kernel combinators.lib +sequences sequences.deep peg peg.parsers assocs arrays +hashtables strings unicode.case namespaces ascii ; +IN: http.parsers + +: except ( quot -- parser ) + [ not ] compose satisfy ; inline + +: except-these ( quots -- parser ) + [ 1|| ] curry except ; inline + +: ctl? ( ch -- ? ) + { [ 0 31 between? ] [ 127 = ] } 1|| ; + +: tspecial? ( ch -- ? ) + "()<>@,;:\\\"/[]?={} \t" member? ; + +: 'token' ( -- parser ) + { [ ctl? ] [ tspecial? ] } except-these repeat1 ; + +: case-insensitive ( parser -- parser' ) + [ flatten >string >lower ] action ; + +: case-sensitive ( parser -- parser' ) + [ flatten >string ] action ; + +: 'space' ( -- parser ) + [ " \t" member? ] satisfy repeat0 hide ; + +: one-of ( strings -- parser ) + [ token ] map choice ; + +: 'http-method' ( -- parser ) + { "OPTIONS" "GET" "HEAD" "POST" "PUT" "DELETE" "TRACE" "CONNECT" } one-of ; + +: 'url' ( -- parser ) + [ " \t\r\n" member? ] except repeat1 case-sensitive ; + +: 'http-version' ( -- parser ) + [ + "HTTP" token hide , + 'space' , + "/" token hide , + 'space' , + "1" token , + "." token , + { "0" "1" } one-of , + ] seq* [ concat >string ] action ; + +PEG: parse-request-line ( string -- triple ) + #! Triple is { method url version } + [ + 'space' , + 'http-method' , + 'space' , + 'url' , + 'space' , + 'http-version' , + 'space' , + ] seq* just ; + +: 'text' ( -- parser ) + [ ctl? ] except ; + +: 'response-code' ( -- parser ) + [ digit? ] satisfy 3 exactly-n [ string>number ] action ; + +: 'response-message' ( -- parser ) + 'text' repeat0 case-sensitive ; + +PEG: parse-response-line ( string -- triple ) + #! Triple is { version code message } + [ + 'space' , + 'http-version' , + 'space' , + 'response-code' , + 'space' , + 'response-message' , + ] seq* just ; + +: 'crlf' ( -- parser ) + "\r\n" token ; + +: 'lws' ( -- parser ) + [ " \t" member? ] satisfy repeat1 ; + +: 'qdtext' ( -- parser ) + { [ CHAR: " = ] [ ctl? ] } except-these ; + +: 'quoted-char' ( -- parser ) + "\\" token hide any-char 2seq ; + +: 'quoted-string' ( -- parser ) + 'quoted-char' 'qdtext' 2choice repeat0 "\"" "\"" surrounded-by ; + +: 'ctext' ( -- parser ) + { [ ctl? ] [ "()" member? ] } except-these ; + +: 'comment' ( -- parser ) + 'ctext' 'comment' 2choice repeat0 "(" ")" surrounded-by ; + +: 'field-name' ( -- parser ) + 'token' case-insensitive ; + +: 'field-content' ( -- parser ) + 'quoted-string' case-sensitive + 'text' repeat0 case-sensitive + 2choice ; + +PEG: parse-header-line ( string -- pair ) + #! Pair is either { name value } or { f value }. If f, its a + #! continuation of the previous header line. + [ + 'field-name' , + 'space' , + ":" token hide , + 'space' , + 'field-content' , + ] seq* + [ + 'lws' [ drop f ] action , + 'field-content' , + ] seq* + 2choice ; + +: 'word' ( -- parser ) + 'token' 'quoted-string' 2choice ; + +: 'value' ( -- parser ) + 'quoted-string' + [ ";" member? ] except repeat0 + 2choice case-sensitive ; + +: 'attr' ( -- parser ) + 'token' case-insensitive ; + +: 'av-pair' ( -- parser ) + [ + 'space' , + 'attr' , + 'space' , + [ "=" token , 'space' , 'value' , ] seq* [ peek ] action + epsilon [ drop f ] action + 2choice , + 'space' , + ] seq* ; + +: 'av-pairs' ( -- parser ) + 'av-pair' ";" token list-of optional ; + +PEG: (parse-set-cookie) ( string -- alist ) 'av-pairs' just ; + +: 'cookie-value' ( -- parser ) + [ + 'space' , + 'attr' , + 'space' , + "=" token hide , + 'space' , + 'value' , + 'space' , + ] seq* ; + +PEG: (parse-cookie) ( string -- alist ) + 'cookie-value' [ ";," member? ] satisfy list-of optional just ; From 9453415eb5f9196a3a7de44dd33ae27d0efd1ebb Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:37:04 -0500 Subject: [PATCH 0256/1850] https support --- extra/furnace/auth/auth.factor | 27 +++++++++++++++----- extra/furnace/auth/login/login.factor | 13 +++++++--- extra/furnace/boilerplate/boilerplate.factor | 8 +++++- extra/furnace/redirection/redirection.factor | 16 ++++++++++-- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/extra/furnace/auth/auth.factor b/extra/furnace/auth/auth.factor index d9f517aaf4..ae042f05bd 100755 --- a/extra/furnace/auth/auth.factor +++ b/extra/furnace/auth/auth.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs namespaces kernel sequences sets -destructors combinators +destructors combinators fry io.encodings.utf8 io.encodings.string io.binary random checksums checksums.sha2 html.forms @@ -10,6 +10,7 @@ http.server.filters http.server.dispatchers furnace furnace.actions +furnace.redirection furnace.boilerplate furnace.auth.providers furnace.auth.providers.db ; @@ -54,7 +55,7 @@ V{ } clone capabilities set-global : define-capability ( word -- ) capabilities get adjoin ; -TUPLE: realm < dispatcher name users checksum ; +TUPLE: realm < dispatcher name users checksum secure ; GENERIC: login-required* ( realm -- response ) @@ -67,7 +68,8 @@ GENERIC: logged-in-username ( realm -- username ) swap >>name swap >>default users-in-db >>users - sha-256 >>checksum ; inline + sha-256 >>checksum + t >>secure ; inline : users ( -- provider ) realm get users>> ; @@ -104,6 +106,16 @@ M: realm call-responder* ( path responder -- response ) : check-login ( password username -- user/f ) users get-user dup [ [ valid-login? ] keep and ] [ 2drop f ] if ; +: if-secure-realm ( quot -- ) + realm get secure>> [ if-secure ] [ call ] if ; inline + +TUPLE: secure-realm-only < filter-responder ; + +C: secure-realm-only + +M: secure-realm-only call-responder* + '[ , , call-next-method ] if-secure-realm ; + TUPLE: protected < filter-responder description capabilities ; : ( responder -- protected ) @@ -118,9 +130,12 @@ TUPLE: protected < filter-responder description capabilities ; } cond ; M: protected call-responder* ( path responder -- response ) - dup protected set - dup logged-in-user get check-capabilities - [ call-next-method ] [ 2drop realm get login-required* ] if ; + '[ + , , + dup protected set + dup logged-in-user get check-capabilities + [ call-next-method ] [ 2drop realm get login-required* ] if + ] if-secure-realm ; : ( responder -- responder' ) { realm "boilerplate" } >>template ; diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 4c53cb9c89..68161382c1 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -39,8 +39,11 @@ M: login-realm modify-form ( responder -- ) : ( -- cookie ) permit-id get realm get name>> permit-id-key "$login-realm" resolve-base-path >>path - realm get timeout>> from-now >>expires - realm get domain>> >>domain ; + realm get + [ timeout>> from-now >>expires ] + [ domain>> >>domain ] + [ secure>> >>secure ] + tri ; : put-permit-cookie ( response -- response' ) put-cookie ; @@ -82,7 +85,9 @@ SYMBOL: capabilities "password" value "username" value check-login [ successful-login ] [ login-failed ] if* - ] >>submit ; + ] >>submit + + ; : ( -- action ) @@ -99,6 +104,6 @@ M: login-realm login-required* : ( responder name -- auth ) login-realm new-realm - "login" add-responder + "login" add-responder "logout" add-responder 20 minutes >>timeout ; diff --git a/extra/furnace/boilerplate/boilerplate.factor b/extra/furnace/boilerplate/boilerplate.factor index a976199661..0e2a673d9b 100644 --- a/extra/furnace/boilerplate/boilerplate.factor +++ b/extra/furnace/boilerplate/boilerplate.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel namespaces +USING: accessors kernel math.order namespaces combinators.lib html.forms html.templates html.templates.chloe @@ -17,6 +17,12 @@ TUPLE: boilerplate < filter-responder template init ; swap >>responder [ ] >>init ; +: wrap-boilerplate? ( response -- ? ) + { + [ code>> { [ 200 = ] [ 400 499 between? ] } 1|| ] + [ content-type>> "text/html" = ] + } 1&& ; + M:: boilerplate call-responder* ( path responder -- ) begin-form path responder call-next-method diff --git a/extra/furnace/redirection/redirection.factor b/extra/furnace/redirection/redirection.factor index 7f87c677b9..88d621b573 100644 --- a/extra/furnace/redirection/redirection.factor +++ b/extra/furnace/redirection/redirection.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel accessors combinators namespaces +USING: kernel accessors combinators namespaces fry io.servers.connection -http http.server http.server.redirection +http http.server http.server.redirection http.server.filters furnace ; IN: furnace.redirection @@ -27,3 +27,15 @@ TUPLE: redirect-responder to ; redirect-responder boa ; M: redirect-responder call-responder* nip to>> ; + +TUPLE: secure-only < filter-responder ; + +C: secure-only + +: if-secure ( quot -- ) + >r request get url>> protocol>> "http" = + [ request get url>> ] + r> if ; inline + +M: secure-only call-responder* + '[ , , call-next-method ] if-secure ; From 21d3380bf229ccc856b2afc4e7550d84aa6192c2 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:50:10 -0500 Subject: [PATCH 0257/1850] Bootstrap fix --- core/optimizer/known-words/known-words.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/optimizer/known-words/known-words.factor b/core/optimizer/known-words/known-words.factor index 7f882d85d0..d69a2f94bc 100755 --- a/core/optimizer/known-words/known-words.factor +++ b/core/optimizer/known-words/known-words.factor @@ -98,7 +98,7 @@ sequences.private combinators byte-arrays byte-vectors ; dup bit-member? [ bit-member-quot ] [ - [ [ t ] ] { } map>assoc + [ literalize [ t ] ] { } map>assoc [ drop f ] suffix [ nip case ] curry ] if ; From 83099e01d4ecb4670c05f12e33023f211769d4f3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 00:58:29 -0500 Subject: [PATCH 0258/1850] Fixing PEG: --- extra/peg/peg.factor | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 05f84afedb..3d3b4ad626 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -571,14 +571,16 @@ M: parse-failed error. : PEG: (:) - [let* | def [ ] word [ ] compiled-def [ def call compile ] | + [let | word [ ] def [ ] | [ [ - [ - dup compiled-def compiled-parse - [ ast>> ] [ word parse-failed ] ?if + [let | compiled-def [ def call compile ] + [ + dup compiled-def compiled-parse + [ ast>> ] [ word parse-failed ] ?if + ] + word swap define ] - word swap define ] with-compilation-unit ] over push-all ] ; parsing From e55c674a2bf97bbf87a38aba0db752d6b03edae4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 01:18:39 -0500 Subject: [PATCH 0259/1850] Fix again --- extra/peg/peg.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 3d3b4ad626..54c25778de 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -571,10 +571,10 @@ M: parse-failed error. : PEG: (:) - [let | word [ ] def [ ] | + [let | def [ ] word [ ] | [ [ - [let | compiled-def [ def call compile ] + [let | compiled-def [ def call compile ] | [ dup compiled-def compiled-parse [ ast>> ] [ word parse-failed ] ?if From 6d2ded44f28c0be26dbe33bfb9231f18a1db9d85 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 01:40:48 -0500 Subject: [PATCH 0260/1850] Launcher fix --- extra/io/unix/launcher/launcher.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 7f6b3396a1..365e51749d 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -31,7 +31,7 @@ USE: unix ] when* ; : redirect-fd ( oldfd fd -- ) - 2dup = [ 2drop ] [ dupd dup2 io-error close-file ] if ; + 2dup = [ 2drop ] [ dup2 io-error ] if ; : reset-fd ( fd -- ) #! We drop the error code because on *BSD, fcntl of From 6aa23fd7a2c93cff05fd89c3260abc281140a14c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 01:52:50 -0500 Subject: [PATCH 0261/1850] Fix http.client load error' --- extra/http/client/client.factor | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/extra/http/client/client.factor b/extra/http/client/client.factor index 56957b021c..0b9224f171 100755 --- a/extra/http/client/client.factor +++ b/extra/http/client/client.factor @@ -79,13 +79,9 @@ ERROR: download-failed response body ; M: download-failed error. "HTTP download failed:" print nl - [ - response>> - write-response-code - write-response-message nl - drop - ] - [ body>> write ] bi ; + [ response>> write-response-line nl drop ] + [ body>> write ] + bi ; : check-response ( response data -- response data ) over code>> success? [ download-failed ] unless ; From ef29b725b8be7927a9f112ab2b5f699ca97aa260 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 01:59:29 -0500 Subject: [PATCH 0262/1850] Fix ftp.server load error --- extra/ftp/server/server.factor | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/extra/ftp/server/server.factor b/extra/ftp/server/server.factor index cce69dde0f..c71eadb72f 100644 --- a/extra/ftp/server/server.factor +++ b/extra/ftp/server/server.factor @@ -2,9 +2,9 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors combinators io io.encodings.8-bit io.encodings io.encodings.binary io.encodings.utf8 io.files -io.server io.sockets kernel math.parser namespaces sequences +io.sockets kernel math.parser namespaces sequences ftp io.unix.launcher.parser unicode.case splitting assocs -classes io.server destructors calendar io.timeouts +classes io.servers.connection destructors calendar io.timeouts io.streams.duplex threads continuations math concurrency.promises byte-arrays ; IN: ftp.server @@ -305,7 +305,10 @@ ERROR: not-a-directory ; [ drop unrecognized-command t ] } case [ handle-client-loop ] when ; -: handle-client ( -- ) +TUPLE: ftp-server < threaded-server ; + +M: ftp-server handle-client* ( server -- ) + drop [ "" [ host-name client set @@ -313,9 +316,14 @@ ERROR: not-a-directory ; ] with-directory ] with-destructors ; +: ( port -- server ) + ftp-server new-threaded-server + swap >>insecure + "ftp.server" >>name + latin1 >>encoding ; + : ftpd ( port -- ) - internet-server "ftp.server" - latin1 [ handle-client ] with-server ; + start-server ; : ftpd-main ( -- ) 2100 ftpd ; From 1260a87468dd1a83f6d35b38d3ac60844186ad30 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 02:52:49 -0500 Subject: [PATCH 0263/1850] Debugging 'recover password' --- .../features/recover-password/recover-1.xml | 2 +- .../features/recover-password/recover-3.xml | 2 +- .../features/recover-password/recover-4.xml | 2 +- .../recover-password/recover-password.factor | 30 +++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/extra/furnace/auth/features/recover-password/recover-1.xml b/extra/furnace/auth/features/recover-password/recover-1.xml index 21fbe6fd39..46e52d5319 100644 --- a/extra/furnace/auth/features/recover-password/recover-1.xml +++ b/extra/furnace/auth/features/recover-password/recover-1.xml @@ -6,7 +6,7 @@

Enter the username and e-mail address you used to register for this site, and you will receive a link for activating a new password.

- +
diff --git a/extra/furnace/auth/features/recover-password/recover-3.xml b/extra/furnace/auth/features/recover-password/recover-3.xml index 2e412d1f18..a71118ea31 100644 --- a/extra/furnace/auth/features/recover-password/recover-3.xml +++ b/extra/furnace/auth/features/recover-password/recover-3.xml @@ -6,7 +6,7 @@

Choose a new password for your account.

- +
diff --git a/extra/furnace/auth/features/recover-password/recover-4.xml b/extra/furnace/auth/features/recover-password/recover-4.xml index f5d02fa858..d71a01bc25 100755 --- a/extra/furnace/auth/features/recover-password/recover-4.xml +++ b/extra/furnace/auth/features/recover-password/recover-4.xml @@ -4,6 +4,6 @@ Recover lost password: step 4 of 4 -

Your password has been reset. You may now log in.

+

Your password has been reset. You may now proceed.

diff --git a/extra/furnace/auth/features/recover-password/recover-password.factor b/extra/furnace/auth/features/recover-password/recover-password.factor index 806df024f0..93b3a7ad73 100644 --- a/extra/furnace/auth/features/recover-password/recover-password.factor +++ b/extra/furnace/auth/features/recover-password/recover-password.factor @@ -1,8 +1,9 @@ ! Copyright (c) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: namespaces accessors kernel assocs arrays io.sockets threads -fry urls smtp validators html.forms -http http.server.responses http.server.dispatchers +fry urls smtp validators html.forms present +http http.server.responses http.server.redirection +http.server.dispatchers furnace furnace.actions furnace.auth furnace.auth.providers furnace.redirection ; IN: furnace.auth.features.recover-password @@ -13,13 +14,12 @@ SYMBOL: lost-password-from request get url>> host>> host-name or ; : new-password-url ( user -- url ) - "recover-3" - swap [ - [ username>> "username" set ] - [ ticket>> "ticket" set ] + URL" recover-3" clone + swap + [ username>> "username" set-query-param ] + [ ticket>> "ticket" set-query-param ] bi - ] H{ } make-assoc - derive-url ; + adjust-url relative-to-request ; : password-email ( user -- email ) @@ -35,7 +35,7 @@ SYMBOL: lost-password-from "If you believe that this request was legitimate, you may click the below link in\n" % "your browser to set a new password for your account:\n" % "\n" % - swap new-password-url % + swap new-password-url present % "\n\n" % "Love,\n" % "\n" % @@ -48,7 +48,7 @@ SYMBOL: lost-password-from : ( -- action ) - { realm "recover-1" } >>template + { realm "features/recover-password/recover-1" } >>template [ { @@ -64,12 +64,12 @@ SYMBOL: lost-password-from send-password-email ] when* - URL" $login/recover-2" + URL" $realm/recover-2" ] >>submit ; : ( -- action ) - { realm "recover-2" } >>template ; + { realm "features/recover-password/recover-2" } >>template ; : ( -- action ) @@ -80,7 +80,7 @@ SYMBOL: lost-password-from } validate-params ] >>init - { realm "recover-3" } >>template + { realm "features/recover-password/recover-3" } >>template [ { @@ -100,7 +100,7 @@ SYMBOL: lost-password-from "new-password" value >>encoded-password users update-user - URL" $login/recover-4" + URL" $realm/recover-4" ] [ <403> ] if* @@ -108,7 +108,7 @@ SYMBOL: lost-password-from : ( -- action ) - { realm "recover-4" } >>template ; + { realm "features/recover-password/recover-4" } >>template ; : allow-password-recovery ( login -- login ) From ef6807a4dd6786c349abb93ccbfdfb458d5a26a8 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 02:54:11 -0500 Subject: [PATCH 0264/1850] Tweak --- extra/websites/concatenative/concatenative.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor index fcf98b08da..1e79b043e2 100644 --- a/extra/websites/concatenative/concatenative.factor +++ b/extra/websites/concatenative/concatenative.factor @@ -63,8 +63,8 @@ TUPLE: factor-website < dispatcher ; : init-factor-website ( -- ) "factorcode.org" 25 smtp-server set-global - "todo@factorcode.org" lost-password-from set-global - "website@factorcode.org" insomniac-sender set-global + "noreply@concatenative.org" lost-password-from set-global + "website@concatenative.org" insomniac-sender set-global "slava@factorcode.org" insomniac-recipients set-global init-factor-db main-responder set-global ; From 9ce8116fad5a079343eebef63d0cac7176927570 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 03:16:45 -0500 Subject: [PATCH 0265/1850] Fix 'delete user' --- extra/webapps/user-admin/user-admin.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index 359730d4b2..f445b6f471 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -139,7 +139,7 @@ TUPLE: user-admin < dispatcher ; [ validate-username - select-tuple 1 >>deleted update-tuple + "username" value select-tuple 1 >>deleted update-tuple URL" $user-admin" ] >>submit ; From db6b24614fbfadf820a97af19a3cbc7299cf7ba4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 03:26:50 -0500 Subject: [PATCH 0266/1850] Improving user-admin tool --- .../deactivate-user/deactivate-user.factor | 22 +++++++++++++++++++ .../features/edit-profile/edit-profile.xml | 3 +++ .../features/registration/registration.factor | 5 +++-- extra/html/templates/chloe/chloe.factor | 5 ++--- extra/webapps/user-admin/user-admin.factor | 2 +- .../concatenative/concatenative.factor | 2 ++ 6 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 extra/furnace/auth/features/deactivate-user/deactivate-user.factor diff --git a/extra/furnace/auth/features/deactivate-user/deactivate-user.factor b/extra/furnace/auth/features/deactivate-user/deactivate-user.factor new file mode 100644 index 0000000000..49fa00353b --- /dev/null +++ b/extra/furnace/auth/features/deactivate-user/deactivate-user.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel assocs namespaces accessors db db.tuples urls +http.server.dispatchers +furnace.asides furnace.actions furnace.auth furnace.auth.providers ; +IN: furnace.auth.features.deactivate-user + +: ( -- action ) + + [ + logged-in-user get + 1 >>deleted + t >>changed? + drop + URL" $realm" end-aside + ] >>submit ; + +: allow-deactivation ( realm -- realm ) + "deactivate-user" add-responder ; + +: allow-deactivation? ( -- ? ) + realm get responders>> "deactivate-user" swap key? ; diff --git a/extra/furnace/auth/features/edit-profile/edit-profile.xml b/extra/furnace/auth/features/edit-profile/edit-profile.xml index 011cc2bdf8..a9d7994e97 100644 --- a/extra/furnace/auth/features/edit-profile/edit-profile.xml +++ b/extra/furnace/auth/features/edit-profile/edit-profile.xml @@ -67,4 +67,7 @@ + + Delete User + diff --git a/extra/furnace/auth/features/registration/registration.factor b/extra/furnace/auth/features/registration/registration.factor index 5c1851fb64..20a48d07d2 100644 --- a/extra/furnace/auth/features/registration/registration.factor +++ b/extra/furnace/auth/features/registration/registration.factor @@ -35,10 +35,11 @@ IN: furnace.auth.features.registration realm get init-user-profile URL" $realm" - ] >>submit ; + ] >>submit + ; : allow-registration ( login -- login ) - "register" add-responder ; + "register" add-responder ; : allow-registration? ( -- ? ) realm get responders>> "register" swap key? ; diff --git a/extra/html/templates/chloe/chloe.factor b/extra/html/templates/chloe/chloe.factor index 32fe954178..103020ee0f 100644 --- a/extra/html/templates/chloe/chloe.factor +++ b/extra/html/templates/chloe/chloe.factor @@ -87,11 +87,10 @@ CHLOE: comment drop ; CHLOE: call-next-template drop call-next-template ; : attr>word ( value -- word/f ) - dup ":" split1 swap lookup - [ ] [ "No such word: " swap append throw ] ?if ; + ":" split1 swap lookup ; : if-satisfied? ( tag -- ? ) - [ "code" optional-attr [ attr>word execute ] [ t ] if* ] + [ "code" optional-attr [ attr>word dup [ execute ] when ] [ t ] if* ] [ "value" optional-attr [ value ] [ t ] if* ] bi and ; diff --git a/extra/webapps/user-admin/user-admin.factor b/extra/webapps/user-admin/user-admin.factor index f445b6f471..2137abbc2d 100644 --- a/extra/webapps/user-admin/user-admin.factor +++ b/extra/webapps/user-admin/user-admin.factor @@ -139,7 +139,7 @@ TUPLE: user-admin < dispatcher ; [ validate-username - "username" value select-tuple 1 >>deleted update-tuple + "username" value delete-tuples URL" $user-admin" ] >>submit ; diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor index 1e79b043e2..a4f826d7f6 100644 --- a/extra/websites/concatenative/concatenative.factor +++ b/extra/websites/concatenative/concatenative.factor @@ -13,6 +13,7 @@ furnace.auth.providers.db furnace.auth.features.edit-profile furnace.auth.features.recover-password furnace.auth.features.registration +furnace.auth.features.deactivate-user furnace.boilerplate furnace.redirection webapps.blogs @@ -57,6 +58,7 @@ TUPLE: factor-website < dispatcher ; allow-registration allow-password-recovery allow-edit-profile + allow-deactivation { factor-website "page" } >>template test-db ; From 5a133ceeceab676eff63174e90b6232771a576c0 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 03:28:15 -0500 Subject: [PATCH 0267/1850] Security --- .../auth/features/deactivate-user/deactivate-user.factor | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extra/furnace/auth/features/deactivate-user/deactivate-user.factor b/extra/furnace/auth/features/deactivate-user/deactivate-user.factor index 49fa00353b..cf6a56c2d4 100644 --- a/extra/furnace/auth/features/deactivate-user/deactivate-user.factor +++ b/extra/furnace/auth/features/deactivate-user/deactivate-user.factor @@ -16,7 +16,9 @@ IN: furnace.auth.features.deactivate-user ] >>submit ; : allow-deactivation ( realm -- realm ) - "deactivate-user" add-responder ; + + "delete your profile" >>description + "deactivate-user" add-responder ; : allow-deactivation? ( -- ? ) realm get responders>> "deactivate-user" swap key? ; From 1b8943a8e0476d7f68542924b3a3079dc1d2d361 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 16 Jun 2008 17:39:14 +1200 Subject: [PATCH 0268/1850] Add failing peg.ebnf tests --- extra/peg/ebnf/ebnf-tests.factor | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index faaa63f4bd..425c05f391 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -365,3 +365,36 @@ main = Primary "ab c ab c" [EBNF a="a" "b" foo=(a "c")* EBNF] call ast>> ] unit-test +{ V{ "a" "a" "a" } } [ + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ drop x ]] EBNF] call ast>> +] unit-test + +{ t } [ + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ drop x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ drop x ]] EBNF] call ast>> = +] unit-test + +{ V{ "a" "a" "a" } } [ + "aaa" [EBNF a=('a')* b=a:x => [[ drop x ]] EBNF] call ast>> +] unit-test + +{ t } [ + "aaa" [EBNF a=('a')* b=a:x => [[ drop x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=(a):x => [[ drop x ]] EBNF] call ast>> = +] unit-test + +{ t } [ + "number=(digit)+:n 'a'" 'ebnf' parse remaining>> length zero? +] unit-test + +{ t } [ + "number=(digit)+ 'a'" 'ebnf' parse remaining>> length zero? +] unit-test + +{ t } [ + "number=digit+ 'a'" 'ebnf' parse remaining>> length zero? +] unit-test + +{ t } [ + "number=digit+:n 'a'" 'ebnf' parse remaining>> length zero? +] unit-test \ No newline at end of file From f1219c906aab7aa0d84b27694e998f2960c30775 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 15:25:47 +1200 Subject: [PATCH 0269/1850] Check stack effect of actions in ebnf. Do implicit drop if needed --- extra/peg/ebnf/ebnf.factor | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index fc10a65024..44765cc60c 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel compiler.units parser words arrays strings math.parser sequences quotations vectors namespaces math assocs continuations peg - peg.parsers unicode.categories multiline combinators.lib - splitting accessors effects sequences.deep peg.search ; + peg.parsers unicode.categories multiline combinators combinators.lib + splitting accessors effects sequences.deep peg.search inference ; IN: peg.ebnf TUPLE: ebnf-non-terminal symbol ; @@ -340,9 +340,16 @@ M: ebnf-var build-locals ( code ast -- ) M: object build-locals ( code ast -- ) drop ; +: check-action-effect ( quot -- quot ) + dup infer { + { [ dup (( a -- b )) effect<= ] [ drop ] } + { [ dup (( -- b )) effect<= ] [ drop [ drop ] prepose ] } + [ "Bad effect: " swap effect>string append throw ] + } cond ; + M: ebnf-action (transform) ( ast -- parser ) [ parser>> (transform) ] [ code>> ] [ parser>> ] tri build-locals - string-lines parse-lines action ; + string-lines parse-lines check-action-effect action ; M: ebnf-semantic (transform) ( ast -- parser ) [ parser>> (transform) ] [ code>> ] [ parser>> ] tri build-locals From dfa4926a84f5fbec165fe398fe7ed78e3666f298 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 22:47:38 +1200 Subject: [PATCH 0270/1850] Print ebnf quotation on error. Fix generated local quotation --- extra/peg/ebnf/ebnf.factor | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 44765cc60c..335607b463 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -3,7 +3,8 @@ USING: kernel compiler.units parser words arrays strings math.parser sequences quotations vectors namespaces math assocs continuations peg peg.parsers unicode.categories multiline combinators combinators.lib - splitting accessors effects sequences.deep peg.search inference ; + splitting accessors effects sequences.deep peg.search inference + io.streams.string io prettyprint ; IN: peg.ebnf TUPLE: ebnf-non-terminal symbol ; @@ -324,7 +325,7 @@ M: ebnf-sequence build-locals ( code ast -- code ) ] 2each " | " % % - " ]" % + " nip ]" % ] "" make ] if ; @@ -334,7 +335,7 @@ M: ebnf-var build-locals ( code ast -- ) name>> % " [ dup ] " % " | " % % - " ]" % + " nip ]" % ] "" make ; M: object build-locals ( code ast -- ) @@ -344,7 +345,12 @@ M: object build-locals ( code ast -- ) dup infer { { [ dup (( a -- b )) effect<= ] [ drop ] } { [ dup (( -- b )) effect<= ] [ drop [ drop ] prepose ] } - [ "Bad effect: " swap effect>string append throw ] + [ + [ + "Bad effect: " write effect>string write + " for quotation " write pprint + ] with-string-writer throw + ] } cond ; M: ebnf-action (transform) ( ast -- parser ) From 479fa6a5b5a3ea5ebec18d4eba8ae30579531c60 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 15:07:23 +1200 Subject: [PATCH 0271/1850] Add support for calling foreign peg.ebnf rules --- extra/peg/ebnf/ebnf.factor | 43 +++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 335607b463..4828ace9af 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -1,14 +1,19 @@ ! Copyright (C) 2007 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel compiler.units parser words arrays strings math.parser sequences +USING: kernel compiler.units words arrays strings math.parser sequences quotations vectors namespaces math assocs continuations peg peg.parsers unicode.categories multiline combinators combinators.lib splitting accessors effects sequences.deep peg.search inference - io.streams.string io prettyprint ; + io.streams.string io prettyprint parser ; IN: peg.ebnf +: rule ( name word -- parser ) + #! Given an EBNF word produced from EBNF: return the EBNF rule + "ebnf-parser" word-prop at ; + TUPLE: ebnf-non-terminal symbol ; TUPLE: ebnf-terminal symbol ; +TUPLE: ebnf-foreign word rule ; TUPLE: ebnf-any-character ; TUPLE: ebnf-range pattern ; TUPLE: ebnf-ensure group ; @@ -27,6 +32,7 @@ TUPLE: ebnf rules ; C: ebnf-non-terminal C: ebnf-terminal +C: ebnf-foreign C: ebnf-any-character C: ebnf-range C: ebnf-ensure @@ -88,6 +94,8 @@ C: ebnf [ dup CHAR: ? = ] [ dup CHAR: : = ] [ dup CHAR: ~ = ] + [ dup CHAR: < = ] + [ dup CHAR: > = ] } 0|| not nip ] satisfy repeat1 [ >string ] action ; @@ -96,6 +104,24 @@ C: ebnf #! and it represents the literal value of the identifier. 'identifier' [ ] action ; +: 'foreign-name' ( -- parser ) + #! Parse a valid foreign parser name + [ + { + [ dup blank? ] + [ dup CHAR: > = ] + } 0|| not nip + ] satisfy repeat1 [ >string ] action ; + +: 'foreign' ( -- parser ) + #! A foreign call is a call to a rule in another ebnf grammar + [ + "" syntax , + ] seq* [ first2 ] action ; + : 'any-character' ( -- parser ) #! A parser to match the symbol for any character match. [ CHAR: . = ] satisfy [ drop ] action ; @@ -117,6 +143,7 @@ C: ebnf [ 'non-terminal' , 'terminal' , + 'foreign' , 'range-parser' , 'any-character' , ] choice* , @@ -367,6 +394,15 @@ M: ebnf-var (transform) ( ast -- parser ) M: ebnf-terminal (transform) ( ast -- parser ) symbol>> token ; +M: ebnf-foreign (transform) ( ast -- parser ) + dup word>> search + [ "Foreign word " swap word>> append " not found" append throw ] unless* + swap rule>> dup [ + swap rule + ] [ + execute + ] if ; + : parser-not-found ( name -- * ) [ "Parser " % % " not found." % @@ -411,6 +447,3 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) ";EBNF" parse-multiline-string replace-escapes ebnf>quot swapd 1 1 define-declared "ebnf-parser" set-word-prop ; parsing -: rule ( name word -- parser ) - #! Given an EBNF word produced from EBNF: return the EBNF rule - "ebnf-parser" word-prop at ; \ No newline at end of file From 0841dbb4ad4567652a0acc53d3a0e1d4b24b4855 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 15:21:10 +1200 Subject: [PATCH 0272/1850] Fix ebnf unit test --- extra/peg/ebnf/ebnf-tests.factor | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index 425c05f391..04cc01c9d0 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -164,23 +164,23 @@ IN: peg.ebnf.tests ] unit-test { 6 } [ - "4+2" [EBNF num=[0-9] => [[ digit> ]] foo=num:x '+' num:y => [[ drop x y + ]] EBNF] call ast>> + "4+2" [EBNF num=[0-9] => [[ digit> ]] foo=num:x '+' num:y => [[ x y + ]] EBNF] call ast>> ] unit-test { 6 } [ - "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ drop x digit> y digit> + ]] EBNF] call ast>> + "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ x digit> y digit> + ]] EBNF] call ast>> ] unit-test { 10 } [ - { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] call ast>> + { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ast>> ] unit-test { f } [ - { "a" 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] call + { "a" 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ] unit-test { 3 } [ - { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] call ast>> + { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ast>> ] unit-test { f } [ @@ -251,7 +251,7 @@ IN: peg.ebnf.tests ] unit-test { t } [ - "abcd='9' | ('8'):x => [[ drop x ]]" 'ebnf' parse parse-result-remaining empty? + "abcd='9' | ('8'):x => [[ x ]]" 'ebnf' parse parse-result-remaining empty? ] unit-test EBNF: primary @@ -366,21 +366,21 @@ main = Primary ] unit-test { V{ "a" "a" "a" } } [ - "aaa" [EBNF a=('a')* b=!('b') a:x => [[ drop x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] call ast>> ] unit-test { t } [ - "aaa" [EBNF a=('a')* b=!('b') a:x => [[ drop x ]] EBNF] call ast>> - "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ drop x ]] EBNF] call ast>> = + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ x ]] EBNF] call ast>> = ] unit-test { V{ "a" "a" "a" } } [ - "aaa" [EBNF a=('a')* b=a:x => [[ drop x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] call ast>> ] unit-test { t } [ - "aaa" [EBNF a=('a')* b=a:x => [[ drop x ]] EBNF] call ast>> - "aaa" [EBNF a=('a')* b=(a):x => [[ drop x ]] EBNF] call ast>> = + "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=(a):x => [[ x ]] EBNF] call ast>> = ] unit-test { t } [ From f4f4ea7eb6fd5b78f635ecbc019649db1a1dd817 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 17:34:21 +1200 Subject: [PATCH 0273/1850] Fix peg.ebnf unit test failures --- extra/peg/ebnf/ebnf.factor | 68 ++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 4828ace9af..215eabdd37 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -49,6 +49,10 @@ C: ebnf-var C: ebnf-semantic C: ebnf +: filter-hidden ( seq -- seq ) + #! Remove elements that produce no AST from sequence + [ ebnf-ensure-not? not ] filter [ ebnf-ensure? not ] filter ; + : syntax ( string -- parser ) #! Parses the string, ignoring white space, and #! does not put the result in the AST. @@ -140,12 +144,18 @@ C: ebnf #! The latter indicates that it is the beginning of a #! new rule. [ - [ - 'non-terminal' , - 'terminal' , - 'foreign' , - 'range-parser' , - 'any-character' , + [ + [ + 'non-terminal' , + 'terminal' , + 'foreign' , + 'range-parser' , + 'any-character' , + ] choice* + [ dup , "*" token hide , ] seq* [ first ] action , + [ dup , "+" token hide , ] seq* [ first ] action , + [ dup , "?[" token ensure-not , "?" token hide , ] seq* [ first ] action , + , ] choice* , [ "=" syntax ensure-not , @@ -153,6 +163,8 @@ C: ebnf ] choice* , ] seq* [ first ] action ; +DEFER: 'action' + : 'element' ( -- parser ) [ [ ('element') , ":" syntax , "a-zA-Z" range-pattern repeat1 [ >string ] action , ] seq* [ first2 ] action , @@ -256,7 +268,7 @@ DEFER: 'choice' ] choice* ; : 'choice' ( -- parser ) - 'actioned-sequence' sp "|" token sp list-of [ + 'actioned-sequence' sp repeat1 [ dup length 1 = [ first ] [ ] if ] action "|" token sp list-of [ dup length 1 = [ first ] [ ] if ] action ; @@ -337,23 +349,29 @@ M: ebnf-whitespace (transform) ( ast -- parser ) GENERIC: build-locals ( code ast -- code ) M: ebnf-sequence build-locals ( code ast -- code ) - elements>> dup [ ebnf-var? ] filter empty? [ - drop - ] [ - [ - "USING: locals sequences ; [let* | " % - dup length swap [ - dup ebnf-var? [ - name>> % - " [ " % # " over nth ] " % - ] [ - 2drop - ] if - ] 2each - " | " % - % - " nip ]" % - ] "" make + #! Note the need to filter out this ebnf items that + #! leave nothing in the AST + elements>> filter-hidden dup length 1 = [ + first build-locals + ] [ + dup [ ebnf-var? ] filter empty? [ + drop + ] [ + [ + "USING: locals sequences ; [let* | " % + dup length swap [ + dup ebnf-var? [ + name>> % + " [ " % # " over nth ] " % + ] [ + 2drop + ] if + ] 2each + " | " % + % + " nip ]" % + ] "" make + ] if ] if ; M: ebnf-var build-locals ( code ast -- ) @@ -381,7 +399,7 @@ M: object build-locals ( code ast -- ) } cond ; M: ebnf-action (transform) ( ast -- parser ) - [ parser>> (transform) ] [ code>> ] [ parser>> ] tri build-locals + [ parser>> (transform) ] [ code>> ] [ parser>> ] tri build-locals string-lines parse-lines check-action-effect action ; M: ebnf-semantic (transform) ( ast -- parser ) From b338fc8feaa04050cac2e10be76a4d7cf812c4b3 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 21:55:53 +1200 Subject: [PATCH 0274/1850] Javascript parser --- extra/peg/javascript/javascript.factor | 247 +++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 extra/peg/javascript/javascript.factor diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor new file mode 100644 index 0000000000..33fd6dd069 --- /dev/null +++ b/extra/peg/javascript/javascript.factor @@ -0,0 +1,247 @@ +! Copyright (C) 2007 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel arrays strings math.parser sequences sequences.deep +peg peg.ebnf peg.parsers memoize namespaces math ; +IN: peg.javascript + +#! Grammar for JavaScript. Based on OMeta-JS example from: +#! http://jarrett.cs.ucla.edu/ometa-js/#JavaScript_Compiler + +USE: prettyprint + +TUPLE: ast-keyword value ; +TUPLE: ast-name value ; +TUPLE: ast-number value ; +TUPLE: ast-string value ; +TUPLE: ast-cond-expr condition then else ; +TUPLE: ast-set lhs rhs ; +TUPLE: ast-get value ; +TUPLE: ast-mset lhs rhs operator ; +TUPLE: ast-binop lhs rhs operator ; +TUPLE: ast-unop expr operator ; +TUPLE: ast-postop expr operator ; +TUPLE: ast-preop expr operator ; +TUPLE: ast-getp index expr ; +TUPLE: ast-send method expr args ; +TUPLE: ast-call expr args ; +TUPLE: ast-this ; +TUPLE: ast-new name args ; +TUPLE: ast-array values ; +TUPLE: ast-json bindings ; +TUPLE: ast-binding name value ; +TUPLE: ast-func fs body ; +TUPLE: ast-var name value ; +TUPLE: ast-begin statements ; +TUPLE: ast-if condition true false ; +TUPLE: ast-while condition statements ; +TUPLE: ast-do-while statements condition ; +TUPLE: ast-for i c u statements ; +TUPLE: ast-for-in v e statements ; +TUPLE: ast-switch expr statements ; +TUPLE: ast-break ; +TUPLE: ast-continue ; +TUPLE: ast-throw e ; +TUPLE: ast-try t e c f ; +TUPLE: ast-return e ; +TUPLE: ast-case c cs ; +TUPLE: ast-default cs ; +C: ast-name +C: ast-keyword +C: ast-number +C: ast-string +C: ast-cond-expr +C: ast-set +C: ast-get +C: ast-mset +C: ast-binop +C: ast-unop +C: ast-preop +C: ast-postop +C: ast-getp +C: ast-send +C: ast-call +C: ast-this +C: ast-new +C: ast-array +C: ast-json +C: ast-binding +C: ast-func +C: ast-var +C: ast-begin +C: ast-if +C: ast-while +C: ast-do-while +C: ast-for +C: ast-for-in +C: ast-switch +C: ast-break +C: ast-continue +C: ast-throw +C: ast-try +C: ast-return +C: ast-case +C: ast-default + +EBNF: javascript +Letter = [a-zA-Z] +Digit = [0-9] +Digits = (Digit)+ +SingleLineComment = "//" (!("\n") .)* "\n" => [[ drop ignore ]] +MultiLineComment = "/*" (!("*/") .)* "*/" => [[ drop ignore ]] +Space = " " | "\t" | "\n" | SingleLineComment | MultiLineComment +Spaces = (Space)* => [[ drop ignore ]] +NameFirst = Letter | "$" | "_" +NameRest = NameFirst | Digit +iName = NameFirst (NameRest)* => [[ first2 swap prefix >string ]] +Keyword = ("break" + | "case" + | "catch" + | "continue" + | "default" + | "delete" + | "do" + | "else" + | "finally" + | "for" + | "function" + | "if" + | "in" + | "instanceof" + | "new" + | "return" + | "switch" + | "this" + | "throw" + | "try" + | "typeof" + | "var" + | "void" + | "while" + | "with") => [[ ]] +Name = !(Keyword) (iName):n => [[ drop n ]] +Number = Digits:ws '.' Digits:fs => [[ drop ws "." fs 3array concat >string string>number ]] + | Digits => [[ >string string>number ]] + +EscapeChar = "\\n" => [[ drop 10 ]] + | "\\r" => [[ drop 13 ]] + | "\\t" => [[ drop 9 ]] +StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] +StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] +StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] +Str = '"""' StringChars1:cs '"""' => [[ drop cs ]] + | '"' StringChars2:cs '"' => [[ drop cs ]] + | "'" StringChars3:cs "'" => [[ drop cs ]] +Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" + | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" + | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" + | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" + | "&&" | "||=" | "||" | "." | "!" +Tok = Spaces (Name | Keyword | Number | Str | Special ) +Toks = (Tok)* Spaces +SpacesNoNl = (!("\n") Space)* => [[ drop ignore ]] + +Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ drop e t f ]] + | OrExpr:e "=" Expr:rhs => [[ drop e rhs ]] + | OrExpr:e "+=" Expr:rhs => [[ drop e rhs "+" ]] + | OrExpr:e "-=" Expr:rhs => [[ drop e rhs "-" ]] + | OrExpr:e "*=" Expr:rhs => [[ drop e rhs "*" ]] + | OrExpr:e "/=" Expr:rhs => [[ drop e rhs "/" ]] + | OrExpr:e "%=" Expr:rhs => [[ drop e rhs "%" ]] + | OrExpr:e "&&=" Expr:rhs => [[ drop e rhs "&&" ]] + | OrExpr:e "||=" Expr:rhs => [[ drop e rhs "||" ]] + | OrExpr:e => [[ drop e ]] + +OrExpr = OrExpr:x "||" AndExpr:y => [[ drop x y "||" ]] + | AndExpr +AndExpr = AndExpr:x "&&" EqExpr:y => [[ drop x y "&&" ]] + | EqExpr +EqExpr = EqExpr:x "==" RelExpr:y => [[ drop x y "==" ]] + | EqExpr:x "!=" RelExpr:y => [[ drop x y "!=" ]] + | EqExpr:x "===" RelExpr:y => [[ drop x y "===" ]] + | EqExpr:x "!==" RelExpr:y => [[ drop x y "!==" ]] + | RelExpr +RelExpr = RelExpr:x ">" AddExpr:y => [[ drop x y ">" ]] + | RelExpr:x ">=" AddExpr:y => [[ drop x y ">=" ]] + | RelExpr:x "<" AddExpr:y => [[ drop x y "<" ]] + | RelExpr:x "<=" AddExpr:y => [[ drop x y "<=" ]] + | RelExpr:x "instanceof" AddExpr:y => [[ drop x y "instanceof" ]] + | AddExpr +AddExpr = AddExpr:x "+" MulExpr:y => [[ drop x y "+" ]] + | AddExpr:x "-" MulExpr:y => [[ drop x y "-" ]] + | MulExpr +MulExpr = MulExpr:x "*" MulExpr:y => [[ drop x y "*" ]] + | MulExpr:x "/" MulExpr:y => [[ drop x y "/" ]] + | MulExpr:x "%" MulExpr:y => [[ drop x y "%" ]] + | Unary +Unary = "-" Postfix:p => [[ drop p "-" ]] + | "+" Postfix:p => [[ drop p ]] + | "++" Postfix:p => [[ drop p "++" ]] + | "--" Postfix:p => [[ drop p "--" ]] + | "!" Postfix:p => [[ drop p "!" ]] + | Postfix +Postfix = PrimExpr:p SpacesNoNl "++" => [[ drop p "++" ]] + | PrimExpr:p SpacesNoNl "--" => [[ drop p "--" ]] + | PrimExpr +Args = Expr ("," Expr)* => [[ first2 swap prefix ]] +PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ drop i p ]] + | PrimExpr:p "." Name:m "(" Args:as ")" => [[ drop m p as ]] + | PrimExpr:p "." Name:f => [[ drop f p ]] + | PrimExpr:p "(" Args:as ")" => [[ drop p as ]] + | PrimExprHd +PrimExprHd = "(" Expr:e ")" => [[ drop e ]] + | "this" => [[ drop ]] + | Name => [[ ]] + | Number => [[ ]] + | Str => [[ ]] + | "function" FuncRest:fr => [[ drop fr ]] + | "new" Name:n "(" Args:as ")" => [[ drop n as ]] + | "[" Args:es "]" => [[ drop es ]] + | Json +JsonBindings = JsonBinding ("," JsonBinding)* => [[ first2 swap prefix ]] +Json = "{" JsonBindings:bs "}" => [[ drop bs ]] +JsonBinding = JsonPropName:n ":" Expr:v => [[ drop n v ]] +JsonPropName = Name | Number | Str +Formal = Spaces Name +Formals = Formal ("," Formal)* => [[ first2 swap prefix ]] +FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ drop fs body ]] +Sc = SpacesNoNl ("\n" | "}")| ";" +Binding = Name:n "=" Expr:v => [[ drop n v ]] + | Name:n => [[ drop n "undefined" ]] +Block = "{" SrcElems:ss "}" => [[ drop ss ]] +Bindings = Binding ("," Binding)* => [[ first2 swap prefix ]] +For1 = "var" Binding => [[ second ]] + | Expr + | Spaces => [[ "undefined" ]] +For2 = Expr + | Spaces => [[ "true" ]] +For3 = Expr + | Spaces => [[ "undefined" ]] +ForIn1 = "var" Name:n => [[ drop n "undefined" ]] + | Expr +Switch1 = "case" Expr:c ":" SrcElems:cs => [[ drop c cs ]] + | "default" ":" SrcElems:cs => [[ drop cs ]] +SwitchBody = (Switch1)* +Finally = "finally" Block:b => [[ drop b ]] + | Spaces => [[ drop "undefined" ]] +Stmt = Block + | "var" Bindings:bs Sc => [[ drop bs ]] + | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ drop c t f ]] + | "if" "(" Expr:c ")" Stmt:t => [[ drop c t "undefined" ]] + | "while" "(" Expr:c ")" Stmt:s => [[ drop c s ]] + | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ drop s c ]] + | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ drop i c u s ]] + | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ drop v e s ]] + | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ drop e cs ]] + | "break" Sc => [[ drop ]] + | "continue" Sc => [[ drop ]] + | "throw" SpacesNoNl Expr:e Sc => [[ drop e ]] + | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ drop t e c f ]] + | "return" Expr:e Sc => [[ drop e ]] + | "return" Sc => [[ drop "undefined" ]] + | Expr:e Sc => [[ drop e ]] + | ";" => [[ drop "undefined" ]] +SrcElem = "function" Name:n FuncRest:f => [[ drop n f ]] + | Stmt +SrcElems = (SrcElem)* => [[ ]] +TopLevel = SrcElems Spaces +;EBNF \ No newline at end of file From 79dfe2806a873b9bef9f405bb8f222eab4b86f50 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 22:07:57 +1200 Subject: [PATCH 0275/1850] Remove javascript boa constructors --- extra/peg/javascript/javascript.factor | 190 ++++++++++--------------- 1 file changed, 77 insertions(+), 113 deletions(-) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 33fd6dd069..5c76c45f4c 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -45,42 +45,6 @@ TUPLE: ast-try t e c f ; TUPLE: ast-return e ; TUPLE: ast-case c cs ; TUPLE: ast-default cs ; -C: ast-name -C: ast-keyword -C: ast-number -C: ast-string -C: ast-cond-expr -C: ast-set -C: ast-get -C: ast-mset -C: ast-binop -C: ast-unop -C: ast-preop -C: ast-postop -C: ast-getp -C: ast-send -C: ast-call -C: ast-this -C: ast-new -C: ast-array -C: ast-json -C: ast-binding -C: ast-func -C: ast-var -C: ast-begin -C: ast-if -C: ast-while -C: ast-do-while -C: ast-for -C: ast-for-in -C: ast-switch -C: ast-break -C: ast-continue -C: ast-throw -C: ast-try -C: ast-return -C: ast-case -C: ast-default EBNF: javascript Letter = [a-zA-Z] @@ -117,10 +81,10 @@ Keyword = ("break" | "var" | "void" | "while" - | "with") => [[ ]] -Name = !(Keyword) (iName):n => [[ drop n ]] -Number = Digits:ws '.' Digits:fs => [[ drop ws "." fs 3array concat >string string>number ]] - | Digits => [[ >string string>number ]] + | "with") => [[ ast-keyword boa ]] +Name = !(Keyword) (iName):n => [[ drop n ast-name boa ]] +Number = Digits:ws '.' Digits:fs => [[ drop ws "." fs 3array concat >string string>number ast-number boa ]] + | Digits => [[ >string string>number ast-number boa ]] EscapeChar = "\\n" => [[ drop 10 ]] | "\\r" => [[ drop 13 ]] @@ -128,9 +92,9 @@ EscapeChar = "\\n" => [[ drop 10 ]] StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] -Str = '"""' StringChars1:cs '"""' => [[ drop cs ]] - | '"' StringChars2:cs '"' => [[ drop cs ]] - | "'" StringChars3:cs "'" => [[ drop cs ]] +Str = '"""' StringChars1:cs '"""' => [[ drop cs ast-string boa ]] + | '"' StringChars2:cs '"' => [[ drop cs ast-string boa ]] + | "'" StringChars3:cs "'" => [[ drop cs ast-string boa ]] Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" @@ -140,108 +104,108 @@ Tok = Spaces (Name | Keyword | Number | Str | Special ) Toks = (Tok)* Spaces SpacesNoNl = (!("\n") Space)* => [[ drop ignore ]] -Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ drop e t f ]] - | OrExpr:e "=" Expr:rhs => [[ drop e rhs ]] - | OrExpr:e "+=" Expr:rhs => [[ drop e rhs "+" ]] - | OrExpr:e "-=" Expr:rhs => [[ drop e rhs "-" ]] - | OrExpr:e "*=" Expr:rhs => [[ drop e rhs "*" ]] - | OrExpr:e "/=" Expr:rhs => [[ drop e rhs "/" ]] - | OrExpr:e "%=" Expr:rhs => [[ drop e rhs "%" ]] - | OrExpr:e "&&=" Expr:rhs => [[ drop e rhs "&&" ]] - | OrExpr:e "||=" Expr:rhs => [[ drop e rhs "||" ]] +Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ drop e t f ast-cond-expr boa ]] + | OrExpr:e "=" Expr:rhs => [[ drop e rhs ast-set boa ]] + | OrExpr:e "+=" Expr:rhs => [[ drop e rhs "+" ast-mset boa ]] + | OrExpr:e "-=" Expr:rhs => [[ drop e rhs "-" ast-mset boa ]] + | OrExpr:e "*=" Expr:rhs => [[ drop e rhs "*" ast-mset boa ]] + | OrExpr:e "/=" Expr:rhs => [[ drop e rhs "/" ast-mset boa ]] + | OrExpr:e "%=" Expr:rhs => [[ drop e rhs "%" ast-mset boa ]] + | OrExpr:e "&&=" Expr:rhs => [[ drop e rhs "&&" ast-mset boa ]] + | OrExpr:e "||=" Expr:rhs => [[ drop e rhs "||" ast-mset boa ]] | OrExpr:e => [[ drop e ]] -OrExpr = OrExpr:x "||" AndExpr:y => [[ drop x y "||" ]] +OrExpr = OrExpr:x "||" AndExpr:y => [[ drop x y "||" ast-binop boa ]] | AndExpr -AndExpr = AndExpr:x "&&" EqExpr:y => [[ drop x y "&&" ]] +AndExpr = AndExpr:x "&&" EqExpr:y => [[ drop x y "&&" ast-binop boa ]] | EqExpr -EqExpr = EqExpr:x "==" RelExpr:y => [[ drop x y "==" ]] - | EqExpr:x "!=" RelExpr:y => [[ drop x y "!=" ]] - | EqExpr:x "===" RelExpr:y => [[ drop x y "===" ]] - | EqExpr:x "!==" RelExpr:y => [[ drop x y "!==" ]] +EqExpr = EqExpr:x "==" RelExpr:y => [[ drop x y "==" ast-binop boa ]] + | EqExpr:x "!=" RelExpr:y => [[ drop x y "!=" ast-binop boa ]] + | EqExpr:x "===" RelExpr:y => [[ drop x y "===" ast-binop boa ]] + | EqExpr:x "!==" RelExpr:y => [[ drop x y "!==" ast-binop boa ]] | RelExpr -RelExpr = RelExpr:x ">" AddExpr:y => [[ drop x y ">" ]] - | RelExpr:x ">=" AddExpr:y => [[ drop x y ">=" ]] - | RelExpr:x "<" AddExpr:y => [[ drop x y "<" ]] - | RelExpr:x "<=" AddExpr:y => [[ drop x y "<=" ]] - | RelExpr:x "instanceof" AddExpr:y => [[ drop x y "instanceof" ]] +RelExpr = RelExpr:x ">" AddExpr:y => [[ drop x y ">" ast-binop boa ]] + | RelExpr:x ">=" AddExpr:y => [[ drop x y ">=" ast-binop boa ]] + | RelExpr:x "<" AddExpr:y => [[ drop x y "<" ast-binop boa ]] + | RelExpr:x "<=" AddExpr:y => [[ drop x y "<=" ast-binop boa ]] + | RelExpr:x "instanceof" AddExpr:y => [[ drop x y "instanceof" ast-binop boa ]] | AddExpr -AddExpr = AddExpr:x "+" MulExpr:y => [[ drop x y "+" ]] - | AddExpr:x "-" MulExpr:y => [[ drop x y "-" ]] +AddExpr = AddExpr:x "+" MulExpr:y => [[ drop x y "+" ast-binop boa ]] + | AddExpr:x "-" MulExpr:y => [[ drop x y "-" ast-binop boa ]] | MulExpr -MulExpr = MulExpr:x "*" MulExpr:y => [[ drop x y "*" ]] - | MulExpr:x "/" MulExpr:y => [[ drop x y "/" ]] - | MulExpr:x "%" MulExpr:y => [[ drop x y "%" ]] +MulExpr = MulExpr:x "*" MulExpr:y => [[ drop x y "*" ast-binop boa ]] + | MulExpr:x "/" MulExpr:y => [[ drop x y "/" ast-binop boa ]] + | MulExpr:x "%" MulExpr:y => [[ drop x y "%" ast-binop boa ]] | Unary -Unary = "-" Postfix:p => [[ drop p "-" ]] +Unary = "-" Postfix:p => [[ drop p "-" ast-unop boa ]] | "+" Postfix:p => [[ drop p ]] - | "++" Postfix:p => [[ drop p "++" ]] - | "--" Postfix:p => [[ drop p "--" ]] - | "!" Postfix:p => [[ drop p "!" ]] + | "++" Postfix:p => [[ drop p "++" ast-preop boa ]] + | "--" Postfix:p => [[ drop p "--" ast-preop boa ]] + | "!" Postfix:p => [[ drop p "!" ast-unop boa ]] | Postfix -Postfix = PrimExpr:p SpacesNoNl "++" => [[ drop p "++" ]] - | PrimExpr:p SpacesNoNl "--" => [[ drop p "--" ]] +Postfix = PrimExpr:p SpacesNoNl "++" => [[ drop p "++" ast-postop boa ]] + | PrimExpr:p SpacesNoNl "--" => [[ drop p "--" ast-postop boa ]] | PrimExpr Args = Expr ("," Expr)* => [[ first2 swap prefix ]] -PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ drop i p ]] - | PrimExpr:p "." Name:m "(" Args:as ")" => [[ drop m p as ]] - | PrimExpr:p "." Name:f => [[ drop f p ]] - | PrimExpr:p "(" Args:as ")" => [[ drop p as ]] +PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ drop i p ast-getp boa ]] + | PrimExpr:p "." Name:m "(" Args:as ")" => [[ drop m p as ast-send boa ]] + | PrimExpr:p "." Name:f => [[ drop f p ast-getp boa ]] + | PrimExpr:p "(" Args:as ")" => [[ drop p as ast-call boa ]] | PrimExprHd PrimExprHd = "(" Expr:e ")" => [[ drop e ]] - | "this" => [[ drop ]] - | Name => [[ ]] - | Number => [[ ]] - | Str => [[ ]] + | "this" => [[ drop ast-this boa ]] + | Name => [[ ast-get boa ]] + | Number => [[ ast-number boa ]] + | Str => [[ ast-string boa ]] | "function" FuncRest:fr => [[ drop fr ]] - | "new" Name:n "(" Args:as ")" => [[ drop n as ]] - | "[" Args:es "]" => [[ drop es ]] + | "new" Name:n "(" Args:as ")" => [[ drop n as ast-new boa ]] + | "[" Args:es "]" => [[ drop es ast-array boa ]] | Json JsonBindings = JsonBinding ("," JsonBinding)* => [[ first2 swap prefix ]] -Json = "{" JsonBindings:bs "}" => [[ drop bs ]] -JsonBinding = JsonPropName:n ":" Expr:v => [[ drop n v ]] +Json = "{" JsonBindings:bs "}" => [[ drop bs ast-json boa ]] +JsonBinding = JsonPropName:n ":" Expr:v => [[ drop n v ast-binding boa ]] JsonPropName = Name | Number | Str Formal = Spaces Name Formals = Formal ("," Formal)* => [[ first2 swap prefix ]] -FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ drop fs body ]] +FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ drop fs body ast-func boa ]] Sc = SpacesNoNl ("\n" | "}")| ";" -Binding = Name:n "=" Expr:v => [[ drop n v ]] - | Name:n => [[ drop n "undefined" ]] +Binding = Name:n "=" Expr:v => [[ drop n v ast-var boa ]] + | Name:n => [[ drop n "undefined" ast-get boa ast-var boa ]] Block = "{" SrcElems:ss "}" => [[ drop ss ]] Bindings = Binding ("," Binding)* => [[ first2 swap prefix ]] For1 = "var" Binding => [[ second ]] | Expr - | Spaces => [[ "undefined" ]] + | Spaces => [[ "undefined" ast-get boa ]] For2 = Expr - | Spaces => [[ "true" ]] + | Spaces => [[ "true" ast-get boa ]] For3 = Expr - | Spaces => [[ "undefined" ]] -ForIn1 = "var" Name:n => [[ drop n "undefined" ]] + | Spaces => [[ "undefined" ast-get boa ]] +ForIn1 = "var" Name:n => [[ drop n "undefined" ast-get boa ast-var boa ]] | Expr -Switch1 = "case" Expr:c ":" SrcElems:cs => [[ drop c cs ]] - | "default" ":" SrcElems:cs => [[ drop cs ]] +Switch1 = "case" Expr:c ":" SrcElems:cs => [[ drop c cs ast-case boa ]] + | "default" ":" SrcElems:cs => [[ drop cs ast-default boa ]] SwitchBody = (Switch1)* Finally = "finally" Block:b => [[ drop b ]] - | Spaces => [[ drop "undefined" ]] + | Spaces => [[ drop "undefined" ast-get boa ]] Stmt = Block - | "var" Bindings:bs Sc => [[ drop bs ]] - | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ drop c t f ]] - | "if" "(" Expr:c ")" Stmt:t => [[ drop c t "undefined" ]] - | "while" "(" Expr:c ")" Stmt:s => [[ drop c s ]] - | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ drop s c ]] - | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ drop i c u s ]] - | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ drop v e s ]] - | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ drop e cs ]] - | "break" Sc => [[ drop ]] - | "continue" Sc => [[ drop ]] - | "throw" SpacesNoNl Expr:e Sc => [[ drop e ]] - | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ drop t e c f ]] - | "return" Expr:e Sc => [[ drop e ]] - | "return" Sc => [[ drop "undefined" ]] + | "var" Bindings:bs Sc => [[ drop bs ast-begin boa ]] + | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ drop c t f ast-if boa ]] + | "if" "(" Expr:c ")" Stmt:t => [[ drop c t "undefined" ast-get boa ast-if boa ]] + | "while" "(" Expr:c ")" Stmt:s => [[ drop c s ast-while boa ]] + | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ drop s c ast-do-while boa ]] + | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ drop i c u s ast-for boa ]] + | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ drop v e s ast-for-in boa ]] + | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ drop e cs ast-switch boa ]] + | "break" Sc => [[ drop ast-break boa ]] + | "continue" Sc => [[ drop ast-continue boa ]] + | "throw" SpacesNoNl Expr:e Sc => [[ drop e ast-throw boa ]] + | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ drop t e c f ast-try boa ]] + | "return" Expr:e Sc => [[ drop e ast-return boa ]] + | "return" Sc => [[ drop "undefined" ast-get boa ast-return boa ]] | Expr:e Sc => [[ drop e ]] - | ";" => [[ drop "undefined" ]] -SrcElem = "function" Name:n FuncRest:f => [[ drop n f ]] + | ";" => [[ drop "undefined" ast-get boa ]] +SrcElem = "function" Name:n FuncRest:f => [[ drop n f ast-var boa ]] | Stmt -SrcElems = (SrcElem)* => [[ ]] +SrcElems = (SrcElem)* => [[ ast-begin boa ]] TopLevel = SrcElems Spaces ;EBNF \ No newline at end of file From 55216a990dc5eaf37dee3345426454876994e70a Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 22:47:05 +1200 Subject: [PATCH 0276/1850] Remove drop from actions --- extra/peg/javascript/javascript.factor | 164 ++++++++++++------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 5c76c45f4c..54b9d8aa0a 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -50,10 +50,10 @@ EBNF: javascript Letter = [a-zA-Z] Digit = [0-9] Digits = (Digit)+ -SingleLineComment = "//" (!("\n") .)* "\n" => [[ drop ignore ]] -MultiLineComment = "/*" (!("*/") .)* "*/" => [[ drop ignore ]] +SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] +MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] Space = " " | "\t" | "\n" | SingleLineComment | MultiLineComment -Spaces = (Space)* => [[ drop ignore ]] +Spaces = (Space)* => [[ ignore ]] NameFirst = Letter | "$" | "_" NameRest = NameFirst | Digit iName = NameFirst (NameRest)* => [[ first2 swap prefix >string ]] @@ -82,19 +82,19 @@ Keyword = ("break" | "void" | "while" | "with") => [[ ast-keyword boa ]] -Name = !(Keyword) (iName):n => [[ drop n ast-name boa ]] -Number = Digits:ws '.' Digits:fs => [[ drop ws "." fs 3array concat >string string>number ast-number boa ]] +Name = !(Keyword) (iName):n => [[ n ast-name boa ]] +Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] | Digits => [[ >string string>number ast-number boa ]] -EscapeChar = "\\n" => [[ drop 10 ]] - | "\\r" => [[ drop 13 ]] - | "\\t" => [[ drop 9 ]] +EscapeChar = "\\n" => [[ 10 ]] + | "\\r" => [[ 13 ]] + | "\\t" => [[ 9 ]] StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] -Str = '"""' StringChars1:cs '"""' => [[ drop cs ast-string boa ]] - | '"' StringChars2:cs '"' => [[ drop cs ast-string boa ]] - | "'" StringChars3:cs "'" => [[ drop cs ast-string boa ]] +Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] + | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] + | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" @@ -102,76 +102,76 @@ Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | " | "&&" | "||=" | "||" | "." | "!" Tok = Spaces (Name | Keyword | Number | Str | Special ) Toks = (Tok)* Spaces -SpacesNoNl = (!("\n") Space)* => [[ drop ignore ]] +SpacesNoNl = (!("\n") Space)* => [[ ignore ]] -Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ drop e t f ast-cond-expr boa ]] - | OrExpr:e "=" Expr:rhs => [[ drop e rhs ast-set boa ]] - | OrExpr:e "+=" Expr:rhs => [[ drop e rhs "+" ast-mset boa ]] - | OrExpr:e "-=" Expr:rhs => [[ drop e rhs "-" ast-mset boa ]] - | OrExpr:e "*=" Expr:rhs => [[ drop e rhs "*" ast-mset boa ]] - | OrExpr:e "/=" Expr:rhs => [[ drop e rhs "/" ast-mset boa ]] - | OrExpr:e "%=" Expr:rhs => [[ drop e rhs "%" ast-mset boa ]] - | OrExpr:e "&&=" Expr:rhs => [[ drop e rhs "&&" ast-mset boa ]] - | OrExpr:e "||=" Expr:rhs => [[ drop e rhs "||" ast-mset boa ]] - | OrExpr:e => [[ drop e ]] +Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-expr boa ]] + | OrExpr:e "=" Expr:rhs => [[ e rhs ast-set boa ]] + | OrExpr:e "+=" Expr:rhs => [[ e rhs "+" ast-mset boa ]] + | OrExpr:e "-=" Expr:rhs => [[ e rhs "-" ast-mset boa ]] + | OrExpr:e "*=" Expr:rhs => [[ e rhs "*" ast-mset boa ]] + | OrExpr:e "/=" Expr:rhs => [[ e rhs "/" ast-mset boa ]] + | OrExpr:e "%=" Expr:rhs => [[ e rhs "%" ast-mset boa ]] + | OrExpr:e "&&=" Expr:rhs => [[ e rhs "&&" ast-mset boa ]] + | OrExpr:e "||=" Expr:rhs => [[ e rhs "||" ast-mset boa ]] + | OrExpr:e => [[ e ]] -OrExpr = OrExpr:x "||" AndExpr:y => [[ drop x y "||" ast-binop boa ]] +OrExpr = OrExpr:x "||" AndExpr:y => [[ x y "||" ast-binop boa ]] | AndExpr -AndExpr = AndExpr:x "&&" EqExpr:y => [[ drop x y "&&" ast-binop boa ]] +AndExpr = AndExpr:x "&&" EqExpr:y => [[ x y "&&" ast-binop boa ]] | EqExpr -EqExpr = EqExpr:x "==" RelExpr:y => [[ drop x y "==" ast-binop boa ]] - | EqExpr:x "!=" RelExpr:y => [[ drop x y "!=" ast-binop boa ]] - | EqExpr:x "===" RelExpr:y => [[ drop x y "===" ast-binop boa ]] - | EqExpr:x "!==" RelExpr:y => [[ drop x y "!==" ast-binop boa ]] +EqExpr = EqExpr:x "==" RelExpr:y => [[ x y "==" ast-binop boa ]] + | EqExpr:x "!=" RelExpr:y => [[ x y "!=" ast-binop boa ]] + | EqExpr:x "===" RelExpr:y => [[ x y "===" ast-binop boa ]] + | EqExpr:x "!==" RelExpr:y => [[ x y "!==" ast-binop boa ]] | RelExpr -RelExpr = RelExpr:x ">" AddExpr:y => [[ drop x y ">" ast-binop boa ]] - | RelExpr:x ">=" AddExpr:y => [[ drop x y ">=" ast-binop boa ]] - | RelExpr:x "<" AddExpr:y => [[ drop x y "<" ast-binop boa ]] - | RelExpr:x "<=" AddExpr:y => [[ drop x y "<=" ast-binop boa ]] - | RelExpr:x "instanceof" AddExpr:y => [[ drop x y "instanceof" ast-binop boa ]] +RelExpr = RelExpr:x ">" AddExpr:y => [[ x y ">" ast-binop boa ]] + | RelExpr:x ">=" AddExpr:y => [[ x y ">=" ast-binop boa ]] + | RelExpr:x "<" AddExpr:y => [[ x y "<" ast-binop boa ]] + | RelExpr:x "<=" AddExpr:y => [[ x y "<=" ast-binop boa ]] + | RelExpr:x "instanceof" AddExpr:y => [[ x y "instanceof" ast-binop boa ]] | AddExpr -AddExpr = AddExpr:x "+" MulExpr:y => [[ drop x y "+" ast-binop boa ]] - | AddExpr:x "-" MulExpr:y => [[ drop x y "-" ast-binop boa ]] +AddExpr = AddExpr:x "+" MulExpr:y => [[ x y "+" ast-binop boa ]] + | AddExpr:x "-" MulExpr:y => [[ x y "-" ast-binop boa ]] | MulExpr -MulExpr = MulExpr:x "*" MulExpr:y => [[ drop x y "*" ast-binop boa ]] - | MulExpr:x "/" MulExpr:y => [[ drop x y "/" ast-binop boa ]] - | MulExpr:x "%" MulExpr:y => [[ drop x y "%" ast-binop boa ]] +MulExpr = MulExpr:x "*" MulExpr:y => [[ x y "*" ast-binop boa ]] + | MulExpr:x "/" MulExpr:y => [[ x y "/" ast-binop boa ]] + | MulExpr:x "%" MulExpr:y => [[ x y "%" ast-binop boa ]] | Unary -Unary = "-" Postfix:p => [[ drop p "-" ast-unop boa ]] - | "+" Postfix:p => [[ drop p ]] - | "++" Postfix:p => [[ drop p "++" ast-preop boa ]] - | "--" Postfix:p => [[ drop p "--" ast-preop boa ]] - | "!" Postfix:p => [[ drop p "!" ast-unop boa ]] +Unary = "-" Postfix:p => [[ p "-" ast-unop boa ]] + | "+" Postfix:p => [[ p ]] + | "++" Postfix:p => [[ p "++" ast-preop boa ]] + | "--" Postfix:p => [[ p "--" ast-preop boa ]] + | "!" Postfix:p => [[ p "!" ast-unop boa ]] | Postfix -Postfix = PrimExpr:p SpacesNoNl "++" => [[ drop p "++" ast-postop boa ]] - | PrimExpr:p SpacesNoNl "--" => [[ drop p "--" ast-postop boa ]] +Postfix = PrimExpr:p SpacesNoNl "++" => [[ p "++" ast-postop boa ]] + | PrimExpr:p SpacesNoNl "--" => [[ p "--" ast-postop boa ]] | PrimExpr Args = Expr ("," Expr)* => [[ first2 swap prefix ]] -PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ drop i p ast-getp boa ]] - | PrimExpr:p "." Name:m "(" Args:as ")" => [[ drop m p as ast-send boa ]] - | PrimExpr:p "." Name:f => [[ drop f p ast-getp boa ]] - | PrimExpr:p "(" Args:as ")" => [[ drop p as ast-call boa ]] +PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ i p ast-getp boa ]] + | PrimExpr:p "." Name:m "(" Args:as ")" => [[ m p as ast-send boa ]] + | PrimExpr:p "." Name:f => [[ f p ast-getp boa ]] + | PrimExpr:p "(" Args:as ")" => [[ p as ast-call boa ]] | PrimExprHd -PrimExprHd = "(" Expr:e ")" => [[ drop e ]] - | "this" => [[ drop ast-this boa ]] +PrimExprHd = "(" Expr:e ")" => [[ e ]] + | "this" => [[ ast-this boa ]] | Name => [[ ast-get boa ]] | Number => [[ ast-number boa ]] | Str => [[ ast-string boa ]] - | "function" FuncRest:fr => [[ drop fr ]] - | "new" Name:n "(" Args:as ")" => [[ drop n as ast-new boa ]] - | "[" Args:es "]" => [[ drop es ast-array boa ]] + | "function" FuncRest:fr => [[ fr ]] + | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] + | "[" Args:es "]" => [[ es ast-array boa ]] | Json JsonBindings = JsonBinding ("," JsonBinding)* => [[ first2 swap prefix ]] -Json = "{" JsonBindings:bs "}" => [[ drop bs ast-json boa ]] -JsonBinding = JsonPropName:n ":" Expr:v => [[ drop n v ast-binding boa ]] +Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] +JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] JsonPropName = Name | Number | Str Formal = Spaces Name Formals = Formal ("," Formal)* => [[ first2 swap prefix ]] -FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ drop fs body ast-func boa ]] +FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] Sc = SpacesNoNl ("\n" | "}")| ";" -Binding = Name:n "=" Expr:v => [[ drop n v ast-var boa ]] - | Name:n => [[ drop n "undefined" ast-get boa ast-var boa ]] -Block = "{" SrcElems:ss "}" => [[ drop ss ]] +Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] + | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] +Block = "{" SrcElems:ss "}" => [[ ss ]] Bindings = Binding ("," Binding)* => [[ first2 swap prefix ]] For1 = "var" Binding => [[ second ]] | Expr @@ -180,31 +180,31 @@ For2 = Expr | Spaces => [[ "true" ast-get boa ]] For3 = Expr | Spaces => [[ "undefined" ast-get boa ]] -ForIn1 = "var" Name:n => [[ drop n "undefined" ast-get boa ast-var boa ]] +ForIn1 = "var" Name:n => [[ n "undefined" ast-get boa ast-var boa ]] | Expr -Switch1 = "case" Expr:c ":" SrcElems:cs => [[ drop c cs ast-case boa ]] - | "default" ":" SrcElems:cs => [[ drop cs ast-default boa ]] +Switch1 = "case" Expr:c ":" SrcElems:cs => [[ c cs ast-case boa ]] + | "default" ":" SrcElems:cs => [[ cs ast-default boa ]] SwitchBody = (Switch1)* -Finally = "finally" Block:b => [[ drop b ]] - | Spaces => [[ drop "undefined" ast-get boa ]] +Finally = "finally" Block:b => [[ b ]] + | Spaces => [[ "undefined" ast-get boa ]] Stmt = Block - | "var" Bindings:bs Sc => [[ drop bs ast-begin boa ]] - | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ drop c t f ast-if boa ]] - | "if" "(" Expr:c ")" Stmt:t => [[ drop c t "undefined" ast-get boa ast-if boa ]] - | "while" "(" Expr:c ")" Stmt:s => [[ drop c s ast-while boa ]] - | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ drop s c ast-do-while boa ]] - | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ drop i c u s ast-for boa ]] - | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ drop v e s ast-for-in boa ]] - | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ drop e cs ast-switch boa ]] - | "break" Sc => [[ drop ast-break boa ]] - | "continue" Sc => [[ drop ast-continue boa ]] - | "throw" SpacesNoNl Expr:e Sc => [[ drop e ast-throw boa ]] - | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ drop t e c f ast-try boa ]] - | "return" Expr:e Sc => [[ drop e ast-return boa ]] - | "return" Sc => [[ drop "undefined" ast-get boa ast-return boa ]] - | Expr:e Sc => [[ drop e ]] - | ";" => [[ drop "undefined" ast-get boa ]] -SrcElem = "function" Name:n FuncRest:f => [[ drop n f ast-var boa ]] + | "var" Bindings:bs Sc => [[ bs ast-begin boa ]] + | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ c t f ast-if boa ]] + | "if" "(" Expr:c ")" Stmt:t => [[ c t "undefined" ast-get boa ast-if boa ]] + | "while" "(" Expr:c ")" Stmt:s => [[ c s ast-while boa ]] + | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ s c ast-do-while boa ]] + | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ i c u s ast-for boa ]] + | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ v e s ast-for-in boa ]] + | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ e cs ast-switch boa ]] + | "break" Sc => [[ ast-break boa ]] + | "continue" Sc => [[ ast-continue boa ]] + | "throw" SpacesNoNl Expr:e Sc => [[ e ast-throw boa ]] + | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ t e c f ast-try boa ]] + | "return" Expr:e Sc => [[ e ast-return boa ]] + | "return" Sc => [[ "undefined" ast-get boa ast-return boa ]] + | Expr:e Sc => [[ e ]] + | ";" => [[ "undefined" ast-get boa ]] +SrcElem = "function" Name:n FuncRest:f => [[ n f ast-var boa ]] | Stmt SrcElems = (SrcElem)* => [[ ast-begin boa ]] TopLevel = SrcElems Spaces From 258951d954343a8e9289425ca9c1180ba285023c Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 22:59:13 +1200 Subject: [PATCH 0277/1850] Split out javascript tokenizer --- extra/peg/javascript/javascript.factor | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 54b9d8aa0a..3db962420a 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -46,6 +46,64 @@ TUPLE: ast-return e ; TUPLE: ast-case c cs ; TUPLE: ast-default cs ; +EBNF: tokenizer +Letter = [a-zA-Z] +Digit = [0-9] +Digits = (Digit)+ +SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] +MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] +Space = " " | "\t" | "\n" | SingleLineComment | MultiLineComment +Spaces = (Space)* => [[ ignore ]] +NameFirst = Letter | "$" | "_" +NameRest = NameFirst | Digit +iName = NameFirst (NameRest)* => [[ first2 swap prefix >string ]] +Keyword = ("break" + | "case" + | "catch" + | "continue" + | "default" + | "delete" + | "do" + | "else" + | "finally" + | "for" + | "function" + | "if" + | "in" + | "instanceof" + | "new" + | "return" + | "switch" + | "this" + | "throw" + | "try" + | "typeof" + | "var" + | "void" + | "while" + | "with") => [[ ast-keyword boa ]] +Name = !(Keyword) (iName):n => [[ n ast-name boa ]] +Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] + | Digits => [[ >string string>number ast-number boa ]] + +EscapeChar = "\\n" => [[ 10 ]] + | "\\r" => [[ 13 ]] + | "\\t" => [[ 9 ]] +StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] +StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] +StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] +Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] + | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] + | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] +Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" + | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" + | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" + | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" + | "&&" | "||=" | "||" | "." | "!" +Tok = Spaces (Name | Keyword | Number | Str | Special ) +Toks = (Tok)* Spaces +;EBNF + EBNF: javascript Letter = [a-zA-Z] Digit = [0-9] From 4050ebcbde098f0b09a34a2123a12dbdc78d134c Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 23:42:28 +1200 Subject: [PATCH 0278/1850] Javascript parser now works on token sequence --- extra/peg/ebnf/ebnf.factor | 2 +- extra/peg/javascript/javascript.factor | 66 ++++---------------------- 2 files changed, 9 insertions(+), 59 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 215eabdd37..36b3742b64 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -410,7 +410,7 @@ M: ebnf-var (transform) ( ast -- parser ) parser>> (transform) ; M: ebnf-terminal (transform) ( ast -- parser ) - symbol>> token ; + symbol>> [ token ] keep [ = ] curry satisfy 2choice ; M: ebnf-foreign (transform) ( ast -- parser ) dup word>> search diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 3db962420a..c9bef2f6d3 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2007 Chris Double. ! See http://factorcode.org/license.txt for BSD license. USING: kernel arrays strings math.parser sequences sequences.deep -peg peg.ebnf peg.parsers memoize namespaces math ; +peg peg.ebnf peg.parsers memoize namespaces math accessors ; IN: peg.javascript #! Grammar for JavaScript. Based on OMeta-JS example from: @@ -81,7 +81,7 @@ Keyword = ("break" | "var" | "void" | "while" - | "with") => [[ ast-keyword boa ]] + | "with") Name = !(Keyword) (iName):n => [[ n ast-name boa ]] Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] | Digits => [[ >string string>number ast-number boa ]] @@ -105,61 +105,11 @@ Toks = (Tok)* Spaces ;EBNF EBNF: javascript -Letter = [a-zA-Z] -Digit = [0-9] -Digits = (Digit)+ -SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] -MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] -Space = " " | "\t" | "\n" | SingleLineComment | MultiLineComment +Space = " " | "\t" | "\n" Spaces = (Space)* => [[ ignore ]] -NameFirst = Letter | "$" | "_" -NameRest = NameFirst | Digit -iName = NameFirst (NameRest)* => [[ first2 swap prefix >string ]] -Keyword = ("break" - | "case" - | "catch" - | "continue" - | "default" - | "delete" - | "do" - | "else" - | "finally" - | "for" - | "function" - | "if" - | "in" - | "instanceof" - | "new" - | "return" - | "switch" - | "this" - | "throw" - | "try" - | "typeof" - | "var" - | "void" - | "while" - | "with") => [[ ast-keyword boa ]] -Name = !(Keyword) (iName):n => [[ n ast-name boa ]] -Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] - | Digits => [[ >string string>number ast-number boa ]] - -EscapeChar = "\\n" => [[ 10 ]] - | "\\r" => [[ 13 ]] - | "\\t" => [[ 9 ]] -StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] -StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] -StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] -Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] - | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] - | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] -Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" - | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" - | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" - | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" - | "&&" | "||=" | "||" | "." | "!" -Tok = Spaces (Name | Keyword | Number | Str | Special ) -Toks = (Tok)* Spaces +Name = . ?[ ast-name? ]? => [[ value>> ]] +Number = . ?[ ast-number? ]? => [[ value>> ]] +String = . ?[ ast-string? ]? => [[ value>> ]] SpacesNoNl = (!("\n") Space)* => [[ ignore ]] Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-expr boa ]] @@ -214,7 +164,7 @@ PrimExprHd = "(" Expr:e ")" => [[ e ]] | "this" => [[ ast-this boa ]] | Name => [[ ast-get boa ]] | Number => [[ ast-number boa ]] - | Str => [[ ast-string boa ]] + | String => [[ ast-string boa ]] | "function" FuncRest:fr => [[ fr ]] | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] | "[" Args:es "]" => [[ es ast-array boa ]] @@ -222,7 +172,7 @@ PrimExprHd = "(" Expr:e ")" => [[ e ]] JsonBindings = JsonBinding ("," JsonBinding)* => [[ first2 swap prefix ]] Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] -JsonPropName = Name | Number | Str +JsonPropName = Name | Number | String Formal = Spaces Name Formals = Formal ("," Formal)* => [[ first2 swap prefix ]] FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] From e99ff9fa6b996ba1fcf6199cfe5979bcfe221757 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 17 Jun 2008 23:57:51 +1200 Subject: [PATCH 0279/1850] Fix list AST in javascript parser --- extra/peg/javascript/javascript.factor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index c9bef2f6d3..c4d87e3ce5 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -154,7 +154,7 @@ Unary = "-" Postfix:p => [[ p "-" ast-unop boa Postfix = PrimExpr:p SpacesNoNl "++" => [[ p "++" ast-postop boa ]] | PrimExpr:p SpacesNoNl "--" => [[ p "--" ast-postop boa ]] | PrimExpr -Args = Expr ("," Expr)* => [[ first2 swap prefix ]] +Args = Expr ("," Expr => [[ second ]])* => [[ first2 swap prefix ]] PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ i p ast-getp boa ]] | PrimExpr:p "." Name:m "(" Args:as ")" => [[ m p as ast-send boa ]] | PrimExpr:p "." Name:f => [[ f p ast-getp boa ]] @@ -169,18 +169,18 @@ PrimExprHd = "(" Expr:e ")" => [[ e ]] | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] | "[" Args:es "]" => [[ es ast-array boa ]] | Json -JsonBindings = JsonBinding ("," JsonBinding)* => [[ first2 swap prefix ]] +JsonBindings = JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]] Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] JsonPropName = Name | Number | String Formal = Spaces Name -Formals = Formal ("," Formal)* => [[ first2 swap prefix ]] +Formals = Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]] FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] Sc = SpacesNoNl ("\n" | "}")| ";" Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] Block = "{" SrcElems:ss "}" => [[ ss ]] -Bindings = Binding ("," Binding)* => [[ first2 swap prefix ]] +Bindings = Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]] For1 = "var" Binding => [[ second ]] | Expr | Spaces => [[ "undefined" ast-get boa ]] From 7694dfd68827394d5df1e61bcc0a3acba7db9e0c Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 00:10:14 +1200 Subject: [PATCH 0280/1850] Allow zero arguments in javascript list handling --- extra/peg/javascript/javascript.factor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index c4d87e3ce5..5368881377 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -154,7 +154,7 @@ Unary = "-" Postfix:p => [[ p "-" ast-unop boa Postfix = PrimExpr:p SpacesNoNl "++" => [[ p "++" ast-postop boa ]] | PrimExpr:p SpacesNoNl "--" => [[ p "--" ast-postop boa ]] | PrimExpr -Args = Expr ("," Expr => [[ second ]])* => [[ first2 swap prefix ]] +Args = (Expr ("," Expr => [[ second ]])* => [[ first2 swap prefix ]])? PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ i p ast-getp boa ]] | PrimExpr:p "." Name:m "(" Args:as ")" => [[ m p as ast-send boa ]] | PrimExpr:p "." Name:f => [[ f p ast-getp boa ]] @@ -169,18 +169,18 @@ PrimExprHd = "(" Expr:e ")" => [[ e ]] | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] | "[" Args:es "]" => [[ es ast-array boa ]] | Json -JsonBindings = JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]] +JsonBindings = (JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]])? Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] JsonPropName = Name | Number | String Formal = Spaces Name -Formals = Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]] +Formals = (Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]])? FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] Sc = SpacesNoNl ("\n" | "}")| ";" Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] Block = "{" SrcElems:ss "}" => [[ ss ]] -Bindings = Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]] +Bindings = (Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]])? For1 = "var" Binding => [[ second ]] | Expr | Spaces => [[ "undefined" ast-get boa ]] From 778573106c10aeddf03ed7384ea6270f3ea07123 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 12:16:47 +1200 Subject: [PATCH 0281/1850] Fix Sc rule --- extra/peg/javascript/javascript.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 5368881377..bdf5f4b369 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -176,7 +176,7 @@ JsonPropName = Name | Number | String Formal = Spaces Name Formals = (Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]])? FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] -Sc = SpacesNoNl ("\n" | "}")| ";" +Sc = SpacesNoNl ("\n" | &("}"))| ";" Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] Block = "{" SrcElems:ss "}" => [[ ss ]] From 4e1e14566943ec4574a498f54dd359bbe123826f Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 03:40:05 -0500 Subject: [PATCH 0282/1850] Tweaking config some more --- .../concatenative/concatenative.factor | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor index a4f826d7f6..6d65f10783 100644 --- a/extra/websites/concatenative/concatenative.factor +++ b/extra/websites/concatenative/concatenative.factor @@ -63,19 +63,33 @@ TUPLE: factor-website < dispatcher ; { factor-website "page" } >>template test-db ; -: init-factor-website ( -- ) - "factorcode.org" 25 smtp-server set-global +SYMBOL: key-password +SYMBOL: key-file +SYMBOL: dh-file + +: common-configuration ( -- ) + "concatenative.org" 25 smtp-server set-global "noreply@concatenative.org" lost-password-from set-global "website@concatenative.org" insomniac-sender set-global "slava@factorcode.org" insomniac-recipients set-global - init-factor-db - main-responder set-global ; + main-responder set-global + init-factor-db ; + +: init-testing ( -- ) + "resource:extra/openssl/test/dh1024.pem" dh-file set-global + "resource:extra/openssl/test/server.pem" key-file set-global + "password" key-password set-global + common-configuration ; + +: init-production ( -- ) + "/home/slava/cert/host.pem" key-file set-global + common-configuration ; : ( -- config ) - "resource:extra/openssl/test/server.pem" >>key-file - "resource:extra/openssl/test/dh1024.pem" >>dh-file - "password" >>password ; + key-file get >>key-file + dh-file get >>dh-file + key-password get >>password ; : ( -- threaded-server ) @@ -83,7 +97,7 @@ TUPLE: factor-website < dispatcher ; 8080 >>insecure 8431 >>secure ; -: start-factor-website ( -- ) +: start-website ( -- ) test-db start-expiring test-db start-update-task http-insomniac From ebb3423e4a5138c4d4985fd080278b298613a4b9 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 03:53:16 -0500 Subject: [PATCH 0283/1850] Fix assocs.lib tests --- extra/assocs/lib/lib-tests.factor | 4 ++++ extra/assocs/lib/lib.factor | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 extra/assocs/lib/lib-tests.factor diff --git a/extra/assocs/lib/lib-tests.factor b/extra/assocs/lib/lib-tests.factor new file mode 100644 index 0000000000..0bf8270088 --- /dev/null +++ b/extra/assocs/lib/lib-tests.factor @@ -0,0 +1,4 @@ +IN: assocs.lib.tests +USING: assocs.lib tools.test vectors ; + +{ 1 1 } [ [ ?push ] histogram ] must-infer-as diff --git a/extra/assocs/lib/lib.factor b/extra/assocs/lib/lib.factor index 1c89c1eb16..14632df771 100755 --- a/extra/assocs/lib/lib.factor +++ b/extra/assocs/lib/lib.factor @@ -41,4 +41,4 @@ IN: assocs.lib : histogram ( assoc quot -- assoc' ) H{ } clone [ swap [ change-at ] 2curry assoc-each - ] keep ; + ] keep ; inline From a5719e33976ae6ebfc75ab81edd6d56dd0f0ee0a Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 21:30:21 +1200 Subject: [PATCH 0284/1850] Add javascript tests. Minor changes to javascript grammar --- extra/peg/javascript/javascript-tests.factor | 42 ++++++++++++++++++++ extra/peg/javascript/javascript.factor | 16 ++++---- 2 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 extra/peg/javascript/javascript-tests.factor diff --git a/extra/peg/javascript/javascript-tests.factor b/extra/peg/javascript/javascript-tests.factor new file mode 100644 index 0000000000..70410a3838 --- /dev/null +++ b/extra/peg/javascript/javascript-tests.factor @@ -0,0 +1,42 @@ +! Copyright (C) 2008 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +! +USING: kernel tools.test peg peg.javascript accessors ; +IN: peg.javascript.tests + +\ javascript must-infer + +{ + V{ + T{ ast-number f 123 } + ";" + T{ ast-string f "hello" } + ";" + T{ ast-name f "foo" } + "(" + T{ ast-name f "x" } + ")" + ";" + } +} [ + "123; 'hello'; foo(x);" tokenizer ast>> +] unit-test + +{ + T{ + ast-begin + f + V{ + T{ ast-number f 123 } + T{ ast-string f "hello" } + T{ + ast-call + f + T{ ast-get f "foo" } + V{ T{ ast-get f "x" } } + } + } + } +} [ + "123; 'hello'; foo(x);" tokenizer ast>> javascript ast>> +] unit-test \ No newline at end of file diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index bdf5f4b369..030d2f1728 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2007 Chris Double. +! Copyright (C) 2008 Chris Double. ! See http://factorcode.org/license.txt for BSD license. USING: kernel arrays strings math.parser sequences sequences.deep peg peg.ebnf peg.parsers memoize namespaces math accessors ; @@ -49,14 +49,14 @@ TUPLE: ast-default cs ; EBNF: tokenizer Letter = [a-zA-Z] Digit = [0-9] -Digits = (Digit)+ +Digits = Digit+ SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] Space = " " | "\t" | "\n" | SingleLineComment | MultiLineComment -Spaces = (Space)* => [[ ignore ]] +Spaces = Space* => [[ ignore ]] NameFirst = Letter | "$" | "_" NameRest = NameFirst | Digit -iName = NameFirst (NameRest)* => [[ first2 swap prefix >string ]] +iName = NameFirst NameRest* => [[ first2 swap prefix >string ]] Keyword = ("break" | "case" | "catch" @@ -101,12 +101,12 @@ Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | " | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" | "&&" | "||=" | "||" | "." | "!" Tok = Spaces (Name | Keyword | Number | Str | Special ) -Toks = (Tok)* Spaces +Toks = Tok* Spaces ;EBNF EBNF: javascript Space = " " | "\t" | "\n" -Spaces = (Space)* => [[ ignore ]] +Spaces = Space* => [[ ignore ]] Name = . ?[ ast-name? ]? => [[ value>> ]] Number = . ?[ ast-number? ]? => [[ value>> ]] String = . ?[ ast-string? ]? => [[ value>> ]] @@ -192,7 +192,7 @@ ForIn1 = "var" Name:n => [[ n "undefined" ast-get boa ast-var boa | Expr Switch1 = "case" Expr:c ":" SrcElems:cs => [[ c cs ast-case boa ]] | "default" ":" SrcElems:cs => [[ cs ast-default boa ]] -SwitchBody = (Switch1)* +SwitchBody = Switch1* Finally = "finally" Block:b => [[ b ]] | Spaces => [[ "undefined" ast-get boa ]] Stmt = Block @@ -214,6 +214,6 @@ Stmt = Block | ";" => [[ "undefined" ast-get boa ]] SrcElem = "function" Name:n FuncRest:f => [[ n f ast-var boa ]] | Stmt -SrcElems = (SrcElem)* => [[ ast-begin boa ]] +SrcElems = SrcElem* => [[ ast-begin boa ]] TopLevel = SrcElems Spaces ;EBNF \ No newline at end of file From 8f140402b3a6d94fc0e770b0c731e9ceb2f92c6c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 05:58:05 -0500 Subject: [PATCH 0285/1850] Move short to core --- core/sequences/sequences.factor | 2 ++ extra/sequences/lib/lib.factor | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/sequences/sequences.factor b/core/sequences/sequences.factor index 02a7191f0a..2d05d3c2ef 100755 --- a/core/sequences/sequences.factor +++ b/core/sequences/sequences.factor @@ -206,6 +206,8 @@ M: slice virtual@ [ slice-from + ] [ slice-seq ] bi ; M: slice length dup slice-to swap slice-from - ; +: short ( seq n -- seq n' ) over length min ; inline + : head-slice ( seq n -- slice ) (head) ; : tail-slice ( seq n -- slice ) (tail) ; diff --git a/extra/sequences/lib/lib.factor b/extra/sequences/lib/lib.factor index 56488818ab..3ac60c2ae3 100755 --- a/extra/sequences/lib/lib.factor +++ b/extra/sequences/lib/lib.factor @@ -234,9 +234,6 @@ PRIVATE> : remove-nth ( seq n -- seq' ) cut-slice rest-slice append ; -: short ( seq n -- seq n' ) - over length min ; inline - : if-seq ( seq quot1 quot2 -- ) [ f like ] 2dip if* ; inline From 03730f30387564b70686a85a800b25b4a089b6c3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 05:58:16 -0500 Subject: [PATCH 0286/1850] Fix see of M:: --- extra/locals/locals-tests.factor | 13 ++++++++++++- extra/locals/locals.factor | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/extra/locals/locals-tests.factor b/extra/locals/locals-tests.factor index 4e670cdac0..025e175bc2 100755 --- a/extra/locals/locals-tests.factor +++ b/extra/locals/locals-tests.factor @@ -1,6 +1,6 @@ USING: locals math sequences tools.test hashtables words kernel namespaces arrays strings prettyprint io.streams.string parser -accessors ; +accessors generic ; IN: locals.tests :: foo ( a b -- a a ) a a ; @@ -265,3 +265,14 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ; [ \ a-word-with-locals see ] with-string-writer new-definition = ] unit-test + +: method-definition "USING: locals locals.tests sequences ;\nM:: sequence method-with-locals ( a -- y ) a reverse ;\n" ; + +GENERIC: method-with-locals ( x -- y ) + +M:: sequence method-with-locals ( a -- y ) a reverse ; + +[ t ] [ + [ \ sequence \ method-with-locals method see ] with-string-writer + method-definition = +] unit-test diff --git a/extra/locals/locals.factor b/extra/locals/locals.factor index 028502560f..cc6a7d093e 100755 --- a/extra/locals/locals.factor +++ b/extra/locals/locals.factor @@ -405,8 +405,8 @@ M: lambda-memoized reset-word M: lambda-method synopsis* dup dup dup definer. - "method-specializer" word-prop pprint* - "method-generic" word-prop pprint* + "method-class" word-prop pprint-word + "method-generic" word-prop pprint-word method-stack-effect effect>string comment. ; PRIVATE> From 42f421d9884fabe528eac295aab83d532b2601fc Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 05:58:26 -0500 Subject: [PATCH 0287/1850] Implement missing input stream protocol methods --- .../tools/interactor/interactor-tests.factor | 46 ++++++++++++++++++- extra/ui/tools/interactor/interactor.factor | 21 +++++++-- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/extra/ui/tools/interactor/interactor-tests.factor b/extra/ui/tools/interactor/interactor-tests.factor index f8d5e33df9..37f43faa8b 100755 --- a/extra/ui/tools/interactor/interactor-tests.factor +++ b/extra/ui/tools/interactor/interactor-tests.factor @@ -1,7 +1,7 @@ IN: ui.tools.interactor.tests USING: ui.tools.interactor ui.gadgets.panes namespaces ui.gadgets.editors concurrency.promises threads listener -tools.test kernel calendar parser accessors ; +tools.test kernel calendar parser accessors calendar io ; \ must-infer @@ -41,3 +41,47 @@ tools.test kernel calendar parser accessors ; [ ] [ 1000 sleep ] unit-test [ ] [ "interactor" get interactor-eof ] unit-test + +[ ] [ "interactor" set ] unit-test + +: text "Hello world.\nThis is a test." ; + +[ ] [ text "interactor" get set-editor-string ] unit-test + +[ ] [ "promise" set ] unit-test + +[ ] [ + [ + "interactor" get register-self + "interactor" get contents "promise" get fulfill + ] in-thread +] unit-test + +[ ] [ 100 sleep ] unit-test + +[ ] [ "interactor" get evaluate-input ] unit-test + +[ ] [ 100 sleep ] unit-test + +[ ] [ "interactor" get interactor-eof ] unit-test + +[ t ] [ "promise" get 2 seconds ?promise-timeout text = ] unit-test + +[ ] [ "interactor" set ] unit-test + +[ ] [ text "interactor" get set-editor-string ] unit-test + +[ ] [ "promise" set ] unit-test + +[ ] [ + [ + "interactor" get register-self + "interactor" get stream-read1 "promise" get fulfill + ] in-thread +] unit-test + +[ ] [ 100 sleep ] unit-test + +[ ] [ "interactor" get evaluate-input ] unit-test + +[ CHAR: H ] [ "promise" get 2 seconds ?promise-timeout ] unit-test diff --git a/extra/ui/tools/interactor/interactor.factor b/extra/ui/tools/interactor/interactor.factor index 400169908b..72bd4e43a3 100755 --- a/extra/ui/tools/interactor/interactor.factor +++ b/extra/ui/tools/interactor/interactor.factor @@ -6,7 +6,8 @@ models namespaces parser prettyprint quotations sequences strings threads listener classes.tuple ui.commands ui.gadgets ui.gadgets.editors ui.gadgets.presentations ui.gadgets.worlds ui.gestures definitions calendar concurrency.flags -concurrency.mailboxes ui.tools.workspace accessors sets ; +concurrency.mailboxes ui.tools.workspace accessors sets +destructors ; IN: ui.tools.interactor ! If waiting is t, we're waiting for user input, and invoking @@ -110,9 +111,11 @@ M: interactor model-changed } cleave ] [ drop f ] if ; +: interactor-read ( interactor -- lines ) + [ interactor-yield ] [ interactor-finish ] bi ; + M: interactor stream-readln - [ interactor-yield ] [ interactor-finish ] bi - dup [ first ] when ; + interactor-read dup [ first ] when ; : interactor-call ( quot interactor -- ) dup interactor-busy? [ @@ -124,12 +127,22 @@ M: interactor stream-read swap dup zero? [ 2drop "" ] [ - >r stream-readln dup length r> min head + >r interactor-read dup [ "\n" join ] when r> short head ] if ; M: interactor stream-read-partial stream-read ; +M: interactor stream-read1 + dup interactor-read { + { [ dup not ] [ 2drop f ] } + { [ dup empty? ] [ drop stream-read1 ] } + { [ dup first empty? ] [ 2drop CHAR: \n ] } + [ nip first first ] + } cond ; + +M: interactor dispose drop ; + : go-to-error ( interactor error -- ) [ line>> 1- ] [ column>> ] bi 2array over set-caret From fea65df1dfeb1f56bf40fb232aae99c430b2d731 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 23:07:26 +1200 Subject: [PATCH 0288/1850] Fix ebnf foreign call breakage and add tests --- extra/peg/ebnf/ebnf-tests.factor | 36 +++++++++++++++++++++++++++++++- extra/peg/ebnf/ebnf.factor | 6 +++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index 04cc01c9d0..73db626685 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. ! USING: kernel tools.test peg peg.ebnf words math math.parser - sequences accessors ; + sequences accessors peg.parsers ; IN: peg.ebnf.tests { T{ ebnf-non-terminal f "abc" } } [ @@ -397,4 +397,38 @@ main = Primary { t } [ "number=digit+:n 'a'" 'ebnf' parse remaining>> length zero? +] unit-test + +<< +EBNF: parser1 +foo='a' +;EBNF +>> + +EBNF: parser2 +foo= 'b' +;EBNF + +EBNF: parser3 +foo= 'c' +;EBNF + +EBNF: parser4 +foo= 'd' +;EBNF + +{ "a" } [ + "a" parser1 ast>> +] unit-test + +{ V{ "a" "b" } } [ + "ab" parser2 ast>> +] unit-test + +{ V{ "a" "c" } } [ + "ac" parser3 ast>> +] unit-test + +{ V{ CHAR: a "d" } } [ + "ad" parser4 ast>> ] unit-test \ No newline at end of file diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 36b3742b64..2ee0958051 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -415,11 +415,11 @@ M: ebnf-terminal (transform) ( ast -- parser ) M: ebnf-foreign (transform) ( ast -- parser ) dup word>> search [ "Foreign word " swap word>> append " not found" append throw ] unless* - swap rule>> dup [ - swap rule + swap rule>> [ main ] unless* dupd swap rule [ + nip ] [ execute - ] if ; + ] if* ; : parser-not-found ( name -- * ) [ From ea6974d5dac52706a67666a50ecaf22c915280eb Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 18 Jun 2008 23:50:25 +1200 Subject: [PATCH 0289/1850] Add \r to whitespace in javascript tokenizer --- extra/peg/javascript/javascript.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 030d2f1728..127b13130a 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -52,7 +52,7 @@ Digit = [0-9] Digits = Digit+ SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] -Space = " " | "\t" | "\n" | SingleLineComment | MultiLineComment +Space = " " | "\t" | "\r" | "\n" | SingleLineComment | MultiLineComment Spaces = Space* => [[ ignore ]] NameFirst = Letter | "$" | "_" NameRest = NameFirst | Digit From 6f8e2a4b0ddf74ea0f7bd43aed53984faaceab9e Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 00:42:11 +1200 Subject: [PATCH 0290/1850] Refactor JavaScript parser --- extra/peg/javascript/ast/ast.factor | 42 ++++ extra/peg/javascript/ast/authors.txt | 1 + extra/peg/javascript/ast/summary.txt | 1 + extra/peg/javascript/ast/tags.txt | 3 + extra/peg/javascript/authors.txt | 1 + extra/peg/javascript/javascript-docs.factor | 14 ++ extra/peg/javascript/javascript-tests.factor | 39 +-- extra/peg/javascript/javascript.factor | 225 +----------------- extra/peg/javascript/parser/authors.txt | 1 + .../peg/javascript/parser/parser-tests.factor | 27 +++ extra/peg/javascript/parser/parser.factor | 121 ++++++++++ extra/peg/javascript/parser/summary.txt | 1 + extra/peg/javascript/parser/tags.txt | 3 + extra/peg/javascript/summary.txt | 1 + extra/peg/javascript/tags.txt | 3 + extra/peg/javascript/tokenizer/authors.txt | 1 + extra/peg/javascript/tokenizer/summary.txt | 1 + extra/peg/javascript/tokenizer/tags.txt | 3 + .../tokenizer/tokenizer-tests.factor | 23 ++ .../peg/javascript/tokenizer/tokenizer.factor | 68 ++++++ 20 files changed, 330 insertions(+), 249 deletions(-) create mode 100644 extra/peg/javascript/ast/ast.factor create mode 100644 extra/peg/javascript/ast/authors.txt create mode 100644 extra/peg/javascript/ast/summary.txt create mode 100644 extra/peg/javascript/ast/tags.txt create mode 100644 extra/peg/javascript/authors.txt create mode 100644 extra/peg/javascript/javascript-docs.factor create mode 100644 extra/peg/javascript/parser/authors.txt create mode 100644 extra/peg/javascript/parser/parser-tests.factor create mode 100644 extra/peg/javascript/parser/parser.factor create mode 100644 extra/peg/javascript/parser/summary.txt create mode 100644 extra/peg/javascript/parser/tags.txt create mode 100644 extra/peg/javascript/summary.txt create mode 100644 extra/peg/javascript/tags.txt create mode 100644 extra/peg/javascript/tokenizer/authors.txt create mode 100644 extra/peg/javascript/tokenizer/summary.txt create mode 100644 extra/peg/javascript/tokenizer/tags.txt create mode 100644 extra/peg/javascript/tokenizer/tokenizer-tests.factor create mode 100644 extra/peg/javascript/tokenizer/tokenizer.factor diff --git a/extra/peg/javascript/ast/ast.factor b/extra/peg/javascript/ast/ast.factor new file mode 100644 index 0000000000..b857dc51bb --- /dev/null +++ b/extra/peg/javascript/ast/ast.factor @@ -0,0 +1,42 @@ +! Copyright (C) 2008 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel ; +IN: peg.javascript.ast + +TUPLE: ast-keyword value ; +TUPLE: ast-name value ; +TUPLE: ast-number value ; +TUPLE: ast-string value ; +TUPLE: ast-regexp value ; +TUPLE: ast-cond-expr condition then else ; +TUPLE: ast-set lhs rhs ; +TUPLE: ast-get value ; +TUPLE: ast-mset lhs rhs operator ; +TUPLE: ast-binop lhs rhs operator ; +TUPLE: ast-unop expr operator ; +TUPLE: ast-postop expr operator ; +TUPLE: ast-preop expr operator ; +TUPLE: ast-getp index expr ; +TUPLE: ast-send method expr args ; +TUPLE: ast-call expr args ; +TUPLE: ast-this ; +TUPLE: ast-new name args ; +TUPLE: ast-array values ; +TUPLE: ast-json bindings ; +TUPLE: ast-binding name value ; +TUPLE: ast-func fs body ; +TUPLE: ast-var name value ; +TUPLE: ast-begin statements ; +TUPLE: ast-if condition true false ; +TUPLE: ast-while condition statements ; +TUPLE: ast-do-while statements condition ; +TUPLE: ast-for i c u statements ; +TUPLE: ast-for-in v e statements ; +TUPLE: ast-switch expr statements ; +TUPLE: ast-break ; +TUPLE: ast-continue ; +TUPLE: ast-throw e ; +TUPLE: ast-try t e c f ; +TUPLE: ast-return e ; +TUPLE: ast-case c cs ; +TUPLE: ast-default cs ; diff --git a/extra/peg/javascript/ast/authors.txt b/extra/peg/javascript/ast/authors.txt new file mode 100644 index 0000000000..44b06f94bc --- /dev/null +++ b/extra/peg/javascript/ast/authors.txt @@ -0,0 +1 @@ +Chris Double diff --git a/extra/peg/javascript/ast/summary.txt b/extra/peg/javascript/ast/summary.txt new file mode 100644 index 0000000000..543a2e6373 --- /dev/null +++ b/extra/peg/javascript/ast/summary.txt @@ -0,0 +1 @@ +Abstract Syntax Tree for JavaScript parser diff --git a/extra/peg/javascript/ast/tags.txt b/extra/peg/javascript/ast/tags.txt new file mode 100644 index 0000000000..c2aac2932f --- /dev/null +++ b/extra/peg/javascript/ast/tags.txt @@ -0,0 +1,3 @@ +text +javascript +parsing diff --git a/extra/peg/javascript/authors.txt b/extra/peg/javascript/authors.txt new file mode 100644 index 0000000000..44b06f94bc --- /dev/null +++ b/extra/peg/javascript/authors.txt @@ -0,0 +1 @@ +Chris Double diff --git a/extra/peg/javascript/javascript-docs.factor b/extra/peg/javascript/javascript-docs.factor new file mode 100644 index 0000000000..5fdc3e8587 --- /dev/null +++ b/extra/peg/javascript/javascript-docs.factor @@ -0,0 +1,14 @@ +! Copyright (C) 2007 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax ; +IN: peg.javascript + +HELP: parse-javascript +{ $values + { "string" "a string" } + { "ast" "a JavaScript abstract syntax tree" } +} +{ $description + "Parse the input string using the JavaScript parser. Throws an error if " + "the string does not contain valid JavaScript. Returns the abstract syntax tree " + "if successful." } ; diff --git a/extra/peg/javascript/javascript-tests.factor b/extra/peg/javascript/javascript-tests.factor index 70410a3838..0d6899714d 100644 --- a/extra/peg/javascript/javascript-tests.factor +++ b/extra/peg/javascript/javascript-tests.factor @@ -1,42 +1,11 @@ ! Copyright (C) 2008 Chris Double. ! See http://factorcode.org/license.txt for BSD license. ! -USING: kernel tools.test peg peg.javascript accessors ; +USING: kernel tools.test peg.javascript peg.javascript.ast accessors ; IN: peg.javascript.tests -\ javascript must-infer +\ parse-javascript must-infer -{ - V{ - T{ ast-number f 123 } - ";" - T{ ast-string f "hello" } - ";" - T{ ast-name f "foo" } - "(" - T{ ast-name f "x" } - ")" - ";" - } -} [ - "123; 'hello'; foo(x);" tokenizer ast>> -] unit-test - -{ - T{ - ast-begin - f - V{ - T{ ast-number f 123 } - T{ ast-string f "hello" } - T{ - ast-call - f - T{ ast-get f "foo" } - V{ T{ ast-get f "x" } } - } - } - } -} [ - "123; 'hello'; foo(x);" tokenizer ast>> javascript ast>> +{ T{ ast-begin f V{ T{ ast-number f 123 } } } } [ + "123;" parse-javascript ] unit-test \ No newline at end of file diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 127b13130a..23a4b4f7f0 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -1,219 +1,16 @@ ! Copyright (C) 2008 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel arrays strings math.parser sequences sequences.deep -peg peg.ebnf peg.parsers memoize namespaces math accessors ; +USING: kernel accessors peg.javascript.tokenizer peg.javascript.parser ; IN: peg.javascript -#! Grammar for JavaScript. Based on OMeta-JS example from: -#! http://jarrett.cs.ucla.edu/ometa-js/#JavaScript_Compiler +: parse-javascript ( string -- ast ) + tokenizer [ + ast>> javascript [ + ast>> + ] [ + "Unable to parse JavaScript" throw + ] if* + ] [ + "Unable to tokenize JavaScript" throw + ] if* ; -USE: prettyprint - -TUPLE: ast-keyword value ; -TUPLE: ast-name value ; -TUPLE: ast-number value ; -TUPLE: ast-string value ; -TUPLE: ast-cond-expr condition then else ; -TUPLE: ast-set lhs rhs ; -TUPLE: ast-get value ; -TUPLE: ast-mset lhs rhs operator ; -TUPLE: ast-binop lhs rhs operator ; -TUPLE: ast-unop expr operator ; -TUPLE: ast-postop expr operator ; -TUPLE: ast-preop expr operator ; -TUPLE: ast-getp index expr ; -TUPLE: ast-send method expr args ; -TUPLE: ast-call expr args ; -TUPLE: ast-this ; -TUPLE: ast-new name args ; -TUPLE: ast-array values ; -TUPLE: ast-json bindings ; -TUPLE: ast-binding name value ; -TUPLE: ast-func fs body ; -TUPLE: ast-var name value ; -TUPLE: ast-begin statements ; -TUPLE: ast-if condition true false ; -TUPLE: ast-while condition statements ; -TUPLE: ast-do-while statements condition ; -TUPLE: ast-for i c u statements ; -TUPLE: ast-for-in v e statements ; -TUPLE: ast-switch expr statements ; -TUPLE: ast-break ; -TUPLE: ast-continue ; -TUPLE: ast-throw e ; -TUPLE: ast-try t e c f ; -TUPLE: ast-return e ; -TUPLE: ast-case c cs ; -TUPLE: ast-default cs ; - -EBNF: tokenizer -Letter = [a-zA-Z] -Digit = [0-9] -Digits = Digit+ -SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] -MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] -Space = " " | "\t" | "\r" | "\n" | SingleLineComment | MultiLineComment -Spaces = Space* => [[ ignore ]] -NameFirst = Letter | "$" | "_" -NameRest = NameFirst | Digit -iName = NameFirst NameRest* => [[ first2 swap prefix >string ]] -Keyword = ("break" - | "case" - | "catch" - | "continue" - | "default" - | "delete" - | "do" - | "else" - | "finally" - | "for" - | "function" - | "if" - | "in" - | "instanceof" - | "new" - | "return" - | "switch" - | "this" - | "throw" - | "try" - | "typeof" - | "var" - | "void" - | "while" - | "with") -Name = !(Keyword) (iName):n => [[ n ast-name boa ]] -Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] - | Digits => [[ >string string>number ast-number boa ]] - -EscapeChar = "\\n" => [[ 10 ]] - | "\\r" => [[ 13 ]] - | "\\t" => [[ 9 ]] -StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] -StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] -StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] -Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] - | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] - | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] -Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" - | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" - | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" - | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" - | "&&" | "||=" | "||" | "." | "!" -Tok = Spaces (Name | Keyword | Number | Str | Special ) -Toks = Tok* Spaces -;EBNF - -EBNF: javascript -Space = " " | "\t" | "\n" -Spaces = Space* => [[ ignore ]] -Name = . ?[ ast-name? ]? => [[ value>> ]] -Number = . ?[ ast-number? ]? => [[ value>> ]] -String = . ?[ ast-string? ]? => [[ value>> ]] -SpacesNoNl = (!("\n") Space)* => [[ ignore ]] - -Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-expr boa ]] - | OrExpr:e "=" Expr:rhs => [[ e rhs ast-set boa ]] - | OrExpr:e "+=" Expr:rhs => [[ e rhs "+" ast-mset boa ]] - | OrExpr:e "-=" Expr:rhs => [[ e rhs "-" ast-mset boa ]] - | OrExpr:e "*=" Expr:rhs => [[ e rhs "*" ast-mset boa ]] - | OrExpr:e "/=" Expr:rhs => [[ e rhs "/" ast-mset boa ]] - | OrExpr:e "%=" Expr:rhs => [[ e rhs "%" ast-mset boa ]] - | OrExpr:e "&&=" Expr:rhs => [[ e rhs "&&" ast-mset boa ]] - | OrExpr:e "||=" Expr:rhs => [[ e rhs "||" ast-mset boa ]] - | OrExpr:e => [[ e ]] - -OrExpr = OrExpr:x "||" AndExpr:y => [[ x y "||" ast-binop boa ]] - | AndExpr -AndExpr = AndExpr:x "&&" EqExpr:y => [[ x y "&&" ast-binop boa ]] - | EqExpr -EqExpr = EqExpr:x "==" RelExpr:y => [[ x y "==" ast-binop boa ]] - | EqExpr:x "!=" RelExpr:y => [[ x y "!=" ast-binop boa ]] - | EqExpr:x "===" RelExpr:y => [[ x y "===" ast-binop boa ]] - | EqExpr:x "!==" RelExpr:y => [[ x y "!==" ast-binop boa ]] - | RelExpr -RelExpr = RelExpr:x ">" AddExpr:y => [[ x y ">" ast-binop boa ]] - | RelExpr:x ">=" AddExpr:y => [[ x y ">=" ast-binop boa ]] - | RelExpr:x "<" AddExpr:y => [[ x y "<" ast-binop boa ]] - | RelExpr:x "<=" AddExpr:y => [[ x y "<=" ast-binop boa ]] - | RelExpr:x "instanceof" AddExpr:y => [[ x y "instanceof" ast-binop boa ]] - | AddExpr -AddExpr = AddExpr:x "+" MulExpr:y => [[ x y "+" ast-binop boa ]] - | AddExpr:x "-" MulExpr:y => [[ x y "-" ast-binop boa ]] - | MulExpr -MulExpr = MulExpr:x "*" MulExpr:y => [[ x y "*" ast-binop boa ]] - | MulExpr:x "/" MulExpr:y => [[ x y "/" ast-binop boa ]] - | MulExpr:x "%" MulExpr:y => [[ x y "%" ast-binop boa ]] - | Unary -Unary = "-" Postfix:p => [[ p "-" ast-unop boa ]] - | "+" Postfix:p => [[ p ]] - | "++" Postfix:p => [[ p "++" ast-preop boa ]] - | "--" Postfix:p => [[ p "--" ast-preop boa ]] - | "!" Postfix:p => [[ p "!" ast-unop boa ]] - | Postfix -Postfix = PrimExpr:p SpacesNoNl "++" => [[ p "++" ast-postop boa ]] - | PrimExpr:p SpacesNoNl "--" => [[ p "--" ast-postop boa ]] - | PrimExpr -Args = (Expr ("," Expr => [[ second ]])* => [[ first2 swap prefix ]])? -PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ i p ast-getp boa ]] - | PrimExpr:p "." Name:m "(" Args:as ")" => [[ m p as ast-send boa ]] - | PrimExpr:p "." Name:f => [[ f p ast-getp boa ]] - | PrimExpr:p "(" Args:as ")" => [[ p as ast-call boa ]] - | PrimExprHd -PrimExprHd = "(" Expr:e ")" => [[ e ]] - | "this" => [[ ast-this boa ]] - | Name => [[ ast-get boa ]] - | Number => [[ ast-number boa ]] - | String => [[ ast-string boa ]] - | "function" FuncRest:fr => [[ fr ]] - | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] - | "[" Args:es "]" => [[ es ast-array boa ]] - | Json -JsonBindings = (JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]])? -Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] -JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] -JsonPropName = Name | Number | String -Formal = Spaces Name -Formals = (Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]])? -FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] -Sc = SpacesNoNl ("\n" | &("}"))| ";" -Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] - | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] -Block = "{" SrcElems:ss "}" => [[ ss ]] -Bindings = (Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]])? -For1 = "var" Binding => [[ second ]] - | Expr - | Spaces => [[ "undefined" ast-get boa ]] -For2 = Expr - | Spaces => [[ "true" ast-get boa ]] -For3 = Expr - | Spaces => [[ "undefined" ast-get boa ]] -ForIn1 = "var" Name:n => [[ n "undefined" ast-get boa ast-var boa ]] - | Expr -Switch1 = "case" Expr:c ":" SrcElems:cs => [[ c cs ast-case boa ]] - | "default" ":" SrcElems:cs => [[ cs ast-default boa ]] -SwitchBody = Switch1* -Finally = "finally" Block:b => [[ b ]] - | Spaces => [[ "undefined" ast-get boa ]] -Stmt = Block - | "var" Bindings:bs Sc => [[ bs ast-begin boa ]] - | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ c t f ast-if boa ]] - | "if" "(" Expr:c ")" Stmt:t => [[ c t "undefined" ast-get boa ast-if boa ]] - | "while" "(" Expr:c ")" Stmt:s => [[ c s ast-while boa ]] - | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ s c ast-do-while boa ]] - | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ i c u s ast-for boa ]] - | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ v e s ast-for-in boa ]] - | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ e cs ast-switch boa ]] - | "break" Sc => [[ ast-break boa ]] - | "continue" Sc => [[ ast-continue boa ]] - | "throw" SpacesNoNl Expr:e Sc => [[ e ast-throw boa ]] - | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ t e c f ast-try boa ]] - | "return" Expr:e Sc => [[ e ast-return boa ]] - | "return" Sc => [[ "undefined" ast-get boa ast-return boa ]] - | Expr:e Sc => [[ e ]] - | ";" => [[ "undefined" ast-get boa ]] -SrcElem = "function" Name:n FuncRest:f => [[ n f ast-var boa ]] - | Stmt -SrcElems = SrcElem* => [[ ast-begin boa ]] -TopLevel = SrcElems Spaces -;EBNF \ No newline at end of file diff --git a/extra/peg/javascript/parser/authors.txt b/extra/peg/javascript/parser/authors.txt new file mode 100644 index 0000000000..44b06f94bc --- /dev/null +++ b/extra/peg/javascript/parser/authors.txt @@ -0,0 +1 @@ +Chris Double diff --git a/extra/peg/javascript/parser/parser-tests.factor b/extra/peg/javascript/parser/parser-tests.factor new file mode 100644 index 0000000000..933d4cf10e --- /dev/null +++ b/extra/peg/javascript/parser/parser-tests.factor @@ -0,0 +1,27 @@ +! Copyright (C) 2008 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +! +USING: kernel tools.test peg peg.javascript.ast peg.javascript.tokenizer + peg.javascript.parser accessors ; +IN: peg.javascript.parser.tests + +\ javascript must-infer + +{ + T{ + ast-begin + f + V{ + T{ ast-number f 123 } + T{ ast-string f "hello" } + T{ + ast-call + f + T{ ast-get f "foo" } + V{ T{ ast-get f "x" } } + } + } + } +} [ + "123; 'hello'; foo(x);" tokenizer ast>> javascript ast>> +] unit-test \ No newline at end of file diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor new file mode 100644 index 0000000000..a38cf4aea8 --- /dev/null +++ b/extra/peg/javascript/parser/parser.factor @@ -0,0 +1,121 @@ +! Copyright (C) 2008 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors peg peg.ebnf peg.javascript.ast ; +IN: peg.javascript.parser + +#! Grammar for JavaScript. Based on OMeta-JS example from: +#! http://jarrett.cs.ucla.edu/ometa-js/#JavaScript_Compiler + +EBNF: javascript +Space = " " | "\t" | "\n" +Spaces = Space* => [[ ignore ]] +Name = . ?[ ast-name? ]? => [[ value>> ]] +Number = . ?[ ast-number? ]? => [[ value>> ]] +String = . ?[ ast-string? ]? => [[ value>> ]] +SpacesNoNl = (!("\n") Space)* => [[ ignore ]] + +Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-expr boa ]] + | OrExpr:e "=" Expr:rhs => [[ e rhs ast-set boa ]] + | OrExpr:e "+=" Expr:rhs => [[ e rhs "+" ast-mset boa ]] + | OrExpr:e "-=" Expr:rhs => [[ e rhs "-" ast-mset boa ]] + | OrExpr:e "*=" Expr:rhs => [[ e rhs "*" ast-mset boa ]] + | OrExpr:e "/=" Expr:rhs => [[ e rhs "/" ast-mset boa ]] + | OrExpr:e "%=" Expr:rhs => [[ e rhs "%" ast-mset boa ]] + | OrExpr:e "&&=" Expr:rhs => [[ e rhs "&&" ast-mset boa ]] + | OrExpr:e "||=" Expr:rhs => [[ e rhs "||" ast-mset boa ]] + | OrExpr:e => [[ e ]] + +OrExpr = OrExpr:x "||" AndExpr:y => [[ x y "||" ast-binop boa ]] + | AndExpr +AndExpr = AndExpr:x "&&" EqExpr:y => [[ x y "&&" ast-binop boa ]] + | EqExpr +EqExpr = EqExpr:x "==" RelExpr:y => [[ x y "==" ast-binop boa ]] + | EqExpr:x "!=" RelExpr:y => [[ x y "!=" ast-binop boa ]] + | EqExpr:x "===" RelExpr:y => [[ x y "===" ast-binop boa ]] + | EqExpr:x "!==" RelExpr:y => [[ x y "!==" ast-binop boa ]] + | RelExpr +RelExpr = RelExpr:x ">" AddExpr:y => [[ x y ">" ast-binop boa ]] + | RelExpr:x ">=" AddExpr:y => [[ x y ">=" ast-binop boa ]] + | RelExpr:x "<" AddExpr:y => [[ x y "<" ast-binop boa ]] + | RelExpr:x "<=" AddExpr:y => [[ x y "<=" ast-binop boa ]] + | RelExpr:x "instanceof" AddExpr:y => [[ x y "instanceof" ast-binop boa ]] + | AddExpr +AddExpr = AddExpr:x "+" MulExpr:y => [[ x y "+" ast-binop boa ]] + | AddExpr:x "-" MulExpr:y => [[ x y "-" ast-binop boa ]] + | MulExpr +MulExpr = MulExpr:x "*" MulExpr:y => [[ x y "*" ast-binop boa ]] + | MulExpr:x "/" MulExpr:y => [[ x y "/" ast-binop boa ]] + | MulExpr:x "%" MulExpr:y => [[ x y "%" ast-binop boa ]] + | Unary +Unary = "-" Postfix:p => [[ p "-" ast-unop boa ]] + | "+" Postfix:p => [[ p ]] + | "++" Postfix:p => [[ p "++" ast-preop boa ]] + | "--" Postfix:p => [[ p "--" ast-preop boa ]] + | "!" Postfix:p => [[ p "!" ast-unop boa ]] + | Postfix +Postfix = PrimExpr:p SpacesNoNl "++" => [[ p "++" ast-postop boa ]] + | PrimExpr:p SpacesNoNl "--" => [[ p "--" ast-postop boa ]] + | PrimExpr +Args = (Expr ("," Expr => [[ second ]])* => [[ first2 swap prefix ]])? +PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ i p ast-getp boa ]] + | PrimExpr:p "." Name:m "(" Args:as ")" => [[ m p as ast-send boa ]] + | PrimExpr:p "." Name:f => [[ f p ast-getp boa ]] + | PrimExpr:p "(" Args:as ")" => [[ p as ast-call boa ]] + | PrimExprHd +PrimExprHd = "(" Expr:e ")" => [[ e ]] + | "this" => [[ ast-this boa ]] + | Name => [[ ast-get boa ]] + | Number => [[ ast-number boa ]] + | String => [[ ast-string boa ]] + | "function" FuncRest:fr => [[ fr ]] + | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] + | "[" Args:es "]" => [[ es ast-array boa ]] + | Json +JsonBindings = (JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]])? +Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] +JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] +JsonPropName = Name | Number | String +Formal = Spaces Name +Formals = (Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]])? +FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] +Sc = SpacesNoNl ("\n" | &("}"))| ";" +Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] + | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] +Block = "{" SrcElems:ss "}" => [[ ss ]] +Bindings = (Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]])? +For1 = "var" Binding => [[ second ]] + | Expr + | Spaces => [[ "undefined" ast-get boa ]] +For2 = Expr + | Spaces => [[ "true" ast-get boa ]] +For3 = Expr + | Spaces => [[ "undefined" ast-get boa ]] +ForIn1 = "var" Name:n => [[ n "undefined" ast-get boa ast-var boa ]] + | Expr +Switch1 = "case" Expr:c ":" SrcElems:cs => [[ c cs ast-case boa ]] + | "default" ":" SrcElems:cs => [[ cs ast-default boa ]] +SwitchBody = Switch1* +Finally = "finally" Block:b => [[ b ]] + | Spaces => [[ "undefined" ast-get boa ]] +Stmt = Block + | "var" Bindings:bs Sc => [[ bs ast-begin boa ]] + | "if" "(" Expr:c ")" Stmt:t "else" Stmt:f => [[ c t f ast-if boa ]] + | "if" "(" Expr:c ")" Stmt:t => [[ c t "undefined" ast-get boa ast-if boa ]] + | "while" "(" Expr:c ")" Stmt:s => [[ c s ast-while boa ]] + | "do" Stmt:s "while" "(" Expr:c ")" Sc => [[ s c ast-do-while boa ]] + | "for" "(" For1:i ";" For2:c ";" For3:u ")" Stmt:s => [[ i c u s ast-for boa ]] + | "for" "(" ForIn1:v "in" Expr:e ")" Stmt:s => [[ v e s ast-for-in boa ]] + | "switch" "(" Expr:e ")" "{" SwitchBody:cs "}" => [[ e cs ast-switch boa ]] + | "break" Sc => [[ ast-break boa ]] + | "continue" Sc => [[ ast-continue boa ]] + | "throw" SpacesNoNl Expr:e Sc => [[ e ast-throw boa ]] + | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ t e c f ast-try boa ]] + | "return" Expr:e Sc => [[ e ast-return boa ]] + | "return" Sc => [[ "undefined" ast-get boa ast-return boa ]] + | Expr:e Sc => [[ e ]] + | ";" => [[ "undefined" ast-get boa ]] +SrcElem = "function" Name:n FuncRest:f => [[ n f ast-var boa ]] + | Stmt +SrcElems = SrcElem* => [[ ast-begin boa ]] +TopLevel = SrcElems Spaces +;EBNF \ No newline at end of file diff --git a/extra/peg/javascript/parser/summary.txt b/extra/peg/javascript/parser/summary.txt new file mode 100644 index 0000000000..bae5a461d2 --- /dev/null +++ b/extra/peg/javascript/parser/summary.txt @@ -0,0 +1 @@ +JavaScript Parser diff --git a/extra/peg/javascript/parser/tags.txt b/extra/peg/javascript/parser/tags.txt new file mode 100644 index 0000000000..c2aac2932f --- /dev/null +++ b/extra/peg/javascript/parser/tags.txt @@ -0,0 +1,3 @@ +text +javascript +parsing diff --git a/extra/peg/javascript/summary.txt b/extra/peg/javascript/summary.txt new file mode 100644 index 0000000000..12f092dcf7 --- /dev/null +++ b/extra/peg/javascript/summary.txt @@ -0,0 +1 @@ +JavaScript parser diff --git a/extra/peg/javascript/tags.txt b/extra/peg/javascript/tags.txt new file mode 100644 index 0000000000..c2aac2932f --- /dev/null +++ b/extra/peg/javascript/tags.txt @@ -0,0 +1,3 @@ +text +javascript +parsing diff --git a/extra/peg/javascript/tokenizer/authors.txt b/extra/peg/javascript/tokenizer/authors.txt new file mode 100644 index 0000000000..44b06f94bc --- /dev/null +++ b/extra/peg/javascript/tokenizer/authors.txt @@ -0,0 +1 @@ +Chris Double diff --git a/extra/peg/javascript/tokenizer/summary.txt b/extra/peg/javascript/tokenizer/summary.txt new file mode 100644 index 0000000000..ce94386ed9 --- /dev/null +++ b/extra/peg/javascript/tokenizer/summary.txt @@ -0,0 +1 @@ +Tokenizer for JavaScript language diff --git a/extra/peg/javascript/tokenizer/tags.txt b/extra/peg/javascript/tokenizer/tags.txt new file mode 100644 index 0000000000..c2aac2932f --- /dev/null +++ b/extra/peg/javascript/tokenizer/tags.txt @@ -0,0 +1,3 @@ +text +javascript +parsing diff --git a/extra/peg/javascript/tokenizer/tokenizer-tests.factor b/extra/peg/javascript/tokenizer/tokenizer-tests.factor new file mode 100644 index 0000000000..1300b3c9c7 --- /dev/null +++ b/extra/peg/javascript/tokenizer/tokenizer-tests.factor @@ -0,0 +1,23 @@ +! Copyright (C) 2008 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +! +USING: kernel tools.test peg peg.javascript.ast peg.javascript.tokenizer accessors ; +IN: peg.javascript.tokenizer.tests + +\ tokenizer must-infer + +{ + V{ + T{ ast-number f 123 } + ";" + T{ ast-string f "hello" } + ";" + T{ ast-name f "foo" } + "(" + T{ ast-name f "x" } + ")" + ";" + } +} [ + "123; 'hello'; foo(x);" tokenizer ast>> +] unit-test diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor new file mode 100644 index 0000000000..d62bb9395b --- /dev/null +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -0,0 +1,68 @@ +! Copyright (C) 2008 Chris Double. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel sequences strings arrays math.parser peg peg.ebnf peg.javascript.ast ; +IN: peg.javascript.tokenizer + +#! Grammar for JavaScript. Based on OMeta-JS example from: +#! http://jarrett.cs.ucla.edu/ometa-js/#JavaScript_Compiler + +EBNF: tokenizer +Letter = [a-zA-Z] +Digit = [0-9] +Digits = Digit+ +SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] +MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] +Space = " " | "\t" | "\r" | "\n" | SingleLineComment | MultiLineComment +Spaces = Space* => [[ ignore ]] +NameFirst = Letter | "$" | "_" +NameRest = NameFirst | Digit +iName = NameFirst NameRest* => [[ first2 swap prefix >string ]] +Keyword = ("break" + | "case" + | "catch" + | "continue" + | "default" + | "delete" + | "do" + | "else" + | "finally" + | "for" + | "function" + | "if" + | "in" + | "instanceof" + | "new" + | "return" + | "switch" + | "this" + | "throw" + | "try" + | "typeof" + | "var" + | "void" + | "while" + | "with") +Name = !(Keyword) (iName):n => [[ n ast-name boa ]] +Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] + | Digits => [[ >string string>number ast-number boa ]] + +EscapeChar = "\\n" => [[ 10 ]] + | "\\r" => [[ 13 ]] + | "\\t" => [[ 9 ]] +StringChars1 = (EscapeChar | !('"""') .)* => [[ >string ]] +StringChars2 = (EscapeChar | !('"') .)* => [[ >string ]] +StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] +Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] + | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] + | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] +RegExpBody = (!("/" | "\n" | "\r") .)* => [[ >string ]] +RegExp = "/" RegExpBody:r "/" => [[ r ast-regexp boa ]] +Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" + | "?" | ":" | "!==" | "~=" | "===" | "==" | "=" | ">=" + | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" + | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" + | "&&" | "||=" | "||" | "." | "!" +Tok = Spaces (Name | Keyword | Number | Str | RegExp | Special ) +Toks = Tok* Spaces +;EBNF + From fc7baebacbcedc177b16c5377991e156e9f62d26 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 00:51:47 +1200 Subject: [PATCH 0291/1850] Fix handling of _ and $ in Javascript names --- extra/peg/javascript/tokenizer/tokenizer.factor | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index d62bb9395b..420abff442 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -6,6 +6,8 @@ IN: peg.javascript.tokenizer #! Grammar for JavaScript. Based on OMeta-JS example from: #! http://jarrett.cs.ucla.edu/ometa-js/#JavaScript_Compiler +USE: prettyprint + EBNF: tokenizer Letter = [a-zA-Z] Digit = [0-9] @@ -14,7 +16,7 @@ SingleLineComment = "//" (!("\n") .)* "\n" => [[ ignore ]] MultiLineComment = "/*" (!("*/") .)* "*/" => [[ ignore ]] Space = " " | "\t" | "\r" | "\n" | SingleLineComment | MultiLineComment Spaces = Space* => [[ ignore ]] -NameFirst = Letter | "$" | "_" +NameFirst = Letter | "$" => [[ CHAR: $ ]] | "_" => [[ CHAR: _ ]] NameRest = NameFirst | Digit iName = NameFirst NameRest* => [[ first2 swap prefix >string ]] Keyword = ("break" From c26d87e11788c107d7467f38ae2a0bded3666c05 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 01:01:46 +1200 Subject: [PATCH 0292/1850] Fix handling of JavasScript names which partially match reserved words --- extra/peg/javascript/tokenizer/tokenizer.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index 420abff442..70fabb10f6 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -44,7 +44,7 @@ Keyword = ("break" | "void" | "while" | "with") -Name = !(Keyword) (iName):n => [[ n ast-name boa ]] +Name = iName !(Keyword) => [[ ast-name boa ]] Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] | Digits => [[ >string string>number ast-number boa ]] From 179ea21c11d95f257a5f3172dab4ffd7fa91ae5a Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 01:10:44 +1200 Subject: [PATCH 0293/1850] Add a couple of failing peg.ebnf tests --- extra/peg/ebnf/ebnf-tests.factor | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index 73db626685..ed38d37421 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -399,6 +399,16 @@ main = Primary "number=digit+:n 'a'" 'ebnf' parse remaining>> length zero? ] unit-test +{ t } [ + "foo=(name):n !(keyword) => [[ n ]]" 'rule' parse ast>> + "foo=name:n !(keyword) => [[ n ]]" 'rule' parse ast>> = +] unit-test + +{ t } [ + "foo=!(keyword) (name):n => [[ n ]]" 'rule' parse ast>> + "foo=!(keyword) name:n => [[ n ]]" 'rule' parse ast>> = +] unit-test + << EBNF: parser1 foo='a' @@ -431,4 +441,4 @@ foo= 'd' { V{ CHAR: a "d" } } [ "ad" parser4 ast>> -] unit-test \ No newline at end of file +] unit-test From fcd1e39834052d7df4548d4c411870a8417ec10c Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 01:20:33 +1200 Subject: [PATCH 0294/1850] More JavaScript fixes for keyword handling --- extra/peg/javascript/tokenizer/tokenizer.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index 70fabb10f6..a1cff8a3db 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -43,8 +43,8 @@ Keyword = ("break" | "var" | "void" | "while" - | "with") -Name = iName !(Keyword) => [[ ast-name boa ]] + | "with") !(NameRest) +Name = !(Keyword) iName => [[ ast-name boa ]] Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array concat >string string>number ast-number boa ]] | Digits => [[ >string string>number ast-number boa ]] From d58a085598e930566c003aaff406e5996f91c73f Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 01:24:17 +1200 Subject: [PATCH 0295/1850] Add additional javascript test --- extra/peg/javascript/parser/parser-tests.factor | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/extra/peg/javascript/parser/parser-tests.factor b/extra/peg/javascript/parser/parser-tests.factor index 933d4cf10e..6741e059f9 100644 --- a/extra/peg/javascript/parser/parser-tests.factor +++ b/extra/peg/javascript/parser/parser-tests.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. ! USING: kernel tools.test peg peg.javascript.ast peg.javascript.tokenizer - peg.javascript.parser accessors ; + peg.javascript.parser accessors multiline sequences math ; IN: peg.javascript.parser.tests \ javascript must-infer @@ -24,4 +24,14 @@ IN: peg.javascript.parser.tests } } [ "123; 'hello'; foo(x);" tokenizer ast>> javascript ast>> -] unit-test \ No newline at end of file +] unit-test + +{ t } [ +<" +function foldl(f, initial, seq) { + for(var i=0; i< seq.length; ++i) + initial = f(initial, seq[i]); + return initial; +} +"> tokenizer ast>> javascript remaining>> length zero? +] unit-test From d5e5e47944736585195b66aab7e997b0e7c9a666 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 01:39:51 +1200 Subject: [PATCH 0296/1850] Fix bug in javascript automatic semicolon insertion rule --- extra/peg/javascript/parser/parser-tests.factor | 11 +++++++++++ extra/peg/javascript/parser/parser.factor | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/extra/peg/javascript/parser/parser-tests.factor b/extra/peg/javascript/parser/parser-tests.factor index 6741e059f9..ec7a30845f 100644 --- a/extra/peg/javascript/parser/parser-tests.factor +++ b/extra/peg/javascript/parser/parser-tests.factor @@ -35,3 +35,14 @@ function foldl(f, initial, seq) { } "> tokenizer ast>> javascript remaining>> length zero? ] unit-test + +{ t } [ +<" +ParseState.prototype.from = function(index) { + var r = new ParseState(this.input, this.index + index); + r.cache = this.cache; + r.length = this.length - index; + return r; +} +"> tokenizer ast>> javascript remaining>> length zero? +] unit-test diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index a38cf4aea8..45aa0f022c 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -7,6 +7,7 @@ IN: peg.javascript.parser #! http://jarrett.cs.ucla.edu/ometa-js/#JavaScript_Compiler EBNF: javascript +End = !(.) Space = " " | "\t" | "\n" Spaces = Space* => [[ ignore ]] Name = . ?[ ast-name? ]? => [[ value>> ]] @@ -78,7 +79,7 @@ JsonPropName = Name | Number | String Formal = Spaces Name Formals = (Formal ("," Formal => [[ second ]])* => [[ first2 swap prefix ]])? FuncRest = "(" Formals:fs ")" "{" SrcElems:body "}" => [[ fs body ast-func boa ]] -Sc = SpacesNoNl ("\n" | &("}"))| ";" +Sc = SpacesNoNl ("\n" | &("}") | End)| ";" Binding = Name:n "=" Expr:v => [[ n v ast-var boa ]] | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] Block = "{" SrcElems:ss "}" => [[ ss ]] From 2b2ede0a89411421649af182bb69439bc6424b17 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 01:45:09 +1200 Subject: [PATCH 0297/1850] Add a javascript sc test --- extra/peg/javascript/parser/parser-tests.factor | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/extra/peg/javascript/parser/parser-tests.factor b/extra/peg/javascript/parser/parser-tests.factor index ec7a30845f..d911a27285 100644 --- a/extra/peg/javascript/parser/parser-tests.factor +++ b/extra/peg/javascript/parser/parser-tests.factor @@ -26,6 +26,14 @@ IN: peg.javascript.parser.tests "123; 'hello'; foo(x);" tokenizer ast>> javascript ast>> ] unit-test +{ t } [ +<" +var x=5 +var y=10 +"> tokenizer ast>> javascript remaining>> length zero? +] unit-test + + { t } [ <" function foldl(f, initial, seq) { @@ -46,3 +54,4 @@ ParseState.prototype.from = function(index) { } "> tokenizer ast>> javascript remaining>> length zero? ] unit-test + From 3e11a7f2040d89271113fcc5ffe2cbebd43afe52 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 19:46:37 -0500 Subject: [PATCH 0298/1850] Debugging persistent vectors --- .../persistent-vectors-tests.factor | 4 +++ .../persistent-vectors.factor | 33 ++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/extra/persistent-vectors/persistent-vectors-tests.factor b/extra/persistent-vectors/persistent-vectors-tests.factor index a4e4ad33fe..45eb894e67 100644 --- a/extra/persistent-vectors/persistent-vectors-tests.factor +++ b/extra/persistent-vectors/persistent-vectors-tests.factor @@ -48,6 +48,10 @@ random namespaces vectors math math.order ; [ ] [ PV{ } "1" set ] unit-test [ ] [ V{ } clone "2" set ] unit-test +: push/pop-test ( vec -- vec' ) 3 swap ppush 3 swap ppush ppop ; + +[ ] [ PV{ } 10000 [ push/pop-test ] times drop ] unit-test + [ t ] [ 100 [ drop diff --git a/extra/persistent-vectors/persistent-vectors.factor b/extra/persistent-vectors/persistent-vectors.factor index f9f4b68933..c80de3b0cd 100644 --- a/extra/persistent-vectors/persistent-vectors.factor +++ b/extra/persistent-vectors/persistent-vectors.factor @@ -1,7 +1,7 @@ ! Based on Clojure's PersistentVector by Rich Hickey. USING: math accessors kernel sequences.private sequences arrays -combinators parser prettyprint.backend ; +combinators combinators.lib parser prettyprint.backend ; IN: persistent-vectors ERROR: empty-error pvec ; @@ -123,30 +123,39 @@ M: persistent-vector new-nth ( obj i pvec -- pvec' ) ] if ] if ; +: ppop-tail ( pvec -- pvec' ) + [ clone [ ppop ] change-children ] change-tail ; + : (ppop-contraction) ( node -- node' tail' ) clone [ unclip-last swap ] change-children swap ; : ppop-contraction ( node -- node' tail' ) - [ (ppop-contraction) ] [ level>> 1 = ] bi swap and ; + dup children>> length 1 = + [ children>> peek f swap ] + [ (ppop-contraction) ] + if ; : (ppop-new-tail) ( root -- root' tail' ) dup level>> 1 > [ - dup children>> peek (ppop-new-tail) over children>> empty? - [ 2drop ppop-contraction ] [ [ swap node-set-last ] dip ] if + dup children>> peek (ppop-new-tail) over + [ [ swap node-set-last ] dip ] + [ 2drop ppop-contraction ] + if ] [ ppop-contraction ] if ; -: ppop-tail ( pvec -- pvec' ) - [ clone [ ppop ] change-children ] change-tail ; +: trivial? ( node -- ? ) + { [ level>> 1 > ] [ children>> length 1 = ] } 1&& ; : ppop-new-tail ( pvec -- pvec' ) - dup root>> (ppop-new-tail) - [ - dup [ level>> 1 > ] [ children>> length 1 = ] bi and - [ children>> first ] when - ] dip - [ >>root ] [ >>tail ] bi* ; + dup root>> (ppop-new-tail) [ + { + { [ dup not ] [ drop T{ node f { } 1 } ] } + { [ dup trivial? ] [ children>> first ] } + [ ] + } cond + ] dip [ >>root ] [ >>tail ] bi* ; PRIVATE> From 04453b242157e5966971fd86dc62c86ab6a56757 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 14:23:18 +1200 Subject: [PATCH 0299/1850] Fix (foo):n usage --- extra/peg/ebnf/ebnf.factor | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 2ee0958051..d982d73229 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -232,14 +232,18 @@ DEFER: 'choice' : ('sequence') ( -- parser ) #! A sequence of terminals and non-terminals, including #! groupings of those. - [ - 'ensure-not' sp , - 'ensure' sp , - 'element' sp , - 'group' sp , - 'repeat0' sp , - 'repeat1' sp , - 'optional' sp , + [ + [ + 'ensure-not' sp , + 'ensure' sp , + 'element' sp , + 'group' sp , + 'repeat0' sp , + 'repeat1' sp , + 'optional' sp , + ] choice* + [ dup , ":" syntax , "a-zA-Z" range-pattern repeat1 [ >string ] action , ] seq* [ first2 ] action , + , ] choice* ; : 'action' ( -- parser ) From 3dc3a6f8996d46f3717302407b197d3b0aa6da1a Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 14:31:14 +1200 Subject: [PATCH 0300/1850] Remove obsolete ebnf stuff --- extra/peg/ebnf/ebnf.factor | 2 -- 1 file changed, 2 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index d982d73229..08ac24e535 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -266,8 +266,6 @@ DEFER: 'choice' : 'actioned-sequence' ( -- parser ) [ [ 'sequence' , "=>" syntax , 'action' , ] seq* [ first2 ] action , - [ 'sequence' , ":" syntax , "a-zA-Z" range-pattern repeat1 [ >string ] action , "=>" syntax , 'action' , ] seq* [ first3 >r r> ] action , - [ 'sequence' , ":" syntax , "a-zA-Z" range-pattern repeat1 [ >string ] action , ] seq* [ first2 ] action , 'sequence' , ] choice* ; From c92224f5b9b94ea2bdc1224c10cf640921c283df Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 14:34:09 +1200 Subject: [PATCH 0301/1850] Put '..' around parser error messages --- extra/peg/ebnf/ebnf.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 08ac24e535..2aec8b9aea 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -416,7 +416,7 @@ M: ebnf-terminal (transform) ( ast -- parser ) M: ebnf-foreign (transform) ( ast -- parser ) dup word>> search - [ "Foreign word " swap word>> append " not found" append throw ] unless* + [ "Foreign word '" swap word>> append "' not found" append throw ] unless* swap rule>> [ main ] unless* dupd swap rule [ nip ] [ @@ -425,7 +425,7 @@ M: ebnf-foreign (transform) ( ast -- parser ) : parser-not-found ( name -- * ) [ - "Parser " % % " not found." % + "Parser '" % % "' not found." % ] "" make throw ; M: ebnf-non-terminal (transform) ( ast -- parser ) From 9b7e2bacc960c03ff28780b0a469018a098b5540 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 19 Jun 2008 14:44:13 +1200 Subject: [PATCH 0302/1850] Throw an error if there are duplicate rules in ebnf --- extra/peg/ebnf/ebnf.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 2aec8b9aea..e78757be34 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -305,7 +305,7 @@ M: ebnf (transform) ( ast -- parser ) M: ebnf-rule (transform) ( ast -- parser ) dup elements>> (transform) [ - swap symbol>> set + swap symbol>> dup get [ "Rule '" over append "' defined more than once" append throw ] [ set ] if ] keep ; M: ebnf-sequence (transform) ( ast -- parser ) From 646a4dd925b8049f39dae33da1a560a5ba25110b Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Wed, 18 Jun 2008 23:58:10 -0300 Subject: [PATCH 0303/1850] irc.client: Make add-listener a word instead of a generic method --- extra/irc/client/client.factor | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index e633f140fb..7760c3a2f3 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -326,6 +326,5 @@ PRIVATE> spawn-irc ] with-variable ; -GENERIC: add-listener ( irc-client irc-listener -- ) -M: irc-listener add-listener ( irc-client irc-listener -- ) - current-irc-client swap '[ , (add-listener) ] with-variable ; +: irc-listener add-listener ( irc-listener irc-client -- ) + current-irc-client '[ , (add-listener) ] with-variable ; From beccf83f7ccb81ddf35f025d22450b8ae51bbca5 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 22:29:48 -0500 Subject: [PATCH 0304/1850] Fix deploy tests --- extra/tools/deploy/deploy-tests.factor | 22 +++++++++++++--------- extra/tools/deploy/test/3/3.factor | 5 ++--- extra/tools/deploy/test/4/4.factor | 7 +++++++ extra/tools/deploy/test/4/deploy.factor | 15 +++++++++++++++ 4 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 extra/tools/deploy/test/4/4.factor create mode 100644 extra/tools/deploy/test/4/deploy.factor diff --git a/extra/tools/deploy/deploy-tests.factor b/extra/tools/deploy/deploy-tests.factor index 8ff22fb1ad..5309784b7c 100755 --- a/extra/tools/deploy/deploy-tests.factor +++ b/extra/tools/deploy/deploy-tests.factor @@ -49,12 +49,16 @@ namespaces continuations layouts accessors ; cell 8 = 50 30 ? 100000 * small-enough? ] unit-test -[ ] [ - "tools.deploy.test.1" shake-and-bake - vm "-i=" "test.image" temp-file append 2array try-process -] unit-test - -[ ] [ - "tools.deploy.test.2" shake-and-bake - vm "-i=" "test.image" temp-file append 2array try-process -] unit-test +{ + "tools.deploy.test.1" + "tools.deploy.test.2" + "tools.deploy.test.3" + "tools.deploy.test.4" +} [ + [ ] swap [ + shake-and-bake + vm + "-i=" "test.image" temp-file append + 2array try-process + ] curry unit-test +] each diff --git a/extra/tools/deploy/test/3/3.factor b/extra/tools/deploy/test/3/3.factor index 69287db4e2..5919fa15db 100755 --- a/extra/tools/deploy/test/3/3.factor +++ b/extra/tools/deploy/test/3/3.factor @@ -1,8 +1,7 @@ IN: tools.deploy.test.3 -USING: io.encodings.ascii io.files kernel ; +USING: io.encodings.ascii io.encodings.string system kernel ; : deploy-test-3 ( -- ) - "resource:extra/tools/deploy/test/3/3.factor" - ascii file-contents drop ; + "xyzthg" ascii encode drop ; MAIN: deploy-test-3 diff --git a/extra/tools/deploy/test/4/4.factor b/extra/tools/deploy/test/4/4.factor new file mode 100644 index 0000000000..6831eae5d3 --- /dev/null +++ b/extra/tools/deploy/test/4/4.factor @@ -0,0 +1,7 @@ +IN: tools.deploy.test.4 +USING: io.encodings.8-bit io.encodings.string kernel ; + +: deploy-test-4 ( -- ) + "xyzthg" latin7 encode drop ; + +MAIN: deploy-test-4 diff --git a/extra/tools/deploy/test/4/deploy.factor b/extra/tools/deploy/test/4/deploy.factor new file mode 100644 index 0000000000..5250ad698a --- /dev/null +++ b/extra/tools/deploy/test/4/deploy.factor @@ -0,0 +1,15 @@ +USING: tools.deploy.config ; +H{ + { deploy-math? f } + { deploy-ui? f } + { deploy-compiler? t } + { deploy-word-props? f } + { deploy-word-defs? f } + { deploy-io 2 } + { deploy-name "tools.deploy.test.4" } + { deploy-c-types? f } + { deploy-random? f } + { "stop-after-last-window?" t } + { deploy-threads? t } + { deploy-reflection 1 } +} From ce8c3cd38907ddcc248aaa33d10ef0a612d0c2c3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 18 Jun 2008 22:30:54 -0500 Subject: [PATCH 0305/1850] Clean up UI a bit --- extra/boids/ui/ui.factor | 8 ++--- extra/gesture-logger/gesture-logger.factor | 6 ++-- extra/lsys/ui/ui.factor | 6 ++-- extra/ui/gadgets/buttons/buttons.factor | 29 +++++++++--------- extra/ui/gadgets/canvas/canvas.factor | 2 +- extra/ui/gadgets/labelled/labelled.factor | 2 +- extra/ui/gadgets/labels/labels.factor | 28 ++++++++--------- extra/ui/gadgets/lists/lists.factor | 15 +++++----- extra/ui/gadgets/menus/menus.factor | 6 ++-- extra/ui/gadgets/panes/panes.factor | 30 ++++++++----------- extra/ui/gadgets/scrollers/scrollers.factor | 2 +- extra/ui/gadgets/sliders/sliders.factor | 13 ++++---- extra/ui/gadgets/status-bar/status-bar.factor | 10 +++---- extra/ui/gadgets/theme/theme.factor | 14 ++++----- 14 files changed, 84 insertions(+), 87 deletions(-) diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor index a1feac381d..0753f4eb06 100755 --- a/extra/boids/ui/ui.factor +++ b/extra/boids/ui/ui.factor @@ -104,11 +104,11 @@ VARS: population-label cohesion-label alignment-label separation-label ; C[ [ run ] in-thread ] slate> set-slate-graft C[ loop off ] slate> set-slate-ungraft - ""
@@ -29,6 +29,6 @@ - Delete + Delete diff --git a/extra/webapps/planet/new-blog.xml b/extra/webapps/planet/new-blog.xml index 4a9638da03..6f75addda5 100644 --- a/extra/webapps/planet/new-blog.xml +++ b/extra/webapps/planet/new-blog.xml @@ -4,7 +4,7 @@ Edit Blog - +
diff --git a/extra/webapps/planet/planet-common.xml b/extra/webapps/planet/planet-common.xml index 6c0affd17f..f4e390056a 100644 --- a/extra/webapps/planet/planet-common.xml +++ b/extra/webapps/planet/planet-common.xml @@ -5,9 +5,9 @@
From f485c63f22cb1f21eaee5b7ed39d11b203e5a86b Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Tue, 8 Jul 2008 20:32:34 +0100 Subject: [PATCH 0547/1850] fixed to use new-style accessor for word-name --- extra/wordtimer/wordtimer.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/wordtimer/wordtimer.factor b/extra/wordtimer/wordtimer.factor index 1ce5f13a81..e9ed0c8cf0 100644 --- a/extra/wordtimer/wordtimer.factor +++ b/extra/wordtimer/wordtimer.factor @@ -1,4 +1,4 @@ -USING: kernel sequences namespaces math assocs words arrays tools.annotations vocabs sorting prettyprint io micros math.statistics ; +USING: kernel sequences namespaces math assocs words arrays tools.annotations vocabs sorting prettyprint io micros math.statistics accessors ; IN: wordtimer SYMBOL: *wordtimes* @@ -15,7 +15,7 @@ SYMBOL: *calling* rot [ + ] curry [ 1+ ] bi* ; : register-time ( utime word -- ) - word-name + name>> [ lookup-word-time update-times 2array ] keep *wordtimes* get-global set-at ; : calling ( word -- ) From 8e24fb9e051e69af1a88edb476605273df84ab9e Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Tue, 8 Jul 2008 20:50:49 +0100 Subject: [PATCH 0548/1850] Added doc for profile-vocab --- extra/wordtimer/wordtimer-docs.factor | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/extra/wordtimer/wordtimer-docs.factor b/extra/wordtimer/wordtimer-docs.factor index 7d9de34252..47b85bb007 100644 --- a/extra/wordtimer/wordtimer-docs.factor +++ b/extra/wordtimer/wordtimer-docs.factor @@ -27,8 +27,15 @@ HELP: print-word-timings HELP: correct-for-timing-overhead { $description "attempts to correct the timings to take into account the overhead of the timing function. This is pretty error-prone but can be handy when you're timing words that only take a handful of milliseconds but are called a lot" } ; + +HELP: profile-vocab +{ $values { "vocabspec" "string name of a vocab" } + { "quot" "a quotation to run" } } +{ $description "Annotates the words in the vocab with timing code then runs the quotation. Finally resets the words and prints the timings information." +} ; + ARTICLE: "wordtimer" "Word Timer" -"The " { $vocab-link "wordtimer" } " vocabulary measures accumulated execution time for words. You first annotate individual words with the " { $link add-timer } " word or whole vocabularies with " { $link add-timers } ". Then you reset the clock with " { $link reset-word-timer } " and execute your code. Finally you can view the timings with " { $link print-word-timings } ". If you have functions that are quick and called often you may want to " { $link correct-for-timing-overhead } ". To remove all the annotations in the vocab you can use " { $link reset-vocab } "." ; +"The " { $vocab-link "wordtimer" } " vocabulary measures accumulated execution time for words. If you just want to profile the accumulated time taken by all words in a vocab you can use " { $vocab-link "profile-vocab" } ". If you need more fine grained control then do the following: First annotate individual words with the " { $link add-timer } " word or whole vocabularies with " { $link add-timers } ". Then reset the clock with " { $link reset-word-timer } " and execute your code. Finally you can view the timings with " { $link print-word-timings } ". If you have functions that are quick and called often you may want to " { $link correct-for-timing-overhead } ". To remove all the annotations in the vocab you can use " { $link reset-vocab } ". Alternatively if you just want to time the contents of a vocabulary you can use profile-vocab." ; ABOUT: "wordtimer" From 3e43c69918aa1c1f6b93359a4593011532d90901 Mon Sep 17 00:00:00 2001 From: Alfredo Beaumont Date: Tue, 8 Jul 2008 21:57:37 +0200 Subject: [PATCH 0549/1850] Fix examples' code and make them unchecked since they have side effects --- extra/ctags/ctags-docs.factor | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/extra/ctags/ctags-docs.factor b/extra/ctags/ctags-docs.factor index 9d98cae0b3..22d811ad3f 100644 --- a/extra/ctags/ctags-docs.factor +++ b/extra/ctags/ctags-docs.factor @@ -12,9 +12,9 @@ HELP: ctags ( path -- ) { $values { "path" "a pathname string" } } { $description "Generates a index file in ctags format and stores in " { $snippet "path" } "." } { $examples - { $example + { $unchecked-example "USING: ctags ;" - "\"tags\" ctags-write" + "\"tags\" ctags" "" } } ; @@ -24,7 +24,7 @@ HELP: ctags-write ( seq path -- ) { "path" "a pathname string" } } { $description "Stores a " { $snippet "alist" } " in " { $snippet "path" } ". " { $snippet "alist" } " must be an association list with ctags format: key must be a valid word and value a sequence whose first element is a resource name and second element is a line number" } { $examples - { $example + { $unchecked-example "USING: kernel ctags ;" "{ { if { \"resource:extra/unix/unix.factor\" 91 } } } \"tags\" ctags-write" "" @@ -38,9 +38,9 @@ HELP: ctag-strings ( alist -- seq ) { "seq" sequence } } { $description "Converts an " { $snippet "alist" } " with ctag format (a word as key and a sequence whose first element is a resource name and a second element is a line number as value) in a " { $snippet "seq" } " of ctag strings." } { $examples - { $example - "USING: kernel ctags ;" - "{ { if { \"resource:extra/unix/unix.factor\" 91 } } } ctag-strings" + { $unchecked-example + "USING: kernel ctags prettyprint ;" + "{ { if { \"resource:extra/unix/unix.factor\" 91 } } } ctag-strings ." "{ \"if\\t/path/to/factor/extra/unix/unix.factor\\t91\" }" } } ; @@ -50,8 +50,8 @@ HELP: ctag ( seq -- str ) { "str" string } } { $description "Outputs a string " { $snippet "str" } " in ctag format for sequence with two elements, first one must be a valid word and second one a sequence whose first element is a resource name and second element is a line number" } { $examples - { $example - "USING: kernel ctags ;" + { $unchecked-example + "USING: kernel ctags prettyprint ;" "{ if { \"resource:extra/unix/unix.factor\" 91 } } ctag ." "\"if\\t/path/to/factor/extra/unix/unix.factor\\t91\"" } From 3929c1239228e34425301acc8be03bfd2e173f1f Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Jul 2008 15:22:03 -0500 Subject: [PATCH 0550/1850] Add failing unit test for string encoding --- extra/db/tuples/tuples-tests.factor | 31 ++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/extra/db/tuples/tuples-tests.factor b/extra/db/tuples/tuples-tests.factor index 36e84187eb..2edf7552cb 100755 --- a/extra/db/tuples/tuples-tests.factor +++ b/extra/db/tuples/tuples-tests.factor @@ -4,7 +4,7 @@ USING: io.files 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.bitfields.lib -math.ranges strings sequences.lib urls ; +math.ranges strings sequences.lib urls fry ; IN: db.tuples.tests TUPLE: person the-id the-name the-number the-real @@ -201,10 +201,10 @@ TUPLE: annotation n paste-id summary author mode contents ; ! ] with-db : test-sqlite ( quot -- ) - >r "tuples-test.db" temp-file sqlite-db r> with-db ; + [ ] swap '[ "tuples-test.db" temp-file sqlite-db , with-db ] unit-test ; : test-postgresql ( quot -- ) - >r { "localhost" "postgres" "foob" "factor-test" } postgresql-db r> with-db ; + [ ] swap '[ { "localhost" "postgres" "foob" "factor-test" } postgresql-db , with-db ] unit-test ; : test-repeated-insert [ ] [ person ensure-table ] unit-test @@ -463,6 +463,31 @@ fubbclass "FUBCLASS" { } define-persistent [ t ] [ fubbclass new select-tuples [ fubbclass? ] all? ] unit-test ; [ test-db-inheritance ] test-sqlite +[ test-db-inheritance ] test-postgresql + + +TUPLE: string-encoding-test id string ; + +string-encoding-test "STRING_ENCODING_TEST" { + { "id" "ID" +db-assigned-id+ } + { "string" "STRING" TEXT } +} define-persistent + +: test-string-encoding ( -- ) + [ ] [ string-encoding-test ensure-table ] unit-test + + [ ] [ + string-encoding-test new + "\u{copyright-sign}\u{bengali-letter-cha}" >>string + [ insert-tuple ] [ id>> "id" set ] bi + ] unit-test + + [ "\u{copyright-sign}\u{bengali-letter-cha}" ] [ + string-encoding-test new "id" get >>id select-tuple string>> + ] unit-test ; + +[ test-string-encoding ] test-sqlite +[ test-string-encoding ] test-postgresql ! Don't comment these out. These words must infer \ bind-tuple must-infer From 7248af54cc88cfd7b2a35cf9a1a203fe9adf6d3d Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Jul 2008 15:22:44 -0500 Subject: [PATCH 0551/1850] Update for planet rename --- extra/websites/concatenative/concatenative.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor index 6d65f10783..211dcb3c11 100644 --- a/extra/websites/concatenative/concatenative.factor +++ b/extra/websites/concatenative/concatenative.factor @@ -48,7 +48,7 @@ TUPLE: factor-website < dispatcher ; "blogs" add-responder "todo" add-responder "pastebin" add-responder - "planet" add-responder + "planet" add-responder "wiki" add-responder "wee-url" add-responder "user-admin" add-responder From 6ad09779cc3e20a33aa2d527606d62eb2e82f410 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Jul 2008 15:46:52 -0500 Subject: [PATCH 0552/1850] Literal aliens in source files are bade bad --- extra/db/pools/pools-tests.factor | 16 +++++++++++++++- extra/io/pools/pools.factor | 2 +- extra/windows/user32/user32.factor | 8 ++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/extra/db/pools/pools-tests.factor b/extra/db/pools/pools-tests.factor index f0534a1d34..34e072c3a5 100644 --- a/extra/db/pools/pools-tests.factor +++ b/extra/db/pools/pools-tests.factor @@ -1,8 +1,22 @@ IN: db.pools.tests -USING: db.pools tools.test ; +USING: db.pools tools.test continuations io.files namespaces +accessors kernel math destructors ; \ must-infer { 2 0 } [ [ ] with-db-pool ] must-infer-as { 1 0 } [ [ ] with-pooled-db ] must-infer-as + +! Test behavior after image save/load +USE: db.sqlite + +[ "pool-test.db" temp-file delete-file ] ignore-errors + +[ ] [ "pool-test.db" sqlite-db "pool" set ] unit-test + +[ ] [ "pool" get expired>> t >>expired drop ] unit-test + +[ ] [ 1000 [ "pool" get [ ] with-pooled-db ] times ] unit-test + +[ ] [ "pool" get dispose ] unit-test diff --git a/extra/io/pools/pools.factor b/extra/io/pools/pools.factor index 0e37e41a76..aa734e6809 100644 --- a/extra/io/pools/pools.factor +++ b/extra/io/pools/pools.factor @@ -9,7 +9,7 @@ TUPLE: pool connections disposed expired ; : check-pool ( pool -- ) dup check-disposed dup expired>> expired? [ - ALIEN: 31337 >>expired + 31337 >>expired connections>> delete-all ] [ drop ] if ; diff --git a/extra/windows/user32/user32.factor b/extra/windows/user32/user32.factor index 1c1df52da8..241eddf9f0 100755 --- a/extra/windows/user32/user32.factor +++ b/extra/windows/user32/user32.factor @@ -1285,10 +1285,10 @@ FUNCTION: void SetLastErrorEx ( DWORD dwErrCode, DWORD dwType ) ; ! FUNCTION: SetWindowPlacement FUNCTION: BOOL SetWindowPos ( HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags ) ; -: HWND_BOTTOM ALIEN: 1 ; -: HWND_NOTOPMOST ALIEN: -2 ; -: HWND_TOP ALIEN: 0 ; -: HWND_TOPMOST ALIEN: -1 ; +: HWND_BOTTOM ( -- alien ) 1 ; +: HWND_NOTOPMOST ( -- alien ) -2 ; +: HWND_TOP ( -- alien ) 0 ; +: HWND_TOPMOST ( -- alien ) -1 ; ! FUNCTION: SetWindowRgn ! FUNCTION: SetWindowsHookA From 3b2f4d92d2c11e409fe12bae6246a4bf67486e00 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Jul 2008 15:50:12 -0500 Subject: [PATCH 0553/1850] Check if the handle has been disposed. This can happen if we close one end of a duplex stream --- extra/io/unix/backend/backend.factor | 7 +++++-- extra/io/windows/files/files.factor | 1 + extra/io/windows/nt/backend/backend.factor | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/extra/io/unix/backend/backend.factor b/extra/io/unix/backend/backend.factor index 165747084e..b984b1f156 100755 --- a/extra/io/unix/backend/backend.factor +++ b/extra/io/unix/backend/backend.factor @@ -125,7 +125,8 @@ M: fd refill } cond ; M: unix (wait-to-read) ( port -- ) - dup dup handle>> refill dup + dup + dup handle>> dup check-disposed refill dup [ dupd wait-for-port (wait-to-read) ] [ 2drop ] if ; ! Writers @@ -144,7 +145,9 @@ M: fd drain } cond ; M: unix (wait-to-write) ( port -- ) - dup dup handle>> drain dup [ wait-for-port ] [ 2drop ] if ; + dup + dup handle>> dup check-disposed drain + dup [ wait-for-port ] [ 2drop ] if ; M: unix io-multiplex ( ms/f -- ) mx get-global wait-for-events ; diff --git a/extra/io/windows/files/files.factor b/extra/io/windows/files/files.factor index 419509f124..e25be71872 100755 --- a/extra/io/windows/files/files.factor +++ b/extra/io/windows/files/files.factor @@ -61,6 +61,7 @@ C: FileArgs : make-FileArgs ( port -- ) { + [ handle>> check-disposed ] [ handle>> handle>> ] [ buffer>> ] [ buffer>> buffer-length ] diff --git a/extra/io/windows/nt/backend/backend.factor b/extra/io/windows/nt/backend/backend.factor index 786275c736..e9df2ddab9 100755 --- a/extra/io/windows/nt/backend/backend.factor +++ b/extra/io/windows/nt/backend/backend.factor @@ -74,7 +74,7 @@ M: winnt add-completion ( win32-handle -- ) ] if ; M: win32-handle cancel-operation - handle>> CancelIo drop ; + [ check-disposed ] [ handle>> CancelIo drop ] bi ; M: winnt io-multiplex ( ms -- ) handle-overlapped [ 0 io-multiplex ] when ; From 75338b577cb39d836b0da548f6f1d08f9f08daf9 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Jul 2008 15:50:38 -0500 Subject: [PATCH 0554/1850] Rename from-now to hence --- extra/alarms/alarms-docs.factor | 2 +- extra/alarms/alarms.factor | 4 ++-- extra/calendar/calendar.factor | 4 ++-- extra/furnace/auth/login/login.factor | 3 +-- extra/furnace/cache/cache.factor | 4 ++-- extra/furnace/sessions/sessions.factor | 1 - extra/tetris/tetris.factor | 2 +- extra/ui/gestures/gestures.factor | 2 +- 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/extra/alarms/alarms-docs.factor b/extra/alarms/alarms-docs.factor index b25df236c9..f07a8b9a2d 100755 --- a/extra/alarms/alarms-docs.factor +++ b/extra/alarms/alarms-docs.factor @@ -10,7 +10,7 @@ HELP: add-alarm HELP: later { $values { "quot" quotation } { "dt" duration } { "alarm" alarm } } -{ $description "Creates and registers an alarm which calls the quotation once at " { $snippet "time" } { $link from-now } "." } ; +{ $description "Creates and registers an alarm which calls the quotation once at " { $snippet "time" } " from now." } ; HELP: cancel-alarm { $values { "alarm" alarm } } diff --git a/extra/alarms/alarms.factor b/extra/alarms/alarms.factor index ddc1d34121..a72960f20f 100755 --- a/extra/alarms/alarms.factor +++ b/extra/alarms/alarms.factor @@ -82,10 +82,10 @@ PRIVATE> [ register-alarm ] keep ; : later ( quot dt -- alarm ) - from-now f add-alarm ; + hence f add-alarm ; : every ( quot dt -- alarm ) - [ from-now ] keep add-alarm ; + [ hence ] keep add-alarm ; : cancel-alarm ( alarm -- ) alarm-entry [ alarms get-global heap-delete ] if-box? ; diff --git a/extra/calendar/calendar.factor b/extra/calendar/calendar.factor index e7b0b6f43a..0abc00b4a4 100755 --- a/extra/calendar/calendar.factor +++ b/extra/calendar/calendar.factor @@ -284,7 +284,7 @@ MEMO: unix-1970 ( -- timestamp ) : now ( -- timestamp ) gmt >local-time ; -: from-now ( dt -- timestamp ) now swap time+ ; +: hence ( dt -- timestamp ) now swap time+ ; : ago ( dt -- timestamp ) now swap time- ; : day-counts { 0 31 28 31 30 31 30 31 31 30 31 30 31 } ; inline @@ -357,7 +357,7 @@ M: timestamp days-in-year ( timestamp -- n ) year>> days-in-year ; M: timestamp sleep-until timestamp>millis sleep-until ; -M: duration sleep from-now sleep-until ; +M: duration sleep hence sleep-until ; { { [ os unix? ] [ "calendar.unix" ] } diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 68161382c1..ce533bce64 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -40,10 +40,9 @@ M: login-realm modify-form ( responder -- ) permit-id get realm get name>> permit-id-key "$login-realm" resolve-base-path >>path realm get - [ timeout>> from-now >>expires ] [ domain>> >>domain ] [ secure>> >>secure ] - tri ; + bi ; : put-permit-cookie ( response -- response' ) put-cookie ; diff --git a/extra/furnace/cache/cache.factor b/extra/furnace/cache/cache.factor index a614a52548..68786a55ab 100644 --- a/extra/furnace/cache/cache.factor +++ b/extra/furnace/cache/cache.factor @@ -31,6 +31,6 @@ TUPLE: server-state-manager < filter-responder timeout ; new swap >>responder 20 minutes >>timeout ; inline - + : touch-state ( state manager -- ) - timeout>> from-now >>expires drop ; + timeout>> hence >>expires drop ; diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 0ec9648a67..5590a9e55e 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -116,7 +116,6 @@ M: session-saver dispose : ( -- cookie ) session get id>> session-id-key "$sessions" resolve-base-path >>path - sessions get timeout>> from-now >>expires sessions get domain>> >>domain ; : put-session-cookie ( response -- response' ) diff --git a/extra/tetris/tetris.factor b/extra/tetris/tetris.factor index 02f8f240d2..c2f874598c 100644 --- a/extra/tetris/tetris.factor +++ b/extra/tetris/tetris.factor @@ -45,7 +45,7 @@ tetris-gadget H{ dup tetris-gadget-tetris maybe-update relayout-1 ; M: tetris-gadget graft* ( gadget -- ) - dup [ tick ] curry 100 milliseconds from-now 100 milliseconds add-alarm + dup [ tick ] curry 100 milliseconds every swap set-tetris-gadget-alarm ; M: tetris-gadget ungraft* ( gadget -- ) diff --git a/extra/ui/gestures/gestures.factor b/extra/ui/gestures/gestures.factor index 88bc2bcee7..5c00fbfdb0 100755 --- a/extra/ui/gestures/gestures.factor +++ b/extra/ui/gestures/gestures.factor @@ -121,7 +121,7 @@ SYMBOL: drag-timer : start-drag-timer ( -- ) hand-buttons get-global empty? [ [ drag-gesture ] - 300 milliseconds from-now + 300 milliseconds hence 100 milliseconds add-alarm drag-timer get-global >box ] when ; From 7c76046d3b65654306c08a7d0d539ea3e04d5bfd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Jul 2008 16:15:51 -0500 Subject: [PATCH 0555/1850] Minor Wiki improvements --- extra/webapps/planet/mini-planet.xml | 14 ----- extra/webapps/wiki/initial-content/Farkup.txt | 63 +++++++++++++++++++ .../wiki/initial-content/Front Page.txt | 5 ++ extra/webapps/wiki/wiki-common.xml | 11 ++++ extra/webapps/wiki/wiki.factor | 29 +++++++-- .../concatenative/concatenative.factor | 2 +- 6 files changed, 105 insertions(+), 19 deletions(-) delete mode 100644 extra/webapps/planet/mini-planet.xml create mode 100644 extra/webapps/wiki/initial-content/Farkup.txt create mode 100644 extra/webapps/wiki/initial-content/Front Page.txt diff --git a/extra/webapps/planet/mini-planet.xml b/extra/webapps/planet/mini-planet.xml deleted file mode 100644 index 661c2dc0f7..0000000000 --- a/extra/webapps/planet/mini-planet.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - -

-
- Read More... -

- -
- -
diff --git a/extra/webapps/wiki/initial-content/Farkup.txt b/extra/webapps/wiki/initial-content/Farkup.txt new file mode 100644 index 0000000000..8814af6c0a --- /dev/null +++ b/extra/webapps/wiki/initial-content/Farkup.txt @@ -0,0 +1,63 @@ +Look at the source to this page by clicking *Edit* to compare the farkup language with resulting output. + += level 1 heading = + +== level 2 heading == + +=== level 3 heading === + +==== level 4 heading ==== + +Here is a paragraph of text, with _emphasized_ and *strong* text, together with an inline %code snippet%. Did you know that E=mc^2^, and L~2~ spaces are cool? Of course, if you want to include \_ special \* characters \^ you \~ can \% do that, too. + +You can make [[Wiki Links]] just like that, as well as links to external sites: [[http://sbcl.sourceforge.net]]. [[Factor|Custom link text]] can be used [[http://www.apple.com|with both types of links]]. + +Images can be embedded in the text: + +[[image:http://factorcode.org/graphics/logo.png]] + +- a list +- with three +- items + +|a table|with|four|columns| +|and|two|rows|...| + +Here is some code: + +[{HAI +CAN HAS STDIO? +VISIBLE "HAI WORLD!" +KTHXBYE}] + +There is syntax highlighting various languages, too: + +[factor{PEG: parse-request-line ( string -- triple ) + #! Triple is { method url version } + [ + 'space' , + 'http-method' , + 'space' , + 'url' , + 'space' , + 'http-version' , + 'space' , + ] seq* just ;}] + +Some Java: + +[java{/** + * Returns the extension of the specified filename, or an empty + * string if there is none. + * @param path The path + */ +public static String getFileExtension(String path) +{ + int fsIndex = getLastSeparatorIndex(path); + int index = path.lastIndexOf('.'); + // there could be a dot in the path and no file extension + if(index == -1 || index < fsIndex ) + return ""; + else + return path.substring(index); +}}] diff --git a/extra/webapps/wiki/initial-content/Front Page.txt b/extra/webapps/wiki/initial-content/Front Page.txt new file mode 100644 index 0000000000..37351eed38 --- /dev/null +++ b/extra/webapps/wiki/initial-content/Front Page.txt @@ -0,0 +1,5 @@ +Congratulations, you are now running your very own Wiki. + +You can now click *Edit* below and begin editing the content of the [[Front Page]]. This Wiki uses [[Farkup]] to mark up text. + +Two special article names are recognized by the Wiki: [[Sidebar]] and [[Footer]]. They do not exist by default, but if you create them, they will be visible on every page. diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml index 0abd36a7cd..5cddcee628 100644 --- a/extra/webapps/wiki/wiki-common.xml +++ b/extra/webapps/wiki/wiki-common.xml @@ -13,6 +13,7 @@ Front Page | All Articles | Recent Changes + | Random Article @@ -45,6 +46,16 @@
+ + + +
+ + + + + +
diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 77ee242668..3c87f3cd49 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel hashtables calendar +USING: accessors kernel hashtables calendar random assocs namespaces splitting sequences sorting math.order present +io.files io.encodings.ascii syndication html.components html.forms http.server @@ -115,6 +116,14 @@ M: revision feed-entry-url id>> revision-url ; { wiki "view" } >>template ; +: ( -- action ) + + [ + article new select-tuples random + [ title>> ] [ "Front Page" ] if* + view-url + ] >>display ; + : amend-article ( revision article -- ) swap id>> >>revision update-tuple ; @@ -286,15 +295,15 @@ M: revision feed-entry-url id>> revision-url ; { wiki "page-common" } >>template ; : init-sidebar ( -- ) - "Sidebar" latest-revision [ - "sidebar" [ from-object ] nest-form - ] when* ; + "Sidebar" latest-revision [ "sidebar" [ from-object ] nest-form ] when* + "Footer" latest-revision [ "footer" [ from-object ] nest-form ] when* ; : ( -- dispatcher ) wiki new-dispatcher "" add-responder "view" add-responder "revision" add-responder + "random" add-responder "revisions" add-responder "revisions.atom" add-responder "diff" add-responder @@ -309,3 +318,15 @@ M: revision feed-entry-url id>> revision-url ; [ init-sidebar ] >>init { wiki "wiki-common" } >>template ; + +: init-wiki ( -- ) + "resource:extra/webapps/wiki/initial-content" directory* keys + [ + [ ascii file-contents ] [ file-name "." split1 drop ] bi + f + swap >>title + swap >>content + "slava" >>author + now >>date + add-revision + ] each ; diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor index 211dcb3c11..1ae7f63a27 100644 --- a/extra/websites/concatenative/concatenative.factor +++ b/extra/websites/concatenative/concatenative.factor @@ -25,7 +25,7 @@ webapps.wee-url webapps.user-admin ; IN: websites.concatenative -: test-db ( -- db params ) "resource:test.db" sqlite-db ; +: test-db ( -- params db ) "resource:test.db" sqlite-db ; : init-factor-db ( -- ) test-db [ From 1a32ffafa389a9769e7d96ce1f7e599247fef280 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Tue, 8 Jul 2008 22:58:34 -0500 Subject: [PATCH 0556/1850] bake: work with strings --- extra/bake/bake.factor | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extra/bake/bake.factor b/extra/bake/bake.factor index 4ce7bfb586..bcb7c2238f 100644 --- a/extra/bake/bake.factor +++ b/extra/bake/bake.factor @@ -1,6 +1,6 @@ USING: kernel parser namespaces sequences quotations arrays vectors splitting - words math + strings words math macros arrays.lib combinators.lib combinators.conditional newfx ; IN: bake @@ -20,7 +20,9 @@ DEFER: [bake] : broil-element ( obj -- quot ) { { [ comma? ] [ drop [ >r ] ] } + { [ f = ] [ [ >r ] prefix-on ] } { [ integer? ] [ [ >r ] prefix-on ] } + { [ string? ] [ [ >r ] prefix-on ] } { [ sequence? ] [ [bake] [ >r ] append ] } { [ word? ] [ literalize [ >r ] prefix-on ] } { [ drop t ] [ [ >r ] prefix-on ] } From 2c8866c1394621df946af41da99e8802a1c89632 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Tue, 8 Jul 2008 23:08:12 -0500 Subject: [PATCH 0557/1850] documents: move from delegation to inheritance --- extra/documents/documents.factor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extra/documents/documents.factor b/extra/documents/documents.factor index 9e4802c2ef..d046102ec9 100755 --- a/extra/documents/documents.factor +++ b/extra/documents/documents.factor @@ -15,11 +15,11 @@ IN: documents : lines-equal? ( loc1 loc2 -- ? ) [ first ] bi@ number= ; -TUPLE: document locs ; +TUPLE: document < model locs ; : ( -- document ) - V{ "" } clone V{ } clone - { set-delegate set-document-locs } document construct ; + V{ "" } clone document new-model + V{ } clone >>locs ; : add-loc ( loc document -- ) locs>> push ; From d4aae8a183dd11847cc1bf663065bb1c408aecde Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Mon, 30 Jun 2008 12:31:21 -0300 Subject: [PATCH 0558/1850] irc.client: Clean a bit. --- extra/irc/client/client-tests.factor | 8 ++++---- extra/irc/client/client.factor | 12 +++--------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor index 24a753d615..f7065664dd 100644 --- a/extra/irc/client/client-tests.factor +++ b/extra/irc/client/client-tests.factor @@ -14,7 +14,7 @@ IN: irc.client.tests swap [ 2nip f ] curry >>connect ; : set-nick ( irc-client nickname -- ) - [ nick>> ] dip >>name drop ; + swap profile>> (>>nickname) ; : with-dummy-client ( quot -- ) rot with-variable ; inline @@ -42,9 +42,9 @@ privmsg new parse-irc-line f >>timestamp ] unit-test { "" } make-client dup "factorbot" set-nick current-irc-client [ - { t } [ irc> nick>> name>> me? ] unit-test + { t } [ irc> profile>> nickname>> me? ] unit-test - { "factorbot" } [ irc> nick>> name>> ] unit-test + { "factorbot" } [ irc> profile>> nickname>> ] unit-test { "someuser" } [ "someuser!n=user@some.where" parse-name ] unit-test @@ -63,7 +63,7 @@ privmsg new ":some.where 001 factorbot :Welcome factorbot" } make-client [ connect-irc ] keep 1 seconds sleep - nick>> name>> ] unit-test + profile>> nickname>> ] unit-test { join_ "#factortest" } [ { ":factorbot!n=factorbo@some.where JOIN :#factortest" diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 5b8fbf62ee..45f2df3bdc 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -14,18 +14,12 @@ SYMBOL: current-irc-client : irc-port 6667 ; ! Default irc port -! "setup" objects TUPLE: irc-profile server port nickname password ; C: irc-profile -! "live" objects -TUPLE: nick name channels log ; -C: nick - -TUPLE: irc-client profile nick stream in-messages out-messages join-messages +TUPLE: irc-client profile stream in-messages out-messages join-messages listeners is-running connect reconnect-time ; : ( profile -- irc-client ) - f V{ } clone V{ } clone f H{ } clone f [ latin1 ] 15 seconds irc-client boa ; @@ -182,7 +176,7 @@ TUPLE: unhandled < irc-message ; ! ====================================== : me? ( string -- ? ) - irc> nick>> name>> = ; + irc> profile>> nickname>> = ; : irc-message-origin ( irc-message -- name ) dup name>> me? [ prefix>> parse-name ] [ name>> ] if ; @@ -196,7 +190,7 @@ M: irc-message handle-incoming-irc ( irc-message -- ) f listener> [ in-messages>> mailbox-put ] [ drop ] if* ; M: logged-in handle-incoming-irc ( logged-in -- ) - name>> irc> nick>> (>>name) ; + name>> irc> profile>> (>>nickname) ; M: ping handle-incoming-irc ( ping -- ) trailing>> /PONG ; From 33fccfe4a4a1ecc9f85d2bf672fe9c3b410e906a Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Tue, 8 Jul 2008 16:57:53 -0300 Subject: [PATCH 0559/1850] irc.client: Add more words, fixes, update docs. --- extra/irc/client/client-docs.factor | 23 ++++++++++++++--- extra/irc/client/client.factor | 38 ++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/extra/irc/client/client-docs.factor b/extra/irc/client/client-docs.factor index 2a66f3a701..a675e663c3 100644 --- a/extra/irc/client/client-docs.factor +++ b/extra/irc/client/client-docs.factor @@ -21,13 +21,25 @@ HELP: connect-irc "Connecting to an irc server" { $description "Connects and logins " { $link irc-client } " using the settings specified on its " { $link irc-profile } "." } ; HELP: add-listener "Listening to irc channels/users/etc" -{ $values { "irc-client" "an irc client object" } { "irc-listener" "an irc listener object" } } +{ $values { "irc-listener" "an irc listener object" } { "irc-client" "an irc client object" } } { $description "Registers " { $snippet "irc-listener" } " with " { $snippet "irc-client" } " and starts listening." } ; +HELP: remove-listener "Stop an unregister listener" +{ $values { "irc-listener" "an irc listener object" } { "irc-client" "an irc client object" } } +{ $description "Unregisters " { $snippet "irc-listener" } " from " { $snippet "irc-client" } " and stops listening. This is how you part from a channel." } ; + HELP: terminate-irc "Terminates an irc client" { $values { "irc-client" "an irc client object" } } { $description "Terminates all activity by " { $link irc-client } " cleaning up resources and notifying listeners." } ; +HELP: write-message "Sends a message through a listener" +{ $values { "message" "a string or irc message object" } { "irc-listener" "an irc listener object" } } +{ $description "Sends " { $snippet "message" } " through " { $snippet "irc-listener" } ". Strings are automatically promoted to privmsg objects." } ; + +HELP: read-message "Reads a message from a listener" +{ $values { "irc-listener" "an irc listener object" } { "message" "an irc message object" } } +{ $description "Reads " { $snippet "message" } " from " { $snippet "irc-listener" } "." } ; + ARTICLE: "irc.client" "IRC Client" "An IRC Client library" { $heading "IRC objects:" } @@ -42,6 +54,9 @@ ARTICLE: "irc.client" "IRC Client" { $subsection connect-irc } { $subsection terminate-irc } { $subsection add-listener } +{ $subsection remove-listener } +{ $subsection read-message } +{ $subsection write-message } { $heading "IRC messages" } "Some of the RFC defined irc messages as objects:" { $table @@ -78,11 +93,11 @@ ARTICLE: "irc.client" "IRC Client" "! Create a channel listener" "\"#mychannel123\" mychannel set" "! Register and start listener (this joins the channel)" - "bot get mychannel get add-listener" + "mychannel get bot get add-listener" "! Send a message to the channel" - "\"what's up?\" mychannel get out-messages>> mailbox-put" + "\"what's up?\" mychannel get write-message" "! Read a message from the channel" - "mychannel get in-messages>> mailbox-get" + "mychannel get read-message" } ; diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 45f2df3bdc..0a627cca1c 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -169,7 +169,8 @@ TUPLE: unhandled < irc-message ; { "KICK" [ \ kick ] } [ drop \ unhandled ] } case - [ [ tuple-slots ] [ parameters>> ] bi append ] dip prefix >tuple ; + [ [ tuple-slots ] [ parameters>> ] bi append ] dip + [ all-slots length head ] keep slots>tuple ; ! ====================================== ! Server message handling @@ -205,6 +206,9 @@ M: join handle-incoming-irc ( join -- ) dup trailing>> listener> [ irc> join-messages>> ] unless* mailbox-put ; +M: part handle-incoming-irc ( part -- ) + dup channel>> to-listener ; + M: kick handle-incoming-irc ( kick -- ) [ ] [ channel>> ] [ who>> ] tri me? [ dup unregister-listener ] when to-listener ; @@ -221,6 +225,9 @@ GENERIC: handle-outgoing-irc ( obj -- ) M: privmsg handle-outgoing-irc ( privmsg -- ) [ name>> ] [ trailing>> ] bi /PRIVMSG ; +M: part handle-outgoing-irc ( privmsg -- ) + [ channel>> ] [ trailing>> "" or ] bi /PART ; + ! ====================================== ! Reader/Writer ! ====================================== @@ -300,6 +307,7 @@ DEFER: (connect-irc) 2bi ; GENERIC: (add-listener) ( irc-listener -- ) + M: irc-channel-listener (add-listener) ( irc-channel-listener -- ) [ [ name>> ] [ password>> ] bi /JOIN ] [ [ [ drop irc> join-messages>> ] @@ -314,19 +322,41 @@ M: irc-nick-listener (add-listener) ( irc-nick-listener -- ) M: irc-server-listener (add-listener) ( irc-server-listener -- ) f swap set+run-listener ; +GENERIC: (remove-listener) ( irc-listener -- ) + +M: irc-nick-listener (remove-listener) ( irc-nick-listener -- ) + name>> unregister-listener ; + +M: irc-channel-listener (remove-listener) ( irc-channel-listener -- ) + [ [ out-messages>> ] [ name>> ] bi + \ part new swap >>channel mailbox-put ] keep + name>> unregister-listener ; + +M: irc-server-listener (remove-listener) ( irc-server-listener -- ) + drop f unregister-listener ; + : (connect-irc) ( irc-client -- ) [ profile>> [ server>> ] [ port>> ] bi /CONNECT ] keep swap >>stream t >>is-running in-messages>> irc-connected swap mailbox-put ; +: with-irc-client ( irc-client quot -- ) + >r current-irc-client r> with-variable ; inline + PRIVATE> : connect-irc ( irc-client -- ) - dup current-irc-client [ + dup [ [ (connect-irc) ] [ profile>> nickname>> /LOGIN ] bi spawn-irc - ] with-variable ; + ] with-irc-client ; : add-listener ( irc-listener irc-client -- ) - current-irc-client rot '[ , (add-listener) ] with-variable ; + swap '[ , (add-listener) ] with-irc-client ; + +: remove-listener ( irc-listener irc-client -- ) + swap '[ , (remove-listener) ] with-irc-client ; + +: write-message ( message irc-listener -- ) out-messages>> mailbox-put ; +: read-message ( irc-listener -- message ) in-messages>> mailbox-get ; From b8d9379b2bc42cef6c7e9910a57bb44a792f73c8 Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Wed, 9 Jul 2008 12:22:07 -0500 Subject: [PATCH 0560/1850] bake and bake.fry: `[ == bake quotation '[ == fry quotation --- extra/bake/bake.factor | 3 ++- extra/bake/fry/fry-tests.factor | 42 ++++++++++++++++----------------- extra/bake/fry/fry.factor | 2 +- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/extra/bake/bake.factor b/extra/bake/bake.factor index 0834c84c9a..748a811b34 100644 --- a/extra/bake/bake.factor +++ b/extra/bake/bake.factor @@ -92,5 +92,6 @@ MACRO: bake ( seq -- quot ) [bake] ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: `{ \ } [ >array ] parse-literal \ bake parsed ; parsing +: `{ \ } [ >array ] parse-literal \ bake parsed ; parsing : `V{ \ } [ >vector ] parse-literal \ bake parsed ; parsing +: `[ \ } [ >quotation ] parse-literal \ bake parsed ; parsing \ No newline at end of file diff --git a/extra/bake/fry/fry-tests.factor b/extra/bake/fry/fry-tests.factor index 13202a78f5..74408dc9f9 100755 --- a/extra/bake/fry/fry-tests.factor +++ b/extra/bake/fry/fry-tests.factor @@ -13,74 +13,74 @@ IN: bake.fry.tests ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -[ [ 3 + ] ] [ 3 `[ , + ] ] unit-test +[ [ 3 + ] ] [ 3 '[ , + ] ] unit-test -[ [ 1 3 + ] ] [ 1 3 `[ , , + ] ] unit-test +[ [ 1 3 + ] ] [ 1 3 '[ , , + ] ] unit-test -[ [ 1 + ] ] [ 1 [ + ] `[ , @ ] ] unit-test +[ [ 1 + ] ] [ 1 [ + ] '[ , @ ] ] unit-test -[ [ 1 + . ] ] [ 1 [ + ] `[ , @ . ] ] unit-test +[ [ 1 + . ] ] [ 1 [ + ] '[ , @ . ] ] unit-test -[ [ + - ] ] [ [ + ] [ - ] `[ @ @ ] ] unit-test +[ [ + - ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test [ [ "a" write "b" print ] ] -[ "a" "b" `[ , write , print ] ] unit-test +[ "a" "b" '[ , write , print ] ] unit-test [ [ 1 2 + 3 4 - ] ] -[ [ + ] [ - ] `[ 1 2 @ 3 4 @ ] ] unit-test +[ [ + ] [ - ] '[ 1 2 @ 3 4 @ ] ] unit-test [ 1/2 ] [ - 1 `[ , _ / ] 2 swap call + 1 '[ , _ / ] 2 swap call ] unit-test [ { { 1 "a" "A" } { 1 "b" "B" } { 1 "c" "C" } } ] [ - 1 `[ , _ _ 3array ] + 1 '[ , _ _ 3array ] { "a" "b" "c" } { "A" "B" "C" } rot 2map ] unit-test [ { { 1 "a" } { 1 "b" } { 1 "c" } } ] [ - `[ 1 _ 2array ] + '[ 1 _ 2array ] { "a" "b" "c" } swap map ] unit-test [ 1 2 ] [ - 1 2 `[ _ , ] call + 1 2 '[ _ , ] call ] unit-test [ { { 1 "a" 2 } { 1 "b" 2 } { 1 "c" 2 } } ] [ - 1 2 `[ , _ , 3array ] + 1 2 '[ , _ , 3array ] { "a" "b" "c" } swap map ] unit-test -: funny-dip `[ @ _ ] call ; inline +: funny-dip '[ @ _ ] call ; inline [ "hi" 3 ] [ "h" "i" 3 [ append ] funny-dip ] unit-test [ { 1 2 3 } ] [ - 3 1 `[ , [ , + ] map ] call + 3 1 '[ , [ , + ] map ] call ] unit-test [ { 1 { 2 { 3 } } } ] [ - 1 2 3 `[ , [ , [ , 1array ] call 2array ] call 2array ] call + 1 2 3 '[ , [ , [ , 1array ] call 2array ] call 2array ] call ] unit-test -{ 1 1 } [ `[ [ [ , ] ] ] ] must-infer-as +{ 1 1 } [ '[ [ [ , ] ] ] ] must-infer-as [ { { { 3 } } } ] [ - 3 `[ [ [ , 1array ] call 1array ] call 1array ] call + 3 '[ [ [ , 1array ] call 1array ] call 1array ] call ] unit-test [ { { { 3 } } } ] [ - 3 `[ [ [ , 1array ] call 1array ] call 1array ] call + 3 '[ [ [ , 1array ] call 1array ] call 1array ] call ] unit-test -! [ 10 20 30 40 `[ , V{ , { , } } , ] ] [ [ 10 V{ 20 { 30 } } 40 ] ] unit-test* +! [ 10 20 30 40 '[ , V{ , { , } } , ] ] [ [ 10 V{ 20 { 30 } } 40 ] ] unit-test* -[ 10 20 30 40 `[ , V{ , { , } } , ] ] +[ 10 20 30 40 '[ , V{ , { , } } , ] ] [ [ 10 20 30 >r r> 1 narray >r >r r> r> 2 narray >vector 40 ] ] unit-test* -[ { 1 2 3 } { 4 5 6 } { 7 8 9 } `[ , { V{ @ } { , } } ] call ] +[ { 1 2 3 } { 4 5 6 } { 7 8 9 } '[ , { V{ @ } { , } } ] call ] [ { 1 2 3 } { V{ 4 5 6 } { { 7 8 9 } } } diff --git a/extra/bake/fry/fry.factor b/extra/bake/fry/fry.factor index 6b069334e6..b9f9882e88 100644 --- a/extra/bake/fry/fry.factor +++ b/extra/bake/fry/fry.factor @@ -77,4 +77,4 @@ DEFER: shallow-fry MACRO: fry ( seq -- quot ) [fry] ; -: `[ \ ] [ >quotation ] parse-literal \ fry parsed ; parsing \ No newline at end of file +: '[ \ ] [ >quotation ] parse-literal \ fry parsed ; parsing \ No newline at end of file From 4b0dc8747a57f4442a95fcba8bf38d8700bd8a77 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Wed, 9 Jul 2008 18:17:19 -0300 Subject: [PATCH 0561/1850] irc.client: Fix "part" messages --- extra/irc/client/client.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 0a627cca1c..5d80b0648f 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -52,7 +52,7 @@ TUPLE: irc-message line prefix command parameters trailing timestamp ; TUPLE: logged-in < irc-message name ; TUPLE: ping < irc-message ; TUPLE: join < irc-message ; -TUPLE: part < irc-message name channel ; +TUPLE: part < irc-message channel ; TUPLE: quit < irc-message ; TUPLE: privmsg < irc-message name ; TUPLE: kick < irc-message channel who ; From 294c301877478268e6efa27768a39d26bf4c39f9 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 16:34:05 -0500 Subject: [PATCH 0562/1850] Logging no longer uses parser combinators --- extra/logging/analysis/analysis.factor | 8 +++- extra/logging/insomniac/insomniac.factor | 12 ++---- extra/logging/parser/parser.factor | 53 +++++++++++++++--------- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/extra/logging/analysis/analysis.factor b/extra/logging/analysis/analysis.factor index a074ccd1b9..8f7f79d81e 100755 --- a/extra/logging/analysis/analysis.factor +++ b/extra/logging/analysis/analysis.factor @@ -1,8 +1,9 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences namespaces words assocs logging sorting -prettyprint io io.styles strings logging.parser calendar.format -combinators ; +prettyprint io io.styles io.files io.encodings.utf8 +strings combinators +logging.server logging.parser calendar.format ; IN: logging.analysis SYMBOL: word-names @@ -69,3 +70,6 @@ SYMBOL: message-histogram : analyze-log ( lines word-names -- ) >r parse-log r> analyze-entries analysis. ; + +: analyze-log-file ( service word-names -- ) + >r parse-log-file r> analyze-entries analysis. ; diff --git a/extra/logging/insomniac/insomniac.factor b/extra/logging/insomniac/insomniac.factor index c7d1faf42e..7810a4afad 100755 --- a/extra/logging/insomniac/insomniac.factor +++ b/extra/logging/insomniac/insomniac.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: logging.analysis logging.server logging smtp kernel io.files io.streams.string namespaces alarms assocs -io.encodings.utf8 accessors calendar qualified ; +io.encodings.utf8 accessors calendar sequences qualified ; QUALIFIED: io.sockets IN: logging.insomniac @@ -10,11 +10,7 @@ SYMBOL: insomniac-sender SYMBOL: insomniac-recipients : ?analyze-log ( service word-names -- string/f ) - >r log-path 1 log# dup exists? [ - utf8 file-lines r> [ analyze-log ] with-string-writer - ] [ - r> 2drop f - ] if ; + [ analyze-log-file ] with-string-writer ; : email-subject ( service -- string ) [ @@ -22,14 +18,14 @@ SYMBOL: insomniac-recipients ] "" make ; : (email-log-report) ( service word-names -- ) - dupd ?analyze-log dup [ + dupd ?analyze-log dup empty? [ 2drop ] [ swap >>body insomniac-recipients get >>to insomniac-sender get >>from swap email-subject >>subject send-email - ] [ 2drop ] if ; + ] if ; \ (email-log-report) NOTICE add-error-logging diff --git a/extra/logging/parser/parser.factor b/extra/logging/parser/parser.factor index 7215f29865..9c9161a15d 100755 --- a/extra/logging/parser/parser.factor +++ b/extra/logging/parser/parser.factor @@ -1,12 +1,15 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors parser-combinators memoize kernel sequences -logging arrays words strings vectors io io.files +USING: accessors peg peg.parsers memoize kernel sequences +logging arrays words strings vectors io io.files io.encodings.utf8 namespaces combinators combinators.lib logging.server calendar calendar.format ; IN: logging.parser -: string-of ( quot -- parser ) satisfy [ >string ] <@ ; +TUPLE: log-entry date level word-name message ; + +: string-of ( quot -- parser ) + satisfy repeat0 [ >string ] action ; inline SYMBOL: multiline @@ -14,13 +17,13 @@ SYMBOL: multiline [ "]" member? not ] string-of [ dup multiline-header = [ drop multiline ] [ rfc3339>timestamp ] if - ] <@ + ] action "[" "]" surrounded-by ; : 'log-level' ( -- parser ) log-levels [ - [ name>> token ] keep [ nip ] curry <@ - ] map ; + [ name>> token ] keep [ nip ] curry action + ] map choice ; : 'word-name' ( -- parser ) [ " :" member? not ] string-of ; @@ -28,36 +31,42 @@ SYMBOL: multiline SYMBOL: malformed : 'malformed-line' ( -- parser ) - [ drop t ] string-of [ malformed swap 2array ] <@ ; + [ drop t ] string-of + [ log-entry new swap >>message malformed >>level ] action ; : 'log-message' ( -- parser ) - [ drop t ] string-of [ 1vector ] <@ ; + [ drop t ] string-of + [ 1vector ] action ; -MEMO: 'log-line' ( -- parser ) - 'date' " " token <& - 'log-level' " " token <& <&> - 'word-name' ": " token <& <:&> - 'log-message' <:&> - 'malformed-line' <|> ; +: 'log-line' ( -- parser ) + [ + 'date' , + " " token hide , + 'log-level' , + " " token hide , + 'word-name' , + ": " token hide , + 'log-message' , + ] seq* [ first4 log-entry boa ] action + 'malformed-line' 2choice ; -: parse-log-line ( string -- entry ) - 'log-line' parse-1 ; +PEG: parse-log-line ( string -- entry ) 'log-line' ; : malformed? ( line -- ? ) - first malformed eq? ; + level>> malformed eq? ; : multiline? ( line -- ? ) - first multiline eq? ; + level>> multiline eq? ; : malformed-line ( line -- ) "Warning: malformed log line:" print - second print ; + message>> print ; : add-multiline ( line -- ) building get empty? [ "Warning: log begins with multiline entry" print drop ] [ - fourth first building get peek fourth push + message>> first building get peek message>> push ] if ; : parse-log ( lines -- entries ) @@ -70,3 +79,7 @@ MEMO: 'log-line' ( -- parser ) } cond ] each ] { } make ; + +: parse-log-file ( service -- entries ) + log-path 1 log# dup exists? + [ utf8 file-lines parse-log ] [ drop f ] if ; From 095a3e984c3205830bfda725d8049469e490cadc Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 17:03:16 -0500 Subject: [PATCH 0563/1850] Fix analysis for recent change --- extra/logging/analysis/analysis.factor | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/extra/logging/analysis/analysis.factor b/extra/logging/analysis/analysis.factor index 8f7f79d81e..1e1e31c501 100755 --- a/extra/logging/analysis/analysis.factor +++ b/extra/logging/analysis/analysis.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences namespaces words assocs logging sorting prettyprint io io.styles io.files io.encodings.utf8 -strings combinators +strings combinators accessors arrays logging.server logging.parser calendar.format ; IN: logging.analysis @@ -12,11 +12,11 @@ SYMBOL: word-histogram SYMBOL: message-histogram : analyze-entry ( entry -- ) - dup second ERROR eq? [ dup errors get push ] when - dup second CRITICAL eq? [ dup errors get push ] when - 1 over third word-histogram get at+ - dup third word-names get member? [ - 1 over rest message-histogram get at+ + dup level>> { ERROR CRITICAL } memq? [ dup errors get push ] when + 1 over word-name>> word-histogram get at+ + dup word-name>> word-names get member? [ + 1 over [ level>> ] [ word-name>> ] [ message>> ] tri 3array + message-histogram get at+ ] when drop ; @@ -46,10 +46,10 @@ SYMBOL: message-histogram : log-entry. ( entry -- ) "====== " write { - [ first (timestamp>string) bl ] - [ second pprint bl ] - [ third write nl ] - [ fourth "\n" join print ] + [ date>> (timestamp>string) bl ] + [ level>> pprint bl ] + [ word-name>> write nl ] + [ message>> "\n" join print ] } cleave ; : errors. ( errors -- ) @@ -59,7 +59,7 @@ SYMBOL: message-histogram "==== INTERESTING MESSAGES:" print nl "Total: " write dup values sum . nl [ - dup second write ": " write third "\n" join write + dup level>> write ": " write message>> "\n" join write ] histogram. nl "==== WORDS:" print nl From 874b123bb06759de6aa4910f2b217e1cbca4e75f Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 17:04:20 -0500 Subject: [PATCH 0564/1850] Debugging web framework and cleaning things up --- extra/furnace/actions/actions.factor | 2 +- extra/furnace/asides/asides.factor | 17 ++- extra/furnace/auth/auth.factor | 30 +++-- .../features/edit-profile/edit-profile.factor | 4 +- .../recover-password/recover-password.factor | 2 +- extra/furnace/auth/login/login.factor | 12 +- .../furnace/auth/login/permits/permits.factor | 6 +- extra/furnace/boilerplate/boilerplate.factor | 5 +- extra/furnace/flash/flash.factor | 2 +- extra/furnace/furnace.factor | 2 +- extra/furnace/redirection/redirection.factor | 6 +- extra/furnace/sessions/sessions.factor | 4 +- extra/furnace/syndication/syndication.factor | 2 +- extra/http/http.factor | 7 +- extra/http/parsers/parsers.factor | 2 +- extra/http/server/cgi/cgi.factor | 8 +- .../server/dispatchers/dispatchers.factor | 4 +- .../server/redirection/redirection.factor | 2 +- extra/http/server/server.factor | 9 +- extra/http/server/static/static.factor | 4 +- extra/webapps/blogs/blogs.factor | 12 +- extra/webapps/todo/todo.factor | 2 +- extra/webapps/wiki/changes.xml | 22 ---- extra/webapps/wiki/diff.xml | 2 +- extra/webapps/wiki/edit.xml | 7 +- extra/webapps/wiki/revisions-common.xml | 33 ++++++ extra/webapps/wiki/revisions.xml | 18 --- extra/webapps/wiki/user-edits.xml | 10 -- extra/webapps/wiki/view.xml | 8 +- extra/webapps/wiki/wiki-common.xml | 20 ++-- extra/webapps/wiki/wiki.factor | 106 +++++++++++++----- 31 files changed, 217 insertions(+), 153 deletions(-) create mode 100644 extra/webapps/wiki/revisions-common.xml diff --git a/extra/furnace/actions/actions.factor b/extra/furnace/actions/actions.factor index 4b431c83bc..6448fcdf07 100755 --- a/extra/furnace/actions/actions.factor +++ b/extra/furnace/actions/actions.factor @@ -110,7 +110,7 @@ M: action call-responder* ( path action -- response ) } case ; M: action modify-form - drop request get url>> revalidate-url-key hidden-form-field ; + drop url get revalidate-url-key hidden-form-field ; : check-validation ( -- ) validation-failed? [ validation-failed ] when ; diff --git a/extra/furnace/asides/asides.factor b/extra/furnace/asides/asides.factor index 9f1411188c..6d41c637c6 100644 --- a/extra/furnace/asides/asides.factor +++ b/extra/furnace/asides/asides.factor @@ -1,10 +1,17 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors namespaces sequences arrays kernel -assocs assocs.lib hashtables math.parser urls combinators -html.elements html.templates.chloe.syntax db.types db.tuples -http http.server http.server.filters -furnace furnace.cache furnace.sessions furnace.redirection ; +assocs hashtables math.parser urls combinators +logging db.types db.tuples +html.elements +html.templates.chloe.syntax +http +http.server +http.server.filters +furnace +furnace.cache +furnace.sessions +furnace.redirection ; IN: furnace.asides TUPLE: aside < server-state session method url post-data ; @@ -44,6 +51,8 @@ TUPLE: asides < server-state-manager ; url>> path>> split-path asides get responder>> call-responder ; +\ end-aside-post DEBUG add-input-logging + ERROR: end-aside-in-get-error ; : get-aside ( id -- aside ) diff --git a/extra/furnace/auth/auth.factor b/extra/furnace/auth/auth.factor index ae042f05bd..0c21c9f18d 100755 --- a/extra/furnace/auth/auth.factor +++ b/extra/furnace/auth/auth.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs namespaces kernel sequences sets -destructors combinators fry +destructors combinators fry logging io.encodings.utf8 io.encodings.string io.binary random checksums checksums.sha2 html.forms @@ -18,7 +18,11 @@ IN: furnace.auth SYMBOL: logged-in-user -: logged-in? ( -- ? ) logged-in-user get >boolean ; +: logged-in? ( -- ? ) + logged-in-user get >boolean ; + +: username ( -- string/f ) + logged-in-user get dup [ username>> ] when ; GENERIC: init-user-profile ( responder -- ) @@ -30,9 +34,6 @@ M: dispatcher init-user-profile M: filter-responder init-user-profile responder>> init-user-profile ; -: have-capability? ( capability -- ? ) - logged-in-user get capabilities>> member? ; - : profile ( -- assoc ) logged-in-user get profile>> ; : user-changed ( -- ) @@ -59,6 +60,8 @@ TUPLE: realm < dispatcher name users checksum secure ; GENERIC: login-required* ( realm -- response ) +GENERIC: init-realm ( realm -- ) + GENERIC: logged-in-username ( realm -- username ) : login-required ( -- * ) realm get login-required* exit-with ; @@ -87,9 +90,16 @@ M: user-saver dispose : init-user ( user -- ) [ [ logged-in-user set ] [ save-user-after ] bi ] when* ; +\ init-user DEBUG add-input-logging + M: realm call-responder* ( path responder -- response ) dup realm set - dup logged-in-username dup [ users get-user ] when init-user + logged-in? [ + dup init-realm + dup logged-in-username + dup [ users get-user ] when + init-user + ] unless call-next-method ; : encode-password ( string salt -- bytes ) @@ -122,18 +132,18 @@ TUPLE: protected < filter-responder description capabilities ; protected new swap >>responder ; -: check-capabilities ( responder user/f -- ? ) - { +: have-capabilities? ( capabilities -- ? ) + logged-in-user get { { [ dup not ] [ 2drop f ] } { [ dup deleted>> 1 = ] [ 2drop f ] } - [ [ capabilities>> ] bi@ subset? ] + [ capabilities>> subset? ] } cond ; M: protected call-responder* ( path responder -- response ) '[ , , dup protected set - dup logged-in-user get check-capabilities + dup capabilities>> have-capabilities? [ call-next-method ] [ 2drop realm get login-required* ] if ] if-secure-realm ; diff --git a/extra/furnace/auth/features/edit-profile/edit-profile.factor b/extra/furnace/auth/features/edit-profile/edit-profile.factor index e03fca99a5..da6acece61 100644 --- a/extra/furnace/auth/features/edit-profile/edit-profile.factor +++ b/extra/furnace/auth/features/edit-profile/edit-profile.factor @@ -22,7 +22,7 @@ IN: furnace.auth.features.edit-profile { realm "features/edit-profile/edit-profile" } >>template [ - logged-in-user get username>> "username" set-value + username "username" set-value { { "realname" [ [ v-one-line ] v-optional ] } @@ -34,7 +34,7 @@ IN: furnace.auth.features.edit-profile { "password" "new-password" "verify-password" } [ value empty? not ] contains? [ - "password" value logged-in-user get username>> check-login + "password" value username check-login [ "incorrect password" validation-error ] unless same-password-twice diff --git a/extra/furnace/auth/features/recover-password/recover-password.factor b/extra/furnace/auth/features/recover-password/recover-password.factor index 93b3a7ad73..77915f1083 100644 --- a/extra/furnace/auth/features/recover-password/recover-password.factor +++ b/extra/furnace/auth/features/recover-password/recover-password.factor @@ -11,7 +11,7 @@ IN: furnace.auth.features.recover-password SYMBOL: lost-password-from : current-host ( -- string ) - request get url>> host>> host-name or ; + url get host>> host-name or ; : new-password-url ( user -- url ) URL" recover-3" clone diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index ce533bce64..9246780a94 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors namespaces sequences math.parser -calendar validators urls html.forms +calendar validators urls logging html.forms http http.server http.server.dispatchers furnace furnace.auth @@ -25,10 +25,8 @@ SYMBOL: permit-id TUPLE: login-realm < realm timeout domain ; -M: login-realm call-responder* - [ name>> client-permit-id permit-id set ] - [ call-next-method ] - bi ; +M: login-realm init-realm + name>> client-permit-id permit-id set ; M: login-realm logged-in-username drop permit-id get dup [ get-permit-uid ] when ; @@ -47,11 +45,15 @@ M: login-realm modify-form ( responder -- ) : put-permit-cookie ( response -- response' ) put-cookie ; +\ put-permit-cookie DEBUG add-input-logging + : successful-login ( user -- response ) [ username>> make-permit permit-id set ] [ init-user ] bi URL" $realm" end-aside put-permit-cookie ; +\ successful-login DEBUG add-input-logging + : logout ( -- ) permit-id get [ delete-permit ] when* URL" $realm" end-aside ; diff --git a/extra/furnace/auth/login/permits/permits.factor b/extra/furnace/auth/login/permits/permits.factor index ae9458f4ac..1a9784f147 100644 --- a/extra/furnace/auth/login/permits/permits.factor +++ b/extra/furnace/auth/login/permits/permits.factor @@ -1,7 +1,5 @@ -USING: accessors namespaces combinators.lib kernel -db.tuples db.types -furnace.auth furnace.sessions furnace.cache -combinators.short-circuit ; +USING: accessors namespaces kernel combinators.short-circuit +db.tuples db.types furnace.auth furnace.sessions furnace.cache ; IN: furnace.auth.login.permits diff --git a/extra/furnace/boilerplate/boilerplate.factor b/extra/furnace/boilerplate/boilerplate.factor index 2bb97e7c14..59f71b1524 100644 --- a/extra/furnace/boilerplate/boilerplate.factor +++ b/extra/furnace/boilerplate/boilerplate.factor @@ -1,13 +1,12 @@ ! Copyright (c) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel math.order namespaces combinators.lib +USING: accessors kernel math.order namespaces furnace combinators.short-circuit html.forms html.templates html.templates.chloe locals http.server -http.server.filters -furnace combinators.short-circuit ; +http.server.filters ; IN: furnace.boilerplate TUPLE: boilerplate < filter-responder template init ; diff --git a/extra/furnace/flash/flash.factor b/extra/furnace/flash/flash.factor index 2149e4fcd7..16d61487e3 100644 --- a/extra/furnace/flash/flash.factor +++ b/extra/furnace/flash/flash.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: namespaces assocs assocs.lib kernel sequences accessors +USING: namespaces assocs kernel sequences accessors urls db.types db.tuples math.parser fry http http.server http.server.filters http.server.redirection furnace furnace.cache furnace.sessions furnace.redirection ; diff --git a/extra/furnace/furnace.factor b/extra/furnace/furnace.factor index 242e193013..45aa55f050 100644 --- a/extra/furnace/furnace.factor +++ b/extra/furnace/furnace.factor @@ -86,7 +86,7 @@ M: object modify-form drop ; "user-agent" request get header>> at "" or ; : same-host? ( url -- ? ) - request get url>> + url get [ [ protocol>> ] [ host>> ] [ port>> ] tri 3array ] bi@ = ; : cookie-client-state ( key request -- value/f ) diff --git a/extra/furnace/redirection/redirection.factor b/extra/furnace/redirection/redirection.factor index 88d621b573..83941cd08f 100644 --- a/extra/furnace/redirection/redirection.factor +++ b/extra/furnace/redirection/redirection.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors combinators namespaces fry -io.servers.connection +io.servers.connection urls http http.server http.server.redirection http.server.filters furnace ; IN: furnace.redirection @@ -33,8 +33,8 @@ TUPLE: secure-only < filter-responder ; C: secure-only : if-secure ( quot -- ) - >r request get url>> protocol>> "http" = - [ request get url>> ] + >r url get protocol>> "http" = + [ url get ] r> if ; inline M: secure-only call-responder* diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 5590a9e55e..31711f54e9 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -2,12 +2,12 @@ ! See http://factorcode.org/license.txt for BSD license. USING: assocs kernel math.intervals math.parser namespaces strings random accessors quotations hashtables sequences continuations -fry calendar combinators combinators.lib destructors alarms +fry calendar combinators combinators.short-circuit destructors alarms io.servers.connection db db.tuples db.types http http.server http.server.dispatchers http.server.filters html.elements -furnace furnace.cache combinators.short-circuit ; +furnace furnace.cache ; IN: furnace.sessions TUPLE: session < server-state namespace user-agent client changed? ; diff --git a/extra/furnace/syndication/syndication.factor b/extra/furnace/syndication/syndication.factor index 7f60bcc746..31a978aef3 100644 --- a/extra/furnace/syndication/syndication.factor +++ b/extra/furnace/syndication/syndication.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel sequences fry sequences.lib +USING: accessors kernel sequences fry combinators syndication http.server.responses http.server.redirection furnace furnace.actions ; diff --git a/extra/http/http.factor b/extra/http/http.factor index bf55cdebfa..90b8b86921 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -114,10 +114,13 @@ TUPLE: cookie name value version comment path domain expires max-age http-only s ] } case ; +: check-cookie-value ( string -- string ) + [ "Cookie value must not be f" throw ] unless* ; + : (unparse-cookie) ( cookie -- strings ) [ dup name>> check-cookie-string >lower - over value>> unparse-cookie-value + over value>> check-cookie-value unparse-cookie-value "$path" over path>> unparse-cookie-value "$domain" over domain>> unparse-cookie-value drop @@ -129,7 +132,7 @@ TUPLE: cookie name value version comment path domain expires max-age http-only s : unparse-set-cookie ( cookie -- string ) [ dup name>> check-cookie-string >lower - over value>> unparse-cookie-value + over value>> check-cookie-value unparse-cookie-value "path" over path>> unparse-cookie-value "domain" over domain>> unparse-cookie-value "expires" over expires>> unparse-cookie-value diff --git a/extra/http/parsers/parsers.factor b/extra/http/parsers/parsers.factor index bc6e1148c3..746741c894 100644 --- a/extra/http/parsers/parsers.factor +++ b/extra/http/parsers/parsers.factor @@ -1,4 +1,4 @@ -USING: combinators.short-circuit math math.order math.parser kernel combinators.lib +USING: combinators.short-circuit math math.order math.parser kernel sequences sequences.deep peg peg.parsers assocs arrays hashtables strings unicode.case namespaces ascii ; IN: http.parsers diff --git a/extra/http/server/cgi/cgi.factor b/extra/http/server/cgi/cgi.factor index 3a13b6de39..354ebd8f70 100755 --- a/extra/http/server/cgi/cgi.factor +++ b/extra/http/server/cgi/cgi.factor @@ -14,10 +14,10 @@ IN: http.server.cgi [ "PATH_TRANSLATED" set ] [ "SCRIPT_FILENAME" set ] bi - request get url>> path>> "SCRIPT_NAME" set + url get path>> "SCRIPT_NAME" set - request get url>> host>> "SERVER_NAME" set - request get url>> port>> number>string "SERVER_PORT" set + url get host>> "SERVER_NAME" set + url get port>> number>string "SERVER_PORT" set "" "PATH_INFO" set "" "REMOTE_HOST" set "" "REMOTE_ADDR" set @@ -26,7 +26,7 @@ IN: http.server.cgi "" "REMOTE_IDENT" set request get method>> "REQUEST_METHOD" set - request get url>> query>> assoc>query "QUERY_STRING" set + url get query>> assoc>query "QUERY_STRING" set request get "cookie" header "HTTP_COOKIE" set request get "user-agent" header "HTTP_USER_AGENT" set diff --git a/extra/http/server/dispatchers/dispatchers.factor b/extra/http/server/dispatchers/dispatchers.factor index 2da2695992..405d96d1f5 100644 --- a/extra/http/server/dispatchers/dispatchers.factor +++ b/extra/http/server/dispatchers/dispatchers.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel namespaces sequences assocs accessors splitting -unicode.case http http.server http.server.responses ; +unicode.case urls http http.server http.server.responses ; IN: http.server.dispatchers TUPLE: dispatcher default responders ; @@ -35,7 +35,7 @@ TUPLE: vhost-dispatcher default responders ; >lower "www." ?head drop "." ?tail drop ; : find-vhost ( dispatcher -- responder ) - request get url>> host>> canonical-host over responders>> at* + url get host>> canonical-host over responders>> at* [ nip ] [ drop default>> ] if ; M: vhost-dispatcher call-responder* ( path dispatcher -- response ) diff --git a/extra/http/server/redirection/redirection.factor b/extra/http/server/redirection/redirection.factor index c1d2eaa63a..314c09e33d 100644 --- a/extra/http/server/redirection/redirection.factor +++ b/extra/http/server/redirection/redirection.factor @@ -9,7 +9,7 @@ GENERIC: relative-to-request ( url -- url' ) M: string relative-to-request ; M: url relative-to-request - request get url>> + url get clone f >>query swap derive-url ensure-port ; diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 6733bb8a41..436d626578 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -81,8 +81,7 @@ GENERIC: write-full-response ( request response -- ) : ensure-domain ( cookie -- cookie ) [ - request get url>> - host>> dup "localhost" = + url get host>> dup "localhost" = [ drop ] [ or ] if ] change-domain ; @@ -189,7 +188,7 @@ LOG: httpd-header NOTICE "/" split harvest ; : init-request ( request -- ) - request set + [ request set ] [ url>> url set ] bi V{ } clone responder-nesting set ; : dispatch-request ( request -- response ) @@ -224,7 +223,7 @@ LOG: httpd-benchmark DEBUG : ?benchmark ( quot -- ) benchmark? get [ - [ benchmark ] [ first ] bi request get url>> rot 3array + [ benchmark ] [ first ] bi url get rot 3array httpd-benchmark ] [ call ] if ; inline @@ -235,7 +234,7 @@ M: http-server handle-client* [ 64 1024 * limit-input ?refresh-all - read-request + [ read-request ] ?benchmark [ do-request ] ?benchmark [ do-response ] ?benchmark ] with-destructors ; diff --git a/extra/http/server/static/static.factor b/extra/http/server/static/static.factor index 83fcf6f4a9..98510e45fd 100755 --- a/extra/http/server/static/static.factor +++ b/extra/http/server/static/static.factor @@ -82,12 +82,12 @@ TUPLE: file-responder root hook special allow-listings ; "index.html" append-path dup exists? [ drop f ] unless ; : serve-directory ( filename -- response ) - request get url>> path>> "/" tail? [ + url get path>> "/" tail? [ dup find-index [ serve-file ] [ list-directory ] ?if ] [ drop - request get url>> clone [ "/" append ] change-path + url get clone [ "/" append ] change-path ] if ; : serve-object ( filename -- response ) diff --git a/extra/webapps/blogs/blogs.factor b/extra/webapps/blogs/blogs.factor index 10e0ab54c0..972c09f9b8 100644 --- a/extra/webapps/blogs/blogs.factor +++ b/extra/webapps/blogs/blogs.factor @@ -160,13 +160,13 @@ M: comment entity-url [ validate-post - logged-in-user get username>> "author" set-value + username "author" set-value ] >>validate [ f dup { "title" "content" } to-object - logged-in-user get username>> >>author + username >>author now >>date [ insert-tuple ] [ entity-url ] bi ] >>submit @@ -177,8 +177,8 @@ M: comment entity-url "make a new blog post" >>description ; : authorize-author ( author -- ) - logged-in-user get username>> = - can-administer-blogs? have-capability? or + username = + { can-administer-blogs? } have-capabilities? or [ login-required ] unless ; : do-post-action ( -- ) @@ -254,13 +254,13 @@ M: comment entity-url [ validate-comment - logged-in-user get username>> "author" set-value + username "author" set-value ] >>validate [ "parent" value f "content" value >>content - logged-in-user get username>> >>author + username >>author now >>date [ insert-tuple ] [ entity-url ] bi ] >>submit diff --git a/extra/webapps/todo/todo.factor b/extra/webapps/todo/todo.factor index 0fb7e7dc89..e726c4ed36 100755 --- a/extra/webapps/todo/todo.factor +++ b/extra/webapps/todo/todo.factor @@ -32,7 +32,7 @@ todo "TODO" : ( id -- todo ) todo new swap >>id - logged-in-user get username>> >>uid ; + username >>uid ; : ( -- action ) diff --git a/extra/webapps/wiki/changes.xml b/extra/webapps/wiki/changes.xml index 1515c4924a..7004871df3 100644 --- a/extra/webapps/wiki/changes.xml +++ b/extra/webapps/wiki/changes.xml @@ -4,26 +4,4 @@ Recent Changes -
- - - - - - - - - - - - - - - - - -
ArticleDateBy
- -
- diff --git a/extra/webapps/wiki/diff.xml b/extra/webapps/wiki/diff.xml index 9d65531eb0..75cb4a29fb 100644 --- a/extra/webapps/wiki/diff.xml +++ b/extra/webapps/wiki/diff.xml @@ -13,7 +13,7 @@ New revision: - + Created on by . diff --git a/extra/webapps/wiki/edit.xml b/extra/webapps/wiki/edit.xml index 057b7f8f71..90843a7140 100644 --- a/extra/webapps/wiki/edit.xml +++ b/extra/webapps/wiki/edit.xml @@ -4,12 +4,17 @@ Edit: - +

+

+ Describe this revision: + +

+

diff --git a/extra/webapps/wiki/revisions-common.xml b/extra/webapps/wiki/revisions-common.xml new file mode 100644 index 0000000000..6cf331532a --- /dev/null +++ b/extra/webapps/wiki/revisions-common.xml @@ -0,0 +1,33 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
ArticleDateByDescriptionRollback
Rollback
+ +
+ + + +
diff --git a/extra/webapps/wiki/revisions.xml b/extra/webapps/wiki/revisions.xml index 0e1af75a8f..68f377e70b 100644 --- a/extra/webapps/wiki/revisions.xml +++ b/extra/webapps/wiki/revisions.xml @@ -4,24 +4,6 @@ Revisions of -
- - - - - - - - - - - - - - -
RevisionByRollback
Rollback
-
-

View Differences

diff --git a/extra/webapps/wiki/user-edits.xml b/extra/webapps/wiki/user-edits.xml index 6f6ada2dbd..8035c24e24 100644 --- a/extra/webapps/wiki/user-edits.xml +++ b/extra/webapps/wiki/user-edits.xml @@ -8,14 +8,4 @@ Edits by -
    - -
  • - - on - -
  • -
    -
- diff --git a/extra/webapps/wiki/view.xml b/extra/webapps/wiki/view.xml index 7d2c7869b5..38d9d39d55 100644 --- a/extra/webapps/wiki/view.xml +++ b/extra/webapps/wiki/view.xml @@ -8,6 +8,12 @@ -

This revision created on by .

+

+ This revision created on by + + () + + +

diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml index 5cddcee628..dea79670a3 100644 --- a/extra/webapps/wiki/wiki-common.xml +++ b/extra/webapps/wiki/wiki-common.xml @@ -47,15 +47,17 @@ - - - - - - - - - + + + + + + + + + + + diff --git a/extra/webapps/wiki/wiki.factor b/extra/webapps/wiki/wiki.factor index 3c87f3cd49..623c8aabe5 100644 --- a/extra/webapps/wiki/wiki.factor +++ b/extra/webapps/wiki/wiki.factor @@ -47,7 +47,7 @@ article "ARTICLES" { :
( title -- article ) article new swap >>title ; -TUPLE: revision id title author date content ; +TUPLE: revision id title author date content description ; revision "REVISIONS" { { "id" "ID" INTEGER +db-assigned-id+ } @@ -55,6 +55,7 @@ revision "REVISIONS" { { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } ! uid { "date" "DATE" TIMESTAMP +not-null+ } { "content" "CONTENT" TEXT +not-null+ } + { "description" "DESCRIPTION" TEXT } } define-persistent M: revision feed-entry-title @@ -76,6 +77,10 @@ M: revision feed-entry-url id>> revision-url ; : validate-author ( -- ) { { "author" [ v-username ] } } validate-params ; +: ( responder -- responder' ) + + { wiki "page-common" } >>template ; + : ( -- action ) [ "Front Page" view-url ] >>display ; @@ -100,7 +105,9 @@ M: revision feed-entry-url id>> revision-url ; ] [ edit-url ] ?if - ] >>display ; + ] >>display + + ; : ( -- action ) @@ -114,7 +121,9 @@ M: revision feed-entry-url id>> revision-url ; URL" $wiki/view/" adjust-url present relative-link-prefix set ] >>init - { wiki "view" } >>template ; + { wiki "view" } >>template + + ; : ( -- action ) @@ -144,28 +153,47 @@ M: revision feed-entry-url id>> revision-url ; [ validate-title - "title" value
select-tuple [ - revision>> select-tuple from-object - ] when* + + "title" value
select-tuple + [ revision>> select-tuple ] + [ f "title" value >>title ] + if* + + [ title>> "title" set-value ] + [ content>> "content" set-value ] + bi ] >>init { wiki "edit" } >>template + ; + +: ( -- action ) + [ validate-title - { { "content" [ v-required ] } } validate-params + + { + { "content" [ v-required ] } + { "description" [ [ v-one-line ] v-optional ] } + } validate-params f "title" value >>title now >>date - logged-in-user get username>> >>author + username >>author "content" value >>content + "description" value >>description [ add-revision ] [ title>> view-url ] bi ] >>submit "edit wiki articles" >>description ; +: ( responder -- responder ) + + { wiki "revisions-common" } >>template ; + : list-revisions ( -- seq ) f "title" value >>title select-tuples reverse-chronological-order ; @@ -180,7 +208,10 @@ M: revision feed-entry-url id>> revision-url ; list-revisions "revisions" set-value ] >>init - { wiki "revisions" } >>template ; + { wiki "revisions" } >>template + + + ; : ( -- action ) @@ -195,15 +226,26 @@ M: revision feed-entry-url id>> revision-url ; [ list-revisions ] >>entries ; +: rollback-description ( description -- description' ) + [ "Rollback of '" swap "'" 3append ] [ "Rollback" ] if* ; + : ( -- action ) [ validate-integer-id ] >>validate [ - "id" value select-tuple clone f >>id - [ add-revision ] [ title>> view-url ] bi - ] >>submit ; + "id" value select-tuple + f >>id + now >>date + username >>author + [ rollback-description ] change-description + [ add-revision ] + [ title>> revisions-url ] bi + ] >>submit + + + "rollback wiki articles" >>description ; : list-changes ( -- seq ) f select-tuples @@ -211,8 +253,10 @@ M: revision feed-entry-url id>> revision-url ; : ( -- action ) - [ list-changes "changes" set-value ] >>init - { wiki "changes" } >>template ; + [ list-changes "revisions" set-value ] >>init + { wiki "changes" } >>template + + ; : ( -- action ) @@ -237,6 +281,7 @@ M: revision feed-entry-url id>> revision-url ; : ( -- action ) + [ { { "old-id" [ v-integer ] } @@ -246,14 +291,18 @@ M: revision feed-entry-url id>> revision-url ; "old-id" "new-id" [ value select-tuple ] bi@ [ - [ [ title>> "title" set-value ] [ "old" [ from-object ] nest-form ] bi ] - [ "new" [ from-object ] nest-form ] bi* + over title>> "title" set-value + [ "old" [ from-object ] nest-form ] + [ "new" [ from-object ] nest-form ] + bi* ] [ [ content>> string-lines ] bi@ diff "diff" set-value ] 2bi ] >>init - { wiki "diff" } >>template ; + { wiki "diff" } >>template + + ; : ( -- action ) @@ -277,10 +326,12 @@ M: revision feed-entry-url id>> revision-url ; [ validate-author - list-user-edits "user-edits" set-value + list-user-edits "revisions" set-value ] >>init - { wiki "user-edits" } >>template ; + { wiki "user-edits" } >>template + + ; : ( -- action ) @@ -290,24 +341,21 @@ M: revision feed-entry-url id>> revision-url ; [ "author" value user-edits-url ] >>url [ list-user-edits ] >>entries ; -: ( responder -- responder' ) - - { wiki "page-common" } >>template ; - : init-sidebar ( -- ) "Sidebar" latest-revision [ "sidebar" [ from-object ] nest-form ] when* "Footer" latest-revision [ "footer" [ from-object ] nest-form ] when* ; : ( -- dispatcher ) wiki new-dispatcher - "" add-responder - "view" add-responder - "revision" add-responder + "" add-responder + "view" add-responder + "revision" add-responder "random" add-responder - "revisions" add-responder + "revisions" add-responder "revisions.atom" add-responder - "diff" add-responder - "edit" add-responder + "diff" add-responder + "edit" add-responder + "submit" add-responder "rollback" add-responder "user-edits" add-responder "articles" add-responder From c3ea84a026a8cd1095400889f40b649e041759e3 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 9 Jul 2008 18:09:03 -0500 Subject: [PATCH 0565/1850] use libcblas on openbsd --- extra/math/blas/cblas/cblas.factor | 1 + 1 file changed, 1 insertion(+) diff --git a/extra/math/blas/cblas/cblas.factor b/extra/math/blas/cblas/cblas.factor index 31807b7389..131007b9d0 100644 --- a/extra/math/blas/cblas/cblas.factor +++ b/extra/math/blas/cblas/cblas.factor @@ -4,6 +4,7 @@ IN: math.blas.cblas << "cblas" { { [ os macosx? ] [ "libblas.dylib" "cdecl" add-library ] } { [ os windows? ] [ "blas.dll" "cdecl" add-library ] } + { [ os openbsd? ] [ "libcblas.so" "cdecl" add-library ] } [ "libblas.so" "cdecl" add-library ] } cond >> From 42f54c8014c7552816e2e49319a47a5f8072f587 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 9 Jul 2008 18:24:28 -0500 Subject: [PATCH 0566/1850] Fix typedefs for 64-bit OpenBSD and FreeBSD --- extra/unix/types/freebsd/freebsd.factor | 6 ++---- extra/unix/types/openbsd/openbsd.factor | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/extra/unix/types/freebsd/freebsd.factor b/extra/unix/types/freebsd/freebsd.factor index 6e01ae9fd5..e012ebcbd6 100755 --- a/extra/unix/types/freebsd/freebsd.factor +++ b/extra/unix/types/freebsd/freebsd.factor @@ -4,8 +4,6 @@ IN: unix.types ! FreeBSD 7 x86.32 -! Need to verify on 64-bit - TYPEDEF: ushort __uint16_t TYPEDEF: uint __uint32_t TYPEDEF: int __int32_t @@ -21,6 +19,6 @@ TYPEDEF: __int64_t off_t TYPEDEF: __int64_t blkcnt_t TYPEDEF: __uint32_t blksize_t TYPEDEF: __uint32_t fflags_t -TYPEDEF: int ssize_t +TYPEDEF: long ssize_t TYPEDEF: int pid_t -TYPEDEF: int time_t \ No newline at end of file +TYPEDEF: int time_t diff --git a/extra/unix/types/openbsd/openbsd.factor b/extra/unix/types/openbsd/openbsd.factor index 5bdda212d8..a07e6f1c6a 100755 --- a/extra/unix/types/openbsd/openbsd.factor +++ b/extra/unix/types/openbsd/openbsd.factor @@ -27,6 +27,6 @@ TYPEDEF: __int64_t off_t TYPEDEF: __int64_t blkcnt_t TYPEDEF: __uint32_t blksize_t TYPEDEF: __uint32_t fflags_t -TYPEDEF: int ssize_t +TYPEDEF: long ssize_t TYPEDEF: int pid_t TYPEDEF: int time_t From 839ebfb3785287a46b4e90a34654dc490b877e1d Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 9 Jul 2008 19:11:38 -0500 Subject: [PATCH 0567/1850] fix encoding bug with text fields in sqlite --- extra/db/sqlite/lib/lib.factor | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extra/db/sqlite/lib/lib.factor b/extra/db/sqlite/lib/lib.factor index 4c440acc55..d14e975ae1 100755 --- a/extra/db/sqlite/lib/lib.factor +++ b/extra/db/sqlite/lib/lib.factor @@ -4,7 +4,8 @@ USING: alien.c-types arrays assocs kernel math math.parser 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.backend db.errors present urls io.encodings.utf8 +io.encodings.string ; IN: db.sqlite.lib ERROR: sqlite-error < db-error n string ; @@ -33,7 +34,7 @@ ERROR: sqlite-sql-error < sql-error n string ; sqlite3_close sqlite-check-result ; : sqlite-prepare ( db sql -- handle ) - dup length "void*" "void*" + utf8 encode dup length "void*" "void*" [ sqlite3_prepare_v2 sqlite-check-result ] 2keep drop *void* ; @@ -44,7 +45,7 @@ ERROR: sqlite-sql-error < sql-error n string ; >r dupd sqlite-bind-parameter-index r> ; : sqlite-bind-text ( handle index text -- ) - dup length SQLITE_TRANSIENT + utf8 encode dup length SQLITE_TRANSIENT sqlite3_bind_text sqlite-check-result ; : sqlite-bind-int ( handle i n -- ) From eba4b990af02ad7c77438d95e2deb5bcea0cd456 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 19:23:35 -0500 Subject: [PATCH 0568/1850] Fix stdin --- extra/io/unix/backend/backend.factor | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extra/io/unix/backend/backend.factor b/extra/io/unix/backend/backend.factor index b984b1f156..aa27b21d98 100755 --- a/extra/io/unix/backend/backend.factor +++ b/extra/io/unix/backend/backend.factor @@ -159,9 +159,9 @@ M: unix io-multiplex ( ms/f -- ) ! pipe to non-blocking, and read from it instead of the real ! stdin. Very crufty, but it will suffice until we get native ! threading support at the language level. -TUPLE: stdin control size data ; +TUPLE: stdin control size data disposed ; -M: stdin dispose +M: stdin dispose* [ [ control>> &dispose drop ] [ size>> &dispose drop ] @@ -194,10 +194,10 @@ M: stdin refill : data-read-fd ( -- fd ) "stdin_read" f dlsym *uint ; : ( -- stdin ) - control-write-fd - size-read-fd init-fd - data-read-fd - stdin boa ; + stdin new + control-write-fd >>control + size-read-fd init-fd >>size + data-read-fd >>data ; M: unix (init-stdio) ( -- ) From 442bde22e581e01fb493070e66f976fc66892f80 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 19:25:24 -0500 Subject: [PATCH 0569/1850] New extra/tr/ vocab for fast translation of ASCII strings; improves reverse-complement performance by 11%; add soundex vocab which uses tr --- .../reverse-complement.factor | 22 ++++-------- extra/soundex/author.txt | 1 + extra/soundex/soundex-tests.factor | 4 +++ extra/soundex/soundex.factor | 33 +++++++++++++++++ extra/soundex/summary.txt | 1 + extra/tr/authors.txt | 1 + extra/tr/summary.txt | 1 + extra/tr/tr-tests.factor | 7 ++++ extra/tr/tr.factor | 35 +++++++++++++++++++ 9 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 extra/soundex/author.txt create mode 100644 extra/soundex/soundex-tests.factor create mode 100644 extra/soundex/soundex.factor create mode 100644 extra/soundex/summary.txt create mode 100644 extra/tr/authors.txt create mode 100644 extra/tr/summary.txt create mode 100644 extra/tr/tr-tests.factor create mode 100644 extra/tr/tr.factor diff --git a/extra/benchmark/reverse-complement/reverse-complement.factor b/extra/benchmark/reverse-complement/reverse-complement.factor index b7c1db043c..665cbba30d 100755 --- a/extra/benchmark/reverse-complement/reverse-complement.factor +++ b/extra/benchmark/reverse-complement/reverse-complement.factor @@ -1,30 +1,20 @@ USING: io io.files io.streams.duplex kernel sequences sequences.private strings vectors words memoize splitting -grouping hints unicode.case continuations io.encodings.ascii ; +grouping hints tr continuations io.encodings.ascii +unicode.case ; IN: benchmark.reverse-complement -MEMO: trans-map ( -- str ) - 256 >string - "TGCAAKYRMBDHV" "ACGTUMRYKVHDB" - [ pick set-nth ] 2each ; - -: do-trans-map ( str -- ) - [ ch>upper trans-map nth ] change-each ; - -HINTS: do-trans-map string ; +TR: trans-map ch>upper "ACGTUMRYKVHDB" "TGCAAKYRMBDHV" ; : translate-seq ( seq -- str ) - concat dup reverse-here dup do-trans-map ; + concat dup reverse-here dup trans-map-fast ; : show-seq ( seq -- ) translate-seq 60 [ print ] each ; : do-line ( seq line -- seq ) - dup first ">;" memq? [ - over show-seq print dup delete-all - ] [ - over push - ] if ; + dup first ">;" memq? + [ over show-seq print dup delete-all ] [ over push ] if ; HINTS: do-line vector string ; diff --git a/extra/soundex/author.txt b/extra/soundex/author.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/extra/soundex/author.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/extra/soundex/soundex-tests.factor b/extra/soundex/soundex-tests.factor new file mode 100644 index 0000000000..df6338c4ec --- /dev/null +++ b/extra/soundex/soundex-tests.factor @@ -0,0 +1,4 @@ +IN: soundex.tests +USING: soundex tools.test ; + +[ "S162" ] [ "supercalifrag" soundex ] unit-test diff --git a/extra/soundex/soundex.factor b/extra/soundex/soundex.factor new file mode 100644 index 0000000000..c82825d814 --- /dev/null +++ b/extra/soundex/soundex.factor @@ -0,0 +1,33 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: sequences sequences.lib grouping assocs kernel ascii +unicode.case tr ; +IN: soundex + +TR: soundex-tr + ch>upper + "AEHIOUWYBFPVCGJKQSXZDTLMNR" + "00000000111122222222334556" ; + +: remove-duplicates ( seq -- seq' ) + #! Remove _consecutive_ duplicates (unlike prune which removes + #! all duplicates). + [ 2 [ = not ] assoc-filter values ] [ first ] bi prefix ; + +: first>upper ( seq -- seq' ) 1 head >upper ; +: trim-first ( seq -- seq' ) dup first [ = ] curry left-trim ; +: remove-zeroes ( seq -- seq' ) CHAR: 0 swap remove ; +: remove-non-alpha ( seq -- seq' ) [ alpha? ] filter ; +: pad-4 ( first seq -- seq' ) "000" 3append 4 head ; + +: soundex ( string -- soundex ) + remove-non-alpha [ f ] [ + [ first>upper ] + [ + soundex-tr + trim-first + remove-duplicates + remove-zeroes + ] bi + pad-4 + ] if-empty ; diff --git a/extra/soundex/summary.txt b/extra/soundex/summary.txt new file mode 100644 index 0000000000..95a271d911 --- /dev/null +++ b/extra/soundex/summary.txt @@ -0,0 +1 @@ +Soundex is a phonetic algorithm for indexing names by sound diff --git a/extra/tr/authors.txt b/extra/tr/authors.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/extra/tr/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/extra/tr/summary.txt b/extra/tr/summary.txt new file mode 100644 index 0000000000..8678446951 --- /dev/null +++ b/extra/tr/summary.txt @@ -0,0 +1 @@ +Fast character-to-character translation of ASCII strings diff --git a/extra/tr/tr-tests.factor b/extra/tr/tr-tests.factor new file mode 100644 index 0000000000..1eea69ba07 --- /dev/null +++ b/extra/tr/tr-tests.factor @@ -0,0 +1,7 @@ +IN: tr.tests +USING: tr tools.test unicode.case ; + +TR: tr-test ch>upper "ABC" "XYZ" ; + +[ "XXYY" ] [ "aabb" tr-test ] unit-test +[ "XXYY" ] [ "AABB" tr-test ] unit-test diff --git a/extra/tr/tr.factor b/extra/tr/tr.factor new file mode 100644 index 0000000000..a95d308d36 --- /dev/null +++ b/extra/tr/tr.factor @@ -0,0 +1,35 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: byte-arrays strings sequences sequences.private +fry kernel words parser lexer assocs ; +IN: tr + + + +: TR: + scan parse-definition + unclip-last [ unclip-last ] dip compute-tr + [ [ create-tr ] dip define-tr ] + [ [ "-fast" append create-tr ] dip define-fast-tr ] 2bi ; + parsing From 34c0cf61113ee18a774b48d599048210fb69e215 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 19:43:46 -0500 Subject: [PATCH 0570/1850] Use tr instead of substitute in a few places --- extra/io/windows/nt/files/files.factor | 6 ++++-- extra/json/writer/writer.factor | 7 ++----- extra/sequences/lib/lib.factor | 3 --- extra/tools/disassembler/disassembler.factor | 5 ++--- extra/tools/vocabs/monitor/monitor.factor | 10 +++++++--- extra/ui/commands/commands.factor | 6 ++++-- extra/unicode/data/data.factor | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/extra/io/windows/nt/files/files.factor b/extra/io/windows/nt/files/files.factor index 2a39cea479..6a890f6392 100755 --- a/extra/io/windows/nt/files/files.factor +++ b/extra/io/windows/nt/files/files.factor @@ -4,7 +4,7 @@ io.windows.nt.backend windows windows.kernel32 kernel libc math threads system alien.c-types alien.arrays alien.strings sequences combinators combinators.short-circuit ascii splitting alien strings -assocs namespaces io.files.private accessors ; +assocs namespaces io.files.private accessors tr ; IN: io.windows.nt.files M: winnt cwd @@ -40,9 +40,11 @@ ERROR: not-absolute-path ; unicode-prefix prepend ] unless ; +TR: normalize-separators "/" "\\" ; + M: winnt normalize-path ( string -- string' ) (normalize-path) - { { CHAR: / CHAR: \\ } } substitute + normalize-separators prepend-prefix ; M: winnt CreateFile-flags ( DWORD -- DWORD ) diff --git a/extra/json/writer/writer.factor b/extra/json/writer/writer.factor index a68c65087e..0d22494b13 100644 --- a/extra/json/writer/writer.factor +++ b/extra/json/writer/writer.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel io.streams.string io strings splitting sequences math math.parser assocs classes words namespaces prettyprint - hashtables mirrors ; + hashtables mirrors tr ; IN: json.writer #! Writes the object out to a stream in JSON format @@ -24,10 +24,7 @@ M: number json-print ( num -- ) M: sequence json-print ( array -- ) CHAR: [ write1 [ >json ] map "," join write CHAR: ] write1 ; -: jsvar-encode ( string -- string ) - #! Convert the string so that it contains characters usable within - #! javascript variable names. - { { CHAR: - CHAR: _ } } substitute ; +TR: jsvar-encode "-" "_" ; : tuple>fields ( object -- seq ) [ diff --git a/extra/sequences/lib/lib.factor b/extra/sequences/lib/lib.factor index 90bca7cef9..0049320b94 100755 --- a/extra/sequences/lib/lib.factor +++ b/extra/sequences/lib/lib.factor @@ -210,9 +210,6 @@ PRIVATE> : nths ( seq indices -- seq' ) swap [ nth ] curry map ; -: replace ( str oldseq newseq -- str' ) - zip >hashtable substitute ; - : remove-nth ( seq n -- seq' ) cut-slice rest-slice append ; diff --git a/extra/tools/disassembler/disassembler.factor b/extra/tools/disassembler/disassembler.factor index a7d9da4840..4a345e2345 100755 --- a/extra/tools/disassembler/disassembler.factor +++ b/extra/tools/disassembler/disassembler.factor @@ -3,7 +3,7 @@ USING: io.files io words alien kernel math.parser alien.syntax io.launcher system assocs arrays sequences namespaces qualified system math generator.fixup io.encodings.ascii accessors -generic ; +generic tr ; IN: tools.disassembler : in-file ( -- path ) "gdb-in.txt" temp-file ; @@ -36,8 +36,7 @@ M: method-spec make-disassemble-cmd try-process out-file ascii file-lines ; -: tabs>spaces ( str -- str' ) - { { CHAR: \t CHAR: \s } } substitute ; +TR: tabs>spaces "\t" "\s" ; : disassemble ( obj -- ) make-disassemble-cmd run-gdb diff --git a/extra/tools/vocabs/monitor/monitor.factor b/extra/tools/vocabs/monitor/monitor.factor index ee5198a8f4..12b2e41d36 100755 --- a/extra/tools/vocabs/monitor/monitor.factor +++ b/extra/tools/vocabs/monitor/monitor.factor @@ -2,12 +2,16 @@ ! See http://factorcode.org/license.txt for BSD license. USING: threads io.files io.monitors init kernel vocabs vocabs.loader tools.vocabs namespaces continuations -sequences splitting assocs command-line concurrency.messaging io.backend sets ; +sequences splitting assocs command-line concurrency.messaging +io.backend sets tr ; IN: tools.vocabs.monitor +TR: convert-separators "/\\" ".." ; + : vocab-dir>vocab-name ( path -- vocab ) - left-trim-separators right-trim-separators - { { CHAR: / CHAR: . } { CHAR: \\ CHAR: . } } substitute ; + left-trim-separators + right-trim-separators + convert-separators ; : path>vocab-name ( path -- vocab ) dup ".factor" tail? [ parent-directory ] when ; diff --git a/extra/ui/commands/commands.factor b/extra/ui/commands/commands.factor index 6a5a4d2c42..39eed24ada 100755 --- a/extra/ui/commands/commands.factor +++ b/extra/ui/commands/commands.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays definitions kernel sequences strings math assocs words generic namespaces assocs quotations splitting -ui.gestures unicode.case unicode.categories ; +ui.gestures unicode.case unicode.categories tr ; IN: ui.commands SYMBOL: +nullary+ @@ -50,8 +50,10 @@ GENERIC: command-word ( command -- word ) swap pick commands set-at update-gestures ; +TR: convert-command-name "-" " " ; + : (command-name) ( string -- newstring ) - { { CHAR: - CHAR: \s } } substitute >title ; + convert-command-name >title ; M: word command-name ( word -- str ) name>> diff --git a/extra/unicode/data/data.factor b/extra/unicode/data/data.factor index f74e2e0473..fdcf495307 100755 --- a/extra/unicode/data/data.factor +++ b/extra/unicode/data/data.factor @@ -125,7 +125,7 @@ VALUE: properties : process-names ( data -- names-hash ) 1 swap (process-data) [ ascii-lower { { CHAR: \s CHAR: - } } substitute swap - ] assoc-map >hashtable ; + ] H{ } assoc-map-as ; : multihex ( hexstring -- string ) " " split [ hex> ] map sift ; From bf47ff4007801c5a47ee1ce0ed78d48cab5277c6 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 19:48:40 -0500 Subject: [PATCH 0571/1850] Working on conversation scope to supercede asides and flash scopes --- extra/furnace/actions/actions.factor | 11 +- extra/furnace/auth/auth.factor | 4 +- extra/furnace/auth/login/login.factor | 2 +- .../conversations/conversations.factor | 151 ++++++++++++++++++ extra/furnace/scopes/scopes.factor | 42 +++++ extra/furnace/sessions/sessions.factor | 37 +---- 6 files changed, 209 insertions(+), 38 deletions(-) create mode 100644 extra/furnace/conversations/conversations.factor create mode 100644 extra/furnace/scopes/scopes.factor diff --git a/extra/furnace/actions/actions.factor b/extra/furnace/actions/actions.factor index 6448fcdf07..ad8a36cca5 100755 --- a/extra/furnace/actions/actions.factor +++ b/extra/furnace/actions/actions.factor @@ -75,12 +75,11 @@ TUPLE: action rest authorize init display validate submit ; revalidate-url-key param dup [ >url [ same-host? ] keep and ] when ; -: validation-failed ( -- * ) - post-request? revalidate-url and - [ +: validation-failed ( flashed -- * ) + post-request? revalidate-url and dup [ nested-forms-key param " " split harvest nested-forms set - { form nested-forms } - ] [ <400> ] if* + swap { form nested-forms } append + ] [ 2drop <400> ] if exit-with ; : handle-post ( action -- response ) @@ -113,7 +112,7 @@ M: action modify-form drop url get revalidate-url-key hidden-form-field ; : check-validation ( -- ) - validation-failed? [ validation-failed ] when ; + validation-failed? [ { } validation-failed ] when ; : validate-params ( validators -- ) params get swap validate-values check-validation ; diff --git a/extra/furnace/auth/auth.factor b/extra/furnace/auth/auth.factor index 0c21c9f18d..4fae10c30d 100755 --- a/extra/furnace/auth/auth.factor +++ b/extra/furnace/auth/auth.factor @@ -152,7 +152,7 @@ M: protected call-responder* ( path responder -- response ) : password-mismatch ( -- * ) "passwords do not match" validation-error - validation-failed ; + { } validation-failed ; : same-password-twice ( -- ) "new-password" value "verify-password" value = @@ -160,4 +160,4 @@ M: protected call-responder* ( path responder -- response ) : user-exists ( -- * ) "username taken" validation-error - validation-failed ; + { } validation-failed ; diff --git a/extra/furnace/auth/login/login.factor b/extra/furnace/auth/login/login.factor index 9246780a94..f2ac81c066 100755 --- a/extra/furnace/auth/login/login.factor +++ b/extra/furnace/auth/login/login.factor @@ -65,7 +65,7 @@ SYMBOL: capabilities : login-failed ( -- * ) "invalid username or password" validation-error - validation-failed ; + flashed-variables validation-failed ; : ( -- action ) diff --git a/extra/furnace/conversations/conversations.factor b/extra/furnace/conversations/conversations.factor new file mode 100644 index 0000000000..cbc4e4b233 --- /dev/null +++ b/extra/furnace/conversations/conversations.factor @@ -0,0 +1,151 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: namespaces assocs kernel sequences accessors hashtables +urls db.types db.tuples math.parser fry logging combinators +html.templates.chloe.syntax +http http.server http.server.filters http.server.redirection +furnace +furnace.cache +furnace.scopes +furnace.sessions +furnace.redirection ; +IN: furnace.conversations + +TUPLE: conversation < scope +session +method url post-data ; + +: ( id -- aside ) + conversation new-server-state ; + +conversation "CONVERSATIONS" { + { "session" "SESSION" BIG-INTEGER +not-null+ } + { "method" "METHOD" { VARCHAR 10 } } + { "url" "URL" URL } + { "post-data" "POST_DATA" FACTOR-BLOB } +} define-persistent + +: conversation-id-key "__f" ; + +TUPLE: conversations < server-state-manager ; + +: ( responder -- responder' ) + conversations new-server-state-manager ; + +SYMBOL: conversation + +SYMBOL: conversation-id + +: cget ( key -- value ) + conversation get scope-get ; + +: cset ( value key -- ) + conversation get scope-set ; + +: cchange ( key quot -- ) + conversation get scope-change ; inline + +: get-conversation ( id -- conversation ) + dup [ conversation get-state ] when + dup [ dup session>> session get id>> = [ drop f ] unless ] when ; + +: request-conversation-id ( request -- id ) + conversation-id-key swap request-params at string>number ; + +: request-conversation ( request -- conversation ) + request-conversation-id get-conversation ; + +: init-conversations ( -- ) + request get request-conversation-id + [ conversation-id set ] + [ get-conversation conversation set ] + bi ; + +M: conversations call-responder* + init-conversations + [ conversations set ] [ call-next-method ] bi ; + +: empty-conversastion ( -- conversation ) + conversation empty-scope + session get id>> >>session ; + +: add-conversation ( conversation -- id ) + [ conversations get touch-state ] [ insert-tuple ] [ id>> ] tri ; + +: begin-conversation* ( -- id ) + empty-conversastion add-conversation ; + +: begin-conversation ( -- ) + conversation-id [ [ begin-conversation* ] unless* ] change ; + +: ( url seq -- response ) + begin-conversation + [ [ get ] keep cset ] each + ; + +: restore-conversation ( seq -- ) + conversation get dup [ + namespace>> + [ '[ , key? ] filter ] + [ '[ [ , at ] keep set ] each ] + bi + ] [ 2drop ] if ; + +: begin-aside* ( -- id ) + empty-conversastion + request get + [ method>> >>method ] + [ url>> >>url ] + [ post-data>> >>post-data ] + tri + add-conversation ; + +: begin-aside ( -- ) + begin-aside* conversation-id set ; + +: end-aside-post ( aside -- response ) + request [ + clone + over post-data>> >>post-data + over url>> >>url + ] change + url>> path>> split-path + conversations get responder>> call-responder ; + +\ end-aside-post DEBUG add-input-logging + +ERROR: end-aside-in-get-error ; + +: end-aside* ( url id -- response ) + post-request? [ end-aside-in-get-error ] unless + get-conversation [ + dup method>> { + { "GET" [ url>> ] } + { "HEAD" [ url>> ] } + { "POST" [ end-aside-post ] } + } case + ] [ ] ?if ; + +: end-aside ( default -- response ) + conversation-id [ f ] change end-aside* ; + +M: conversations link-attr ( tag -- ) + drop + "aside" optional-attr { + { "none" [ conversation-id off ] } + { "begin" [ begin-aside ] } + { "current" [ ] } + { f [ ] } + } case ; + +M: conversations modify-query ( query conversations -- query' ) + drop + conversation-id get [ + conversation-id-key associate assoc-union + ] when* ; + +M: conversations modify-form ( conversations -- ) + drop + conversation-id get + conversation-id-key + hidden-form-field ; diff --git a/extra/furnace/scopes/scopes.factor b/extra/furnace/scopes/scopes.factor new file mode 100644 index 0000000000..daad0dcf91 --- /dev/null +++ b/extra/furnace/scopes/scopes.factor @@ -0,0 +1,42 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors assocs destructors +db.tuples db.types furnace.cache ; +IN: furnace.scopes + +TUPLE: scope < server-state namespace changed? ; + +: empty-scope ( class -- scope ) + f swap new-server-state + H{ } clone >>namespace ; inline + +scope f +{ + { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ } +} define-persistent + +: scope-changed ( scope -- ) + t >>changed? drop ; + +: scope-get ( key scope -- value ) + dup [ namespace>> at ] [ 2drop f ] if ; + +: scope-set ( value key scope -- ) + [ namespace>> set-at ] [ scope-changed ] bi ; + +: scope-change ( key quot scope -- ) + [ namespace>> swap change-at ] [ scope-changed ] bi ; inline + +! Destructor +TUPLE: scope-saver scope manager ; + +C: scope-saver + +M: scope-saver dispose + [ manager>> ] [ scope>> ] bi + dup changed?>> [ + [ swap touch-state ] [ update-tuple ] bi + ] [ 2drop ] if ; + +: save-scope-after ( scope manager -- ) + &dispose drop ; diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 31711f54e9..3aafadaf68 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -7,17 +7,16 @@ io.servers.connection db db.tuples db.types http http.server http.server.dispatchers http.server.filters html.elements -furnace furnace.cache ; +furnace furnace.cache furnace.scopes ; IN: furnace.sessions -TUPLE: session < server-state namespace user-agent client changed? ; +TUPLE: session < scope user-agent client ; : ( id -- session ) session new-server-state ; session "SESSIONS" { - { "namespace" "NAMESPACE" FACTOR-BLOB +not-null+ } { "user-agent" "USER_AGENT" TEXT +not-null+ } { "client" "CLIENT" TEXT +not-null+ } } define-persistent @@ -39,23 +38,14 @@ TUPLE: sessions < server-state-manager domain verify? ; sessions new-server-state-manager t >>verify? ; -: (session-changed) ( session -- ) - t >>changed? drop ; - : session-changed ( -- ) - session get (session-changed) ; + session get scope-changed ; -: sget ( key -- value ) - session get namespace>> at ; +: sget ( key -- value ) session get scope-get ; -: sset ( value key -- ) - session get - [ namespace>> set-at ] [ (session-changed) ] bi ; +: sset ( value key -- ) session get scope-set ; -: schange ( key quot -- ) - session get - [ namespace>> swap change-at ] keep - (session-changed) ; inline +: schange ( key quot -- ) session get scope-change ; inline : init-session ( session -- ) session [ sessions get init-session* ] with-variable ; @@ -70,8 +60,7 @@ TUPLE: sessions < server-state-manager domain verify? ; } 0|| ; : empty-session ( -- session ) - f - H{ } clone >>namespace + session empty-scope remote-host >>client user-agent >>user-agent dup touch-session ; @@ -79,18 +68,8 @@ TUPLE: sessions < server-state-manager domain verify? ; : begin-session ( -- session ) empty-session [ init-session ] [ insert-tuple ] [ ] tri ; -! Destructor -TUPLE: session-saver session ; - -C: session-saver - -M: session-saver dispose - session>> dup changed?>> [ - [ touch-session ] [ update-tuple ] bi - ] [ drop ] if ; - : save-session-after ( session -- ) - &dispose drop ; + sessions get &dispose drop ; : existing-session ( path session -- response ) [ session set ] [ save-session-after ] bi From e58f41da407daa31fafcd23c5d9243b1dfd9c991 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 20:42:59 -0500 Subject: [PATCH 0572/1850] Fix tr for chars > 255 --- extra/tr/tr-tests.factor | 1 + extra/tr/tr.factor | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/extra/tr/tr-tests.factor b/extra/tr/tr-tests.factor index 1eea69ba07..c168f5384d 100644 --- a/extra/tr/tr-tests.factor +++ b/extra/tr/tr-tests.factor @@ -5,3 +5,4 @@ TR: tr-test ch>upper "ABC" "XYZ" ; [ "XXYY" ] [ "aabb" tr-test ] unit-test [ "XXYY" ] [ "AABB" tr-test ] unit-test +[ { 12345 } ] [ { 12345 } tr-test ] unit-test diff --git a/extra/tr/tr.factor b/extra/tr/tr.factor index a95d308d36..b5ad2ba430 100644 --- a/extra/tr/tr.factor +++ b/extra/tr/tr.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: byte-arrays strings sequences sequences.private -fry kernel words parser lexer assocs ; +fry kernel words parser lexer assocs math.order ; IN: tr From 4141399bebdd10ccf67b23ff8d2652de7c627a68 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Wed, 9 Jul 2008 22:48:17 -0300 Subject: [PATCH 0573/1850] irc.client: Move message tuples and parser to irc.messages, fix join handling --- extra/irc/client/client-docs.factor | 2 +- extra/irc/client/client.factor | 101 ++++++++-------------------- extra/irc/messages/authors.txt | 1 + extra/irc/messages/messages.factor | 69 +++++++++++++++++++ 4 files changed, 99 insertions(+), 74 deletions(-) create mode 100644 extra/irc/messages/authors.txt create mode 100644 extra/irc/messages/messages.factor diff --git a/extra/irc/client/client-docs.factor b/extra/irc/client/client-docs.factor index a675e663c3..6bb6a6328e 100644 --- a/extra/irc/client/client-docs.factor +++ b/extra/irc/client/client-docs.factor @@ -1,4 +1,4 @@ -USING: help.markup help.syntax quotations kernel ; +USING: help.markup help.syntax quotations kernel irc.messages ; IN: irc.client HELP: irc-client "IRC Client object" diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 5d80b0648f..ffe78437a7 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -1,9 +1,11 @@ ! Copyright (C) 2008 Bruno Deferrari, Doug Coleman, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators concurrency.mailboxes fry io strings - io.encodings.8-bit io.sockets kernel namespaces sequences - splitting threads calendar classes.tuple - classes ascii assocs accessors destructors continuations ; +USING: concurrency.mailboxes kernel io.sockets io.encodings.8-bit calendar + accessors destructors namespaces io assocs arrays qualified fry + continuations threads strings classes combinators + irc.messages irc.messages.private ; +RENAME: join sequences => sjoin +EXCLUDE: sequences => join ; IN: irc.client ! ====================================== @@ -27,6 +29,7 @@ TUPLE: irc-listener in-messages out-messages ; TUPLE: irc-server-listener < irc-listener ; TUPLE: irc-channel-listener < irc-listener name password timeout ; TUPLE: irc-nick-listener < irc-listener name ; +SYMBOL: +server-listener+ : ( -- irc-listener ) irc-listener boa ; @@ -48,20 +51,6 @@ SINGLETON: irc-disconnected ! sent when connection is lost SINGLETON: irc-connected ! sent when connection is established UNION: irc-broadcasted-message irc-end irc-disconnected irc-connected ; -TUPLE: irc-message line prefix command parameters trailing timestamp ; -TUPLE: logged-in < irc-message name ; -TUPLE: ping < irc-message ; -TUPLE: join < irc-message ; -TUPLE: part < irc-message channel ; -TUPLE: quit < irc-message ; -TUPLE: privmsg < irc-message name ; -TUPLE: kick < irc-message channel who ; -TUPLE: roomlist < irc-message channel names ; -TUPLE: nick-in-use < irc-message asterisk name ; -TUPLE: notice < irc-message type ; -TUPLE: mode < irc-message name channel mode ; -TUPLE: unhandled < irc-message ; - : terminate-irc ( irc-client -- ) [ in-messages>> irc-end swap mailbox-put ] [ f >>is-running drop ] @@ -82,13 +71,21 @@ TUPLE: unhandled < irc-message ; : unregister-listener ( name -- ) irc> listeners>> delete-at ; : to-listener ( message name -- ) - listener> [ f listener> ] unless* + listener> [ +server-listener+ listener> ] unless* [ in-messages>> mailbox-put ] [ drop ] if* ; ! ====================================== ! IRC client messages ! ====================================== +GENERIC: irc-message>string ( irc-message -- string ) + +M: irc-message irc-message>string ( irc-message -- string ) + [ command>> ] + [ parameters>> " " sjoin ] + [ trailing>> dup [ CHAR: : prefix ] when ] + tri 3array " " sjoin ; + : /NICK ( nick -- ) "NICK " irc-write irc-print ; @@ -125,53 +122,6 @@ TUPLE: unhandled < irc-message ; : /PONG ( text -- ) "PONG " irc-write irc-print ; -! ====================================== -! Message parsing -! ====================================== - -: split-at-first ( seq separators -- before after ) - dupd '[ , member? ] find - [ cut 1 tail ] - [ swap ] - if ; - -: remove-heading-: ( seq -- seq ) dup ":" head? [ 1 tail ] when ; - -: parse-name ( string -- string ) - remove-heading-: "!" split-at-first drop ; - -: split-prefix ( string -- string/f string ) - dup ":" head? - [ remove-heading-: " " split1 ] - [ f swap ] - if ; - -: split-trailing ( string -- string string/f ) - ":" split1 ; - -: string>irc-message ( string -- object ) - dup split-prefix split-trailing - [ [ blank? ] trim " " split unclip swap ] dip - now irc-message boa ; - -: parse-irc-line ( string -- message ) - string>irc-message - dup command>> { - { "PING" [ \ ping ] } - { "NOTICE" [ \ notice ] } - { "001" [ \ logged-in ] } - { "433" [ \ nick-in-use ] } - { "JOIN" [ \ join ] } - { "PART" [ \ part ] } - { "PRIVMSG" [ \ privmsg ] } - { "QUIT" [ \ quit ] } - { "MODE" [ \ mode ] } - { "KICK" [ \ kick ] } - [ drop \ unhandled ] - } case - [ [ tuple-slots ] [ parameters>> ] bi append ] dip - [ all-slots length head ] keep slots>tuple ; - ! ====================================== ! Server message handling ! ====================================== @@ -188,7 +138,7 @@ TUPLE: unhandled < irc-message ; GENERIC: handle-incoming-irc ( irc-message -- ) M: irc-message handle-incoming-irc ( irc-message -- ) - f listener> [ in-messages>> mailbox-put ] [ drop ] if* ; + +server-listener+ listener> [ in-messages>> mailbox-put ] [ drop ] if* ; M: logged-in handle-incoming-irc ( logged-in -- ) name>> irc> profile>> (>>nickname) ; @@ -203,8 +153,10 @@ M: privmsg handle-incoming-irc ( privmsg -- ) dup irc-message-origin to-listener ; M: join handle-incoming-irc ( join -- ) - dup trailing>> listener> - [ irc> join-messages>> ] unless* mailbox-put ; + [ [ prefix>> parse-name me? ] keep and + [ irc> join-messages>> mailbox-put ] when* ] + [ dup channel>> to-listener ] + bi ; M: part handle-incoming-irc ( part -- ) dup channel>> to-listener ; @@ -222,11 +174,14 @@ M: irc-broadcasted-message handle-incoming-irc ( irc-broadcasted-message -- ) GENERIC: handle-outgoing-irc ( obj -- ) +! M: irc-message handle-outgoing-irc ( irc-message -- ) +! irc-message>string irc-print ; + M: privmsg handle-outgoing-irc ( privmsg -- ) - [ name>> ] [ trailing>> ] bi /PRIVMSG ; + [ name>> ] [ trailing>> ] bi /PRIVMSG ; M: part handle-outgoing-irc ( privmsg -- ) - [ channel>> ] [ trailing>> "" or ] bi /PART ; + [ channel>> ] [ trailing>> "" or ] bi /PART ; ! ====================================== ! Reader/Writer @@ -320,7 +275,7 @@ M: irc-nick-listener (add-listener) ( irc-nick-listener -- ) [ name>> ] keep set+run-listener ; M: irc-server-listener (add-listener) ( irc-server-listener -- ) - f swap set+run-listener ; + +server-listener+ swap set+run-listener ; GENERIC: (remove-listener) ( irc-listener -- ) @@ -333,7 +288,7 @@ M: irc-channel-listener (remove-listener) ( irc-channel-listener -- ) name>> unregister-listener ; M: irc-server-listener (remove-listener) ( irc-server-listener -- ) - drop f unregister-listener ; + drop +server-listener+ unregister-listener ; : (connect-irc) ( irc-client -- ) [ profile>> [ server>> ] [ port>> ] bi /CONNECT ] keep diff --git a/extra/irc/messages/authors.txt b/extra/irc/messages/authors.txt new file mode 100644 index 0000000000..f4a8cb1dc2 --- /dev/null +++ b/extra/irc/messages/authors.txt @@ -0,0 +1 @@ +Bruno Deferrari diff --git a/extra/irc/messages/messages.factor b/extra/irc/messages/messages.factor new file mode 100644 index 0000000000..f1beba9b26 --- /dev/null +++ b/extra/irc/messages/messages.factor @@ -0,0 +1,69 @@ +! Copyright (C) 2008 Bruno Deferrari +! See http://factorcode.org/license.txt for BSD license. +USING: kernel fry sequences splitting ascii calendar accessors combinators + classes.tuple math.order ; +IN: irc.messages + +TUPLE: irc-message line prefix command parameters trailing timestamp ; +TUPLE: logged-in < irc-message name ; +TUPLE: ping < irc-message ; +TUPLE: join < irc-message channel ; +TUPLE: part < irc-message channel ; +TUPLE: quit < irc-message ; +TUPLE: privmsg < irc-message name ; +TUPLE: kick < irc-message channel who ; +TUPLE: roomlist < irc-message channel names ; +TUPLE: nick-in-use < irc-message asterisk name ; +TUPLE: notice < irc-message type ; +TUPLE: mode < irc-message name channel mode ; +TUPLE: unhandled < irc-message ; + +irc-message ( string -- object ) + dup split-prefix split-trailing + [ [ blank? ] trim " " split unclip swap ] dip + now irc-message boa ; + +: parse-irc-line ( string -- message ) + string>irc-message + dup command>> { + { "PING" [ \ ping ] } + { "NOTICE" [ \ notice ] } + { "001" [ \ logged-in ] } + { "433" [ \ nick-in-use ] } + { "JOIN" [ \ join ] } + { "PART" [ \ part ] } + { "PRIVMSG" [ \ privmsg ] } + { "QUIT" [ \ quit ] } + { "MODE" [ \ mode ] } + { "KICK" [ \ kick ] } + [ drop \ unhandled ] + } case + [ [ tuple-slots ] [ parameters>> ] bi append ] dip + [ all-slots over [ length ] bi@ min head ] keep slots>tuple ; + +PRIVATE> From 37ade561a95a7bf10883336b5c6b9fd11acf9236 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 25 Jun 2008 12:29:16 +1200 Subject: [PATCH 0574/1850] Fix unary expression in js grammar --- extra/peg/javascript/parser/parser.factor | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index b7df9908da..002804dcd8 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -64,14 +64,14 @@ MulExpr = MulExpr:x "*" Unary:y => [[ x y "*" ast-binop | MulExpr:x "/" Unary:y => [[ x y "/" ast-binop boa ]] | MulExpr:x "%" Unary:y => [[ x y "%" ast-binop boa ]] | Unary -Unary = "-" Postfix:p => [[ p "-" ast-unop boa ]] - | "+" Postfix:p => [[ p ]] - | "++" Postfix:p => [[ p "++" ast-preop boa ]] - | "--" Postfix:p => [[ p "--" ast-preop boa ]] - | "!" Postfix:p => [[ p "!" ast-unop boa ]] - | "typeof" Postfix:p => [[ p "typeof" ast-unop boa ]] - | "void" Postfix:p => [[ p "void" ast-unop boa ]] - | "delete" Postfix:p => [[ p "delete" ast-unop boa ]] +Unary = "-" Unary:p => [[ p "-" ast-unop boa ]] + | "+" Unary:p => [[ p ]] + | "++" Unary:p => [[ p "++" ast-preop boa ]] + | "--" Unary:p => [[ p "--" ast-preop boa ]] + | "!" Unary:p => [[ p "!" ast-unop boa ]] + | "typeof" Unary:p => [[ p "typeof" ast-unop boa ]] + | "void" Unary:p => [[ p "void" ast-unop boa ]] + | "delete" Unary:p => [[ p "delete" ast-unop boa ]] | Postfix Postfix = PrimExpr:p SpacesNoNl "++" => [[ p "++" ast-postop boa ]] | PrimExpr:p SpacesNoNl "--" => [[ p "--" ast-postop boa ]] From 00827d3b12bcca1f7e7706914592da5cc4d4202a Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 25 Jun 2008 13:14:15 +1200 Subject: [PATCH 0575/1850] Throw error on failed parse, returning relevant error information --- extra/peg/peg.factor | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 54c25778de..0d0d8ed72c 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -9,20 +9,31 @@ IN: peg USE: prettyprint TUPLE: parse-result remaining ast ; - +TUPLE: parse-error details ; +TUPLE: error-details remaining message ; TUPLE: parser id compiled ; - M: parser equal? [ id>> ] bi@ = ; M: parser hashcode* id>> hashcode* ; -C: parser +C: parse-result +C: error-details +C: parser +SYMBOL: errors + +: ( -- parse-error ) + V{ } clone parse-error boa ; + +: add-error ( remaining message -- ) + errors get [ + [ ] [ details>> ] bi* push + ] [ + 2drop + ] if* ; + SYMBOL: ignore -: ( remaining ast -- parse-result ) - parse-result boa ; - SYMBOL: packrat SYMBOL: pos SYMBOL: input @@ -207,6 +218,7 @@ C: peg-head input set 0 pos set f lrstack set + errors set H{ } clone heads set H{ } clone packrat set ] H{ } make-assoc swap bind ; inline @@ -257,7 +269,7 @@ SYMBOL: delayed ] with-compilation-unit ; : compiled-parse ( state word -- result ) - swap [ execute ] with-packrat ; inline + swap [ execute [ errors get throw ] unless* ] with-packrat ; inline : parse ( input parser -- result ) dup word? [ compile ] unless compiled-parse ; @@ -288,7 +300,7 @@ TUPLE: token-parser symbol ; dup >r ?head-slice [ r> ] [ - r> 2drop f + drop input-slice "Expected token '" r> append "'" append add-error f ] if ; M: token-parser (compile) ( parser -- quot ) From e14bb84a5a7fe860c3550bf7de9427917914e875 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 25 Jun 2008 19:37:58 +1200 Subject: [PATCH 0576/1850] More error handling for pegs --- extra/peg/peg.factor | 51 +++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 0d0d8ed72c..a0f5fc05e8 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -1,36 +1,47 @@ ! Copyright (C) 2007, 2008 Chris Double. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences strings fry namespaces math assocs shuffle debugger io - vectors arrays math.parser math.order - unicode.categories compiler.units parser + vectors arrays math.parser math.order vectors combinators combinators.lib + sets unicode.categories compiler.units parser words quotations effects memoize accessors locals effects splitting ; IN: peg USE: prettyprint TUPLE: parse-result remaining ast ; -TUPLE: parse-error details ; -TUPLE: error-details remaining message ; +TUPLE: parse-error position messages ; TUPLE: parser id compiled ; M: parser equal? [ id>> ] bi@ = ; M: parser hashcode* id>> hashcode* ; C: parse-result -C: error-details +C: parse-error C: parser -SYMBOL: errors +SYMBOL: error-stack -: ( -- parse-error ) - V{ } clone parse-error boa ; +: (merge-errors) ( a b -- c ) + { + { [ over position>> not ] [ nip ] } + { [ dup position>> not ] [ drop ] } + [ 2dup [ position>> ] bi@ <=> { + { +lt+ [ nip ] } + { +gt+ [ drop ] } + { +eq+ [ messages>> over messages>> union [ position>> ] dip ] } + } case + ] + } cond ; + +: merge-errors ( -- ) + error-stack get dup length 1 > [ + dup pop over pop swap (merge-errors) swap push + ] [ + drop + ] if ; : add-error ( remaining message -- ) - errors get [ - [ ] [ details>> ] bi* push - ] [ - 2drop - ] if* ; + error-stack get push ; SYMBOL: ignore @@ -218,7 +229,7 @@ C: peg-head input set 0 pos set f lrstack set - errors set + V{ } clone error-stack set H{ } clone heads set H{ } clone packrat set ] H{ } make-assoc swap bind ; inline @@ -269,7 +280,7 @@ SYMBOL: delayed ] with-compilation-unit ; : compiled-parse ( state word -- result ) - swap [ execute [ errors get throw ] unless* ] with-packrat ; inline + swap [ execute [ error-stack get throw ] unless* ] with-packrat ; inline : parse ( input parser -- result ) dup word? [ compile ] unless compiled-parse ; @@ -298,9 +309,9 @@ TUPLE: token-parser symbol ; : parse-token ( input string -- result ) #! Parse the string, returning a parse result dup >r ?head-slice [ - r> + r> f f add-error ] [ - drop input-slice "Expected token '" r> append "'" append add-error f + drop input-slice input-from "Expected token '" r> append "'" append 1vector add-error f ] if ; M: token-parser (compile) ( parser -- quot ) @@ -366,7 +377,8 @@ TUPLE: seq-parser parsers ; M: seq-parser (compile) ( parser -- quot ) [ [ input-slice V{ } clone ] % - parsers>> [ compiled-parser 1quotation , \ parse-seq-element , ] each + parsers>> unclip compiled-parser 1quotation , \ parse-seq-element , [ + compiled-parser 1quotation [ merge-errors ] compose , \ parse-seq-element , ] each ] [ ] make ; TUPLE: choice-parser parsers ; @@ -374,7 +386,8 @@ TUPLE: choice-parser parsers ; M: choice-parser (compile) ( parser -- quot ) [ f , - parsers>> [ compiled-parser 1quotation , \ unless* , ] each + parsers>> [ compiled-parser ] map + unclip 1quotation , \ unless* , [ 1quotation [ merge-errors ] compose , \ unless* , ] each ] [ ] make ; TUPLE: repeat0-parser p1 ; From 9c96edb805ecd81cc0c2c60f93aa918f739940e6 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 11:29:57 +1200 Subject: [PATCH 0577/1850] Fix 'For' statement in JavaScript parser --- extra/peg/javascript/parser/parser.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index 002804dcd8..de6e2bae32 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -105,7 +105,7 @@ Binding = Name:n "=" Expr:v => [[ n v ast-var | Name:n => [[ n "undefined" ast-get boa ast-var boa ]] Block = "{" SrcElems:ss "}" => [[ ss ]] Bindings = (Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]])? -For1 = "var" Binding => [[ second ]] +For1 = "var" Bindings => [[ second ]] | Expr | Spaces => [[ "undefined" ast-get boa ]] For2 = Expr From cf00bc8a0c0d5e3d211e81a099a57ba3374cabac Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 11:54:47 +1200 Subject: [PATCH 0578/1850] Add flags to regexp tokenizer in JavaScript --- extra/peg/javascript/ast/ast.factor | 2 +- extra/peg/javascript/parser/parser.factor | 12 ++++++------ extra/peg/javascript/tokenizer/tokenizer.factor | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/extra/peg/javascript/ast/ast.factor b/extra/peg/javascript/ast/ast.factor index b857dc51bb..47ab6da864 100644 --- a/extra/peg/javascript/ast/ast.factor +++ b/extra/peg/javascript/ast/ast.factor @@ -7,7 +7,7 @@ TUPLE: ast-keyword value ; TUPLE: ast-name value ; TUPLE: ast-number value ; TUPLE: ast-string value ; -TUPLE: ast-regexp value ; +TUPLE: ast-regexp body flags ; TUPLE: ast-cond-expr condition then else ; TUPLE: ast-set lhs rhs ; TUPLE: ast-get value ; diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index de6e2bae32..41387d0a5c 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -26,9 +26,9 @@ End = !(.) Space = " " | "\t" | "\n" Spaces = Space* => [[ ignore ]] Name = . ?[ ast-name? ]? => [[ value>> ]] -Number = . ?[ ast-number? ]? => [[ value>> ]] -String = . ?[ ast-string? ]? => [[ value>> ]] -RegExp = . ?[ ast-regexp? ]? => [[ value>> ]] +Number = . ?[ ast-number? ]? +String = . ?[ ast-string? ]? +RegExp = . ?[ ast-regexp? ]? SpacesNoNl = (!(nl) Space)* => [[ ignore ]] Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-expr boa ]] @@ -85,9 +85,9 @@ PrimExpr = PrimExpr:p "[" Expr:i "]" => [[ i p ast-getp PrimExprHd = "(" Expr:e ")" => [[ e ]] | "this" => [[ ast-this boa ]] | Name => [[ ast-get boa ]] - | Number => [[ ast-number boa ]] - | String => [[ ast-string boa ]] - | RegExp => [[ ast-regexp boa ]] + | Number + | String + | RegExp | "function" FuncRest:fr => [[ fr ]] | "new" PrimExpr:n "(" Args:as ")" => [[ n as ast-new boa ]] | "new" PrimExpr:n => [[ n f ast-new boa ]] diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index 195184a16c..825c8f03d1 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -57,8 +57,9 @@ StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] +RegExpFlags = NameRest* RegExpBody = (!("/" | "\n" | "\r") .)* => [[ >string ]] -RegExp = "/" RegExpBody:r "/" => [[ r ast-regexp boa ]] +RegExp = "/" RegExpBody:b "/" RegExpFlags:fl => [[ b fl ast-regexp boa ]] Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" | "?" | ":" | "!==" | "!=" | "===" | "==" | "=" | ">=" | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" From acb6d3a312dff4450f37a4ffafc1132010a92578 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 14:32:20 +1200 Subject: [PATCH 0579/1850] Fix peg.ebnf tests. Handle \ in EBNF --- extra/peg/ebnf/ebnf-tests.factor | 60 ++++++++++--------- extra/peg/ebnf/ebnf.factor | 1 + .../peg/javascript/tokenizer/tokenizer.factor | 9 ++- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index 2269af6625..a2807d20db 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -132,21 +132,21 @@ IN: peg.ebnf.tests "Z" [EBNF foo=[A-Z] EBNF] call ast>> ] unit-test -{ f } [ +[ "0" [EBNF foo=[A-Z] EBNF] call -] unit-test +] must-fail { CHAR: 0 } [ "0" [EBNF foo=[^A-Z] EBNF] call ast>> ] unit-test -{ f } [ +[ "A" [EBNF foo=[^A-Z] EBNF] call -] unit-test +] must-fail -{ f } [ +[ "Z" [EBNF foo=[^A-Z] EBNF] call -] unit-test +] must-fail { V{ "1" "+" "foo" } } [ "1+1" [EBNF foo='1' '+' '1' [[ drop "foo" ]] EBNF] call ast>> @@ -176,17 +176,17 @@ IN: peg.ebnf.tests { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ast>> ] unit-test -{ f } [ +[ { "a" 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call -] unit-test +] must-fail { 3 } [ { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ast>> ] unit-test -{ f } [ +[ "ab" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] call -] unit-test +] must-fail { V{ "a" " " "b" } } [ "a b" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] call ast>> @@ -229,9 +229,9 @@ IN: peg.ebnf.tests "a\nb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] call ast>> ] unit-test -{ f } [ +[ "axb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] call -] unit-test +] must-fail { V{ V{ 49 } "+" V{ 49 } } } [ #! Test direct left recursion. @@ -314,41 +314,41 @@ main = Primary "abc" [EBNF a="a" "b" foo=a "c" EBNF] call ast>> ] unit-test -{ f } [ +[ "a bc" [EBNF a="a" "b" foo=(a "c") EBNF] call -] unit-test +] must-fail -{ f } [ +[ "a bc" [EBNF a="a" "b" foo=a "c" EBNF] call -] unit-test +] must-fail -{ f } [ +[ "a bc" [EBNF a="a" "b" foo={a "c"} EBNF] call -] unit-test +] must-fail -{ f } [ +[ "ab c" [EBNF a="a" "b" foo=a "c" EBNF] call -] unit-test +] must-fail { V{ V{ "a" "b" } "c" } } [ "ab c" [EBNF a="a" "b" foo={a "c"} EBNF] call ast>> ] unit-test -{ f } [ +[ "ab c" [EBNF a="a" "b" foo=(a "c") EBNF] call -] unit-test +] must-fail -{ f } [ +[ "a b c" [EBNF a="a" "b" foo=a "c" EBNF] call -] unit-test +] must-fail -{ f } [ +[ "a b c" [EBNF a="a" "b" foo=(a "c") EBNF] call -] unit-test +] must-fail -{ f } [ +[ "a b c" [EBNF a="a" "b" foo={a "c"} EBNF] call -] unit-test +] must-fail { V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [ "ab cab c" [EBNF a="a" "b" foo={a "c"}* EBNF] call ast>> @@ -515,4 +515,8 @@ Tok = Spaces (Number | Special ) { "++" } [ "++--" [EBNF tokenizer=("++" | "--") main="++" EBNF] call ast>> +] unit-test + +{ "\\" } [ + "\\" [EBNF foo="\\" EBNF] call ast>> ] unit-test \ No newline at end of file diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 3d48665c8c..610cffd273 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -99,6 +99,7 @@ PEG: escaper ( string -- ast ) "\\t" token [ drop "\t" ] action , "\\n" token [ drop "\n" ] action , "\\r" token [ drop "\r" ] action , + "\\\\" token [ drop "\\" ] action , ] choice* any-char-parser 2array choice repeat0 ; : replace-escapes ( string -- string ) diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index 825c8f03d1..256e478571 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -58,7 +58,14 @@ Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] RegExpFlags = NameRest* -RegExpBody = (!("/" | "\n" | "\r") .)* => [[ >string ]] +NonTerminator = !("\n" | "\r") . +BackslashSequence = "\\" NonTerminator +RegExpFirstChar = !("*" | "\\" | "/") NonTerminator + | BackslashSequence +RegExpChar = !("\\" | "/") NonTerminator + | BackslashSequence +RegExpChars = RegExpChar* +RegExpBody = RegExpFirstChar RegExpChars RegExp = "/" RegExpBody:b "/" RegExpFlags:fl => [[ b fl ast-regexp boa ]] Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" | "?" | ":" | "!==" | "!=" | "===" | "==" | "=" | ">=" From 4394cb08f69896f86b0712931610b6465d9c9b58 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 15:20:12 +1200 Subject: [PATCH 0580/1850] RegExp fix for javascript tokenizer --- extra/peg/javascript/tokenizer/tokenizer-tests.factor | 4 ++++ extra/peg/javascript/tokenizer/tokenizer.factor | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/extra/peg/javascript/tokenizer/tokenizer-tests.factor b/extra/peg/javascript/tokenizer/tokenizer-tests.factor index 509ff4a0fe..a61125d08c 100644 --- a/extra/peg/javascript/tokenizer/tokenizer-tests.factor +++ b/extra/peg/javascript/tokenizer/tokenizer-tests.factor @@ -21,3 +21,7 @@ IN: peg.javascript.tokenizer.tests } [ "123; 'hello'; foo(x);" tokenize-javascript ast>> ] unit-test + +{ V{ T{ ast-regexp f "<(w+)[^>]*?)/>" "g" } } } [ + "/<(\\w+)[^>]*?)\\/>/g" tokenize-javascript ast>> +] unit-test \ No newline at end of file diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index 256e478571..f65b0b2ad6 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -57,15 +57,15 @@ StringChars3 = (EscapeChar | !("'") .)* => [[ >string ]] Str = '"""' StringChars1:cs '"""' => [[ cs ast-string boa ]] | '"' StringChars2:cs '"' => [[ cs ast-string boa ]] | "'" StringChars3:cs "'" => [[ cs ast-string boa ]] -RegExpFlags = NameRest* +RegExpFlags = NameRest* => [[ >string ]] NonTerminator = !("\n" | "\r") . -BackslashSequence = "\\" NonTerminator +BackslashSequence = "\\" NonTerminator => [[ second ]] RegExpFirstChar = !("*" | "\\" | "/") NonTerminator | BackslashSequence RegExpChar = !("\\" | "/") NonTerminator | BackslashSequence RegExpChars = RegExpChar* -RegExpBody = RegExpFirstChar RegExpChars +RegExpBody = RegExpFirstChar RegExpChars => [[ first2 swap prefix >string ]] RegExp = "/" RegExpBody:b "/" RegExpFlags:fl => [[ b fl ast-regexp boa ]] Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" | "?" | ":" | "!==" | "!=" | "===" | "==" | "=" | ">=" From 7404c5dc01026b19b1f69bf7d8e4181758cdfc20 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 16:04:57 +1200 Subject: [PATCH 0581/1850] Add ShiftExpr to JavaScript parser --- extra/peg/javascript/parser/parser.factor | 14 +++++++++----- extra/peg/javascript/tokenizer/tokenizer.factor | 6 +++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index 41387d0a5c..e491c35d2b 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -51,11 +51,15 @@ EqExpr = EqExpr:x "==" RelExpr:y => [[ x y "==" ast-binop | EqExpr:x "===" RelExpr:y => [[ x y "===" ast-binop boa ]] | EqExpr:x "!==" RelExpr:y => [[ x y "!==" ast-binop boa ]] | RelExpr -RelExpr = RelExpr:x ">" AddExpr:y => [[ x y ">" ast-binop boa ]] - | RelExpr:x ">=" AddExpr:y => [[ x y ">=" ast-binop boa ]] - | RelExpr:x "<" AddExpr:y => [[ x y "<" ast-binop boa ]] - | RelExpr:x "<=" AddExpr:y => [[ x y "<=" ast-binop boa ]] - | RelExpr:x "instanceof" AddExpr:y => [[ x y "instanceof" ast-binop boa ]] +RelExpr = RelExpr:x ">" ShiftExpr:y => [[ x y ">" ast-binop boa ]] + | RelExpr:x ">=" ShiftExpr:y => [[ x y ">=" ast-binop boa ]] + | RelExpr:x "<" ShiftExpr:y => [[ x y "<" ast-binop boa ]] + | RelExpr:x "<=" ShiftExpr:y => [[ x y "<=" ast-binop boa ]] + | RelExpr:x "instanceof" ShiftExpr:y => [[ x y "instanceof" ast-binop boa ]] + | ShiftExpr +ShiftExpr = ShiftExpr:x "<<" AddExpr:y => [[ x y "<<" ast-binop boa ]] + | ShiftExpr:x ">>>" AddExpr:y => [[ x y ">>>" ast-binop boa ]] + | ShiftExpr:x ">>" AddExpr:y => [[ x y ">>" ast-binop boa ]] | AddExpr AddExpr = AddExpr:x "+" MulExpr:y => [[ x y "+" ast-binop boa ]] | AddExpr:x "-" MulExpr:y => [[ x y "-" ast-binop boa ]] diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index f65b0b2ad6..0698c8427e 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -69,9 +69,9 @@ RegExpBody = RegExpFirstChar RegExpChars => [[ first2 swap prefix >strin RegExp = "/" RegExpBody:b "/" RegExpFlags:fl => [[ b fl ast-regexp boa ]] Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" | "?" | ":" | "!==" | "!=" | "===" | "==" | "=" | ">=" - | ">" | "<=" | "<" | "++" | "+=" | "+" | "--" | "-=" - | "-" | "*=" | "*" | "/=" | "/" | "%=" | "%" | "&&=" - | "&&" | "||=" | "||" | "." | "!" + | ">>>" | ">>" | ">" | "<=" | "<<" | "<" | "++" | "+=" + | "+" | "--" | "-=" | "-" | "*=" | "*" | "/=" | "/" + | "%=" | "%" | "&&=" | "&&" | "||=" | "||" | "." | "!" Tok = Spaces (Name | Keyword | Number | Str | RegExp | Special ) Toks = Tok* Spaces ;EBNF From bf664e7ec895b07ae1c7f3fc00ca54e67de5c5b3 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 16:16:13 +1200 Subject: [PATCH 0582/1850] Add ShiftExpr to JavaScript parser --- extra/peg/javascript/parser/parser.factor | 1 + 1 file changed, 1 insertion(+) diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index e491c35d2b..39bab79ea9 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -56,6 +56,7 @@ RelExpr = RelExpr:x ">" ShiftExpr:y => [[ x y ">" ast-bino | RelExpr:x "<" ShiftExpr:y => [[ x y "<" ast-binop boa ]] | RelExpr:x "<=" ShiftExpr:y => [[ x y "<=" ast-binop boa ]] | RelExpr:x "instanceof" ShiftExpr:y => [[ x y "instanceof" ast-binop boa ]] + | RelExpr:x "in" ShiftExpr:y => [[ x y "in" ast-binop boa ]] | ShiftExpr ShiftExpr = ShiftExpr:x "<<" AddExpr:y => [[ x y "<<" ast-binop boa ]] | ShiftExpr:x ">>>" AddExpr:y => [[ x y ">>>" ast-binop boa ]] From 87bbe8cae162c828e04a7af15ac5f3fa2d0f4b4e Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 18:24:59 +1200 Subject: [PATCH 0583/1850] Get for(x in y) { } working in js parser --- extra/peg/javascript/parser/parser.factor | 32 ++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index 39bab79ea9..2736496cc7 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -42,15 +42,35 @@ Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-exp | OrExpr:e "||=" Expr:rhs => [[ e rhs "||" ast-mset boa ]] | OrExpr:e => [[ e ]] +ExprNoIn = OrExprNoIn:e "?" ExprNoIn:t ":" ExprNoIn:f => [[ e t f ast-cond-expr boa ]] + | OrExprNoIn:e "=" ExprNoIn:rhs => [[ e rhs ast-set boa ]] + | OrExprNoIn:e "+=" ExprNoIn:rhs => [[ e rhs "+" ast-mset boa ]] + | OrExprNoIn:e "-=" ExprNoIn:rhs => [[ e rhs "-" ast-mset boa ]] + | OrExprNoIn:e "*=" ExprNoIn:rhs => [[ e rhs "*" ast-mset boa ]] + | OrExprNoIn:e "/=" ExprNoIn:rhs => [[ e rhs "/" ast-mset boa ]] + | OrExprNoIn:e "%=" ExprNoIn:rhs => [[ e rhs "%" ast-mset boa ]] + | OrExprNoIn:e "&&=" ExprNoIn:rhs => [[ e rhs "&&" ast-mset boa ]] + | OrExprNoIn:e "||=" ExprNoIn:rhs => [[ e rhs "||" ast-mset boa ]] + | OrExprNoIn:e => [[ e ]] + OrExpr = OrExpr:x "||" AndExpr:y => [[ x y "||" ast-binop boa ]] | AndExpr +OrExprNoIn = OrExprNoIn:x "||" AndExprNoIn:y => [[ x y "||" ast-binop boa ]] + | AndExprNoIn AndExpr = AndExpr:x "&&" EqExpr:y => [[ x y "&&" ast-binop boa ]] | EqExpr +AndExprNoIn = AndExprNoIn:x "&&" EqExprNoIn:y => [[ x y "&&" ast-binop boa ]] + | EqExprNoIn EqExpr = EqExpr:x "==" RelExpr:y => [[ x y "==" ast-binop boa ]] | EqExpr:x "!=" RelExpr:y => [[ x y "!=" ast-binop boa ]] | EqExpr:x "===" RelExpr:y => [[ x y "===" ast-binop boa ]] | EqExpr:x "!==" RelExpr:y => [[ x y "!==" ast-binop boa ]] | RelExpr +EqExprNoIn = EqExprNoIn:x "==" RelExprNoIn:y => [[ x y "==" ast-binop boa ]] + | EqExprNoIn:x "!=" RelExprNoIn:y => [[ x y "!=" ast-binop boa ]] + | EqExprNoIn:x "===" RelExprNoIn:y => [[ x y "===" ast-binop boa ]] + | EqExprNoIn:x "!==" RelExprNoIn:y => [[ x y "!==" ast-binop boa ]] + | RelExprNoIn RelExpr = RelExpr:x ">" ShiftExpr:y => [[ x y ">" ast-binop boa ]] | RelExpr:x ">=" ShiftExpr:y => [[ x y ">=" ast-binop boa ]] | RelExpr:x "<" ShiftExpr:y => [[ x y "<" ast-binop boa ]] @@ -58,6 +78,12 @@ RelExpr = RelExpr:x ">" ShiftExpr:y => [[ x y ">" ast-bino | RelExpr:x "instanceof" ShiftExpr:y => [[ x y "instanceof" ast-binop boa ]] | RelExpr:x "in" ShiftExpr:y => [[ x y "in" ast-binop boa ]] | ShiftExpr +RelExprNoIn = RelExprNoIn:x ">" ShiftExpr:y => [[ x y ">" ast-binop boa ]] + | RelExprNoIn:x ">=" ShiftExpr:y => [[ x y ">=" ast-binop boa ]] + | RelExprNoIn:x "<" ShiftExpr:y => [[ x y "<" ast-binop boa ]] + | RelExprNoIn:x "<=" ShiftExpr:y => [[ x y "<=" ast-binop boa ]] + | RelExprNoIn:x "instanceof" ShiftExpr:y => [[ x y "instanceof" ast-binop boa ]] + | ShiftExpr ShiftExpr = ShiftExpr:x "<<" AddExpr:y => [[ x y "<<" ast-binop boa ]] | ShiftExpr:x ">>>" AddExpr:y => [[ x y ">>>" ast-binop boa ]] | ShiftExpr:x ">>" AddExpr:y => [[ x y ">>" ast-binop boa ]] @@ -98,7 +124,7 @@ PrimExprHd = "(" Expr:e ")" => [[ e ]] | "new" PrimExpr:n => [[ n f ast-new boa ]] | "[" Args:es "]" => [[ es ast-array boa ]] | Json -JsonBindings = (JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]])? +JsonBindings = (JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]])? Json = "{" JsonBindings:bs "}" => [[ bs ast-json boa ]] JsonBinding = JsonPropName:n ":" Expr:v => [[ n v ast-binding boa ]] JsonPropName = Name | Number | String | RegExp @@ -111,14 +137,14 @@ Binding = Name:n "=" Expr:v => [[ n v ast-var Block = "{" SrcElems:ss "}" => [[ ss ]] Bindings = (Binding ("," Binding => [[ second ]])* => [[ first2 swap prefix ]])? For1 = "var" Bindings => [[ second ]] - | Expr + | ExprNoIn | Spaces => [[ "undefined" ast-get boa ]] For2 = Expr | Spaces => [[ "true" ast-get boa ]] For3 = Expr | Spaces => [[ "undefined" ast-get boa ]] ForIn1 = "var" Name:n => [[ n "undefined" ast-get boa ast-var boa ]] - | Expr + | PrimExprHd Switch1 = "case" Expr:c ":" SrcElems:cs => [[ c cs ast-case boa ]] | "default" ":" SrcElems:cs => [[ cs ast-default boa ]] SwitchBody = Switch1* From 8f718fa41eab364708867cc60d2a8f9644b1b765 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 19:05:18 +1200 Subject: [PATCH 0584/1850] Parse more valid JavaScript --- extra/peg/javascript/parser/parser.factor | 28 +++++++++++++++++-- .../peg/javascript/tokenizer/tokenizer.factor | 12 ++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index 2736496cc7..45da7c3bb4 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -40,6 +40,12 @@ Expr = OrExpr:e "?" Expr:t ":" Expr:f => [[ e t f ast-cond-exp | OrExpr:e "%=" Expr:rhs => [[ e rhs "%" ast-mset boa ]] | OrExpr:e "&&=" Expr:rhs => [[ e rhs "&&" ast-mset boa ]] | OrExpr:e "||=" Expr:rhs => [[ e rhs "||" ast-mset boa ]] + | OrExpr:e "^=" Expr:rhs => [[ e rhs "^" ast-mset boa ]] + | OrExpr:e "&=" Expr:rhs => [[ e rhs "&" ast-mset boa ]] + | OrExpr:e "|=" Expr:rhs => [[ e rhs "|" ast-mset boa ]] + | OrExpr:e "<<=" Expr:rhs => [[ e rhs "<<" ast-mset boa ]] + | OrExpr:e ">>=" Expr:rhs => [[ e rhs ">>" ast-mset boa ]] + | OrExpr:e ">>>=" Expr:rhs => [[ e rhs ">>>" ast-mset boa ]] | OrExpr:e => [[ e ]] ExprNoIn = OrExprNoIn:e "?" ExprNoIn:t ":" ExprNoIn:f => [[ e t f ast-cond-expr boa ]] @@ -51,15 +57,33 @@ ExprNoIn = OrExprNoIn:e "?" ExprNoIn:t ":" ExprNoIn:f => [[ e t f as | OrExprNoIn:e "%=" ExprNoIn:rhs => [[ e rhs "%" ast-mset boa ]] | OrExprNoIn:e "&&=" ExprNoIn:rhs => [[ e rhs "&&" ast-mset boa ]] | OrExprNoIn:e "||=" ExprNoIn:rhs => [[ e rhs "||" ast-mset boa ]] + | OrExprNoIn:e "^=" ExprNoIn:rhs => [[ e rhs "^" ast-mset boa ]] + | OrExprNoIn:e "&=" ExprNoIn:rhs => [[ e rhs "&" ast-mset boa ]] + | OrExprNoIn:e "|=" ExprNoIn:rhs => [[ e rhs "|" ast-mset boa ]] + | OrExprNoIn:e "<<=" ExprNoIn:rhs => [[ e rhs "<<" ast-mset boa ]] + | OrExprNoIn:e ">>=" ExprNoIn:rhs => [[ e rhs ">>" ast-mset boa ]] + | OrExprNoIn:e ">>>=" ExprNoIn:rhs => [[ e rhs ">>>" ast-mset boa ]] | OrExprNoIn:e => [[ e ]] OrExpr = OrExpr:x "||" AndExpr:y => [[ x y "||" ast-binop boa ]] | AndExpr OrExprNoIn = OrExprNoIn:x "||" AndExprNoIn:y => [[ x y "||" ast-binop boa ]] | AndExprNoIn -AndExpr = AndExpr:x "&&" EqExpr:y => [[ x y "&&" ast-binop boa ]] +AndExpr = AndExpr:x "&&" BitOrExpr:y => [[ x y "&&" ast-binop boa ]] + | BitOrExpr +AndExprNoIn = AndExprNoIn:x "&&" BitOrExprNoIn:y => [[ x y "&&" ast-binop boa ]] + | BitOrExprNoIn +BitOrExpr = BitOrExpr:x "|" BitXORExpr:y => [[ x y "|" ast-binop boa ]] + | BitXORExpr +BitOrExprNoIn = BitOrExprNoIn:x "|" BitXORExprNoIn:y => [[ x y "|" ast-binop boa ]] + | BitXORExprNoIn +BitXORExpr = BitXORExpr:x "^" BitANDExpr:y => [[ x y "^" ast-binop boa ]] + | BitANDExpr +BitXORExprNoIn = BitXORExprNoIn:x "^" BitANDExprNoIn:y => [[ x y "^" ast-binop boa ]] + | BitANDExprNoIn +BitANDExpr = BitANDExpr:x "&" EqExpr:y => [[ x y "&" ast-binop boa ]] | EqExpr -AndExprNoIn = AndExprNoIn:x "&&" EqExprNoIn:y => [[ x y "&&" ast-binop boa ]] +BitANDExprNoIn = BitANDExprNoIn:x "&" EqExprNoIn:y => [[ x y "&" ast-binop boa ]] | EqExprNoIn EqExpr = EqExpr:x "==" RelExpr:y => [[ x y "==" ast-binop boa ]] | EqExpr:x "!=" RelExpr:y => [[ x y "!=" ast-binop boa ]] diff --git a/extra/peg/javascript/tokenizer/tokenizer.factor b/extra/peg/javascript/tokenizer/tokenizer.factor index 0698c8427e..30a3b5e7a5 100644 --- a/extra/peg/javascript/tokenizer/tokenizer.factor +++ b/extra/peg/javascript/tokenizer/tokenizer.factor @@ -67,11 +67,13 @@ RegExpChar = !("\\" | "/") NonTerminator RegExpChars = RegExpChar* RegExpBody = RegExpFirstChar RegExpChars => [[ first2 swap prefix >string ]] RegExp = "/" RegExpBody:b "/" RegExpFlags:fl => [[ b fl ast-regexp boa ]] -Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" - | "?" | ":" | "!==" | "!=" | "===" | "==" | "=" | ">=" - | ">>>" | ">>" | ">" | "<=" | "<<" | "<" | "++" | "+=" - | "+" | "--" | "-=" | "-" | "*=" | "*" | "/=" | "/" - | "%=" | "%" | "&&=" | "&&" | "||=" | "||" | "." | "!" +Special = "(" | ")" | "{" | "}" | "[" | "]" | "," | ";" + | "?" | ":" | "!==" | "!=" | "===" | "==" | "=" | ">=" + | ">>>=" | ">>>" | ">>=" | ">>" | ">" | "<=" | "<<=" | "<<" + | "<" | "++" | "+=" | "+" | "--" | "-=" | "-" | "*=" + | "*" | "/=" | "/" | "%=" | "%" | "&&=" | "&&" | "||=" + | "||" | "." | "!" | "&=" | "&" | "|=" | "|" | "^=" + | "^" Tok = Spaces (Name | Keyword | Number | Str | RegExp | Special ) Toks = Tok* Spaces ;EBNF From c8511b483fa911f63e58f4ed171df76186632346 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Mon, 30 Jun 2008 19:25:23 +1200 Subject: [PATCH 0585/1850] Add support for 'with' in js parser. Now parses jquery successfully --- extra/peg/javascript/ast/ast.factor | 1 + extra/peg/javascript/parser/parser.factor | 1 + 2 files changed, 2 insertions(+) diff --git a/extra/peg/javascript/ast/ast.factor b/extra/peg/javascript/ast/ast.factor index 47ab6da864..9f67af86aa 100644 --- a/extra/peg/javascript/ast/ast.factor +++ b/extra/peg/javascript/ast/ast.factor @@ -38,5 +38,6 @@ TUPLE: ast-continue ; TUPLE: ast-throw e ; TUPLE: ast-try t e c f ; TUPLE: ast-return e ; +TUPLE: ast-with expr body ; TUPLE: ast-case c cs ; TUPLE: ast-default cs ; diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index 45da7c3bb4..7ace528150 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -189,6 +189,7 @@ Stmt = Block | "try" Block:t "catch" "(" Name:e ")" Block:c Finally:f => [[ t e c f ast-try boa ]] | "return" Expr:e Sc => [[ e ast-return boa ]] | "return" Sc => [[ "undefined" ast-get boa ast-return boa ]] + | "with" "(" Expr:e ")" Stmt:b => [[ e b ast-with boa ]] | Expr:e Sc => [[ e ]] | ";" => [[ "undefined" ast-get boa ]] SrcElem = "function" Name:n FuncRest:f => [[ n f ast-var boa ]] From b5cef674b1f99dbb3d763cd162f1891857c40c76 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 3 Jul 2008 16:52:22 +1200 Subject: [PATCH 0586/1850] Pegs throw exceptions on error now --- extra/peg/parsers/parsers-tests.factor | 65 ++++++++++++-------------- extra/peg/peg-tests.factor | 60 ++++++++++++------------ extra/peg/peg.factor | 2 +- 3 files changed, 62 insertions(+), 65 deletions(-) diff --git a/extra/peg/parsers/parsers-tests.factor b/extra/peg/parsers/parsers-tests.factor index e80baf3c4f..0cf3ad8b17 100644 --- a/extra/peg/parsers/parsers-tests.factor +++ b/extra/peg/parsers/parsers-tests.factor @@ -1,54 +1,51 @@ -USING: kernel peg peg.parsers tools.test ; +USING: kernel peg peg.parsers tools.test accessors ; IN: peg.parsers.tests -[ V{ "a" } ] -[ "a" "a" token "," token list-of parse parse-result-ast ] unit-test +{ V{ "a" } } +[ "a" "a" token "," token list-of parse ast>> ] unit-test -[ V{ "a" "a" "a" "a" } ] -[ "a,a,a,a" "a" token "," token list-of parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "a,a,a,a" "a" token "," token list-of parse ast>> ] unit-test -[ f ] -[ "a" "a" token "," token list-of-many parse ] unit-test +[ "a" "a" token "," token list-of-many parse ] must-fail -[ V{ "a" "a" "a" "a" } ] -[ "a,a,a,a" "a" token "," token list-of-many parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "a,a,a,a" "a" token "," token list-of-many parse ast>> ] unit-test -[ f ] -[ "aaa" "a" token 4 exactly-n parse ] unit-test +[ "aaa" "a" token 4 exactly-n parse ] must-fail -[ V{ "a" "a" "a" "a" } ] -[ "aaaa" "a" token 4 exactly-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "aaaa" "a" token 4 exactly-n parse ast>> ] unit-test -[ f ] -[ "aaa" "a" token 4 at-least-n parse ] unit-test +[ "aaa" "a" token 4 at-least-n parse ] must-fail -[ V{ "a" "a" "a" "a" } ] -[ "aaaa" "a" token 4 at-least-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "aaaa" "a" token 4 at-least-n parse ast>> ] unit-test -[ V{ "a" "a" "a" "a" "a" } ] -[ "aaaaa" "a" token 4 at-least-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" "a" } } +[ "aaaaa" "a" token 4 at-least-n parse ast>> ] unit-test -[ V{ "a" "a" "a" "a" } ] -[ "aaaa" "a" token 4 at-most-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "aaaa" "a" token 4 at-most-n parse ast>> ] unit-test -[ V{ "a" "a" "a" "a" } ] -[ "aaaaa" "a" token 4 at-most-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "aaaaa" "a" token 4 at-most-n parse ast>> ] unit-test -[ V{ "a" "a" "a" } ] -[ "aaa" "a" token 3 4 from-m-to-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" } } +[ "aaa" "a" token 3 4 from-m-to-n parse ast>> ] unit-test -[ V{ "a" "a" "a" "a" } ] -[ "aaaa" "a" token 3 4 from-m-to-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "aaaa" "a" token 3 4 from-m-to-n parse ast>> ] unit-test -[ V{ "a" "a" "a" "a" } ] -[ "aaaaa" "a" token 3 4 from-m-to-n parse parse-result-ast ] unit-test +{ V{ "a" "a" "a" "a" } } +[ "aaaaa" "a" token 3 4 from-m-to-n parse ast>> ] unit-test -[ 97 ] -[ "a" any-char parse parse-result-ast ] unit-test +{ 97 } +[ "a" any-char parse ast>> ] unit-test -[ V{ } ] -[ "" epsilon parse parse-result-ast ] unit-test +{ V{ } } +[ "" epsilon parse ast>> ] unit-test { "a" } [ - "a" "a" token just parse parse-result-ast + "a" "a" token just parse ast>> ] unit-test \ No newline at end of file diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor index 1beeb51678..466da83b6e 100644 --- a/extra/peg/peg-tests.factor +++ b/extra/peg/peg-tests.factor @@ -5,9 +5,9 @@ USING: kernel tools.test strings namespaces arrays sequences peg peg.private accessors words math accessors ; IN: peg.tests -{ f } [ +[ "endbegin" "begin" token parse -] unit-test +] must-fail { "begin" "end" } [ "beginend" "begin" token parse @@ -15,13 +15,13 @@ IN: peg.tests >string ] unit-test -{ f } [ +[ "" CHAR: a CHAR: z range parse -] unit-test +] must-fail -{ f } [ +[ "1bcd" CHAR: a CHAR: z range parse -] unit-test +] must-fail { CHAR: a } [ "abcd" CHAR: a CHAR: z range parse ast>> @@ -31,9 +31,9 @@ IN: peg.tests "zbcd" CHAR: a CHAR: z range parse ast>> ] unit-test -{ f } [ +[ "bad" "a" token "b" token 2array seq parse -] unit-test +] must-fail { V{ "g" "o" } } [ "good" "g" token "o" token 2array seq parse ast>> @@ -47,13 +47,13 @@ IN: peg.tests "bbcd" "a" token "b" token 2array choice parse ast>> ] unit-test -{ f } [ +[ "cbcd" "a" token "b" token 2array choice parse -] unit-test +] must-fail -{ f } [ +[ "" "a" token "b" token 2array choice parse -] unit-test +] must-fail { 0 } [ "" "a" token repeat0 parse ast>> length @@ -67,13 +67,13 @@ IN: peg.tests "aaab" "a" token repeat0 parse ast>> ] unit-test -{ f } [ +[ "" "a" token repeat1 parse -] unit-test +] must-fail -{ f } [ +[ "b" "a" token repeat1 parse -] unit-test +] must-fail { V{ "a" "a" "a" } } [ "aaab" "a" token repeat1 parse ast>> @@ -87,17 +87,17 @@ IN: peg.tests "b" "a" token optional "b" token 2array seq parse ast>> ] unit-test -{ f } [ +[ "cb" "a" token optional "b" token 2array seq parse -] unit-test +] must-fail { V{ CHAR: a CHAR: b } } [ "ab" "a" token ensure CHAR: a CHAR: z range dup 3array seq parse ast>> ] unit-test -{ f } [ +[ "bb" "a" token ensure CHAR: a CHAR: z range 2array seq parse -] unit-test +] must-fail { t } [ "a+b" @@ -117,11 +117,11 @@ IN: peg.tests parse [ t ] [ f ] if ] unit-test -{ f } [ +[ "a++b" "a" token "+" token "++" token 2array choice "b" token 3array seq parse [ t ] [ f ] if -] unit-test +] must-fail { 1 } [ "a" "a" token [ drop 1 ] action parse ast>> @@ -131,13 +131,13 @@ IN: peg.tests "aa" "a" token [ drop 1 ] action dup 2array seq parse ast>> ] unit-test -{ f } [ +[ "b" "a" token [ drop 1 ] action parse -] unit-test +] must-fail -{ f } [ +[ "b" [ CHAR: a = ] satisfy parse -] unit-test +] must-fail { CHAR: a } [ "a" [ CHAR: a = ] satisfy parse ast>> @@ -155,9 +155,9 @@ IN: peg.tests "[a]" "[" token hide "a" token "]" token hide 3array seq parse ast>> ] unit-test -{ f } [ +[ "a]" "[" token hide "a" token "]" token hide 3array seq parse -] unit-test +] must-fail { V{ "1" "-" "1" } V{ "1" "+" "1" } } [ @@ -185,9 +185,9 @@ IN: peg.tests dupd 0 swap set-nth compile word? ] unit-test -{ f } [ +[ "A" [ drop t ] satisfy [ 66 >= ] semantic parse -] unit-test +] must-fail { CHAR: B } [ "B" [ drop t ] satisfy [ 66 >= ] semantic parse ast>> diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index a0f5fc05e8..a9695f90d8 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -280,7 +280,7 @@ SYMBOL: delayed ] with-compilation-unit ; : compiled-parse ( state word -- result ) - swap [ execute [ error-stack get throw ] unless* ] with-packrat ; inline + swap [ execute [ error-stack get first throw ] unless* ] with-packrat ; inline : parse ( input parser -- result ) dup word? [ compile ] unless compiled-parse ; From e47f944ccab3571c3fbc37700a5adf0954472f8b Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 3 Jul 2008 17:38:28 +1200 Subject: [PATCH 0587/1850] Print error message nicely --- extra/peg/peg.factor | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index a9695f90d8..d388bbd124 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -19,6 +19,10 @@ C: parse-result C: parse-error C: parser +M: parse-error error. + "Peg parsing error at character position " write dup position>> number>string write + "." print "Expected " write messages>> [ " or " write ] [ write ] interleave nl ; + SYMBOL: error-stack : (merge-errors) ( a b -- c ) @@ -311,7 +315,7 @@ TUPLE: token-parser symbol ; dup >r ?head-slice [ r> f f add-error ] [ - drop input-slice input-from "Expected token '" r> append "'" append 1vector add-error f + drop input-slice input-from "token '" r> append "'" append 1vector add-error f ] if ; M: token-parser (compile) ( parser -- quot ) From 8aa7bc6d78a0c6d64b56a0a5fa78253961665671 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Fri, 4 Jul 2008 12:32:02 +1200 Subject: [PATCH 0588/1850] [EBNF ... EBNF] now does an implicit call --- extra/peg/ebnf/ebnf-tests.factor | 126 +++++++++++++++---------------- extra/peg/ebnf/ebnf.factor | 3 +- 2 files changed, 65 insertions(+), 64 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index a2807d20db..ba34248159 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -113,142 +113,142 @@ IN: peg.ebnf.tests ] unit-test { V{ "a" "b" } } [ - "ab" [EBNF foo='a' 'b' EBNF] call ast>> + "ab" [EBNF foo='a' 'b' EBNF] ast>> ] unit-test { V{ 1 "b" } } [ - "ab" [EBNF foo=('a')[[ drop 1 ]] 'b' EBNF] call ast>> + "ab" [EBNF foo=('a')[[ drop 1 ]] 'b' EBNF] ast>> ] unit-test { V{ 1 2 } } [ - "ab" [EBNF foo=('a') [[ drop 1 ]] ('b') [[ drop 2 ]] EBNF] call ast>> + "ab" [EBNF foo=('a') [[ drop 1 ]] ('b') [[ drop 2 ]] EBNF] ast>> ] unit-test { CHAR: A } [ - "A" [EBNF foo=[A-Z] EBNF] call ast>> + "A" [EBNF foo=[A-Z] EBNF] ast>> ] unit-test { CHAR: Z } [ - "Z" [EBNF foo=[A-Z] EBNF] call ast>> + "Z" [EBNF foo=[A-Z] EBNF] ast>> ] unit-test [ - "0" [EBNF foo=[A-Z] EBNF] call + "0" [EBNF foo=[A-Z] EBNF] ] must-fail { CHAR: 0 } [ - "0" [EBNF foo=[^A-Z] EBNF] call ast>> + "0" [EBNF foo=[^A-Z] EBNF] ast>> ] unit-test [ - "A" [EBNF foo=[^A-Z] EBNF] call + "A" [EBNF foo=[^A-Z] EBNF] ] must-fail [ - "Z" [EBNF foo=[^A-Z] EBNF] call + "Z" [EBNF foo=[^A-Z] EBNF] ] must-fail { V{ "1" "+" "foo" } } [ - "1+1" [EBNF foo='1' '+' '1' [[ drop "foo" ]] EBNF] call ast>> + "1+1" [EBNF foo='1' '+' '1' [[ drop "foo" ]] EBNF] ast>> ] unit-test { "foo" } [ - "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] EBNF] call ast>> + "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] EBNF] ast>> ] unit-test { "foo" } [ - "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] call ast>> + "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] ast>> ] unit-test { "bar" } [ - "1-1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] call ast>> + "1-1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] ast>> ] unit-test { 6 } [ - "4+2" [EBNF num=[0-9] => [[ digit> ]] foo=num:x '+' num:y => [[ x y + ]] EBNF] call ast>> + "4+2" [EBNF num=[0-9] => [[ digit> ]] foo=num:x '+' num:y => [[ x y + ]] EBNF] ast>> ] unit-test { 6 } [ - "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ x digit> y digit> + ]] EBNF] call ast>> + "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ x digit> y digit> + ]] EBNF] ast>> ] unit-test { 10 } [ - { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ast>> + { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ast>> ] unit-test [ - { "a" 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call + { "a" 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ] must-fail { 3 } [ - { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] call ast>> + { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ast>> ] unit-test [ - "ab" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] call + "ab" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ] must-fail { V{ "a" " " "b" } } [ - "a b" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] call ast>> + "a b" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ast>> ] unit-test { V{ "a" "\t" "b" } } [ - "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] call ast>> + "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ast>> ] unit-test { V{ "a" "\n" "b" } } [ - "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] call ast>> + "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ast>> ] unit-test { V{ "a" f "b" } } [ - "ab" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] call ast>> + "ab" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> ] unit-test { V{ "a" " " "b" } } [ - "a b" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] call ast>> + "a b" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> ] unit-test { V{ "a" "\t" "b" } } [ - "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] call ast>> + "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> ] unit-test { V{ "a" "\n" "b" } } [ - "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] call ast>> + "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> ] unit-test { V{ "a" "b" } } [ - "ab" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] call ast>> + "ab" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ast>> ] unit-test { V{ "a" "b" } } [ - "a\tb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] call ast>> + "a\tb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ast>> ] unit-test { V{ "a" "b" } } [ - "a\nb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] call ast>> + "a\nb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ast>> ] unit-test [ - "axb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] call + "axb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ] must-fail { V{ V{ 49 } "+" V{ 49 } } } [ #! Test direct left recursion. #! Using packrat, so first part of expr fails, causing 2nd choice to be used - "1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call ast>> + "1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] ast>> ] unit-test { V{ V{ V{ 49 } "+" V{ 49 } } "+" V{ 49 } } } [ #! Test direct left recursion. #! Using packrat, so first part of expr fails, causing 2nd choice to be used - "1+1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call ast>> + "1+1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] ast>> ] unit-test { V{ V{ V{ 49 } "+" V{ 49 } } "+" V{ 49 } } } [ #! Test indirect left recursion. #! Using packrat, so first part of expr fails, causing 2nd choice to be used - "1+1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] call ast>> + "1+1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] ast>> ] unit-test { t } [ @@ -303,85 +303,85 @@ main = Primary 'ebnf' compile must-infer { V{ V{ "a" "b" } "c" } } [ - "abc" [EBNF a="a" "b" foo=(a "c") EBNF] call ast>> + "abc" [EBNF a="a" "b" foo=(a "c") EBNF] ast>> ] unit-test { V{ V{ "a" "b" } "c" } } [ - "abc" [EBNF a="a" "b" foo={a "c"} EBNF] call ast>> + "abc" [EBNF a="a" "b" foo={a "c"} EBNF] ast>> ] unit-test { V{ V{ "a" "b" } "c" } } [ - "abc" [EBNF a="a" "b" foo=a "c" EBNF] call ast>> + "abc" [EBNF a="a" "b" foo=a "c" EBNF] ast>> ] unit-test [ - "a bc" [EBNF a="a" "b" foo=(a "c") EBNF] call + "a bc" [EBNF a="a" "b" foo=(a "c") EBNF] ] must-fail [ - "a bc" [EBNF a="a" "b" foo=a "c" EBNF] call + "a bc" [EBNF a="a" "b" foo=a "c" EBNF] ] must-fail [ - "a bc" [EBNF a="a" "b" foo={a "c"} EBNF] call + "a bc" [EBNF a="a" "b" foo={a "c"} EBNF] ] must-fail [ - "ab c" [EBNF a="a" "b" foo=a "c" EBNF] call + "ab c" [EBNF a="a" "b" foo=a "c" EBNF] ] must-fail { V{ V{ "a" "b" } "c" } } [ - "ab c" [EBNF a="a" "b" foo={a "c"} EBNF] call ast>> + "ab c" [EBNF a="a" "b" foo={a "c"} EBNF] ast>> ] unit-test [ - "ab c" [EBNF a="a" "b" foo=(a "c") EBNF] call + "ab c" [EBNF a="a" "b" foo=(a "c") EBNF] ] must-fail [ - "a b c" [EBNF a="a" "b" foo=a "c" EBNF] call + "a b c" [EBNF a="a" "b" foo=a "c" EBNF] ] must-fail [ - "a b c" [EBNF a="a" "b" foo=(a "c") EBNF] call + "a b c" [EBNF a="a" "b" foo=(a "c") EBNF] ] must-fail [ - "a b c" [EBNF a="a" "b" foo={a "c"} EBNF] call + "a b c" [EBNF a="a" "b" foo={a "c"} EBNF] ] must-fail { V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [ - "ab cab c" [EBNF a="a" "b" foo={a "c"}* EBNF] call ast>> + "ab cab c" [EBNF a="a" "b" foo={a "c"}* EBNF] ast>> ] unit-test { V{ } } [ - "ab cab c" [EBNF a="a" "b" foo=(a "c")* EBNF] call ast>> + "ab cab c" [EBNF a="a" "b" foo=(a "c")* EBNF] ast>> ] unit-test { V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [ - "ab c ab c" [EBNF a="a" "b" foo={a "c"}* EBNF] call ast>> + "ab c ab c" [EBNF a="a" "b" foo={a "c"}* EBNF] ast>> ] unit-test { V{ } } [ - "ab c ab c" [EBNF a="a" "b" foo=(a "c")* EBNF] call ast>> + "ab c ab c" [EBNF a="a" "b" foo=(a "c")* EBNF] ast>> ] unit-test { V{ "a" "a" "a" } } [ - "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] ast>> ] unit-test { t } [ - "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] call ast>> - "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ x ]] EBNF] call ast>> = + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] ast>> + "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ x ]] EBNF] ast>> = ] unit-test { V{ "a" "a" "a" } } [ - "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] call ast>> + "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] ast>> ] unit-test { t } [ - "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] call ast>> - "aaa" [EBNF a=('a')* b=(a):x => [[ x ]] EBNF] call ast>> = + "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] ast>> + "aaa" [EBNF a=('a')* b=(a):x => [[ x ]] EBNF] ast>> = ] unit-test { t } [ @@ -445,11 +445,11 @@ foo= 'd' ] unit-test { t } [ - "USING: kernel peg.ebnf ; [EBNF foo='a' '\n' => [[ drop \"\n\" ]] EBNF]" eval drop t + "USING: kernel peg.ebnf ; \"a\\n\" [EBNF foo='a' '\n' => [[ drop \"\n\" ]] EBNF]" eval drop t ] unit-test [ - "USING: peg.ebnf ; [EBNF foo='a' foo='b' EBNF]" eval drop + "USING: peg.ebnf ; \"ab\" [EBNF foo='a' foo='b' EBNF]" eval drop ] must-fail { t } [ @@ -460,7 +460,7 @@ foo= 'd' #! Tokenizer tests { V{ "a" CHAR: b } } [ - "ab" [EBNF tokenizer=default foo="a" . EBNF] call ast>> + "ab" [EBNF tokenizer=default foo="a" . EBNF] ast>> ] unit-test TUPLE: ast-number value ; @@ -488,7 +488,7 @@ Tok = Spaces (Number | Special ) tokenizer = foo=. tokenizer=default baz=. main = bar foo foo baz - EBNF] call ast>> + EBNF] ast>> ] unit-test { V{ CHAR: 5 "+" CHAR: 2 } } [ @@ -499,7 +499,7 @@ Tok = Spaces (Number | Special ) spaces=space* => [[ ignore ]] tokenizer=spaces (number | operator) main= . . . - EBNF] call ast>> + EBNF] ast>> ] unit-test { V{ CHAR: 5 "+" CHAR: 2 } } [ @@ -510,13 +510,13 @@ Tok = Spaces (Number | Special ) spaces=space* => [[ ignore ]] tokenizer=spaces (number | operator) main= . . . - EBNF] call ast>> + EBNF] ast>> ] unit-test { "++" } [ - "++--" [EBNF tokenizer=("++" | "--") main="++" EBNF] call ast>> + "++--" [EBNF tokenizer=("++" | "--") main="++" EBNF] ast>> ] unit-test { "\\" } [ - "\\" [EBNF foo="\\" EBNF] call ast>> + "\\" [EBNF foo="\\" EBNF] ast>> ] unit-test \ No newline at end of file diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 610cffd273..2a6b55ad9d 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -523,7 +523,8 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) parse-result-ast transform dup dup parser [ main swap at compile ] with-variable [ compiled-parse ] curry [ with-scope ] curry ; -: [EBNF "EBNF]" reset-tokenizer parse-multiline-string ebnf>quot nip parsed reset-tokenizer ; parsing +: [EBNF "EBNF]" reset-tokenizer parse-multiline-string ebnf>quot nip + parsed \ call parsed reset-tokenizer ; parsing : EBNF: reset-tokenizer CREATE-WORD dup ";EBNF" parse-multiline-string From 4c1fe8f0b30b7adabb819cbb74fddce6f75bdf9f Mon Sep 17 00:00:00 2001 From: Chris Double Date: Fri, 4 Jul 2008 12:40:42 +1200 Subject: [PATCH 0589/1850] Add syntax to return a parser object --- extra/peg/ebnf/ebnf.factor | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 2a6b55ad9d..ff4bd2db61 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -518,11 +518,16 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) "Could not parse EBNF" throw ] if ; +: parse-ebnf ( string -- hashtable ) + 'ebnf' parse check-parse-result ast>> transform ; + : ebnf>quot ( string -- hashtable quot ) - 'ebnf' parse check-parse-result - parse-result-ast transform dup dup parser [ main swap at compile ] with-variable + parse-ebnf dup dup parser [ main swap at compile ] with-variable [ compiled-parse ] curry [ with-scope ] curry ; +: " reset-tokenizer parse-multiline-string parse-ebnf main swap at + parsed reset-tokenizer ; parsing + : [EBNF "EBNF]" reset-tokenizer parse-multiline-string ebnf>quot nip parsed \ call parsed reset-tokenizer ; parsing From 72bd6b4dc852cc46b9c9a73946f19e78f7fd5e82 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Fri, 4 Jul 2008 14:20:19 +1200 Subject: [PATCH 0590/1850] Fix peg tests --- extra/peg/ebnf/ebnf-tests.factor | 44 ++++++++++++------------ extra/peg/ebnf/ebnf.factor | 4 +-- extra/peg/parsers/parsers-tests.factor | 28 ++++++++-------- extra/peg/parsers/parsers.factor | 14 ++++---- extra/peg/peg-tests.factor | 46 +++++++++++++------------- extra/peg/peg.factor | 5 ++- extra/peg/pl0/pl0-tests.factor | 18 +++++----- extra/peg/search/search.factor | 11 +++--- 8 files changed, 85 insertions(+), 85 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index ba34248159..ef90929b79 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -7,11 +7,11 @@ USING: kernel tools.test peg peg.ebnf words math math.parser IN: peg.ebnf.tests { T{ ebnf-non-terminal f "abc" } } [ - "abc" 'non-terminal' parse ast>> + "abc" 'non-terminal' parse ] unit-test { T{ ebnf-terminal f "55" } } [ - "'55'" 'terminal' parse ast>> + "'55'" 'terminal' parse ] unit-test { @@ -22,7 +22,7 @@ IN: peg.ebnf.tests } } } [ - "digit = '1' | '2'" 'rule' parse ast>> + "digit = '1' | '2'" 'rule' parse ] unit-test { @@ -33,7 +33,7 @@ IN: peg.ebnf.tests } } } [ - "digit = '1' '2'" 'rule' parse ast>> + "digit = '1' '2'" 'rule' parse ] unit-test { @@ -46,7 +46,7 @@ IN: peg.ebnf.tests } } } [ - "one two | three" 'choice' parse ast>> + "one two | three" 'choice' parse ] unit-test { @@ -61,7 +61,7 @@ IN: peg.ebnf.tests } } } [ - "one {two | three}" 'choice' parse ast>> + "one {two | three}" 'choice' parse ] unit-test { @@ -81,7 +81,7 @@ IN: peg.ebnf.tests } } } [ - "one ((two | three) four)*" 'choice' parse ast>> + "one ((two | three) four)*" 'choice' parse ] unit-test { @@ -93,23 +93,23 @@ IN: peg.ebnf.tests } } } [ - "one ( two )? three" 'choice' parse ast>> + "one ( two )? three" 'choice' parse ] unit-test { "foo" } [ - "\"foo\"" 'identifier' parse ast>> + "\"foo\"" 'identifier' parse ] unit-test { "foo" } [ - "'foo'" 'identifier' parse ast>> + "'foo'" 'identifier' parse ] unit-test { "foo" } [ - "foo" 'non-terminal' parse ast>> ebnf-non-terminal-symbol + "foo" 'non-terminal' parse ebnf-non-terminal-symbol ] unit-test { "foo" } [ - "foo]" 'non-terminal' parse ast>> ebnf-non-terminal-symbol + "foo]" 'non-terminal' parse ebnf-non-terminal-symbol ] unit-test { V{ "a" "b" } } [ @@ -252,7 +252,7 @@ IN: peg.ebnf.tests ] unit-test { t } [ - "abcd='9' | ('8'):x => [[ x ]]" 'ebnf' parse parse-result-remaining empty? + "abcd='9' | ('8'):x => [[ x ]]" 'ebnf' (parse) remaining>> empty? ] unit-test EBNF: primary @@ -385,29 +385,29 @@ main = Primary ] unit-test { t } [ - "number=(digit)+:n 'a'" 'ebnf' parse remaining>> length zero? + "number=(digit)+:n 'a'" 'ebnf' (parse) remaining>> length zero? ] unit-test { t } [ - "number=(digit)+ 'a'" 'ebnf' parse remaining>> length zero? + "number=(digit)+ 'a'" 'ebnf' (parse) remaining>> length zero? ] unit-test { t } [ - "number=digit+ 'a'" 'ebnf' parse remaining>> length zero? + "number=digit+ 'a'" 'ebnf' (parse) remaining>> length zero? ] unit-test { t } [ - "number=digit+:n 'a'" 'ebnf' parse remaining>> length zero? + "number=digit+:n 'a'" 'ebnf' (parse) remaining>> length zero? ] unit-test { t } [ - "foo=(name):n !(keyword) => [[ n ]]" 'rule' parse ast>> - "foo=name:n !(keyword) => [[ n ]]" 'rule' parse ast>> = + "foo=(name):n !(keyword) => [[ n ]]" 'rule' parse + "foo=name:n !(keyword) => [[ n ]]" 'rule' parse = ] unit-test { t } [ - "foo=!(keyword) (name):n => [[ n ]]" 'rule' parse ast>> - "foo=!(keyword) name:n => [[ n ]]" 'rule' parse ast>> = + "foo=!(keyword) (name):n => [[ n ]]" 'rule' parse + "foo=!(keyword) name:n => [[ n ]]" 'rule' parse = ] unit-test << @@ -455,7 +455,7 @@ foo= 'd' { t } [ #! Rule lookup occurs in a namespace. This causes an incorrect duplicate rule #! if a var in a namespace is set. This unit test is to remind me to fix this. - [ "fail" "foo" set "foo='a'" 'ebnf' parse ast>> transform drop t ] with-scope + [ "fail" "foo" set "foo='a'" 'ebnf' parse transform drop t ] with-scope ] unit-test #! Tokenizer tests diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index ff4bd2db61..2a57015fa6 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -504,7 +504,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) ] [ ] make box ; : transform-ebnf ( string -- object ) - 'ebnf' parse parse-result-ast transform ; + 'ebnf' parse transform ; : check-parse-result ( result -- result ) dup [ @@ -519,7 +519,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) ] if ; : parse-ebnf ( string -- hashtable ) - 'ebnf' parse check-parse-result ast>> transform ; + 'ebnf' (parse) check-parse-result ast>> transform ; : ebnf>quot ( string -- hashtable quot ) parse-ebnf dup dup parser [ main swap at compile ] with-variable diff --git a/extra/peg/parsers/parsers-tests.factor b/extra/peg/parsers/parsers-tests.factor index 0cf3ad8b17..20d19c9a64 100644 --- a/extra/peg/parsers/parsers-tests.factor +++ b/extra/peg/parsers/parsers-tests.factor @@ -2,50 +2,50 @@ USING: kernel peg peg.parsers tools.test accessors ; IN: peg.parsers.tests { V{ "a" } } -[ "a" "a" token "," token list-of parse ast>> ] unit-test +[ "a" "a" token "," token list-of parse ] unit-test { V{ "a" "a" "a" "a" } } -[ "a,a,a,a" "a" token "," token list-of parse ast>> ] unit-test +[ "a,a,a,a" "a" token "," token list-of parse ] unit-test [ "a" "a" token "," token list-of-many parse ] must-fail { V{ "a" "a" "a" "a" } } -[ "a,a,a,a" "a" token "," token list-of-many parse ast>> ] unit-test +[ "a,a,a,a" "a" token "," token list-of-many parse ] unit-test [ "aaa" "a" token 4 exactly-n parse ] must-fail { V{ "a" "a" "a" "a" } } -[ "aaaa" "a" token 4 exactly-n parse ast>> ] unit-test +[ "aaaa" "a" token 4 exactly-n parse ] unit-test [ "aaa" "a" token 4 at-least-n parse ] must-fail { V{ "a" "a" "a" "a" } } -[ "aaaa" "a" token 4 at-least-n parse ast>> ] unit-test +[ "aaaa" "a" token 4 at-least-n parse ] unit-test { V{ "a" "a" "a" "a" "a" } } -[ "aaaaa" "a" token 4 at-least-n parse ast>> ] unit-test +[ "aaaaa" "a" token 4 at-least-n parse ] unit-test { V{ "a" "a" "a" "a" } } -[ "aaaa" "a" token 4 at-most-n parse ast>> ] unit-test +[ "aaaa" "a" token 4 at-most-n parse ] unit-test { V{ "a" "a" "a" "a" } } -[ "aaaaa" "a" token 4 at-most-n parse ast>> ] unit-test +[ "aaaaa" "a" token 4 at-most-n parse ] unit-test { V{ "a" "a" "a" } } -[ "aaa" "a" token 3 4 from-m-to-n parse ast>> ] unit-test +[ "aaa" "a" token 3 4 from-m-to-n parse ] unit-test { V{ "a" "a" "a" "a" } } -[ "aaaa" "a" token 3 4 from-m-to-n parse ast>> ] unit-test +[ "aaaa" "a" token 3 4 from-m-to-n parse ] unit-test { V{ "a" "a" "a" "a" } } -[ "aaaaa" "a" token 3 4 from-m-to-n parse ast>> ] unit-test +[ "aaaaa" "a" token 3 4 from-m-to-n parse ] unit-test { 97 } -[ "a" any-char parse ast>> ] unit-test +[ "a" any-char parse ] unit-test { V{ } } -[ "" epsilon parse ast>> ] unit-test +[ "" epsilon parse ] unit-test { "a" } [ - "a" "a" token just parse ast>> + "a" "a" token just parse ] unit-test \ No newline at end of file diff --git a/extra/peg/parsers/parsers.factor b/extra/peg/parsers/parsers.factor index da44c12e8f..351e3b5fc1 100755 --- a/extra/peg/parsers/parsers.factor +++ b/extra/peg/parsers/parsers.factor @@ -3,7 +3,7 @@ USING: kernel sequences strings namespaces math assocs shuffle vectors arrays math.parser unicode.categories sequences.deep peg peg.private - peg.search math.ranges words memoize ; + peg.search math.ranges words ; IN: peg.parsers TUPLE: just-parser p1 ; @@ -19,7 +19,7 @@ TUPLE: just-parser p1 ; M: just-parser (compile) ( parser -- quot ) just-parser-p1 compiled-parser just-pattern curry ; -MEMO: just ( parser -- parser ) +: just ( parser -- parser ) just-parser boa init-parser ; : 1token ( ch -- parser ) 1string token ; @@ -45,10 +45,10 @@ MEMO: just ( parser -- parser ) PRIVATE> -MEMO: exactly-n ( parser n -- parser' ) +: exactly-n ( parser n -- parser' ) swap seq ; -MEMO: at-most-n ( parser n -- parser' ) +: at-most-n ( parser n -- parser' ) dup zero? [ 2drop epsilon ] [ @@ -56,15 +56,15 @@ MEMO: at-most-n ( parser n -- parser' ) -rot 1- at-most-n 2choice ] if ; -MEMO: at-least-n ( parser n -- parser' ) +: at-least-n ( parser n -- parser' ) dupd exactly-n swap repeat0 2seq [ flatten-vectors ] action ; -MEMO: from-m-to-n ( parser m n -- parser' ) +: from-m-to-n ( parser m n -- parser' ) >r [ exactly-n ] 2keep r> swap - at-most-n 2seq [ flatten-vectors ] action ; -MEMO: pack ( begin body end -- parser ) +: pack ( begin body end -- parser ) >r >r hide r> r> hide 3seq [ first ] action ; : surrounded-by ( parser begin end -- parser' ) diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor index 466da83b6e..f9e4a0d4a6 100644 --- a/extra/peg/peg-tests.factor +++ b/extra/peg/peg-tests.factor @@ -10,7 +10,7 @@ IN: peg.tests ] must-fail { "begin" "end" } [ - "beginend" "begin" token parse + "beginend" "begin" token (parse) { ast>> remaining>> } get-slots >string ] unit-test @@ -24,11 +24,11 @@ IN: peg.tests ] must-fail { CHAR: a } [ - "abcd" CHAR: a CHAR: z range parse ast>> + "abcd" CHAR: a CHAR: z range parse ] unit-test { CHAR: z } [ - "zbcd" CHAR: a CHAR: z range parse ast>> + "zbcd" CHAR: a CHAR: z range parse ] unit-test [ @@ -36,15 +36,15 @@ IN: peg.tests ] must-fail { V{ "g" "o" } } [ - "good" "g" token "o" token 2array seq parse ast>> + "good" "g" token "o" token 2array seq parse ] unit-test { "a" } [ - "abcd" "a" token "b" token 2array choice parse ast>> + "abcd" "a" token "b" token 2array choice parse ] unit-test { "b" } [ - "bbcd" "a" token "b" token 2array choice parse ast>> + "bbcd" "a" token "b" token 2array choice parse ] unit-test [ @@ -56,15 +56,15 @@ IN: peg.tests ] must-fail { 0 } [ - "" "a" token repeat0 parse ast>> length + "" "a" token repeat0 parse length ] unit-test { 0 } [ - "b" "a" token repeat0 parse ast>> length + "b" "a" token repeat0 parse length ] unit-test { V{ "a" "a" "a" } } [ - "aaab" "a" token repeat0 parse ast>> + "aaab" "a" token repeat0 parse ] unit-test [ @@ -76,15 +76,15 @@ IN: peg.tests ] must-fail { V{ "a" "a" "a" } } [ - "aaab" "a" token repeat1 parse ast>> + "aaab" "a" token repeat1 parse ] unit-test { V{ "a" "b" } } [ - "ab" "a" token optional "b" token 2array seq parse ast>> + "ab" "a" token optional "b" token 2array seq parse ] unit-test { V{ f "b" } } [ - "b" "a" token optional "b" token 2array seq parse ast>> + "b" "a" token optional "b" token 2array seq parse ] unit-test [ @@ -92,7 +92,7 @@ IN: peg.tests ] must-fail { V{ CHAR: a CHAR: b } } [ - "ab" "a" token ensure CHAR: a CHAR: z range dup 3array seq parse ast>> + "ab" "a" token ensure CHAR: a CHAR: z range dup 3array seq parse ] unit-test [ @@ -124,11 +124,11 @@ IN: peg.tests ] must-fail { 1 } [ - "a" "a" token [ drop 1 ] action parse ast>> + "a" "a" token [ drop 1 ] action parse ] unit-test { V{ 1 1 } } [ - "aa" "a" token [ drop 1 ] action dup 2array seq parse ast>> + "aa" "a" token [ drop 1 ] action dup 2array seq parse ] unit-test [ @@ -140,19 +140,19 @@ IN: peg.tests ] must-fail { CHAR: a } [ - "a" [ CHAR: a = ] satisfy parse ast>> + "a" [ CHAR: a = ] satisfy parse ] unit-test { "a" } [ - " a" "a" token sp parse ast>> + " a" "a" token sp parse ] unit-test { "a" } [ - "a" "a" token sp parse ast>> + "a" "a" token sp parse ] unit-test { V{ "a" } } [ - "[a]" "[" token hide "a" token "]" token hide 3array seq parse ast>> + "[a]" "[" token hide "a" token "]" token hide 3array seq parse ] unit-test [ @@ -165,8 +165,8 @@ IN: peg.tests [ "1" token , "-" token , "1" token , ] seq* , [ "1" token , "+" token , "1" token , ] seq* , ] choice* - "1-1" over parse ast>> swap - "1+1" swap parse ast>> + "1-1" over parse swap + "1+1" swap parse ] unit-test : expr ( -- parser ) @@ -175,7 +175,7 @@ IN: peg.tests [ expr ] delay "+" token "1" token 3seq "1" token 2choice ; { V{ V{ "1" "+" "1" } "+" "1" } } [ - "1+1+1" expr parse ast>> + "1+1+1" expr parse ] unit-test { t } [ @@ -190,6 +190,6 @@ IN: peg.tests ] must-fail { CHAR: B } [ - "B" [ drop t ] satisfy [ 66 >= ] semantic parse ast>> + "B" [ drop t ] satisfy [ 66 >= ] semantic parse ] unit-test diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index d388bbd124..0847c57299 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -286,9 +286,12 @@ SYMBOL: delayed : compiled-parse ( state word -- result ) swap [ execute [ error-stack get first throw ] unless* ] with-packrat ; inline -: parse ( input parser -- result ) +: (parse) ( input parser -- result ) dup word? [ compile ] unless compiled-parse ; +: parse ( input parser -- ast ) + (parse) ast>> ; + > empty? + "CONST foo = 1;" "block" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "VAR foo;" "block" \ pl0 rule parse remaining>> empty? + "VAR foo;" "block" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "VAR foo,bar , baz;" "block" \ pl0 rule parse remaining>> empty? + "VAR foo,bar , baz;" "block" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "foo := 5" "statement" \ pl0 rule parse remaining>> empty? + "foo := 5" "statement" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "BEGIN foo := 5 END" "statement" \ pl0 rule parse remaining>> empty? + "BEGIN foo := 5 END" "statement" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "IF 1=1 THEN foo := 5" "statement" \ pl0 rule parse remaining>> empty? + "IF 1=1 THEN foo := 5" "statement" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "WHILE 1=1 DO foo := 5" "statement" \ pl0 rule parse remaining>> empty? + "WHILE 1=1 DO foo := 5" "statement" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "WHILE ODD 1 DO foo := 5" "statement" \ pl0 rule parse remaining>> empty? + "WHILE ODD 1 DO foo := 5" "statement" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ - "PROCEDURE square; BEGIN squ:=x*x END" "block" \ pl0 rule parse remaining>> empty? + "PROCEDURE square; BEGIN squ:=x*x END" "block" \ pl0 rule (parse) remaining>> empty? ] unit-test { t } [ diff --git a/extra/peg/search/search.factor b/extra/peg/search/search.factor index 7ab7e83d12..04e4affe39 100755 --- a/extra/peg/search/search.factor +++ b/extra/peg/search/search.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2006 Chris Double. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math io io.streams.string sequences strings -combinators peg memoize arrays ; +combinators peg memoize arrays continuations ; IN: peg.search : tree-write ( object -- ) @@ -16,15 +16,12 @@ MEMO: any-char-parser ( -- parser ) [ drop t ] satisfy ; : search ( string parser -- seq ) - any-char-parser [ drop f ] action 2array choice repeat0 parse dup [ - parse-result-ast sift - ] [ - drop { } - ] if ; + any-char-parser [ drop f ] action 2array choice repeat0 + [ parse sift ] [ 3drop { } ] recover ; : (replace) ( string parser -- seq ) - any-char-parser 2array choice repeat0 parse parse-result-ast sift ; + any-char-parser 2array choice repeat0 parse sift ; : replace ( string parser -- result ) [ (replace) [ tree-write ] each ] with-string-writer ; From f3145c5961dab694f51ba8a1845362d5dcb6a1f9 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Fri, 4 Jul 2008 15:48:52 +1200 Subject: [PATCH 0591/1850] [EBNF and EBNF: now return ast --- extra/peg/ebnf/ebnf-tests.factor | 112 +++++++++--------- extra/peg/ebnf/ebnf.factor | 2 +- extra/peg/javascript/javascript.factor | 6 +- .../peg/javascript/parser/parser-tests.factor | 10 +- .../tokenizer/tokenizer-tests.factor | 4 +- 5 files changed, 65 insertions(+), 69 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index ef90929b79..7f14293a15 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -113,23 +113,23 @@ IN: peg.ebnf.tests ] unit-test { V{ "a" "b" } } [ - "ab" [EBNF foo='a' 'b' EBNF] ast>> + "ab" [EBNF foo='a' 'b' EBNF] ] unit-test { V{ 1 "b" } } [ - "ab" [EBNF foo=('a')[[ drop 1 ]] 'b' EBNF] ast>> + "ab" [EBNF foo=('a')[[ drop 1 ]] 'b' EBNF] ] unit-test { V{ 1 2 } } [ - "ab" [EBNF foo=('a') [[ drop 1 ]] ('b') [[ drop 2 ]] EBNF] ast>> + "ab" [EBNF foo=('a') [[ drop 1 ]] ('b') [[ drop 2 ]] EBNF] ] unit-test { CHAR: A } [ - "A" [EBNF foo=[A-Z] EBNF] ast>> + "A" [EBNF foo=[A-Z] EBNF] ] unit-test { CHAR: Z } [ - "Z" [EBNF foo=[A-Z] EBNF] ast>> + "Z" [EBNF foo=[A-Z] EBNF] ] unit-test [ @@ -137,7 +137,7 @@ IN: peg.ebnf.tests ] must-fail { CHAR: 0 } [ - "0" [EBNF foo=[^A-Z] EBNF] ast>> + "0" [EBNF foo=[^A-Z] EBNF] ] unit-test [ @@ -149,31 +149,31 @@ IN: peg.ebnf.tests ] must-fail { V{ "1" "+" "foo" } } [ - "1+1" [EBNF foo='1' '+' '1' [[ drop "foo" ]] EBNF] ast>> + "1+1" [EBNF foo='1' '+' '1' [[ drop "foo" ]] EBNF] ] unit-test { "foo" } [ - "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] EBNF] ast>> + "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] EBNF] ] unit-test { "foo" } [ - "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] ast>> + "1+1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] ] unit-test { "bar" } [ - "1-1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] ast>> + "1-1" [EBNF foo='1' '+' '1' => [[ drop "foo" ]] | '1' '-' '1' => [[ drop "bar" ]] EBNF] ] unit-test { 6 } [ - "4+2" [EBNF num=[0-9] => [[ digit> ]] foo=num:x '+' num:y => [[ x y + ]] EBNF] ast>> + "4+2" [EBNF num=[0-9] => [[ digit> ]] foo=num:x '+' num:y => [[ x y + ]] EBNF] ] unit-test { 6 } [ - "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ x digit> y digit> + ]] EBNF] ast>> + "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ x digit> y digit> + ]] EBNF] ] unit-test { 10 } [ - { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ast>> + { 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ] unit-test [ @@ -181,7 +181,7 @@ IN: peg.ebnf.tests ] must-fail { 3 } [ - { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ast>> + { 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ x y + ]] | num EBNF] ] unit-test [ @@ -189,44 +189,44 @@ IN: peg.ebnf.tests ] must-fail { V{ "a" " " "b" } } [ - "a b" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ast>> + "a b" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ] unit-test { V{ "a" "\t" "b" } } [ - "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ast>> + "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ] unit-test { V{ "a" "\n" "b" } } [ - "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ast>> + "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" - "b" EBNF] ] unit-test { V{ "a" f "b" } } [ - "ab" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> + "ab" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ] unit-test { V{ "a" " " "b" } } [ - "a b" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> + "a b" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ] unit-test { V{ "a" "\t" "b" } } [ - "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> + "a\tb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ] unit-test { V{ "a" "\n" "b" } } [ - "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ast>> + "a\nb" [EBNF -=" " | "\t" | "\n" foo="a" (-)? "b" EBNF] ] unit-test { V{ "a" "b" } } [ - "ab" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ast>> + "ab" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ] unit-test { V{ "a" "b" } } [ - "a\tb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ast>> + "a\tb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ] unit-test { V{ "a" "b" } } [ - "a\nb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ast>> + "a\nb" [EBNF -=(" " | "\t" | "\n")? => [[ drop ignore ]] foo="a" - "b" EBNF] ] unit-test [ @@ -236,19 +236,19 @@ IN: peg.ebnf.tests { V{ V{ 49 } "+" V{ 49 } } } [ #! Test direct left recursion. #! Using packrat, so first part of expr fails, causing 2nd choice to be used - "1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] ast>> + "1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] ] unit-test { V{ V{ V{ 49 } "+" V{ 49 } } "+" V{ 49 } } } [ #! Test direct left recursion. #! Using packrat, so first part of expr fails, causing 2nd choice to be used - "1+1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] ast>> + "1+1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] ] unit-test { V{ V{ V{ 49 } "+" V{ 49 } } "+" V{ 49 } } } [ #! Test indirect left recursion. #! Using packrat, so first part of expr fails, causing 2nd choice to be used - "1+1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] ast>> + "1+1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] ] unit-test { t } [ @@ -281,37 +281,37 @@ main = Primary ;EBNF { "this" } [ - "this" primary ast>> + "this" primary ] unit-test { V{ "this" "." "x" } } [ - "this.x" primary ast>> + "this.x" primary ] unit-test { V{ V{ "this" "." "x" } "." "y" } } [ - "this.x.y" primary ast>> + "this.x.y" primary ] unit-test { V{ V{ "this" "." "x" } "." "m" "(" ")" } } [ - "this.x.m()" primary ast>> + "this.x.m()" primary ] unit-test { V{ V{ V{ "x" "[" "i" "]" } "[" "j" "]" } "." "y" } } [ - "x[i][j].y" primary ast>> + "x[i][j].y" primary ] unit-test 'ebnf' compile must-infer { V{ V{ "a" "b" } "c" } } [ - "abc" [EBNF a="a" "b" foo=(a "c") EBNF] ast>> + "abc" [EBNF a="a" "b" foo=(a "c") EBNF] ] unit-test { V{ V{ "a" "b" } "c" } } [ - "abc" [EBNF a="a" "b" foo={a "c"} EBNF] ast>> + "abc" [EBNF a="a" "b" foo={a "c"} EBNF] ] unit-test { V{ V{ "a" "b" } "c" } } [ - "abc" [EBNF a="a" "b" foo=a "c" EBNF] ast>> + "abc" [EBNF a="a" "b" foo=a "c" EBNF] ] unit-test [ @@ -331,7 +331,7 @@ main = Primary ] must-fail { V{ V{ "a" "b" } "c" } } [ - "ab c" [EBNF a="a" "b" foo={a "c"} EBNF] ast>> + "ab c" [EBNF a="a" "b" foo={a "c"} EBNF] ] unit-test [ @@ -351,37 +351,37 @@ main = Primary ] must-fail { V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [ - "ab cab c" [EBNF a="a" "b" foo={a "c"}* EBNF] ast>> + "ab cab c" [EBNF a="a" "b" foo={a "c"}* EBNF] ] unit-test { V{ } } [ - "ab cab c" [EBNF a="a" "b" foo=(a "c")* EBNF] ast>> + "ab cab c" [EBNF a="a" "b" foo=(a "c")* EBNF] ] unit-test { V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [ - "ab c ab c" [EBNF a="a" "b" foo={a "c"}* EBNF] ast>> + "ab c ab c" [EBNF a="a" "b" foo={a "c"}* EBNF] ] unit-test { V{ } } [ - "ab c ab c" [EBNF a="a" "b" foo=(a "c")* EBNF] ast>> + "ab c ab c" [EBNF a="a" "b" foo=(a "c")* EBNF] ] unit-test { V{ "a" "a" "a" } } [ - "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] ast>> + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] ] unit-test { t } [ - "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] ast>> - "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ x ]] EBNF] ast>> = + "aaa" [EBNF a=('a')* b=!('b') a:x => [[ x ]] EBNF] + "aaa" [EBNF a=('a')* b=!('b') (a):x => [[ x ]] EBNF] = ] unit-test { V{ "a" "a" "a" } } [ - "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] ast>> + "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] ] unit-test { t } [ - "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] ast>> - "aaa" [EBNF a=('a')* b=(a):x => [[ x ]] EBNF] ast>> = + "aaa" [EBNF a=('a')* b=a:x => [[ x ]] EBNF] + "aaa" [EBNF a=('a')* b=(a):x => [[ x ]] EBNF] = ] unit-test { t } [ @@ -429,19 +429,19 @@ foo= 'd' ;EBNF { "a" } [ - "a" parser1 ast>> + "a" parser1 ] unit-test { V{ "a" "b" } } [ - "ab" parser2 ast>> + "ab" parser2 ] unit-test { V{ "a" "c" } } [ - "ac" parser3 ast>> + "ac" parser3 ] unit-test { V{ CHAR: a "d" } } [ - "ad" parser4 ast>> + "ad" parser4 ] unit-test { t } [ @@ -460,7 +460,7 @@ foo= 'd' #! Tokenizer tests { V{ "a" CHAR: b } } [ - "ab" [EBNF tokenizer=default foo="a" . EBNF] ast>> + "ab" [EBNF tokenizer=default foo="a" . EBNF] ] unit-test TUPLE: ast-number value ; @@ -488,7 +488,7 @@ Tok = Spaces (Number | Special ) tokenizer = foo=. tokenizer=default baz=. main = bar foo foo baz - EBNF] ast>> + EBNF] ] unit-test { V{ CHAR: 5 "+" CHAR: 2 } } [ @@ -499,7 +499,7 @@ Tok = Spaces (Number | Special ) spaces=space* => [[ ignore ]] tokenizer=spaces (number | operator) main= . . . - EBNF] ast>> + EBNF] ] unit-test { V{ CHAR: 5 "+" CHAR: 2 } } [ @@ -510,13 +510,13 @@ Tok = Spaces (Number | Special ) spaces=space* => [[ ignore ]] tokenizer=spaces (number | operator) main= . . . - EBNF] ast>> + EBNF] ] unit-test { "++" } [ - "++--" [EBNF tokenizer=("++" | "--") main="++" EBNF] ast>> + "++--" [EBNF tokenizer=("++" | "--") main="++" EBNF] ] unit-test { "\\" } [ - "\\" [EBNF foo="\\" EBNF] ast>> + "\\" [EBNF foo="\\" EBNF] ] unit-test \ No newline at end of file diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 2a57015fa6..2a75fcccc0 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -523,7 +523,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) : ebnf>quot ( string -- hashtable quot ) parse-ebnf dup dup parser [ main swap at compile ] with-variable - [ compiled-parse ] curry [ with-scope ] curry ; + [ compiled-parse ] curry [ with-scope ast>> ] curry ; : " reset-tokenizer parse-multiline-string parse-ebnf main swap at parsed reset-tokenizer ; parsing diff --git a/extra/peg/javascript/javascript.factor b/extra/peg/javascript/javascript.factor index 8fe0538eae..4a919cf39f 100644 --- a/extra/peg/javascript/javascript.factor +++ b/extra/peg/javascript/javascript.factor @@ -4,8 +4,4 @@ USING: kernel accessors peg.javascript.tokenizer peg.javascript.parser ; IN: peg.javascript : parse-javascript ( string -- ast ) - javascript [ - ast>> - ] [ - "Unable to parse JavaScript" throw - ] if* ; + javascript ; diff --git a/extra/peg/javascript/parser/parser-tests.factor b/extra/peg/javascript/parser/parser-tests.factor index fd0e27b6d4..769dc41f78 100644 --- a/extra/peg/javascript/parser/parser-tests.factor +++ b/extra/peg/javascript/parser/parser-tests.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. ! USING: kernel tools.test peg peg.javascript.ast peg.javascript.parser - accessors multiline sequences math ; + accessors multiline sequences math peg.ebnf ; IN: peg.javascript.parser.tests \ javascript must-infer @@ -23,14 +23,14 @@ IN: peg.javascript.parser.tests } } } [ - "123; 'hello'; foo(x);" javascript ast>> + "123; 'hello'; foo(x);" javascript ] unit-test { t } [ <" var x=5 var y=10 -"> javascript remaining>> length zero? +"> main \ javascript rule (parse) remaining>> length zero? ] unit-test @@ -41,7 +41,7 @@ function foldl(f, initial, seq) { initial = f(initial, seq[i]); return initial; } -"> javascript remaining>> length zero? +"> main \ javascript rule (parse) remaining>> length zero? ] unit-test { t } [ @@ -52,6 +52,6 @@ ParseState.prototype.from = function(index) { r.length = this.length - index; return r; } -"> javascript remaining>> length zero? +"> main \ javascript rule (parse) remaining>> length zero? ] unit-test diff --git a/extra/peg/javascript/tokenizer/tokenizer-tests.factor b/extra/peg/javascript/tokenizer/tokenizer-tests.factor index a61125d08c..f0080a31b2 100644 --- a/extra/peg/javascript/tokenizer/tokenizer-tests.factor +++ b/extra/peg/javascript/tokenizer/tokenizer-tests.factor @@ -19,9 +19,9 @@ IN: peg.javascript.tokenizer.tests ";" } } [ - "123; 'hello'; foo(x);" tokenize-javascript ast>> + "123; 'hello'; foo(x);" tokenize-javascript ] unit-test { V{ T{ ast-regexp f "<(w+)[^>]*?)/>" "g" } } } [ - "/<(\\w+)[^>]*?)\\/>/g" tokenize-javascript ast>> + "/<(\\w+)[^>]*?)\\/>/g" tokenize-javascript ] unit-test \ No newline at end of file From 7f4fe7669861497137569e36130854dc77b5b872 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Fri, 4 Jul 2008 15:55:23 +1200 Subject: [PATCH 0592/1850] More peg test fixes --- extra/peg/expr/expr-tests.factor | 10 +++++----- extra/peg/expr/expr.factor | 4 ---- extra/peg/pl0/pl0-tests.factor | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/extra/peg/expr/expr-tests.factor b/extra/peg/expr/expr-tests.factor index b6f3163bf4..59c70cd358 100644 --- a/extra/peg/expr/expr-tests.factor +++ b/extra/peg/expr/expr-tests.factor @@ -5,21 +5,21 @@ USING: kernel tools.test peg peg.expr multiline sequences ; IN: peg.expr.tests { 5 } [ - "2+3" eval-expr + "2+3" expr ] unit-test { 6 } [ - "2*3" eval-expr + "2*3" expr ] unit-test { 14 } [ - "2+3*4" eval-expr + "2+3*4" expr ] unit-test { 17 } [ - "2+3*4+3" eval-expr + "2+3*4+3" expr ] unit-test { 23 } [ - "2+3*(4+3)" eval-expr + "2+3*(4+3)" expr ] unit-test diff --git a/extra/peg/expr/expr.factor b/extra/peg/expr/expr.factor index e2df60ea9a..8b10b4fc0c 100644 --- a/extra/peg/expr/expr.factor +++ b/extra/peg/expr/expr.factor @@ -18,7 +18,3 @@ exp = exp "+" fac => [[ first3 nip + ]] | exp "-" fac => [[ first3 nip - ]] | fac ;EBNF - -: eval-expr ( string -- number ) - expr ast>> ; - diff --git a/extra/peg/pl0/pl0-tests.factor b/extra/peg/pl0/pl0-tests.factor index 4ba550a26c..e84d37e5d4 100644 --- a/extra/peg/pl0/pl0-tests.factor +++ b/extra/peg/pl0/pl0-tests.factor @@ -58,7 +58,7 @@ BEGIN x := x + 1; END END. -"> pl0 remaining>> empty? +"> main \ pl0 rule (parse) remaining>> empty? ] unit-test { f } [ @@ -124,5 +124,5 @@ BEGIN y := 36; CALL gcd; END. - "> pl0 remaining>> empty? + "> main \ pl0 rule (parse) remaining>> empty? ] unit-test \ No newline at end of file From d92c19f694057eccc8aa8656a5a73ef46f26c3ab Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 8 Jul 2008 16:10:06 +1200 Subject: [PATCH 0593/1850] Remove delegate usage from pegs --- extra/peg/peg.factor | 106 ++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 0847c57299..3882315dc9 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -10,14 +10,13 @@ USE: prettyprint TUPLE: parse-result remaining ast ; TUPLE: parse-error position messages ; -TUPLE: parser id compiled ; -M: parser equal? [ id>> ] bi@ = ; +TUPLE: parser peg compiled id ; +M: parser equal? [ id>> ] bi@ = ; M: parser hashcode* id>> hashcode* ; -C: parse-result -C: parse-error -C: parser +C: parse-result +C: parse-error M: parse-error error. "Peg parsing error at character position " write dup position>> number>string write @@ -59,11 +58,16 @@ SYMBOL: heads : failed? ( obj -- ? ) fail = ; -: delegates ( -- cache ) - \ delegates get-global [ H{ } clone dup \ delegates set-global ] unless* ; +: peg-cache ( -- cache ) + #! Holds a hashtable mapping a peg tuple to + #! the parser tuple for that peg. The parser tuple + #! holds a unique id and the compiled form of that peg. + \ peg-cache get-global [ + H{ } clone dup \ peg-cache set-global + ] unless* ; : reset-pegs ( -- ) - H{ } clone \ delegates set-global ; + H{ } clone \ peg-cache set-global ; reset-pegs @@ -239,7 +243,7 @@ C: peg-head ] H{ } make-assoc swap bind ; inline -GENERIC: (compile) ( parser -- quot ) +GENERIC: (compile) ( peg -- quot ) : execute-parser ( word -- result ) pos get apply-rule dup failed? [ @@ -251,7 +255,7 @@ GENERIC: (compile) ( parser -- quot ) : parser-body ( parser -- quot ) #! Return the body of the word that is the compiled version #! of the parser. - gensym 2dup swap (compile) 0 1 define-declared swap dupd "peg" set-word-prop + gensym 2dup swap peg>> (compile) 0 1 define-declared swap dupd "peg" set-word-prop [ execute-parser ] curry ; : compiled-parser ( parser -- word ) @@ -304,12 +308,13 @@ SYMBOL: id 1 id set-global 0 ] if* ; -: init-parser ( parser -- parser ) - #! Set the delegate for the parser. Equivalent parsers - #! get a delegate with the same id. - dup clone delegates [ - drop next-id f - ] cache over set-delegate ; +: wrap-peg ( peg -- parser ) + #! Wrap a parser tuple around the peg object. + #! Look for an existing parser tuple for that + #! peg object. + peg-cache [ + f next-id parser boa + ] cache ; TUPLE: token-parser symbol ; @@ -321,7 +326,7 @@ TUPLE: token-parser symbol ; drop input-slice input-from "token '" r> append "'" append 1vector add-error f ] if ; -M: token-parser (compile) ( parser -- quot ) +M: token-parser (compile) ( peg -- quot ) symbol>> '[ input-slice , parse-token ] ; TUPLE: satisfy-parser quot ; @@ -338,7 +343,7 @@ TUPLE: satisfy-parser quot ; ] if ; inline -M: satisfy-parser (compile) ( parser -- quot ) +M: satisfy-parser (compile) ( peg -- quot ) quot>> '[ input-slice , parse-satisfy ] ; TUPLE: range-parser min max ; @@ -354,7 +359,7 @@ TUPLE: range-parser min max ; ] if ] if ; -M: range-parser (compile) ( parser -- quot ) +M: range-parser (compile) ( peg -- quot ) [ min>> ] [ max>> ] bi '[ input-slice , , parse-range ] ; TUPLE: seq-parser parsers ; @@ -381,7 +386,7 @@ TUPLE: seq-parser parsers ; 2drop f ] if ; inline -M: seq-parser (compile) ( parser -- quot ) +M: seq-parser (compile) ( peg -- quot ) [ [ input-slice V{ } clone ] % parsers>> unclip compiled-parser 1quotation , \ parse-seq-element , [ @@ -390,7 +395,7 @@ M: seq-parser (compile) ( parser -- quot ) TUPLE: choice-parser parsers ; -M: choice-parser (compile) ( parser -- quot ) +M: choice-parser (compile) ( peg -- quot ) [ f , parsers>> [ compiled-parser ] map @@ -408,7 +413,7 @@ TUPLE: repeat0-parser p1 ; nip ] if* ; inline -M: repeat0-parser (compile) ( parser -- quot ) +M: repeat0-parser (compile) ( peg -- quot ) p1>> compiled-parser 1quotation '[ input-slice V{ } clone , swap (repeat) ] ; @@ -422,7 +427,7 @@ TUPLE: repeat1-parser p1 ; f ] if* ; -M: repeat1-parser (compile) ( parser -- quot ) +M: repeat1-parser (compile) ( peg -- quot ) p1>> compiled-parser 1quotation '[ input-slice V{ } clone , swap (repeat) repeat1-empty-check ] ; @@ -432,7 +437,7 @@ TUPLE: optional-parser p1 ; : check-optional ( result -- result ) [ input-slice f ] unless* ; -M: optional-parser (compile) ( parser -- quot ) +M: optional-parser (compile) ( peg -- quot ) p1>> compiled-parser 1quotation '[ @ check-optional ] ; TUPLE: semantic-parser p1 quot ; @@ -444,7 +449,7 @@ TUPLE: semantic-parser p1 quot ; drop ] if ; inline -M: semantic-parser (compile) ( parser -- quot ) +M: semantic-parser (compile) ( peg -- quot ) [ p1>> compiled-parser 1quotation ] [ quot>> ] bi '[ @ , check-semantic ] ; @@ -453,7 +458,7 @@ TUPLE: ensure-parser p1 ; : check-ensure ( old-input result -- result ) [ ignore ] [ drop f ] if ; -M: ensure-parser (compile) ( parser -- quot ) +M: ensure-parser (compile) ( peg -- quot ) p1>> compiled-parser 1quotation '[ input-slice @ check-ensure ] ; TUPLE: ensure-not-parser p1 ; @@ -461,7 +466,7 @@ TUPLE: ensure-not-parser p1 ; : check-ensure-not ( old-input result -- result ) [ drop f ] [ ignore ] if ; -M: ensure-not-parser (compile) ( parser -- quot ) +M: ensure-not-parser (compile) ( peg -- quot ) p1>> compiled-parser 1quotation '[ input-slice @ check-ensure-not ] ; TUPLE: action-parser p1 quot ; @@ -473,7 +478,7 @@ TUPLE: action-parser p1 quot ; drop ] if ; inline -M: action-parser (compile) ( parser -- quot ) +M: action-parser (compile) ( peg -- quot ) [ p1>> compiled-parser 1quotation ] [ quot>> ] bi '[ @ , check-action ] ; : left-trim-slice ( string -- string ) @@ -485,14 +490,14 @@ M: action-parser (compile) ( parser -- quot ) TUPLE: sp-parser p1 ; -M: sp-parser (compile) ( parser -- quot ) +M: sp-parser (compile) ( peg -- quot ) p1>> compiled-parser 1quotation '[ input-slice left-trim-slice input-from pos set @ ] ; TUPLE: delay-parser quot ; -M: delay-parser (compile) ( parser -- quot ) +M: delay-parser (compile) ( peg -- quot ) #! For efficiency we memoize the quotation. #! This way it is run only once and the #! parser constructed once at run time. @@ -500,29 +505,26 @@ M: delay-parser (compile) ( parser -- quot ) TUPLE: box-parser quot ; -M: box-parser (compile) ( parser -- quot ) +M: box-parser (compile) ( peg -- quot ) #! Calls the quotation at compile time #! to produce the parser to be compiled. #! This differs from 'delay' which calls - #! it at run time. Due to using the runtime - #! environment at compile time, this parser - #! must not be cached, so we clear out the - #! delgates cache. - f >>compiled quot>> call compiled-parser 1quotation ; + #! it at run time. + quot>> call compiled-parser 1quotation ; PRIVATE> : token ( string -- parser ) - token-parser boa init-parser ; + token-parser boa wrap-peg ; : satisfy ( quot -- parser ) - satisfy-parser boa init-parser ; + satisfy-parser boa wrap-peg ; : range ( min max -- parser ) - range-parser boa init-parser ; + range-parser boa wrap-peg ; : seq ( seq -- parser ) - seq-parser boa init-parser ; + seq-parser boa wrap-peg ; : 2seq ( parser1 parser2 -- parser ) 2array seq ; @@ -537,7 +539,7 @@ PRIVATE> { } make seq ; inline : choice ( seq -- parser ) - choice-parser boa init-parser ; + choice-parser boa wrap-peg ; : 2choice ( parser1 parser2 -- parser ) 2array choice ; @@ -552,38 +554,38 @@ PRIVATE> { } make choice ; inline : repeat0 ( parser -- parser ) - repeat0-parser boa init-parser ; + repeat0-parser boa wrap-peg ; : repeat1 ( parser -- parser ) - repeat1-parser boa init-parser ; + repeat1-parser boa wrap-peg ; : optional ( parser -- parser ) - optional-parser boa init-parser ; + optional-parser boa wrap-peg ; : semantic ( parser quot -- parser ) - semantic-parser boa init-parser ; + semantic-parser boa wrap-peg ; : ensure ( parser -- parser ) - ensure-parser boa init-parser ; + ensure-parser boa wrap-peg ; : ensure-not ( parser -- parser ) - ensure-not-parser boa init-parser ; + ensure-not-parser boa wrap-peg ; : action ( parser quot -- parser ) - action-parser boa init-parser ; + action-parser boa wrap-peg ; : sp ( parser -- parser ) - sp-parser boa init-parser ; + sp-parser boa wrap-peg ; : hide ( parser -- parser ) [ drop ignore ] action ; : delay ( quot -- parser ) - delay-parser boa init-parser ; + delay-parser boa wrap-peg ; : box ( quot -- parser ) #! because a box has its quotation run at compile time - #! it must always have a new parser delgate created, + #! it must always have a new parser wrapper created, #! not a cached one. This is because the same box, #! compiled twice can have a different compiled word #! due to running at compile time. @@ -593,7 +595,7 @@ PRIVATE> #! parse. The action adds an indirection with a parser type #! that gets memoized and fixes this. Need to rethink how #! to fix boxes so this isn't needed... - box-parser boa next-id f over set-delegate [ ] action ; + box-parser boa f next-id parser boa [ ] action ; ERROR: parse-failed input word ; From ec896eeba8c32a974e84ab431e6673b6f591d438 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Tue, 8 Jul 2008 16:56:12 +1200 Subject: [PATCH 0594/1850] peg fixes --- extra/peg/parsers/parsers.factor | 2 +- extra/peg/peg-tests.factor | 2 +- extra/peg/peg.factor | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/extra/peg/parsers/parsers.factor b/extra/peg/parsers/parsers.factor index 351e3b5fc1..f6c2820ac2 100755 --- a/extra/peg/parsers/parsers.factor +++ b/extra/peg/parsers/parsers.factor @@ -20,7 +20,7 @@ M: just-parser (compile) ( parser -- quot ) just-parser-p1 compiled-parser just-pattern curry ; : just ( parser -- parser ) - just-parser boa init-parser ; + just-parser boa wrap-peg ; : 1token ( ch -- parser ) 1string token ; diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor index f9e4a0d4a6..62e041441f 100644 --- a/extra/peg/peg-tests.factor +++ b/extra/peg/peg-tests.factor @@ -181,7 +181,7 @@ IN: peg.tests { t } [ #! Ensure a circular parser doesn't loop infinitely [ f , "a" token , ] seq* - dup parsers>> + dup peg>> parsers>> dupd 0 swap set-nth compile word? ] unit-test diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 3882315dc9..871db21084 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -245,12 +245,15 @@ C: peg-head GENERIC: (compile) ( peg -- quot ) -: execute-parser ( word -- result ) - pos get apply-rule dup failed? [ +: process-parser-result ( result -- result ) + dup failed? [ drop f ] [ input-slice swap - ] if ; inline + ] if ; + +: execute-parser ( word -- result ) + pos get apply-rule process-parser-result ; inline : parser-body ( parser -- quot ) #! Return the body of the word that is the compiled version @@ -323,7 +326,7 @@ TUPLE: token-parser symbol ; dup >r ?head-slice [ r> f f add-error ] [ - drop input-slice input-from "token '" r> append "'" append 1vector add-error f + drop pos get "token '" r> append "'" append 1vector add-error f ] if ; M: token-parser (compile) ( peg -- quot ) From 4135f81514c91257c901a1c2819c204955714d10 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 9 Jul 2008 11:45:51 +1200 Subject: [PATCH 0595/1850] Fix comment in peg eval-rule --- extra/peg/peg.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 871db21084..4cfa94ce48 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -109,7 +109,7 @@ C: peg-head : eval-rule ( rule -- ast ) #! Evaluate a rule, return an ast resulting from it. #! Return fail if the rule failed. The rule has - #! stack effect ( input -- parse-result ) + #! stack effect ( -- parse-result ) pos get swap execute process-rule-result ; inline : memo ( pos rule -- memo-entry ) From 9e78bb70f2216c8582827a9a880b2fca8ca32e1d Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 9 Jul 2008 12:07:17 +1200 Subject: [PATCH 0596/1850] packrat refactoring --- extra/peg/peg.factor | 72 +++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 4cfa94ce48..9540b1fd70 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -48,12 +48,27 @@ SYMBOL: error-stack SYMBOL: ignore -SYMBOL: packrat +: packrat ( id -- cache ) + #! The packrat cache is a mapping of parser-id->cache. + #! For each parser it maps to a cache holding a mapping + #! of position->result. The packrat cache therefore keeps + #! track of all parses that have occurred at each position + #! of the input string and the results obtained from that + #! parser. + \ packrat get [ drop H{ } clone ] cache ; + SYMBOL: pos SYMBOL: input SYMBOL: fail SYMBOL: lrstack -SYMBOL: heads + +: heads ( -- cache ) + #! A mapping from position->peg-head. It maps a + #! position in the input string being parsed to + #! the head of the left recursion which is currently + #! being grown. It is 'f' at any position where + #! left recursion growth is not underway. + \ heads get ; : failed? ( obj -- ? ) fail = ; @@ -71,19 +86,20 @@ SYMBOL: heads reset-pegs +#! An entry in the table of memoized parse results +#! ast = an AST produced from the parse +#! or the symbol 'fail' +#! or a left-recursion object +#! pos = the position in the input string of this entry TUPLE: memo-entry ans pos ; -C: memo-entry -TUPLE: left-recursion seed rule head next ; -C: left-recursion - +TUPLE: left-recursion seed rule head next ; TUPLE: peg-head rule involved-set eval-set ; -C: peg-head -: rule-parser ( rule -- parser ) +: rule-id ( word -- id ) #! A rule is the parser compiled down to a word. It has - #! a "peg" property containing the original parser. - "peg" word-prop ; + #! a "peg-id" property containing the id of the original parser. + "peg-id" word-prop ; : input-slice ( -- slice ) #! Return a slice of the input from the current parse position @@ -94,11 +110,6 @@ C: peg-head #! input slice is based on. dup slice? [ slice-from ] [ drop 0 ] if ; -: input-cache ( parser -- cache ) - #! From the packrat cache, obtain the cache for the parser - #! that maps the position to the parser result. - id>> packrat get [ drop H{ } clone ] cache ; - : process-rule-result ( p result -- result ) [ nip [ ast>> ] [ remaining>> ] bi input-from pos set @@ -114,11 +125,13 @@ C: peg-head : memo ( pos rule -- memo-entry ) #! Return the result from the memo cache. - rule-parser input-cache at ; + rule-id packrat at +! " memo result " write dup . + ; : set-memo ( memo-entry pos rule -- ) #! Store an entry in the cache - rule-parser input-cache set-at ; + rule-id packrat set-at ; : update-m ( ast m -- ) swap >>ans pos get >>pos drop ; @@ -141,9 +154,9 @@ C: peg-head ] if ; inline : grow-lr ( h p r m -- ast ) - >r >r [ heads get set-at ] 2keep r> r> + >r >r [ heads set-at ] 2keep r> r> pick over >r >r (grow-lr) r> r> - swap heads get delete-at + swap heads delete-at dup pos>> pos set ans>> ; inline @@ -156,7 +169,7 @@ C: peg-head :: setup-lr ( r l -- ) l head>> [ - r V{ } clone V{ } clone l (>>head) + r V{ } clone V{ } clone peg-head boa l (>>head) ] unless r l lrstack get (setup-lr) ; @@ -179,11 +192,11 @@ C: peg-head :: recall ( r p -- memo-entry ) [let* | m [ p r memo ] - h [ p heads get at ] + h [ p heads at ] | h [ m r h involved-set>> h rule>> suffix member? not and [ - fail p + fail p memo-entry boa ] [ r h eval-set>> member? [ h [ r swap remove ] change-eval-set drop @@ -201,8 +214,8 @@ C: peg-head :: apply-non-memo-rule ( r p -- ast ) [let* | - lr [ fail r f lrstack get ] - m [ lr lrstack set lr p dup p r set-memo ] + lr [ fail r f lrstack get left-recursion boa ] + m [ lr lrstack set lr p memo-entry boa dup p r set-memo ] ans [ r eval-rule ] | lrstack get next>> lrstack set @@ -224,10 +237,15 @@ C: peg-head nip ] if ; +USE: prettyprint + : apply-rule ( r p -- ast ) +! 2dup [ rule-id ] dip 2array "apply-rule: " write . 2dup recall [ +! " memoed" print nip apply-memo-rule ] [ +! " not memoed" print apply-non-memo-rule ] if* ; inline @@ -238,8 +256,8 @@ C: peg-head 0 pos set f lrstack set V{ } clone error-stack set - H{ } clone heads set - H{ } clone packrat set + H{ } clone \ heads set + H{ } clone \ packrat set ] H{ } make-assoc swap bind ; inline @@ -258,7 +276,7 @@ GENERIC: (compile) ( peg -- quot ) : parser-body ( parser -- quot ) #! Return the body of the word that is the compiled version #! of the parser. - gensym 2dup swap peg>> (compile) 0 1 define-declared swap dupd "peg" set-word-prop + gensym 2dup swap peg>> (compile) 0 1 define-declared swap dupd id>> "peg-id" set-word-prop [ execute-parser ] curry ; : compiled-parser ( parser -- word ) From 2ed0d561aef1338abf2f0ad1f34990e0360c66fe Mon Sep 17 00:00:00 2001 From: Chris Double Date: Wed, 9 Jul 2008 14:26:11 +1200 Subject: [PATCH 0597/1850] Store peg rules by their id rather than word in left recursion handling --- extra/peg/peg.factor | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor index 9540b1fd70..11d36f032c 100755 --- a/extra/peg/peg.factor +++ b/extra/peg/peg.factor @@ -93,8 +93,8 @@ reset-pegs #! pos = the position in the input string of this entry TUPLE: memo-entry ans pos ; -TUPLE: left-recursion seed rule head next ; -TUPLE: peg-head rule involved-set eval-set ; +TUPLE: left-recursion seed rule-id head next ; +TUPLE: peg-head rule-id involved-set eval-set ; : rule-id ( word -- id ) #! A rule is the parser compiled down to a word. It has @@ -123,15 +123,15 @@ TUPLE: peg-head rule involved-set eval-set ; #! stack effect ( -- parse-result ) pos get swap execute process-rule-result ; inline -: memo ( pos rule -- memo-entry ) +: memo ( pos id -- memo-entry ) #! Return the result from the memo cache. - rule-id packrat at + packrat at ! " memo result " write dup . ; -: set-memo ( memo-entry pos rule -- ) +: set-memo ( memo-entry pos id -- ) #! Store an entry in the cache - rule-id packrat set-at ; + packrat set-at ; : update-m ( ast m -- ) swap >>ans pos get >>pos drop ; @@ -163,13 +163,13 @@ TUPLE: peg-head rule involved-set eval-set ; :: (setup-lr) ( r l s -- ) s head>> l head>> eq? [ l head>> s (>>head) - l head>> [ s rule>> suffix ] change-involved-set drop + l head>> [ s rule-id>> suffix ] change-involved-set drop r l s next>> (setup-lr) ] unless ; :: setup-lr ( r l -- ) l head>> [ - r V{ } clone V{ } clone peg-head boa l (>>head) + r rule-id V{ } clone V{ } clone peg-head boa l (>>head) ] unless r l lrstack get (setup-lr) ; @@ -177,7 +177,7 @@ TUPLE: peg-head rule involved-set eval-set ; [let* | h [ m ans>> head>> ] | - h rule>> r eq? [ + h rule-id>> r rule-id eq? [ m ans>> seed>> m (>>ans) m ans>> failed? [ fail @@ -191,15 +191,15 @@ TUPLE: peg-head rule involved-set eval-set ; :: recall ( r p -- memo-entry ) [let* | - m [ p r memo ] + m [ p r rule-id memo ] h [ p heads at ] | h [ - m r h involved-set>> h rule>> suffix member? not and [ + m r rule-id h involved-set>> h rule-id>> suffix member? not and [ fail p memo-entry boa ] [ - r h eval-set>> member? [ - h [ r swap remove ] change-eval-set drop + r rule-id h eval-set>> member? [ + h [ r rule-id swap remove ] change-eval-set drop r eval-rule m update-m m @@ -214,8 +214,8 @@ TUPLE: peg-head rule involved-set eval-set ; :: apply-non-memo-rule ( r p -- ast ) [let* | - lr [ fail r f lrstack get left-recursion boa ] - m [ lr lrstack set lr p memo-entry boa dup p r set-memo ] + lr [ fail r rule-id f lrstack get left-recursion boa ] + m [ lr lrstack set lr p memo-entry boa dup p r rule-id set-memo ] ans [ r eval-rule ] | lrstack get next>> lrstack set From dda15b0d0617c9e251d4fec51fe163cef3eab408 Mon Sep 17 00:00:00 2001 From: Bruno Deferrari Date: Wed, 9 Jul 2008 23:11:39 -0300 Subject: [PATCH 0598/1850] irc.client: Fix join message handling --- extra/irc/client/client.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index ffe78437a7..472805f5ae 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -155,7 +155,7 @@ M: privmsg handle-incoming-irc ( privmsg -- ) M: join handle-incoming-irc ( join -- ) [ [ prefix>> parse-name me? ] keep and [ irc> join-messages>> mailbox-put ] when* ] - [ dup channel>> to-listener ] + [ dup trailing>> to-listener ] bi ; M: part handle-incoming-irc ( part -- ) From 2a1aa7b019bd386312c7fe7dc6d4119490ddecce Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 9 Jul 2008 23:41:45 -0500 Subject: [PATCH 0599/1850] Conversation scope work in progress --- extra/furnace/actions/actions.factor | 36 +++--- extra/furnace/alloy/alloy.factor | 14 +-- extra/furnace/asides/asides.factor | 104 ------------------ extra/furnace/auth/auth.factor | 14 ++- extra/furnace/auth/basic/basic.factor | 4 +- .../deactivate-user/deactivate-user.factor | 5 +- .../features/edit-profile/edit-profile.factor | 10 +- extra/furnace/auth/login/login.factor | 22 ++-- .../conversations/conversations.factor | 81 +++++++++----- extra/furnace/flash/flash.factor | 61 ---------- extra/furnace/sessions/sessions.factor | 2 +- extra/http/http-tests.factor | 4 +- .../redirection/redirection-tests.factor | 3 +- extra/webapps/blogs/blogs.factor | 2 +- 14 files changed, 114 insertions(+), 248 deletions(-) delete mode 100644 extra/furnace/asides/asides.factor delete mode 100644 extra/furnace/flash/flash.factor diff --git a/extra/furnace/actions/actions.factor b/extra/furnace/actions/actions.factor index ad8a36cca5..d42972c360 100755 --- a/extra/furnace/actions/actions.factor +++ b/extra/furnace/actions/actions.factor @@ -7,7 +7,8 @@ xml.entities http.server http.server.responses furnace -furnace.flash +furnace.redirection +furnace.conversations html.forms html.elements html.components @@ -38,20 +39,23 @@ TUPLE: action rest authorize init display validate submit ; : ( -- action ) action new-action ; +: merge-forms ( form -- ) + form get + [ [ errors>> ] bi@ push-all ] + [ [ values>> ] bi@ swap update ] + [ swap validation-failed>> >>validation-failed drop ] + 2tri ; + : set-nested-form ( form name -- ) dup empty? [ - drop form set + drop merge-forms ] [ - dup length 1 = [ - first set-value - ] [ - unclip [ set-nested-form ] nest-form - ] if + unclip [ set-nested-form ] nest-form ] if ; : restore-validation-errors ( -- ) - form fget [ - nested-forms fget set-nested-form + form cget [ + nested-forms cget set-nested-form ] when* ; : handle-get ( action -- response ) @@ -75,11 +79,13 @@ TUPLE: action rest authorize init display validate submit ; revalidate-url-key param dup [ >url [ same-host? ] keep and ] when ; -: validation-failed ( flashed -- * ) - post-request? revalidate-url and dup [ - nested-forms-key param " " split harvest nested-forms set - swap { form nested-forms } append - ] [ 2drop <400> ] if +: validation-failed ( -- * ) + post-request? revalidate-url and [ + begin-conversation + nested-forms-key param " " split harvest nested-forms cset + form get form cset + + ] [ <400> ] if* exit-with ; : handle-post ( action -- response ) @@ -112,7 +118,7 @@ M: action modify-form drop url get revalidate-url-key hidden-form-field ; : check-validation ( -- ) - validation-failed? [ { } validation-failed ] when ; + validation-failed? [ validation-failed ] when ; : validate-params ( validators -- ) params get swap validate-values check-validation ; diff --git a/extra/furnace/alloy/alloy.factor b/extra/furnace/alloy/alloy.factor index 28c34e6715..29cb37b557 100644 --- a/extra/furnace/alloy/alloy.factor +++ b/extra/furnace/alloy/alloy.factor @@ -1,26 +1,24 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences db.tuples alarms calendar db fry -furnace.cache -furnace.asides -furnace.flash -furnace.sessions -furnace.referrer furnace.db +furnace.cache +furnace.referrer +furnace.sessions +furnace.conversations furnace.auth.providers furnace.auth.login.permits ; IN: furnace.alloy : ( responder db params -- responder' ) '[ - - + , , ] call ; -: state-classes { session flash-scope aside permit } ; inline +: state-classes { session conversation permit } ; inline : init-furnace-tables ( -- ) state-classes ensure-tables diff --git a/extra/furnace/asides/asides.factor b/extra/furnace/asides/asides.factor deleted file mode 100644 index 6d41c637c6..0000000000 --- a/extra/furnace/asides/asides.factor +++ /dev/null @@ -1,104 +0,0 @@ -! Copyright (C) 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: accessors namespaces sequences arrays kernel -assocs hashtables math.parser urls combinators -logging db.types db.tuples -html.elements -html.templates.chloe.syntax -http -http.server -http.server.filters -furnace -furnace.cache -furnace.sessions -furnace.redirection ; -IN: furnace.asides - -TUPLE: aside < server-state session method url post-data ; - -: