From ba68a3732dbc1bdf5becc0db03e2ea2a2e54d054 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Mon, 14 Jan 2008 15:49:13 -1000 Subject: [PATCH 01/78] better support for http-get redirects --- extra/http/client/client.factor | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/extra/http/client/client.factor b/extra/http/client/client.factor index f117a4fda1..7c385c0bb3 100644 --- a/extra/http/client/client.factor +++ b/extra/http/client/client.factor @@ -9,11 +9,14 @@ IN: http.client #! Extract the host name and port number from an HTTP URL. ":" split1 [ string>number ] [ 80 ] if* ; +SYMBOL: domain + : parse-url ( url -- host resource ) - "http://" ?head [ - "URL must begin with http://" throw - ] unless - "/" split1 [ "/" swap append ] [ "/" ] if* ; + dup "https://" head? [ + "ssl not yet supported: " swap append throw + ] when "http://" ?head drop + "/" split1 [ "/" swap append ] [ "/" ] if* + >r dup empty? [ drop domain get ] [ dup domain set ] if r> ; : parse-response ( line -- code ) "HTTP/" ?head [ " " split1 nip ] when @@ -52,7 +55,9 @@ DEFER: http-get-stream : http-get ( url -- code headers string ) #! Opens a stream for reading from an HTTP URL. - http-get-stream [ stdio get contents ] with-stream ; + [ + http-get-stream [ stdio get contents ] with-stream + ] with-scope ; : download ( url file -- ) #! Downloads the contents of a URL to a file. From 27d56e998ddb29640072dbc0ca5391300e69b076 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 16 Jan 2008 10:18:53 -1000 Subject: [PATCH 02/78] make lots of calendar words GENERIC: clean up the codez --- extra/calendar/calendar.factor | 134 +++++++++++++++++++++++---------- 1 file changed, 96 insertions(+), 38 deletions(-) diff --git a/extra/calendar/calendar.factor b/extra/calendar/calendar.factor index c9b62ce7aa..8c1c2fb3a6 100755 --- a/extra/calendar/calendar.factor +++ b/extra/calendar/calendar.factor @@ -4,7 +4,8 @@ USING: arrays hashtables io io.streams.string kernel math math.vectors math.functions math.parser namespaces sequences strings tuples system debugger combinators vocabs.loader -calendar.backend structs alien.c-types math.vectors ; +calendar.backend structs alien.c-types math.vectors +math.ranges shuffle ; IN: calendar TUPLE: timestamp year month day hour minute second gmt-offset ; @@ -115,14 +116,18 @@ GENERIC: +second ( timestamp x -- timestamp ) : /rem ( f n -- q r ) #! q is positive or negative, r is positive from 0 <= r < n - [ /f floor >bignum ] 2keep rem ; + [ /f floor >integer ] 2keep rem ; : float>whole-part ( float -- int float ) - [ floor >bignum ] keep over - ; + [ floor >integer ] keep over - ; -: leap-year? ( year -- ? ) +GENERIC: leap-year? ( obj -- ? ) +M: integer leap-year? ( year -- ? ) dup 100 mod zero? 400 4 ? mod zero? ; +M: timestamp leap-year? ( timestamp -- ? ) + timestamp-year leap-year? ; + : adjust-leap-year ( timestamp -- timestamp ) dup >date< 29 = swap 2 = and swap leap-year? not and [ dup >r timestamp-year 3 1 r> [ set-date ] keep @@ -161,7 +166,7 @@ M: real +minute ( timestamp n -- timestamp ) float>whole-part rot swap 60 * +second swap +minute ; M: number +second ( timestamp n -- timestamp ) - over timestamp-second + 60 /rem >r >bignum r> + over timestamp-second + 60 /rem >r >integer r> pick set-timestamp-second +minute ; : +dt ( timestamp dt -- timestamp ) @@ -178,6 +183,9 @@ M: number +second ( timestamp n -- timestamp ) [ 0 seconds +dt ] keep [ = [ "invalid timestamp" throw ] unless ] keep ; +: make-date ( year month day -- timestamp ) + 0 0 0 gmt-offset make-timestamp ; + : array>dt ( vec -- dt ) { dt f } swap append >tuple ; : +dts ( dt dt -- dt ) [ tuple-slots ] 2apply v+ array>dt ; @@ -214,14 +222,14 @@ M: timestamp <=> ( ts1 ts2 -- n ) [ [ >date< julian-day-number ] 2apply - 86400 * ] 2keep [ >time< >r >r 3600 * r> 60 * r> + + ] 2apply - + ; -: unix-1970 +: unix-1970 ( -- timestamp ) 1970 1 1 0 0 0 0 ; : unix-time>timestamp ( n -- timestamp ) >r unix-1970 r> seconds +dt ; : timestamp>unix-time ( timestamp -- n ) - unix-1970 timestamp- >bignum ; + unix-1970 timestamp- >integer ; : timestamp>timeval ( timestamp -- timeval ) timestamp>unix-time 1000 * make-timeval ; @@ -240,14 +248,7 @@ M: timestamp <=> ( ts1 ts2 -- n ) : from-now ( dt -- timestamp ) now swap +dt ; : ago ( dt -- timestamp ) before from-now ; -: days-in-year ( year -- n ) leap-year? 366 365 ? ; : day-counts { 0 31 28 31 30 31 30 31 31 30 31 30 31 } ; -: days-in-month ( year month -- n ) - swap leap-year? [ - [ day-counts nth ] keep 2 = [ 1+ ] when - ] [ - day-counts nth - ] if ; : zeller-congruence ( year month day -- n ) #! Zeller Congruence @@ -258,33 +259,79 @@ M: timestamp <=> ( ts1 ts2 -- n ) [ 1+ 3 * 5 /i + ] keep 2 * + r> 1+ + 7 mod ; -: day-of-week ( timestamp -- n ) +GENERIC: days-in-year ( obj -- n ) + +M: integer days-in-year ( year -- n ) leap-year? 366 365 ? ; +M: timestamp days-in-year ( timestamp -- n ) timestamp-year days-in-year ; + +GENERIC: days-in-month ( obj -- n ) + +M: array days-in-month ( obj -- n ) + first2 dup 2 = [ + drop leap-year? 29 28 ? + ] [ + nip day-counts nth + ] if ; + +M: timestamp days-in-month ( timestamp -- n ) + { timestamp-year timestamp-month } get-slots 2array days-in-month ; + +GENERIC: day-of-week ( obj -- n ) + +M: timestamp day-of-week ( timestamp -- n ) >date< zeller-congruence ; -: day-of-year ( timestamp -- n ) - [ - [ timestamp-year leap-year? ] keep - [ >date< 3array ] keep timestamp-year 3 1 3array <=> - 0 >= and 1 0 ? - ] keep - [ timestamp-month day-counts swap head-slice sum + ] keep - timestamp-day + ; +M: array day-of-week ( array -- n ) + first3 zeller-congruence ; -: print-day ( n -- ) +GENERIC: day-of-year ( obj -- n ) + +M: array day-of-year ( array -- n ) + first3 + 3dup day-counts rot head-slice sum + + swap leap-year? [ + -roll + pick 3 1 make-date >r make-date r> + <=> 0 >= [ 1+ ] when + ] [ + 3nip + ] if ; + +M: timestamp day-of-year ( timestamp -- n ) + { timestamp-year timestamp-month timestamp-day } get-slots + 3array day-of-year ; + +GENERIC: day. ( obj -- ) + +M: integer day. ( n -- ) number>string dup length 2 < [ bl ] when write ; -: print-month ( year month -- ) +M: timestamp day. ( timestamp -- ) + timestamp-day day. ; + +GENERIC: month. ( obj -- ) + +M: array month. ( pair -- ) + first2 [ month-names nth write bl number>string print ] 2keep [ 1 zeller-congruence ] 2keep - days-in-month day-abbreviations2 " " join print + 2array days-in-month day-abbreviations2 " " join print over " " concat write [ - [ 1+ print-day ] keep + [ 1+ day. ] keep 1+ + 7 mod zero? [ nl ] [ bl ] if ] with each nl ; -: print-year ( year -- ) - 12 [ 1+ print-month nl ] with each ; +M: timestamp month. ( timestamp -- ) + { timestamp-year timestamp-month } get-slots 2array month. ; + +GENERIC: year. ( obj -- ) + +M: integer year. ( n -- ) + 12 [ 1+ 2array month. nl ] with each ; + +M: timestamp year. ( timestamp -- ) + timestamp-year year. ; : pad-00 number>string 2 CHAR: 0 pad-left write ; @@ -298,9 +345,7 @@ M: timestamp <=> ( ts1 ts2 -- n ) timestamp-second >fixnum pad-00 ; : timestamp>string ( timestamp -- str ) - [ - (timestamp>string) - ] string-out ; + [ (timestamp>string) ] string-out ; : timestamp>http-string ( timestamp -- str ) #! http timestamp format @@ -319,9 +364,7 @@ M: timestamp <=> ( ts1 ts2 -- n ) timestamp-second >fixnum pad-00 CHAR: Z write1 ; : timestamp>rfc3339 ( timestamp -- str ) - >gmt [ - (timestamp>rfc3339) - ] string-out ; + >gmt [ (timestamp>rfc3339) ] string-out ; : expect read1 assert= ; @@ -340,9 +383,7 @@ M: timestamp <=> ( ts1 ts2 -- n ) 0 ; : rfc3339>timestamp ( str -- timestamp ) - [ - (rfc3339>timestamp) - ] string-in ; + [ (rfc3339>timestamp) ] string-in ; : file-time-string ( timestamp -- string ) [ @@ -370,6 +411,23 @@ M: timestamp <=> ( ts1 ts2 -- n ) : friday ( timestamp -- timestamp ) 5 day-this-week ; : saturday ( timestamp -- timestamp ) 6 day-this-week ; +: beginning-of-day ( timestamp -- new-timestamp ) + clone dup >r 0 0 0 r> + { set-timestamp-hour set-timestamp-minute set-timestamp-second } + set-slots ; inline + +: beginning-of-month ( timestamp -- new-timestamp ) + beginning-of-day 1 over set-timestamp-day ; + +: beginning-of-week ( timestamp -- new-timestamp ) + beginning-of-day sunday ; + +: beginning-of-year ( timestamp -- new-timestamp ) + beginning-of-month 1 over set-timestamp-month ; + +: seconds-since-midnight ( timestamp -- x ) + dup beginning-of-day timestamp- ; + { { [ unix? ] [ "calendar.unix" ] } { [ windows? ] [ "calendar.windows" ] } From 93187f356b5905c7a5c42427100e71e1f3601237 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 16 Jan 2008 10:19:50 -1000 Subject: [PATCH 03/78] add map-index, each-index, 2quot-with, or?, and? --- extra/combinators/lib/lib.factor | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/extra/combinators/lib/lib.factor b/extra/combinators/lib/lib.factor index 9356d6c9b5..aae4c5d9ab 100755 --- a/extra/combinators/lib/lib.factor +++ b/extra/combinators/lib/lib.factor @@ -191,3 +191,23 @@ MACRO: construct-slots ( assoc tuple-class -- tuple ) : either ( object first second -- ? ) >r keep swap [ r> drop ] [ r> call ] ?if ; inline + +: 2quot-with ( obj seq quot1 quot2 -- seq quot1 quot2 ) + >r pick >r with r> r> swapd with ; + +: or? ( obj quot1 quot2 -- ? ) + >r keep r> rot [ 2nip ] [ call ] if* ; inline + +: and? ( obj quot1 quot2 -- ? ) + >r keep r> rot [ call ] [ 2drop f ] if ; inline + +: prepare-index ( seq quot -- seq n quot ) + >r dup length r> ; inline + +: each-index ( seq quot -- ) + #! quot: ( elt index -- ) + prepare-index 2each ; inline + +: map-index ( seq quot -- ) + #! quot: ( elt index -- obj ) + prepare-index 2map ; inline From 40df3eefc34ee50e79791da75e026f65977311c1 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 16 Jan 2008 10:20:28 -1000 Subject: [PATCH 04/78] add >Upper, >Upper-dashes --- extra/strings/lib/lib.factor | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/extra/strings/lib/lib.factor b/extra/strings/lib/lib.factor index 870e72b385..223fdb2090 100644 --- a/extra/strings/lib/lib.factor +++ b/extra/strings/lib/lib.factor @@ -1,8 +1,14 @@ - -USING: math arrays sequences ; - +USING: math arrays sequences kernel splitting strings ; IN: strings.lib : char>digit ( c -- i ) 48 - ; : string>digits ( s -- seq ) [ char>digit ] { } map-as ; + +: >Upper ( str -- str ) + dup empty? [ + unclip ch>upper 1string swap append + ] unless ; + +: >Upper-dashes ( str -- str ) + "-" split [ >Upper ] map "-" join ; From 225ead4cedd94c0192d75f273d985a7dfb8a3abd Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 16 Jan 2008 11:25:29 -1000 Subject: [PATCH 05/78] move hashtables.lib to assocs.lib --- extra/assocs/lib/lib.factor | 7 +++++-- extra/automata/ui/ui.factor | 4 ++-- extra/boids/ui/ui.factor | 4 ++-- extra/namespaces/lib/lib.factor | 6 +++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/extra/assocs/lib/lib.factor b/extra/assocs/lib/lib.factor index 0181514ab4..50da66e669 100644 --- a/extra/assocs/lib/lib.factor +++ b/extra/assocs/lib/lib.factor @@ -11,14 +11,17 @@ IN: assocs.lib ! set-hash with alternative stack effects -: put-hash* ( table key value -- ) swap rot set-at ; +: put-hash* ( table key value -- ) spin set-at ; : put-hash ( table key value -- table ) swap pick set-at ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : set-hash-stack ( value key seq -- ) - dupd [ key? ] when find-last nip set-at ; + dupd [ key? ] with find-last nip set-at ; : at-default ( key assoc -- value/key ) dupd at [ nip ] when* ; + +: at-peek ( key assoc -- value ? ) + at* dup >r [ peek ] when r> ; diff --git a/extra/automata/ui/ui.factor b/extra/automata/ui/ui.factor index 5cf9ccc71f..ab424cdab6 100644 --- a/extra/automata/ui/ui.factor +++ b/extra/automata/ui/ui.factor @@ -14,7 +14,7 @@ USING: kernel namespaces math quotations arrays hashtables sequences threads ui.gadgets.packs ui.gadgets.grids ui.gadgets.theme - namespaces.lib hashtables.lib vars + namespaces.lib assocs.lib vars rewrite-closures automata ; IN: automata.ui @@ -85,4 +85,4 @@ over @center grid-add : automata-window ( -- ) [ [ automata-window* ] with-scope ] with-ui ; -MAIN: automata-window \ No newline at end of file +MAIN: automata-window diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor index 235ccc3914..6d04a4d623 100644 --- a/extra/boids/ui/ui.factor +++ b/extra/boids/ui/ui.factor @@ -20,7 +20,7 @@ USING: kernel namespaces ui.gadgets.grids ui.gestures combinators.cleave - hashtables.lib vars rewrite-closures boids ; + assocs.lib vars rewrite-closures boids ; IN: boids.ui @@ -163,4 +163,4 @@ VARS: population-label cohesion-label alignment-label separation-label ; : boids-window ( -- ) [ [ boids-window* ] with-scope ] with-ui ; -MAIN: boids-window \ No newline at end of file +MAIN: boids-window diff --git a/extra/namespaces/lib/lib.factor b/extra/namespaces/lib/lib.factor index 79a4855c04..6e66119cb0 100644 --- a/extra/namespaces/lib/lib.factor +++ b/extra/namespaces/lib/lib.factor @@ -1,8 +1,8 @@ -! USING: kernel quotations namespaces sequences hashtables.lib ; +! USING: kernel quotations namespaces sequences assocs.lib ; USING: kernel namespaces namespaces.private quotations sequences - hashtables.lib ; + assocs.lib ; IN: namespaces.lib @@ -16,4 +16,4 @@ IN: namespaces.lib ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: set* ( val var -- ) namestack* set-hash-stack ; \ No newline at end of file +: set* ( val var -- ) namestack* set-hash-stack ; From 36518ef3921b0d0892a3c0961427899e0fe1b55e Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Wed, 16 Jan 2008 11:26:30 -1000 Subject: [PATCH 06/78] remove hashtables.lib --- extra/hashtables/lib/lib.factor | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100755 extra/hashtables/lib/lib.factor diff --git a/extra/hashtables/lib/lib.factor b/extra/hashtables/lib/lib.factor deleted file mode 100755 index ee35093929..0000000000 --- a/extra/hashtables/lib/lib.factor +++ /dev/null @@ -1,19 +0,0 @@ - -USING: kernel sequences assocs ; - -IN: hashtables.lib - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -: ref-hash ( table key -- value ) swap at ; - -! set-hash with alternative stack effects - -: put-hash* ( table key value -- ) spin set-at ; - -: put-hash ( table key value -- table ) swap pick set-at ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -: set-hash-stack ( value key seq -- ) - dupd [ key? ] with find-last nip set-at ; From 9c78c7c05f61958c460f79254609d27f24d65cbd Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Thu, 17 Jan 2008 12:25:43 -0500 Subject: [PATCH 07/78] Solution to Project Euler problem 27 --- extra/project-euler/004/004.factor | 5 +- extra/project-euler/027/027.factor | 67 ++++++++++++++++++++++++ extra/project-euler/common/common.factor | 8 ++- extra/project-euler/project-euler.factor | 4 +- 4 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 extra/project-euler/027/027.factor diff --git a/extra/project-euler/004/004.factor b/extra/project-euler/004/004.factor index 0db0c6f2cb..d7984a4991 100644 --- a/extra/project-euler/004/004.factor +++ b/extra/project-euler/004/004.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Aaron Schaefer, Daniel Ehrenberg. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays combinators.lib hashtables kernel math math.parser math.ranges +USING: hashtables kernel math math.parser math.ranges project-euler.common sequences sorting ; IN: project-euler.004 @@ -21,9 +21,6 @@ IN: project-euler.004 : palindrome? ( n -- ? ) number>string dup reverse = ; -: cartesian-product ( seq1 seq2 -- seq1xseq2 ) - swap [ swap [ 2array ] map-with ] map-with concat ; - + +: euler027 ( -- answer ) + source-027 max-consecutive drop product ; + +! [ euler027 ] 100 ave-time +! 1306 ms run / 58 ms GC ave time - 100 trials + +! TODO: generalize max-consecutive/max-product (from #26) into a new word + +MAIN: euler027 diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor index 2bd2b7ec0b..d21a780773 100644 --- a/extra/project-euler/common/common.factor +++ b/extra/project-euler/common/common.factor @@ -1,5 +1,5 @@ -USING: kernel math math.functions math.miller-rabin math.parser - math.primes.factors math.ranges namespaces sequences ; +USING: arrays combinators.lib kernel math math.functions math.miller-rabin + math.parser math.primes.factors math.ranges namespaces sequences ; IN: project-euler.common ! A collection of words used by more than one Project Euler solution @@ -7,6 +7,7 @@ IN: project-euler.common ! Problems using each public word ! ------------------------------- +! cartesian-product - #4, #27 ! collect-consecutive - #8, #11 ! log10 - #25, #134 ! max-path - #18, #67 @@ -45,6 +46,9 @@ IN: project-euler.common PRIVATE> +: cartesian-product ( seq1 seq2 -- seq1xseq2 ) + swap [ swap [ 2array ] map-with ] map-with concat ; + : collect-consecutive ( seq width -- seq ) [ 2dup count-shifts [ 2dup head shift-3rd , ] times diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index 6abb056d28..8ff3b9da88 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -8,8 +8,8 @@ USING: definitions io io.files kernel math.parser sequences vocabs project-euler.013 project-euler.014 project-euler.015 project-euler.016 project-euler.017 project-euler.018 project-euler.019 project-euler.020 project-euler.021 project-euler.022 project-euler.023 project-euler.024 - project-euler.025 project-euler.026 project-euler.067 project-euler.134 - project-euler.169 project-euler.173 project-euler.175 ; + project-euler.025 project-euler.026 project-euler.027 project-euler.067 + project-euler.134 project-euler.169 project-euler.173 project-euler.175 ; IN: project-euler Date: Thu, 17 Jan 2008 12:55:02 -0500 Subject: [PATCH 08/78] Optimize solution to Project Euler problem 27 --- extra/project-euler/027/027.factor | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/extra/project-euler/027/027.factor b/extra/project-euler/027/027.factor index abfe4d5704..3ce684549a 100644 --- a/extra/project-euler/027/027.factor +++ b/extra/project-euler/027/027.factor @@ -36,10 +36,15 @@ IN: project-euler.027 ! SOLUTION ! -------- +! b must be prime since n = 0 must return a prime +! a + b + 1 must be prime since n = 1 must return a prime +! a < b + source-027 max-consecutive drop product ; ! [ euler027 ] 100 ave-time -! 1306 ms run / 58 ms GC ave time - 100 trials +! 687 ms run / 23 ms GC ave time - 100 trials ! TODO: generalize max-consecutive/max-product (from #26) into a new word From 43ee25cdf701e70b3734afc35143fc5acc2e31b3 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 17 Jan 2008 12:53:29 -1000 Subject: [PATCH 09/78] fix load errors --- extra/shufflers/shufflers-docs.factor | 3 ++- extra/shufflers/shufflers.factor | 2 +- extra/state-machine/state-machine.factor | 4 ++-- extra/tools/deploy/shaker/shaker.factor | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/extra/shufflers/shufflers-docs.factor b/extra/shufflers/shufflers-docs.factor index efeb4dc8a4..ac372534ae 100644 --- a/extra/shufflers/shufflers-docs.factor +++ b/extra/shufflers/shufflers-docs.factor @@ -1,4 +1,5 @@ -USING: shufflers help.syntax help.markup ; +USING: help.syntax help.markup ; +IN: shufflers HELP: SHUFFLE: { $syntax "SHUFFLE: alphabet #" } diff --git a/extra/shufflers/shufflers.factor b/extra/shufflers/shufflers.factor index 01b5133a80..172db1def1 100644 --- a/extra/shufflers/shufflers.factor +++ b/extra/shufflers/shufflers.factor @@ -29,7 +29,7 @@ IN: shufflers : define-shuffles ( names max-out -- ) in-shuffle over length make-shuffles [ [ shuffle>string create-in ] keep - shuffle>quot dupd define-compound put-effect + shuffle>quot dupd define put-effect ] with each out-shuffle ; : SHUFFLE: diff --git a/extra/state-machine/state-machine.factor b/extra/state-machine/state-machine.factor index 85f4812d9a..ac0bdc81c7 100644 --- a/extra/state-machine/state-machine.factor +++ b/extra/state-machine/state-machine.factor @@ -7,7 +7,7 @@ IN: state-machine ";" parse-tokens [ length ] keep unclip add - [ create-in swap 1quotation define-compound ] 2each ; parsing + [ create-in swap 1quotation define ] 2each ; parsing TUPLE: state place data ; @@ -27,7 +27,7 @@ M: missing-state error. : define-machine ( word state-class -- ) execute make-machine - >r over r> define-compound + >r over r> define "state-table" set-word-prop ; : MACHINE: diff --git a/extra/tools/deploy/shaker/shaker.factor b/extra/tools/deploy/shaker/shaker.factor index d157571757..fcdb6ba76e 100755 --- a/extra/tools/deploy/shaker/shaker.factor +++ b/extra/tools/deploy/shaker/shaker.factor @@ -5,7 +5,7 @@ assocs kernel vocabs words sequences memory io system arrays continuations math definitions mirrors splitting parser classes inspector layouts vocabs.loader prettyprint.config prettyprint debugger io.streams.c io.streams.duplex io.files io.backend -quotations words.private tools.deploy.config ; +quotations words.private tools.deploy.config compliler.units ; IN: tools.deploy.shaker : show ( msg -- ) From b03548caad3eb1a28a59956803c2ec803c0850d5 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 17 Jan 2008 13:00:50 -1000 Subject: [PATCH 10/78] fix typo --- extra/tools/deploy/shaker/shaker.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/tools/deploy/shaker/shaker.factor b/extra/tools/deploy/shaker/shaker.factor index fcdb6ba76e..4ab12bf352 100755 --- a/extra/tools/deploy/shaker/shaker.factor +++ b/extra/tools/deploy/shaker/shaker.factor @@ -5,7 +5,7 @@ assocs kernel vocabs words sequences memory io system arrays continuations math definitions mirrors splitting parser classes inspector layouts vocabs.loader prettyprint.config prettyprint debugger io.streams.c io.streams.duplex io.files io.backend -quotations words.private tools.deploy.config compliler.units ; +quotations words.private tools.deploy.config compiler.units ; IN: tools.deploy.shaker : show ( msg -- ) From 4cba26462df7ebeda53926dc31b8ef07af056a51 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Thu, 17 Jan 2008 23:37:10 -0500 Subject: [PATCH 11/78] Solution to Project Euler problem 28 --- extra/project-euler/027/027.factor | 5 +- extra/project-euler/028/028.factor | 61 ++++++++++++++++++++++++ extra/project-euler/project-euler.factor | 5 +- 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 extra/project-euler/028/028.factor diff --git a/extra/project-euler/027/027.factor b/extra/project-euler/027/027.factor index 3ce684549a..c208caaf9e 100644 --- a/extra/project-euler/027/027.factor +++ b/extra/project-euler/027/027.factor @@ -38,7 +38,10 @@ IN: project-euler.027 ! b must be prime since n = 0 must return a prime ! a + b + 1 must be prime since n = 1 must return a prime -! a < b +! 1 - a + b must be prime as well, hence >= 2. Therefore: +! 1 - a + b >= 2 +! b - a >= 1 +! a < b (2n + 1)² from 0 .. n +! se -> (4 * n²) - (10 * n) + 7 from 1 .. n +! sw -> (4 * n²) + 1 from 0 .. n +! nw -> (4 * n²) - (6 * n) + 3 from 1 .. n + + + +: euler028 ( -- answer ) + 1001 spiral-diags ; + +! [ euler027 ] 100 ave-time +! 0 ms run / 0 ms GC ave time - 100 trials + +MAIN: euler028 diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index 8ff3b9da88..812a010042 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -8,8 +8,9 @@ USING: definitions io io.files kernel math.parser sequences vocabs project-euler.013 project-euler.014 project-euler.015 project-euler.016 project-euler.017 project-euler.018 project-euler.019 project-euler.020 project-euler.021 project-euler.022 project-euler.023 project-euler.024 - project-euler.025 project-euler.026 project-euler.027 project-euler.067 - project-euler.134 project-euler.169 project-euler.173 project-euler.175 ; + project-euler.025 project-euler.026 project-euler.027 project-euler.028 + project-euler.067 project-euler.134 project-euler.169 project-euler.173 + project-euler.175 ; IN: project-euler Date: Fri, 18 Jan 2008 00:43:15 -0500 Subject: [PATCH 12/78] Optimize solution to Project Euler problem 28 --- extra/project-euler/028/028.factor | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/extra/project-euler/028/028.factor b/extra/project-euler/028/028.factor index 33d87ea451..29a864e2a0 100644 --- a/extra/project-euler/028/028.factor +++ b/extra/project-euler/028/028.factor @@ -25,35 +25,20 @@ IN: project-euler.028 ! SOLUTION ! -------- -! Noticed patterns in the diagnoal numbers starting from the origin going to -! the corners and used these instead of generating the entire spiral: -! ne -> (2n + 1)² from 0 .. n -! se -> (4 * n²) - (10 * n) + 7 from 1 .. n -! sw -> (4 * n²) + 1 from 0 .. n -! nw -> (4 * n²) - (6 * n) + 3 from 1 .. n +! For a square sized n by n, the sum of corners is 4n² - 6n + 6 [ sum-corners ] sigma ; PRIVATE> : euler028 ( -- answer ) - 1001 spiral-diags ; + 1001 sum-diags ; ! [ euler027 ] 100 ave-time ! 0 ms run / 0 ms GC ave time - 100 trials From a3dd5cb1e63f8c02068a32a655b9de4e6af1079a Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Fri, 18 Jan 2008 01:24:55 -0500 Subject: [PATCH 13/78] Solution to Project Euler problem 29 --- extra/project-euler/028/028.factor | 2 +- extra/project-euler/029/029.factor | 37 ++++++++++++++++++++++++ extra/project-euler/project-euler.factor | 4 +-- 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 extra/project-euler/029/029.factor diff --git a/extra/project-euler/028/028.factor b/extra/project-euler/028/028.factor index 29a864e2a0..5d20032ea9 100644 --- a/extra/project-euler/028/028.factor +++ b/extra/project-euler/028/028.factor @@ -40,7 +40,7 @@ PRIVATE> : euler028 ( -- answer ) 1001 sum-diags ; -! [ euler027 ] 100 ave-time +! [ euler028 ] 100 ave-time ! 0 ms run / 0 ms GC ave time - 100 trials MAIN: euler028 diff --git a/extra/project-euler/029/029.factor b/extra/project-euler/029/029.factor new file mode 100644 index 0000000000..47855c0bf1 --- /dev/null +++ b/extra/project-euler/029/029.factor @@ -0,0 +1,37 @@ +! Copyright (c) 2007 Aaron Schaefer. +! See http://factorcode.org/license.txt for BSD license. +USING: hashtables kernel math.functions math.ranges project-euler.common + sequences ; +IN: project-euler.029 + +! http://projecteuler.net/index.php?section=problems&id=29 + +! DESCRIPTION +! ----------- + +! Consider all integer combinations of a^b for 2 ≤ a ≤ 5 and 2 ≤ b ≤ 5: + +! 2^2 = 4, 2^3 = 8, 2^4 = 16, 2^5 = 32 +! 3^2 = 9, 3^3 = 27, 3^4 = 81, 3^5 = 243 +! 4^2 = 16, 4^3 = 64, 4^4 = 256, 4^5 = 1024 +! 5^2 = 25, 5^3 = 125, 5^4 = 625, 5^5 = 3125 + +! If they are then placed in numerical order, with any repeats removed, we get +! the following sequence of 15 distinct terms: + +! 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 + +! How many distinct terms are in the sequence generated by a^b for 2 ≤ a ≤ 100 +! and 2 ≤ b ≤ 100? + + +! SOLUTION +! -------- + +: euler029 ( -- answer ) + 2 100 [a,b] dup cartesian-product [ first2 ^ ] map prune length ; + +! [ euler029 ] 100 ave-time +! 951 ms run / 12 ms GC ave time - 100 trials + +MAIN: euler029 diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index 812a010042..513eeba020 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -9,8 +9,8 @@ USING: definitions io io.files kernel math.parser sequences vocabs project-euler.017 project-euler.018 project-euler.019 project-euler.020 project-euler.021 project-euler.022 project-euler.023 project-euler.024 project-euler.025 project-euler.026 project-euler.027 project-euler.028 - project-euler.067 project-euler.134 project-euler.169 project-euler.173 - project-euler.175 ; + project-euler.029 project-euler.067 project-euler.134 project-euler.169 + project-euler.173 project-euler.175 ; IN: project-euler Date: Fri, 18 Jan 2008 02:39:09 -0500 Subject: [PATCH 14/78] XMode fixes --- extra/xmode/README.txt | 3 +++ extra/xmode/catalog/catalog.factor | 22 +++++++++++----------- extra/xmode/marker/context/context.factor | 1 + extra/xmode/marker/marker-tests.factor | 8 ++++++++ extra/xmode/modes/bcel.xml | 2 +- extra/xmode/modes/clips.xml | 2 +- extra/xmode/modes/objective-c.xml | 2 +- extra/xmode/modes/powerdynamo.xml | 16 ++++++++-------- extra/xmode/modes/rview.xml | 2 +- extra/xmode/modes/tthtml.xml | 2 +- 10 files changed, 36 insertions(+), 24 deletions(-) diff --git a/extra/xmode/README.txt b/extra/xmode/README.txt index 57d9f42b22..07d56dd877 100755 --- a/extra/xmode/README.txt +++ b/extra/xmode/README.txt @@ -36,6 +36,9 @@ to depend on: find a mode file which depends on this flaw, please fix it and submit the changes to the jEdit project. +- References to non-existent rule sets in IMPORT tags and DELEGATE + attributes were ignored in jEdit. They raise an error in Factor. + If you wish to contribute a new or improved mode file, please contact the jEdit project. Updated mode files in jEdit will be periodically imported into the Factor source tree. diff --git a/extra/xmode/catalog/catalog.factor b/extra/xmode/catalog/catalog.factor index 6a0efa072e..9c7e6a1ee7 100644 --- a/extra/xmode/catalog/catalog.factor +++ b/extra/xmode/catalog/catalog.factor @@ -42,9 +42,12 @@ MEMO: (load-mode) ( name -- rule-sets ) SYMBOL: rule-sets +: no-such-rule-set ( name -- * ) + "No such rule set: " swap append throw ; + : get-rule-set ( name -- rule-sets rules ) - "::" split1 [ swap (load-mode) ] [ rule-sets get ] if* - tuck at ; + dup "::" split1 [ swap (load-mode) ] [ rule-sets get ] if* + dup -roll at* [ nip ] [ drop no-such-rule-set ] if ; : resolve-delegate ( rule -- ) dup rule-delegate dup string? @@ -68,14 +71,11 @@ SYMBOL: rule-sets : resolve-imports ( ruleset -- ) dup rule-set-imports [ - get-rule-set dup [ - swap rule-sets [ - 2dup import-keywords - import-rules - ] with-variable - ] [ - 3drop - ] if + get-rule-set swap rule-sets [ + dup resolve-delegates + 2dup import-keywords + import-rules + ] with-variable ] with each ; : finalize-rule-set ( ruleset -- ) @@ -99,7 +99,7 @@ SYMBOL: rule-sets (load-mode) dup finalize-mode ; : reset-modes ( -- ) - \ load-mode "memoize" word-prop clear-assoc ; + \ (load-mode) "memoize" word-prop clear-assoc ; : ?glob-matches ( string glob/f -- ? ) dup [ glob-matches? ] [ 2drop f ] if ; diff --git a/extra/xmode/marker/context/context.factor b/extra/xmode/marker/context/context.factor index 8023e1d321..72ac3f2a3f 100644 --- a/extra/xmode/marker/context/context.factor +++ b/extra/xmode/marker/context/context.factor @@ -10,6 +10,7 @@ end ; : ( ruleset parent -- line-context ) + over [ "no context" throw ] unless { set-line-context-in-rule-set set-line-context-parent } line-context construct ; diff --git a/extra/xmode/marker/marker-tests.factor b/extra/xmode/marker/marker-tests.factor index b9621a112a..6bcba91c84 100755 --- a/extra/xmode/marker/marker-tests.factor +++ b/extra/xmode/marker/marker-tests.factor @@ -133,3 +133,11 @@ IN: temporary ] [ f "font:75%/1.6em \"Lucida Grande\", \"Lucida Sans Unicode\", verdana, geneva, sans-serif;" "css" load-mode tokenize-line 2drop ] unit-test + +[ + { + T{ token f "<" MARKUP } + T{ token f "aaa" MARKUP } + T{ token f ">" MARKUP } + } +] [ f "" "html" load-mode tokenize-line nip ] unit-test diff --git a/extra/xmode/modes/bcel.xml b/extra/xmode/modes/bcel.xml index 19ab3cfd67..628911f431 100644 --- a/extra/xmode/modes/bcel.xml +++ b/extra/xmode/modes/bcel.xml @@ -19,7 +19,7 @@ /**/ - + /** */ diff --git a/extra/xmode/modes/clips.xml b/extra/xmode/modes/clips.xml index ce2efcabab..51d89d05eb 100644 --- a/extra/xmode/modes/clips.xml +++ b/extra/xmode/modes/clips.xml @@ -33,7 +33,7 @@ - + [ ] diff --git a/extra/xmode/modes/objective-c.xml b/extra/xmode/modes/objective-c.xml index c6c52c8211..7496838938 100644 --- a/extra/xmode/modes/objective-c.xml +++ b/extra/xmode/modes/objective-c.xml @@ -89,7 +89,7 @@ elif\b if\b - + diff --git a/extra/xmode/modes/powerdynamo.xml b/extra/xmode/modes/powerdynamo.xml index 7babf3dc74..f5eb29e49c 100644 --- a/extra/xmode/modes/powerdynamo.xml +++ b/extra/xmode/modes/powerdynamo.xml @@ -200,11 +200,11 @@ for the other tags (data, document, etc). more support planned for future. */ - + " " - + ' ' @@ -413,11 +413,11 @@ for the other tags (data, document, etc). more support planned for future. - + " " - + ' ' @@ -428,11 +428,11 @@ for the other tags (data, document, etc). more support planned for future. - + " " - + ' ' @@ -444,11 +444,11 @@ for the other tags (data, document, etc). more support planned for future. - + " " - + ' ' diff --git a/extra/xmode/modes/rview.xml b/extra/xmode/modes/rview.xml index 9747465814..2ca2fdf36a 100644 --- a/extra/xmode/modes/rview.xml +++ b/extra/xmode/modes/rview.xml @@ -23,7 +23,7 @@ /**/ - + /** */ diff --git a/extra/xmode/modes/tthtml.xml b/extra/xmode/modes/tthtml.xml index 24d9667c6c..37bfa2fb17 100644 --- a/extra/xmode/modes/tthtml.xml +++ b/extra/xmode/modes/tthtml.xml @@ -101,7 +101,7 @@ HIGHLIGHT_DIGITS="TRUE" DIGIT_RE="(0x[\p{XDigit}]+[lL]?|[\p{Digit}]+(e[\p{Digit}]*)?[lLdDfF]?)"> - + ${ } From 15fa72da9c3c3e1e12f0fa3a2112300c93393c7b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 02:39:24 -0500 Subject: [PATCH 15/78] No point having get/set-global inline --- core/namespaces/namespaces.factor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/namespaces/namespaces.factor b/core/namespaces/namespaces.factor index bac6895b62..3d3d3c554b 100644 --- a/core/namespaces/namespaces.factor +++ b/core/namespaces/namespaces.factor @@ -15,16 +15,16 @@ IN: namespaces PRIVATE> : namespace ( -- namespace ) namestack* peek ; -: namestack ( -- namestack ) namestack* clone ; inline -: set-namestack ( namestack -- ) >vector 0 setenv ; inline +: namestack ( -- namestack ) namestack* clone ; +: set-namestack ( namestack -- ) >vector 0 setenv ; : global ( -- g ) 21 getenv { hashtable } declare ; inline : init-namespaces ( -- ) global 1array set-namestack ; : get ( variable -- value ) namestack* assoc-stack ; flushable : set ( value variable -- ) namespace set-at ; : on ( variable -- ) t swap set ; inline : off ( variable -- ) f swap set ; inline -: get-global ( variable -- value ) global at ; inline -: set-global ( value variable -- ) global set-at ; inline +: get-global ( variable -- value ) global at ; +: set-global ( value variable -- ) global set-at ; : change ( variable quot -- ) >r dup get r> rot slip set ; inline From 423b0c469745f88c6641b75ac995261cc5e11eba Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 17:09:30 -0500 Subject: [PATCH 16/78] Remove useless optimization --- core/cpu/architecture/architecture.factor | 10 ++-------- core/cpu/ppc/architecture/architecture.factor | 14 +------------- core/cpu/x86/architecture/architecture.factor | 10 +--------- core/generator/generator.factor | 17 +++-------------- 4 files changed, 7 insertions(+), 44 deletions(-) diff --git a/core/cpu/architecture/architecture.factor b/core/cpu/architecture/architecture.factor index e48ba97f33..4da22ff38a 100755 --- a/core/cpu/architecture/architecture.factor +++ b/core/cpu/architecture/architecture.factor @@ -51,14 +51,8 @@ HOOK: %save-dispatch-xt compiler-backend ( -- ) M: object %save-dispatch-xt %save-word-xt ; -! Call C primitive -HOOK: %call-primitive compiler-backend ( label -- ) - -! Call another label -HOOK: %call-label compiler-backend ( label -- ) - -! Far jump to C primitive -HOOK: %jump-primitive compiler-backend ( label -- ) +! Call another word +HOOK: %call compiler-backend ( word -- ) ! Local jump for branches HOOK: %jump-label compiler-backend ( label -- ) diff --git a/core/cpu/ppc/architecture/architecture.factor b/core/cpu/ppc/architecture/architecture.factor index edbed571e1..7444c21a8c 100755 --- a/core/cpu/ppc/architecture/architecture.factor +++ b/core/cpu/ppc/architecture/architecture.factor @@ -97,26 +97,14 @@ M: ppc-backend %epilogue ( n -- ) 1 1 rot ADDI 0 MTLR ; -: %prepare-primitive ( word -- ) - #! Save stack pointer to stack_chain->callstack_top, load XT - 4 1 MR - 0 11 LOAD32 - rc-absolute-ppc-2/2 rel-primitive ; - : (%call) 11 MTLR BLRL ; -M: ppc-backend %call-primitive ( word -- ) - %prepare-primitive (%call) ; - : (%jump) 11 MTCTR BCTR ; -M: ppc-backend %jump-primitive ( word -- ) - %prepare-primitive (%jump) ; - : %load-dlsym ( symbol dll register -- ) 0 swap LOAD32 rc-absolute-ppc-2/2 rel-dlsym ; -M: ppc-backend %call-label ( label -- ) BL ; +M: ppc-backend %call ( label -- ) BL ; M: ppc-backend %jump-label ( label -- ) B ; diff --git a/core/cpu/x86/architecture/architecture.factor b/core/cpu/x86/architecture/architecture.factor index 876c631b81..8c5d5c1dc0 100755 --- a/core/cpu/x86/architecture/architecture.factor +++ b/core/cpu/x86/architecture/architecture.factor @@ -70,15 +70,7 @@ M: x86-backend %prepare-alien-invoke temp-reg v>operand 2 cells [+] ds-reg MOV temp-reg v>operand 3 cells [+] rs-reg MOV ; -M: x86-backend %call-primitive ( word -- ) - stack-save-reg stack-reg cell neg [+] LEA - address-operand CALL ; - -M: x86-backend %jump-primitive ( word -- ) - stack-save-reg stack-reg MOV - address-operand JMP ; - -M: x86-backend %call-label ( label -- ) CALL ; +M: x86-backend %call ( label -- ) CALL ; M: x86-backend %jump-label ( label -- ) JMP ; diff --git a/core/generator/generator.factor b/core/generator/generator.factor index df01f9e490..0e499cf90f 100755 --- a/core/generator/generator.factor +++ b/core/generator/generator.factor @@ -100,21 +100,10 @@ UNION: #terminal ! node M: node generate-node drop iterate-next ; -: %call ( word -- ) - dup primitive? [ %call-primitive ] [ %call-label ] if ; - : %jump ( word -- ) - { - { [ dup compiling-label get eq? ] [ - drop current-label-start get %jump-label - ] } - { [ dup primitive? ] [ - %epilogue-later %jump-primitive - ] } - { [ t ] [ - %epilogue-later %jump-label - ] } - } cond ; + dup compiling-label get eq? + [ drop current-label-start get ] [ %epilogue-later ] if + %jump-label ; : generate-call ( label -- next ) dup maybe-compile From 011681f07ab08c0425e398bda93000f6fca3aef2 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 17:09:45 -0500 Subject: [PATCH 17/78] Fix construct-empty transform --- .../transforms/transforms-tests.factor | 4 ++- core/inference/transforms/transforms.factor | 26 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core/inference/transforms/transforms-tests.factor b/core/inference/transforms/transforms-tests.factor index 6dc5bcabcd..9a62a1faca 100644 --- a/core/inference/transforms/transforms-tests.factor +++ b/core/inference/transforms/transforms-tests.factor @@ -1,6 +1,6 @@ IN: temporary USING: sequences inference.transforms tools.test math kernel -quotations ; +quotations tools.test.inference ; : compose-n-quot >quotation ; : compose-n compose-n-quot call ; @@ -18,3 +18,5 @@ quotations ; [ 268 ] [ 1 { 8 { 3 2 } } bitfield-quot call ] unit-test [ 512 ] [ 1 { { 1+ 8 } } bitfield-quot call ] unit-test + +\ construct-empty must-infer diff --git a/core/inference/transforms/transforms.factor b/core/inference/transforms/transforms.factor index 62c3129f3a..eabe4b8c2a 100755 --- a/core/inference/transforms/transforms.factor +++ b/core/inference/transforms/transforms.factor @@ -1,8 +1,8 @@ -! Copyright (C) 2007 Slava Pestov. +! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel words sequences generic math namespaces quotations assocs combinators math.bitfields inference.backend -inference.dataflow inference.state tuples.private ; +inference.dataflow inference.state tuples.private effects ; IN: inference.transforms : pop-literals ( n -- rstate seq ) @@ -61,11 +61,21 @@ M: pair (bitfield-quot) ( spec -- quot ) \ set-slots [ [get-slots] ] 1 define-transform -: [construct] ( word quot -- newquot ) - >r dup +inlined+ depends-on dup tuple-size r> 2curry ; +\ construct-boa [ + dup +inlined+ depends-on + dup tuple-size [ ] 2curry +] 1 define-transform -\ construct-boa -[ [ ] [construct] ] 1 define-transform +\ construct-empty [ + 1 ensure-values + peek-d value? [ + pop-literal + dup +inlined+ depends-on + dup tuple-size [ ] 2curry + swap infer-quot + ] [ + \ construct-empty declared-infer + ] if +] "infer" set-word-prop -\ construct-empty -[ [ ] [construct] ] 1 define-transform +\ construct-empty 1 1 "inferred-effect" set-word-prop From 30dec8b0a886eea7e9f833d3eda019ec3750f3e3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 17:09:55 -0500 Subject: [PATCH 18/78] Fix documentation typos --- core/kernel/kernel-docs.factor | 2 +- extra/io/launcher/launcher-docs.factor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/kernel/kernel-docs.factor b/core/kernel/kernel-docs.factor index 8f0e4efbd9..2301216394 100755 --- a/core/kernel/kernel-docs.factor +++ b/core/kernel/kernel-docs.factor @@ -557,7 +557,7 @@ HELP: dip HELP: while { $values { "pred" "a quotation with stack effect " { $snippet "( -- ? )" } } { "body" "a quotation" } { "tail" "a quotation" } } -{ $description "Repeatedly calls " { $snippet "pred" } ". If it yields " { $link f } ", iteration stops, otherwise " { $snippet "quot" } " is called. After iteration stops, " { $snippet "tail" } " is called." } +{ $description "Repeatedly calls " { $snippet "pred" } ". If it yields " { $link f } ", iteration stops, otherwise " { $snippet "body" } " is called. After iteration stops, " { $snippet "tail" } " is called." } { $notes "In most cases, tail recursion should be used, because it is simpler both in terms of implementation and conceptually. However in some cases this combinator expresses intent better and should be used." $nl "Strictly speaking, the " { $snippet "tail" } " is not necessary, since the following are equivalent:" diff --git a/extra/io/launcher/launcher-docs.factor b/extra/io/launcher/launcher-docs.factor index 99f318eaf4..7ad5e064bf 100755 --- a/extra/io/launcher/launcher-docs.factor +++ b/extra/io/launcher/launcher-docs.factor @@ -85,7 +85,7 @@ HELP: run-detached HELP: { $values { "obj" object } { "stream" "a bidirectional stream" } } -{ $description "Launches a process and redirects its input and output via a paper of pipes which may be read and written as a stream." } +{ $description "Launches a process and redirects its input and output via a pair of pipes which may be read and written as a stream." } { $notes "Closing the stream will block until the process exits." } ; { run-process run-detached } related-words From 5c388404d6e061a1d6b4894e12560b010fe5b2f1 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 17:10:08 -0500 Subject: [PATCH 19/78] Fix sha1 --- extra/benchmark/sha1/sha1.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/benchmark/sha1/sha1.factor b/extra/benchmark/sha1/sha1.factor index 614077c673..897d83ea0e 100644 --- a/extra/benchmark/sha1/sha1.factor +++ b/extra/benchmark/sha1/sha1.factor @@ -1,7 +1,7 @@ USING: crypto.sha1 io.files kernel ; IN: benchmark.sha1 -: sha1-primes-list ( -- seq ) - "extra/math/primes/list/list.factor" resource-path file>sha1 ; +: sha1-primes-list ( -- ) + "extra/math/primes/list/list.factor" resource-path file>sha1 drop ; MAIN: sha1-primes-list From ab7849f71105559a337f81f408cdecccb48bc8f9 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Fri, 18 Jan 2008 17:11:06 -0500 Subject: [PATCH 20/78] Use vectors instead of arrays in solution to Project Euler problem 2 --- extra/project-euler/002/002.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/project-euler/002/002.factor b/extra/project-euler/002/002.factor index b9375b7d1e..55c1b153cc 100644 --- a/extra/project-euler/002/002.factor +++ b/extra/project-euler/002/002.factor @@ -22,12 +22,12 @@ IN: project-euler.002 r add dup 2 tail* sum r> (fib-upto) ] [ 2drop ] if ; + 2dup <= [ [ over push dup 2 tail* sum ] dip (fib-upto) ] [ 2drop ] if ; PRIVATE> : fib-upto ( n -- seq ) - { 0 } 1 rot (fib-upto) ; + V{ 0 } clone 1 rot (fib-upto) ; : euler002 ( -- answer ) 1000000 fib-upto [ even? ] subset sum ; From 588253dfe3f9c042c1522b2b8174236b63f6ad97 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 18:18:54 -0500 Subject: [PATCH 21/78] Cleaning up Unix I/O --- extra/io/unix/backend/backend.factor | 127 +++++++++------------ extra/io/unix/backend/select/select.factor | 53 +++++++++ extra/io/unix/sockets/sockets.factor | 20 ++-- extra/unix/kqueue/kqueue.factor | 73 ++++++++++++ 4 files changed, 188 insertions(+), 85 deletions(-) create mode 100644 extra/io/unix/backend/select/select.factor create mode 100644 extra/unix/kqueue/kqueue.factor diff --git a/extra/io/unix/backend/backend.factor b/extra/io/unix/backend/backend.factor index 3522a2218b..ec73a5395e 100755 --- a/extra/io/unix/backend/backend.factor +++ b/extra/io/unix/backend/backend.factor @@ -1,21 +1,24 @@ -! Copyright (C) 2004, 2007 Slava Pestov. +! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien bit-arrays generic assocs io kernel -kernel.private math io.nonblocking sequences strings structs -sbufs threads unix vectors io.buffers io.backend -io.streams.duplex math.parser continuations system libc ; +USING: alien generic assocs kernel kernel.private math +io.nonblocking sequences strings structs sbufs threads unix +vectors io.buffers io.backend io.streams.duplex math.parser +continuations system libc qualified namespaces ; +QUALIFIED: io IN: io.unix.backend +! Multiplexer protocol +SYMBOL: unix-io-backend + +HOOK: init-unix-io unix-io-backend ( -- ) +HOOK: register-io-task unix-io-backend ( task -- ) +HOOK: unregister-io-task unix-io-backend ( task -- ) +HOOK: unix-io-multiplex unix-io-backend ( timeval -- ) + TUPLE: unix-io ; -! We want namespaces::bind to shadow the bind system call from -! unix -USING: namespaces ; - ! Global variables -SYMBOL: read-fdset SYMBOL: read-tasks -SYMBOL: write-fdset SYMBOL: write-tasks ! Some general stuff @@ -53,9 +56,9 @@ M: integer close-handle ( fd -- ) ! port to finish I/O TUPLE: io-task port callbacks ; -: ( port class -- task ) - >r V{ } clone io-task construct-boa - { set-delegate } r> construct ; inline +: ( port continuation class -- task ) + >r 1vector io-task construct-boa r> construct-delegate ; + inline ! Multiplexer GENERIC: do-io-task ( task -- ? ) @@ -63,58 +66,30 @@ GENERIC: task-container ( task -- vector ) : io-task-fd io-task-port port-handle ; -: add-io-task ( callback task -- ) - [ io-task-callbacks push ] keep - dup io-task-fd over task-container 2dup at [ +: check-io-task ( task -- ) + dup io-task-fd swap task-container at [ "Cannot perform multiple reads from the same port" throw - ] when set-at ; + ] when ; + +: add-io-task ( task -- ) + dup check-io-task + dup register-io-task + dup io-task-fd over task-container set-at ; : remove-io-task ( task -- ) - dup io-task-fd swap task-container delete-at ; + dup io-task-fd over task-container delete-at + unregister-io-task ; : pop-callbacks ( task -- ) - dup io-task-callbacks swap remove-io-task - [ schedule-thread ] each ; + dup remove-io-task + io-task-callbacks [ schedule-thread ] each ; : handle-fd ( task -- ) dup io-task-port touch-port dup do-io-task [ pop-callbacks ] [ drop ] if ; -: handle-fdset ( fdset tasks -- ) - swap [ - swap dup io-task-port timeout? [ - dup io-task-port "Timeout" swap report-error - nip pop-callbacks - ] [ - tuck io-task-fd swap nth - [ handle-fd ] [ drop ] if - ] if drop - ] curry assoc-each ; - -: init-fdset ( fdset tasks -- ) - swap dup clear-bits - [ >r drop t swap r> set-nth ] curry assoc-each ; - -: read-fdset/tasks - read-fdset get-global read-tasks get-global ; - -: write-fdset/tasks - write-fdset get-global write-tasks get-global ; - -: init-fdsets ( -- read write except ) - read-fdset/tasks dupd init-fdset - write-fdset/tasks dupd init-fdset - f ; - -: (io-multiplex) ( ms -- ) - >r FD_SETSIZE init-fdsets r> make-timeval select 0 < [ - err_no ignorable-error? [ (io-error) ] unless - ] when ; - -M: unix-io io-multiplex ( ms -- ) - (io-multiplex) - read-fdset/tasks handle-fdset - write-fdset/tasks handle-fdset ; +: handle-timeout ( task -- ) + "Timeout" over io-task-port report-error pop-callbacks ; ! Readers : reader-eof ( reader -- ) @@ -137,17 +112,18 @@ M: unix-io io-multiplex ( ms -- ) TUPLE: read-task ; -: ( port -- task ) read-task ; +: ( port continuation -- task ) + read-task ; M: read-task do-io-task io-task-port dup refill [ [ reader-eof ] [ drop ] if ] keep ; -M: read-task task-container drop read-tasks get-global ; +M: read-task task-container + drop read-tasks get-global ; M: input-port (wait-to-read) - [ swap add-io-task stop ] callcc0 - pending-error ; + [ add-io-task stop ] callcc0 pending-error ; ! Writers : write-step ( port -- ? ) @@ -156,35 +132,34 @@ M: input-port (wait-to-read) TUPLE: write-task ; -: ( port -- task ) write-task ; +: ( port continuation -- task ) + write-task ; M: write-task do-io-task io-task-port dup buffer-empty? over port-error or [ 0 swap buffer-reset t ] [ write-step ] if ; -M: write-task task-container drop write-tasks get-global ; +M: write-task task-container + drop write-tasks get-global ; -: add-write-io-task ( callback task -- ) - dup io-task-fd write-tasks get-global at - [ io-task-callbacks push ] [ add-io-task ] ?if ; +: add-write-io-task ( port continuation -- ) + over port-handle write-tasks get-global at + [ io-task-callbacks push drop ] + [ add-io-task ] if* ; : (wait-to-write) ( port -- ) - [ swap add-write-io-task stop ] callcc0 drop ; + [ add-write-io-task stop ] callcc0 drop ; M: port port-flush ( port -- ) dup buffer-empty? [ drop ] [ (wait-to-write) ] if ; -USE: io +M: unix-io io-multiplex ( ms -- ) + make-timeval unix-io-multiplex ; M: unix-io init-io ( -- ) - #! Should only be called on startup. Calling this at any - #! other time can have unintended consequences. - global [ - H{ } clone read-tasks set - FD_SETSIZE 8 * read-fdset set - H{ } clone write-tasks set - FD_SETSIZE 8 * write-fdset set - ] bind ; + H{ } clone read-tasks set-global + H{ } clone write-tasks set-global + init-unix-io ; M: unix-io init-stdio ( -- ) - 0 1 handle>duplex-stream stdio set-global ; + 0 1 handle>duplex-stream io:stdio set-global ; diff --git a/extra/io/unix/backend/select/select.factor b/extra/io/unix/backend/select/select.factor new file mode 100644 index 0000000000..255010bff6 --- /dev/null +++ b/extra/io/unix/backend/select/select.factor @@ -0,0 +1,53 @@ +! Copyright (C) 2004, 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax kernel io.nonblocking io.unix.backend +bit-arrays sequences assocs unix math namespaces ; +IN: io.unix.backend.select + +TUPLE: unix-select-io ; + +! Global variables +SYMBOL: read-fdset +SYMBOL: write-fdset + +M: unix-select-io init-unix-io ( -- ) + FD_SETSIZE 8 * read-fdset set-global + FD_SETSIZE 8 * write-fdset set-global ; + +: handle-fdset ( fdset tasks -- ) + swap [ + swap dup io-task-port timeout? [ + nip handle-timeout + ] [ + tuck io-task-fd swap nth + [ handle-fd ] [ drop ] if + ] if drop + ] curry assoc-each ; + +: init-fdset ( fdset tasks -- ) + swap dup clear-bits + [ >r drop t swap r> set-nth ] curry assoc-each ; + +: read-fdset/tasks + read-fdset get-global read-tasks get-global ; + +: write-fdset/tasks + write-fdset get-global write-tasks get-global ; + +: init-fdsets ( -- read write except ) + read-fdset/tasks dupd init-fdset + write-fdset/tasks dupd init-fdset + f ; + +M: unix-select-io register-io-task ( task -- ) drop ; + +M: unix-select-io unregister-io-task ( task -- ) drop ; + +M: unix-select-io unix-io-multiplex ( timeval -- ) + >r FD_SETSIZE init-fdsets r> select 0 < [ + err_no ignorable-error? [ (io-error) ] unless + ] when + read-fdset/tasks handle-fdset + write-fdset/tasks handle-fdset ; + +T{ unix-select-io } unix-io-backend set-global diff --git a/extra/io/unix/sockets/sockets.factor b/extra/io/unix/sockets/sockets.factor index 0787a1afde..30d3bbd94c 100644 --- a/extra/io/unix/sockets/sockets.factor +++ b/extra/io/unix/sockets/sockets.factor @@ -33,7 +33,8 @@ M: unix-io addrinfo-error ( n -- ) TUPLE: connect-task ; -: ( port -- task ) connect-task ; +: ( port continuation -- task ) + connect-task ; M: connect-task do-io-task io-task-port dup port-handle f 0 write @@ -42,7 +43,7 @@ M: connect-task do-io-task M: connect-task task-container drop write-tasks get-global ; : wait-to-connect ( port -- ) - [ swap add-io-task stop ] callcc0 drop ; + [ add-io-task stop ] callcc0 drop ; M: unix-io (client) ( addrspec -- stream ) dup make-sockaddr/size >r >r @@ -66,7 +67,8 @@ USE: unix TUPLE: accept-task ; -: ( port -- task ) accept-task ; +: ( port continuation -- task ) + accept-task ; M: accept-task task-container drop read-tasks get ; @@ -85,7 +87,7 @@ M: accept-task do-io-task over 0 >= [ do-accept t ] [ 2drop defer-error ] if ; : wait-to-accept ( server -- ) - [ swap add-io-task stop ] callcc0 drop ; + [ add-io-task stop ] callcc0 drop ; USE: io.sockets @@ -136,7 +138,8 @@ packet-size receive-buffer set-global TUPLE: receive-task ; -: ( stream -- task ) receive-task ; +: ( stream continuation -- task ) + receive-task ; M: receive-task do-io-task io-task-port @@ -152,7 +155,7 @@ M: receive-task do-io-task M: receive-task task-container drop read-tasks get ; : wait-receive ( stream -- ) - [ swap add-io-task stop ] callcc0 drop ; + [ add-io-task stop ] callcc0 drop ; M: unix-io receive ( datagram -- packet addrspec ) dup check-datagram-port @@ -166,7 +169,7 @@ M: unix-io receive ( datagram -- packet addrspec ) TUPLE: send-task packet sockaddr len ; -: ( packet sockaddr len port -- task ) +: ( packet sockaddr len stream continuation -- task ) send-task [ { set-send-task-packet @@ -185,8 +188,7 @@ M: send-task do-io-task M: send-task task-container drop write-tasks get ; : wait-send ( packet sockaddr len stream -- ) - [ >r r> swap add-io-task stop ] callcc0 - 2drop 2drop ; + [ add-io-task stop ] callcc0 2drop 2drop ; M: unix-io send ( packet addrspec datagram -- ) 3dup check-datagram-send diff --git a/extra/unix/kqueue/kqueue.factor b/extra/unix/kqueue/kqueue.factor new file mode 100644 index 0000000000..4e6504470d --- /dev/null +++ b/extra/unix/kqueue/kqueue.factor @@ -0,0 +1,73 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax ; +IN: unix.kqueue + +FUNCTION: int kqueue ( ) ; + +FUNCTION: int kevent ( int kq, kevent* changelist, int nchanges, kevent* eventlist, int nevents, timespec* timeout ) ; + +C-STRUCT: kevent + { "ulong" "ident" } ! identifier for this event + { "short" "filter" } ! filter for event + { "ushort" "flags" } ! action flags for kqueue + { "uint" "fflags" } ! filter flag value + { "long" "data" } ! filter data value + { "void*" "udata" } ! opaque user data identifier +; + +: EVFILT_READ -1 ; inline +: EVFILT_WRITE -2 ; inline +: EVFILT_AIO -3 ; inline ! attached to aio requests +: EVFILT_VNODE -4 ; inline ! attached to vnodes +: EVFILT_PROC -5 ; inline ! attached to struct proc +: EVFILT_SIGNAL -6 ; inline ! attached to struct proc +: EVFILT_TIMER -7 ; inline ! timers +: EVFILT_MACHPORT -8 ; inline ! Mach ports +: EVFILT_FS -9 ; inline ! Filesystem events + +! actions +: EV_ADD HEX: 1 ; inline ! add event to kq (implies enable) +: EV_DELETE HEX: 2 ; inline ! delete event from kq +: EV_ENABLE HEX: 4 ; inline ! enable event +: EV_DISABLE HEX: 8 ; inline ! disable event (not reported) + +! flags +: EV_ONESHOT HEX: 10 ; inline ! only report one occurrence +: EV_CLEAR HEX: 20 ; inline ! clear event state after reporting + +: EV_SYSFLAGS HEX: f000 ; inline ! reserved by system +: EV_FLAG0 HEX: 1000 ; inline ! filter-specific flag +: EV_FLAG1 HEX: 2000 ; inline ! filter-specific flag + +! returned values +: EV_EOF HEX: 8000 ; inline ! EOF detected +: EV_ERROR HEX: 4000 ; inline ! error, data contains errno + +: EV_POLL EV_FLAG0 ; inline +: EV_OOBAND EV_FLAG1 ; inline + +: NOTE_LOWAT HEX: 00000001 ; inline ! low water mark + +: NOTE_DELETE HEX: 00000001 ; inline ! vnode was removed +: NOTE_WRITE HEX: 00000002 ; inline ! data contents changed +: NOTE_EXTEND HEX: 00000004 ; inline ! size increased +: NOTE_ATTRIB HEX: 00000008 ; inline ! attributes changed +: NOTE_LINK HEX: 00000010 ; inline ! link count changed +: NOTE_RENAME HEX: 00000020 ; inline ! vnode was renamed +: NOTE_REVOKE HEX: 00000040 ; inline ! vnode access was revoked + +: NOTE_EXIT HEX: 80000000 ; inline ! process exited +: NOTE_FORK HEX: 40000000 ; inline ! process forked +: NOTE_EXEC HEX: 20000000 ; inline ! process exec'd +: NOTE_PCTRLMASK HEX: f0000000 ; inline ! mask for hint bits +: NOTE_PDATAMASK HEX: 000fffff ; inline ! mask for pid + +: NOTE_SECONDS HEX: 00000001 ; inline ! data is seconds +: NOTE_USECONDS HEX: 00000002 ; inline ! data is microseconds +: NOTE_NSECONDS HEX: 00000004 ; inline ! data is nanoseconds +: NOTE_ABSOLUTE HEX: 00000008 ; inline ! absolute timeout + +: NOTE_TRACK HEX: 00000001 ; inline ! follow across forks +: NOTE_TRACKERR HEX: 00000002 ; inline ! could not track child +: NOTE_CHILD HEX: 00000004 ; inline ! am a child process From 309a1c179c6fb745210eb7f92dce8c0a872abcf3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 19:43:14 -0500 Subject: [PATCH 22/78] Add stderr stream; more Unix I/O work --- core/io/io.factor | 3 + core/io/streams/c/c.factor | 5 +- extra/io/unix/backend/backend.factor | 8 ++- extra/io/unix/backend/kqueue/kqueue.factor | 83 ++++++++++++++++++++++ extra/io/unix/backend/select/select.factor | 5 +- extra/io/unix/unix.factor | 16 +++-- extra/structs/structs.factor | 1 - extra/unix/unix.factor | 6 ++ vm/io.c | 5 +- vm/run.h | 7 +- 10 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 extra/io/unix/backend/kqueue/kqueue.factor diff --git a/core/io/io.factor b/core/io/io.factor index 0336ffda78..56b284eaaf 100755 --- a/core/io/io.factor +++ b/core/io/io.factor @@ -35,6 +35,9 @@ GENERIC: stream-write-table ( table-cells style stream -- ) ! Default stream SYMBOL: stdio +! Default error stream +SYMBOL: stderr + : close ( -- ) stdio get stream-close ; : readln ( -- str/f ) stdio get stream-readln ; diff --git a/core/io/streams/c/c.factor b/core/io/streams/c/c.factor index 61eea4ba7b..1dfb89f9c9 100755 --- a/core/io/streams/c/c.factor +++ b/core/io/streams/c/c.factor @@ -57,11 +57,12 @@ M: c-reader stream-close M: object init-io ; : stdin 11 getenv ; - : stdout 12 getenv ; +: stderr 38 getenv ; M: object init-stdio - stdin stdout stdio set-global ; + stdin stdout stdio set-global + stderr stderr set-global ; M: object io-multiplex (sleep) ; diff --git a/extra/io/unix/backend/backend.factor b/extra/io/unix/backend/backend.factor index ec73a5395e..f29d71dd86 100755 --- a/extra/io/unix/backend/backend.factor +++ b/extra/io/unix/backend/backend.factor @@ -154,7 +154,7 @@ M: port port-flush ( port -- ) dup buffer-empty? [ drop ] [ (wait-to-write) ] if ; M: unix-io io-multiplex ( ms -- ) - make-timeval unix-io-multiplex ; + unix-io-multiplex ; M: unix-io init-io ( -- ) H{ } clone read-tasks set-global @@ -162,4 +162,8 @@ M: unix-io init-io ( -- ) init-unix-io ; M: unix-io init-stdio ( -- ) - 0 1 handle>duplex-stream io:stdio set-global ; + 0 1 handle>duplex-stream io:stdio set-global + 2 io:stderr set-global ; + +: multiplexer-error ( n -- ) + 0 < [ err_no ignorable-error? [ (io-error) ] unless ] when ; diff --git a/extra/io/unix/backend/kqueue/kqueue.factor b/extra/io/unix/backend/kqueue/kqueue.factor new file mode 100644 index 0000000000..35f2641e00 --- /dev/null +++ b/extra/io/unix/backend/kqueue/kqueue.factor @@ -0,0 +1,83 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax kernel io.nonblocking io.unix.backend +sequences assocs unix unix.kqueue math namespaces ; +IN: io.unix.backend.kqueue + +TUPLE: unix-kqueue-io ; + +! Global variables +SYMBOL: kqueue-fd +SYMBOL: kqueue-changes +SYMBOL: kqueue-events + +: max-events ( -- n ) + #! We read up to 256 events at a time. This is an arbitrary + #! constant... + 256 ; inline + +M: unix-kqueue-io init-unix-io ( -- ) + V{ } clone kqueue-changes set-global + max-events "kevent" kqueue-events set-global + kqueue kqueue-fd dup io-error set-global ; + +: add-change ( event -- ) kqueue-changes get-global push ; + +: io-task-filter ( task -- n ) + class { + { read-task EVFILT_READ } + { accept-task EVFILT_READ } + { receive-task EVFILT_READ } + { write-task EVFILT_WRITE } + { connect-task EVFILT_WRITE } + { send-task EVFILT_WRITE } + } case ; + +: make-kevent ( task -- event ) + "kevent" + over io-task-fd over set-kevent-ident + over io-task-filter over set-kevent-filter ; + +: make-add-kevent ( task -- event ) + make-kevent + EV_ADD over set-kevent-flags ; + +: make-delete-kevent ( task -- event ) + make-kevent + EV_DELETE over set-kevent-flags ; + +M: unix-select-io register-io-task ( task -- ) + make-add-kevent add-change ; + +M: unix-select-io unregister-io-task ( task -- ) + make-delete-kevent add-change ; + +: kqueue-changelist ( -- byte-array n ) + kqueue-changes get-global + dup concat f like over length rot delete-all ; + +: kqueue-eventlist ( -- byte-array n ) + kqueue-events get-global max-events ; + +: do-kevent ( timespec -- n ) + >r + kqueue-fd get-global + kqueue-changelist + kqueue-eventlist + r> kevent dup multiplexer-error ; + +: kevent-task ( kevent -- task ) + dup kevent-filter { + { [ dup EVFILT_READ = ] [ read-tasks ] } + { [ dup EVFILT_WRITE = ] [ write-tasks ] } + } cond get at ; + +: handle-kevents ( n eventlist -- ) + [ kevent-nth kevent-task handle-fd ] curry each ; + +M: unix-select-io unix-io-multiplex ( ms -- ) + make-timespec + do-kevent + kqueue-events get-global handle-kevents ; + +T{ unix-kqueue-io } unix-io-backend set-global diff --git a/extra/io/unix/backend/select/select.factor b/extra/io/unix/backend/select/select.factor index 255010bff6..b132c8b9e8 100644 --- a/extra/io/unix/backend/select/select.factor +++ b/extra/io/unix/backend/select/select.factor @@ -44,9 +44,8 @@ M: unix-select-io register-io-task ( task -- ) drop ; M: unix-select-io unregister-io-task ( task -- ) drop ; M: unix-select-io unix-io-multiplex ( timeval -- ) - >r FD_SETSIZE init-fdsets r> select 0 < [ - err_no ignorable-error? [ (io-error) ] unless - ] when + make-timeval >r FD_SETSIZE init-fdsets r> + select multiplexer-error read-fdset/tasks handle-fdset write-fdset/tasks handle-fdset ; diff --git a/extra/io/unix/unix.factor b/extra/io/unix/unix.factor index 7114f388e0..1c86224433 100755 --- a/extra/io/unix/unix.factor +++ b/extra/io/unix/unix.factor @@ -1,9 +1,11 @@ -USE: io.unix.backend -USE: io.unix.files -USE: io.unix.sockets -USE: io.unix.launcher -USE: io.unix.mmap -USE: io.backend -USE: namespaces +USING: io.unix.backend io.unix.files io.unix.sockets +io.unix.launcher io.unix.mmap io.backend combinators namespaces +system vocabs.loader ; + +{ + { [ macosx? ] [ "io.unix.backend.kqueue" ] } + { [ bsd? ] [ "io.unix.backend.kqueue" ] } + { [ unix? ] [ "io.unix.backend.select" ] } +} cond require T{ unix-io } io-backend set-global diff --git a/extra/structs/structs.factor b/extra/structs/structs.factor index c0792ed317..f54917dc47 100644 --- a/extra/structs/structs.factor +++ b/extra/structs/structs.factor @@ -10,4 +10,3 @@ C-STRUCT: timeval "timeval" [ set-timeval-usec ] keep [ set-timeval-sec ] keep ; - diff --git a/extra/unix/unix.factor b/extra/unix/unix.factor index 94bb598c25..d87e7f885d 100755 --- a/extra/unix/unix.factor +++ b/extra/unix/unix.factor @@ -41,6 +41,12 @@ C-STRUCT: timespec { "time_t" "sec" } { "long" "nsec" } ; +: make-timespec ( ms -- timespec ) + 1000 /mod 1000000 * + "timespec" + [ set-timespec-nsec ] keep + [ set-timespec-usec ] keep ; + ! ! ! Unix constants ! File type diff --git a/vm/io.c b/vm/io.c index bc7d057abf..d3a29abe72 100755 --- a/vm/io.c +++ b/vm/io.c @@ -13,8 +13,9 @@ normal operation. */ void init_c_io(void) { - userenv[IN_ENV] = allot_alien(F,(CELL)stdin); - userenv[OUT_ENV] = allot_alien(F,(CELL)stdout); + userenv[STDIN_ENV] = allot_alien(F,(CELL)stdin); + userenv[STDOUT_ENV] = allot_alien(F,(CELL)stdout); + userenv[STDERR_ENV] = allot_alien(F,(CELL)stderr); } void io_error(void) diff --git a/vm/run.h b/vm/run.h index 6f2caa0c14..976fa36337 100755 --- a/vm/run.h +++ b/vm/run.h @@ -16,8 +16,8 @@ typedef enum { OS_ENV, /* operating system name */ ARGS_ENV = 10, /* command line arguments */ - IN_ENV, /* stdin FILE* handle */ - OUT_ENV, /* stdout FILE* handle */ + STDIN_ENV, /* stdin FILE* handle */ + STDOUT_ENV, /* stdout FILE* handle */ IMAGE_ENV = 13, /* image path name */ EXECUTABLE_ENV, /* runtime executable path name */ @@ -51,6 +51,9 @@ typedef enum { STACK_TRACES_ENV = 36, UNDEFINED_ENV = 37, /* default quotation for undefined words */ + + STDERR_ENV = 38, /* stderr FILE* handle */ + STAGE2_ENV = 39 /* have we bootstrapped? */ } F_ENVTYPE; From d5257e47b14cb1bd77a8a748ca5ff53a2c7fd4a6 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 19:50:18 -0500 Subject: [PATCH 23/78] Fix circularity --- core/alien/syntax/syntax-docs.factor | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/alien/syntax/syntax-docs.factor b/core/alien/syntax/syntax-docs.factor index 858c3f145e..09169e63b4 100755 --- a/core/alien/syntax/syntax-docs.factor +++ b/core/alien/syntax/syntax-docs.factor @@ -1,5 +1,6 @@ -USING: alien alien.c-types alien.structs alien.syntax -alien.syntax.private help.markup help.syntax ; +IN: alien.syntax +USING: alien alien.c-types alien.structs alien.syntax.private +help.markup help.syntax ; HELP: DLL" { $syntax "DLL\" path\"" } From 670a28477286dc633771d1dbcbc6389a942765ad Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 19:50:35 -0500 Subject: [PATCH 24/78] Fix stderr --- core/io/streams/c/c-docs.factor | 15 ++++++++++----- core/io/streams/c/c.factor | 10 +++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/io/streams/c/c-docs.factor b/core/io/streams/c/c-docs.factor index af8136262a..de8a756f92 100644 --- a/core/io/streams/c/c-docs.factor +++ b/core/io/streams/c/c-docs.factor @@ -14,9 +14,10 @@ ARTICLE: "io.streams.c" "ANSI C streams" { $subsection fclose } { $subsection fgetc } { $subsection fread } -"Two standard file handles:" -{ $subsection stdin } -{ $subsection stdout } ; +"The three standard file handles:" +{ $subsection stdin-handle } +{ $subsection stdout-handle } +{ $subsection stderr-handle } ; ABOUT: "io.streams.c" @@ -64,10 +65,14 @@ HELP: fread ( n alien -- str/f ) { $description "Reads a sequence of characters from a C FILE* handle, and outputs " { $link f } " on end of file." } { $errors "Throws an error if the input operation failed." } ; -HELP: stdin +HELP: stdin-handle { $values { "in" "a C FILE* handle" } } { $description "Outputs the console standard input file handle." } ; -HELP: stdout +HELP: stdout-handle { $values { "out" "a C FILE* handle" } } { $description "Outputs the console standard output file handle." } ; + +HELP: stderr-handle +{ $values { "out" "a C FILE* handle" } } +{ $description "Outputs the console standard error file handle." } ; diff --git a/core/io/streams/c/c.factor b/core/io/streams/c/c.factor index 1dfb89f9c9..d816e08443 100755 --- a/core/io/streams/c/c.factor +++ b/core/io/streams/c/c.factor @@ -56,13 +56,13 @@ M: c-reader stream-close M: object init-io ; -: stdin 11 getenv ; -: stdout 12 getenv ; -: stderr 38 getenv ; +: stdin-handle 11 getenv ; +: stdout-handle 12 getenv ; +: stderr-handle 38 getenv ; M: object init-stdio - stdin stdout stdio set-global - stderr stderr set-global ; + stdin-handle stdout-handle stdio set-global + stderr-handle stderr set-global ; M: object io-multiplex (sleep) ; From 3f5342890e92f3b07ff713c1eea02f95e47fe19c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 19:50:48 -0500 Subject: [PATCH 25/78] Fix typo --- extra/unix/unix.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/unix/unix.factor b/extra/unix/unix.factor index d87e7f885d..16b279765f 100755 --- a/extra/unix/unix.factor +++ b/extra/unix/unix.factor @@ -45,7 +45,7 @@ C-STRUCT: timespec 1000 /mod 1000000 * "timespec" [ set-timespec-nsec ] keep - [ set-timespec-usec ] keep ; + [ set-timespec-sec ] keep ; ! ! ! Unix constants From f138c3675eb7794a198c63c8991d15c8afef7027 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 19:51:01 -0500 Subject: [PATCH 26/78] Fix typo --- core/kernel/kernel-docs.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/kernel/kernel-docs.factor b/core/kernel/kernel-docs.factor index 2301216394..f832742034 100755 --- a/core/kernel/kernel-docs.factor +++ b/core/kernel/kernel-docs.factor @@ -49,7 +49,7 @@ ARTICLE: "basic-combinators" "Basic combinators" { $subsection execute } "These words are used to implement " { $emphasis "combinators" } ", which are words that take code from the stack. Note that combinator definitions must be followed by the " { $link POSTPONE: inline } " declaration in order to compile in the optimizing compiler; for example:" { $code - ": keep ( x quot -- x | quot: x -- )" + ": keep ( x quot -- x )" " over >r call r> ; inline" } "Word inlining is documented in " { $link "declarations" } "." From 8339cb0b4a01447d095797458a464ad3dee2c248 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 20:28:43 -0500 Subject: [PATCH 27/78] Fix for word renaming --- extra/tools/deploy/shaker/shaker.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/tools/deploy/shaker/shaker.factor b/extra/tools/deploy/shaker/shaker.factor index d157571757..fd6c79e5ba 100755 --- a/extra/tools/deploy/shaker/shaker.factor +++ b/extra/tools/deploy/shaker/shaker.factor @@ -11,7 +11,7 @@ IN: tools.deploy.shaker : show ( msg -- ) #! Use primitives directly so that we can print stuff even #! after most of the image has been stripped away - "\r\n" append stdout fwrite stdout fflush ; + "\r\n" append stdout-handle fwrite stdout-handle fflush ; : strip-init-hooks ( -- ) "Stripping startup hooks" show From 74329237e6d49522ba0c169ca04039e041d02fff Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 18 Jan 2008 20:29:43 -0500 Subject: [PATCH 28/78] kqueue work in progress --- extra/io/unix/backend/kqueue/kqueue.factor | 67 +++++++++++++++------- extra/io/unix/unix.factor | 5 +- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/extra/io/unix/backend/kqueue/kqueue.factor b/extra/io/unix/backend/kqueue/kqueue.factor index 35f2641e00..287b88c1c3 100644 --- a/extra/io/unix/backend/kqueue/kqueue.factor +++ b/extra/io/unix/backend/kqueue/kqueue.factor @@ -1,14 +1,16 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien.syntax kernel io.nonblocking io.unix.backend -sequences assocs unix unix.kqueue math namespaces ; +USING: alien.c-types kernel io.nonblocking io.unix.backend +io.unix.sockets sequences assocs unix unix.kqueue math +namespaces classes combinators ; IN: io.unix.backend.kqueue TUPLE: unix-kqueue-io ; ! Global variables SYMBOL: kqueue-fd -SYMBOL: kqueue-changes +SYMBOL: kqueue-added +SYMBOL: kqueue-deleted SYMBOL: kqueue-events : max-events ( -- n ) @@ -17,26 +19,43 @@ SYMBOL: kqueue-events 256 ; inline M: unix-kqueue-io init-unix-io ( -- ) - V{ } clone kqueue-changes set-global + H{ } clone kqueue-added set-global + H{ } clone kqueue-deleted set-global max-events "kevent" kqueue-events set-global - kqueue kqueue-fd dup io-error set-global ; + kqueue dup io-error kqueue-fd set-global ; -: add-change ( event -- ) kqueue-changes get-global push ; +M: unix-kqueue-io register-io-task ( task -- ) + dup io-task-fd kqueue-added get-global key? [ drop ] [ + dup io-task-fd kqueue-deleted get-global key? [ + io-task-fd kqueue-deleted get-global delete-at + ] [ + dup io-task-fd kqueue-added get-global set-at + ] if + ] if ; + +M: unix-kqueue-io unregister-io-task ( task -- ) + dup io-task-fd kqueue-deleted get-global key? [ drop ] [ + dup io-task-fd kqueue-added get-global key? [ + io-task-fd kqueue-added get-global delete-at + ] [ + dup io-task-fd kqueue-deleted get-global set-at + ] if + ] if ; : io-task-filter ( task -- n ) class { - { read-task EVFILT_READ } - { accept-task EVFILT_READ } - { receive-task EVFILT_READ } - { write-task EVFILT_WRITE } - { connect-task EVFILT_WRITE } - { send-task EVFILT_WRITE } + { read-task [ EVFILT_READ ] } + { accept-task [ EVFILT_READ ] } + { receive-task [ EVFILT_READ ] } + { write-task [ EVFILT_WRITE ] } + { connect-task [ EVFILT_WRITE ] } + { send-task [ EVFILT_WRITE ] } } case ; : make-kevent ( task -- event ) "kevent" over io-task-fd over set-kevent-ident - over io-task-filter over set-kevent-filter ; + swap io-task-filter over set-kevent-filter ; : make-add-kevent ( task -- event ) make-kevent @@ -46,15 +65,19 @@ M: unix-kqueue-io init-unix-io ( -- ) make-kevent EV_DELETE over set-kevent-flags ; -M: unix-select-io register-io-task ( task -- ) - make-add-kevent add-change ; +: kqueue-additions ( -- kevents ) + kqueue-added get-global + dup clear-assoc values + [ make-add-kevent ] map ; -M: unix-select-io unregister-io-task ( task -- ) - make-delete-kevent add-change ; +: kqueue-deletions ( -- kevents ) + kqueue-deleted get-global + dup clear-assoc values + [ make-delete-kevent ] map ; : kqueue-changelist ( -- byte-array n ) - kqueue-changes get-global - dup concat f like over length rot delete-all ; + kqueue-additions kqueue-deletions append + dup concat f like swap length ; : kqueue-eventlist ( -- byte-array n ) kqueue-events get-global max-events ; @@ -67,15 +90,15 @@ M: unix-select-io unregister-io-task ( task -- ) r> kevent dup multiplexer-error ; : kevent-task ( kevent -- task ) - dup kevent-filter { + dup kevent-ident swap kevent-filter { { [ dup EVFILT_READ = ] [ read-tasks ] } { [ dup EVFILT_WRITE = ] [ write-tasks ] } - } cond get at ; + } cond nip get at ; : handle-kevents ( n eventlist -- ) [ kevent-nth kevent-task handle-fd ] curry each ; -M: unix-select-io unix-io-multiplex ( ms -- ) +M: unix-kqueue-io unix-io-multiplex ( ms -- ) make-timespec do-kevent kqueue-events get-global handle-kevents ; diff --git a/extra/io/unix/unix.factor b/extra/io/unix/unix.factor index 1c86224433..3800008864 100755 --- a/extra/io/unix/unix.factor +++ b/extra/io/unix/unix.factor @@ -3,8 +3,9 @@ io.unix.launcher io.unix.mmap io.backend combinators namespaces system vocabs.loader ; { - { [ macosx? ] [ "io.unix.backend.kqueue" ] } - { [ bsd? ] [ "io.unix.backend.kqueue" ] } + ! kqueue is a work in progress + ! { [ macosx? ] [ "io.unix.backend.kqueue" ] } + ! { [ bsd? ] [ "io.unix.backend.kqueue" ] } { [ unix? ] [ "io.unix.backend.select" ] } } cond require From 827faa205c661af763dd916385330475a2dac8b0 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Fri, 18 Jan 2008 20:07:41 -0500 Subject: [PATCH 29/78] Alternate solution to Project Euler problem 2 --- extra/project-euler/002/002.factor | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/extra/project-euler/002/002.factor b/extra/project-euler/002/002.factor index 55c1b153cc..b0b21e76e1 100644 --- a/extra/project-euler/002/002.factor +++ b/extra/project-euler/002/002.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math sequences ; +USING: kernel math sequences shuffle ; IN: project-euler.002 ! http://projecteuler.net/index.php?section=problems&id=2 @@ -35,4 +35,18 @@ PRIVATE> ! [ euler002 ] 100 ave-time ! 0 ms run / 0 ms GC ave time - 100 trials -MAIN: euler002 + +! ALTERNATE SOLUTIONS +! ------------------- + +: fib-upto* ( n -- seq ) + 0 1 [ pick over >= ] [ tuck + dup ] [ ] unfold 3nip + 1 head-slice* { 0 1 } swap append ; + +: euler002a ( -- answer ) + 1000000 fib-upto* [ even? ] subset sum ; + +! [ euler002a ] 100 ave-time +! 0 ms run / 0 ms GC ave time - 100 trials + +MAIN: euler002a From 44e9d1fdd098023b6043b0f86c57598c0d00b70e Mon Sep 17 00:00:00 2001 From: Eduardo Cavazos Date: Sat, 19 Jan 2008 05:26:59 -0600 Subject: [PATCH 30/78] Typo in Unit testing docs --- extra/tools/test/test-docs.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/tools/test/test-docs.factor b/extra/tools/test/test-docs.factor index 48a1192282..32825c965d 100644 --- a/extra/tools/test/test-docs.factor +++ b/extra/tools/test/test-docs.factor @@ -6,7 +6,7 @@ ARTICLE: "tools.test" "Unit testing" $nl "For example, if you were developing a word for computing symbolic derivatives, your unit tests would apply the word to certain input functions, comparing the results against the correct values. While the passing of these tests would not guarantee the algorithm is correct, it would at least ensure that what used to work keeps working, in that as soon as something breaks due to a change in another part of your program, failing tests will let you know." $nl -"Unit tests for a vocabulary are placed in test files, named " { $snippet { $emphasis "vocab" } " -tests.factor" } " alongside " { $snippet { $emphasis "vocab" } ".factor" } "; see " { $link "vocabs.loader" } " for details." +"Unit tests for a vocabulary are placed in test files, named " { $snippet { $emphasis "vocab" } "-tests.factor" } " alongside " { $snippet { $emphasis "vocab" } ".factor" } "; see " { $link "vocabs.loader" } " for details." $nl "If the test harness needs to define words, they should be placed in the " { $snippet "temporary" } " vocabulary so that they can be forgotten after the tests have been run. Test harness files consist mostly of calls to the following two words:" { $subsection unit-test } From 5585815935f7599fc956d6d610f685aee8716fda Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 19 Jan 2008 14:18:30 +0100 Subject: [PATCH 31/78] Add missing structs dependency needed for Unix bootstraping --- extra/io/unix/backend/select/select.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/io/unix/backend/select/select.factor b/extra/io/unix/backend/select/select.factor index b132c8b9e8..3c808a278f 100644 --- a/extra/io/unix/backend/select/select.factor +++ b/extra/io/unix/backend/select/select.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien.syntax kernel io.nonblocking io.unix.backend -bit-arrays sequences assocs unix math namespaces ; +bit-arrays sequences assocs unix math namespaces structs ; IN: io.unix.backend.select TUPLE: unix-select-io ; From e29d665a10b9aab987bb60d0b36ae768c29837d7 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sat, 19 Jan 2008 10:18:35 -1000 Subject: [PATCH 32/78] fix up misc/factor.sh add bootstrap option fix usage() --- misc/factor.sh | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/misc/factor.sh b/misc/factor.sh index b2cbb836e6..8dca786846 100755 --- a/misc/factor.sh +++ b/misc/factor.sh @@ -237,19 +237,19 @@ maybe_download_dlls() { fi } +get_config_info() { + check_installed_programs + find_build_info + check_libraries +} + bootstrap() { ./$FACTOR_BINARY -i=$BOOT_IMAGE } -usage() { - echo "usage: $0 install|install-x11|update|quick-update" -} - install() { check_factor_exists - check_installed_programs - find_build_info - check_libraries + get_config_info git_clone cd_factor make_factor @@ -259,9 +259,7 @@ install() { } update() { - check_installed_programs - find_build_info - check_libraries + get_config_info git_pull_factorcode make_clean make_factor @@ -288,11 +286,16 @@ install_libraries() { sudo apt-get install libc6-dev libfreetype6-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap } +usage() { + echo "usage: $0 install|install-x11|self-update|quick-update|update|bootstrap" +} + case "$1" in install) install ;; install-x11) install_libraries; install ;; self-update) update; make_boot_image; bootstrap;; quick-update) update; refresh_image ;; update) update; update_bootstrap ;; + bootstrap) get_config_info; bootstrap ;; *) usage ;; esac From 80fcbf2514a18bcead63601948c428bd4964a6f0 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sat, 19 Jan 2008 10:18:52 -1000 Subject: [PATCH 33/78] add missing use --- extra/io/unix/backend/select/select.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/io/unix/backend/select/select.factor b/extra/io/unix/backend/select/select.factor index b132c8b9e8..3c808a278f 100644 --- a/extra/io/unix/backend/select/select.factor +++ b/extra/io/unix/backend/select/select.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien.syntax kernel io.nonblocking io.unix.backend -bit-arrays sequences assocs unix math namespaces ; +bit-arrays sequences assocs unix math namespaces structs ; IN: io.unix.backend.select TUPLE: unix-select-io ; From 3355b075bbd3b5c3f68162e92835bcdffc70686b Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Sat, 19 Jan 2008 15:19:21 -0500 Subject: [PATCH 34/78] Add attribution for alternate solution on PE problem 2 --- extra/project-euler/002/002.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/project-euler/002/002.factor b/extra/project-euler/002/002.factor index b0b21e76e1..0b8f773887 100644 --- a/extra/project-euler/002/002.factor +++ b/extra/project-euler/002/002.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2007 Aaron Schaefer, Alexander Solovyov. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math sequences shuffle ; IN: project-euler.002 From 654574181b0c3e5fd481192cc7c10fdfd44018c4 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 20 Jan 2008 09:52:50 -0700 Subject: [PATCH 35/78] fix up some old code --- extra/hexdump/hexdump.factor | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/extra/hexdump/hexdump.factor b/extra/hexdump/hexdump.factor index 57bbbe2481..6a91cd65c5 100644 --- a/extra/hexdump/hexdump.factor +++ b/extra/hexdump/hexdump.factor @@ -1,4 +1,6 @@ -USING: arrays io io.streams.string kernel math math.parser namespaces prettyprint sequences splitting strings ; +USING: arrays combinators.lib io io.streams.string +kernel math math.parser namespaces prettyprint +sequences splitting strings ; IN: hexdump hex write "h" write nl ; -: offset. ( lineno -- ) 16 * >hex 8 CHAR: 0 pad-left write "h: " write ; -: h-pad. ( digit -- ) >hex 2 CHAR: 0 pad-left write ; +: offset. ( lineno -- ) + 16 * >hex 8 CHAR: 0 pad-left write "h: " write ; + +: h-pad. ( digit -- ) + >hex 2 CHAR: 0 pad-left write ; + : line. ( str n -- ) offset. dup [ h-pad. " " write ] each - 16 over length - " " concat write + 16 over length - 3 * CHAR: \s write [ dup printable? [ drop CHAR: . ] unless write1 ] each nl ; @@ -19,9 +25,8 @@ PRIVATE> : hexdump ( seq -- str ) [ dup length header. - 16 dup length [ line. ] 2each + 16 [ line. ] each-index ] string-out ; : hexdump. ( seq -- ) hexdump write ; - From 1302a8055d27f3cf14c1d021166811dbe43003ed Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 20 Jan 2008 13:13:04 -0500 Subject: [PATCH 36/78] More kqueue work --- extra/io/unix/backend/kqueue/kqueue.factor | 52 +++++----------------- extra/io/unix/unix.factor | 5 +-- 2 files changed, 13 insertions(+), 44 deletions(-) diff --git a/extra/io/unix/backend/kqueue/kqueue.factor b/extra/io/unix/backend/kqueue/kqueue.factor index 287b88c1c3..226e6c2ec7 100644 --- a/extra/io/unix/backend/kqueue/kqueue.factor +++ b/extra/io/unix/backend/kqueue/kqueue.factor @@ -9,8 +9,6 @@ TUPLE: unix-kqueue-io ; ! Global variables SYMBOL: kqueue-fd -SYMBOL: kqueue-added -SYMBOL: kqueue-deleted SYMBOL: kqueue-events : max-events ( -- n ) @@ -19,29 +17,9 @@ SYMBOL: kqueue-events 256 ; inline M: unix-kqueue-io init-unix-io ( -- ) - H{ } clone kqueue-added set-global - H{ } clone kqueue-deleted set-global max-events "kevent" kqueue-events set-global kqueue dup io-error kqueue-fd set-global ; -M: unix-kqueue-io register-io-task ( task -- ) - dup io-task-fd kqueue-added get-global key? [ drop ] [ - dup io-task-fd kqueue-deleted get-global key? [ - io-task-fd kqueue-deleted get-global delete-at - ] [ - dup io-task-fd kqueue-added get-global set-at - ] if - ] if ; - -M: unix-kqueue-io unregister-io-task ( task -- ) - dup io-task-fd kqueue-deleted get-global key? [ drop ] [ - dup io-task-fd kqueue-added get-global key? [ - io-task-fd kqueue-added get-global delete-at - ] [ - dup io-task-fd kqueue-deleted get-global set-at - ] if - ] if ; - : io-task-filter ( task -- n ) class { { read-task [ EVFILT_READ ] } @@ -57,6 +35,10 @@ M: unix-kqueue-io unregister-io-task ( task -- ) over io-task-fd over set-kevent-ident swap io-task-filter over set-kevent-filter ; +: register-kevent ( task flags -- ) + >r make-kevent r> over set-kevent-flags + kqueue-fd get-global swap 1 f 0 f kevent io-error ; + : make-add-kevent ( task -- event ) make-kevent EV_ADD over set-kevent-flags ; @@ -65,28 +47,16 @@ M: unix-kqueue-io unregister-io-task ( task -- ) make-kevent EV_DELETE over set-kevent-flags ; -: kqueue-additions ( -- kevents ) - kqueue-added get-global - dup clear-assoc values - [ make-add-kevent ] map ; +M: unix-kqueue-io register-io-task ( task -- ) + EV_ADD EV_ENABLE bitor register-kevent ; -: kqueue-deletions ( -- kevents ) - kqueue-deleted get-global - dup clear-assoc values - [ make-delete-kevent ] map ; +M: unix-kqueue-io unregister-io-task ( task -- ) + EV_DELETE EV_DISABLE bitor register-kevent ; -: kqueue-changelist ( -- byte-array n ) - kqueue-additions kqueue-deletions append - dup concat f like swap length ; - -: kqueue-eventlist ( -- byte-array n ) - kqueue-events get-global max-events ; - -: do-kevent ( timespec -- n ) +: wait-kevent ( timespec -- n ) >r kqueue-fd get-global - kqueue-changelist - kqueue-eventlist + f 0 kqueue-events get-global max-events r> kevent dup multiplexer-error ; : kevent-task ( kevent -- task ) @@ -100,7 +70,7 @@ M: unix-kqueue-io unregister-io-task ( task -- ) M: unix-kqueue-io unix-io-multiplex ( ms -- ) make-timespec - do-kevent + wait-kevent kqueue-events get-global handle-kevents ; T{ unix-kqueue-io } unix-io-backend set-global diff --git a/extra/io/unix/unix.factor b/extra/io/unix/unix.factor index 3800008864..1c86224433 100755 --- a/extra/io/unix/unix.factor +++ b/extra/io/unix/unix.factor @@ -3,9 +3,8 @@ io.unix.launcher io.unix.mmap io.backend combinators namespaces system vocabs.loader ; { - ! kqueue is a work in progress - ! { [ macosx? ] [ "io.unix.backend.kqueue" ] } - ! { [ bsd? ] [ "io.unix.backend.kqueue" ] } + { [ macosx? ] [ "io.unix.backend.kqueue" ] } + { [ bsd? ] [ "io.unix.backend.kqueue" ] } { [ unix? ] [ "io.unix.backend.select" ] } } cond require From 7db1b072f8972d7e88c4174401bfb9256488958f Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 20 Jan 2008 17:06:38 -0500 Subject: [PATCH 37/78] epoll() binding --- extra/unix/linux/epoll/epoll.factor | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 extra/unix/linux/epoll/epoll.factor diff --git a/extra/unix/linux/epoll/epoll.factor b/extra/unix/linux/epoll/epoll.factor new file mode 100644 index 0000000000..946c387acc --- /dev/null +++ b/extra/unix/linux/epoll/epoll.factor @@ -0,0 +1,30 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +IN: unix.linux.epoll +USING: alien.syntax ; + +FUNCTION: int epoll_create ( int size ) ; + +FUNCTION: int epoll_ctl ( int epfd, int op, int fd, epoll_event* event ) ; + +C-STRUCT: epoll-event + { "uint" "events" } + { "uint" "fd" } ; + +FUNCTION: int epoll_wait ( int epfd, epoll_event* events, int maxevents, int timeout ) ; + +: EPOLL_CTL_ADD 1 ; inline ! Add a file decriptor to the interface. +: EPOLL_CTL_DEL 2 ; inline ! Remove a file decriptor from the interface. +: EPOLL_CTL_MOD 3 ; inline ! Change file decriptor epoll_event structure. + +: EPOLLIN HEX: 001 ; inline +: EPOLLPRI HEX: 002 ; inline +: EPOLLOUT HEX: 004 ; inline +: EPOLLRDNORM HEX: 040 ; inline +: EPOLLRDBAND HEX: 080 ; inline +: EPOLLWRNORM HEX: 100 ; inline +: EPOLLWRBAND HEX: 200 ; inline +: EPOLLMSG HEX: 400 ; inline +: EPOLLERR HEX: 008 ; inline +: EPOLLHUP HEX: 010 ; inline +: EPOLLET 31 2^ ; inline From eb5644ad5f05093fe69c2586ec36232d7b6329f6 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 20 Jan 2008 17:07:18 -0500 Subject: [PATCH 38/78] Unix I/O re-working; nested multiplexer support, use kqueue on *bsd to wait for process completion, start Linux epoll support --- extra/io/unix/backend/backend.factor | 118 +++++++++++---------- extra/io/unix/backend/kqueue/kqueue.factor | 76 ------------- extra/io/unix/backend/select/select.factor | 52 --------- extra/io/unix/bsd/bsd.factor | 29 +++++ extra/io/unix/epoll/epoll.factor | 61 +++++++++++ extra/io/unix/kqueue/kqueue.factor | 90 ++++++++++++++++ extra/io/unix/launcher/launcher.factor | 37 ++++--- extra/io/unix/linux/linux.factor | 17 +++ extra/io/unix/select/select.factor | 47 ++++++++ extra/io/unix/sockets/sockets.factor | 8 +- extra/io/unix/unix.factor | 9 +- extra/unix/process/process.factor | 62 +++++------ 12 files changed, 367 insertions(+), 239 deletions(-) delete mode 100644 extra/io/unix/backend/kqueue/kqueue.factor delete mode 100644 extra/io/unix/backend/select/select.factor create mode 100644 extra/io/unix/bsd/bsd.factor create mode 100644 extra/io/unix/epoll/epoll.factor create mode 100644 extra/io/unix/kqueue/kqueue.factor create mode 100644 extra/io/unix/linux/linux.factor create mode 100644 extra/io/unix/select/select.factor diff --git a/extra/io/unix/backend/backend.factor b/extra/io/unix/backend/backend.factor index f29d71dd86..19856dc6be 100755 --- a/extra/io/unix/backend/backend.factor +++ b/extra/io/unix/backend/backend.factor @@ -7,19 +7,46 @@ continuations system libc qualified namespaces ; QUALIFIED: io IN: io.unix.backend -! Multiplexer protocol -SYMBOL: unix-io-backend +MIXIN: unix-io -HOOK: init-unix-io unix-io-backend ( -- ) -HOOK: register-io-task unix-io-backend ( task -- ) -HOOK: unregister-io-task unix-io-backend ( task -- ) -HOOK: unix-io-multiplex unix-io-backend ( timeval -- ) +! I/O tasks +TUPLE: io-task port callbacks ; -TUPLE: unix-io ; +: io-task-fd io-task-port port-handle ; -! Global variables -SYMBOL: read-tasks -SYMBOL: write-tasks +: ( port continuation class -- task ) + >r 1vector io-task construct-boa r> construct-delegate ; + inline + +GENERIC: do-io-task ( task -- ? ) +GENERIC: io-task-container ( mx task -- hashtable ) + +! I/O multiplexers +TUPLE: mx fd reads writes ; + +: ( -- mx ) f H{ } clone H{ } clone mx construct-boa ; + +: construct-mx ( class -- obj ) swap construct-delegate ; + +GENERIC: register-io-task ( task mx -- ) +GENERIC: unregister-io-task ( task mx -- ) +GENERIC: unix-io-multiplex ( ms mx -- ) + +: fd/container ( task mx -- task fd container ) + over io-task-container >r dup io-task-fd r> ; inline + +: check-io-task ( task mx -- ) + fd/container key? nip [ + "Cannot perform multiple reads from the same port" throw + ] when ; + +M: mx register-io-task ( task mx -- ) + 2dup check-io-task fd/container set-at ; + +: add-io-task ( task -- ) mx get-global register-io-task ; + +M: mx unregister-io-task ( task mx -- ) + fd/container delete-at drop ; ! Some general stuff : file-mode OCT: 0666 ; @@ -52,43 +79,15 @@ M: integer close-handle ( fd -- ) err_no dup ignorable-error? [ 2drop f ] [ strerror swap report-error t ] if ; -! Associates a port with a list of continuations waiting on the -! port to finish I/O -TUPLE: io-task port callbacks ; - -: ( port continuation class -- task ) - >r 1vector io-task construct-boa r> construct-delegate ; - inline - -! Multiplexer -GENERIC: do-io-task ( task -- ? ) -GENERIC: task-container ( task -- vector ) - -: io-task-fd io-task-port port-handle ; - -: check-io-task ( task -- ) - dup io-task-fd swap task-container at [ - "Cannot perform multiple reads from the same port" throw - ] when ; - -: add-io-task ( task -- ) - dup check-io-task - dup register-io-task - dup io-task-fd over task-container set-at ; - -: remove-io-task ( task -- ) - dup io-task-fd over task-container delete-at - unregister-io-task ; - -: pop-callbacks ( task -- ) - dup remove-io-task +: pop-callbacks ( mx task -- ) + dup rot unregister-io-task io-task-callbacks [ schedule-thread ] each ; -: handle-fd ( task -- ) +: handle-io-task ( mx task -- ) dup io-task-port touch-port - dup do-io-task [ pop-callbacks ] [ drop ] if ; + dup do-io-task [ pop-callbacks ] [ 2drop ] if ; -: handle-timeout ( task -- ) +: handle-timeout ( mx task -- ) "Timeout" over io-task-port report-error pop-callbacks ; ! Readers @@ -119,8 +118,7 @@ M: read-task do-io-task io-task-port dup refill [ [ reader-eof ] [ drop ] if ] keep ; -M: read-task task-container - drop read-tasks get-global ; +M: read-task io-task-container drop mx-reads ; M: input-port (wait-to-read) [ add-io-task stop ] callcc0 pending-error ; @@ -139,13 +137,12 @@ M: write-task do-io-task io-task-port dup buffer-empty? over port-error or [ 0 swap buffer-reset t ] [ write-step ] if ; -M: write-task task-container - drop write-tasks get-global ; +M: write-task io-task-container drop mx-writes ; : add-write-io-task ( port continuation -- ) - over port-handle write-tasks get-global at + over port-handle mx get-global mx-writes at* [ io-task-callbacks push drop ] - [ add-io-task ] if* ; + [ drop add-io-task ] if ; : (wait-to-write) ( port -- ) [ add-write-io-task stop ] callcc0 drop ; @@ -154,16 +151,27 @@ M: port port-flush ( port -- ) dup buffer-empty? [ drop ] [ (wait-to-write) ] if ; M: unix-io io-multiplex ( ms -- ) - unix-io-multiplex ; - -M: unix-io init-io ( -- ) - H{ } clone read-tasks set-global - H{ } clone write-tasks set-global - init-unix-io ; + mx get-global unix-io-multiplex ; M: unix-io init-stdio ( -- ) 0 1 handle>duplex-stream io:stdio set-global 2 io:stderr set-global ; +! mx io-task for embedding an fd-based mx inside another mx +TUPLE: mx-port mx ; + +: ( mx -- port ) + dup mx-fd f + mx-port over set-port-type + { set-mx-port-mx set-delegate } mx-port construct ; + +TUPLE: mx-task ; + +: ( port -- task ) + f io-task construct-boa mx-task construct-delegate ; + +M: mx-task do-io-task + io-task-port mx-port-mx 0 swap unix-io-multiplex f ; + : multiplexer-error ( n -- ) 0 < [ err_no ignorable-error? [ (io-error) ] unless ] when ; diff --git a/extra/io/unix/backend/kqueue/kqueue.factor b/extra/io/unix/backend/kqueue/kqueue.factor deleted file mode 100644 index 226e6c2ec7..0000000000 --- a/extra/io/unix/backend/kqueue/kqueue.factor +++ /dev/null @@ -1,76 +0,0 @@ -! Copyright (C) 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: alien.c-types kernel io.nonblocking io.unix.backend -io.unix.sockets sequences assocs unix unix.kqueue math -namespaces classes combinators ; -IN: io.unix.backend.kqueue - -TUPLE: unix-kqueue-io ; - -! Global variables -SYMBOL: kqueue-fd -SYMBOL: kqueue-events - -: max-events ( -- n ) - #! We read up to 256 events at a time. This is an arbitrary - #! constant... - 256 ; inline - -M: unix-kqueue-io init-unix-io ( -- ) - max-events "kevent" kqueue-events set-global - kqueue dup io-error kqueue-fd set-global ; - -: io-task-filter ( task -- n ) - class { - { read-task [ EVFILT_READ ] } - { accept-task [ EVFILT_READ ] } - { receive-task [ EVFILT_READ ] } - { write-task [ EVFILT_WRITE ] } - { connect-task [ EVFILT_WRITE ] } - { send-task [ EVFILT_WRITE ] } - } case ; - -: make-kevent ( task -- event ) - "kevent" - over io-task-fd over set-kevent-ident - swap io-task-filter over set-kevent-filter ; - -: register-kevent ( task flags -- ) - >r make-kevent r> over set-kevent-flags - kqueue-fd get-global swap 1 f 0 f kevent io-error ; - -: make-add-kevent ( task -- event ) - make-kevent - EV_ADD over set-kevent-flags ; - -: make-delete-kevent ( task -- event ) - make-kevent - EV_DELETE over set-kevent-flags ; - -M: unix-kqueue-io register-io-task ( task -- ) - EV_ADD EV_ENABLE bitor register-kevent ; - -M: unix-kqueue-io unregister-io-task ( task -- ) - EV_DELETE EV_DISABLE bitor register-kevent ; - -: wait-kevent ( timespec -- n ) - >r - kqueue-fd get-global - f 0 kqueue-events get-global max-events - r> kevent dup multiplexer-error ; - -: kevent-task ( kevent -- task ) - dup kevent-ident swap kevent-filter { - { [ dup EVFILT_READ = ] [ read-tasks ] } - { [ dup EVFILT_WRITE = ] [ write-tasks ] } - } cond nip get at ; - -: handle-kevents ( n eventlist -- ) - [ kevent-nth kevent-task handle-fd ] curry each ; - -M: unix-kqueue-io unix-io-multiplex ( ms -- ) - make-timespec - wait-kevent - kqueue-events get-global handle-kevents ; - -T{ unix-kqueue-io } unix-io-backend set-global diff --git a/extra/io/unix/backend/select/select.factor b/extra/io/unix/backend/select/select.factor deleted file mode 100644 index 3c808a278f..0000000000 --- a/extra/io/unix/backend/select/select.factor +++ /dev/null @@ -1,52 +0,0 @@ -! Copyright (C) 2004, 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: alien.syntax kernel io.nonblocking io.unix.backend -bit-arrays sequences assocs unix math namespaces structs ; -IN: io.unix.backend.select - -TUPLE: unix-select-io ; - -! Global variables -SYMBOL: read-fdset -SYMBOL: write-fdset - -M: unix-select-io init-unix-io ( -- ) - FD_SETSIZE 8 * read-fdset set-global - FD_SETSIZE 8 * write-fdset set-global ; - -: handle-fdset ( fdset tasks -- ) - swap [ - swap dup io-task-port timeout? [ - nip handle-timeout - ] [ - tuck io-task-fd swap nth - [ handle-fd ] [ drop ] if - ] if drop - ] curry assoc-each ; - -: init-fdset ( fdset tasks -- ) - swap dup clear-bits - [ >r drop t swap r> set-nth ] curry assoc-each ; - -: read-fdset/tasks - read-fdset get-global read-tasks get-global ; - -: write-fdset/tasks - write-fdset get-global write-tasks get-global ; - -: init-fdsets ( -- read write except ) - read-fdset/tasks dupd init-fdset - write-fdset/tasks dupd init-fdset - f ; - -M: unix-select-io register-io-task ( task -- ) drop ; - -M: unix-select-io unregister-io-task ( task -- ) drop ; - -M: unix-select-io unix-io-multiplex ( timeval -- ) - make-timeval >r FD_SETSIZE init-fdsets r> - select multiplexer-error - read-fdset/tasks handle-fdset - write-fdset/tasks handle-fdset ; - -T{ unix-select-io } unix-io-backend set-global diff --git a/extra/io/unix/bsd/bsd.factor b/extra/io/unix/bsd/bsd.factor new file mode 100644 index 0000000000..8ed84dc305 --- /dev/null +++ b/extra/io/unix/bsd/bsd.factor @@ -0,0 +1,29 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +IN: io.unix.bsd +USING: io.backend io.unix.backend io.unix.kqueue io.unix.select +io.unix.launcher namespaces kernel assocs threads continuations +; + +! On *BSD and Mac OS X, we use select() for the top-level +! multiplexer, and we hang a kqueue off of it but file change +! notification and process exit notification. + +! kqueue is buggy with files and ptys so we can't use it as the +! main multiplexer. + +TUPLE: bsd-io ; + +INSTANCE: bsd-io unix-io + +M: bsd-io init-io ( -- ) + mx set-global + kqueue-mx set-global + kqueue-mx get-global dup io-task-fd + 2dup mx get-global mx-reads set-at + mx get-global mx-writes set-at ; + +M: bsd-io wait-for-process ( pid -- status ) + [ kqueue-mx get-global add-pid-task stop ] curry callcc1 ; + +T{ bsd-io } io-backend set-global diff --git a/extra/io/unix/epoll/epoll.factor b/extra/io/unix/epoll/epoll.factor new file mode 100644 index 0000000000..e39c35aca3 --- /dev/null +++ b/extra/io/unix/epoll/epoll.factor @@ -0,0 +1,61 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.c-types kernel io.nonblocking io.unix.backend +bit-arrays sequences assocs unix math namespaces structs ; +IN: io.unix.epoll + +TUPLE: epoll-mx events ; + +: max-events ( -- n ) + #! We read up to 256 events at a time. This is an arbitrary + #! constant... + 256 ; inline + +: ( -- mx ) + epoll-mx construct-mx + max-events epoll_create dup io-error over set-mx-fd + max-events "epoll-event" over set-epoll-mx-events ; + +: io-task-filter ( task -- n ) + class { + { read-task [ EVFILT_READ ] } + { accept-task [ EVFILT_READ ] } + { receive-task [ EVFILT_READ ] } + { write-task [ EVFILT_WRITE ] } + { connect-task [ EVFILT_WRITE ] } + { send-task [ EVFILT_WRITE ] } + } case ; + +: make-event ( task -- event ) + "epoll-event" + tuck set-epoll-event-events + over io-task-fd over set-epoll-fd ; + +: do-epoll-ctl ( task mx what -- ) + >r >r make-event r> mx-fd r> pick event-data *int roll + epoll_ctl io-error ; + +M: epoll-mx register-io-task ( task mx -- ) + EPOLL_CTL_ADD do-epoll-ctl ; + +M: epoll-mx unregister-io-task ( task mx -- ) + EPOLL_CTL_DEL do-epoll-ctl ; + +: wait-kevent ( mx timeout -- n ) + >r mx-fd epoll-mx-events max-events r> epoll_wait + dup multiplexer-error ; + +: epoll-read-task ( mx fd -- ) + over mx-reads at* [ handle-io-task ] [ 2drop ] if ; + +: epoll-write-task ( mx fd -- ) + over mx-reads at* [ handle-io-task ] [ 2drop ] if ; + +: handle-event ( mx kevent -- ) + epoll-event-fd 2dup epoll-read-task epoll-write-task ; + +: handle-events ( mx n -- ) + [ over epoll-mx-events kevent-nth handle-kevent ] with each ; + +M: epoll-mx unix-io-multiplex ( ms mx -- ) + dup rot wait-kevent handle-kevents ; diff --git a/extra/io/unix/kqueue/kqueue.factor b/extra/io/unix/kqueue/kqueue.factor new file mode 100644 index 0000000000..e1ce7666f1 --- /dev/null +++ b/extra/io/unix/kqueue/kqueue.factor @@ -0,0 +1,90 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.c-types kernel io.nonblocking io.unix.backend +io.unix.sockets sequences assocs unix unix.kqueue unix.process +math namespaces classes combinators threads vectors ; +IN: io.unix.kqueue + +TUPLE: kqueue-mx events processes ; + +: max-events ( -- n ) + #! We read up to 256 events at a time. This is an arbitrary + #! constant... + 256 ; inline + +: ( -- mx ) + kqueue-mx construct-mx + kqueue dup io-error over set-mx-fd + H{ } clone over set-kqueue-mx-processes + max-events "kevent" over set-kqueue-mx-events ; + +: io-task-filter ( task -- n ) + class { + { read-task [ EVFILT_READ ] } + { accept-task [ EVFILT_READ ] } + { receive-task [ EVFILT_READ ] } + { write-task [ EVFILT_WRITE ] } + { connect-task [ EVFILT_WRITE ] } + { send-task [ EVFILT_WRITE ] } + } case ; + +: make-kevent ( task flags -- event ) + "kevent" + tuck set-kevent-flags + over io-task-fd over set-kevent-ident + swap io-task-filter over set-kevent-filter ; + +: register-kevent ( kevent mx -- ) + mx-fd swap 1 f 0 f kevent io-error ; + +M: kqueue-mx register-io-task ( task mx -- ) + over EV_ADD make-kevent over register-kevent + delegate register-io-task ; + +M: kqueue-mx unregister-io-task ( task mx -- ) + 2dup delegate unregister-io-task + swap EV_DELETE make-kevent swap register-kevent ; + +: wait-kevent ( mx timespec -- n ) + >r dup mx-fd f 0 roll kqueue-mx-events max-events r> kevent + dup multiplexer-error ; + +: kevent-read-task ( mx fd -- ) + over mx-reads at handle-io-task ; + +: kevent-write-task ( mx fd -- ) + over mx-reads at handle-io-task ; + +: kevent-proc-task ( mx pid -- ) + dup (wait-for-pid) spin kqueue-mx-processes delete-at* [ + [ schedule-thread-with ] with each + ] [ 2drop ] if ; + +: handle-kevent ( mx kevent -- ) + dup kevent-ident swap kevent-filter { + { [ dup EVFILT_READ = ] [ drop kevent-read-task ] } + { [ dup EVFILT_WRITE = ] [ drop kevent-write-task ] } + { [ dup EVFILT_PROC = ] [ drop kevent-proc-task ] } + } cond ; + +: handle-kevents ( mx n -- ) + [ over kqueue-mx-events kevent-nth handle-kevent ] with each ; + +M: kqueue-mx unix-io-multiplex ( ms mx -- ) + swap make-timespec dupd wait-kevent handle-kevents ; + +: make-proc-kevent ( pid -- kevent ) + "kevent" + tuck set-kevent-ident + EV_ADD over set-kevent-flags + EVFILT_PROC over set-kevent-filter + NOTE_EXIT over set-kevent-fflags ; + +: add-pid-task ( continuation pid mx -- ) + 2dup kqueue-mx-processes at* [ + 2nip push + ] [ + drop + over make-proc-kevent over register-kevent + >r >r 1vector r> r> kqueue-mx-processes set-at + ] if ; diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 74bced16c4..adf571a8b7 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -1,14 +1,18 @@ -! Copyright (C) 2007 Slava Pestov. +! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: io io.launcher io.unix.backend io.nonblocking -sequences kernel namespaces math system alien.c-types -debugger continuations arrays assocs combinators unix.process +USING: io io.backend io.launcher io.unix.backend io.nonblocking +sequences kernel namespaces math system alien.c-types debugger +continuations arrays assocs combinators unix.process parser-combinators memoize promises strings ; IN: io.unix.launcher ! Search unix first USE: unix +HOOK: wait-for-process io-backend ( pid -- status ) + +M: unix-io wait-for-process ( pid -- status ) wait-for-pid ; + ! Our command line parser. Supported syntax: ! foo bar baz -- simple tokens ! foo\ bar -- escaping the space @@ -44,28 +48,26 @@ MEMO: 'arguments' ( -- parser ) : (spawn-process) ( -- ) [ - pass-environment? [ - get-arguments get-environment assoc>env exec-args-with-env - ] [ - get-arguments exec-args-with-path - ] if io-error + get-arguments + pass-environment? + [ get-environment assoc>env exec-args-with-env ] + [ exec-args-with-path ] if + io-error ] [ error. :c flush ] recover 1 exit ; -: wait-for-process ( pid -- ) - 0 0 waitpid drop ; - : spawn-process ( -- pid ) [ (spawn-process) ] [ ] with-fork ; : spawn-detached ( -- ) - [ spawn-process 0 exit ] [ ] with-fork wait-for-process ; + [ spawn-process 0 exit ] [ ] with-fork + wait-for-process drop ; M: unix-io run-process* ( desc -- ) [ +detached+ get [ spawn-detached ] [ - spawn-process wait-for-process + spawn-process wait-for-process drop ] if ] with-descriptor ; @@ -85,15 +87,16 @@ M: unix-io run-process* ( desc -- ) -rot 2dup second close first close ] with-fork first swap second rot ; -TUPLE: pipe-stream pid ; +TUPLE: pipe-stream pid status ; : ( in out pid -- stream ) - pipe-stream construct-boa + f pipe-stream construct-boa -rot handle>duplex-stream over set-delegate ; M: pipe-stream stream-close dup delegate stream-close - pipe-stream-pid wait-for-process ; + dup pipe-stream-pid wait-for-process + swap set-pipe-stream-status ; M: unix-io process-stream* [ spawn-process-stream ] with-descriptor ; diff --git a/extra/io/unix/linux/linux.factor b/extra/io/unix/linux/linux.factor new file mode 100644 index 0000000000..180e81e30a --- /dev/null +++ b/extra/io/unix/linux/linux.factor @@ -0,0 +1,17 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +IN: io.unix.linux +USING: io.unix.backend io.unix.select namespaces kernel assocs ; + +TUPLE: linux-io ; + +INSTANCE: linux-io unix-io + +M: linux-io init-io ( -- ) + start-wait-loop + mx set-global ; + +M: linux-io wait-for-pid ( pid -- status ) + [ kqueue-mx get-global add-pid-task stop ] curry callcc1 ; + +T{ linux-io } io-backend set-global diff --git a/extra/io/unix/select/select.factor b/extra/io/unix/select/select.factor new file mode 100644 index 0000000000..e74324f3b6 --- /dev/null +++ b/extra/io/unix/select/select.factor @@ -0,0 +1,47 @@ +! Copyright (C) 2004, 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.c-types kernel io.nonblocking io.unix.backend +bit-arrays sequences assocs unix math namespaces structs ; +IN: io.unix.select + +TUPLE: select-mx read-fdset write-fdset ; + +! Factor's bit-arrays are an array of bytes, OS X expects +! FD_SET to be an array of cells, so we have to account for +! byte order differences on big endian platforms +: little-endian? 1 *char 1 = ; foldable + +: munge ( i -- i' ) + little-endian? [ BIN: 11000 bitxor ] unless ; inline + +: ( -- mx ) + select-mx construct-mx + FD_SETSIZE 8 * over set-select-mx-read-fdset + FD_SETSIZE 8 * over set-select-mx-write-fdset ; + +: handle-fd ( fd task fdset mx -- ) + roll munge rot nth [ swap handle-io-task ] [ 2drop ] if ; + +: handle-fdset ( tasks fdset mx -- ) + [ handle-fd ] 2curry assoc-each ; + +: init-fdset ( tasks fdset -- ) + dup clear-bits + [ >r drop t swap munge r> set-nth ] curry assoc-each ; + +: read-fdset/tasks + { mx-reads select-mx-read-fdset } get-slots ; + +: write-fdset/tasks + { mx-writes select-mx-write-fdset } get-slots ; + +: init-fdsets ( mx -- read write except ) + [ read-fdset/tasks tuck init-fdset ] keep + write-fdset/tasks tuck init-fdset + f ; + +M: select-mx unix-io-multiplex ( ms mx -- ) + swap >r FD_SETSIZE over init-fdsets r> make-timeval + select multiplexer-error + dup read-fdset/tasks pick handle-fdset + dup write-fdset/tasks rot handle-fdset ; diff --git a/extra/io/unix/sockets/sockets.factor b/extra/io/unix/sockets/sockets.factor index 30d3bbd94c..81c0e50b42 100644 --- a/extra/io/unix/sockets/sockets.factor +++ b/extra/io/unix/sockets/sockets.factor @@ -40,7 +40,7 @@ M: connect-task do-io-task io-task-port dup port-handle f 0 write 0 < [ defer-error ] [ drop t ] if ; -M: connect-task task-container drop write-tasks get-global ; +M: connect-task io-task-container drop mx-writes ; : wait-to-connect ( port -- ) [ add-io-task stop ] callcc0 drop ; @@ -70,7 +70,7 @@ TUPLE: accept-task ; : ( port continuation -- task ) accept-task ; -M: accept-task task-container drop read-tasks get ; +M: accept-task io-task-container drop mx-reads ; : accept-sockaddr ( port -- fd sockaddr ) dup port-handle swap server-port-addr sockaddr-type @@ -152,7 +152,7 @@ M: receive-task do-io-task 2drop defer-error ] if ; -M: receive-task task-container drop read-tasks get ; +M: receive-task io-task-container drop mx-reads ; : wait-receive ( stream -- ) [ add-io-task stop ] callcc0 drop ; @@ -185,7 +185,7 @@ M: send-task do-io-task [ send-task-len do-send ] keep swap 0 < [ io-task-port defer-error ] [ drop t ] if ; -M: send-task task-container drop write-tasks get ; +M: send-task io-task-container drop mx-writes ; : wait-send ( packet sockaddr len stream -- ) [ add-io-task stop ] callcc0 2drop 2drop ; diff --git a/extra/io/unix/unix.factor b/extra/io/unix/unix.factor index 1c86224433..d6d0a9cc22 100755 --- a/extra/io/unix/unix.factor +++ b/extra/io/unix/unix.factor @@ -3,9 +3,8 @@ io.unix.launcher io.unix.mmap io.backend combinators namespaces system vocabs.loader ; { - { [ macosx? ] [ "io.unix.backend.kqueue" ] } - { [ bsd? ] [ "io.unix.backend.kqueue" ] } - { [ unix? ] [ "io.unix.backend.select" ] } + { [ bsd? ] [ "io.unix.bsd" ] } + { [ macosx? ] [ "io.unix.bsd" ] } + { [ linux? ] [ "io.unix.backend.linux" ] } + { [ solaris? ] [ "io.unix.backend.solaris" ] } } cond require - -T{ unix-io } io-backend set-global diff --git a/extra/unix/process/process.factor b/extra/unix/process/process.factor index a99611aba6..b2877dc4a1 100644 --- a/extra/unix/process/process.factor +++ b/extra/unix/process/process.factor @@ -1,53 +1,55 @@ - -USING: kernel alien.c-types sequences math unix combinators.cleave ; +USING: kernel alien.c-types sequences math unix +combinators.cleave vectors kernel namespaces continuations +threads assocs vectors ; IN: unix.process -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! Low-level Unix process launching utilities. These are used +! to implement io.launcher on Unix. User code should use +! io.launcher instead. : >argv ( seq -- alien ) [ malloc-char-string ] map f add >c-void*-array ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - : exec ( pathname argv -- int ) - [ malloc-char-string ] [ >argv ] bi* execv ; + [ malloc-char-string ] [ >argv ] bi* execv ; : exec-with-path ( filename argv -- int ) - [ malloc-char-string ] [ >argv ] bi* execvp ; + [ malloc-char-string ] [ >argv ] bi* execvp ; : exec-with-env ( filename argv envp -- int ) - [ malloc-char-string ] [ >argv ] [ >argv ] tri* execve ; + [ malloc-char-string ] [ >argv ] [ >argv ] tri* execve ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +: exec-args ( seq -- int ) + [ first ] [ ] bi exec ; -: exec-args ( seq -- int ) [ first ] [ ] bi exec ; -: exec-args-with-path ( seq -- int ) [ first ] [ ] bi exec-with-path ; +: exec-args-with-path ( seq -- int ) + [ first ] [ ] bi exec-with-path ; -: exec-args-with-env ( seq seq -- int ) >r [ first ] [ ] bi r> exec-with-env ; +: exec-args-with-env ( seq seq -- int ) + >r [ first ] [ ] bi r> exec-with-env ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +: with-fork ( child parent -- ) + fork dup zero? -roll swap curry if ; inline -: with-fork ( child parent -- ) fork dup zero? -roll swap curry if ; inline - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -USING: kernel alien.c-types namespaces continuations threads assocs unix - combinators.cleave ; +! Lame polling strategy for getting process exit codes. On +! BSD, we use kqueue which is more efficient. SYMBOL: pid-wait -! KEY | VALUE -! ----------- -! pid | continuation +: (wait-for-pid) ( pid -- status ) + 0 [ 0 waitpid drop ] keep *int ; -: init-pid-wait ( -- ) H{ } clone pid-wait set-global ; - -: wait-for-pid ( pid -- status ) [ pid-wait get set-at stop ] curry callcc1 ; +: wait-for-pid ( pid -- status ) + [ pid-wait get-global [ ?push ] change-at stop ] curry + callcc1 ; : wait-loop ( -- ) - -1 0 tuck WNOHANG waitpid ! &status return - [ *int ] [ pid-wait get delete-at* drop ] bi* ! status ? - dup [ schedule-thread-with ] [ 2drop ] if - 250 sleep wait-loop ; + -1 0 tuck WNOHANG waitpid ! &status return + [ *int ] [ pid-wait get delete-at* drop ] bi* ! status ? + [ schedule-thread-with ] with each + 250 sleep + wait-loop ; -: start-wait-loop ( -- ) init-pid-wait [ wait-loop ] in-thread ; \ No newline at end of file +: start-wait-loop ( -- ) + H{ } clone pid-wait set-global + [ wait-loop ] in-thread ; \ No newline at end of file From 6812eac271fa5beea592ef9630e5371f4e3ca168 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Sun, 20 Jan 2008 19:20:28 -0500 Subject: [PATCH 39/78] Solution to Project Euler problem 30 --- extra/project-euler/030/030.factor | 46 ++++++++++++++++++++++++ extra/project-euler/common/common.factor | 2 +- extra/project-euler/project-euler.factor | 4 +-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 extra/project-euler/030/030.factor diff --git a/extra/project-euler/030/030.factor b/extra/project-euler/030/030.factor new file mode 100644 index 0000000000..854b7ca5ca --- /dev/null +++ b/extra/project-euler/030/030.factor @@ -0,0 +1,46 @@ +! Copyright (c) 2007 Aaron Schaefer. +! See http://factorcode.org/license.txt for BSD license. +USING: combinators.lib kernel math math.functions project-euler.common sequences ; +IN: project-euler.030 + +! http://projecteuler.net/index.php?section=problems&id=30 + +! DESCRIPTION +! ----------- + +! Surprisingly there are only three numbers that can be written as the sum of +! fourth powers of their digits: + +! 1634 = 1^4 + 6^4 + 3^4 + 4^4 +! 8208 = 8^4 + 2^4 + 0^4 + 8^4 +! 9474 = 9^4 + 4^4 + 7^4 + 4^4 + +! As 1 = 1^4 is not a sum it is not included. + +! The sum of these numbers is 1634 + 8208 + 9474 = 19316. + +! Find the sum of all the numbers that can be written as the sum of fifth +! powers of their digits. + + +! SOLUTION +! -------- + +! if n is the number of digits +! n * 9^5 = 10^n when n ≈ 5.513 +! 10^5.513 ≈ 325537 + +digits [ 5 ^ ] sigma ; + +PRIVATE> + +: euler030 ( -- answer ) + 325537 [ dup sum-fifth-powers = ] subset sum 1- ; + +! [ euler030 ] 100 ave-time +! 2537 ms run / 125 ms GC ave time - 100 trials + +MAIN: euler030 diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor index d21a780773..c875a440ba 100644 --- a/extra/project-euler/common/common.factor +++ b/extra/project-euler/common/common.factor @@ -11,7 +11,7 @@ IN: project-euler.common ! collect-consecutive - #8, #11 ! log10 - #25, #134 ! max-path - #18, #67 -! number>digits - #16, #20 +! number>digits - #16, #20, #30 ! propagate-all - #18, #67 ! sum-proper-divisors - #21 ! tau* - #12 diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index 513eeba020..329a1b9668 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -9,8 +9,8 @@ USING: definitions io io.files kernel math.parser sequences vocabs project-euler.017 project-euler.018 project-euler.019 project-euler.020 project-euler.021 project-euler.022 project-euler.023 project-euler.024 project-euler.025 project-euler.026 project-euler.027 project-euler.028 - project-euler.029 project-euler.067 project-euler.134 project-euler.169 - project-euler.173 project-euler.175 ; + project-euler.029 project-euler.030 project-euler.067 project-euler.134 + project-euler.169 project-euler.173 project-euler.175 ; IN: project-euler Date: Sun, 20 Jan 2008 22:30:58 -0500 Subject: [PATCH 40/78] Solution to Project Euler problem 31 --- extra/project-euler/031/031.factor | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 extra/project-euler/031/031.factor diff --git a/extra/project-euler/031/031.factor b/extra/project-euler/031/031.factor new file mode 100644 index 0000000000..b4402d8904 --- /dev/null +++ b/extra/project-euler/031/031.factor @@ -0,0 +1,63 @@ +! Copyright (c) 2007 Aaron Schaefer. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel math ; +IN: project-euler.031 + +! http://projecteuler.net/index.php?section=problems&id=31 + +! DESCRIPTION +! ----------- + +! In England the currency is made up of pound, £, and pence, p, and there are +! eight coins in general circulation: + +! 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p). + +! It is possible to make £2 in the following way: + +! 1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p + +! How many different ways can £2 be made using any number of coins? + + + +! SOLUTION +! -------- + += [ [ 2 - 2p ] keep 1p + ] [ drop 0 ] if ; + +: 5p ( m -- n ) + dup 0 >= [ [ 5 - 5p ] keep 2p + ] [ drop 0 ] if ; + +: 10p ( m -- n ) + dup 0 >= [ [ 10 - 10p ] keep 5p + ] [ drop 0 ] if ; + +: 20p ( m -- n ) + dup 0 >= [ [ 20 - 20p ] keep 10p + ] [ drop 0 ] if ; + +: 50p ( m -- n ) + dup 0 >= [ [ 50 - 50p ] keep 20p + ] [ drop 0 ] if ; + +: 100p ( m -- n ) + dup 0 >= [ [ 100 - 100p ] keep 50p + ] [ drop 0 ] if ; + +: 200p ( m -- n ) + dup 0 >= [ [ 200 - 200p ] keep 100p + ] [ drop 0 ] if ; + +PRIVATE> + +: euler031 ( -- answer ) + 200 200p ; + +! [ euler031 ] 100 ave-time +! 4 ms run / 0 ms GC ave time - 100 trials + +! TODO: generalize to eliminate duplication; use a sequence to specify denominations? + +MAIN: euler031 From feb4e8df9e0d5159cbe68dd85754d769ec0605b4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 15:33:37 -0500 Subject: [PATCH 41/78] Fix typo --- core/math/math-docs.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/math/math-docs.factor b/core/math/math-docs.factor index 307a5531a1..1ec3592c79 100755 --- a/core/math/math-docs.factor +++ b/core/math/math-docs.factor @@ -209,7 +209,7 @@ HELP: bitxor HELP: shift { $values { "x" integer } { "n" integer } { "y" integer } } -{ $description "Shifts " { $snippet "x" } " to the left by " { $snippet "y" } " bits if " { $snippet "y" } " is positive, or " { $snippet "-y" } " bits to the right if " { $snippet "y" } " is negative. A left shift of a fixnum may overflow, yielding a bignum. A right shift may result in bits ``falling off'' the right hand side and being discarded." } +{ $description "Shifts " { $snippet "x" } " to the left by " { $snippet "n" } " bits if " { $snippet "n" } " is positive, or " { $snippet "-n" } " bits to the right if " { $snippet "n" } " is negative. A left shift of a fixnum may overflow, yielding a bignum. A right shift may result in bits ``falling off'' the right hand side and being discarded." } { $examples { $example "BIN: 101 5 shift .b" "10100000" } { $example "BIN: 11111 -2 shift .b" "111" } } ; HELP: bitnot From c1963dd4abd6566550c18edc73268898ca366fce Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 15:33:43 -0500 Subject: [PATCH 42/78] I/O cleanups --- extra/io/nonblocking/nonblocking-docs.factor | 2 +- extra/io/nonblocking/nonblocking.factor | 30 +++++++++---------- extra/io/sniffer/bsd/bsd.factor | 2 +- extra/io/unix/backend/backend.factor | 31 +++++++++++++------- extra/io/unix/epoll/epoll.factor | 18 +++++------- extra/io/unix/kqueue/kqueue.factor | 20 +++++-------- extra/io/unix/select/select.factor | 2 +- extra/io/unix/sockets/sockets.factor | 21 ++++--------- extra/io/windows/ce/sockets/sockets.factor | 4 +-- extra/io/windows/nt/sockets/sockets.factor | 4 +-- 10 files changed, 62 insertions(+), 72 deletions(-) diff --git a/extra/io/nonblocking/nonblocking-docs.factor b/extra/io/nonblocking/nonblocking-docs.factor index 049c3bf497..c4adc3aa38 100644 --- a/extra/io/nonblocking/nonblocking-docs.factor +++ b/extra/io/nonblocking/nonblocking-docs.factor @@ -55,7 +55,7 @@ HELP: init-handle { $contract "Prepares a native handle for use by the port; called by " { $link } "." } ; HELP: -{ $values { "handle" "a native handle identifying an I/O resource" } { "buffer" "a " { $link buffer } " or " { $link f } } { "port" "a new " { $link port } } } +{ $values { "handle" "a native handle identifying an I/O resource" } { "buffer" "a " { $link buffer } " or " { $link f } } { "type" symbol } { "port" "a new " { $link port } } } { $description "Creates a new " { $link port } " using the specified native handle and I/O buffer." } $low-level-note ; diff --git a/extra/io/nonblocking/nonblocking.factor b/extra/io/nonblocking/nonblocking.factor index 9ff21aa011..9839cc7066 100755 --- a/extra/io/nonblocking/nonblocking.factor +++ b/extra/io/nonblocking/nonblocking.factor @@ -12,38 +12,36 @@ SYMBOL: default-buffer-size ! Common delegate of native stream readers and writers TUPLE: port handle error timeout cutoff type eof? ; -SYMBOL: input -SYMBOL: output SYMBOL: closed -PREDICATE: port input-port port-type input eq? ; -PREDICATE: port output-port port-type output eq? ; +PREDICATE: port input-port port-type input-port eq? ; +PREDICATE: port output-port port-type output-port eq? ; GENERIC: init-handle ( handle -- ) GENERIC: close-handle ( handle -- ) -: ( handle buffer -- port ) - over init-handle +: ( handle buffer type -- port ) + pick init-handle 0 0 { set-port-handle set-delegate + set-port-type set-port-timeout set-port-cutoff } port construct ; -: ( handle -- port ) - default-buffer-size get ; +: ( handle type -- port ) + default-buffer-size get swap ; : ( handle -- stream ) - input over set-port-type ; + input-port ; : ( handle -- stream ) - output over set-port-type ; + output-port ; : handle>duplex-stream ( in-handle out-handle -- stream ) - [ >r r> ] - [ ] [ stream-close ] + [ >r r> ] [ ] [ stream-close ] cleanup ; : touch-port ( port -- ) @@ -170,8 +168,8 @@ M: port stream-close TUPLE: server-port addr client ; -: ( port addr -- server ) - server-port pick set-port-type +: ( handle addr -- server ) + >r f server-port r> { set-delegate set-server-port-addr } server-port construct ; @@ -180,8 +178,8 @@ TUPLE: server-port addr client ; TUPLE: datagram-port addr packet packet-addr ; -: ( port addr -- datagram ) - datagram-port pick set-port-type +: ( handle addr -- datagram ) + >r f datagram-port r> { set-delegate set-datagram-port-addr } datagram-port construct ; diff --git a/extra/io/sniffer/bsd/bsd.factor b/extra/io/sniffer/bsd/bsd.factor index 5c32bd78d2..ae87c05d38 100644 --- a/extra/io/sniffer/bsd/bsd.factor +++ b/extra/io/sniffer/bsd/bsd.factor @@ -83,7 +83,7 @@ M: unix-io ( obj -- sniffer ) ] keep dupd sniffer-spec-ifname ioctl-sniffer-fd dup make-ioctl-buffer - input over set-port-type + input-port \ sniffer construct-delegate ] with-destructors ; diff --git a/extra/io/unix/backend/backend.factor b/extra/io/unix/backend/backend.factor index 19856dc6be..6da26b5b67 100755 --- a/extra/io/unix/backend/backend.factor +++ b/extra/io/unix/backend/backend.factor @@ -18,19 +18,33 @@ TUPLE: io-task port callbacks ; >r 1vector io-task construct-boa r> construct-delegate ; inline +TUPLE: input-task ; + +: ( port continuation class -- task ) + >r input-task r> construct-delegate ; inline + +TUPLE: output-task ; + +: ( port continuation class -- task ) + >r output-task r> construct-delegate ; inline + GENERIC: do-io-task ( task -- ? ) GENERIC: io-task-container ( mx task -- hashtable ) ! I/O multiplexers TUPLE: mx fd reads writes ; +M: input-task io-task-container drop mx-reads ; + +M: output-task io-task-container drop mx-writes ; + : ( -- mx ) f H{ } clone H{ } clone mx construct-boa ; : construct-mx ( class -- obj ) swap construct-delegate ; GENERIC: register-io-task ( task mx -- ) GENERIC: unregister-io-task ( task mx -- ) -GENERIC: unix-io-multiplex ( ms mx -- ) +GENERIC: wait-for-events ( ms mx -- ) : fd/container ( task mx -- task fd container ) over io-task-container >r dup io-task-fd r> ; inline @@ -112,14 +126,12 @@ M: integer close-handle ( fd -- ) TUPLE: read-task ; : ( port continuation -- task ) - read-task ; + read-task ; M: read-task do-io-task io-task-port dup refill [ [ reader-eof ] [ drop ] if ] keep ; -M: read-task io-task-container drop mx-reads ; - M: input-port (wait-to-read) [ add-io-task stop ] callcc0 pending-error ; @@ -131,14 +143,12 @@ M: input-port (wait-to-read) TUPLE: write-task ; : ( port continuation -- task ) - write-task ; + write-task ; M: write-task do-io-task io-task-port dup buffer-empty? over port-error or [ 0 swap buffer-reset t ] [ write-step ] if ; -M: write-task io-task-container drop mx-writes ; - : add-write-io-task ( port continuation -- ) over port-handle mx get-global mx-writes at* [ io-task-callbacks push drop ] @@ -151,7 +161,7 @@ M: port port-flush ( port -- ) dup buffer-empty? [ drop ] [ (wait-to-write) ] if ; M: unix-io io-multiplex ( ms -- ) - mx get-global unix-io-multiplex ; + mx get-global wait-for-events ; M: unix-io init-stdio ( -- ) 0 1 handle>duplex-stream io:stdio set-global @@ -161,8 +171,7 @@ M: unix-io init-stdio ( -- ) TUPLE: mx-port mx ; : ( mx -- port ) - dup mx-fd f - mx-port over set-port-type + dup mx-fd f mx-port { set-mx-port-mx set-delegate } mx-port construct ; TUPLE: mx-task ; @@ -171,7 +180,7 @@ TUPLE: mx-task ; f io-task construct-boa mx-task construct-delegate ; M: mx-task do-io-task - io-task-port mx-port-mx 0 swap unix-io-multiplex f ; + io-task-port mx-port-mx 0 swap wait-for-events f ; : multiplexer-error ( n -- ) 0 < [ err_no ignorable-error? [ (io-error) ] unless ] when ; diff --git a/extra/io/unix/epoll/epoll.factor b/extra/io/unix/epoll/epoll.factor index e39c35aca3..f2230f6e81 100644 --- a/extra/io/unix/epoll/epoll.factor +++ b/extra/io/unix/epoll/epoll.factor @@ -16,19 +16,15 @@ TUPLE: epoll-mx events ; max-events epoll_create dup io-error over set-mx-fd max-events "epoll-event" over set-epoll-mx-events ; -: io-task-filter ( task -- n ) - class { - { read-task [ EVFILT_READ ] } - { accept-task [ EVFILT_READ ] } - { receive-task [ EVFILT_READ ] } - { write-task [ EVFILT_WRITE ] } - { connect-task [ EVFILT_WRITE ] } - { send-task [ EVFILT_WRITE ] } - } case ; +GENERIC: io-task-events ( task -- n ) + +M: input-task drop EPOLLIN ; + +M: output-task drop EPOLLOUT ; : make-event ( task -- event ) "epoll-event" - tuck set-epoll-event-events + over io-task-events over set-epoll-event-events over io-task-fd over set-epoll-fd ; : do-epoll-ctl ( task mx what -- ) @@ -57,5 +53,5 @@ M: epoll-mx unregister-io-task ( task mx -- ) : handle-events ( mx n -- ) [ over epoll-mx-events kevent-nth handle-kevent ] with each ; -M: epoll-mx unix-io-multiplex ( ms mx -- ) +M: epoll-mx wait-for-events ( ms mx -- ) dup rot wait-kevent handle-kevents ; diff --git a/extra/io/unix/kqueue/kqueue.factor b/extra/io/unix/kqueue/kqueue.factor index e1ce7666f1..4fbfbcaaf0 100644 --- a/extra/io/unix/kqueue/kqueue.factor +++ b/extra/io/unix/kqueue/kqueue.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types kernel io.nonblocking io.unix.backend -io.unix.sockets sequences assocs unix unix.kqueue unix.process -math namespaces classes combinators threads vectors ; +sequences assocs unix unix.kqueue unix.process math namespaces +combinators threads vectors ; IN: io.unix.kqueue TUPLE: kqueue-mx events processes ; @@ -18,15 +18,11 @@ TUPLE: kqueue-mx events processes ; H{ } clone over set-kqueue-mx-processes max-events "kevent" over set-kqueue-mx-events ; -: io-task-filter ( task -- n ) - class { - { read-task [ EVFILT_READ ] } - { accept-task [ EVFILT_READ ] } - { receive-task [ EVFILT_READ ] } - { write-task [ EVFILT_WRITE ] } - { connect-task [ EVFILT_WRITE ] } - { send-task [ EVFILT_WRITE ] } - } case ; +GENERIC: io-task-filter ( task -- n ) + +M: input-task io-task-filter drop EVFILT_READ ; + +M: output-task io-task-filter drop EVFILT_WRITE ; : make-kevent ( task flags -- event ) "kevent" @@ -70,7 +66,7 @@ M: kqueue-mx unregister-io-task ( task mx -- ) : handle-kevents ( mx n -- ) [ over kqueue-mx-events kevent-nth handle-kevent ] with each ; -M: kqueue-mx unix-io-multiplex ( ms mx -- ) +M: kqueue-mx wait-for-events ( ms mx -- ) swap make-timespec dupd wait-kevent handle-kevents ; : make-proc-kevent ( pid -- kevent ) diff --git a/extra/io/unix/select/select.factor b/extra/io/unix/select/select.factor index e74324f3b6..c28686d2f2 100644 --- a/extra/io/unix/select/select.factor +++ b/extra/io/unix/select/select.factor @@ -40,7 +40,7 @@ TUPLE: select-mx read-fdset write-fdset ; write-fdset/tasks tuck init-fdset f ; -M: select-mx unix-io-multiplex ( ms mx -- ) +M: select-mx wait-for-events ( ms mx -- ) swap >r FD_SETSIZE over init-fdsets r> make-timeval select multiplexer-error dup read-fdset/tasks pick handle-fdset diff --git a/extra/io/unix/sockets/sockets.factor b/extra/io/unix/sockets/sockets.factor index 81c0e50b42..35366b1d41 100644 --- a/extra/io/unix/sockets/sockets.factor +++ b/extra/io/unix/sockets/sockets.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2004, 2007 Slava Pestov, Ivan Tikhonov. +! Copyright (C) 2004, 2008 Slava Pestov, Ivan Tikhonov. ! See http://factorcode.org/license.txt for BSD license. ! We need to fiddle with the exact search order here, since @@ -34,14 +34,12 @@ M: unix-io addrinfo-error ( n -- ) TUPLE: connect-task ; : ( port continuation -- task ) - connect-task ; + connect-task ; M: connect-task do-io-task io-task-port dup port-handle f 0 write 0 < [ defer-error ] [ drop t ] if ; -M: connect-task io-task-container drop mx-writes ; - : wait-to-connect ( port -- ) [ add-io-task stop ] callcc0 drop ; @@ -68,9 +66,7 @@ USE: unix TUPLE: accept-task ; : ( port continuation -- task ) - accept-task ; - -M: accept-task io-task-container drop mx-reads ; + accept-task ; : accept-sockaddr ( port -- fd sockaddr ) dup port-handle swap server-port-addr sockaddr-type @@ -101,7 +97,6 @@ M: unix-io ( addrspec -- stream ) [ SOCK_STREAM server-fd dup 10 listen zero? [ dup close (io-error) ] unless - f ] keep ; M: unix-io accept ( server -- client ) @@ -113,7 +108,7 @@ M: unix-io accept ( server -- client ) ! Datagram sockets - UDP and Unix domain M: unix-io - [ SOCK_DGRAM server-fd f ] keep ; + [ SOCK_DGRAM server-fd ] keep ; SYMBOL: receive-buffer @@ -139,7 +134,7 @@ packet-size receive-buffer set-global TUPLE: receive-task ; : ( stream continuation -- task ) - receive-task ; + receive-task ; M: receive-task do-io-task io-task-port @@ -152,8 +147,6 @@ M: receive-task do-io-task 2drop defer-error ] if ; -M: receive-task io-task-container drop mx-reads ; - : wait-receive ( stream -- ) [ add-io-task stop ] callcc0 drop ; @@ -170,7 +163,7 @@ M: unix-io receive ( datagram -- packet addrspec ) TUPLE: send-task packet sockaddr len ; : ( packet sockaddr len stream continuation -- task ) - send-task [ + send-task [ { set-send-task-packet set-send-task-sockaddr @@ -185,8 +178,6 @@ M: send-task do-io-task [ send-task-len do-send ] keep swap 0 < [ io-task-port defer-error ] [ drop t ] if ; -M: send-task io-task-container drop mx-writes ; - : wait-send ( packet sockaddr len stream -- ) [ add-io-task stop ] callcc0 2drop 2drop ; diff --git a/extra/io/windows/ce/sockets/sockets.factor b/extra/io/windows/ce/sockets/sockets.factor index da64b25933..cc19976bc5 100755 --- a/extra/io/windows/ce/sockets/sockets.factor +++ b/extra/io/windows/ce/sockets/sockets.factor @@ -38,7 +38,7 @@ M: windows-ce-io ( addrspec -- duplex-stream ) [ windows.winsock:SOCK_STREAM server-fd dup listen-on-socket - f + ] keep ; M: windows-ce-io accept ( server -- client ) @@ -58,7 +58,7 @@ M: windows-ce-io accept ( server -- client ) M: windows-ce-io ( addrspec -- datagram ) [ - windows.winsock:SOCK_DGRAM server-fd f + windows.winsock:SOCK_DGRAM server-fd ] keep ; : packet-size 65536 ; inline diff --git a/extra/io/windows/nt/sockets/sockets.factor b/extra/io/windows/nt/sockets/sockets.factor index e86f070719..a6c44a0b86 100755 --- a/extra/io/windows/nt/sockets/sockets.factor +++ b/extra/io/windows/nt/sockets/sockets.factor @@ -149,7 +149,7 @@ M: windows-nt-io ( addrspec -- server ) [ SOCK_STREAM server-fd dup listen-on-socket dup add-completion - f + ] keep ] with-destructors ; @@ -158,7 +158,7 @@ M: windows-nt-io ( addrspec -- datagram ) [ SOCK_DGRAM server-fd dup add-completion - f + ] keep ] with-destructors ; From 913403f06617a12fa080cb5208223ba6a66b5b21 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 17:29:54 -0500 Subject: [PATCH 43/78] Load fix --- extra/io/nonblocking/nonblocking-docs.factor | 2 +- extra/io/nonblocking/nonblocking.factor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/io/nonblocking/nonblocking-docs.factor b/extra/io/nonblocking/nonblocking-docs.factor index c4adc3aa38..d0d5818bee 100644 --- a/extra/io/nonblocking/nonblocking-docs.factor +++ b/extra/io/nonblocking/nonblocking-docs.factor @@ -40,7 +40,7 @@ $nl { { $link port-error } " - the most recent I/O error, if any. This error is thrown to the waiting thread when " { $link pending-error } " is called by stream operations" } { { $link port-timeout } " - a timeout, specifying the maximum length of time, in milliseconds, for which input operations can block before throwing an error. A value of 0 denotes no timeout is desired." } { { $link port-cutoff } " - the time when the current timeout expires; if no input data arrives before this time, an error is thrown" } - { { $link port-type } " - a symbol identifying the port's intended purpose. Can be " { $link input } ", " { $link output } ", " { $link closed } ", or any other symbol" } + { { $link port-type } " - a symbol identifying the port's intended purpose" } { { $link port-eof? } " - a flag indicating if the port has reached the end of file while reading" } } } ; diff --git a/extra/io/nonblocking/nonblocking.factor b/extra/io/nonblocking/nonblocking.factor index 9839cc7066..8a7e732281 100755 --- a/extra/io/nonblocking/nonblocking.factor +++ b/extra/io/nonblocking/nonblocking.factor @@ -160,7 +160,7 @@ M: output-port stream-flush ( port -- ) M: port stream-close dup port-type closed eq? [ dup port-type >r closed over set-port-type r> - output eq? [ dup port-flush ] when + output-port eq? [ dup port-flush ] when dup port-handle close-handle dup delegate [ buffer-free ] when* f over set-delegate From 64d284a97041f65356a4a77ffc64da4f66995329 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 17:30:10 -0500 Subject: [PATCH 44/78] Fix recompilation of foldable, flushable --- core/compiler/test/redefine.factor | 24 ++++++++++++++++++++++++ core/optimizer/backend/backend.factor | 11 ++++++----- core/words/words-tests.factor | 11 +++++++++++ core/words/words.factor | 2 +- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/core/compiler/test/redefine.factor b/core/compiler/test/redefine.factor index 6e652df877..718e98c9c2 100755 --- a/core/compiler/test/redefine.factor +++ b/core/compiler/test/redefine.factor @@ -205,3 +205,27 @@ DEFER: generic-then-not-generic-test-2 [ ] [ "IN: temporary USE: math : generic-then-not-generic-test-1 1 + ;" eval ] unit-test [ 4 ] [ generic-then-not-generic-test-2 ] unit-test + +DEFER: foldable-test-2 + +[ ] [ "IN: temporary : foldable-test-1 3 ; foldable" eval ] unit-test + +[ ] [ "IN: temporary : foldable-test-2 foldable-test-1 ;" eval ] unit-test + +[ 3 ] [ foldable-test-2 ] unit-test + +[ ] [ "IN: temporary : foldable-test-1 4 ; foldable" eval ] unit-test + +[ 4 ] [ foldable-test-2 ] unit-test + +DEFER: flushable-test-2 + +[ ] [ "IN: temporary USE: kernel : flushable-test-1 drop 3 ; flushable" eval ] unit-test + +[ ] [ "IN: temporary USE: kernel : flushable-test-2 V{ } dup flushable-test-1 drop ;" eval ] unit-test + +[ V{ } ] [ flushable-test-2 ] unit-test + +[ ] [ "IN: temporary USING: kernel sequences ; : flushable-test-1 3 over push ;" eval ] unit-test + +[ V{ 3 } ] [ flushable-test-2 ] unit-test diff --git a/core/optimizer/backend/backend.factor b/core/optimizer/backend/backend.factor index 1122d83129..4843a9ff26 100644 --- a/core/optimizer/backend/backend.factor +++ b/core/optimizer/backend/backend.factor @@ -17,17 +17,17 @@ SYMBOL: optimizer-changed GENERIC: optimize-node* ( node -- node/t changed? ) -: ?union ( hash/f hash -- hash ) +: ?union ( assoc/f assoc -- hash ) over [ union ] [ nip ] if ; -: add-node-literals ( hash node -- ) +: add-node-literals ( assoc node -- ) over assoc-empty? [ 2drop ] [ [ node-literals ?union ] keep set-node-literals ] if ; -: add-node-classes ( hash node -- ) +: add-node-classes ( assoc node -- ) over assoc-empty? [ 2drop ] [ @@ -324,6 +324,7 @@ M: #dispatch optimize-node* ] if ; : flush-eval ( #call -- node ) + dup node-param +inlined+ depends-on dup node-out-d length f inline-literals ; : partial-eval? ( #call -- ? ) @@ -337,9 +338,9 @@ M: #dispatch optimize-node* dup node-in-d [ node-literal ] with map ; : partial-eval ( #call -- node ) + dup node-param +inlined+ depends-on dup literal-in-d over node-param 1quotation - [ with-datastack ] catch - [ 3drop t ] [ inline-literals ] if ; + [ with-datastack inline-literals ] [ 2drop 2drop t ] recover ; : define-identities ( words identities -- ) [ "identities" set-word-prop ] curry each ; diff --git a/core/words/words-tests.factor b/core/words/words-tests.factor index a88892b5f4..2455250dc9 100755 --- a/core/words/words-tests.factor +++ b/core/words/words-tests.factor @@ -175,3 +175,14 @@ SYMBOL: quot-uses-b [ t ] [ "symbol-generic" "temporary" lookup symbol? ] unit-test [ f ] [ "symbol-generic" "temporary" lookup generic? ] unit-test + +! Regressions +[ ] [ "IN: temporary : decl-forget-test ; foldable" eval ] unit-test +[ t ] [ "decl-forget-test" "temporary" lookup "foldable" word-prop ] unit-test +[ ] [ "IN: temporary : decl-forget-test ;" eval ] unit-test +[ f ] [ "decl-forget-test" "temporary" lookup "foldable" word-prop ] unit-test + +[ ] [ "IN: temporary : decl-forget-test ; flushable" eval ] unit-test +[ t ] [ "decl-forget-test" "temporary" lookup "flushable" word-prop ] unit-test +[ ] [ "IN: temporary : decl-forget-test ;" eval ] unit-test +[ f ] [ "decl-forget-test" "temporary" lookup "flushable" word-prop ] unit-test diff --git a/core/words/words.factor b/core/words/words.factor index a2d9234353..6d8bad4f9e 100755 --- a/core/words/words.factor +++ b/core/words/words.factor @@ -127,7 +127,7 @@ SYMBOL: changed-words : reset-word ( word -- ) { "unannotated-def" - "parsing" "inline" "foldable" + "parsing" "inline" "foldable" "flushable" "predicating" "reading" "writing" "constructing" From 1f2e4c88ed8a24a4127483ee0d39e5dc1aef2440 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 17:30:19 -0500 Subject: [PATCH 45/78] Fix obsolete docs --- core/parser/parser-docs.factor | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/parser/parser-docs.factor b/core/parser/parser-docs.factor index de56dc55db..30e259c033 100755 --- a/core/parser/parser-docs.factor +++ b/core/parser/parser-docs.factor @@ -44,8 +44,7 @@ ARTICLE: "vocabulary-search-errors" "Word lookup errors" "If the parser cannot not find a word in the current vocabulary search path, it attempts to look for the word in all loaded vocabularies. Then, one of three things happen:" { $list { "If there are no words having this name at all, an error is thrown and parsing stops." } - { "If there is exactly one vocabulary having a word with this name, the vocabulary is automatically added to the search path. This behavior is intended for interactive use and exploratory programming only, and production code should contain full " { $link POSTPONE: USING: } " declarations." } - { "If there is more than one vocabulary which contains a word with this name, a restartable error is thrown, with a restart for each vocabulary in question. The restarts add the vocabulary to the search path and continue parsing." } + { "If there are vocabularies which contain words with this name, a restartable error is thrown, with a restart for each vocabulary in question. The restarts add the vocabulary to the search path and continue parsing." } } "When writing a new vocabulary, one approach is to ignore " { $link POSTPONE: USING: } " declarations altogether, then to load the vocabulary and observe any parser notes and restarts and use this information to write the correct " { $link POSTPONE: USING: } " declaration." ; From e2ebe78915389fcff6eb54715ee66c3354b900ff Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 20:39:44 -0500 Subject: [PATCH 46/78] Faster bootstrap --- core/bootstrap/stage2.factor | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/bootstrap/stage2.factor b/core/bootstrap/stage2.factor index f9c738a8d0..d035744cd0 100755 --- a/core/bootstrap/stage2.factor +++ b/core/bootstrap/stage2.factor @@ -48,7 +48,11 @@ IN: bootstrap.stage2 "Compiling remaining words..." print flush - all-words [ compiled? not ] subset recompile-hook get call + "bootstrap.compiler" vocab [ + vocabs [ + words "compile" "compiler" lookup execute + ] each + ] when ] with-compiler-errors f error set-global From cc9646c80d0611d860e8cdcc60f4be9837a23bb5 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 21 Jan 2008 20:39:49 -0500 Subject: [PATCH 47/78] Fix typo --- extra/io/nonblocking/nonblocking-docs.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/io/nonblocking/nonblocking-docs.factor b/extra/io/nonblocking/nonblocking-docs.factor index d0d5818bee..d6d619229f 100644 --- a/extra/io/nonblocking/nonblocking-docs.factor +++ b/extra/io/nonblocking/nonblocking-docs.factor @@ -1,5 +1,5 @@ USING: io io.buffers io.backend help.markup help.syntax kernel -strings sbufs ; +strings sbufs words ; IN: io.nonblocking ARTICLE: "io.nonblocking" "Non-blocking I/O implementation" From 62415768cad61332ea1768e3bb6ee6a1405807dc Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Mon, 21 Jan 2008 22:36:20 -0500 Subject: [PATCH 48/78] Minor tweak to math.text.english --- extra/math/text/english/english.factor | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extra/math/text/english/english.factor b/extra/math/text/english/english.factor index a6179382bd..645d7e2054 100644 --- a/extra/math/text/english/english.factor +++ b/extra/math/text/english/english.factor @@ -12,10 +12,10 @@ IN: math.text.english "Seventeen" "Eighteen" "Nineteen" } nth ; : tens ( n -- str ) - { "" "" "Twenty" "Thirty" "Forty" "Fifty" "Sixty" "Seventy" "Eighty" "Ninety" } nth ; + { f f "Twenty" "Thirty" "Forty" "Fifty" "Sixty" "Seventy" "Eighty" "Ninety" } nth ; : scale-numbers ( n -- str ) ! up to 10^99 - { "" "Thousand" "Million" "Billion" "Trillion" "Quadrillion" "Quintillion" + { f "Thousand" "Million" "Billion" "Trillion" "Quadrillion" "Quintillion" "Sextillion" "Septillion" "Octillion" "Nonillion" "Decillion" "Undecillion" "Duodecillion" "Tredecillion" "Quattuordecillion" "Quindecillion" "Sexdecillion" "Septendecillion" "Octodecillion" "Novemdecillion" @@ -45,7 +45,7 @@ SYMBOL: and-needed? : tens-place ( n -- str ) 100 mod dup 20 >= [ - 10 /mod >r tens r> + 10 /mod [ tens ] dip dup zero? [ drop ] [ "-" swap small-numbers 3append ] if ] [ dup zero? [ drop "" ] [ small-numbers ] if @@ -97,3 +97,4 @@ PRIVATE> ] [ [ (number>text) ] with-scope ] if ; + From 7fbee3e810fc8598f899ca74c198461270f91450 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Tue, 22 Jan 2008 00:08:27 -0500 Subject: [PATCH 49/78] Solutions to Project Euler problem 32 --- extra/project-euler/032/032.factor | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 extra/project-euler/032/032.factor diff --git a/extra/project-euler/032/032.factor b/extra/project-euler/032/032.factor new file mode 100644 index 0000000000..f4d5704e21 --- /dev/null +++ b/extra/project-euler/032/032.factor @@ -0,0 +1,81 @@ +! Copyright (c) 2007 Aaron Schaefer. +! See http://factorcode.org/license.txt for BSD license. +USING: combinators.lib hashtables kernel math math.combinatorics math.parser + math.ranges project-euler.common project-euler.024 sequences sorting ; +IN: project-euler.032 + +! http://projecteuler.net/index.php?section=problems&id=32 + +! DESCRIPTION +! ----------- + +! The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing +! multiplicand, multiplier, and product is 1 through 9 pandigital. + +! Find the sum of all products whose multiplicand/multiplier/product identity +! can be written as a 1 through 9 pandigital. + +! HINT: Some products can be obtained in more than one way so be sure to only +! include it once in your sum. + + +! SOLUTION +! -------- + +! Generate all pandigital numbers and then check if they fit the identity + +integer ] map ; + +: 1and4 ( n -- ? ) + number>string 1 cut-slice 4 cut-slice + [ 10 string>integer ] 3apply [ * ] dip = ; + +: 2and3 ( n -- ? ) + number>string 2 cut-slice 3 cut-slice + [ 10 string>integer ] 3apply [ * ] dip = ; + +: valid? ( n -- ? ) + dup 1and4 swap 2and3 or ; + +: products ( seq -- m ) + [ number>string 4 tail* 10 string>integer ] map ; + +PRIVATE> + +: euler032 ( -- answer ) + source-032 [ valid? ] subset products prune sum ; + +! [ euler032 ] 10 ave-time +! 27609 ms run / 2484 ms GC ave time - 10 trials + + +! ALTERNATE SOLUTIONS +! ------------------- + +! Generate all reasonable multiplicand/multiplier pairs, then multiply and see +! if the equation is pandigital + +string natural-sort "123456789" = ; + +! multiplicand/multiplier/product +: mmp ( pair -- n ) + first2 2dup * [ number>string ] 3apply 3append 10 string>integer ; + +PRIVATE> + +: euler032a ( -- answer ) + source-032a [ mmp ] map [ pandigital? ] subset products prune sum ; + +! [ euler032a ] 100 ave-time +! 5978 ms run / 327 ms GC ave time - 100 trials + +MAIN: euler032a From cd92504288148cf80310bd553372bf9421d4a2c7 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Tue, 22 Jan 2008 17:02:02 -0500 Subject: [PATCH 50/78] Fix copyright date on PE solutions after the new year --- extra/project-euler/023/023.factor | 2 +- extra/project-euler/024/024.factor | 2 +- extra/project-euler/025/025.factor | 2 +- extra/project-euler/026/026.factor | 2 +- extra/project-euler/027/027.factor | 2 +- extra/project-euler/028/028.factor | 2 +- extra/project-euler/029/029.factor | 2 +- extra/project-euler/030/030.factor | 2 +- extra/project-euler/031/031.factor | 2 +- extra/project-euler/032/032.factor | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extra/project-euler/023/023.factor b/extra/project-euler/023/023.factor index 06f6555ea3..526bb4c446 100644 --- a/extra/project-euler/023/023.factor +++ b/extra/project-euler/023/023.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: hashtables kernel math math.ranges project-euler.common sequences sorting ; diff --git a/extra/project-euler/024/024.factor b/extra/project-euler/024/024.factor index 44434b4a88..230aea02b9 100644 --- a/extra/project-euler/024/024.factor +++ b/extra/project-euler/024/024.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.parser math.ranges namespaces sequences ; IN: project-euler.024 diff --git a/extra/project-euler/025/025.factor b/extra/project-euler/025/025.factor index 2819e210a7..4eed8b55cb 100644 --- a/extra/project-euler/025/025.factor +++ b/extra/project-euler/025/025.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: alien.syntax kernel math math.functions math.parser math.ranges memoize project-euler.common sequences ; diff --git a/extra/project-euler/026/026.factor b/extra/project-euler/026/026.factor index d79effed02..3ad1908aa6 100644 --- a/extra/project-euler/026/026.factor +++ b/extra/project-euler/026/026.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.functions math.primes math.ranges sequences ; IN: project-euler.026 diff --git a/extra/project-euler/027/027.factor b/extra/project-euler/027/027.factor index c208caaf9e..2bc7894684 100644 --- a/extra/project-euler/027/027.factor +++ b/extra/project-euler/027/027.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.primes project-euler.common sequences ; IN: project-euler.027 diff --git a/extra/project-euler/028/028.factor b/extra/project-euler/028/028.factor index 5d20032ea9..c8ac19ef82 100644 --- a/extra/project-euler/028/028.factor +++ b/extra/project-euler/028/028.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib kernel math math.ranges ; IN: project-euler.028 diff --git a/extra/project-euler/029/029.factor b/extra/project-euler/029/029.factor index 47855c0bf1..459a3a4bd6 100644 --- a/extra/project-euler/029/029.factor +++ b/extra/project-euler/029/029.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: hashtables kernel math.functions math.ranges project-euler.common sequences ; diff --git a/extra/project-euler/030/030.factor b/extra/project-euler/030/030.factor index 854b7ca5ca..22d05524b2 100644 --- a/extra/project-euler/030/030.factor +++ b/extra/project-euler/030/030.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib kernel math math.functions project-euler.common sequences ; IN: project-euler.030 diff --git a/extra/project-euler/031/031.factor b/extra/project-euler/031/031.factor index b4402d8904..4be866dc03 100644 --- a/extra/project-euler/031/031.factor +++ b/extra/project-euler/031/031.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math ; IN: project-euler.031 diff --git a/extra/project-euler/032/032.factor b/extra/project-euler/032/032.factor index f4d5704e21..67a8befb0a 100644 --- a/extra/project-euler/032/032.factor +++ b/extra/project-euler/032/032.factor @@ -1,4 +1,4 @@ -! Copyright (c) 2007 Aaron Schaefer. +! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib hashtables kernel math math.combinatorics math.parser math.ranges project-euler.common project-euler.024 sequences sorting ; From 817dfbfbbe18e67da2ee361fc1045e862b1aa34b Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Tue, 22 Jan 2008 17:17:04 -0500 Subject: [PATCH 51/78] Add summary for Miller-Rabin vocab, and cleanup tests --- extra/math/miller-rabin/miller-rabin-tests.factor | 4 ++-- extra/math/miller-rabin/summary.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 extra/math/miller-rabin/summary.txt diff --git a/extra/math/miller-rabin/miller-rabin-tests.factor b/extra/math/miller-rabin/miller-rabin-tests.factor index 42e4164ef3..f8bc9d4970 100644 --- a/extra/math/miller-rabin/miller-rabin-tests.factor +++ b/extra/math/miller-rabin/miller-rabin-tests.factor @@ -1,4 +1,5 @@ -USING: math.miller-rabin kernel math namespaces tools.test ; +USING: math.miller-rabin tools.test ; +IN: temporary [ f ] [ 473155932665450549999756893736999469773678960651272093993257221235459777950185377130233556540099119926369437865330559863 miller-rabin ] unit-test [ t ] [ 2 miller-rabin ] unit-test @@ -7,4 +8,3 @@ USING: math.miller-rabin kernel math namespaces tools.test ; [ t ] [ 37 miller-rabin ] unit-test [ 101 ] [ 100 next-prime ] unit-test [ 100000000000031 ] [ 100000000000000 next-prime ] unit-test - diff --git a/extra/math/miller-rabin/summary.txt b/extra/math/miller-rabin/summary.txt new file mode 100644 index 0000000000..b2591a3182 --- /dev/null +++ b/extra/math/miller-rabin/summary.txt @@ -0,0 +1 @@ +Miller-Rabin probabilistic primality test From cf670bd2348fa84cdd51d94de9b67e54a514a0b1 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Tue, 22 Jan 2008 17:37:54 -0500 Subject: [PATCH 52/78] Add summary for math.text --- extra/math/text/summary.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 extra/math/text/summary.txt diff --git a/extra/math/text/summary.txt b/extra/math/text/summary.txt new file mode 100644 index 0000000000..95dc6939e2 --- /dev/null +++ b/extra/math/text/summary.txt @@ -0,0 +1 @@ +Convert integers to text in multiple languages From 157043ad199b75d5b09b98fd56bf7519e95a2572 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 23 Jan 2008 02:45:55 -0400 Subject: [PATCH 53/78] Minor I/O backend tweak --- core/io/backend/backend.factor | 3 +++ extra/bootstrap/io/io.factor | 3 --- extra/io/unix/bsd/bsd.factor | 2 +- extra/io/unix/linux/linux.factor | 2 +- extra/io/windows/ce/ce.factor | 2 +- extra/io/windows/nt/nt.factor | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) mode change 100644 => 100755 core/io/backend/backend.factor mode change 100644 => 100755 extra/io/unix/bsd/bsd.factor mode change 100644 => 100755 extra/io/unix/linux/linux.factor diff --git a/core/io/backend/backend.factor b/core/io/backend/backend.factor old mode 100644 new mode 100755 index a7736ae47e..6d0a6d5ec5 --- a/core/io/backend/backend.factor +++ b/core/io/backend/backend.factor @@ -21,3 +21,6 @@ M: object normalize-pathname ; [ init-io embedded? [ init-stdio ] unless ] "io.backend" add-init-hook + +: set-io-backend ( backend -- ) + io-backend set-global init-io init-stdio ; diff --git a/extra/bootstrap/io/io.factor b/extra/bootstrap/io/io.factor index 238a971e67..065f7dd5c4 100755 --- a/extra/bootstrap/io/io.factor +++ b/extra/bootstrap/io/io.factor @@ -10,6 +10,3 @@ IN: bootstrap.io { [ wince? ] [ "windows.ce" ] } } cond append require ] when - -init-io -init-stdio diff --git a/extra/io/unix/bsd/bsd.factor b/extra/io/unix/bsd/bsd.factor old mode 100644 new mode 100755 index 8ed84dc305..39eb8b6fb9 --- a/extra/io/unix/bsd/bsd.factor +++ b/extra/io/unix/bsd/bsd.factor @@ -26,4 +26,4 @@ M: bsd-io init-io ( -- ) M: bsd-io wait-for-process ( pid -- status ) [ kqueue-mx get-global add-pid-task stop ] curry callcc1 ; -T{ bsd-io } io-backend set-global +T{ bsd-io } set-io-backend diff --git a/extra/io/unix/linux/linux.factor b/extra/io/unix/linux/linux.factor old mode 100644 new mode 100755 index 180e81e30a..34afc16246 --- a/extra/io/unix/linux/linux.factor +++ b/extra/io/unix/linux/linux.factor @@ -14,4 +14,4 @@ M: linux-io init-io ( -- ) M: linux-io wait-for-pid ( pid -- status ) [ kqueue-mx get-global add-pid-task stop ] curry callcc1 ; -T{ linux-io } io-backend set-global +T{ linux-io } set-io-backend diff --git a/extra/io/windows/ce/ce.factor b/extra/io/windows/ce/ce.factor index 9fb0d700d9..a5e0cb6b4a 100755 --- a/extra/io/windows/ce/ce.factor +++ b/extra/io/windows/ce/ce.factor @@ -3,4 +3,4 @@ io.windows.ce.files io.windows.ce.sockets io.windows.ce.launcher namespaces io.windows.mmap ; IN: io.windows.ce -T{ windows-ce-io } io-backend set-global +T{ windows-ce-io } set-io-backend diff --git a/extra/io/windows/nt/nt.factor b/extra/io/windows/nt/nt.factor index 9ec97b33c6..000d1362b6 100755 --- a/extra/io/windows/nt/nt.factor +++ b/extra/io/windows/nt/nt.factor @@ -9,4 +9,4 @@ USE: io.windows.mmap USE: io.backend USE: namespaces -T{ windows-nt-io } io-backend set-global +T{ windows-nt-io } set-io-backend From 81c5b413f489337abf9ea4255d21d4a0ccf23328 Mon Sep 17 00:00:00 2001 From: Slava Date: Wed, 23 Jan 2008 01:49:01 -0500 Subject: [PATCH 54/78] Working on epoll --- extra/io/unix/epoll/epoll.factor | 23 +++++++++++++---------- extra/io/unix/linux/linux.factor | 11 ++++++----- extra/io/unix/unix.factor | 4 ++-- extra/unix/linux/epoll/epoll.factor | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/extra/io/unix/epoll/epoll.factor b/extra/io/unix/epoll/epoll.factor index f2230f6e81..f0280aac78 100644 --- a/extra/io/unix/epoll/epoll.factor +++ b/extra/io/unix/epoll/epoll.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types kernel io.nonblocking io.unix.backend -bit-arrays sequences assocs unix math namespaces structs ; +bit-arrays sequences assocs unix unix.linux.epoll math +namespaces structs ; IN: io.unix.epoll TUPLE: epoll-mx events ; @@ -18,17 +19,17 @@ TUPLE: epoll-mx events ; GENERIC: io-task-events ( task -- n ) -M: input-task drop EPOLLIN ; +M: input-task io-task-events drop EPOLLIN ; -M: output-task drop EPOLLOUT ; +M: output-task io-task-events drop EPOLLOUT ; : make-event ( task -- event ) "epoll-event" over io-task-events over set-epoll-event-events - over io-task-fd over set-epoll-fd ; + swap io-task-fd over set-epoll-event-fd ; : do-epoll-ctl ( task mx what -- ) - >r >r make-event r> mx-fd r> pick event-data *int roll + >r >r make-event r> mx-fd r> pick epoll-event-fd roll epoll_ctl io-error ; M: epoll-mx register-io-task ( task mx -- ) @@ -37,9 +38,9 @@ M: epoll-mx register-io-task ( task mx -- ) M: epoll-mx unregister-io-task ( task mx -- ) EPOLL_CTL_DEL do-epoll-ctl ; -: wait-kevent ( mx timeout -- n ) - >r mx-fd epoll-mx-events max-events r> epoll_wait - dup multiplexer-error ; +: wait-event ( mx timeout -- n ) + >r { mx-fd epoll-mx-events } get-slots max-events + r> epoll_wait dup multiplexer-error ; : epoll-read-task ( mx fd -- ) over mx-reads at* [ handle-io-task ] [ 2drop ] if ; @@ -51,7 +52,9 @@ M: epoll-mx unregister-io-task ( task mx -- ) epoll-event-fd 2dup epoll-read-task epoll-write-task ; : handle-events ( mx n -- ) - [ over epoll-mx-events kevent-nth handle-kevent ] with each ; + [ + over epoll-mx-events epoll-event-nth handle-event + ] with each ; M: epoll-mx wait-for-events ( ms mx -- ) - dup rot wait-kevent handle-kevents ; + dup rot wait-event handle-events ; diff --git a/extra/io/unix/linux/linux.factor b/extra/io/unix/linux/linux.factor index 180e81e30a..919fba8d5d 100644 --- a/extra/io/unix/linux/linux.factor +++ b/extra/io/unix/linux/linux.factor @@ -1,17 +1,18 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: io.unix.linux -USING: io.unix.backend io.unix.select namespaces kernel assocs ; +USING: io.backend io.unix.backend io.unix.launcher io.unix.epoll +namespaces kernel assocs unix.process ; TUPLE: linux-io ; INSTANCE: linux-io unix-io M: linux-io init-io ( -- ) - start-wait-loop - mx set-global ; + mx set-global + start-wait-loop ; -M: linux-io wait-for-pid ( pid -- status ) - [ kqueue-mx get-global add-pid-task stop ] curry callcc1 ; +M: linux-io wait-for-process ( pid -- status ) + wait-for-pid ; T{ linux-io } io-backend set-global diff --git a/extra/io/unix/unix.factor b/extra/io/unix/unix.factor index d6d0a9cc22..7dc66a05ad 100755 --- a/extra/io/unix/unix.factor +++ b/extra/io/unix/unix.factor @@ -5,6 +5,6 @@ system vocabs.loader ; { { [ bsd? ] [ "io.unix.bsd" ] } { [ macosx? ] [ "io.unix.bsd" ] } - { [ linux? ] [ "io.unix.backend.linux" ] } - { [ solaris? ] [ "io.unix.backend.solaris" ] } + { [ linux? ] [ "io.unix.linux" ] } + { [ solaris? ] [ "io.unix.solaris" ] } } cond require diff --git a/extra/unix/linux/epoll/epoll.factor b/extra/unix/linux/epoll/epoll.factor index 946c387acc..6606c11568 100644 --- a/extra/unix/linux/epoll/epoll.factor +++ b/extra/unix/linux/epoll/epoll.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: unix.linux.epoll -USING: alien.syntax ; +USING: alien.syntax math ; FUNCTION: int epoll_create ( int size ) ; From 09eb56d0c2975a1f5182d721f200536f402f48fd Mon Sep 17 00:00:00 2001 From: Slava Date: Wed, 23 Jan 2008 03:07:15 -0500 Subject: [PATCH 55/78] epoll almost works --- core/io/backend/backend.factor | 4 ++-- extra/io/unix/epoll/epoll.factor | 8 +++++--- extra/io/unix/linux/linux.factor | 2 +- extra/unix/linux/epoll/epoll.factor | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/core/io/backend/backend.factor b/core/io/backend/backend.factor index 6d0a6d5ec5..9aa1299871 100755 --- a/core/io/backend/backend.factor +++ b/core/io/backend/backend.factor @@ -1,6 +1,6 @@ -! Copyright (C) 2007 Slava Pestov. +! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: init kernel system ; +USING: init kernel system namespaces ; IN: io.backend SYMBOL: io-backend diff --git a/extra/io/unix/epoll/epoll.factor b/extra/io/unix/epoll/epoll.factor index f0280aac78..1459549f9e 100644 --- a/extra/io/unix/epoll/epoll.factor +++ b/extra/io/unix/epoll/epoll.factor @@ -29,13 +29,15 @@ M: output-task io-task-events drop EPOLLOUT ; swap io-task-fd over set-epoll-event-fd ; : do-epoll-ctl ( task mx what -- ) - >r >r make-event r> mx-fd r> pick epoll-event-fd roll + >r mx-fd r> rot dup io-task-fd swap make-event epoll_ctl io-error ; M: epoll-mx register-io-task ( task mx -- ) - EPOLL_CTL_ADD do-epoll-ctl ; + 2dup EPOLL_CTL_ADD do-epoll-ctl + delegate register-io-task ; M: epoll-mx unregister-io-task ( task mx -- ) + 2dup delegate unregister-io-task EPOLL_CTL_DEL do-epoll-ctl ; : wait-event ( mx timeout -- n ) @@ -46,7 +48,7 @@ M: epoll-mx unregister-io-task ( task mx -- ) over mx-reads at* [ handle-io-task ] [ 2drop ] if ; : epoll-write-task ( mx fd -- ) - over mx-reads at* [ handle-io-task ] [ 2drop ] if ; + over mx-writes at* [ handle-io-task ] [ 2drop ] if ; : handle-event ( mx kevent -- ) epoll-event-fd 2dup epoll-read-task epoll-write-task ; diff --git a/extra/io/unix/linux/linux.factor b/extra/io/unix/linux/linux.factor index bd1d166252..56032ad019 100755 --- a/extra/io/unix/linux/linux.factor +++ b/extra/io/unix/linux/linux.factor @@ -15,4 +15,4 @@ M: linux-io init-io ( -- ) M: linux-io wait-for-process ( pid -- status ) wait-for-pid ; -T{ linux-io } set-io-backend +T{ linux-io } io-backend set-global ! set-io-backend diff --git a/extra/unix/linux/epoll/epoll.factor b/extra/unix/linux/epoll/epoll.factor index 6606c11568..c18fa2ee6c 100644 --- a/extra/unix/linux/epoll/epoll.factor +++ b/extra/unix/linux/epoll/epoll.factor @@ -9,7 +9,8 @@ FUNCTION: int epoll_ctl ( int epfd, int op, int fd, epoll_event* event ) ; C-STRUCT: epoll-event { "uint" "events" } - { "uint" "fd" } ; + { "uint" "fd" } + { "uint" "padding" } ; FUNCTION: int epoll_wait ( int epfd, epoll_event* events, int maxevents, int timeout ) ; From 42e97d4629fef0610c6fed0198ea6295f168962f Mon Sep 17 00:00:00 2001 From: Slava Date: Wed, 23 Jan 2008 03:30:16 -0500 Subject: [PATCH 56/78] epoll works but not for files; disable it for now --- extra/io/unix/linux/linux.factor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extra/io/unix/linux/linux.factor b/extra/io/unix/linux/linux.factor index 56032ad019..06380c7e1e 100755 --- a/extra/io/unix/linux/linux.factor +++ b/extra/io/unix/linux/linux.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: io.unix.linux -USING: io.backend io.unix.backend io.unix.launcher io.unix.epoll +USING: io.backend io.unix.backend io.unix.launcher io.unix.select namespaces kernel assocs unix.process ; TUPLE: linux-io ; @@ -9,10 +9,10 @@ TUPLE: linux-io ; INSTANCE: linux-io unix-io M: linux-io init-io ( -- ) - mx set-global + mx set-global start-wait-loop ; M: linux-io wait-for-process ( pid -- status ) wait-for-pid ; -T{ linux-io } io-backend set-global ! set-io-backend +T{ linux-io } set-io-backend From bc5bc22072f8c1833e82f4631c8ef601e972a183 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 23 Jan 2008 06:31:30 -0400 Subject: [PATCH 57/78] Better dlists behavior --- core/dlists/dlists.factor | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core/dlists/dlists.factor b/core/dlists/dlists.factor index a3c869efaf..84d68b28aa 100755 --- a/core/dlists/dlists.factor +++ b/core/dlists/dlists.factor @@ -78,7 +78,8 @@ PRIVATE> : pop-front ( dlist -- obj ) dup dlist-front [ - dlist-node-next + dup dlist-node-next + f rot set-dlist-node-next f over set-prev-when swap set-dlist-front ] 2keep dlist-node-obj @@ -87,13 +88,13 @@ PRIVATE> : pop-front* ( dlist -- ) pop-front drop ; : pop-back ( dlist -- obj ) - [ - dlist-back dup dlist-node-prev f over set-next-when - ] keep - [ set-dlist-back ] keep - [ normalize-front ] keep - dec-length - dlist-node-obj ; + dup dlist-back [ + dup dlist-node-prev + f rot set-dlist-node-prev + f over set-next-when + swap set-dlist-back + ] 2keep dlist-node-obj + swap [ normalize-front ] keep dec-length ; : pop-back* ( dlist -- ) pop-back drop ; From 83d6e10ac030d98f65284b71b373f04ae0d867ed Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 23 Jan 2008 06:32:51 -0400 Subject: [PATCH 58/78] Fix resolver on FreeBSD --- extra/io/sockets/impl/impl.factor | 33 ++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/extra/io/sockets/impl/impl.factor b/extra/io/sockets/impl/impl.factor index e490b9312b..e8ab957482 100755 --- a/extra/io/sockets/impl/impl.factor +++ b/extra/io/sockets/impl/impl.factor @@ -51,10 +51,13 @@ M: inet4 make-sockaddr ( inet -- sockaddr ) "0.0.0.0" or rot inet-pton *uint over set-sockaddr-in-addr ; +SYMBOL: port-override + +: (port) port-override get [ ] [ ] ?if ; + M: inet4 parse-sockaddr >r dup sockaddr-in-addr r> inet-ntop - swap sockaddr-in-port ntohs ; - + swap sockaddr-in-port ntohs (port) ; M: inet6 inet-ntop ( data addrspec -- str ) drop 16 memory>string 2 [ be> >hex ] map ":" join ; @@ -80,7 +83,7 @@ M: inet6 make-sockaddr ( inet -- sockaddr ) M: inet6 parse-sockaddr >r dup sockaddr-in6-addr r> inet-ntop - swap sockaddr-in6-port ntohs ; + swap sockaddr-in6-port ntohs (port) ; : addrspec-of-family ( af -- addrspec ) { @@ -102,15 +105,23 @@ M: f parse-sockaddr nip ; [ dup addrinfo-next swap addrinfo>addrspec ] [ ] unfold nip [ ] subset ; +: prepare-resolve-host ( host serv passive? -- host' serv' flags ) + >r + >r string>char-alien r> + dup integer? [ port-override set f ] [ string>char-alien ] if + r> AI_PASSIVE 0 ? ; + M: object resolve-host ( host serv passive? -- seq ) - >r dup integer? [ number>string ] when - "addrinfo" - r> [ AI_PASSIVE over set-addrinfo-flags ] when - PF_UNSPEC over set-addrinfo-family - IPPROTO_TCP over set-addrinfo-protocol - f [ getaddrinfo addrinfo-error ] keep *void* - [ parse-addrinfo-list ] keep - freeaddrinfo ; + [ + prepare-resolve-host + "addrinfo" + [ set-addrinfo-flags ] keep + PF_UNSPEC over set-addrinfo-family + IPPROTO_TCP over set-addrinfo-protocol + f [ getaddrinfo addrinfo-error ] keep *void* + [ parse-addrinfo-list ] keep + freeaddrinfo + ] with-scope ; M: object host-name ( -- name ) 256 dup dup length gethostname From ecc0170afab550777f005235e24a8d2deeb1f878 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 03:20:05 -0400 Subject: [PATCH 59/78] Forgetting a word clears compiled usage --- core/compiler/compiler.factor | 17 +---------------- core/compiler/test/redefine.factor | 11 ++++++++++- core/words/words.factor | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/core/compiler/compiler.factor b/core/compiler/compiler.factor index 784104d57f..8d9f004270 100755 --- a/core/compiler/compiler.factor +++ b/core/compiler/compiler.factor @@ -7,21 +7,6 @@ optimizer definitions math compiler.errors threads graphs generic ; IN: compiler -SYMBOL: compiled-crossref - -compiled-crossref global [ H{ } assoc-like ] change-at - -: compiled-xref ( word dependencies -- ) - 2dup "compiled-uses" set-word-prop - compiled-crossref get add-vertex* ; - -: compiled-unxref ( word -- ) - dup "compiled-uses" word-prop - compiled-crossref get remove-vertex* ; - -: compiled-usage ( word -- assoc ) - compiled-crossref get at ; - : compiled-usages ( words -- seq ) [ [ dup ] H{ } map>assoc dup ] keep [ compiled-usage [ nip +inlined+ eq? ] assoc-subset update @@ -41,7 +26,7 @@ compiled-crossref global [ H{ } assoc-like ] change-at >r dupd save-effect r> f pick compiler-error over compiled-unxref - compiled-xref ; + over word-vocabulary [ compiled-xref ] [ 2drop ] if ; : compile-succeeded ( word -- effect dependencies ) [ diff --git a/core/compiler/test/redefine.factor b/core/compiler/test/redefine.factor index 718e98c9c2..266b331ffc 100755 --- a/core/compiler/test/redefine.factor +++ b/core/compiler/test/redefine.factor @@ -1,6 +1,6 @@ USING: compiler definitions generic assocs inference math namespaces parser tools.test words kernel sequences arrays io -effects tools.test.inference compiler.units ; +effects tools.test.inference compiler.units inference.state ; IN: temporary DEFER: x-1 @@ -206,12 +206,15 @@ DEFER: generic-then-not-generic-test-2 [ 4 ] [ generic-then-not-generic-test-2 ] unit-test +DEFER: foldable-test-1 DEFER: foldable-test-2 [ ] [ "IN: temporary : foldable-test-1 3 ; foldable" eval ] unit-test [ ] [ "IN: temporary : foldable-test-2 foldable-test-1 ;" eval ] unit-test +[ +inlined+ ] [ \ foldable-test-2 \ foldable-test-1 compiled-usage at ] unit-test + [ 3 ] [ foldable-test-2 ] unit-test [ ] [ "IN: temporary : foldable-test-1 4 ; foldable" eval ] unit-test @@ -229,3 +232,9 @@ DEFER: flushable-test-2 [ ] [ "IN: temporary USING: kernel sequences ; : flushable-test-1 3 over push ;" eval ] unit-test [ V{ 3 } ] [ flushable-test-2 ] unit-test + +: ax ; +: bx ax ; +[ \ bx forget ] with-compilation-unit + +[ t ] [ \ ax compiled-usage [ drop interned? ] assoc-all? ] unit-test diff --git a/core/words/words.factor b/core/words/words.factor index 6d8bad4f9e..5dc89212a8 100755 --- a/core/words/words.factor +++ b/core/words/words.factor @@ -87,6 +87,25 @@ M: wrapper (quot-uses) >r wrapped r> (quot-uses) ; M: word uses ( word -- seq ) word-def quot-uses keys ; +SYMBOL: compiled-crossref + +compiled-crossref global [ H{ } assoc-like ] change-at + +: compiled-xref ( word dependencies -- ) + 2dup "compiled-uses" set-word-prop + compiled-crossref get add-vertex* ; + +: compiled-unxref ( word -- ) + dup "compiled-uses" word-prop + compiled-crossref get remove-vertex* ; + +: delete-compiled-xref ( word -- ) + dup compiled-unxref + compiled-crossref get delete-at ; + +: compiled-usage ( word -- assoc ) + compiled-crossref get at ; + M: word redefined* ( word -- ) { "inferred-effect" "base-case" "no-effect" } reset-props ; @@ -187,6 +206,7 @@ M: word (forget-word) : forget-word ( word -- ) dup delete-xref + dup delete-compiled-xref (forget-word) ; M: word forget* forget-word ; From af915caaa358ba74282f1f42997b206517723864 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 03:27:15 -0400 Subject: [PATCH 60/78] Add wait-for-process word to io.launcher; run-process and run-detached now return process tuples --- extra/io/launcher/launcher-docs.factor | 40 +++++++++--- extra/io/launcher/launcher.factor | 43 ++++++++++--- extra/io/windows/launcher/launcher.factor | 66 +++++++++++++++----- extra/io/windows/nt/launcher/launcher.factor | 2 +- extra/windows/kernel32/kernel32.factor | 4 +- 5 files changed, 118 insertions(+), 37 deletions(-) diff --git a/extra/io/launcher/launcher-docs.factor b/extra/io/launcher/launcher-docs.factor index 7ad5e064bf..2c30431714 100755 --- a/extra/io/launcher/launcher-docs.factor +++ b/extra/io/launcher/launcher-docs.factor @@ -1,6 +1,6 @@ -! Copyright (C) 2007 Slava Pestov. +! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: help.markup help.syntax quotations kernel ; +USING: help.markup help.syntax quotations kernel io math ; IN: io.launcher HELP: +command+ @@ -58,7 +58,7 @@ HELP: get-environment { $description "Combines the current environment with the value of " { $link +environment+ } " using " { $link +environment-mode+ } "." } ; HELP: run-process* -{ $values { "desc" "a launch descriptor" } } +{ $values { "desc" "a launch descriptor" } { "handle" "a process handle" } } { $contract "Launches a process using the launch descriptor." } { $notes "User code should call " { $link run-process } " instead." } ; @@ -73,22 +73,41 @@ HELP: >descriptor } ; HELP: run-process -{ $values { "obj" object } } -{ $contract "Launches a process. The object can either be a string, a sequence of strings or a launch descriptor. See " { $link >descriptor } " for details." } ; +{ $values { "obj" object } { "process" process } } +{ $description "Launches a process. The object can either be a string, a sequence of strings or a launch descriptor. See " { $link >descriptor } " for details." } +{ $notes "The output value can be passed to " { $link wait-for-process } " to get an exit code." } ; HELP: run-detached -{ $values { "obj" object } } +{ $values { "obj" object } { "process" process } } { $contract "Launches a process without waiting for it to complete. The object can either be a string, a sequence of strings or a launch descriptor. See " { $link >descriptor } " for details." } { $notes "This word is functionally identical to passing a launch descriptor to " { $link run-process } " having the " { $link +detached+ } " key set." + $nl + "The output value can be passed to " { $link wait-for-process } " to get an exit code." } ; +HELP: process +{ $class-description "A class representing an active or finished process." +$nl +"Processes are output by " { $link run-process } " and " { $link run-detached } ", and are stored in the " { $link process-stream-process } " slot of " { $link process-stream } " instances." +$nl +"Processes can be passed to " { $link wait-for-process } "." } ; + +HELP: process-stream +{ $class-description "A bidirectional stream for interacting with a running process. Instances are created by calling " { $link } ". The " { $link process-stream-process } " slot holds a " { $link process } " instance." } ; + HELP: { $values { "obj" object } { "stream" "a bidirectional stream" } } { $description "Launches a process and redirects its input and output via a pair of pipes which may be read and written as a stream." } { $notes "Closing the stream will block until the process exits." } ; -{ run-process run-detached } related-words +HELP: with-process-stream +{ $values { "obj" object } { "quot" quotation } { "process" process } } +{ $description "Calls " { $snippet "quot" } " in a dynamic scope where " { $link stdio } " is rebound to a " { $link process-stream } ". When the quotation returns, the " { $link process } " instance is output." } ; + +HELP: wait-for-process +{ $values { "process" process } { "status" integer } } +{ $description "If the process is still running, waits for it to exit, otherwise outputs the exit code immediately. Can be called multiple times on the same process." } ; ARTICLE: "io.launcher" "Launching OS processes" "The " { $vocab-link "io.launcher" } " vocabulary implements cross-platform process launching." @@ -108,6 +127,11 @@ $nl "The following words are used to launch processes:" { $subsection run-process } { $subsection run-detached } -{ $subsection } ; +{ $subsection } +{ $subsection with-process-stream } +"A class representing an active or finished process:" +{ $subsection process } +"Waiting for a process to end, or getting the exit code of a finished process:" +{ $subsection wait-for-process } ; ABOUT: "io.launcher" diff --git a/extra/io/launcher/launcher.factor b/extra/io/launcher/launcher.factor index 806b56a092..decf4f3434 100755 --- a/extra/io/launcher/launcher.factor +++ b/extra/io/launcher/launcher.factor @@ -1,9 +1,17 @@ -! Copyright (C) 2007 Slava Pestov. +! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: io.backend system kernel namespaces strings hashtables +USING: io io.backend system kernel namespaces strings hashtables sequences assocs combinators vocabs.loader ; IN: io.launcher +TUPLE: process handle status ; + +: ( handle -- process ) f process construct-boa ; + +M: process equal? 2drop f ; + +M: process hashcode* process-handle hashcode* ; + SYMBOL: +command+ SYMBOL: +arguments+ SYMBOL: +detached+ @@ -44,15 +52,32 @@ M: string >descriptor +command+ associate ; M: sequence >descriptor +arguments+ associate ; M: assoc >descriptor ; -HOOK: run-process* io-backend ( desc -- ) +HOOK: run-process* io-backend ( desc -- handle ) -: run-process ( obj -- ) - >descriptor run-process* ; +HOOK: wait-for-process* io-backend ( process -- ) -: run-detached ( obj -- ) - >descriptor H{ { +detached+ t } } union run-process* ; +: wait-for-process ( process -- status ) + dup process-handle [ dup wait-for-process* ] when + process-status ; -HOOK: process-stream* io-backend ( desc -- stream ) +: run-process ( obj -- process ) + >descriptor + dup run-process* + +detached+ rot at [ dup wait-for-process drop ] unless ; + +: run-detached ( obj -- process ) + >descriptor H{ { +detached+ t } } union run-process ; + +HOOK: process-stream* io-backend ( desc -- stream process ) + +TUPLE: process-stream process ; : ( obj -- stream ) - >descriptor process-stream* ; + >descriptor process-stream* + { set-delegate set-process-stream-process } + process-stream construct ; + +: with-process-stream ( obj quot -- process ) + swap + [ swap with-stream ] keep + process-stream-process ; inline diff --git a/extra/io/windows/launcher/launcher.factor b/extra/io/windows/launcher/launcher.factor index 136c8197fc..603fa2a638 100755 --- a/extra/io/windows/launcher/launcher.factor +++ b/extra/io/windows/launcher/launcher.factor @@ -1,11 +1,19 @@ -! Copyright (C) 2007 Doug Coleman, Slava Pestov. +! Copyright (C) 2007, 2008 Doug Coleman, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types arrays continuations destructors io io.windows libc io.nonblocking io.streams.duplex windows.types math windows.kernel32 windows namespaces io.launcher kernel -sequences windows.errors assocs splitting system ; +sequences windows.errors assocs splitting system threads init ; IN: io.windows.launcher +SYMBOL: processes + +[ H{ } clone processes set-global ] +"io.windows.launcher" add-init-hook + +: ( handle -- process ) + V{ } clone over processes get set-at ; + TUPLE: CreateProcess-args lpApplicationName lpCommandLine @@ -19,13 +27,6 @@ TUPLE: CreateProcess-args lpProcessInformation stdout-pipe stdin-pipe ; -: dispose-CreateProcess-args ( args -- ) - #! From MSDN: "Handles in PROCESS_INFORMATION must be closed - #! with CloseHandle when they are no longer needed." - CreateProcess-args-lpProcessInformation dup - PROCESS_INFORMATION-hProcess [ CloseHandle drop ] when* - PROCESS_INFORMATION-hThread [ CloseHandle drop ] when* ; - : default-CreateProcess-args ( -- obj ) 0 0 @@ -93,21 +94,52 @@ TUPLE: CreateProcess-args over set-CreateProcess-args-lpEnvironment ] when ; -: wait-for-process ( args -- ) - CreateProcess-args-lpProcessInformation - PROCESS_INFORMATION-hProcess INFINITE - WaitForSingleObject drop ; - : make-CreateProcess-args ( -- args ) default-CreateProcess-args wince? [ fill-lpApplicationName ] [ fill-lpCommandLine ] if fill-dwCreateFlags fill-lpEnvironment ; -M: windows-io run-process* ( desc -- ) +M: windows-io run-process* ( desc -- handle ) [ make-CreateProcess-args dup call-CreateProcess - +detached+ get [ dup wait-for-process ] unless - dispose-CreateProcess-args + CreateProcess-args-lpProcessInformation ] with-descriptor ; + +M: windows-io wait-for-process* + [ processes get at push stop ] curry callcc0 ; + +: dispose-process ( process-information -- ) + #! From MSDN: "Handles in PROCESS_INFORMATION must be closed + #! with CloseHandle when they are no longer needed." + dup PROCESS_INFORMATION-hProcess [ CloseHandle drop ] when* + PROCESS_INFORMATION-hThread [ CloseHandle drop ] when* ; + +: exit-code ( process -- n ) + PROCESS_INFORMATION-hProcess + 0 [ GetExitCodeProcess ] keep *ulong + swap win32-error=0/f ; + +: notify-exit ( process -- ) + dup process-handle exit-code over set-process-status + dup process-handle dispose-process + dup processes get delete-at* drop [ schedule-thread ] each + f swap set-process-handle ; + +: wait-for-processes ( processes -- ? ) + keys dup + [ process-handle PROCESS_INFORMATION-hProcess ] map + dup length swap >c-void*-array 0 0 + WaitForMultipleObjects + dup HEX: ffffffff = [ win32-error ] when + dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth notify-exit f ] if ; + +: wait-loop ( -- ) + processes get dup assoc-empty? + [ drop t ] [ wait-for-processes ] if + [ 250 sleep ] when + wait-loop ; + +: start-wait-thread ( -- ) + [ wait-loop ] in-thread ; diff --git a/extra/io/windows/nt/launcher/launcher.factor b/extra/io/windows/nt/launcher/launcher.factor index 3ee0e05e32..6e788003ea 100755 --- a/extra/io/windows/nt/launcher/launcher.factor +++ b/extra/io/windows/nt/launcher/launcher.factor @@ -59,6 +59,6 @@ M: windows-io process-stream* dup CreateProcess-args-stdout-pipe pipe-in over CreateProcess-args-stdin-pipe pipe-out - swap dispose-CreateProcess-args + swap CreateProcess-args-lpProcessInformation ] with-destructors ] with-descriptor ; diff --git a/extra/windows/kernel32/kernel32.factor b/extra/windows/kernel32/kernel32.factor index 5e0f4ddc65..1c75e33698 100755 --- a/extra/windows/kernel32/kernel32.factor +++ b/extra/windows/kernel32/kernel32.factor @@ -898,7 +898,7 @@ FUNCTION: HANDLE GetCurrentThread ( ) ; ! FUNCTION: GetEnvironmentStringsW ! FUNCTION: GetEnvironmentVariableA ! FUNCTION: GetEnvironmentVariableW -! FUNCTION: GetExitCodeProcess +FUNCTION: BOOL GetExitCodeProcess ( HANDLE hProcess, LPDWORD lpExitCode ) ; ! FUNCTION: GetExitCodeThread ! FUNCTION: GetExpandedNameA ! FUNCTION: GetExpandedNameW @@ -1496,7 +1496,7 @@ FUNCTION: BOOL VirtualQueryEx ( HANDLE hProcess, void* lpAddress, MEMORY_BASIC_I ! FUNCTION: VirtualUnlock ! FUNCTION: WaitCommEvent ! FUNCTION: WaitForDebugEvent -! FUNCTION: WaitForMultipleObjects +FUNCTION: DWORD WaitForMultipleObjects ( DWORD nCount, HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds ) ; ! FUNCTION: WaitForMultipleObjectsEx FUNCTION: BOOL WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds ) ; ! FUNCTION: WaitForSingleObjectEx From d621b9852eb6ab3c2127da859f3ef4875c525942 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 03:50:40 -0400 Subject: [PATCH 61/78] Updating extra/ for launcher changes --- extra/editors/editpadpro/editpadpro.factor | 4 +++- extra/editors/editplus/editplus.factor | 4 ++-- extra/editors/emacs/emacs.factor | 7 +++++-- extra/editors/emeditor/emeditor.factor | 5 ++--- extra/editors/notepadpp/notepadpp.factor | 5 +++-- extra/editors/scite/scite.factor | 13 ++++++------- extra/editors/ted-notepad/ted-notepad.factor | 5 ++--- extra/editors/textmate/textmate.factor | 3 ++- extra/editors/ultraedit/ultraedit.factor | 4 ++-- extra/editors/vim/vim.factor | 8 +++++--- extra/editors/wordpad/wordpad.factor | 4 +--- extra/tools/deploy/macosx/macosx.factor | 4 ++-- 12 files changed, 35 insertions(+), 31 deletions(-) mode change 100644 => 100755 extra/editors/editpadpro/editpadpro.factor mode change 100644 => 100755 extra/editors/emacs/emacs.factor mode change 100644 => 100755 extra/editors/notepadpp/notepadpp.factor mode change 100644 => 100755 extra/editors/scite/scite.factor mode change 100644 => 100755 extra/editors/ted-notepad/ted-notepad.factor mode change 100644 => 100755 extra/editors/textmate/textmate.factor mode change 100644 => 100755 extra/editors/ultraedit/ultraedit.factor mode change 100644 => 100755 extra/editors/vim/vim.factor mode change 100644 => 100755 extra/editors/wordpad/wordpad.factor diff --git a/extra/editors/editpadpro/editpadpro.factor b/extra/editors/editpadpro/editpadpro.factor old mode 100644 new mode 100755 index 69a9e2badd..885349e27b --- a/extra/editors/editpadpro/editpadpro.factor +++ b/extra/editors/editpadpro/editpadpro.factor @@ -10,6 +10,8 @@ IN: editors.editpadpro ] unless* ; : editpadpro ( file line -- ) - [ editpadpro-path % " /l" % # " \"" % % "\"" % ] "" make run-detached ; + [ + editpadpro-path , "/l" swap number>string append , , + ] { } make run-detached drop ; [ editpadpro ] edit-hook set-global diff --git a/extra/editors/editplus/editplus.factor b/extra/editors/editplus/editplus.factor index bff523b50d..feaa177954 100755 --- a/extra/editors/editplus/editplus.factor +++ b/extra/editors/editplus/editplus.factor @@ -9,7 +9,7 @@ IN: editors.editplus : editplus ( file line -- ) [ - editplus-path % " -cursor " % # " " % % - ] "" make run-detached ; + editplus-path , "-cursor" , number>string , , + ] { } make run-detached drop ; [ editplus ] edit-hook set-global diff --git a/extra/editors/emacs/emacs.factor b/extra/editors/emacs/emacs.factor old mode 100644 new mode 100755 index e131179755..31e0761043 --- a/extra/editors/emacs/emacs.factor +++ b/extra/editors/emacs/emacs.factor @@ -4,8 +4,11 @@ IN: editors.emacs : emacsclient ( file line -- ) [ - "emacsclient --no-wait +" % # " " % % - ] "" make run-process ; + "emacsclient" , + "--no-wait" , + "+" swap number>string append , + , + ] { } make run-process drop ; : emacs ( word -- ) where first2 emacsclient ; diff --git a/extra/editors/emeditor/emeditor.factor b/extra/editors/emeditor/emeditor.factor index 2caa42b480..bed333694c 100755 --- a/extra/editors/emeditor/emeditor.factor +++ b/extra/editors/emeditor/emeditor.factor @@ -9,8 +9,7 @@ IN: editors.emeditor : emeditor ( file line -- ) [ - emeditor-path % " /l " % # - " " % "\"" % % "\"" % - ] "" make run-detached ; + emeditor-path , "/l" , number>string , , + ] { } make run-detached drop ; [ emeditor ] edit-hook set-global diff --git a/extra/editors/notepadpp/notepadpp.factor b/extra/editors/notepadpp/notepadpp.factor old mode 100644 new mode 100755 index 4f3fde917d..f9fa95f175 --- a/extra/editors/notepadpp/notepadpp.factor +++ b/extra/editors/notepadpp/notepadpp.factor @@ -9,7 +9,8 @@ IN: editors.notepadpp : notepadpp ( file line -- ) [ - notepadpp-path % " -n" % # " " % % - ] "" make run-detached ; + notepadpp-path , + "-n" swap number>string append , , + ] "" make run-detached drop ; [ notepadpp ] edit-hook set-global diff --git a/extra/editors/scite/scite.factor b/extra/editors/scite/scite.factor old mode 100644 new mode 100755 index 529d11b722..bc9a98a051 --- a/extra/editors/scite/scite.factor +++ b/extra/editors/scite/scite.factor @@ -18,14 +18,13 @@ SYMBOL: scite-path : scite-command ( file line -- cmd ) swap - [ scite-path get % - " \"" % - % - "\" -goto:" % - # - ] "" make ; + [ + scite-path get , + , + "-goto:" swap number>string append , + ] { } make ; : scite-location ( file line -- ) - scite-command run-detached ; + scite-command run-detached drop ; [ scite-location ] edit-hook set-global diff --git a/extra/editors/ted-notepad/ted-notepad.factor b/extra/editors/ted-notepad/ted-notepad.factor old mode 100644 new mode 100755 index b56ee0a08b..5d58e182a3 --- a/extra/editors/ted-notepad/ted-notepad.factor +++ b/extra/editors/ted-notepad/ted-notepad.factor @@ -9,8 +9,7 @@ IN: editors.ted-notepad : ted-notepad ( file line -- ) [ - ted-notepad-path % " /l" % # - " " % % - ] "" make run-detached ; + ted-notepad-path , "/l" swap number>string append , , + ] { } make run-detached drop ; [ ted-notepad ] edit-hook set-global diff --git a/extra/editors/textmate/textmate.factor b/extra/editors/textmate/textmate.factor old mode 100644 new mode 100755 index 18c7dbd07e..0145ccae81 --- a/extra/editors/textmate/textmate.factor +++ b/extra/editors/textmate/textmate.factor @@ -4,6 +4,7 @@ namespaces prettyprint editors ; IN: editors.textmate : textmate-location ( file line -- ) - [ "mate -a -l " % # " " % unparse % ] "" make run-process ; + [ "mate" , "-a" , "-l" , number>string , , ] { } make + run-process drop ; [ textmate-location ] edit-hook set-global diff --git a/extra/editors/ultraedit/ultraedit.factor b/extra/editors/ultraedit/ultraedit.factor old mode 100644 new mode 100755 index 50c241daea..7da4b807ce --- a/extra/editors/ultraedit/ultraedit.factor +++ b/extra/editors/ultraedit/ultraedit.factor @@ -10,8 +10,8 @@ IN: editors.ultraedit : ultraedit ( file line -- ) [ - ultraedit-path % " " % swap % "/" % # "/1" % - ] "" make run-detached ; + ultraedit-path , [ % "/" % # "/1" % ] "" make , + ] { } make run-detached drop ; [ ultraedit ] edit-hook set-global diff --git a/extra/editors/vim/vim.factor b/extra/editors/vim/vim.factor old mode 100644 new mode 100755 index 040e3fb4b4..8d60942d67 --- a/extra/editors/vim/vim.factor +++ b/extra/editors/vim/vim.factor @@ -10,13 +10,15 @@ HOOK: vim-command vim-editor TUPLE: vim ; -M: vim vim-command ( file line -- string ) - [ "\"" % vim-path get % "\" \"" % swap % "\" +" % # ] "" make ; +M: vim vim-command ( file line -- array ) + [ + vim-path get , swap , "+" swap number>string append , + ] { } make ; : vim-location ( file line -- ) vim-command vim-detach get-global - [ run-detached ] [ run-process ] if ; + [ run-detached ] [ run-process ] if drop ; "vim" vim-path set-global [ vim-location ] edit-hook set-global diff --git a/extra/editors/wordpad/wordpad.factor b/extra/editors/wordpad/wordpad.factor old mode 100644 new mode 100755 index eb882a9e38..0a86250a92 --- a/extra/editors/wordpad/wordpad.factor +++ b/extra/editors/wordpad/wordpad.factor @@ -8,8 +8,6 @@ IN: editors.wordpad ] unless* ; : wordpad ( file line -- ) - [ - wordpad-path % drop " " % "\"" % % "\"" % - ] "" make run-detached ; + drop wordpad-path swap 2array run-detached drop ; [ wordpad ] edit-hook set-global diff --git a/extra/tools/deploy/macosx/macosx.factor b/extra/tools/deploy/macosx/macosx.factor index 7b44703013..7efb34a6ae 100755 --- a/extra/tools/deploy/macosx/macosx.factor +++ b/extra/tools/deploy/macosx/macosx.factor @@ -8,10 +8,10 @@ QUALIFIED: unix IN: tools.deploy.macosx : touch ( path -- ) - { "touch" } swap add run-process ; + { "touch" } swap add run-process drop ; : rm ( path -- ) - { "rm" "-rf" } swap add run-process ; + { "rm" "-rf" } swap add run-process drop ; : bundle-dir ( -- dir ) vm parent-directory parent-directory ; From 6afa4119c8e3519e182b2163bd0402c79ba5cec4 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 04:19:15 -0400 Subject: [PATCH 62/78] Clean up non-blocking wait-for-process support, implement on Unix (untested) --- extra/io/launcher/launcher.factor | 29 +++++++-- extra/io/unix/bsd/bsd.factor | 4 +- extra/io/unix/kqueue/kqueue.factor | 18 ++---- extra/io/unix/launcher/launcher.factor | 63 ++++++++++---------- extra/io/unix/linux/linux.factor | 5 +- extra/io/windows/launcher/launcher.factor | 26 +++----- extra/io/windows/nt/launcher/launcher.factor | 2 +- extra/unix/process/process.factor | 22 +------ 8 files changed, 72 insertions(+), 97 deletions(-) mode change 100644 => 100755 extra/io/unix/kqueue/kqueue.factor mode change 100644 => 100755 extra/unix/process/process.factor diff --git a/extra/io/launcher/launcher.factor b/extra/io/launcher/launcher.factor index decf4f3434..c646358b2e 100755 --- a/extra/io/launcher/launcher.factor +++ b/extra/io/launcher/launcher.factor @@ -1,12 +1,25 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: io io.backend system kernel namespaces strings hashtables -sequences assocs combinators vocabs.loader ; +sequences assocs combinators vocabs.loader init threads +continuations ; IN: io.launcher +! Non-blocking process exit notification facility +SYMBOL: processes + +[ H{ } clone processes set-global ] "io.launcher" add-init-hook + TUPLE: process handle status ; -: ( handle -- process ) f process construct-boa ; +HOOK: register-process io-backend ( process -- ) + +M: object register-process drop ; + +: ( handle -- process ) + f process construct-boa + V{ } clone over processes get set-at + dup register-process ; M: process equal? 2drop f ; @@ -54,11 +67,10 @@ M: assoc >descriptor ; HOOK: run-process* io-backend ( desc -- handle ) -HOOK: wait-for-process* io-backend ( process -- ) - : wait-for-process ( process -- status ) - dup process-handle [ dup wait-for-process* ] when - process-status ; + dup process-handle [ + dup [ processes get at push stop ] curry callcc0 + ] when process-status ; : run-process ( obj -- process ) >descriptor @@ -81,3 +93,8 @@ TUPLE: process-stream process ; swap [ swap with-stream ] keep process-stream-process ; inline + +: notify-exit ( status process -- ) + [ set-process-status ] keep + [ processes get delete-at* drop [ schedule-thread ] each ] keep + f swap set-process-handle ; diff --git a/extra/io/unix/bsd/bsd.factor b/extra/io/unix/bsd/bsd.factor index 39eb8b6fb9..3319324c3d 100755 --- a/extra/io/unix/bsd/bsd.factor +++ b/extra/io/unix/bsd/bsd.factor @@ -23,7 +23,7 @@ M: bsd-io init-io ( -- ) 2dup mx get-global mx-reads set-at mx get-global mx-writes set-at ; -M: bsd-io wait-for-process ( pid -- status ) - [ kqueue-mx get-global add-pid-task stop ] curry callcc1 ; +M: bsd-io register-process ( process -- ) + process-handle kqueue-mx get-global add-pid-task ; T{ bsd-io } set-io-backend diff --git a/extra/io/unix/kqueue/kqueue.factor b/extra/io/unix/kqueue/kqueue.factor old mode 100644 new mode 100755 index 4fbfbcaaf0..3df2d7cd57 --- a/extra/io/unix/kqueue/kqueue.factor +++ b/extra/io/unix/kqueue/kqueue.factor @@ -5,7 +5,7 @@ sequences assocs unix unix.kqueue unix.process math namespaces combinators threads vectors ; IN: io.unix.kqueue -TUPLE: kqueue-mx events processes ; +TUPLE: kqueue-mx events ; : max-events ( -- n ) #! We read up to 256 events at a time. This is an arbitrary @@ -15,7 +15,6 @@ TUPLE: kqueue-mx events processes ; : ( -- mx ) kqueue-mx construct-mx kqueue dup io-error over set-mx-fd - H{ } clone over set-kqueue-mx-processes max-events "kevent" over set-kqueue-mx-events ; GENERIC: io-task-filter ( task -- n ) @@ -52,9 +51,8 @@ M: kqueue-mx unregister-io-task ( task mx -- ) over mx-reads at handle-io-task ; : kevent-proc-task ( mx pid -- ) - dup (wait-for-pid) spin kqueue-mx-processes delete-at* [ - [ schedule-thread-with ] with each - ] [ 2drop ] if ; + dup (wait-for-pid) swap find-process + dup [ notify-exit ] [ 2drop ] if ; : handle-kevent ( mx kevent -- ) dup kevent-ident swap kevent-filter { @@ -76,11 +74,5 @@ M: kqueue-mx wait-for-events ( ms mx -- ) EVFILT_PROC over set-kevent-filter NOTE_EXIT over set-kevent-fflags ; -: add-pid-task ( continuation pid mx -- ) - 2dup kqueue-mx-processes at* [ - 2nip push - ] [ - drop - over make-proc-kevent over register-kevent - >r >r 1vector r> r> kqueue-mx-processes set-at - ] if ; +: add-pid-task ( pid mx -- ) + swap make-proc-kevent swap register-kevent ; diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index adf571a8b7..3cd21e6c51 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -9,10 +9,6 @@ IN: io.unix.launcher ! Search unix first USE: unix -HOOK: wait-for-process io-backend ( pid -- status ) - -M: unix-io wait-for-process ( pid -- status ) wait-for-pid ; - ! Our command line parser. Supported syntax: ! foo bar baz -- simple tokens ! foo\ bar -- escaping the space @@ -46,7 +42,7 @@ MEMO: 'arguments' ( -- parser ) : assoc>env ( assoc -- env ) [ "=" swap 3append ] { } assoc>map ; -: (spawn-process) ( -- ) +: spawn-process ( -- ) [ get-arguments pass-environment? @@ -55,20 +51,9 @@ MEMO: 'arguments' ( -- parser ) io-error ] [ error. :c flush ] recover 1 exit ; -: spawn-process ( -- pid ) - [ (spawn-process) ] [ ] with-fork ; - -: spawn-detached ( -- ) - [ spawn-process 0 exit ] [ ] with-fork - wait-for-process drop ; - -M: unix-io run-process* ( desc -- ) +M: unix-io run-process* ( desc -- pid ) [ - +detached+ get [ - spawn-detached - ] [ - spawn-process wait-for-process drop - ] if + [ spawn-process ] [ ] with-fork ] with-descriptor ; : open-pipe ( -- pair ) @@ -82,21 +67,35 @@ M: unix-io run-process* ( desc -- ) : spawn-process-stream ( -- in out pid ) open-pipe open-pipe [ setup-stdio-pipe - (spawn-process) + spawn-process ] [ -rot 2dup second close first close - ] with-fork first swap second rot ; - -TUPLE: pipe-stream pid status ; - -: ( in out pid -- stream ) - f pipe-stream construct-boa - -rot handle>duplex-stream over set-delegate ; - -M: pipe-stream stream-close - dup delegate stream-close - dup pipe-stream-pid wait-for-process - swap set-pipe-stream-status ; + ] with-fork first swap second rot ; M: unix-io process-stream* - [ spawn-process-stream ] with-descriptor ; + [ + spawn-process-stream >r handle>duplex-stream r> + ] with-descriptor ; + +: find-process ( handle -- process ) + f process construct-boa processes get at ; + +! Inefficient process wait polling, used on Linux and Solaris. +! On BSD and Mac OS X, we use kqueue() which scales better. +: wait-for-processes ( -- ? ) + -1 0 tuck WNOHANG waitpid + dup zero? [ + 2drop t + ] [ + find-process dup [ + >r *uint r> notify-exit f + ] [ + 2drop f + ] if + ] if ; + +: wait-loop ( -- ) + wait-for-processes [ 250 sleep ] when wait-loop ; + +: start-wait-thread ( -- ) + [ wait-loop ] in-thread ; diff --git a/extra/io/unix/linux/linux.factor b/extra/io/unix/linux/linux.factor index 06380c7e1e..fcb48dd577 100755 --- a/extra/io/unix/linux/linux.factor +++ b/extra/io/unix/linux/linux.factor @@ -10,9 +10,6 @@ INSTANCE: linux-io unix-io M: linux-io init-io ( -- ) mx set-global - start-wait-loop ; - -M: linux-io wait-for-process ( pid -- status ) - wait-for-pid ; + start-wait-thread ; T{ linux-io } set-io-backend diff --git a/extra/io/windows/launcher/launcher.factor b/extra/io/windows/launcher/launcher.factor index 603fa2a638..79284b265b 100755 --- a/extra/io/windows/launcher/launcher.factor +++ b/extra/io/windows/launcher/launcher.factor @@ -6,14 +6,6 @@ math windows.kernel32 windows namespaces io.launcher kernel sequences windows.errors assocs splitting system threads init ; IN: io.windows.launcher -SYMBOL: processes - -[ H{ } clone processes set-global ] -"io.windows.launcher" add-init-hook - -: ( handle -- process ) - V{ } clone over processes get set-at ; - TUPLE: CreateProcess-args lpApplicationName lpCommandLine @@ -104,12 +96,9 @@ M: windows-io run-process* ( desc -- handle ) [ make-CreateProcess-args dup call-CreateProcess - CreateProcess-args-lpProcessInformation + CreateProcess-args-lpProcessInformation ] with-descriptor ; -M: windows-io wait-for-process* - [ processes get at push stop ] curry callcc0 ; - : dispose-process ( process-information -- ) #! From MSDN: "Handles in PROCESS_INFORMATION must be closed #! with CloseHandle when they are no longer needed." @@ -121,11 +110,10 @@ M: windows-io wait-for-process* 0 [ GetExitCodeProcess ] keep *ulong swap win32-error=0/f ; -: notify-exit ( process -- ) - dup process-handle exit-code over set-process-status - dup process-handle dispose-process - dup processes get delete-at* drop [ schedule-thread ] each - f swap set-process-handle ; +: process-exited ( process -- ) + dup process-handle exit-code + over process-handle dispose-process + swap notify-exit ; : wait-for-processes ( processes -- ? ) keys dup @@ -133,7 +121,7 @@ M: windows-io wait-for-process* dup length swap >c-void*-array 0 0 WaitForMultipleObjects dup HEX: ffffffff = [ win32-error ] when - dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth notify-exit f ] if ; + dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth process-exited f ] if ; : wait-loop ( -- ) processes get dup assoc-empty? @@ -143,3 +131,5 @@ M: windows-io wait-for-process* : start-wait-thread ( -- ) [ wait-loop ] in-thread ; + +[ start-wait-thread ] "io.windows.launcher" add-init-hook diff --git a/extra/io/windows/nt/launcher/launcher.factor b/extra/io/windows/nt/launcher/launcher.factor index 6e788003ea..bfce92e17d 100755 --- a/extra/io/windows/nt/launcher/launcher.factor +++ b/extra/io/windows/nt/launcher/launcher.factor @@ -59,6 +59,6 @@ M: windows-io process-stream* dup CreateProcess-args-stdout-pipe pipe-in over CreateProcess-args-stdin-pipe pipe-out - swap CreateProcess-args-lpProcessInformation + swap CreateProcess-args-lpProcessInformation ] with-destructors ] with-descriptor ; diff --git a/extra/unix/process/process.factor b/extra/unix/process/process.factor old mode 100644 new mode 100755 index b2877dc4a1..fb4271ea23 --- a/extra/unix/process/process.factor +++ b/extra/unix/process/process.factor @@ -31,25 +31,5 @@ IN: unix.process : with-fork ( child parent -- ) fork dup zero? -roll swap curry if ; inline -! Lame polling strategy for getting process exit codes. On -! BSD, we use kqueue which is more efficient. - -SYMBOL: pid-wait - -: (wait-for-pid) ( pid -- status ) - 0 [ 0 waitpid drop ] keep *int ; - : wait-for-pid ( pid -- status ) - [ pid-wait get-global [ ?push ] change-at stop ] curry - callcc1 ; - -: wait-loop ( -- ) - -1 0 tuck WNOHANG waitpid ! &status return - [ *int ] [ pid-wait get delete-at* drop ] bi* ! status ? - [ schedule-thread-with ] with each - 250 sleep - wait-loop ; - -: start-wait-loop ( -- ) - H{ } clone pid-wait set-global - [ wait-loop ] in-thread ; \ No newline at end of file + 0 [ 0 waitpid drop ] keep *int ; \ No newline at end of file From 6d5c1bf1d2ce420da8b9ceafe4a396e6acfec361 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Thu, 24 Jan 2008 18:12:39 -0500 Subject: [PATCH 63/78] Add more math.constants --- extra/math/constants/constants-docs.factor | 9 +++++++++ extra/math/constants/constants.factor | 2 ++ 2 files changed, 11 insertions(+) diff --git a/extra/math/constants/constants-docs.factor b/extra/math/constants/constants-docs.factor index 92c96985c3..653444376a 100755 --- a/extra/math/constants/constants-docs.factor +++ b/extra/math/constants/constants-docs.factor @@ -4,6 +4,8 @@ IN: math.constants ARTICLE: "math-constants" "Constants" "Standard mathematical constants:" { $subsection e } +{ $subsection gamma } +{ $subsection phi } { $subsection pi } "Various limits:" { $subsection most-positive-fixnum } @@ -15,6 +17,13 @@ ABOUT: "math-constants" HELP: e { $values { "e" "base of natural logarithm" } } ; +HELP: gamma +{ $values { "gamma" "Euler-Mascheroni constant" } } +{ $description "The Euler-Mascheroni constant, also called \"Euler's constant\" or \"the Euler constant\"." } ; + +HELP: phi +{ $values { "phi" "golden ratio" } } ; + HELP: pi { $values { "pi" "circumference of circle with diameter 1" } } ; diff --git a/extra/math/constants/constants.factor b/extra/math/constants/constants.factor index e2d7c4f433..7e2b8842ad 100755 --- a/extra/math/constants/constants.factor +++ b/extra/math/constants/constants.factor @@ -3,5 +3,7 @@ IN: math.constants : e ( -- e ) 2.7182818284590452354 ; inline +: gamma ( -- gamma ) 0.57721566490153286060 ; inline : pi ( -- pi ) 3.14159265358979323846 ; inline +: phi ( -- phi ) 1.61803398874989484820 ; inline : epsilon ( -- epsilon ) 2.2204460492503131e-16 ; inline From 6df78419b9930e3d3a95a39a8abb533c333a63e8 Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Thu, 24 Jan 2008 18:18:12 -0500 Subject: [PATCH 64/78] Fix uses of new math constants --- extra/golden-section/golden-section.factor | 53 ++++++++++------------ extra/project-euler/025/025.factor | 7 +-- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/extra/golden-section/golden-section.factor b/extra/golden-section/golden-section.factor index 9dd3a747ed..ef6f1ca4c2 100644 --- a/extra/golden-section/golden-section.factor +++ b/extra/golden-section/golden-section.factor @@ -1,28 +1,25 @@ -USING: kernel namespaces math math.constants math.functions -arrays sequences opengl opengl.gl opengl.glu ui ui.render -ui.gadgets ui.gadgets.theme ui.gadgets.slate colors ; +USING: kernel namespaces math math.constants math.functions arrays sequences + opengl opengl.gl opengl.glu ui ui.render ui.gadgets ui.gadgets.theme + ui.gadgets.slate colors ; IN: golden-section ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! To run: -! -! "demos.golden-section" run +! "golden-section" run ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : disk ( quadric radius center -- ) -glPushMatrix -gl-translate -dup 0 glScalef -0 1 10 10 gluDisk -glPopMatrix ; + glPushMatrix + gl-translate + dup 0 glScalef + 0 1 10 10 gluDisk + glPopMatrix ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -: phi ( -- phi ) 5 sqrt 1 + 2 / 1 - ; - -: omega ( i -- omega ) phi * 2 * pi * ; +: omega ( i -- omega ) phi 1- * 2 * pi * ; : x ( i -- x ) dup omega cos * 0.5 * ; @@ -35,10 +32,10 @@ glPopMatrix ; : color ( i -- color ) 360.0 / dup 0.25 1 4array ; : rim ( quadric i -- ) -black gl-color dup radius 1.5 * swap center disk ; + black gl-color dup radius 1.5 * swap center disk ; : inner ( quadric i -- ) -dup color gl-color dup radius swap center disk ; + dup color gl-color dup radius swap center disk ; : dot ( quadric i -- ) 2dup rim inner ; @@ -47,21 +44,21 @@ dup color gl-color dup radius swap center disk ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : with-quadric ( quot -- ) -gluNewQuadric [ swap call ] keep gluDeleteQuadric ; inline + gluNewQuadric [ swap call ] keep gluDeleteQuadric ; inline : display ( -- ) -GL_PROJECTION glMatrixMode -glLoadIdentity --400 400 -400 400 -1 1 glOrtho -GL_MODELVIEW glMatrixMode -glLoadIdentity -[ golden-section ] with-quadric ; + GL_PROJECTION glMatrixMode + glLoadIdentity + -400 400 -400 400 -1 1 glOrtho + GL_MODELVIEW glMatrixMode + glLoadIdentity + [ golden-section ] with-quadric ; : golden-section-window ( -- ) -[ - [ display ] - { 600 600 } over set-slate-dim - "Golden Section" open-window -] with-ui ; + [ + [ display ] + { 600 600 } over set-slate-dim + "Golden Section" open-window + ] with-ui ; -MAIN: golden-section-window \ No newline at end of file +MAIN: golden-section-window diff --git a/extra/project-euler/025/025.factor b/extra/project-euler/025/025.factor index 4eed8b55cb..2786d9f0e6 100644 --- a/extra/project-euler/025/025.factor +++ b/extra/project-euler/025/025.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: alien.syntax kernel math math.functions math.parser math.ranges memoize - project-euler.common sequences ; +USING: alien.syntax kernel math math.constants math.functions math.parser + math.ranges memoize project-euler.common sequences ; IN: project-euler.025 ! http://projecteuler.net/index.php?section=problems&id=25 @@ -67,9 +67,6 @@ PRIVATE> integer ; From 42a710e96531576b94011b77aff9a57111b9f3a3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 19:19:45 -0400 Subject: [PATCH 65/78] Update calendar for Windows --- extra/calendar/windows/windows.factor | 38 +----------------- .../time/time-tests.factor} | 0 extra/windows/time/time.factor | 39 +++++++++++++++++++ 3 files changed, 41 insertions(+), 36 deletions(-) mode change 100644 => 100755 extra/calendar/windows/windows.factor rename extra/{calendar/windows/windows-tests.factor => windows/time/time-tests.factor} (100%) create mode 100755 extra/windows/time/time.factor diff --git a/extra/calendar/windows/windows.factor b/extra/calendar/windows/windows.factor old mode 100644 new mode 100755 index 6c3a7a71e7..320400822c --- a/extra/calendar/windows/windows.factor +++ b/extra/calendar/windows/windows.factor @@ -1,5 +1,5 @@ -USING: alien alien.c-types kernel math -windows windows.kernel32 namespaces ; +USING: calendar.backend namespaces alien.c-types +windows windows.kernel32 kernel math ; IN: calendar.windows TUPLE: windows-calendar ; @@ -11,37 +11,3 @@ M: windows-calendar gmt-offset ( -- float ) [ GetTimeZoneInformation win32-error=0/f ] keep [ TIME_ZONE_INFORMATION-Bias ] keep TIME_ZONE_INFORMATION-DaylightBias + 60 /f neg ; - -: >64bit ( lo hi -- n ) - 32 shift bitor ; - -: windows-1601 ( -- timestamp ) - 1601 1 1 0 0 0 0 ; - -: FILETIME>windows-time ( FILETIME -- n ) - [ FILETIME-dwLowDateTime ] keep - FILETIME-dwHighDateTime >64bit ; - -: windows-time>timestamp ( n -- timestamp ) - 10000000 /i seconds windows-1601 swap +dt ; - -: windows-time ( -- n ) - "FILETIME" [ GetSystemTimeAsFileTime ] keep - FILETIME>windows-time ; - -: timestamp>windows-time ( timestamp -- n ) - #! 64bit number representing # of nanoseconds since Jan 1, 1601 (UTC) - >gmt windows-1601 timestamp- >bignum 10000000 * ; - -: windows-time>FILETIME ( n -- FILETIME ) - "FILETIME" - [ - [ >r HEX: ffffffff bitand r> set-FILETIME-dwLowDateTime ] 2keep - >r -32 shift r> set-FILETIME-dwHighDateTime - ] keep ; - -: timestamp>FILETIME ( timestamp -- FILETIME/f ) - [ >gmt timestamp>windows-time windows-time>FILETIME ] [ f ] if* ; - -: FILETIME>timestamp ( FILETIME -- timestamp/f ) - FILETIME>windows-time windows-time>timestamp ; diff --git a/extra/calendar/windows/windows-tests.factor b/extra/windows/time/time-tests.factor similarity index 100% rename from extra/calendar/windows/windows-tests.factor rename to extra/windows/time/time-tests.factor diff --git a/extra/windows/time/time.factor b/extra/windows/time/time.factor new file mode 100755 index 0000000000..3ccb4cfa67 --- /dev/null +++ b/extra/windows/time/time.factor @@ -0,0 +1,39 @@ +! Copyright (C) 2007 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien alien.c-types kernel math windows windows.kernel32 +namespaces calendar.backend ; +IN: windows.time + +: >64bit ( lo hi -- n ) + 32 shift bitor ; + +: windows-1601 ( -- timestamp ) + 1601 1 1 0 0 0 0 ; + +: FILETIME>windows-time ( FILETIME -- n ) + [ FILETIME-dwLowDateTime ] keep + FILETIME-dwHighDateTime >64bit ; + +: windows-time>timestamp ( n -- timestamp ) + 10000000 /i seconds windows-1601 swap +dt ; + +: windows-time ( -- n ) + "FILETIME" [ GetSystemTimeAsFileTime ] keep + FILETIME>windows-time ; + +: timestamp>windows-time ( timestamp -- n ) + #! 64bit number representing # of nanoseconds since Jan 1, 1601 (UTC) + >gmt windows-1601 timestamp- >bignum 10000000 * ; + +: windows-time>FILETIME ( n -- FILETIME ) + "FILETIME" + [ + [ >r HEX: ffffffff bitand r> set-FILETIME-dwLowDateTime ] 2keep + >r -32 shift r> set-FILETIME-dwHighDateTime + ] keep ; + +: timestamp>FILETIME ( timestamp -- FILETIME/f ) + [ >gmt timestamp>windows-time windows-time>FILETIME ] [ f ] if* ; + +: FILETIME>timestamp ( FILETIME -- timestamp/f ) + FILETIME>windows-time windows-time>timestamp ; From 1249e3a720bd526fb2e61f746a5df50fb480737b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 19:20:07 -0400 Subject: [PATCH 66/78] Move prettyprint:-> to prettyprint.private --- core/prettyprint/prettyprint-docs.factor | 4 ++-- core/prettyprint/prettyprint.factor | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 100755 core/prettyprint/prettyprint-docs.factor diff --git a/core/prettyprint/prettyprint-docs.factor b/core/prettyprint/prettyprint-docs.factor old mode 100644 new mode 100755 index 2b01df8faa..69400d2527 --- a/core/prettyprint/prettyprint-docs.factor +++ b/core/prettyprint/prettyprint-docs.factor @@ -1,6 +1,6 @@ USING: prettyprint.backend prettyprint.config -prettyprint.sections help.markup help.syntax io kernel words -definitions quotations strings ; +prettyprint.sections prettyprint.private help.markup help.syntax +io kernel words definitions quotations strings ; IN: prettyprint ARTICLE: "prettyprint-numbers" "Prettyprinting numbers" diff --git a/core/prettyprint/prettyprint.factor b/core/prettyprint/prettyprint.factor index 45ff0c0572..ed52f0238c 100755 --- a/core/prettyprint/prettyprint.factor +++ b/core/prettyprint/prettyprint.factor @@ -86,14 +86,14 @@ combinators quotations ; : .s ( -- ) datastack stack. ; : .r ( -- ) retainstack stack. ; + \ -> { { foreground { 1 1 1 1 } } { background { 0 0 0 1 } } } "word-style" set-word-prop - Date: Thu, 24 Jan 2008 19:20:27 -0400 Subject: [PATCH 67/78] Fix erronous stack effect comment --- extra/cocoa/messages/messages.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/cocoa/messages/messages.factor b/extra/cocoa/messages/messages.factor index 33d635c8b7..e2072f441c 100755 --- a/extra/cocoa/messages/messages.factor +++ b/extra/cocoa/messages/messages.factor @@ -79,11 +79,11 @@ MACRO: (send) ( selector super? -- quot ) super-message-senders message-senders ? get at [ slip execute ] 2curry ; -: send ( args... receiver selector -- return... ) f (send) ; inline +: send ( receiver args... selector -- return... ) f (send) ; inline \ send soft "break-after" set-word-prop -: super-send ( args... receiver selector -- return... ) t (send) ; inline +: super-send ( receiver args... selector -- return... ) t (send) ; inline \ super-send soft "break-after" set-word-prop From 783e63781f1ebdd7c3b3ebc592606c1049d00d78 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 19:21:10 -0400 Subject: [PATCH 68/78] I/O fixes --- extra/io/sockets/impl/impl.factor | 9 +++++++-- extra/io/sockets/sockets.factor | 0 extra/io/windows/nt/backend/backend.factor | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) mode change 100644 => 100755 extra/io/sockets/sockets.factor diff --git a/extra/io/sockets/impl/impl.factor b/extra/io/sockets/impl/impl.factor index e8ab957482..ce4d5ad566 100755 --- a/extra/io/sockets/impl/impl.factor +++ b/extra/io/sockets/impl/impl.factor @@ -106,9 +106,14 @@ M: f parse-sockaddr nip ; [ ] unfold nip [ ] subset ; : prepare-resolve-host ( host serv passive? -- 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 - >r string>char-alien r> - dup integer? [ port-override set f ] [ string>char-alien ] if + dup integer? [ port-override set "http" ] when r> AI_PASSIVE 0 ? ; M: object resolve-host ( host serv passive? -- seq ) diff --git a/extra/io/sockets/sockets.factor b/extra/io/sockets/sockets.factor old mode 100644 new mode 100755 diff --git a/extra/io/windows/nt/backend/backend.factor b/extra/io/windows/nt/backend/backend.factor index 0d1f2cec0b..82d609c371 100755 --- a/extra/io/windows/nt/backend/backend.factor +++ b/extra/io/windows/nt/backend/backend.factor @@ -116,25 +116,27 @@ M: windows-nt-io add-completion ( handle -- ) : lookup-callback ( GetQueuedCompletion-args -- callback ) io-hash get-global delete-at* drop ; -: wait-for-io ( timeout -- continuation/f ) +: handle-overlapped ( timeout -- ? ) wait-for-overlapped [ GetLastError dup expected-io-error? [ - 2drop f + 2drop t ] [ dup eof? [ drop lookup-callback dup io-callback-port t swap set-port-eof? - io-callback-continuation ] [ (win32-error-string) swap lookup-callback [ io-callback-port set-port-error ] keep - io-callback-continuation - ] if + ] if io-callback-continuation schedule-thread f ] if ] [ - lookup-callback io-callback-continuation + lookup-callback + io-callback-continuation schedule-thread f ] if ; +: drain-overlapped ( timeout -- ) + handle-overlapped [ 0 drain-overlapped ] unless ; + : maybe-expire ( io-callbck -- ) io-callback-port dup timeout? [ @@ -144,10 +146,10 @@ M: windows-nt-io add-completion ( handle -- ) ] if ; : cancel-timeout ( -- ) - io-hash get-global values [ maybe-expire ] each ; + io-hash get-global [ nip maybe-expire ] assoc-each ; M: windows-nt-io io-multiplex ( ms -- ) - cancel-timeout wait-for-io [ schedule-thread ] when* ; + cancel-timeout drain-overlapped ; M: windows-nt-io init-io ( -- ) master-completion-port set-global From b5a337bb2a72c6daa5a64127a78ba483dd800a68 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 21:10:17 -0400 Subject: [PATCH 69/78] Fix Linux I/O --- extra/io/unix/launcher/launcher.factor | 2 +- extra/unix/unix.factor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 3cd21e6c51..769e905b6e 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -84,7 +84,7 @@ M: unix-io process-stream* ! On BSD and Mac OS X, we use kqueue() which scales better. : wait-for-processes ( -- ? ) -1 0 tuck WNOHANG waitpid - dup zero? [ + dup 0 <= [ 2drop t ] [ find-process dup [ diff --git a/extra/unix/unix.factor b/extra/unix/unix.factor index 16b279765f..f5c484568e 100755 --- a/extra/unix/unix.factor +++ b/extra/unix/unix.factor @@ -13,7 +13,7 @@ TYPEDEF: longlong quad_t TYPEDEF: uint gid_t TYPEDEF: uint in_addr_t TYPEDEF: uint ino_t -TYPEDEF: uint pid_t +TYPEDEF: int pid_t TYPEDEF: uint socklen_t TYPEDEF: uint time_t TYPEDEF: uint uid_t From 0b4be5f0a2e30f9879e9b3106bf79fa7866700d3 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 24 Jan 2008 22:41:55 -0600 Subject: [PATCH 70/78] Fix Unix io.launcher --- extra/io/unix/bsd/bsd.factor | 4 ++-- extra/io/unix/kqueue/kqueue.factor | 8 ++++---- extra/io/unix/launcher/launcher.factor | 5 +++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/extra/io/unix/bsd/bsd.factor b/extra/io/unix/bsd/bsd.factor index 3319324c3d..a4315ce5d0 100755 --- a/extra/io/unix/bsd/bsd.factor +++ b/extra/io/unix/bsd/bsd.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. IN: io.unix.bsd USING: io.backend io.unix.backend io.unix.kqueue io.unix.select -io.unix.launcher namespaces kernel assocs threads continuations -; +io.launcher io.unix.launcher namespaces kernel assocs threads +continuations ; ! On *BSD and Mac OS X, we use select() for the top-level ! multiplexer, and we hang a kqueue off of it but file change diff --git a/extra/io/unix/kqueue/kqueue.factor b/extra/io/unix/kqueue/kqueue.factor index 3df2d7cd57..19005df404 100755 --- a/extra/io/unix/kqueue/kqueue.factor +++ b/extra/io/unix/kqueue/kqueue.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types kernel io.nonblocking io.unix.backend sequences assocs unix unix.kqueue unix.process math namespaces -combinators threads vectors ; +combinators threads vectors io.launcher io.unix.launcher ; IN: io.unix.kqueue TUPLE: kqueue-mx events ; @@ -50,15 +50,15 @@ M: kqueue-mx unregister-io-task ( task mx -- ) : kevent-write-task ( mx fd -- ) over mx-reads at handle-io-task ; -: kevent-proc-task ( mx pid -- ) - dup (wait-for-pid) swap find-process +: kevent-proc-task ( pid -- ) + dup wait-for-pid swap find-process dup [ notify-exit ] [ 2drop ] if ; : handle-kevent ( mx kevent -- ) dup kevent-ident swap kevent-filter { { [ dup EVFILT_READ = ] [ drop kevent-read-task ] } { [ dup EVFILT_WRITE = ] [ drop kevent-write-task ] } - { [ dup EVFILT_PROC = ] [ drop kevent-proc-task ] } + { [ dup EVFILT_PROC = ] [ drop kevent-proc-task drop ] } } cond ; : handle-kevents ( mx n -- ) diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 769e905b6e..50c41380d0 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -3,7 +3,7 @@ USING: io io.backend io.launcher io.unix.backend io.nonblocking sequences kernel namespaces math system alien.c-types debugger continuations arrays assocs combinators unix.process -parser-combinators memoize promises strings ; +parser-combinators memoize promises strings threads ; IN: io.unix.launcher ! Search unix first @@ -78,7 +78,8 @@ M: unix-io process-stream* ] with-descriptor ; : find-process ( handle -- process ) - f process construct-boa processes get at ; + processes get swap [ nip swap process-handle = ] curry + assoc-find 2drop ; ! Inefficient process wait polling, used on Linux and Solaris. ! On BSD and Mac OS X, we use kqueue() which scales better. From 9cc5f5c78ed1ed0013fab524081de5b95ce7252a Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 24 Jan 2008 23:07:14 -0600 Subject: [PATCH 71/78] Fix construct-empty transform --- core/inference/transforms/transforms.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/inference/transforms/transforms.factor b/core/inference/transforms/transforms.factor index eabe4b8c2a..c4eeb98145 100755 --- a/core/inference/transforms/transforms.factor +++ b/core/inference/transforms/transforms.factor @@ -74,7 +74,7 @@ M: pair (bitfield-quot) ( spec -- quot ) dup tuple-size [ ] 2curry swap infer-quot ] [ - \ construct-empty declared-infer + \ construct-empty 1 1 make-call-node ] if ] "infer" set-word-prop From 00d2122a4c3f10419a0a379e0d2861c73ce4c5e5 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 23:45:56 -0400 Subject: [PATCH 72/78] Working on Unix io.launcher redirection --- extra/io/launcher/launcher-docs.factor | 30 ++++++++++++++++++++++++++ extra/io/launcher/launcher.factor | 4 ++++ extra/io/unix/files/files.factor | 6 ++++-- extra/io/unix/launcher/launcher.factor | 13 +++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/extra/io/launcher/launcher-docs.factor b/extra/io/launcher/launcher-docs.factor index 2c30431714..495894b25d 100755 --- a/extra/io/launcher/launcher-docs.factor +++ b/extra/io/launcher/launcher-docs.factor @@ -31,6 +31,36 @@ HELP: +environment-mode+ "Default value is " { $link append-environment } "." } ; +HELP: +stdin+ +{ $description "Launch descriptor key. Must equal one of the following:" + { $list + { { $link f } " - standard input is inherited" } + { { $link +closed+ } " - standard input is closed" } + { "a path name - standard input is read from the given file, which must exist" } + } +} ; + +HELP: +stdout+ +{ $description "Launch descriptor key. Must equal one of the following:" + { $list + { { $link f } " - standard output is inherited" } + { { $link +closed+ } " - standard output is closed" } + { "a path name - standard output is written to the given file, which is overwritten if it already exists" } + } +} ; + +HELP: +stderr+ +{ $description "Launch descriptor key. Must equal one of the following:" + { $list + { { $link f } " - standard error is inherited" } + { { $link +closed+ } " - standard error is closed" } + { "a path name - standard error is written to the given file, which is overwritten if it already exists" } + } +} ; + +HELP: +closed+ +{ $description "Possible value for " { $link +stdin+ } ", " { $link +stdout+ } ", and " { $link +stderr+ } " launch descriptors." } ; + HELP: prepend-environment { $description "Possible value of " { $link +environment-mode+ } " launch descriptor key. The child process environment consists of the value of the " { $link +environment+ } " key together with the current environment, with entries from the current environment taking precedence." $nl diff --git a/extra/io/launcher/launcher.factor b/extra/io/launcher/launcher.factor index c646358b2e..fe3244916d 100755 --- a/extra/io/launcher/launcher.factor +++ b/extra/io/launcher/launcher.factor @@ -30,6 +30,10 @@ SYMBOL: +arguments+ SYMBOL: +detached+ SYMBOL: +environment+ SYMBOL: +environment-mode+ +SYMBOL: +stdin+ +SYMBOL: +stdout+ +SYMBOL: +stderr+ +SYMBOL: +closed+ SYMBOL: prepend-environment SYMBOL: replace-environment diff --git a/extra/io/unix/files/files.factor b/extra/io/unix/files/files.factor index f9d642d661..b56e62d3c4 100755 --- a/extra/io/unix/files/files.factor +++ b/extra/io/unix/files/files.factor @@ -4,13 +4,15 @@ USING: io.backend io.nonblocking io.unix.backend io.files io unix kernel math continuations ; IN: io.unix.files +: read-flags O_RDONLY ; inline + : open-read ( path -- fd ) O_RDONLY file-mode open dup io-error ; M: unix-io ( path -- stream ) open-read ; -: write-flags O_WRONLY O_CREAT O_TRUNC bitor bitor ; +: write-flags O_WRONLY O_CREAT O_TRUNC bitor bitor ; inline : open-write ( path -- fd ) write-flags file-mode open dup io-error ; @@ -18,7 +20,7 @@ M: unix-io ( path -- stream ) M: unix-io ( path -- stream ) open-write ; -: append-flags O_WRONLY O_APPEND O_CREAT bitor bitor ; +: append-flags O_WRONLY O_APPEND O_CREAT bitor bitor ; inline : open-append ( path -- fd ) append-flags file-mode open dup io-error diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 50c41380d0..6439fc0848 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -42,8 +42,21 @@ MEMO: 'arguments' ( -- parser ) : assoc>env ( assoc -- env ) [ "=" swap 3append ] { } assoc>map ; +: redirect ( obj mode fd -- ) + { + { [ pick not ] [ 3drop ] } + { [ pick +closed+ eq? ] [ close 3drop ] } + { [ t ] [ >r file-mode open dup io-error r> dup2 io-error ] } + } cond ; + +: setup-redirection ( -- ) + +stdin+ get read-flags 0 redirect + +stdout+ get write-flags 1 redirect + +stderr+ get read-flags 2 redirect ; + : spawn-process ( -- ) [ + setup-redirection get-arguments pass-environment? [ get-environment assoc>env exec-args-with-env ] From 62f076d0c3fa2fe1f880449d7473689b9e39e9a8 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 23:48:28 -0400 Subject: [PATCH 73/78] Fix FD leak --- extra/io/unix/launcher/launcher.factor | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 6439fc0848..1e4d5fab52 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -42,11 +42,15 @@ MEMO: 'arguments' ( -- parser ) : assoc>env ( assoc -- env ) [ "=" swap 3append ] { } assoc>map ; +: (redirect) + >r file-mode open dup io-error dup + r> dup2 io-error close drop ; + : redirect ( obj mode fd -- ) { { [ pick not ] [ 3drop ] } { [ pick +closed+ eq? ] [ close 3drop ] } - { [ t ] [ >r file-mode open dup io-error r> dup2 io-error ] } + { [ t ] [ (redirect) ] } } cond ; : setup-redirection ( -- ) From 35f390e8ca17adaa3e277e479e03b135631b49cd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 24 Jan 2008 23:50:00 -0400 Subject: [PATCH 74/78] Remove unnecessary word --- core/io/io-docs.factor | 5 ----- core/io/io.factor | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) mode change 100644 => 100755 core/io/io-docs.factor diff --git a/core/io/io-docs.factor b/core/io/io-docs.factor old mode 100644 new mode 100755 index 5c71714c64..cf867d7945 --- a/core/io/io-docs.factor +++ b/core/io/io-docs.factor @@ -29,7 +29,6 @@ ARTICLE: "stdio" "The default stream" "Various words take an implicit stream parameter from a variable to reduce stack shuffling." { $subsection stdio } "Unless rebound in a child namespace, this variable will be set to a console stream for interacting with the user." -{ $subsection close } { $subsection read1 } { $subsection read } { $subsection read-until } @@ -178,10 +177,6 @@ $io-error ; HELP: stdio { $var-description "Holds a stream, used for various implicit stream operations. Rebound using " { $link with-stream } " and " { $link with-stream* } "." } ; -HELP: close -{ $contract "Closes the " { $link stdio } " stream." } -$io-error ; - HELP: readln { $values { "str/f" "a string or " { $link f } } } { $contract "Reads a line of input from the " { $link stdio } " stream. Outputs " { $link f } " on stream exhaustion." } diff --git a/core/io/io.factor b/core/io/io.factor index 56b284eaaf..edd0fa938f 100755 --- a/core/io/io.factor +++ b/core/io/io.factor @@ -38,8 +38,6 @@ SYMBOL: stdio ! Default error stream SYMBOL: stderr -: close ( -- ) stdio get stream-close ; - : readln ( -- str/f ) stdio get stream-readln ; : read1 ( -- ch/f ) stdio get stream-read1 ; : read ( n -- str/f ) stdio get stream-read ; @@ -56,7 +54,9 @@ SYMBOL: stderr stdio swap with-variable ; inline : with-stream ( stream quot -- ) - swap [ [ close ] [ ] cleanup ] with-stream* ; inline + swap [ + [ stdio get stream-close ] [ ] cleanup + ] with-stream* ; inline : tabular-output ( style quot -- ) swap >r { } make r> stdio get stream-write-table ; inline From d09bc942ac96acbeb1287dd4e143176c4e7f2b56 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 25 Jan 2008 00:21:49 -0600 Subject: [PATCH 75/78] Get file redirection working in Unix io.launcher --- extra/io/launcher/launcher.factor | 2 +- extra/io/unix/launcher/launcher.factor | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/extra/io/launcher/launcher.factor b/extra/io/launcher/launcher.factor index fe3244916d..7cf9d51ed0 100755 --- a/extra/io/launcher/launcher.factor +++ b/extra/io/launcher/launcher.factor @@ -67,7 +67,7 @@ GENERIC: >descriptor ( obj -- desc ) M: string >descriptor +command+ associate ; M: sequence >descriptor +arguments+ associate ; -M: assoc >descriptor ; +M: assoc >descriptor >hashtable ; HOOK: run-process* io-backend ( desc -- handle ) diff --git a/extra/io/unix/launcher/launcher.factor b/extra/io/unix/launcher/launcher.factor index 1e4d5fab52..0135b55a7e 100755 --- a/extra/io/unix/launcher/launcher.factor +++ b/extra/io/unix/launcher/launcher.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: io io.backend io.launcher io.unix.backend io.nonblocking -sequences kernel namespaces math system alien.c-types debugger -continuations arrays assocs combinators unix.process -parser-combinators memoize promises strings threads ; +USING: io io.backend io.launcher io.unix.backend io.unix.files +io.nonblocking sequences kernel namespaces math system + alien.c-types debugger continuations arrays assocs +combinators unix.process parser-combinators memoize +promises strings threads ; IN: io.unix.launcher ! Search unix first @@ -42,21 +43,21 @@ MEMO: 'arguments' ( -- parser ) : assoc>env ( assoc -- env ) [ "=" swap 3append ] { } assoc>map ; -: (redirect) +: (redirect) ( path mode fd -- ) >r file-mode open dup io-error dup - r> dup2 io-error close drop ; + r> dup2 io-error close ; : redirect ( obj mode fd -- ) { { [ pick not ] [ 3drop ] } - { [ pick +closed+ eq? ] [ close 3drop ] } - { [ t ] [ (redirect) ] } + { [ pick +closed+ eq? ] [ close 2drop ] } + { [ pick string? ] [ (redirect) ] } } cond ; : setup-redirection ( -- ) +stdin+ get read-flags 0 redirect +stdout+ get write-flags 1 redirect - +stderr+ get read-flags 2 redirect ; + +stderr+ get write-flags 2 redirect ; : spawn-process ( -- ) [ From 034b4dcaa66a557b439ce46e2c4bfd8be8ef8afd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 25 Jan 2008 01:49:03 -0400 Subject: [PATCH 76/78] Windows launcher work in progress --- extra/io/windows/launcher/launcher.factor | 72 +++++++++++++++++--- extra/io/windows/nt/launcher/launcher.factor | 14 +--- extra/io/windows/{nt => }/pipes/pipes.factor | 10 +-- extra/io/windows/windows.factor | 10 ++- 4 files changed, 75 insertions(+), 31 deletions(-) rename extra/io/windows/{nt => }/pipes/pipes.factor (84%) diff --git a/extra/io/windows/launcher/launcher.factor b/extra/io/windows/launcher/launcher.factor index 79284b265b..6d7a96b069 100755 --- a/extra/io/windows/launcher/launcher.factor +++ b/extra/io/windows/launcher/launcher.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2007, 2008 Doug Coleman, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types arrays continuations destructors io -io.windows libc io.nonblocking io.streams.duplex windows.types -math windows.kernel32 windows namespaces io.launcher kernel -sequences windows.errors assocs splitting system threads init ; +io.windows io.windows.pipes libc io.nonblocking +io.streams.duplex windows.types math windows.kernel32 windows +namespaces io.launcher kernel sequences windows.errors assocs +splitting system threads init strings combinators io.backend ; IN: io.windows.launcher TUPLE: CreateProcess-args @@ -86,18 +87,73 @@ TUPLE: CreateProcess-args over set-CreateProcess-args-lpEnvironment ] when ; +: (redirect) ( path access-mode create-mode -- handle ) + >r >r + normalize-pathname + r> ! access-mode + share-mode + security-attributes-inherit + r> ! create-mode + FILE_ATTRIBUTE_NORMAL ! flags and attributes + f ! template file + CreateFile dup invalid-handle? dup close-later ; + +: redirect ( obj access-mode create-mode -- handle ) + { + { [ pick not ] [ 3drop f ] } + { [ pick +closed+ eq? ] [ 3drop f ] } + { [ pick string? ] [ (redirect) ] } + } cond ; + +: inherited-stdout ( args -- handle ) + CreateProcess-args-stdout-pipe + [ pipe-out ] [ STD_OUTPUT_HANDLE GetStdHandle ] if* ; + +: redirect-stdout ( args -- handle ) + +stdout+ get GENERIC_WRITE CREATE_ALWAYS redirect + swap inherited-stdout or ; + +: inherited-stderr ( args -- handle ) + CreateProcess-args-stdout-pipe + [ pipe-out ] [ STD_ERROR_HANDLE GetStdHandle ] if* ; + +: redirect-stderr ( args -- handle ) + +stderr+ get GENERIC_WRITE CREATE_ALWAYS redirect + swap inherited-stderr or ; + +: inherited-stdin ( args -- handle ) + CreateProcess-args-stdin-pipe + [ pipe-in ] [ STD_INPUT_HANDLE GetStdHandle ] if* ; + +: redirect-stdin ( args -- handle ) + +stdin+ get GENERIC_READ OPEN_EXISTING redirect + swap inherited-stdin or ; + +: fill-startup-info + dup CreateProcess-args-lpStartupInfo + STARTF_USESTDHANDLES over set-STARTUPINFO-dwFlags + + over redirect-stdout over set-STARTUPINFO-hStdOutput + over redirect-stderr over set-STARTUPINFO-hStdError + over redirect-stdin over set-STARTUPINFO-hStdInput + + drop ; + : make-CreateProcess-args ( -- args ) default-CreateProcess-args wince? [ fill-lpApplicationName ] [ fill-lpCommandLine ] if fill-dwCreateFlags - fill-lpEnvironment ; + fill-lpEnvironment + fill-startup-info ; M: windows-io run-process* ( desc -- handle ) [ - make-CreateProcess-args - dup call-CreateProcess - CreateProcess-args-lpProcessInformation - ] with-descriptor ; + [ + make-CreateProcess-args + dup call-CreateProcess + CreateProcess-args-lpProcessInformation + ] with-descriptor + ] with-destructors ; : dispose-process ( process-information -- ) #! From MSDN: "Handles in PROCESS_INFORMATION must be closed diff --git a/extra/io/windows/nt/launcher/launcher.factor b/extra/io/windows/nt/launcher/launcher.factor index bfce92e17d..f548c5945c 100755 --- a/extra/io/windows/nt/launcher/launcher.factor +++ b/extra/io/windows/nt/launcher/launcher.factor @@ -4,7 +4,7 @@ USING: alien alien.c-types arrays continuations destructors io io.windows libc io.nonblocking io.streams.duplex windows.types math windows.kernel32 windows namespaces io.launcher kernel sequences windows.errors assocs splitting system -io.windows.launcher io.windows.nt.pipes ; +io.windows.launcher io.windows.pipes ; IN: io.windows.nt.launcher ! The below code is based on the example given in @@ -30,17 +30,6 @@ IN: io.windows.nt.launcher dup pipe-out f set-inherit over set-CreateProcess-args-stdin-pipe ; -: fill-startup-info - dup CreateProcess-args-lpStartupInfo - STARTF_USESTDHANDLES over set-STARTUPINFO-dwFlags - - over CreateProcess-args-stdout-pipe - pipe-out over set-STARTUPINFO-hStdOutput - over CreateProcess-args-stdout-pipe - pipe-out over set-STARTUPINFO-hStdError - over CreateProcess-args-stdin-pipe - pipe-in swap set-STARTUPINFO-hStdInput ; - M: windows-io process-stream* [ [ @@ -49,7 +38,6 @@ M: windows-io process-stream* fill-stdout-pipe fill-stdin-pipe - fill-startup-info dup call-CreateProcess diff --git a/extra/io/windows/nt/pipes/pipes.factor b/extra/io/windows/pipes/pipes.factor similarity index 84% rename from extra/io/windows/nt/pipes/pipes.factor rename to extra/io/windows/pipes/pipes.factor index a10a98bd30..8c2acc4009 100755 --- a/extra/io/windows/nt/pipes/pipes.factor +++ b/extra/io/windows/pipes/pipes.factor @@ -3,19 +3,11 @@ USING: alien alien.c-types arrays destructors io io.windows libc windows.types math windows.kernel32 windows namespaces kernel sequences windows.errors assocs math.parser system random ; -IN: io.windows.nt.pipes +IN: io.windows.pipes ! This code is based on ! http://twistedmatrix.com/trac/browser/trunk/twisted/internet/iocpreactor/process.py -: default-security-attributes ( -- obj ) - "SECURITY_ATTRIBUTES" - "SECURITY_ATTRIBUTES" heap-size over set-SECURITY_ATTRIBUTES-nLength ; - -: security-attributes-inherit ( -- obj ) - default-security-attributes - TRUE over set-SECURITY_ATTRIBUTES-bInheritHandle ; foldable - : create-named-pipe ( name mode -- handle ) FILE_FLAG_OVERLAPPED bitor PIPE_TYPE_BYTE diff --git a/extra/io/windows/windows.factor b/extra/io/windows/windows.factor index 8dcb138999..efac6cb1cc 100755 --- a/extra/io/windows/windows.factor +++ b/extra/io/windows/windows.factor @@ -4,7 +4,7 @@ USING: alien alien.c-types arrays destructors io io.backend io.buffers io.files io.nonblocking io.sockets io.binary io.sockets.impl windows.errors strings io.streams.duplex kernel math namespaces sequences windows windows.kernel32 -windows.shell32 windows.winsock splitting ; +windows.shell32 windows.types windows.winsock splitting ; IN: io.windows TUPLE: windows-nt-io ; @@ -34,6 +34,14 @@ M: windows-io normalize-directory ( string -- string ) FILE_SHARE_READ FILE_SHARE_WRITE bitor FILE_SHARE_DELETE bitor ; foldable +: default-security-attributes ( -- obj ) + "SECURITY_ATTRIBUTES" + "SECURITY_ATTRIBUTES" heap-size over set-SECURITY_ATTRIBUTES-nLength ; + +: security-attributes-inherit ( -- obj ) + default-security-attributes + TRUE over set-SECURITY_ATTRIBUTES-bInheritHandle ; foldable + M: win32-file init-handle ( handle -- ) drop ; From 993684ebb001b01521dd472809b54e4e4d9ddc8a Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 25 Jan 2008 02:21:27 -0400 Subject: [PATCH 77/78] More work in progress --- extra/io/windows/launcher/launcher.factor | 7 ++++--- extra/io/windows/nt/launcher/launcher.factor | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/extra/io/windows/launcher/launcher.factor b/extra/io/windows/launcher/launcher.factor index 6d7a96b069..bd2a4adb6e 100755 --- a/extra/io/windows/launcher/launcher.factor +++ b/extra/io/windows/launcher/launcher.factor @@ -26,11 +26,13 @@ TUPLE: CreateProcess-args "STARTUPINFO" "STARTUPINFO" heap-size over set-STARTUPINFO-cb "PROCESS_INFORMATION" + TRUE { set-CreateProcess-args-bInheritHandles set-CreateProcess-args-dwCreateFlags set-CreateProcess-args-lpStartupInfo set-CreateProcess-args-lpProcessInformation + set-CreateProcess-args-bInheritHandles } \ CreateProcess-args construct ; : call-CreateProcess ( CreateProcess-args -- ) @@ -143,13 +145,12 @@ TUPLE: CreateProcess-args default-CreateProcess-args wince? [ fill-lpApplicationName ] [ fill-lpCommandLine ] if fill-dwCreateFlags - fill-lpEnvironment - fill-startup-info ; + fill-lpEnvironment ; M: windows-io run-process* ( desc -- handle ) [ [ - make-CreateProcess-args + make-CreateProcess-args fill-startup-info dup call-CreateProcess CreateProcess-args-lpProcessInformation ] with-descriptor diff --git a/extra/io/windows/nt/launcher/launcher.factor b/extra/io/windows/nt/launcher/launcher.factor index f548c5945c..c2f14c21bb 100755 --- a/extra/io/windows/nt/launcher/launcher.factor +++ b/extra/io/windows/nt/launcher/launcher.factor @@ -34,10 +34,10 @@ M: windows-io process-stream* [ [ make-CreateProcess-args - TRUE over set-CreateProcess-args-bInheritHandles fill-stdout-pipe fill-stdin-pipe + fill-startup-info dup call-CreateProcess From 76e4702f38b04f23be87671a7d0539a769406708 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 25 Jan 2008 02:37:37 -0400 Subject: [PATCH 78/78] Got Windows launcher redirection working --- extra/io/launcher/launcher-docs.factor | 5 +++++ extra/io/windows/launcher/launcher.factor | 15 +++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/extra/io/launcher/launcher-docs.factor b/extra/io/launcher/launcher-docs.factor index 495894b25d..28063bae0d 100755 --- a/extra/io/launcher/launcher-docs.factor +++ b/extra/io/launcher/launcher-docs.factor @@ -154,9 +154,14 @@ $nl { $subsection +detached+ } { $subsection +environment+ } { $subsection +environment-mode+ } +"Redirecting standard input and output to files:" +{ $subsection +stdin+ } +{ $subsection +stdout+ } +{ $subsection +stderr+ } "The following words are used to launch processes:" { $subsection run-process } { $subsection run-detached } +"Redirecting standard input and output to a pipe:" { $subsection } { $subsection with-process-stream } "A class representing an active or finished process:" diff --git a/extra/io/windows/launcher/launcher.factor b/extra/io/windows/launcher/launcher.factor index bd2a4adb6e..7b793ef74d 100755 --- a/extra/io/windows/launcher/launcher.factor +++ b/extra/io/windows/launcher/launcher.factor @@ -21,14 +21,12 @@ TUPLE: CreateProcess-args stdout-pipe stdin-pipe ; : default-CreateProcess-args ( -- obj ) - 0 0 "STARTUPINFO" "STARTUPINFO" heap-size over set-STARTUPINFO-cb "PROCESS_INFORMATION" TRUE { - set-CreateProcess-args-bInheritHandles set-CreateProcess-args-dwCreateFlags set-CreateProcess-args-lpStartupInfo set-CreateProcess-args-lpProcessInformation @@ -103,25 +101,26 @@ TUPLE: CreateProcess-args : redirect ( obj access-mode create-mode -- handle ) { { [ pick not ] [ 3drop f ] } - { [ pick +closed+ eq? ] [ 3drop f ] } + { [ pick +closed+ eq? ] [ 3drop t ] } { [ pick string? ] [ (redirect) ] } } cond ; +: ?closed or dup t eq? [ drop f ] when ; + : inherited-stdout ( args -- handle ) CreateProcess-args-stdout-pipe [ pipe-out ] [ STD_OUTPUT_HANDLE GetStdHandle ] if* ; : redirect-stdout ( args -- handle ) +stdout+ get GENERIC_WRITE CREATE_ALWAYS redirect - swap inherited-stdout or ; + swap inherited-stdout ?closed ; : inherited-stderr ( args -- handle ) - CreateProcess-args-stdout-pipe - [ pipe-out ] [ STD_ERROR_HANDLE GetStdHandle ] if* ; + drop STD_ERROR_HANDLE GetStdHandle ; : redirect-stderr ( args -- handle ) +stderr+ get GENERIC_WRITE CREATE_ALWAYS redirect - swap inherited-stderr or ; + swap inherited-stderr ?closed ; : inherited-stdin ( args -- handle ) CreateProcess-args-stdin-pipe @@ -129,7 +128,7 @@ TUPLE: CreateProcess-args : redirect-stdin ( args -- handle ) +stdin+ get GENERIC_READ OPEN_EXISTING redirect - swap inherited-stdin or ; + swap inherited-stdin ?closed ; : fill-startup-info dup CreateProcess-args-lpStartupInfo