Fix conflict

db4
Slava Pestov 2008-03-05 15:04:42 -06:00
commit 8da6f2a7f9
60 changed files with 1970 additions and 1877 deletions

View File

@ -116,16 +116,18 @@ HELP: method-spec
{ $class-description "The class of method specifiers, which are two-element arrays consisting of a class word followed by a generic word." }
{ $examples { $code "{ fixnum + }" "{ editor draw-gadget* }" } } ;
HELP: method-body
{ $class-description "The class of method bodies, which are words with special word properties set." } ;
HELP: method
{ $values { "class" class } { "generic" generic } { "method/f" "a " { $link method } " or " { $link f } } }
{ $description "Looks up a method definition." }
{ $class-description "Instances of this class are methods. A method consists of a quotation together with a source location where it was defined." } ;
{ $values { "class" class } { "generic" generic } { "method/f" "a " { $link method-body } " or " { $link f } } }
{ $description "Looks up a method definition." } ;
{ method define-method POSTPONE: M: } related-words
HELP: <method>
{ $values { "def" "a quotation" } { "method" "a new method definition" } }
{ $description "Creates a new "{ $link method } " instance." } ;
{ $description "Creates a new method." } ;
HELP: methods
{ $values { "word" generic } { "assoc" "an association list mapping classes to quotations" } }

View File

@ -33,8 +33,6 @@ M: generic definition drop f ;
dup { "unannotated-def" } reset-props
dup dup "combination" word-prop perform-combination define ;
TUPLE: method word def specializer generic loc ;
: method ( class generic -- method/f )
"methods" word-prop at ;
@ -47,7 +45,7 @@ PREDICATE: pair method-spec
: methods ( word -- assoc )
"methods" word-prop
[ keys sort-classes ] keep
[ dupd at method-word ] curry { } map>assoc ;
[ dupd at ] curry { } map>assoc ;
TUPLE: check-method class generic ;
@ -63,29 +61,33 @@ TUPLE: check-method class generic ;
: method-word-name ( class word -- string )
word-name "/" rot word-name 3append ;
: make-method-def ( quot word combination -- quot )
: make-method-def ( quot class generic -- quot )
"combination" word-prop method-prologue swap append ;
PREDICATE: word method-body "method" word-prop >boolean ;
PREDICATE: word method-body "method-def" word-prop >boolean ;
M: method-body stack-effect
"method" word-prop method-generic stack-effect ;
"method-generic" word-prop stack-effect ;
: <method-word> ( quot class generic -- word )
[ make-method-def ] 2keep
method-word-name f <word>
dup rot define
dup xref ;
: method-word-props ( quot class generic -- assoc )
[
"method-generic" set
"method-class" set
"method-def" set
] H{ } make-assoc ;
: <method> ( quot class generic -- method )
: <method> ( quot class generic -- word )
check-method
[ <method-word> ] 3keep f \ method construct-boa
dup method-word over "method" set-word-prop ;
[ make-method-def ] 3keep
[ method-word-props ] 2keep
method-word-name f <word>
tuck set-word-props
dup rot define ;
: redefine-method ( quot class generic -- )
[ method set-method-def ] 3keep
[ method swap "method-def" set-word-prop ] 3keep
[ make-method-def ] 2keep
method method-word swap define ;
method swap define ;
: define-method ( quot class generic -- )
>r bootstrap-word r>
@ -102,21 +104,22 @@ M: method-body stack-effect
! Definition protocol
M: method-spec where
dup first2 method [ method-word ] [ second ] ?if where ;
dup first2 method [ ] [ second ] ?if where ;
M: method-spec set-where
first2 method method-word set-where ;
first2 method set-where ;
M: method-spec definer
drop \ M: \ ; ;
M: method-spec definition
first2 method dup [ method-def ] when ;
first2 method dup
[ "method-def" word-prop ] when ;
: forget-method ( class generic -- )
check-method
[ delete-at* ] with-methods
[ method-word forget-word ] [ drop ] if ;
[ forget-word ] [ drop ] if ;
M: method-spec forget*
first2 forget-method ;
@ -125,11 +128,11 @@ M: method-body definer
drop \ M: \ ; ;
M: method-body definition
"method" word-prop method-def ;
"method-def" word-prop ;
M: method-body forget*
"method" word-prop
{ method-specializer method-generic } get-slots
dup "method-class" word-prop
swap "method-generic" word-prop
forget-method ;
: implementors* ( classes -- words )
@ -168,8 +171,7 @@ M: word subwords drop f ;
M: generic subwords
dup "methods" word-prop values
swap "default-method" word-prop add
[ method-word ] map ;
swap "default-method" word-prop add ;
M: generic forget-word
dup subwords [ forget-word ] each (forget-word) ;

View File

@ -43,7 +43,7 @@ TUPLE: no-math-method left right generic ;
: applicable-method ( generic class -- quot )
over method
[ method-word word-def ]
[ word-def ]
[ default-math-method ] ?if ;
: object-method ( generic -- quot )

View File

@ -69,7 +69,7 @@ TUPLE: no-method object generic ;
] if ;
: default-method ( word -- pair )
"default-method" word-prop method-word
"default-method" word-prop
object bootstrap-word swap 2array ;
: method-alist>quot ( alist base-class -- quot )

View File

@ -10,8 +10,7 @@ IN: inference.backend
recursive-state get at ;
: inline? ( word -- ? )
dup "method" word-prop
[ method-generic inline? ] [ "inline" word-prop ] ?if ;
dup "method-generic" word-prop swap or "inline" word-prop ;
: local-recursive-state ( -- assoc )
recursive-state get dup keys

View File

@ -9,7 +9,7 @@ IN: listener.tests
<string-reader> stream-read-quot ;
[ [ ] ] [
"USE: temporary hello" parse-interactive
"USE: listener.tests hello" parse-interactive
] unit-test
[

View File

@ -1,208 +1,208 @@
! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays generic assocs inference inference.class
inference.dataflow inference.backend inference.state io kernel
math namespaces sequences vectors words quotations hashtables
combinators classes generic.math continuations optimizer.def-use
optimizer.backend generic.standard optimizer.specializers
optimizer.def-use optimizer.pattern-match generic.standard
optimizer.control kernel.private ;
IN: optimizer.inlining
: remember-inlining ( node history -- )
[ swap set-node-history ] curry each-node ;
: inlining-quot ( node quot -- node )
over node-in-d dataflow-with
dup rot infer-classes/node ;
: splice-quot ( #call quot history -- node )
#! Must add history *before* splicing in, otherwise
#! the rest of the IR will also remember the history
pick node-history append
>r dupd inlining-quot dup r> remember-inlining
tuck splice-node ;
! A heuristic to avoid excessive inlining
DEFER: (flat-length)
: word-flat-length ( word -- n )
{
! heuristic: { ... } declare comes up in method bodies
! and we don't care about it
{ [ dup \ declare eq? ] [ drop -2 ] }
! recursive
{ [ dup get ] [ drop 1 ] }
! not inline
{ [ dup inline? not ] [ drop 1 ] }
! inline
{ [ t ] [ dup dup set word-def (flat-length) ] }
} cond ;
: (flat-length) ( seq -- n )
[
{
{ [ dup quotation? ] [ (flat-length) 1+ ] }
{ [ dup array? ] [ (flat-length) ] }
{ [ dup word? ] [ word-flat-length ] }
{ [ t ] [ drop 1 ] }
} cond
] map sum ;
: flat-length ( seq -- n )
[ word-def (flat-length) ] with-scope ;
! Single dispatch method inlining optimization
: specific-method ( class word -- class ) order min-class ;
: node-class# ( node n -- class )
over node-in-d <reversed> ?nth node-class ;
: dispatching-class ( node word -- class )
[ dispatch# node-class# ] keep specific-method ;
: inline-standard-method ( node word -- node )
2dup dispatching-class dup [
over +inlined+ depends-on
swap method method-word 1quotation f splice-quot
] [
3drop t
] if ;
! Partial dispatch of math-generic words
: math-both-known? ( word left right -- ? )
math-class-max swap specific-method ;
: inline-math-method ( #call word -- node )
over node-input-classes first2 3dup math-both-known?
[ math-method f splice-quot ] [ 2drop 2drop t ] if ;
: inline-method ( #call -- node )
dup node-param {
{ [ dup standard-generic? ] [ inline-standard-method ] }
{ [ dup math-generic? ] [ inline-math-method ] }
{ [ t ] [ 2drop t ] }
} cond ;
! Resolve type checks at compile time where possible
: comparable? ( actual testing -- ? )
#! If actual is a subset of testing or if the two classes
#! are disjoint, return t.
2dup class< >r classes-intersect? not r> or ;
: optimize-predicate? ( #call -- ? )
dup node-param "predicating" word-prop dup [
>r node-class-first r> comparable?
] [
2drop f
] if ;
: literal-quot ( node literals -- quot )
#! Outputs a quotation which drops the node's inputs, and
#! pushes some literals.
>r node-in-d length \ drop <repetition>
r> [ literalize ] map append >quotation ;
: inline-literals ( node literals -- node )
#! Make #shuffle -> #push -> #return -> successor
dupd literal-quot f splice-quot ;
: evaluate-predicate ( #call -- ? )
dup node-param "predicating" word-prop >r
node-class-first r> class< ;
: optimize-predicate ( #call -- node )
#! If the predicate is followed by a branch we fold it
#! immediately
dup evaluate-predicate swap
dup node-successor #if? [
dup drop-inputs >r
node-successor swap 0 1 ? fold-branch
r> [ set-node-successor ] keep
] [
swap 1array inline-literals
] if ;
: optimizer-hooks ( node -- conditions )
node-param "optimizer-hooks" word-prop ;
: optimizer-hook ( node -- pair/f )
dup optimizer-hooks [ first call ] find 2nip ;
: optimize-hook ( node -- )
dup optimizer-hook second call ;
: define-optimizers ( word optimizers -- )
"optimizer-hooks" set-word-prop ;
: flush-eval? ( #call -- ? )
dup node-param "flushable" word-prop [
node-out-d [ unused? ] all?
] [
drop f
] if ;
: flush-eval ( #call -- node )
dup node-param +inlined+ depends-on
dup node-out-d length f <repetition> inline-literals ;
: partial-eval? ( #call -- ? )
dup node-param "foldable" word-prop [
dup node-in-d [ node-literal? ] with all?
] [
drop f
] if ;
: literal-in-d ( #call -- inputs )
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 inline-literals ] [ 2drop 2drop t ] recover ;
: define-identities ( words identities -- )
[ "identities" set-word-prop ] curry each ;
: find-identity ( node -- quot )
[ node-param "identities" word-prop ] keep
[ swap first in-d-match? ] curry find
nip dup [ second ] when ;
: apply-identities ( node -- node/f )
dup find-identity dup [ f splice-quot ] [ 2drop f ] if ;
: optimistic-inline? ( #call -- ? )
dup node-param "specializer" word-prop dup [
>r node-input-classes r> specialized-length tail*
[ types length 1 = ] all?
] [
2drop f
] if ;
: splice-word-def ( #call word -- node )
dup +inlined+ depends-on
dup word-def swap 1array splice-quot ;
: optimistic-inline ( #call -- node )
dup node-param over node-history memq? [
drop t
] [
dup node-param splice-word-def
] if ;
: method-body-inline? ( #call -- ? )
node-param dup method-body?
[ flat-length 10 <= ] [ drop f ] if ;
M: #call optimize-node*
{
{ [ dup flush-eval? ] [ flush-eval ] }
{ [ dup partial-eval? ] [ partial-eval ] }
{ [ dup find-identity ] [ apply-identities ] }
{ [ dup optimizer-hook ] [ optimize-hook ] }
{ [ dup optimize-predicate? ] [ optimize-predicate ] }
{ [ dup optimistic-inline? ] [ optimistic-inline ] }
{ [ dup method-body-inline? ] [ optimistic-inline ] }
{ [ t ] [ inline-method ] }
} cond dup not ;
! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays generic assocs inference inference.class
inference.dataflow inference.backend inference.state io kernel
math namespaces sequences vectors words quotations hashtables
combinators classes generic.math continuations optimizer.def-use
optimizer.backend generic.standard optimizer.specializers
optimizer.def-use optimizer.pattern-match generic.standard
optimizer.control kernel.private ;
IN: optimizer.inlining
: remember-inlining ( node history -- )
[ swap set-node-history ] curry each-node ;
: inlining-quot ( node quot -- node )
over node-in-d dataflow-with
dup rot infer-classes/node ;
: splice-quot ( #call quot history -- node )
#! Must add history *before* splicing in, otherwise
#! the rest of the IR will also remember the history
pick node-history append
>r dupd inlining-quot dup r> remember-inlining
tuck splice-node ;
! A heuristic to avoid excessive inlining
DEFER: (flat-length)
: word-flat-length ( word -- n )
{
! heuristic: { ... } declare comes up in method bodies
! and we don't care about it
{ [ dup \ declare eq? ] [ drop -2 ] }
! recursive
{ [ dup get ] [ drop 1 ] }
! not inline
{ [ dup inline? not ] [ drop 1 ] }
! inline
{ [ t ] [ dup dup set word-def (flat-length) ] }
} cond ;
: (flat-length) ( seq -- n )
[
{
{ [ dup quotation? ] [ (flat-length) 1+ ] }
{ [ dup array? ] [ (flat-length) ] }
{ [ dup word? ] [ word-flat-length ] }
{ [ t ] [ drop 1 ] }
} cond
] map sum ;
: flat-length ( seq -- n )
[ word-def (flat-length) ] with-scope ;
! Single dispatch method inlining optimization
: specific-method ( class word -- class ) order min-class ;
: node-class# ( node n -- class )
over node-in-d <reversed> ?nth node-class ;
: dispatching-class ( node word -- class )
[ dispatch# node-class# ] keep specific-method ;
: inline-standard-method ( node word -- node )
2dup dispatching-class dup [
over +inlined+ depends-on
swap method 1quotation f splice-quot
] [
3drop t
] if ;
! Partial dispatch of math-generic words
: math-both-known? ( word left right -- ? )
math-class-max swap specific-method ;
: inline-math-method ( #call word -- node )
over node-input-classes first2 3dup math-both-known?
[ math-method f splice-quot ] [ 2drop 2drop t ] if ;
: inline-method ( #call -- node )
dup node-param {
{ [ dup standard-generic? ] [ inline-standard-method ] }
{ [ dup math-generic? ] [ inline-math-method ] }
{ [ t ] [ 2drop t ] }
} cond ;
! Resolve type checks at compile time where possible
: comparable? ( actual testing -- ? )
#! If actual is a subset of testing or if the two classes
#! are disjoint, return t.
2dup class< >r classes-intersect? not r> or ;
: optimize-predicate? ( #call -- ? )
dup node-param "predicating" word-prop dup [
>r node-class-first r> comparable?
] [
2drop f
] if ;
: literal-quot ( node literals -- quot )
#! Outputs a quotation which drops the node's inputs, and
#! pushes some literals.
>r node-in-d length \ drop <repetition>
r> [ literalize ] map append >quotation ;
: inline-literals ( node literals -- node )
#! Make #shuffle -> #push -> #return -> successor
dupd literal-quot f splice-quot ;
: evaluate-predicate ( #call -- ? )
dup node-param "predicating" word-prop >r
node-class-first r> class< ;
: optimize-predicate ( #call -- node )
#! If the predicate is followed by a branch we fold it
#! immediately
dup evaluate-predicate swap
dup node-successor #if? [
dup drop-inputs >r
node-successor swap 0 1 ? fold-branch
r> [ set-node-successor ] keep
] [
swap 1array inline-literals
] if ;
: optimizer-hooks ( node -- conditions )
node-param "optimizer-hooks" word-prop ;
: optimizer-hook ( node -- pair/f )
dup optimizer-hooks [ first call ] find 2nip ;
: optimize-hook ( node -- )
dup optimizer-hook second call ;
: define-optimizers ( word optimizers -- )
"optimizer-hooks" set-word-prop ;
: flush-eval? ( #call -- ? )
dup node-param "flushable" word-prop [
node-out-d [ unused? ] all?
] [
drop f
] if ;
: flush-eval ( #call -- node )
dup node-param +inlined+ depends-on
dup node-out-d length f <repetition> inline-literals ;
: partial-eval? ( #call -- ? )
dup node-param "foldable" word-prop [
dup node-in-d [ node-literal? ] with all?
] [
drop f
] if ;
: literal-in-d ( #call -- inputs )
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 inline-literals ] [ 2drop 2drop t ] recover ;
: define-identities ( words identities -- )
[ "identities" set-word-prop ] curry each ;
: find-identity ( node -- quot )
[ node-param "identities" word-prop ] keep
[ swap first in-d-match? ] curry find
nip dup [ second ] when ;
: apply-identities ( node -- node/f )
dup find-identity dup [ f splice-quot ] [ 2drop f ] if ;
: optimistic-inline? ( #call -- ? )
dup node-param "specializer" word-prop dup [
>r node-input-classes r> specialized-length tail*
[ types length 1 = ] all?
] [
2drop f
] if ;
: splice-word-def ( #call word -- node )
dup +inlined+ depends-on
dup word-def swap 1array splice-quot ;
: optimistic-inline ( #call -- node )
dup node-param over node-history memq? [
drop t
] [
dup node-param splice-word-def
] if ;
: method-body-inline? ( #call -- ? )
node-param dup method-body?
[ flat-length 10 <= ] [ drop f ] if ;
M: #call optimize-node*
{
{ [ dup flush-eval? ] [ flush-eval ] }
{ [ dup partial-eval? ] [ partial-eval ] }
{ [ dup find-identity ] [ apply-identities ] }
{ [ dup optimizer-hook ] [ optimize-hook ] }
{ [ dup optimize-predicate? ] [ optimize-predicate ] }
{ [ dup optimistic-inline? ] [ optimistic-inline ] }
{ [ dup method-body-inline? ] [ optimistic-inline ] }
{ [ t ] [ inline-method ] }
} cond dup not ;

View File

@ -1,378 +1,378 @@
USING: arrays compiler.units generic hashtables inference kernel
kernel.private math optimizer prettyprint sequences sbufs
strings tools.test vectors words sequences.private quotations
optimizer.backend classes inference.dataflow tuples.private
continuations growable optimizer.inlining namespaces hints ;
IN: optimizer.tests
[ H{ { 1 5 } { 3 4 } { 2 5 } } ] [
H{ { 1 2 } { 3 4 } } H{ { 2 5 } } union*
] unit-test
[ H{ { 1 4 } { 2 4 } { 3 4 } } ] [
H{ { 1 2 } { 3 4 } } H{ { 2 3 } } union*
] unit-test
! Test method inlining
[ f ] [ fixnum { } min-class ] unit-test
[ string ] [
\ string
[ integer string array reversed sbuf
slice vector quotation ]
sort-classes min-class
] unit-test
[ fixnum ] [
\ fixnum
[ fixnum integer object ]
sort-classes min-class
] unit-test
[ integer ] [
\ fixnum
[ integer float object ]
sort-classes min-class
] unit-test
[ object ] [
\ word
[ integer float object ]
sort-classes min-class
] unit-test
[ reversed ] [
\ reversed
[ integer reversed slice ]
sort-classes min-class
] unit-test
GENERIC: xyz ( obj -- obj )
M: array xyz xyz ;
[ t ] [ \ xyz compiled? ] unit-test
! Test predicate inlining
: pred-test-1
dup fixnum? [
dup integer? [ "integer" ] [ "nope" ] if
] [
"not a fixnum"
] if ;
[ 1 "integer" ] [ 1 pred-test-1 ] unit-test
TUPLE: pred-test ;
: pred-test-2
dup tuple? [
dup pred-test? [ "pred-test" ] [ "nope" ] if
] [
"not a tuple"
] if ;
[ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-2 ] unit-test
: pred-test-3
dup pred-test? [
dup tuple? [ "pred-test" ] [ "nope" ] if
] [
"not a tuple"
] if ;
[ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-3 ] unit-test
: inline-test
"nom" = ;
[ t ] [ "nom" inline-test ] unit-test
[ f ] [ "shayin" inline-test ] unit-test
[ f ] [ 3 inline-test ] unit-test
: fixnum-declarations >fixnum 24 shift 1234 bitxor ;
[ ] [ 1000000 fixnum-declarations . ] unit-test
! regression
: literal-not-branch 0 not [ ] [ ] if ;
[ ] [ literal-not-branch ] unit-test
! regression
: bad-kill-1 ( a b -- c d e ) [ 3 f ] [ dup bad-kill-1 ] if ; inline
: bad-kill-2 bad-kill-1 drop ;
[ 3 ] [ t bad-kill-2 ] unit-test
! regression
: (the-test) ( x -- y ) dup 0 > [ 1- (the-test) ] when ; inline
: the-test ( -- x y ) 2 dup (the-test) ;
[ 2 0 ] [ the-test ] unit-test
! regression
: (double-recursion) ( start end -- )
< [
6 1 (double-recursion)
3 2 (double-recursion)
] when ; inline
: double-recursion 0 2 (double-recursion) ;
[ ] [ double-recursion ] unit-test
! regression
: double-label-1 ( a b c -- d )
[ f double-label-1 ] [ swap nth-unsafe ] if ; inline
: double-label-2 ( a -- b )
dup array? [ ] [ ] if 0 t double-label-1 ;
[ 0 ] [ 10 double-label-2 ] unit-test
! regression
GENERIC: void-generic ( obj -- * )
: breakage "hi" void-generic ;
[ t ] [ \ breakage compiled? ] unit-test
[ breakage ] must-fail
! regression
: test-0 ( n -- ) dup 0 = [ drop ] [ 1- test-0 ] if ; inline
: test-1 ( n -- ) t [ test-0 ] [ delegate dup [ test-1 ] [ drop ] if ] if ; inline
: test-2 ( -- ) 5 test-1 ;
[ f ] [ f test-2 ] unit-test
: branch-fold-regression-0 ( m -- n )
t [ ] [ 1+ branch-fold-regression-0 ] if ; inline
: branch-fold-regression-1 ( -- m )
10 branch-fold-regression-0 ;
[ 10 ] [ branch-fold-regression-1 ] unit-test
! another regression
: constant-branch-fold-0 "hey" ; foldable
: constant-branch-fold-1 constant-branch-fold-0 "hey" = ; inline
[ 1 ] [ [ constant-branch-fold-1 [ 1 ] [ 2 ] if ] compile-call ] unit-test
! another regression
: foo f ;
: bar foo 4 4 = and ;
[ f ] [ bar ] unit-test
! ensure identities are working in some form
[ t ] [
[ { number } declare 0 + ] dataflow optimize
[ #push? ] node-exists? not
] unit-test
! compiling <tuple> with a non-literal class failed
: <tuple>-regression <tuple> ;
[ t ] [ \ <tuple>-regression compiled? ] unit-test
GENERIC: foozul ( a -- b )
M: reversed foozul ;
M: integer foozul ;
M: slice foozul ;
[ reversed ] [ reversed \ foozul specific-method ] unit-test
! regression
: constant-fold-2 f ; foldable
: constant-fold-3 4 ; foldable
[ f t ] [
[ constant-fold-2 constant-fold-3 4 = ] compile-call
] unit-test
: constant-fold-4 f ; foldable
: constant-fold-5 f ; foldable
[ f ] [
[ constant-fold-4 constant-fold-5 or ] compile-call
] unit-test
[ 5 ] [ 5 [ 0 + ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 swap + ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 - ] compile-call ] unit-test
[ -5 ] [ 5 [ 0 swap - ] compile-call ] unit-test
[ 0 ] [ 5 [ dup - ] compile-call ] unit-test
[ 5 ] [ 5 [ 1 * ] compile-call ] unit-test
[ 5 ] [ 5 [ 1 swap * ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 * ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 swap * ] compile-call ] unit-test
[ -5 ] [ 5 [ -1 * ] compile-call ] unit-test
[ -5 ] [ 5 [ -1 swap * ] compile-call ] unit-test
[ 0 ] [ 5 [ 1 mod ] compile-call ] unit-test
[ 0 ] [ 5 [ 1 rem ] compile-call ] unit-test
[ 5 ] [ 5 [ -1 bitand ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 bitand ] compile-call ] unit-test
[ 5 ] [ 5 [ -1 swap bitand ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 swap bitand ] compile-call ] unit-test
[ 5 ] [ 5 [ dup bitand ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 bitor ] compile-call ] unit-test
[ -1 ] [ 5 [ -1 bitor ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 swap bitor ] compile-call ] unit-test
[ -1 ] [ 5 [ -1 swap bitor ] compile-call ] unit-test
[ 5 ] [ 5 [ dup bitor ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 bitxor ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 swap bitxor ] compile-call ] unit-test
[ -6 ] [ 5 [ -1 bitxor ] compile-call ] unit-test
[ -6 ] [ 5 [ -1 swap bitxor ] compile-call ] unit-test
[ 0 ] [ 5 [ dup bitxor ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 swap shift ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 shift ] compile-call ] unit-test
[ f ] [ 5 [ dup < ] compile-call ] unit-test
[ t ] [ 5 [ dup <= ] compile-call ] unit-test
[ f ] [ 5 [ dup > ] compile-call ] unit-test
[ t ] [ 5 [ dup >= ] compile-call ] unit-test
[ t ] [ 5 [ dup eq? ] compile-call ] unit-test
[ t ] [ 5 [ dup = ] compile-call ] unit-test
[ t ] [ 5 [ dup number= ] compile-call ] unit-test
[ t ] [ \ vector [ \ vector = ] compile-call ] unit-test
GENERIC: detect-number ( obj -- obj )
M: number detect-number ;
[ 10 f [ <array> 0 + detect-number ] compile-call ] must-fail
! Regression
[ 4 [ + ] ] [ 2 2 [ [ + ] [ call ] keep ] compile-call ] unit-test
! Regression
USE: sorting
USE: sorting.private
: old-binsearch ( elt quot seq -- elt quot i )
dup length 1 <= [
slice-from
] [
[ midpoint swap call ] 3keep roll dup zero?
[ drop dup slice-from swap midpoint@ + ]
[ partition old-binsearch ] if
] if ; inline
[ 10 ] [
10 20 >vector <flat-slice>
[ [ - ] swap old-binsearch ] compile-call 2nip
] unit-test
! Regression
TUPLE: silly-tuple a b ;
[ 1 2 { silly-tuple-a silly-tuple-b } ] [
T{ silly-tuple f 1 2 }
[
{ silly-tuple-a silly-tuple-b } [ get-slots ] keep
] compile-call
] unit-test
! Regression
: empty-compound ;
: node-successor-f-bug ( x -- * )
[ 3 throw ] [ empty-compound ] compose [ 3 throw ] if ;
[ t ] [ \ node-successor-f-bug compiled? ] unit-test
[ ] [ [ construct-empty ] dataflow optimize drop ] unit-test
[ ] [ [ <tuple> ] dataflow optimize drop ] unit-test
! Make sure we have sane heuristics
: should-inline? method method-word flat-length 10 <= ;
[ t ] [ \ fixnum \ shift should-inline? ] unit-test
[ f ] [ \ array \ equal? should-inline? ] unit-test
[ f ] [ \ sequence \ hashcode* should-inline? ] unit-test
[ t ] [ \ array \ nth-unsafe should-inline? ] unit-test
[ t ] [ \ growable \ nth-unsafe should-inline? ] unit-test
[ t ] [ \ sbuf \ set-nth-unsafe should-inline? ] unit-test
! Regression
: lift-throw-tail-regression
dup integer? [ "an integer" ] [
dup string? [ "a string" ] [
"error" throw
] if
] if ;
[ t ] [ \ lift-throw-tail-regression compiled? ] unit-test
[ 3 "an integer" ] [ 3 lift-throw-tail-regression ] unit-test
[ "hi" "a string" ] [ "hi" lift-throw-tail-regression ] unit-test
: lift-loop-tail-test-1 ( a quot -- )
over even? [
[ >r 3 - r> call ] keep lift-loop-tail-test-1
] [
over 0 < [
2drop
] [
[ >r 2 - r> call ] keep lift-loop-tail-test-1
] if
] if ; inline
: lift-loop-tail-test-2
10 [ ] lift-loop-tail-test-1 1 2 3 ;
[ 1 2 3 ] [ lift-loop-tail-test-2 ] unit-test
! Make sure we don't lose
GENERIC: generic-inline-test ( x -- y )
M: integer generic-inline-test ;
: generic-inline-test-1
1
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test ;
[ { t f } ] [
\ generic-inline-test-1 word-def dataflow
[ optimize-1 , optimize-1 , drop ] { } make
] unit-test
! Forgot a recursive inline check
: recursive-inline-hang ( a -- a )
dup array? [ recursive-inline-hang ] when ;
HINTS: recursive-inline-hang array ;
: recursive-inline-hang-1
{ } recursive-inline-hang ;
[ t ] [ \ recursive-inline-hang-1 compiled? ] unit-test
DEFER: recursive-inline-hang-3
: recursive-inline-hang-2 ( a -- a )
dup array? [ recursive-inline-hang-3 ] when ;
HINTS: recursive-inline-hang-2 array ;
: recursive-inline-hang-3 ( a -- a )
dup array? [ recursive-inline-hang-2 ] when ;
HINTS: recursive-inline-hang-3 array ;
USING: arrays compiler.units generic hashtables inference kernel
kernel.private math optimizer prettyprint sequences sbufs
strings tools.test vectors words sequences.private quotations
optimizer.backend classes inference.dataflow tuples.private
continuations growable optimizer.inlining namespaces hints ;
IN: optimizer.tests
[ H{ { 1 5 } { 3 4 } { 2 5 } } ] [
H{ { 1 2 } { 3 4 } } H{ { 2 5 } } union*
] unit-test
[ H{ { 1 4 } { 2 4 } { 3 4 } } ] [
H{ { 1 2 } { 3 4 } } H{ { 2 3 } } union*
] unit-test
! Test method inlining
[ f ] [ fixnum { } min-class ] unit-test
[ string ] [
\ string
[ integer string array reversed sbuf
slice vector quotation ]
sort-classes min-class
] unit-test
[ fixnum ] [
\ fixnum
[ fixnum integer object ]
sort-classes min-class
] unit-test
[ integer ] [
\ fixnum
[ integer float object ]
sort-classes min-class
] unit-test
[ object ] [
\ word
[ integer float object ]
sort-classes min-class
] unit-test
[ reversed ] [
\ reversed
[ integer reversed slice ]
sort-classes min-class
] unit-test
GENERIC: xyz ( obj -- obj )
M: array xyz xyz ;
[ t ] [ \ xyz compiled? ] unit-test
! Test predicate inlining
: pred-test-1
dup fixnum? [
dup integer? [ "integer" ] [ "nope" ] if
] [
"not a fixnum"
] if ;
[ 1 "integer" ] [ 1 pred-test-1 ] unit-test
TUPLE: pred-test ;
: pred-test-2
dup tuple? [
dup pred-test? [ "pred-test" ] [ "nope" ] if
] [
"not a tuple"
] if ;
[ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-2 ] unit-test
: pred-test-3
dup pred-test? [
dup tuple? [ "pred-test" ] [ "nope" ] if
] [
"not a tuple"
] if ;
[ T{ pred-test } "pred-test" ] [ T{ pred-test } pred-test-3 ] unit-test
: inline-test
"nom" = ;
[ t ] [ "nom" inline-test ] unit-test
[ f ] [ "shayin" inline-test ] unit-test
[ f ] [ 3 inline-test ] unit-test
: fixnum-declarations >fixnum 24 shift 1234 bitxor ;
[ ] [ 1000000 fixnum-declarations . ] unit-test
! regression
: literal-not-branch 0 not [ ] [ ] if ;
[ ] [ literal-not-branch ] unit-test
! regression
: bad-kill-1 ( a b -- c d e ) [ 3 f ] [ dup bad-kill-1 ] if ; inline
: bad-kill-2 bad-kill-1 drop ;
[ 3 ] [ t bad-kill-2 ] unit-test
! regression
: (the-test) ( x -- y ) dup 0 > [ 1- (the-test) ] when ; inline
: the-test ( -- x y ) 2 dup (the-test) ;
[ 2 0 ] [ the-test ] unit-test
! regression
: (double-recursion) ( start end -- )
< [
6 1 (double-recursion)
3 2 (double-recursion)
] when ; inline
: double-recursion 0 2 (double-recursion) ;
[ ] [ double-recursion ] unit-test
! regression
: double-label-1 ( a b c -- d )
[ f double-label-1 ] [ swap nth-unsafe ] if ; inline
: double-label-2 ( a -- b )
dup array? [ ] [ ] if 0 t double-label-1 ;
[ 0 ] [ 10 double-label-2 ] unit-test
! regression
GENERIC: void-generic ( obj -- * )
: breakage "hi" void-generic ;
[ t ] [ \ breakage compiled? ] unit-test
[ breakage ] must-fail
! regression
: test-0 ( n -- ) dup 0 = [ drop ] [ 1- test-0 ] if ; inline
: test-1 ( n -- ) t [ test-0 ] [ delegate dup [ test-1 ] [ drop ] if ] if ; inline
: test-2 ( -- ) 5 test-1 ;
[ f ] [ f test-2 ] unit-test
: branch-fold-regression-0 ( m -- n )
t [ ] [ 1+ branch-fold-regression-0 ] if ; inline
: branch-fold-regression-1 ( -- m )
10 branch-fold-regression-0 ;
[ 10 ] [ branch-fold-regression-1 ] unit-test
! another regression
: constant-branch-fold-0 "hey" ; foldable
: constant-branch-fold-1 constant-branch-fold-0 "hey" = ; inline
[ 1 ] [ [ constant-branch-fold-1 [ 1 ] [ 2 ] if ] compile-call ] unit-test
! another regression
: foo f ;
: bar foo 4 4 = and ;
[ f ] [ bar ] unit-test
! ensure identities are working in some form
[ t ] [
[ { number } declare 0 + ] dataflow optimize
[ #push? ] node-exists? not
] unit-test
! compiling <tuple> with a non-literal class failed
: <tuple>-regression <tuple> ;
[ t ] [ \ <tuple>-regression compiled? ] unit-test
GENERIC: foozul ( a -- b )
M: reversed foozul ;
M: integer foozul ;
M: slice foozul ;
[ reversed ] [ reversed \ foozul specific-method ] unit-test
! regression
: constant-fold-2 f ; foldable
: constant-fold-3 4 ; foldable
[ f t ] [
[ constant-fold-2 constant-fold-3 4 = ] compile-call
] unit-test
: constant-fold-4 f ; foldable
: constant-fold-5 f ; foldable
[ f ] [
[ constant-fold-4 constant-fold-5 or ] compile-call
] unit-test
[ 5 ] [ 5 [ 0 + ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 swap + ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 - ] compile-call ] unit-test
[ -5 ] [ 5 [ 0 swap - ] compile-call ] unit-test
[ 0 ] [ 5 [ dup - ] compile-call ] unit-test
[ 5 ] [ 5 [ 1 * ] compile-call ] unit-test
[ 5 ] [ 5 [ 1 swap * ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 * ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 swap * ] compile-call ] unit-test
[ -5 ] [ 5 [ -1 * ] compile-call ] unit-test
[ -5 ] [ 5 [ -1 swap * ] compile-call ] unit-test
[ 0 ] [ 5 [ 1 mod ] compile-call ] unit-test
[ 0 ] [ 5 [ 1 rem ] compile-call ] unit-test
[ 5 ] [ 5 [ -1 bitand ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 bitand ] compile-call ] unit-test
[ 5 ] [ 5 [ -1 swap bitand ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 swap bitand ] compile-call ] unit-test
[ 5 ] [ 5 [ dup bitand ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 bitor ] compile-call ] unit-test
[ -1 ] [ 5 [ -1 bitor ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 swap bitor ] compile-call ] unit-test
[ -1 ] [ 5 [ -1 swap bitor ] compile-call ] unit-test
[ 5 ] [ 5 [ dup bitor ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 bitxor ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 swap bitxor ] compile-call ] unit-test
[ -6 ] [ 5 [ -1 bitxor ] compile-call ] unit-test
[ -6 ] [ 5 [ -1 swap bitxor ] compile-call ] unit-test
[ 0 ] [ 5 [ dup bitxor ] compile-call ] unit-test
[ 0 ] [ 5 [ 0 swap shift ] compile-call ] unit-test
[ 5 ] [ 5 [ 0 shift ] compile-call ] unit-test
[ f ] [ 5 [ dup < ] compile-call ] unit-test
[ t ] [ 5 [ dup <= ] compile-call ] unit-test
[ f ] [ 5 [ dup > ] compile-call ] unit-test
[ t ] [ 5 [ dup >= ] compile-call ] unit-test
[ t ] [ 5 [ dup eq? ] compile-call ] unit-test
[ t ] [ 5 [ dup = ] compile-call ] unit-test
[ t ] [ 5 [ dup number= ] compile-call ] unit-test
[ t ] [ \ vector [ \ vector = ] compile-call ] unit-test
GENERIC: detect-number ( obj -- obj )
M: number detect-number ;
[ 10 f [ <array> 0 + detect-number ] compile-call ] must-fail
! Regression
[ 4 [ + ] ] [ 2 2 [ [ + ] [ call ] keep ] compile-call ] unit-test
! Regression
USE: sorting
USE: sorting.private
: old-binsearch ( elt quot seq -- elt quot i )
dup length 1 <= [
slice-from
] [
[ midpoint swap call ] 3keep roll dup zero?
[ drop dup slice-from swap midpoint@ + ]
[ partition old-binsearch ] if
] if ; inline
[ 10 ] [
10 20 >vector <flat-slice>
[ [ - ] swap old-binsearch ] compile-call 2nip
] unit-test
! Regression
TUPLE: silly-tuple a b ;
[ 1 2 { silly-tuple-a silly-tuple-b } ] [
T{ silly-tuple f 1 2 }
[
{ silly-tuple-a silly-tuple-b } [ get-slots ] keep
] compile-call
] unit-test
! Regression
: empty-compound ;
: node-successor-f-bug ( x -- * )
[ 3 throw ] [ empty-compound ] compose [ 3 throw ] if ;
[ t ] [ \ node-successor-f-bug compiled? ] unit-test
[ ] [ [ construct-empty ] dataflow optimize drop ] unit-test
[ ] [ [ <tuple> ] dataflow optimize drop ] unit-test
! Make sure we have sane heuristics
: should-inline? method flat-length 10 <= ;
[ t ] [ \ fixnum \ shift should-inline? ] unit-test
[ f ] [ \ array \ equal? should-inline? ] unit-test
[ f ] [ \ sequence \ hashcode* should-inline? ] unit-test
[ t ] [ \ array \ nth-unsafe should-inline? ] unit-test
[ t ] [ \ growable \ nth-unsafe should-inline? ] unit-test
[ t ] [ \ sbuf \ set-nth-unsafe should-inline? ] unit-test
! Regression
: lift-throw-tail-regression
dup integer? [ "an integer" ] [
dup string? [ "a string" ] [
"error" throw
] if
] if ;
[ t ] [ \ lift-throw-tail-regression compiled? ] unit-test
[ 3 "an integer" ] [ 3 lift-throw-tail-regression ] unit-test
[ "hi" "a string" ] [ "hi" lift-throw-tail-regression ] unit-test
: lift-loop-tail-test-1 ( a quot -- )
over even? [
[ >r 3 - r> call ] keep lift-loop-tail-test-1
] [
over 0 < [
2drop
] [
[ >r 2 - r> call ] keep lift-loop-tail-test-1
] if
] if ; inline
: lift-loop-tail-test-2
10 [ ] lift-loop-tail-test-1 1 2 3 ;
[ 1 2 3 ] [ lift-loop-tail-test-2 ] unit-test
! Make sure we don't lose
GENERIC: generic-inline-test ( x -- y )
M: integer generic-inline-test ;
: generic-inline-test-1
1
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test
generic-inline-test ;
[ { t f } ] [
\ generic-inline-test-1 word-def dataflow
[ optimize-1 , optimize-1 , drop ] { } make
] unit-test
! Forgot a recursive inline check
: recursive-inline-hang ( a -- a )
dup array? [ recursive-inline-hang ] when ;
HINTS: recursive-inline-hang array ;
: recursive-inline-hang-1
{ } recursive-inline-hang ;
[ t ] [ \ recursive-inline-hang-1 compiled? ] unit-test
DEFER: recursive-inline-hang-3
: recursive-inline-hang-2 ( a -- a )
dup array? [ recursive-inline-hang-3 ] when ;
HINTS: recursive-inline-hang-2 array ;
: recursive-inline-hang-3 ( a -- a )
dup array? [ recursive-inline-hang-2 ] when ;
HINTS: recursive-inline-hang-3 array ;

View File

@ -24,7 +24,7 @@ IN: parser.tests
[ "hello world" ]
[
"IN: parser.tests : hello \"hello world\" ;"
eval "USE: temporary hello" eval
eval "USE: parser.tests hello" eval
] unit-test
[ ]
@ -104,12 +104,12 @@ IN: parser.tests
"IN: parser.tests USING: math prettyprint ; : foo 2 2 + . ; parsing" eval
[ ] [ "USE: temporary foo" eval ] unit-test
[ ] [ "USE: parser.tests foo" eval ] unit-test
"IN: parser.tests USING: math prettyprint ; : foo 2 2 + . ;" eval
[ t ] [
"USE: temporary \\ foo" eval
"USE: parser.tests \\ foo" eval
"foo" "parser.tests" lookup eq?
] unit-test

View File

@ -125,18 +125,18 @@ unit-test
"IN: prettyprint.tests"
"GENERIC: method-layout"
""
"USING: math temporary ;"
"USING: math prettyprint.tests ;"
"M: complex method-layout"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
" ;"
""
"USING: math temporary ;"
"USING: math prettyprint.tests ;"
"M: fixnum method-layout ;"
""
"USING: math temporary ;"
"USING: math prettyprint.tests ;"
"M: integer method-layout ;"
""
"USING: kernel temporary ;"
"USING: kernel prettyprint.tests ;"
"M: object method-layout ;"
} ;
@ -280,7 +280,7 @@ unit-test
"IN: prettyprint.tests"
"GENERIC: class-see-layout ( x -- y )"
""
"USING: temporary ;"
"USING: prettyprint.tests ;"
"M: class-see-layout class-see-layout ;"
} ;

View File

@ -175,10 +175,10 @@ M: method-spec synopsis*
dup definer. [ pprint-word ] each ;
M: method-body synopsis*
dup definer.
"method" word-prop dup
method-specializer pprint*
method-generic pprint* ;
dup dup
definer.
"method-class" word-prop pprint*
"method-generic" word-prop pprint* ;
M: mixin-instance synopsis*
dup definer.
@ -269,7 +269,7 @@ M: builtin-class see-class*
: see-implementors ( class -- seq )
dup implementors
[ method method-word ] with map
[ method ] with map
natural-sort ;
: see-class ( class -- )
@ -280,9 +280,7 @@ M: builtin-class see-class*
] when drop ;
: see-methods ( generic -- seq )
"methods" word-prop
[ nip method-word ] { } assoc>map
natural-sort ;
"methods" word-prop values natural-sort ;
M: word see
dup see-class

View File

@ -68,7 +68,10 @@ uses definitions ;
: reset-checksums ( -- )
source-files get [
swap ?resource-path dup exists?
[ file-lines swap record-checksum ] [ 2drop ] if
[
over record-modified
file-lines swap record-checksum
] [ 2drop ] if
] assoc-each ;
M: pathname where pathname-string 1 2array ;

View File

@ -55,6 +55,8 @@ M: f vocab-docs-loaded? ;
M: f set-vocab-docs-loaded? 2drop ;
M: f vocab-help ;
: create-vocab ( name -- vocab )
dictionary get [ <vocab> ] cache ;

View File

@ -68,7 +68,7 @@ SYMBOL: bootstrapping?
: crossref? ( word -- ? )
{
{ [ dup "forgotten" word-prop ] [ f ] }
{ [ dup "method" word-prop ] [ t ] }
{ [ dup "method-definition" word-prop ] [ t ] }
{ [ dup word-vocabulary ] [ t ] }
{ [ t ] [ f ] }
} cond nip ;

View File

@ -1,65 +1,58 @@
USING: io.sockets io kernel math threads
debugger tools.time prettyprint concurrency.count-downs
namespaces arrays continuations ;
IN: benchmark.sockets
SYMBOL: counter
: number-of-requests 1 ;
: server-addr "127.0.0.1" 7777 <inet4> ;
: server-loop ( server -- )
dup accept [
[
read1 CHAR: x = [
"server" get dispose
] [
number-of-requests
[ read1 write1 flush ] times
counter get count-down
] if
] with-stream
] curry "Client handler" spawn drop server-loop ;
: simple-server ( -- )
[
server-addr <server> dup "server" set [
server-loop
] with-disposal
] ignore-errors ;
: simple-client ( -- )
server-addr <client> [
CHAR: b write1 flush
number-of-requests
[ CHAR: a dup write1 flush read1 assert= ] times
counter get count-down
] with-stream ;
: stop-server ( -- )
server-addr <client> [
CHAR: x write1
] with-stream ;
: clients ( n -- )
dup pprint " clients: " write [
dup 2 * <count-down> counter set
[ simple-server ] "Simple server" spawn drop
yield yield
[ [ simple-client ] "Simple client" spawn drop ] times
counter get await
stop-server
yield yield
] time ;
: socket-benchmarks
10 clients
20 clients
40 clients ;
! 80 clients
! 160 clients
! 320 clients
! 640 clients ;
MAIN: socket-benchmarks
USING: io.sockets io kernel math threads
debugger tools.time prettyprint concurrency.count-downs
namespaces arrays continuations ;
IN: benchmark.sockets
SYMBOL: counter
: number-of-requests 1 ;
: server-addr "127.0.0.1" 7777 <inet4> ;
: server-loop ( server -- )
dup accept [
[
read1 CHAR: x = [
"server" get dispose
] [
number-of-requests
[ read1 write1 flush ] times
counter get count-down
] if
] with-stream
] curry "Client handler" spawn drop server-loop ;
: simple-server ( -- )
[
server-addr <server> dup "server" set [
server-loop
] with-disposal
] ignore-errors ;
: simple-client ( -- )
server-addr <client> [
CHAR: b write1 flush
number-of-requests
[ CHAR: a dup write1 flush read1 assert= ] times
counter get count-down
] with-stream ;
: stop-server ( -- )
server-addr <client> [
CHAR: x write1
] with-stream ;
: clients ( n -- )
dup pprint " clients: " write [
dup 2 * <count-down> counter set
[ simple-server ] "Simple server" spawn drop
yield yield
[ [ simple-client ] "Simple client" spawn drop ] times
counter get await
stop-server
yield yield
] time ;
: socket-benchmarks ;
MAIN: socket-benchmarks

View File

@ -43,8 +43,6 @@ IN: builder
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! : target ( -- target ) { os [ cpu "." split ] } to-strings "-" join ;
: make-vm ( -- desc )
<process*>
{ "make" } >>arguments
@ -110,7 +108,7 @@ SYMBOL: build-status
"Build machine: " write host-name print
"CPU: " write cpu print
"OS: " write os print
"Build directory: " write cwd print nl
"Build directory: " write cwd print
git-clone [ "git clone failed" print ] run-or-bail
@ -127,6 +125,8 @@ SYMBOL: build-status
"test-log" delete-file
"git id: " write "git-id" eval-file print nl
"Boot time: " write "boot-time" eval-file milli-seconds>time print
"Load time: " write "load-time" eval-file milli-seconds>time print
"Test time: " write "test-time" eval-file milli-seconds>time print nl

View File

@ -3,7 +3,7 @@ USING: kernel words namespaces classes parser continuations
io io.files io.launcher io.sockets
math math.parser
combinators sequences splitting quotations arrays strings tools.time
parser-combinators new-slots accessors assocs.lib
sequences.deep new-slots accessors assocs.lib
combinators.cleave bake calendar calendar.format ;
IN: builder.util
@ -108,4 +108,4 @@ USE: prettyprint
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: failsafe ( quot -- ) [ drop ] recover ;
: failsafe ( quot -- ) [ drop ] recover ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: arrays assocs classes continuations kernel math
namespaces sequences sequences.lib tuples words strings
tools.walker ;
tools.walker new-slots accessors ;
IN: db
TUPLE: db
@ -25,10 +25,10 @@ HOOK: db-close db ( handle -- )
: dispose-db ( db -- )
dup db [
dup db-insert-statements dispose-statements
dup db-update-statements dispose-statements
dup db-delete-statements dispose-statements
db-handle db-close
dup insert-statements>> dispose-statements
dup update-statements>> dispose-statements
dup delete-statements>> dispose-statements
handle>> db-close
] with-variable ;
TUPLE: statement handle sql in-params out-params bind-params bound? ;
@ -36,11 +36,7 @@ TUPLE: simple-statement ;
TUPLE: prepared-statement ;
TUPLE: result-set sql params handle n max ;
: <statement> ( sql in out -- statement )
{
set-statement-sql
set-statement-in-params
set-statement-out-params
} statement construct ;
{ (>>sql) (>>in-params) (>>out-params) } statement construct ;
HOOK: <simple-statement> db ( str in out -- statement )
HOOK: <prepared-statement> db ( str in out -- statement )
@ -62,21 +58,18 @@ GENERIC: more-rows? ( result-set -- ? )
] if ;
: bind-statement ( obj statement -- )
[ set-statement-bind-params ] keep
swap >>bind-params
[ bind-statement* ] keep
t swap set-statement-bound? ;
t >>bound? drop ;
: init-result-set ( result-set -- )
dup #rows over set-result-set-max
0 swap set-result-set-n ;
dup #rows >>max
0 >>n drop ;
: <result-set> ( query handle tuple -- result-set )
>r >r { statement-sql statement-in-params } get-slots r>
{
set-result-set-sql
set-result-set-params
set-result-set-handle
} result-set construct r> construct-delegate ;
>r >r { sql>> in-params>> } get-slots r>
{ (>>sql) (>>params) (>>handle) } result-set
construct r> construct-delegate ;
: sql-row ( result-set -- seq )
dup #columns [ row-column ] with map ;

View File

@ -33,24 +33,6 @@ IN: db.postgresql.tests
] with-db
] unit-test
[
{ { "John" "America" } }
] [
test-db [
"select * from person where name = $1 and country = $2"
f f <simple-statement> [
{ { "Jane" TEXT } { "New Zealand" TEXT } }
over do-bound-query
{ { "Jane" "New Zealand" } } =
[ "test fails" throw ] unless
{ { "John" TEXT } { "America" TEXT } }
swap do-bound-query
] with-disposal
] with-db
] unit-test
[
{
{ "John" "America" }
@ -111,244 +93,3 @@ IN: db.postgresql.tests
: with-dummy-db ( quot -- )
>r T{ postgresql-db } db r> with-variable ;
! TEST TUPLE DB
TUPLE: puppy id name age ;
: <puppy> ( name age -- puppy )
{ set-puppy-name set-puppy-age } puppy construct ;
puppy "PUPPY" {
{ "id" "ID" +native-id+ +not-null+ }
{ "name" "NAME" { VARCHAR 256 } }
{ "age" "AGE" INTEGER }
} define-persistent
TUPLE: kitty id name age ;
: <kitty> ( name age -- kitty )
{ set-kitty-name set-kitty-age } kitty construct ;
kitty "KITTY" {
{ "id" "ID" INTEGER +assigned-id+ }
{ "name" "NAME" TEXT }
{ "age" "AGE" INTEGER }
} define-persistent
TUPLE: basket id puppies kitties ;
basket "BASKET"
{
{ "id" "ID" +native-id+ +not-null+ }
{ "location" "LOCATION" TEXT }
{ "puppies" { +has-many+ puppy } }
{ "kitties" { +has-many+ kitty } }
} define-persistent
! Create table
[
"create table puppy(id serial primary key not null, name varchar 256, age integer);"
] [
T{ postgresql-db } db [
puppy dup db-columns swap db-table create-table-sql >lower
] with-variable
] unit-test
[
"create table kitty(id integer primary key, name text, age integer);"
] [
T{ postgresql-db } db [
kitty dup db-columns swap db-table create-table-sql >lower
] with-variable
] unit-test
[
"create table basket(id serial primary key not null, location text);"
] [
T{ postgresql-db } db [
basket dup db-columns swap db-table create-table-sql >lower
] with-variable
] unit-test
! Create function
[
"create function add_puppy(varchar,integer) returns bigint as 'insert into puppy(name, age) values($1, $2); select currval(''puppy_id_seq'');' language sql;"
] [
T{ postgresql-db } db [
puppy dup db-columns swap db-table create-function-sql >lower
] with-variable
] unit-test
! Drop table
[
"drop table puppy;"
] [
T{ postgresql-db } db [
puppy db-table drop-table-sql >lower
] with-variable
] unit-test
[
"drop table kitty;"
] [
T{ postgresql-db } db [
kitty db-table drop-table-sql >lower
] with-variable
] unit-test
[
"drop table basket;"
] [
T{ postgresql-db } db [
basket db-table drop-table-sql >lower
] with-variable
] unit-test
! Drop function
[
"drop function add_puppy(varchar, integer);"
] [
T{ postgresql-db } db [
puppy dup db-columns swap db-table drop-function-sql >lower
] with-variable
] unit-test
! Insert
[
] [
T{ postgresql-db } db [
puppy <insert-native-statement>
] with-variable
] unit-test
[
"insert into kitty(id, name, age) values($1, $2, $3);"
{
T{
sql-spec
f
"id"
"ID"
INTEGER
{ +assigned-id+ }
+assigned-id+
}
T{ sql-spec f "name" "NAME" TEXT { } f }
T{ sql-spec f "age" "AGE" INTEGER { } f }
}
{ }
] [
T{ postgresql-db } db [
kitty <insert-assigned-statement>
] with-variable
] unit-test
! Update
[
"update puppy set name = $1, age = $2 where id = $3"
{
T{ sql-spec f "name" "NAME" { VARCHAR 256 } { } f }
T{ sql-spec f "age" "AGE" INTEGER { } f }
T{
sql-spec
f
"id"
"ID"
+native-id+
{ +not-null+ }
+native-id+
}
}
{ }
] [
T{ postgresql-db } db [
puppy dup db-columns swap db-table <update-tuple-statement> >r >r >lower r> r>
] with-variable
] unit-test
[
"update kitty set name = $1, age = $2 where id = $3"
{
T{ sql-spec f "name" "NAME" TEXT { } f }
T{ sql-spec f "age" "AGE" INTEGER { } f }
T{
sql-spec
f
"id"
"ID"
INTEGER
{ +assigned-id+ }
+assigned-id+
}
}
{ }
] [
T{ postgresql-db } db [
kitty dup db-columns swap db-table <update-tuple-statement> >r >r >lower r> r>
] with-variable
] unit-test
! Delete
[
"delete from puppy where id = $1"
{
T{
sql-spec
f
"id"
"ID"
+native-id+
{ +not-null+ }
+native-id+
}
}
{ }
] [
T{ postgresql-db } db [
puppy dup db-columns swap db-table <delete-tuple-statement> >r >r >lower r> r>
] with-variable
] unit-test
[
"delete from KITTY where ID = $1"
{
T{
sql-spec
f
"id"
"ID"
INTEGER
{ +assigned-id+ }
+assigned-id+
}
}
{ }
] [
T{ postgresql-db } db [
kitty dup db-columns swap db-table <delete-tuple-statement>
] with-variable
] unit-test
! Select
[
"select from PUPPY ID, NAME, AGE where NAME = $1;"
{ T{ sql-spec f "name" "NAME" { VARCHAR 256 } { } f } }
{
T{
sql-spec
f
"id"
"ID"
+native-id+
{ +not-null+ }
+native-id+
}
T{ sql-spec f "name" "NAME" { VARCHAR 256 } { } f }
T{ sql-spec f "age" "AGE" INTEGER { } f }
}
] [
T{ postgresql-db } db [
T{ puppy f f "Mr. Clunkers" }
<select-by-slots-statement>
] with-variable
] unit-test

View File

@ -3,49 +3,34 @@ prettyprint tools.test db.sqlite db sequences
continuations db.types db.tuples unicode.case ;
IN: db.sqlite.tests
: test.db "extra/db/sqlite/test.db" resource-path ;
: db-path "extra/db/sqlite/test.db" resource-path ;
: test.db db-path sqlite-db ;
[ ] [ [ test.db delete-file ] ignore-errors ] unit-test
[ ] [ [ db-path delete-file ] ignore-errors ] unit-test
[ ] [
test.db [
"create table person (name varchar(30), country varchar(30))" sql-command
"insert into person values('John', 'America')" sql-command
"insert into person values('Jane', 'New Zealand')" sql-command
] with-sqlite
] with-db
] unit-test
[ { { "John" "America" } { "Jane" "New Zealand" } } ] [
test.db [
"select * from person" sql-query
] with-sqlite
] unit-test
[ { { "John" "America" } } ] [
test.db [
"select * from person where name = :name and country = :country"
<simple-statement> [
{ { ":name" "Jane" TEXT } { ":country" "New Zealand" TEXT } }
over do-bound-query
{ { "Jane" "New Zealand" } } =
[ "test fails" throw ] unless
{ { ":name" "John" TEXT } { ":country" "America" TEXT } }
swap do-bound-query
] with-disposal
] with-sqlite
] with-db
] unit-test
[ { { "1" "John" "America" } { "2" "Jane" "New Zealand" } } ]
[ test.db [ "select rowid, * from person" sql-query ] with-sqlite ] unit-test
[ test.db [ "select rowid, * from person" sql-query ] with-db ] unit-test
[ ] [
test.db [
"insert into person(name, country) values('Jimmy', 'Canada')"
sql-command
] with-sqlite
] with-db
] unit-test
[
@ -54,7 +39,7 @@ IN: db.sqlite.tests
{ "2" "Jane" "New Zealand" }
{ "3" "Jimmy" "Canada" }
}
] [ test.db [ "select rowid, * from person" sql-query ] with-sqlite ] unit-test
] [ test.db [ "select rowid, * from person" sql-query ] with-db ] unit-test
[
test.db [
@ -63,13 +48,13 @@ IN: db.sqlite.tests
"insert into person(name, country) values('Jose', 'Mexico')" sql-command
"oops" throw
] with-transaction
] with-sqlite
] with-db
] must-fail
[ 3 ] [
test.db [
"select * from person" sql-query length
] with-sqlite
] with-db
] unit-test
[
@ -81,166 +66,11 @@ IN: db.sqlite.tests
"insert into person(name, country) values('Jose', 'Mexico')"
sql-command
] with-transaction
] with-sqlite
] with-db
] unit-test
[ 5 ] [
test.db [
"select * from person" sql-query length
] with-sqlite
] unit-test
! TEST TUPLE DB
TUPLE: puppy id name age ;
: <puppy> ( name age -- puppy )
{ set-puppy-name set-puppy-age } puppy construct ;
puppy "PUPPY" {
{ "id" "ID" +native-id+ +not-null+ }
{ "name" "NAME" { VARCHAR 256 } }
{ "age" "AGE" INTEGER }
} define-persistent
TUPLE: kitty id name age ;
: <kitty> ( name age -- kitty )
{ set-kitty-name set-kitty-age } kitty construct ;
kitty "KITTY" {
{ "id" "ID" INTEGER +assigned-id+ }
{ "name" "NAME" TEXT }
{ "age" "AGE" INTEGER }
} define-persistent
TUPLE: basket id puppies kitties ;
basket "BASKET"
{
{ "id" "ID" +native-id+ +not-null+ }
{ "location" "LOCATION" TEXT }
{ "puppies" { +has-many+ puppy } }
{ "kitties" { +has-many+ kitty } }
} define-persistent
! Create table
[
"create table puppy(id integer primary key not null, name varchar, age integer);"
] [
T{ sqlite-db } db [
puppy dup db-columns swap db-table create-sql >lower
] with-variable
] unit-test
[
"create table kitty(id integer primary key, name text, age integer);"
] [
T{ sqlite-db } db [
kitty dup db-columns swap db-table create-sql >lower
] with-variable
] unit-test
[
"create table basket(id integer primary key not null, location text);"
] [
T{ sqlite-db } db [
basket dup db-columns swap db-table create-sql >lower
] with-variable
] unit-test
! Drop table
[
"drop table puppy;"
] [
T{ sqlite-db } db [
puppy db-table drop-sql >lower
] with-variable
] unit-test
[
"drop table kitty;"
] [
T{ sqlite-db } db [
kitty db-table drop-sql >lower
] with-variable
] unit-test
[
"drop table basket;"
] [
T{ sqlite-db } db [
basket db-table drop-sql >lower
] with-variable
] unit-test
! Insert
[
"insert into puppy(name, age) values(:name, :age);"
] [
T{ sqlite-db } db [
puppy dup db-columns swap db-table insert-sql* >lower
] with-variable
] unit-test
[
"insert into kitty(id, name, age) values(:id, :name, :age);"
] [
T{ sqlite-db } db [
kitty dup db-columns swap db-table insert-sql* >lower
] with-variable
] unit-test
! Update
[
"update puppy set name = :name, age = :age where id = :id"
] [
T{ sqlite-db } db [
puppy dup db-columns swap db-table update-sql* >lower
] with-variable
] unit-test
[
"update kitty set name = :name, age = :age where id = :id"
] [
T{ sqlite-db } db [
kitty dup db-columns swap db-table update-sql* >lower
] with-variable
] unit-test
! Delete
[
"delete from puppy where id = :id"
] [
T{ sqlite-db } db [
puppy dup db-columns swap db-table delete-sql* >lower
] with-variable
] unit-test
[
"delete from kitty where id = :id"
] [
T{ sqlite-db } db [
kitty dup db-columns swap db-table delete-sql* >lower
] with-variable
] unit-test
! Select
[
"select from puppy id, name, age where name = :name;"
{
T{
sql-spec
f
"id"
"ID"
+native-id+
{ +not-null+ }
+native-id+
}
T{ sql-spec f "name" "NAME" { VARCHAR 256 } { } f }
T{ sql-spec f "age" "AGE" INTEGER { } f }
}
] [
T{ sqlite-db } db [
T{ puppy f f "Mr. Clunkers" }
select-sql >r >lower r>
] with-variable
] with-db
] unit-test

View File

@ -5,7 +5,7 @@ hashtables io.files kernel math math.parser namespaces
prettyprint sequences strings tuples alien.c-types
continuations db.sqlite.lib db.sqlite.ffi db.tuples
words combinators.lib db.types combinators tools.walker
combinators.cleave ;
combinators.cleave io ;
IN: db.sqlite
TUPLE: sqlite-db path ;
@ -173,7 +173,9 @@ M: sqlite-db <select-by-slots-statement> ( tuple class -- statement )
" from " 0% 0%
[ sql-spec-slot-name swap get-slot-named ] with subset
dup empty? [ drop ] [
dup empty? [
drop
] [
" where " 0%
[ ", " 0% ]
[ dup sql-spec-column-name 0% " = " 0% bind% ] interleave

View File

@ -41,73 +41,73 @@ SYMBOL: the-person2
T{ person f 2 "johnny" 10 3.14 }
}
] [ T{ person f f f f 3.14 } select-tuples ] unit-test
[
{
T{ person f 1 "billy" 200 3.14 }
T{ person f 2 "johnny" 10 3.14 }
}
] [ T{ person f } select-tuples ] unit-test
[ ] [ the-person1 get delete-tuple ] unit-test
[ f ] [ T{ person f 1 } select-tuple ] unit-test
[ ] [ person drop-table ] unit-test ;
: test-sqlite ( -- )
"tuples-test.db" resource-path sqlite-db [
test-tuples
] with-db ;
: make-native-person-table ( -- )
[ person drop-table ] [ drop ] recover
person create-table
T{ person f f "billy" 200 3.14 } insert-tuple
T{ person f f "johnny" 10 3.14 } insert-tuple
;
: test-postgresql ( -- )
{ "localhost" "postgres" "" "factor-test" } postgresql-db [
test-tuples
] with-db ;
: native-person-schema ( -- )
person "PERSON"
{
{ "the-id" "ID" +native-id+ }
{ "the-name" "NAME" { VARCHAR 256 } +not-null+ }
{ "the-number" "AGE" INTEGER { +default+ 0 } }
{ "the-real" "REAL" DOUBLE { +default+ 0.3 } }
} define-persistent
"billy" 10 3.14 <person> the-person1 set
"johnny" 10 3.14 <person> the-person2 set ;
person "PERSON"
{
{ "the-id" "ID" +native-id+ }
{ "the-name" "NAME" { VARCHAR 256 } +not-null+ }
{ "the-number" "AGE" INTEGER { +default+ 0 } }
{ "the-real" "REAL" DOUBLE { +default+ 0.3 } }
} define-persistent
: assigned-person-schema ( -- )
person "PERSON"
{
{ "the-id" "ID" INTEGER +assigned-id+ }
{ "the-name" "NAME" { VARCHAR 256 } +not-null+ }
{ "the-number" "AGE" INTEGER { +default+ 0 } }
{ "the-real" "REAL" DOUBLE { +default+ 0.3 } }
} define-persistent
1 "billy" 10 3.14 <assigned-person> the-person1 set
2 "johnny" 10 3.14 <assigned-person> the-person2 set ;
"billy" 10 3.14 <person> the-person1 set
"johnny" 10 3.14 <person> the-person2 set
test-sqlite
! test-postgresql
person "PERSON"
{
{ "the-id" "ID" INTEGER +assigned-id+ }
{ "the-name" "NAME" { VARCHAR 256 } +not-null+ }
{ "the-number" "AGE" INTEGER { +default+ 0 } }
{ "the-real" "REAL" DOUBLE { +default+ 0.3 } }
} define-persistent
1 "billy" 10 3.14 <assigned-person> the-person1 set
2 "johnny" 10 3.14 <assigned-person> the-person2 set
test-sqlite
! test-postgresql
TUPLE: paste n summary author channel mode contents timestamp annotations ;
TUPLE: annotation n paste-id summary author mode contents ;
paste "PASTE"
{
{ "n" "ID" +native-id+ }
{ "summary" "SUMMARY" TEXT }
{ "author" "AUTHOR" TEXT }
{ "channel" "CHANNEL" TEXT }
{ "mode" "MODE" TEXT }
{ "contents" "CONTENTS" TEXT }
{ "date" "DATE" TIMESTAMP }
{ "annotations" { +has-many+ annotation } }
} define-persistent
: native-paste-schema ( -- )
paste "PASTE"
{
{ "n" "ID" +native-id+ }
{ "summary" "SUMMARY" TEXT }
{ "author" "AUTHOR" TEXT }
{ "channel" "CHANNEL" TEXT }
{ "mode" "MODE" TEXT }
{ "contents" "CONTENTS" TEXT }
{ "date" "DATE" TIMESTAMP }
{ "annotations" { +has-many+ annotation } }
} define-persistent
annotation "ANNOTATION"
{
{ "n" "ID" +native-id+ }
{ "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "n" } }
{ "summary" "SUMMARY" TEXT }
{ "author" "AUTHOR" TEXT }
{ "mode" "MODE" TEXT }
{ "contents" "CONTENTS" TEXT }
} define-persistent
annotation "ANNOTATION"
{
{ "n" "ID" +native-id+ }
{ "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "n" } }
{ "summary" "SUMMARY" TEXT }
{ "author" "AUTHOR" TEXT }
{ "mode" "MODE" TEXT }
{ "contents" "CONTENTS" TEXT }
} define-persistent ;
! { "localhost" "postgres" "" "factor-test" } postgresql-db [
! [ paste drop-table ] [ drop ] recover
@ -117,3 +117,15 @@ annotation "ANNOTATION"
! [ ] [ paste create-table ] unit-test
! [ ] [ annotation create-table ] unit-test
! ] with-db
: test-sqlite ( quot -- )
>r "tuples-test.db" resource-path sqlite-db r> with-db ;
: test-postgresql ( -- )
>r { "localhost" "postgres" "" "factor-test" } postgresql-db r> with-db ;
[ native-person-schema test-tuples ] test-sqlite
[ assigned-person-schema test-tuples ] test-sqlite
! [ make-native-person-table ] test-sqlite

46
extra/farkup/farkup-tests.factor Normal file → Executable file
View File

@ -1,42 +1,44 @@
USING: farkup kernel tools.test ;
IN: farkup.tests
[ "<ul><li>foo</li></ul>" ] [ "-foo" parse-farkup ] unit-test
[ "<ul><li>foo</li></ul>\n" ] [ "-foo\n" parse-farkup ] unit-test
[ "<ul><li>foo</li><li>bar</li></ul>" ] [ "-foo\n-bar" parse-farkup ] unit-test
[ "<ul><li>foo</li><li>bar</li></ul>\n" ] [ "-foo\n-bar\n" parse-farkup ] unit-test
[ "<ul><li>foo</li></ul>" ] [ "-foo" convert-farkup ] unit-test
[ "<ul><li>foo</li></ul>\n" ] [ "-foo\n" convert-farkup ] unit-test
[ "<ul><li>foo</li><li>bar</li></ul>" ] [ "-foo\n-bar" convert-farkup ] unit-test
[ "<ul><li>foo</li><li>bar</li></ul>\n" ] [ "-foo\n-bar\n" convert-farkup ] unit-test
[ "<ul><li>foo</li></ul>\n<p>bar\n</p>" ] [ "-foo\nbar\n" parse-farkup ] unit-test
[ "<p>*foo\nbar\n</p>" ] [ "*foo\nbar\n" parse-farkup ] unit-test
[ "<p><strong>Wow!</strong></p>" ] [ "*Wow!*" parse-farkup ] unit-test
[ "<p><em>Wow.</em></p>" ] [ "_Wow._" parse-farkup ] unit-test
[ "<ul><li>foo</li></ul>\n<p>bar\n</p>" ] [ "-foo\nbar\n" convert-farkup ] unit-test
[ "<p>*foo\nbar\n</p>" ] [ "*foo\nbar\n" convert-farkup ] unit-test
[ "<p><strong>Wow!</strong></p>" ] [ "*Wow!*" convert-farkup ] unit-test
[ "<p><em>Wow.</em></p>" ] [ "_Wow._" convert-farkup ] unit-test
[ "<p>*</p>" ] [ "*" parse-farkup ] unit-test
[ "<p>*</p>" ] [ "\\*" parse-farkup ] unit-test
[ "<p>**</p>" ] [ "\\**" parse-farkup ] unit-test
[ "<p>*</p>" ] [ "*" convert-farkup ] unit-test
[ "<p>*</p>" ] [ "\\*" convert-farkup ] unit-test
[ "<p>**</p>" ] [ "\\**" convert-farkup ] unit-test
[ "" ] [ "\n\n" parse-farkup ] unit-test
[ "\n" ] [ "\n\n\n" parse-farkup ] unit-test
[ "<p>foo</p><p>bar</p>" ] [ "foo\n\nbar" parse-farkup ] unit-test
[ "" ] [ "\n\n" convert-farkup ] unit-test
[ "\n" ] [ "\n\n\n" convert-farkup ] unit-test
[ "<p>foo</p><p>bar</p>" ] [ "foo\n\nbar" convert-farkup ] unit-test
[ "\n<p>bar\n</p>" ] [ "\nbar\n" parse-farkup ] unit-test
[ "\n<p>bar\n</p>" ] [ "\nbar\n" convert-farkup ] unit-test
[ "<p>foo</p>\n<p>bar</p>" ] [ "foo\n\n\nbar" parse-farkup ] unit-test
[ "<p>foo</p>\n<p>bar</p>" ] [ "foo\n\n\nbar" convert-farkup ] unit-test
[ "" ] [ "" parse-farkup ] unit-test
[ "" ] [ "" convert-farkup ] unit-test
[ "<p>|a</p>" ]
[ "|a" parse-farkup ] unit-test
[ "|a" convert-farkup ] unit-test
[ "<p>|a|</p>" ]
[ "|a|" parse-farkup ] unit-test
[ "|a|" convert-farkup ] unit-test
[ "<table><tr><td>a</td><td>b</td></tr></table>" ]
[ "a|b" parse-farkup ] unit-test
[ "a|b" convert-farkup ] unit-test
[ "<table><tr><td>a</td><td>b</td></tr></table>\n<table><tr><td>c</td><td>d</td></tr></table>" ]
[ "a|b\nc|d" parse-farkup ] unit-test
[ "a|b\nc|d" convert-farkup ] unit-test
[ "<table><tr><td>a</td><td>b</td></tr></table>\n<table><tr><td>c</td><td>d</td></tr></table>\n" ]
[ "a|b\nc|d\n" parse-farkup ] unit-test
[ "a|b\nc|d\n" convert-farkup ] unit-test
[ "<p><strong>foo</strong>\n</p><h1>aheading</h1>\n<p>adfasd</p>" ]
[ "*foo*\n=aheading=\nadfasd" convert-farkup ] unit-test

45
extra/farkup/farkup.factor Normal file → Executable file
View File

@ -1,24 +1,20 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays io kernel memoize namespaces peg
peg.ebnf sequences strings html.elements xml.entities
xmode.code2html splitting io.streams.string html
html.elements sequences.deep ascii ;
! unicode.categories ;
USE: tools.walker
USING: arrays io kernel memoize namespaces peg sequences strings
html.elements xml.entities xmode.code2html splitting
io.streams.string html peg.parsers html.elements sequences.deep
unicode.categories ;
IN: farkup
MEMO: any-char ( -- parser ) [ drop t ] satisfy ;
: delimiters ( -- string )
"*_^~%=[-|\\\n" ; inline
"*_^~%[-=|\\\n" ; inline
MEMO: text ( -- parser )
[ delimiters member? not ] satisfy repeat1
[ >string escape-string ] action ;
MEMO: delimiter ( -- parser )
[ dup delimiters member? swap CHAR: \n = not and ] satisfy
[ dup delimiters member? swap "\n=" member? not and ] satisfy
[ 1string ] action ;
: surround-with-foo ( string tag -- seq )
@ -39,12 +35,12 @@ MEMO: emphasis ( -- parser ) "_" "em" delimited ;
MEMO: superscript ( -- parser ) "^" "sup" delimited ;
MEMO: subscript ( -- parser ) "~" "sub" delimited ;
MEMO: inline-code ( -- parser ) "%" "code" delimited ;
MEMO: nl ( -- parser ) "\n" token ;
MEMO: 2nl ( -- parser ) "\n\n" token hide ;
MEMO: h1 ( -- parser ) "=" "h1" delimited ;
MEMO: h2 ( -- parser ) "==" "h2" delimited ;
MEMO: h3 ( -- parser ) "===" "h3" delimited ;
MEMO: h4 ( -- parser ) "====" "h4" delimited ;
MEMO: nl ( -- parser ) "\n" token ;
MEMO: 2nl ( -- parser ) "\n\n" token hide ;
: render-code ( string mode -- string' )
>r string-lines r>
@ -87,7 +83,7 @@ MEMO: table-column ( -- parser )
MEMO: table-row ( -- parser )
[
table-column "|" token hide list-of* ,
table-column "|" token hide list-of-many ,
] seq* [ "tr" surround-with-foo ] action ;
MEMO: table ( -- parser )
@ -121,28 +117,13 @@ MEMO: paragraph ( -- parser )
[ "<p>" swap "</p>" 3array ] unless
] action ;
MEMO: farkup ( -- parser )
PEG: parse-farkup ( -- parser )
[
list , table , h1 , h2 , h3 , h4 , code , paragraph , 2nl , nl ,
] choice* repeat0 "\n" token optional 2seq ;
: farkup. ( parse-result -- )
parse-result-ast
: write-farkup ( parse-result -- )
[ dup string? [ write ] [ drop ] if ] deep-each ;
: parse-farkup ( string -- string' )
farkup parse [ farkup. ] with-string-writer ;
! MEMO: table-column ( -- parser )
! text [ "td" surround-with-foo ] action ;
!
! MEMO: table-row ( -- parser )
! [
! "|" token hide ,
! table-column "|" token hide list-of ,
! "|" token "\n" token 2array choice hide ,
! ] seq* [ "tr" surround-with-foo ] action ;
!
! MEMO: table ( -- parser )
! table-row repeat1
! [ "table" surround-with-foo ] action ;
: convert-farkup ( string -- string' )
parse-farkup [ write-farkup ] with-string-writer ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: kernel peg strings promises sequences math math.parser
namespaces words quotations arrays hashtables io
io.streams.string assocs memoize ascii ;
io.streams.string assocs memoize ascii peg.parsers ;
IN: fjsc
TUPLE: ast-number value ;

View File

@ -1,42 +1,46 @@
IN: fry.tests
USING: fry tools.test math prettyprint kernel io arrays
sequences ;
[ [ 3 + ] ] [ 3 '[ , + ] ] unit-test
[ [ 1 3 + ] ] [ 1 3 '[ , , + ] ] unit-test
[ [ 1 + ] ] [ 1 [ + ] '[ , @ ] ] unit-test
[ [ 1 + . ] ] [ 1 [ + ] '[ , @ . ] ] unit-test
[ [ + - ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test
[ [ "a" write "b" print ] ]
[ "a" "b" '[ , write , print ] ] unit-test
[ [ 1 2 + 3 4 - ] ]
[ [ + ] [ - ] '[ 1 2 @ 3 4 @ ] ] unit-test
[ 1/2 ] [
1 '[ , _ / ] 2 swap call
] unit-test
[ { { 1 "a" "A" } { 1 "b" "B" } { 1 "c" "C" } } ] [
1 '[ , _ _ 3array ]
{ "a" "b" "c" } { "A" "B" "C" } rot 2map
] unit-test
[ { { 1 "a" } { 1 "b" } { 1 "c" } } ] [
'[ 1 _ 2array ]
{ "a" "b" "c" } swap map
] unit-test
[ { { 1 "a" 2 } { 1 "b" 2 } { 1 "c" 2 } } ] [
1 2 '[ , _ , 3array ]
{ "a" "b" "c" } swap map
] unit-test
: funny-dip '[ @ _ ] call ; inline
[ "hi" 3 ] [ "h" "i" 3 [ append ] funny-dip ] unit-test
IN: fry.tests
USING: fry tools.test math prettyprint kernel io arrays
sequences ;
[ [ 3 + ] ] [ 3 '[ , + ] ] unit-test
[ [ 1 3 + ] ] [ 1 3 '[ , , + ] ] unit-test
[ [ 1 + ] ] [ 1 [ + ] '[ , @ ] ] unit-test
[ [ 1 + . ] ] [ 1 [ + ] '[ , @ . ] ] unit-test
[ [ + - ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test
[ [ "a" write "b" print ] ]
[ "a" "b" '[ , write , print ] ] unit-test
[ [ 1 2 + 3 4 - ] ]
[ [ + ] [ - ] '[ 1 2 @ 3 4 @ ] ] unit-test
[ 1/2 ] [
1 '[ , _ / ] 2 swap call
] unit-test
[ { { 1 "a" "A" } { 1 "b" "B" } { 1 "c" "C" } } ] [
1 '[ , _ _ 3array ]
{ "a" "b" "c" } { "A" "B" "C" } rot 2map
] unit-test
[ { { 1 "a" } { 1 "b" } { 1 "c" } } ] [
'[ 1 _ 2array ]
{ "a" "b" "c" } swap map
] unit-test
[ 1 2 ] [
1 2 '[ _ , ] call
] unit-test
[ { { 1 "a" 2 } { 1 "b" 2 } { 1 "c" 2 } } ] [
1 2 '[ , _ , 3array ]
{ "a" "b" "c" } swap map
] unit-test
: funny-dip '[ @ _ ] call ; inline
[ "hi" 3 ] [ "h" "i" 3 [ append ] funny-dip ] unit-test

View File

@ -1,39 +1,44 @@
! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences combinators parser splitting
quotations ;
IN: fry
: , "Only valid inside a fry" throw ;
: @ "Only valid inside a fry" throw ;
: _ "Only valid inside a fry" throw ;
DEFER: (fry)
: ((fry)) ( accum quot adder -- result )
>r [ ] swap (fry) r>
append swap dup empty? [ drop ] [
[ swap compose ] curry append
] if ; inline
: (fry) ( accum quot -- result )
dup empty? [
drop 1quotation
] [
unclip {
{ , [ [ curry ] ((fry)) ] }
{ @ [ [ compose ] ((fry)) ] }
[ swap >r add r> (fry) ]
} case
] if ;
: trivial-fry ( quot -- quot' ) [ ] swap (fry) ;
: fry ( quot -- quot' )
{ _ } last-split1 [
>r fry [ [ dip ] curry ] r> trivial-fry [ compose ] compose 3compose
] [
trivial-fry
] if* ;
: '[ \ ] parse-until fry over push-all ; parsing
! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences combinators parser splitting
quotations arrays namespaces ;
IN: fry
: , "Only valid inside a fry" throw ;
: @ "Only valid inside a fry" throw ;
: _ "Only valid inside a fry" throw ;
DEFER: (fry)
: ((fry)) ( accum quot adder -- result )
>r [ ] swap (fry) r>
append swap dup empty? [ drop ] [
[ swap compose ] curry append
] if ; inline
: (fry) ( accum quot -- result )
dup empty? [
drop 1quotation
] [
unclip {
{ , [ [ curry ] ((fry)) ] }
{ @ [ [ compose ] ((fry)) ] }
[ swap >r add r> (fry) ]
} case
] if ;
: trivial-fry ( quot -- quot' ) [ ] swap (fry) ;
: fry ( quot -- quot' )
{ _ } last-split1 [
[
trivial-fry %
[ >r ] %
fry %
[ [ dip ] curry r> compose ] %
] [ ] make
] [
trivial-fry
] if* ;
: '[ \ ] parse-until fry over push-all ; parsing

2
extra/furnace/furnace-tests.factor Normal file → Executable file
View File

@ -39,7 +39,7 @@ TUPLE: test-tuple m n ;
] unit-test
[
"/responder/temporary/foo?foo=3"
"/responder/furnace.tests/foo?foo=3"
] [
[
[ "3" foo ] quot-link

View File

@ -16,7 +16,7 @@ IN: help.definitions.tests
[ t ] [ "hello" articles get key? ] unit-test
[ t ] [ "hello2" articles get key? ] unit-test
[ t ] [
"hello" "help.definitions" lookup "help" word-prop >boolean
"hello" "help.definitions.tests" lookup "help" word-prop >boolean
] unit-test
[ 2 ] [
@ -29,12 +29,12 @@ IN: help.definitions.tests
[ t ] [ "hello" articles get key? ] unit-test
[ f ] [ "hello2" articles get key? ] unit-test
[ f ] [
"hello" "help.definitions" lookup "help" word-prop
"hello" "help.definitions.tests" lookup "help" word-prop
] unit-test
[ ] [ "IN: help.definitions.tests USING: help.syntax ; : xxx ; HELP: xxx ;" eval ] unit-test
[ ] [ "xxx" "help.definitions" lookup help ] unit-test
[ ] [ "xxx" "help.definitions.tests" lookup help ] unit-test
[ ] [ "xxx" "help.definitions" lookup >link synopsis print ] unit-test
[ ] [ "xxx" "help.definitions.tests" lookup >link synopsis print ] unit-test
] with-file-vocabs

26
extra/help/markup/markup.factor Normal file → Executable file
View File

@ -144,20 +144,32 @@ M: f print-element drop ;
: $link ( element -- )
first ($link) ;
: ($subsection) ( object -- )
[ article-title ] keep >link write-object ;
: ($long-link) ( object -- )
dup article-title swap >link write-link ;
: $subsection ( element -- )
: ($subsection) ( element quot -- )
[
subsection-style get [
bullet get write bl
first ($subsection)
call
] with-style
] ($block) ;
] ($block) ; inline
: ($vocab-link) ( vocab -- ) dup f >vocab-link write-link ;
: $subsection ( element -- )
[ first ($long-link) ] ($subsection) ;
: $vocab-link ( element -- ) first ($vocab-link) ;
: ($vocab-link) ( text vocab -- ) f >vocab-link write-link ;
: $vocab-subsection ( element -- )
[
first2 dup vocab-help dup [
2nip ($long-link)
] [
drop ($vocab-link)
] if
] ($subsection) ;
: $vocab-link ( element -- ) first dup ($vocab-link) ;
: $vocabulary ( element -- )
first word-vocabulary [

View File

@ -4,18 +4,18 @@ USING: tools.test parser vocabs help.syntax namespaces ;
[
[ "foobar" ] [
"IN: help.syntax.tests USE: help.syntax ABOUT: \"foobar\"" eval
"help.syntax" vocab vocab-help
"help.syntax.tests" vocab vocab-help
] unit-test
[ { "foobar" } ] [
"IN: help.syntax.tests USE: help.syntax ABOUT: { \"foobar\" }" eval
"help.syntax" vocab vocab-help
"help.syntax.tests" vocab vocab-help
] unit-test
SYMBOL: xyz
[ xyz ] [
"IN: help.syntax.tests USE: help.syntax ABOUT: xyz" eval
"help.syntax" vocab vocab-help
"help.syntax.tests" vocab vocab-help
] unit-test
] with-file-vocabs

View File

@ -1,5 +0,0 @@
USING: io.backend ;
IN: io.files.temporary.backend
HOOK: (temporary-file) io-backend ( path -- stream path )
HOOK: temporary-path io-backend ( -- path )

View File

@ -1,32 +0,0 @@
USING: kernel math math.bitfields combinators.lib math.parser
random sequences sequences.lib continuations namespaces
io.files io.backend io.nonblocking io arrays
io.files.temporary.backend system combinators vocabs.loader ;
IN: io.files.temporary
: random-letter ( -- ch ) 26 random { CHAR: a CHAR: A } random + ;
: random-ch ( -- ch )
{ t f } random [ 10 random CHAR: 0 + ] [ random-letter ] if ;
: random-name ( n -- string ) [ drop random-ch ] "" map-as ;
: <temporary-file> ( prefix suffix -- path duplex-stream )
temporary-path -rot
[ 10 random-name swap 3append path+ dup (temporary-file) ] 3curry
10 retry ;
: with-temporary-file ( quot -- path )
>r f f <temporary-file> r> with-stream ;
: temporary-directory ( -- path )
[ temporary-path 10 random-name path+ dup make-directory ] 10 retry ;
: with-temporary-directory ( quot -- )
>r temporary-directory r>
[ with-directory ] 2keep drop delete-tree ;
{
{ [ unix? ] [ "io.unix.files.temporary" ] }
{ [ windows? ] [ "io.windows.files.temporary" ] }
} cond require

View File

@ -35,33 +35,43 @@ HELP: +environment-mode+
HELP: +stdin+
{ $description "Launch descriptor key. Must equal one of the following:"
{ $list
{ { $link f } " - standard input is inherited" }
{ { $link f } " - standard input is either inherited from the current process, or is a " { $link <process-stream> } " pipe" }
{ { $link +inherit+ } " - standard input is inherited from the current process" }
{ { $link +closed+ } " - standard input is closed" }
{ "a path name - standard input is read from the given file, which must exist" }
{ "a file stream or a socket - standard input is read from the given stream, which must be closed after the process has been started" }
}
} ;
HELP: +stdout+
{ $description "Launch descriptor key. Must equal one of the following:"
{ $list
{ { $link f } " - standard output is inherited" }
{ { $link f } " - standard output is either inherited from the current process, or is a " { $link <process-stream> } " pipe" }
{ { $link +inherit+ } " - standard output is inherited from the current process" }
{ { $link +closed+ } " - standard output is closed" }
{ "a path name - standard output is written to the given file, which is overwritten if it already exists" }
{ "a file stream or a socket - standard output is written to the given stream, which must be closed after the process has been started" }
}
} ;
HELP: +stderr+
{ $description "Launch descriptor key. Must equal one of the following:"
{ $list
{ { $link f } " - standard error is inherited" }
{ { $link f } " - standard error is inherited from the current process" }
{ { $link +inherit+ } " - same as above" }
{ { $link +stdout+ } " - standard error is merged with standard output" }
{ { $link +closed+ } " - standard error is closed" }
{ "a path name - standard error is written to the given file, which is overwritten if it already exists" }
{ "a file stream or a socket - standard error is written to the given stream, which must be closed after the process has been started" }
}
} ;
HELP: +closed+
{ $description "Possible value for " { $link +stdin+ } ", " { $link +stdout+ } ", and " { $link +stderr+ } " launch descriptors." } ;
HELP: +inherit+
{ $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

View File

@ -1,8 +1,9 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: io io.backend io.timeouts system kernel namespaces
strings hashtables sequences assocs combinators vocabs.loader
init threads continuations math ;
USING: io io.backend io.nonblocking io.streams.duplex
io.timeouts system kernel namespaces strings hashtables
sequences assocs combinators vocabs.loader init threads
continuations math ;
IN: io.launcher
! Non-blocking process exit notification facility
@ -35,13 +36,16 @@ SYMBOL: +environment-mode+
SYMBOL: +stdin+
SYMBOL: +stdout+
SYMBOL: +stderr+
SYMBOL: +closed+
SYMBOL: +timeout+
SYMBOL: +prepend-environment+
SYMBOL: +replace-environment+
SYMBOL: +append-environment+
SYMBOL: +closed+
SYMBOL: +inherit+
: default-descriptor
H{
{ +command+ f }
@ -141,3 +145,12 @@ TUPLE: process-stream process ;
[ set-process-status ] keep
[ processes get delete-at* drop [ resume ] each ] keep
f swap set-process-handle ;
GENERIC: underlying-handle ( stream -- handle )
M: port underlying-handle port-handle ;
M: duplex-stream underlying-handle
dup duplex-stream-in underlying-handle
swap duplex-stream-out underlying-handle tuck =
[ "Invalid duplex stream" throw ] when ;

107
extra/io/unix/launcher/launcher-tests.factor Executable file → Normal file
View File

@ -1,33 +1,80 @@
IN: io.unix.launcher.tests
USING: io.unix.launcher tools.test ;
USING: io.files tools.test io.launcher arrays io namespaces
continuations math ;
[ "" tokenize-command ] must-fail
[ " " tokenize-command ] must-fail
[ { "a" } ] [ "a" tokenize-command ] unit-test
[ { "abc" } ] [ "abc" tokenize-command ] unit-test
[ { "abc" } ] [ "abc " tokenize-command ] unit-test
[ { "abc" } ] [ " abc" tokenize-command ] unit-test
[ { "abc" "def" } ] [ "abc def" tokenize-command ] unit-test
[ { "abc def" } ] [ "abc\\ def" tokenize-command ] unit-test
[ { "abc\\" "def" } ] [ "abc\\\\ def" tokenize-command ] unit-test
[ { "abc\\ def" } ] [ "'abc\\\\ def'" tokenize-command ] unit-test
[ { "abc\\ def" } ] [ " 'abc\\\\ def'" tokenize-command ] unit-test
[ { "abc\\ def" "hey" } ] [ "'abc\\\\ def' hey" tokenize-command ] unit-test
[ { "abc def" "hey" } ] [ "'abc def' \"hey\"" tokenize-command ] unit-test
[ "'abc def' \"hey" tokenize-command ] must-fail
[ "'abc def" tokenize-command ] must-fail
[ { "abc def" "h\"ey" } ] [ "'abc def' \"h\\\"ey\" " tokenize-command ] unit-test
[
{
"Hello world.app/Contents/MacOS/hello-ui"
"-i=boot.macosx-ppc.image"
"-include= math compiler ui"
"-deploy-vocab=hello-ui"
"-output-image=Hello world.app/Contents/Resources/hello-ui.image"
"-no-stack-traces"
"-no-user-init"
}
] [
"\"Hello world.app/Contents/MacOS/hello-ui\" -i=boot.macosx-ppc.image \"-include= math compiler ui\" -deploy-vocab=hello-ui \"-output-image=Hello world.app/Contents/Resources/hello-ui.image\" -no-stack-traces -no-user-init" tokenize-command
[ ] [
[ "launcher-test-1" temp-file delete-file ] ignore-errors
] unit-test
[ ] [
"touch"
"launcher-test-1" temp-file
2array
try-process
] unit-test
[ t ] [ "launcher-test-1" temp-file exists? ] unit-test
[ ] [
[ "launcher-test-1" temp-file delete-file ] ignore-errors
] unit-test
[ ] [
[
"echo Hello" +command+ set
"launcher-test-1" temp-file +stdout+ set
] { } make-assoc try-process
] unit-test
[ "Hello\n" ] [
"cat"
"launcher-test-1" temp-file
2array
<process-stream> contents
] unit-test
[ "" ] [
[
"cat"
"launcher-test-1" temp-file
2array +arguments+ set
+inherit+ +stdout+ set
] { } make-assoc <process-stream> contents
] unit-test
[ ] [
[ "launcher-test-1" temp-file delete-file ] ignore-errors
] unit-test
[ ] [
[
"cat" +command+ set
+closed+ +stdin+ set
"launcher-test-1" temp-file +stdout+ set
] { } make-assoc try-process
] unit-test
[ "" ] [
"cat"
"launcher-test-1" temp-file
2array
<process-stream> contents
] unit-test
[ ] [
2 [
"launcher-test-1" temp-file <file-appender> [
[
+stdout+ set
"echo Hello" +command+ set
] { } make-assoc try-process
] with-disposal
] times
] unit-test
[ "Hello\nHello\n" ] [
"cat"
"launcher-test-1" temp-file
2array
<process-stream> contents
] unit-test

View File

@ -1,56 +1,45 @@
! 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.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 unix ;
USING: io io.backend io.launcher io.nonblocking io.unix.backend
io.unix.files io.nonblocking sequences kernel namespaces math
system alien.c-types debugger continuations arrays assocs
combinators unix.process strings threads unix
io.unix.launcher.parser ;
IN: io.unix.launcher
! Search unix first
USE: unix
! Our command line parser. Supported syntax:
! foo bar baz -- simple tokens
! foo\ bar -- escaping the space
! 'foo bar' -- quotation
! "foo bar" -- quotation
LAZY: 'escaped-char' "\\" token any-char-parser &> ;
LAZY: 'quoted-char' ( delimiter -- parser' )
'escaped-char'
swap [ member? not ] curry satisfy
<|> ; inline
LAZY: 'quoted' ( delimiter -- parser )
dup 'quoted-char' <!*> swap dup surrounded-by ;
LAZY: 'unquoted' ( -- parser ) " '\"" 'quoted-char' <!+> ;
LAZY: 'argument' ( -- parser )
"\"" 'quoted' "'" 'quoted' 'unquoted' <|> <|>
[ >string ] <@ ;
MEMO: 'arguments' ( -- parser )
'argument' " " token <!+> nonempty-list-of ;
: tokenize-command ( command -- arguments )
'arguments' just parse-1 ;
: get-arguments ( -- seq )
+command+ get [ tokenize-command ] [ +arguments+ get ] if* ;
: assoc>env ( assoc -- env )
[ "=" swap 3append ] { } assoc>map ;
: (redirect) ( path mode fd -- )
>r file-mode open dup io-error dup
r> dup2 io-error close ;
: redirect-fd ( oldfd fd -- )
2dup = [ 2drop ] [ dupd dup2 io-error close ] if ;
: reset-fd ( fd -- ) F_SETFL 0 fcntl io-error ;
: redirect-inherit ( obj mode fd -- )
2nip reset-fd ;
: redirect-file ( obj mode fd -- )
>r file-mode open dup io-error r> redirect-fd ;
: redirect-closed ( obj mode fd -- )
>r >r drop "/dev/null" r> r> redirect-file ;
: redirect-stream ( obj mode fd -- )
>r drop underlying-handle dup reset-fd r> redirect-fd ;
: redirect ( obj mode fd -- )
{
{ [ pick not ] [ 2nip F_SETFL 0 fcntl io-error ] }
{ [ pick string? ] [ (redirect) ] }
{ [ pick not ] [ redirect-inherit ] }
{ [ pick string? ] [ redirect-file ] }
{ [ pick +closed+ eq? ] [ redirect-closed ] }
{ [ pick +inherit+ eq? ] [ redirect-closed ] }
{ [ t ] [ redirect-stream ] }
} cond ;
: ?closed dup +closed+ eq? [ drop "/dev/null" ] when ;

View File

@ -0,0 +1,33 @@
IN: io.unix.launcher.parser.tests
USING: io.unix.launcher.parser tools.test ;
[ "" tokenize-command ] must-fail
[ " " tokenize-command ] must-fail
[ V{ "a" } ] [ "a" tokenize-command ] unit-test
[ V{ "abc" } ] [ "abc" tokenize-command ] unit-test
[ V{ "abc" } ] [ "abc " tokenize-command ] unit-test
[ V{ "abc" } ] [ " abc" tokenize-command ] unit-test
[ V{ "abc" "def" } ] [ "abc def" tokenize-command ] unit-test
[ V{ "abc def" } ] [ "abc\\ def" tokenize-command ] unit-test
[ V{ "abc\\" "def" } ] [ "abc\\\\ def" tokenize-command ] unit-test
[ V{ "abc\\ def" } ] [ "'abc\\\\ def'" tokenize-command ] unit-test
[ V{ "abc\\ def" } ] [ " 'abc\\\\ def'" tokenize-command ] unit-test
[ V{ "abc\\ def" "hey" } ] [ "'abc\\\\ def' hey" tokenize-command ] unit-test
[ V{ "abc def" "hey" } ] [ "'abc def' \"hey\"" tokenize-command ] unit-test
[ "'abc def' \"hey" tokenize-command ] must-fail
[ "'abc def" tokenize-command ] must-fail
[ V{ "abc def" "h\"ey" } ] [ "'abc def' \"h\\\"ey\" " tokenize-command ] unit-test
[
V{
"Hello world.app/Contents/MacOS/hello-ui"
"-i=boot.macosx-ppc.image"
"-include= math compiler ui"
"-deploy-vocab=hello-ui"
"-output-image=Hello world.app/Contents/Resources/hello-ui.image"
"-no-stack-traces"
"-no-user-init"
}
] [
"\"Hello world.app/Contents/MacOS/hello-ui\" -i=boot.macosx-ppc.image \"-include= math compiler ui\" -deploy-vocab=hello-ui \"-output-image=Hello world.app/Contents/Resources/hello-ui.image\" -no-stack-traces -no-user-init" tokenize-command
] unit-test

View File

@ -0,0 +1,34 @@
! Copyright (C) 2008 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
USING: peg peg.parsers kernel sequences strings words
memoize ;
IN: io.unix.launcher.parser
! Our command line parser. Supported syntax:
! foo bar baz -- simple tokens
! foo\ bar -- escaping the space
! 'foo bar' -- quotation
! "foo bar" -- quotation
MEMO: 'escaped-char' ( -- parser )
"\\" token [ drop t ] satisfy 2seq [ second ] action ;
MEMO: 'quoted-char' ( delimiter -- parser' )
'escaped-char'
swap [ member? not ] curry satisfy
2choice ; inline
MEMO: 'quoted' ( delimiter -- parser )
dup 'quoted-char' repeat0 swap dup surrounded-by ;
MEMO: 'unquoted' ( -- parser ) " '\"" 'quoted-char' repeat1 ;
MEMO: 'argument' ( -- parser )
"\"" 'quoted'
"'" 'quoted'
'unquoted' 3choice
[ >string ] action ;
PEG: tokenize-command ( command -- ast/f )
'argument' " " token repeat1 list-of
" " token repeat0 swap over pack
just ;

View File

@ -0,0 +1,108 @@
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: alien.c-types io.files io.windows kernel
math windows windows.kernel32 combinators.cleave
windows.time calendar combinators math.functions
sequences combinators.lib namespaces words ;
IN: io.windows.files
SYMBOL: +read-only+
SYMBOL: +hidden+
SYMBOL: +system+
SYMBOL: +directory+
SYMBOL: +archive+
SYMBOL: +device+
SYMBOL: +normal+
SYMBOL: +temporary+
SYMBOL: +sparse-file+
SYMBOL: +reparse-point+
SYMBOL: +compressed+
SYMBOL: +offline+
SYMBOL: +not-content-indexed+
SYMBOL: +encrypted+
: expand-constants ( word/obj -- obj'/obj )
dup word? [ execute ] when ;
: get-flags ( n seq -- seq' )
[
[
first2 expand-constants
[ swapd mask? [ , ] [ drop ] if ] 2curry
] map call-with
] { } make ;
: win32-file-attributes ( n -- seq )
{
{ +read-only+ FILE_ATTRIBUTE_READONLY }
{ +hidden+ FILE_ATTRIBUTE_HIDDEN }
{ +system+ FILE_ATTRIBUTE_SYSTEM }
{ +directory+ FILE_ATTRIBUTE_DIRECTORY }
{ +archive+ FILE_ATTRIBUTE_ARCHIVE }
{ +device+ FILE_ATTRIBUTE_DEVICE }
{ +normal+ FILE_ATTRIBUTE_NORMAL }
{ +temporary+ FILE_ATTRIBUTE_TEMPORARY }
{ +sparse-file+ FILE_ATTRIBUTE_SPARSE_FILE }
{ +reparse-point+ FILE_ATTRIBUTE_REPARSE_POINT }
{ +compressed+ FILE_ATTRIBUTE_COMPRESSED }
{ +offline+ FILE_ATTRIBUTE_OFFLINE }
{ +not-content-indexed+ FILE_ATTRIBUTE_NOT_CONTENT_INDEXED }
{ +encrypted+ FILE_ATTRIBUTE_ENCRYPTED }
} get-flags ;
: WIN32_FIND_DATA>file-info
{
[ WIN32_FIND_DATA-dwFileAttributes win32-file-attributes ]
[
[ WIN32_FIND_DATA-nFileSizeLow ]
[ WIN32_FIND_DATA-nFileSizeHigh ] bi >64bit
]
[ WIN32_FIND_DATA-dwFileAttributes ]
[
WIN32_FIND_DATA-ftLastWriteTime FILETIME>timestamp
]
} cleave
\ file-info construct-boa ;
: find-first-file-stat ( path -- WIN32_FIND_DATA )
"WIN32_FIND_DATA" <c-object> [
FindFirstFile
[ INVALID_HANDLE_VALUE = [ win32-error ] when ] keep
FindClose win32-error=0/f
] keep ;
: BY_HANDLE_FILE_INFORMATION>file-info
{
[ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-attributes ]
[
[ BY_HANDLE_FILE_INFORMATION-nFileSizeLow ]
[ BY_HANDLE_FILE_INFORMATION-nFileSizeHigh ] bi >64bit
]
[ BY_HANDLE_FILE_INFORMATION-dwFileAttributes ]
[
BY_HANDLE_FILE_INFORMATION-ftLastWriteTime
FILETIME>timestamp
]
} cleave
\ file-info construct-boa ;
: get-file-information ( handle -- BY_HANDLE_FILE_INFORMATION )
[
"BY_HANDLE_FILE_INFORMATION" <c-object>
[ GetFileInformationByHandle win32-error=0/f ] keep
] keep CloseHandle win32-error=0/f ;
: get-file-information-stat ( path -- BY_HANDLE_FILE_INFORMATION )
dup
GENERIC_READ FILE_SHARE_READ f
OPEN_EXISTING FILE_FLAG_BACKUP_SEMANTICS f
CreateFileW dup INVALID_HANDLE_VALUE = [
drop find-first-file-stat WIN32_FIND_DATA>file-info
] [
nip
get-file-information BY_HANDLE_FILE_INFORMATION>file-info
] if ;
M: windows-nt-io file-info ( path -- info )
get-file-information-stat ;

View File

@ -1,10 +0,0 @@
USING: io.files.temporary.backend io.nonblocking io.windows
kernel system windows.kernel32 ;
IN: io.windows.files.temporary
M: windows-io (temporary-file) ( path -- stream )
GENERIC_WRITE CREATE_NEW 0 open-file 0 <win32-file> <writer> ;
M: windows-io temporary-path ( -- path )
"TEMP" os-env ;

View File

@ -1,18 +1,38 @@
! 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 strings
io.windows.launcher io.windows.nt.pipes io.backend
combinators ;
combinators shuffle ;
IN: io.windows.nt.launcher
: duplicate-handle ( handle -- handle' )
GetCurrentProcess ! source process
swap ! handle
GetCurrentProcess ! target process
f <void*> [ ! target handle
DUPLICATE_SAME_ACCESS ! desired access
TRUE ! inherit handle
DUPLICATE_CLOSE_SOURCE ! options
DuplicateHandle win32-error=0/f
] keep *void* ;
! The below code is based on the example given in
! http://msdn2.microsoft.com/en-us/library/ms682499.aspx
: (redirect) ( path access-mode create-mode -- handle )
>r >r
: redirect-default ( default obj access-mode create-mode -- handle )
3drop ;
: redirect-inherit ( default obj access-mode create-mode -- handle )
4drop f ;
: redirect-closed ( default obj access-mode create-mode -- handle )
drop 2nip null-pipe ;
: redirect-file ( default path access-mode create-mode -- handle )
>r >r >r drop r>
normalize-pathname
r> ! access-mode
share-mode
@ -22,47 +42,59 @@ IN: io.windows.nt.launcher
f ! template file
CreateFile dup invalid-handle? dup close-later ;
: redirect ( obj access-mode create-mode -- handle )
{
{ [ pick not ] [ 3drop f ] }
{ [ pick +closed+ eq? ] [ drop nip null-pipe ] }
{ [ 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 ?closed ;
: inherited-stderr ( args -- handle )
drop STD_ERROR_HANDLE GetStdHandle ;
: redirect-stderr ( args -- handle )
+stderr+ get
dup +stdout+ eq? [
drop
CreateProcess-args-lpStartupInfo STARTUPINFO-hStdOutput
] [
GENERIC_WRITE CREATE_ALWAYS redirect
swap inherited-stderr ?closed
] if ;
: 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 ?closed ;
: set-inherit ( handle ? -- )
>r HANDLE_FLAG_INHERIT r> >BOOLEAN SetHandleInformation win32-error=0/f ;
: redirect-stream ( default stream access-mode create-mode -- handle )
2drop nip
underlying-handle win32-file-handle
duplicate-handle dup t set-inherit ;
: redirect ( default obj access-mode create-mode -- handle )
{
{ [ pick not ] [ redirect-default ] }
{ [ pick +inherit+ eq? ] [ redirect-inherit ] }
{ [ pick +closed+ eq? ] [ redirect-closed ] }
{ [ pick string? ] [ redirect-file ] }
{ [ t ] [ redirect-stream ] }
} cond ;
: default-stdout ( args -- handle )
CreateProcess-args-stdout-pipe dup [ pipe-out ] when ;
: redirect-stdout ( args -- handle )
default-stdout
+stdout+ get
GENERIC_WRITE
CREATE_ALWAYS
redirect
STD_OUTPUT_HANDLE GetStdHandle or ;
: redirect-stderr ( args -- handle )
+stderr+ get +stdout+ eq? [
CreateProcess-args-lpStartupInfo
STARTUPINFO-hStdOutput
] [
drop
f
+stderr+ get
GENERIC_WRITE
CREATE_ALWAYS
redirect
STD_ERROR_HANDLE GetStdHandle or
] if ;
: default-stdin ( args -- handle )
CreateProcess-args-stdin-pipe dup [ pipe-in ] when ;
: redirect-stdin ( args -- handle )
default-stdin
+stdin+ get
GENERIC_READ
OPEN_EXISTING
redirect
STD_INPUT_HANDLE GetStdHandle or ;
: add-pipe-dtors ( pipe -- )
dup
pipe-in close-later

View File

@ -55,7 +55,7 @@ M: win32-file close-handle ( handle -- )
: open-file ( path access-mode create-mode flags -- handle )
[
>r >r >r normalize-pathname r>
share-mode f r> r> CreateFile-flags f CreateFile
share-mode security-attributes-inherit r> r> CreateFile-flags f CreateFile
dup invalid-handle? dup close-later
dup add-completion
] with-destructors ;

View File

@ -279,7 +279,7 @@ MACRO: with-locals ( form -- quot ) lambda-rewrite ;
! are unified
: create-method ( class generic -- method )
2dup method dup
[ 2nip method-word ]
[ 2nip ]
[ drop 2dup [ ] -rot define-method create-method ] if ;
: CREATE-METHOD ( -- class generic body )
@ -369,14 +369,14 @@ M: lambda-method definition
: method-stack-effect
dup "lambda" word-prop lambda-vars
swap "method" word-prop method-generic stack-effect dup [ effect-out ] when
swap "method-generic" word-prop stack-effect
dup [ effect-out ] when
<effect> ;
M: lambda-method synopsis*
dup definer.
dup "method" word-prop dup
method-specializer pprint*
method-generic pprint*
dup dup definer.
"method-specializer" word-prop pprint*
"method-generic" word-prop pprint*
method-stack-effect effect>string comment. ;
PRIVATE>

2
extra/logging/insomniac/insomniac-docs.factor Normal file → Executable file
View File

@ -27,7 +27,7 @@ HELP: schedule-insomniac
{ $values { "alist" "a sequence of pairs of shape " { $snippet "{ service word-names }" } } }
{ $description "Starts a thread which e-mails log reports and rotates logs daily." } ;
ARTICLE: "logging.insomniac" "Automating log analysis and rotation"
ARTICLE: "logging.insomniac" "Automated log analysis"
"The " { $vocab-link "logging.insomniac" } " vocabulary builds on the " { $vocab-link "logging.analysis" } " vocabulary. It provides support for e-mailing log reports and rotating logs on a daily basis. E-mails are sent using the " { $vocab-link "smtp" } " vocabulary."
$nl
"Required configuration parameters:"

6
extra/logging/logging-docs.factor Normal file → Executable file
View File

@ -115,9 +115,9 @@ ARTICLE: "logging" "Logging framework"
{ $subsection "logging.levels" }
{ $subsection "logging.messages" }
{ $subsection "logging.rotation" }
{ $subsection "logging.parser" }
{ $subsection "logging.analysis" }
{ $subsection "logging.insomniac" }
{ $vocab-subsection "Log file parser" "logging.parser" }
{ $vocab-subsection "Log analysis" "logging.analysis" }
{ $vocab-subsection "Automated log analysis" "logging.insomniac" }
{ $subsection "logging.server" } ;
ABOUT: "logging"

View File

@ -34,6 +34,10 @@ M: real sqrt
: set-bit ( x n -- y ) 2^ bitor ; foldable
: bit-clear? ( x n -- ? ) 2^ bitand zero? ; foldable
: bit-set? ( x n -- ? ) bit-clear? not ; foldable
: unmask ( x n -- ? ) bitnot bitand ; foldable
: unmask? ( x n -- ? ) unmask 0 > ; foldable
: mask ( x n -- ? ) bitand ; foldable
: mask? ( x n -- ? ) mask 0 > ; foldable
GENERIC: (^) ( x y -- z ) foldable

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: lazy-lists promises kernel sequences strings math
arrays splitting quotations combinators namespaces
unicode.case unicode.categories ;
unicode.case unicode.categories sequences.deep ;
IN: parser-combinators
! Parser combinator protocol
@ -329,11 +329,6 @@ LAZY: <(+)> ( parser -- parser )
LAZY: surrounded-by ( parser start end -- parser' )
[ token ] 2apply swapd pack ;
: flatten* ( obj -- )
dup array? [ [ flatten* ] each ] [ , ] if ;
: flatten [ flatten* ] { } make ;
: exactly-n ( parser n -- parser' )
swap <repetition> <and-parser> [ flatten ] <@ ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: kernel parser words arrays strings math.parser sequences
quotations vectors namespaces math assocs continuations peg
unicode.categories ;
peg.parsers unicode.categories ;
IN: peg.ebnf
TUPLE: ebnf-non-terminal symbol ;
@ -182,4 +182,4 @@ DEFER: 'choice'
f
] if* ;
: <EBNF "EBNF>" parse-tokens " " join ebnf>quot call ; parsing
: <EBNF "EBNF>" parse-tokens " " join ebnf>quot call ; parsing

View File

@ -0,0 +1,149 @@
! Copyright (C) 2007 Chris Double.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax peg peg.parsers.private
unicode.categories ;
IN: peg.parsers
HELP: (list-of)
{ $values
{ "items" "a sequence" }
{ "separator" "a parser" }
{ "repeat1?" "a boolean" }
{ "parser" "a parser" }
} { $description
"Returns a parser that returns a list of items separated by the separator parser. Does not hide the separators."
} { $see-also list-of list-of-many } ;
HELP: list-of
{ $values
{ "items" "a sequence" }
{ "separator" "a parser" }
} { $description
"Returns a parser that returns a list of items separated by the separator parser. Hides the separators and matches a list of one or more items."
} { $notes "Use " { $link list-of-many } " to ensure a list contains two or more items." }
{ $examples
{ $example "\"a\" \"a\" token \",\" token list-of parse parse-result-ast ." "V{ \"a\" }" }
{ $example "\"a,a,a,a\" \"a\" token \",\" token list-of parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
} { $see-also list-of-many } ;
HELP: list-of-many
{ $values
{ "items" "a sequence" }
{ "separator" "a parser" }
} { $description
"Returns a parser that returns a list of items separated by the separator parser. Hides the separators and matches a list of two or more items."
} { $notes "Use " { $link list-of } " to return a list of only one item."
} { $examples
{ $example "\"a\" \"a\" token \",\" token list-of-many parse ." "f" }
{ $example "\"a,a,a,a\" \"a\" token \",\" token list-of-many parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
} { $see-also list-of } ;
HELP: epsilon
{ $values
{ "parser" "a parser" }
} { $description
"Returns a parser that matches the empty sequence."
} ;
HELP: any-char
{ $values
{ "parser" "a parser" }
} { $description
"Returns a parser that matches the any single character."
} ;
HELP: exactly-n
{ $values
{ "parser" "a parser" }
{ "n" "an integer" }
{ "parser'" "a parser" }
} { $description
"Returns a parser that matches an exact repetition of the input parser."
} { $examples
{ $example "\"aaa\" \"a\" token 4 exactly-n parse ." "f" }
{ $example "\"aaaa\" \"a\" token 4 exactly-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
} { $see-also at-least-n at-most-n from-m-to-n } ;
HELP: at-least-n
{ $values
{ "parser" "a parser" }
{ "n" "an integer" }
{ "parser'" "a parser" }
} { $description
"Returns a parser that matches n or more repetitions of the input parser."
} { $examples
{ $example "\"aaa\" \"a\" token 4 at-least-n parse ." "f" }
{ $example "\"aaaa\" \"a\" token 4 at-least-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
{ $example "\"aaaaa\" \"a\" token 4 at-least-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" \"a\" }" }
} { $see-also exactly-n at-most-n from-m-to-n } ;
HELP: at-most-n
{ $values
{ "parser" "a parser" }
{ "n" "an integer" }
{ "parser'" "a parser" }
} { $description
"Returns a parser that matches n or fewer repetitions of the input parser."
} { $examples
{ $example "\"aaaa\" \"a\" token 4 at-most-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
{ $example "\"aaaaa\" \"a\" token 4 at-most-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
} { $see-also exactly-n at-least-n from-m-to-n } ;
HELP: from-m-to-n
{ $values
{ "parser" "a parser" }
{ "m" "an integer" }
{ "n" "an integer" }
{ "parser'" "a parser" }
} { $description
"Returns a parser that matches between and including m to n repetitions of the input parser."
} { $examples
{ $example "\"aaa\" \"a\" token 3 4 from-m-to-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" }" }
{ $example "\"aaaa\" \"a\" token 3 4 from-m-to-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
{ $example "\"aaaaa\" \"a\" token 3 4 from-m-to-n parse parse-result-ast ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
} { $see-also exactly-n at-most-n at-least-n } ;
HELP: pack
{ $values
{ "begin" "a parser" }
{ "body" "a parser" }
{ "end" "a parser" }
{ "parser'" "a parser" }
} { $description
"Returns a parser that parses the begin, body, and end parsers in order. The begin and end parsers are hidden."
} { $examples
{ $example "\"hi123bye\" \"hi\" token 'integer' \"bye\" token pack parse parse-result-ast ." "123" }
} { $see-also surrounded-by } ;
HELP: surrounded-by
{ $values
{ "parser" "a parser" }
{ "begin" "a string" }
{ "end" "a string" }
{ "parser'" "a parser" }
} { $description
"Calls token on begin and end to make them into string parsers. Returns a parser that parses the begin, body, and end parsers in order. The begin and end parsers are hidden."
} { $examples
{ $example "\"hi123bye\" 'integer' \"hi\" \"bye\" surrounded-by parse parse-result-ast ." "123" }
} { $see-also pack } ;
HELP: 'digit'
{ $values
{ "parser" "a parser" }
} { $description
"Returns a parser that matches a single digit as defined by the " { $link digit? } " word."
} { $see-also 'integer' } ;
HELP: 'integer'
{ $values
{ "parser" "a parser" }
} { $description
"Returns a parser that matches an integer composed of digits, as defined by the " { $link 'digit' } " word."
} { $see-also 'digit' 'string' } ;
HELP: 'string'
{ $values
{ "parser" "a parser" }
} { $description
"Returns a parser that matches an string composed of a \", anything that is not \", and another \"."
} { $see-also 'integer' } ;

View File

@ -0,0 +1,50 @@
USING: kernel peg peg.parsers tools.test ;
IN: peg.parsers.tests
[ V{ "a" } ]
[ "a" "a" token "," token list-of parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "a,a,a,a" "a" token "," token list-of parse parse-result-ast ] unit-test
[ f ]
[ "a" "a" token "," token list-of-many parse ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "a,a,a,a" "a" token "," token list-of-many parse parse-result-ast ] unit-test
[ f ]
[ "aaa" "a" token 4 exactly-n parse ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "aaaa" "a" token 4 exactly-n parse parse-result-ast ] unit-test
[ f ]
[ "aaa" "a" token 4 at-least-n parse ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "aaaa" "a" token 4 at-least-n parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" "a" "a" } ]
[ "aaaaa" "a" token 4 at-least-n parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "aaaa" "a" token 4 at-most-n parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "aaaaa" "a" token 4 at-most-n parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" } ]
[ "aaa" "a" token 3 4 from-m-to-n parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "aaaa" "a" token 3 4 from-m-to-n parse parse-result-ast ] unit-test
[ V{ "a" "a" "a" "a" } ]
[ "aaaaa" "a" token 3 4 from-m-to-n parse parse-result-ast ] unit-test
[ 97 ]
[ "a" any-char parse parse-result-ast ] unit-test
[ V{ } ]
[ "" epsilon parse parse-result-ast ] unit-test

View File

@ -0,0 +1,83 @@
! Copyright (C) 2007, 2008 Chris Double, Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences strings namespaces math assocs shuffle
vectors arrays combinators.lib memoize math.parser match
unicode.categories sequences.deep peg peg.private ;
IN: peg.parsers
TUPLE: just-parser p1 ;
: just-pattern
[
dup [
dup parse-result-remaining empty? [ drop f ] unless
] when
] ;
M: just-parser compile ( parser -- quot )
just-parser-p1 compile just-pattern append ;
MEMO: just ( parser -- parser )
just-parser construct-boa init-parser ;
<PRIVATE
MEMO: (list-of) ( items separator repeat1? -- parser )
>r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
[ unclip 1vector swap first append ] action ;
PRIVATE>
MEMO: list-of ( items separator -- parser )
hide f (list-of) ;
MEMO: list-of-many ( items separator -- parser )
hide t (list-of) ;
MEMO: epsilon ( -- parser ) V{ } token ;
MEMO: any-char ( -- parser ) [ drop t ] satisfy ;
<PRIVATE
: flatten-vectors ( pair -- vector )
first2 over push-all ;
PRIVATE>
MEMO: exactly-n ( parser n -- parser' )
swap <repetition> seq ;
MEMO: at-most-n ( parser n -- parser' )
dup zero? [
2drop epsilon
] [
2dup exactly-n
-rot 1- at-most-n 2choice
] if ;
MEMO: at-least-n ( parser n -- parser' )
dupd exactly-n swap repeat0 2seq
[ flatten-vectors ] action ;
MEMO: from-m-to-n ( parser m n -- parser' )
>r [ exactly-n ] 2keep r> swap - at-most-n 2seq
[ flatten-vectors ] action ;
MEMO: pack ( begin body end -- parser )
>r >r hide r> r> hide 3seq [ first ] action ;
MEMO: surrounded-by ( parser begin end -- parser' )
[ token ] 2apply swapd pack ;
MEMO: 'digit' ( -- parser )
[ digit? ] satisfy [ digit> ] action ;
MEMO: 'integer' ( -- parser )
'digit' repeat1 [ 10 digits>integer ] action ;
MEMO: 'string' ( -- parser )
[
[ CHAR: " = ] satisfy hide ,
[ CHAR: " = not ] satisfy repeat0 ,
[ CHAR: " = ] satisfy hide ,
] { } make seq [ first >string ] action ;

View File

@ -2,7 +2,8 @@
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences strings namespaces math assocs shuffle
vectors arrays combinators.lib memoize math.parser match
unicode.categories ;
unicode.categories sequences.lib compiler.units parser
words ;
IN: peg
TUPLE: parse-result remaining ast ;
@ -312,6 +313,9 @@ MEMO: range ( min max -- parser )
: 3seq ( parser1 parser2 parser3 -- parser )
3array seq ;
: 4seq ( parser1 parser2 parser3 parser4 -- parser )
4array seq ;
: seq* ( quot -- paser )
{ } make seq ; inline
@ -324,6 +328,9 @@ MEMO: range ( min max -- parser )
: 3choice ( parser1 parser2 parser3 -- parser )
3array choice ;
: 4choice ( parser1 parser2 parser3 parser4 -- parser )
4array choice ;
: choice* ( quot -- paser )
{ } make choice ; inline
@ -354,25 +361,11 @@ MEMO: hide ( parser -- parser )
MEMO: delay ( parser -- parser )
delay-parser construct-boa init-parser ;
MEMO: (list-of) ( items separator repeat1? -- parser )
>r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
[ unclip 1vector swap first append ] action ;
MEMO: list-of ( items separator -- parser )
hide f (list-of) ;
MEMO: list-of* ( items separator -- parser )
hide t (list-of) ;
MEMO: 'digit' ( -- parser )
[ digit? ] satisfy [ digit> ] action ;
MEMO: 'integer' ( -- parser )
'digit' repeat1 [ 10 digits>integer ] action ;
MEMO: 'string' ( -- parser )
[
[ CHAR: " = ] satisfy hide ,
[ CHAR: " = not ] satisfy repeat0 ,
[ CHAR: " = ] satisfy hide ,
] { } make seq [ first >string ] action ;
: PEG:
(:) [
[
call compile
[ dup [ parse-result-ast ] [ "Parse failed" throw ] if ]
append define
] with-compilation-unit
] 2curry over push-all ; parsing

View File

@ -1,6 +1,7 @@
! Copyright (C) 2007 Chris Double.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel arrays strings math.parser sequences peg peg.ebnf memoize ;
USING: kernel arrays strings math.parser sequences
peg peg.ebnf peg.parsers memoize ;
IN: peg.pl0
#! Grammar for PL/0 based on http://en.wikipedia.org/wiki/PL/0

View File

@ -6,7 +6,7 @@ GENERIC: foo
M: integer foo + ;
"resource:extra/tools/test/foo.factor" run-file
"resource:extra/tools/crossref/test/foo.factor" run-file
[ t ] [ integer \ foo method method-word \ + usage member? ] unit-test
[ t ] [ \ foo usage [ pathname? ] contains? ] unit-test

View File

@ -1,4 +1,4 @@
USE: temporary
USE: tools.crossref.tests
USE: kernel
1 2 foo drop

View File

@ -29,9 +29,8 @@ M: string (profile.)
dup <vocab-profile> write-object ;
M: method-body (profile.)
"method" word-prop
dup method-specializer over method-generic 2array synopsis
swap method-generic <usage-profile> write-object ;
dup synopsis swap "method-generic" word-prop
<usage-profile> write-object ;
: counter. ( obj n -- )
[

View File

@ -445,6 +445,18 @@ C-STRUCT: WIN32_FIND_DATA
{ { "TCHAR" 260 } "cFileName" }
{ { "TCHAR" 14 } "cAlternateFileName" } ;
C-STRUCT: BY_HANDLE_FILE_INFORMATION
{ "DWORD" "dwFileAttributes" }
{ "FILETIME" "ftCreationTime" }
{ "FILETIME" "ftLastAccessTime" }
{ "FILETIME" "ftLastWriteTime" }
{ "DWORD" "dwVolumeSerialNumber" }
{ "DWORD" "nFileSizeHigh" }
{ "DWORD" "nFileSizeLow" }
{ "DWORD" "nNumberOfLinks" }
{ "DWORD" "nFileIndexHigh" }
{ "DWORD" "nFileIndexLow" } ;
TYPEDEF: WIN32_FIND_DATA* PWIN32_FIND_DATA
TYPEDEF: WIN32_FIND_DATA* LPWIN32_FIND_DATA
TYPEDEF: void* POVERLAPPED

View File

@ -1,39 +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 <timestamp> ;
: FILETIME>windows-time ( FILETIME -- n )
[ FILETIME-dwLowDateTime ] keep
FILETIME-dwHighDateTime >64bit ;
: windows-time>timestamp ( n -- timestamp )
10000000 /i seconds windows-1601 swap time+ ;
: windows-time ( -- n )
"FILETIME" <c-object> [ GetSystemTimeAsFileTime ] keep
FILETIME>windows-time ;
: timestamp>windows-time ( timestamp -- n )
#! 64bit number representing # of nanoseconds since Jan 1, 1601 (UTC)
>gmt windows-1601 (time-) 10000000 * >integer ;
: windows-time>FILETIME ( n -- FILETIME )
"FILETIME" <c-object>
[
[ >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 ;
! 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 calendar.backend ;
IN: windows.time
: >64bit ( lo hi -- n )
32 shift bitor ;
: windows-1601 ( -- timestamp )
1601 1 1 0 0 0 0 <timestamp> ;
: FILETIME>windows-time ( FILETIME -- n )
[ FILETIME-dwLowDateTime ] keep
FILETIME-dwHighDateTime >64bit ;
: windows-time>timestamp ( n -- timestamp )
10000000 /i seconds windows-1601 swap time+ ;
: windows-time ( -- n )
"FILETIME" <c-object> [ GetSystemTimeAsFileTime ] keep
FILETIME>windows-time ;
: timestamp>windows-time ( timestamp -- n )
#! 64bit number representing # of nanoseconds since Jan 1, 1601 (UTC)
>gmt windows-1601 (time-) 10000000 * >integer ;
: windows-time>FILETIME ( n -- FILETIME )
"FILETIME" <c-object>
[
[ >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 ;

View File

@ -15,246 +15,247 @@ GIT_PROTOCOL=${GIT_PROTOCOL:="git"}
GIT_URL=${GIT_URL:=$GIT_PROTOCOL"://factorcode.org/git/factor.git"}
test_program_installed() {
if ! [[ -n `type -p $1` ]] ; then
return 0;
fi
return 1;
if ! [[ -n `type -p $1` ]] ; then
return 0;
fi
return 1;
}
ensure_program_installed() {
installed=0;
for i in $* ;
do
echo -n "Checking for $i..."
test_program_installed $i
if [[ $? -eq 0 ]]; then
echo -n "not "
else
installed=$(( $installed + 1 ))
fi
echo "found!"
done
if [[ $installed -eq 0 ]] ; then
echo -n "Install "
if [[ $# -eq 1 ]] ; then
echo -n $1
else
echo -n "any of [ $* ]"
fi
echo " and try again."
exit 1
fi
installed=0;
for i in $* ;
do
echo -n "Checking for $i..."
test_program_installed $i
if [[ $? -eq 0 ]]; then
echo -n "not "
else
installed=$(( $installed + 1 ))
fi
echo "found!"
done
if [[ $installed -eq 0 ]] ; then
echo -n "Install "
if [[ $# -eq 1 ]] ; then
echo -n $1
else
echo -n "any of [ $* ]"
fi
echo " and try again."
exit 1
fi
}
check_ret() {
RET=$?
if [[ $RET -ne 0 ]] ; then
echo $1 failed
exit 2
fi
RET=$?
if [[ $RET -ne 0 ]] ; then
echo $1 failed
exit 2
fi
}
check_gcc_version() {
echo -n "Checking gcc version..."
GCC_VERSION=`gcc --version`
check_ret gcc
if [[ $GCC_VERSION == *3.3.* ]] ; then
echo "bad!"
echo "You have a known buggy version of gcc (3.3)"
echo "Install gcc 3.4 or higher and try again."
exit 3
fi
echo "ok."
echo -n "Checking gcc version..."
GCC_VERSION=`gcc --version`
check_ret gcc
if [[ $GCC_VERSION == *3.3.* ]] ; then
echo "bad!"
echo "You have a known buggy version of gcc (3.3)"
echo "Install gcc 3.4 or higher and try again."
exit 3
fi
echo "ok."
}
set_downloader() {
test_program_installed wget
if [[ $? -ne 0 ]] ; then
DOWNLOAD=wget
else
DOWNLOAD="curl -O"
fi
test_program_installed wget
if [[ $? -ne 0 ]] ; then
DOWNLOAD=wget
else
DOWNLOAD="curl -O"
fi
}
set_md5sum() {
test_program_installed md5sum
if [[ $? -ne 0 ]] ; then
MD5SUM=md5sum
else
MD5SUM="md5 -r"
fi
test_program_installed md5sum
if [[ $? -ne 0 ]] ; then
MD5SUM=md5sum
else
MD5SUM="md5 -r"
fi
}
check_installed_programs() {
ensure_program_installed chmod
ensure_program_installed uname
ensure_program_installed git
ensure_program_installed wget curl
ensure_program_installed gcc
ensure_program_installed make
ensure_program_installed md5sum md5
ensure_program_installed cut
case $OS in
netbsd) ensure_program_installed gmake;;
esac
check_gcc_version
ensure_program_installed chmod
ensure_program_installed uname
ensure_program_installed git
ensure_program_installed wget curl
ensure_program_installed gcc
ensure_program_installed make
ensure_program_installed md5sum md5
ensure_program_installed cut
case $OS in
macosx) ensure_program_installed port;;
netbsd) ensure_program_installed gmake;;
esac
check_gcc_version
}
check_library_exists() {
GCC_TEST=factor-library-test.c
GCC_OUT=factor-library-test.out
echo -n "Checking for library $1..."
echo "int main(){return 0;}" > $GCC_TEST
gcc $GCC_TEST -o $GCC_OUT -l $1
if [[ $? -ne 0 ]] ; then
echo "not found!"
echo "Warning: library $1 not found."
echo "***Factor will compile NO_UI=1"
NO_UI=1
fi
rm -f $GCC_TEST
check_ret rm
rm -f $GCC_OUT
check_ret rm
echo "found."
GCC_TEST=factor-library-test.c
GCC_OUT=factor-library-test.out
echo -n "Checking for library $1..."
echo "int main(){return 0;}" > $GCC_TEST
gcc $GCC_TEST -o $GCC_OUT -l $1
if [[ $? -ne 0 ]] ; then
echo "not found!"
echo "Warning: library $1 not found."
echo "***Factor will compile NO_UI=1"
NO_UI=1
fi
rm -f $GCC_TEST
check_ret rm
rm -f $GCC_OUT
check_ret rm
echo "found."
}
check_X11_libraries() {
check_library_exists freetype
check_library_exists GLU
check_library_exists GL
check_library_exists X11
check_library_exists freetype
check_library_exists GLU
check_library_exists GL
check_library_exists X11
}
check_libraries() {
case $OS in
linux) check_X11_libraries;;
esac
case $OS in
linux) check_X11_libraries;;
esac
}
check_factor_exists() {
if [[ -d "factor" ]] ; then
echo "A directory called 'factor' already exists."
echo "Rename or delete it and try again."
exit 4
fi
if [[ -d "factor" ]] ; then
echo "A directory called 'factor' already exists."
echo "Rename or delete it and try again."
exit 4
fi
}
find_os() {
echo "Finding OS..."
uname_s=`uname -s`
check_ret uname
case $uname_s in
CYGWIN_NT-5.2-WOW64) OS=winnt;;
*CYGWIN_NT*) OS=winnt;;
*CYGWIN*) OS=winnt;;
*darwin*) OS=macosx;;
*Darwin*) OS=macosx;;
*linux*) OS=linux;;
*Linux*) OS=linux;;
*NetBSD*) OS=netbsd;;
esac
echo "Finding OS..."
uname_s=`uname -s`
check_ret uname
case $uname_s in
CYGWIN_NT-5.2-WOW64) OS=winnt;;
*CYGWIN_NT*) OS=winnt;;
*CYGWIN*) OS=winnt;;
*darwin*) OS=macosx;;
*Darwin*) OS=macosx;;
*linux*) OS=linux;;
*Linux*) OS=linux;;
*NetBSD*) OS=netbsd;;
esac
}
find_architecture() {
echo "Finding ARCH..."
uname_m=`uname -m`
check_ret uname
case $uname_m in
i386) ARCH=x86;;
i686) ARCH=x86;;
*86) ARCH=x86;;
*86_64) ARCH=x86;;
"Power Macintosh") ARCH=ppc;;
esac
echo "Finding ARCH..."
uname_m=`uname -m`
check_ret uname
case $uname_m in
i386) ARCH=x86;;
i686) ARCH=x86;;
*86) ARCH=x86;;
*86_64) ARCH=x86;;
"Power Macintosh") ARCH=ppc;;
esac
}
write_test_program() {
echo "#include <stdio.h>" > $C_WORD.c
echo "int main(){printf(\"%d\", 8*sizeof(void*)); return 0; }" >> $C_WORD.c
echo "#include <stdio.h>" > $C_WORD.c
echo "int main(){printf(\"%d\", 8*sizeof(void*)); return 0; }" >> $C_WORD.c
}
find_word_size() {
echo "Finding WORD..."
C_WORD=factor-word-size
write_test_program
gcc -o $C_WORD $C_WORD.c
WORD=$(./$C_WORD)
check_ret $C_WORD
rm -f $C_WORD*
echo "Finding WORD..."
C_WORD=factor-word-size
write_test_program
gcc -o $C_WORD $C_WORD.c
WORD=$(./$C_WORD)
check_ret $C_WORD
rm -f $C_WORD*
}
set_factor_binary() {
case $OS in
# winnt) FACTOR_BINARY=factor-nt;;
# macosx) FACTOR_BINARY=./Factor.app/Contents/MacOS/factor;;
*) FACTOR_BINARY=factor;;
esac
case $OS in
# winnt) FACTOR_BINARY=factor-nt;;
# macosx) FACTOR_BINARY=./Factor.app/Contents/MacOS/factor;;
*) FACTOR_BINARY=factor;;
esac
}
echo_build_info() {
echo OS=$OS
echo ARCH=$ARCH
echo WORD=$WORD
echo FACTOR_BINARY=$FACTOR_BINARY
echo MAKE_TARGET=$MAKE_TARGET
echo BOOT_IMAGE=$BOOT_IMAGE
echo MAKE_IMAGE_TARGET=$MAKE_IMAGE_TARGET
echo GIT_PROTOCOL=$GIT_PROTOCOL
echo GIT_URL=$GIT_URL
echo OS=$OS
echo ARCH=$ARCH
echo WORD=$WORD
echo FACTOR_BINARY=$FACTOR_BINARY
echo MAKE_TARGET=$MAKE_TARGET
echo BOOT_IMAGE=$BOOT_IMAGE
echo MAKE_IMAGE_TARGET=$MAKE_IMAGE_TARGET
echo GIT_PROTOCOL=$GIT_PROTOCOL
echo GIT_URL=$GIT_URL
}
set_build_info() {
if ! [[ -n $OS && -n $ARCH && -n $WORD ]] ; then
echo "OS: $OS"
echo "ARCH: $ARCH"
echo "WORD: $WORD"
echo "OS, ARCH, or WORD is empty. Please report this"
exit 5
fi
if ! [[ -n $OS && -n $ARCH && -n $WORD ]] ; then
echo "OS: $OS"
echo "ARCH: $ARCH"
echo "WORD: $WORD"
echo "OS, ARCH, or WORD is empty. Please report this"
exit 5
fi
MAKE_TARGET=$OS-$ARCH-$WORD
MAKE_IMAGE_TARGET=$ARCH.$WORD
BOOT_IMAGE=boot.$ARCH.$WORD.image
if [[ $OS == macosx && $ARCH == ppc ]] ; then
MAKE_IMAGE_TARGET=$OS-$ARCH
MAKE_TARGET=$OS-$ARCH
BOOT_IMAGE=boot.macosx-ppc.image
fi
if [[ $OS == linux && $ARCH == ppc ]] ; then
MAKE_IMAGE_TARGET=$OS-$ARCH
MAKE_TARGET=$OS-$ARCH
BOOT_IMAGE=boot.linux-ppc.image
fi
MAKE_TARGET=$OS-$ARCH-$WORD
MAKE_IMAGE_TARGET=$ARCH.$WORD
BOOT_IMAGE=boot.$ARCH.$WORD.image
if [[ $OS == macosx && $ARCH == ppc ]] ; then
MAKE_IMAGE_TARGET=$OS-$ARCH
MAKE_TARGET=$OS-$ARCH
BOOT_IMAGE=boot.macosx-ppc.image
fi
if [[ $OS == linux && $ARCH == ppc ]] ; then
MAKE_IMAGE_TARGET=$OS-$ARCH
MAKE_TARGET=$OS-$ARCH
BOOT_IMAGE=boot.linux-ppc.image
fi
}
find_build_info() {
find_os
find_architecture
find_word_size
set_factor_binary
set_build_info
echo_build_info
find_os
find_architecture
find_word_size
set_factor_binary
set_build_info
echo_build_info
}
invoke_git() {
git $*
check_ret git
git $*
check_ret git
}
git_clone() {
echo "Downloading the git repository from factorcode.org..."
invoke_git clone $GIT_URL
echo "Downloading the git repository from factorcode.org..."
invoke_git clone $GIT_URL
}
git_pull_factorcode() {
echo "Updating the git repository from factorcode.org..."
invoke_git pull $GIT_URL master
echo "Updating the git repository from factorcode.org..."
invoke_git pull $GIT_URL master
}
cd_factor() {
cd factor
check_ret cd
cd factor
check_ret cd
}
invoke_make() {
@ -267,128 +268,134 @@ invoke_make() {
}
make_clean() {
invoke_make clean
invoke_make clean
}
make_factor() {
invoke_make NO_UI=$NO_UI $MAKE_TARGET -j5
invoke_make NO_UI=$NO_UI $MAKE_TARGET -j5
}
update_boot_images() {
echo "Deleting old images..."
rm checksums.txt* > /dev/null 2>&1
rm $BOOT_IMAGE.* > /dev/null 2>&1
rm staging.*.image > /dev/null 2>&1
if [[ -f $BOOT_IMAGE ]] ; then
get_url http://factorcode.org/images/latest/checksums.txt
factorcode_md5=`cat checksums.txt|grep $BOOT_IMAGE|cut -f2 -d' '`;
set_md5sum
disk_md5=`$MD5SUM $BOOT_IMAGE|cut -f1 -d' '`;
echo "Factorcode md5: $factorcode_md5";
echo "Disk md5: $disk_md5";
if [[ "$factorcode_md5" == "$disk_md5" ]] ; then
echo "Your disk boot image matches the one on factorcode.org."
else
rm $BOOT_IMAGE > /dev/null 2>&1
get_boot_image;
fi
else
get_boot_image
fi
echo "Deleting old images..."
rm checksums.txt* > /dev/null 2>&1
rm $BOOT_IMAGE.* > /dev/null 2>&1
rm staging.*.image > /dev/null 2>&1
if [[ -f $BOOT_IMAGE ]] ; then
get_url http://factorcode.org/images/latest/checksums.txt
factorcode_md5=`cat checksums.txt|grep $BOOT_IMAGE|cut -f2 -d' '`;
set_md5sum
disk_md5=`$MD5SUM $BOOT_IMAGE|cut -f1 -d' '`;
echo "Factorcode md5: $factorcode_md5";
echo "Disk md5: $disk_md5";
if [[ "$factorcode_md5" == "$disk_md5" ]] ; then
echo "Your disk boot image matches the one on factorcode.org."
else
rm $BOOT_IMAGE > /dev/null 2>&1
get_boot_image;
fi
else
get_boot_image
fi
}
get_boot_image() {
echo "Downloading boot image $BOOT_IMAGE."
get_url http://factorcode.org/images/latest/$BOOT_IMAGE
echo "Downloading boot image $BOOT_IMAGE."
get_url http://factorcode.org/images/latest/$BOOT_IMAGE
}
get_url() {
if [[ $DOWNLOAD -eq "" ]] ; then
set_downloader;
fi
echo $DOWNLOAD $1 ;
$DOWNLOAD $1
check_ret $DOWNLOAD
if [[ $DOWNLOAD -eq "" ]] ; then
set_downloader;
fi
echo $DOWNLOAD $1 ;
$DOWNLOAD $1
check_ret $DOWNLOAD
}
maybe_download_dlls() {
if [[ $OS == winnt ]] ; then
get_url http://factorcode.org/dlls/freetype6.dll
get_url http://factorcode.org/dlls/zlib1.dll
get_url http://factorcode.org/dlls/OpenAL32.dll
get_url http://factorcode.org/dlls/alut.dll
get_url http://factorcode.org/dlls/ogg.dll
get_url http://factorcode.org/dlls/theora.dll
get_url http://factorcode.org/dlls/vorbis.dll
get_url http://factorcode.org/dlls/sqlite3.dll
chmod 777 *.dll
check_ret chmod
fi
if [[ $OS == winnt ]] ; then
get_url http://factorcode.org/dlls/freetype6.dll
get_url http://factorcode.org/dlls/zlib1.dll
get_url http://factorcode.org/dlls/OpenAL32.dll
get_url http://factorcode.org/dlls/alut.dll
get_url http://factorcode.org/dlls/ogg.dll
get_url http://factorcode.org/dlls/theora.dll
get_url http://factorcode.org/dlls/vorbis.dll
get_url http://factorcode.org/dlls/sqlite3.dll
chmod 777 *.dll
check_ret chmod
fi
}
get_config_info() {
find_build_info
check_installed_programs
check_libraries
find_build_info
check_installed_programs
check_libraries
}
bootstrap() {
./$FACTOR_BINARY -i=$BOOT_IMAGE
./$FACTOR_BINARY -i=$BOOT_IMAGE
}
install() {
check_factor_exists
get_config_info
git_clone
cd_factor
make_factor
get_boot_image
maybe_download_dlls
bootstrap
check_factor_exists
get_config_info
git_clone
cd_factor
make_factor
get_boot_image
maybe_download_dlls
bootstrap
}
update() {
get_config_info
git_pull_factorcode
make_clean
make_factor
get_config_info
git_pull_factorcode
make_clean
make_factor
}
update_bootstrap() {
update_boot_images
bootstrap
update_boot_images
bootstrap
}
refresh_image() {
./$FACTOR_BINARY -script -e="USE: vocabs.loader refresh-all USE: memory save 0 USE: system exit"
check_ret factor
./$FACTOR_BINARY -script -e="USE: vocabs.loader refresh-all USE: memory save 0 USE: system exit"
check_ret factor
}
make_boot_image() {
./$FACTOR_BINARY -script -e="\"$MAKE_IMAGE_TARGET\" USE: bootstrap.image make-image save 0 USE: system exit"
check_ret factor
./$FACTOR_BINARY -script -e="\"$MAKE_IMAGE_TARGET\" USE: bootstrap.image make-image save 0 USE: system exit"
check_ret factor
}
install_libraries() {
yes | sudo apt-get install sudo libc6-dev libfreetype6-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap gcc make
check_ret sudo
install_libraries_apt() {
yes | sudo apt-get install sudo libc6-dev libfreetype6-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap gcc make
check_ret sudo
}
install_libraries_port() {
ensure_program_installed port
yes | sudo port install git-core
}
usage() {
echo "usage: $0 install|install-x11|self-update|quick-update|update|bootstrap|net-bootstrap"
echo "If you are behind a firewall, invoke as:"
echo "env GIT_PROTOCOL=http $0 <command>"
echo "usage: $0 install|install-x11|install-macosx|self-update|quick-update|update|bootstrap|net-bootstrap"
echo "If you are behind a firewall, invoke as:"
echo "env GIT_PROTOCOL=http $0 <command>"
}
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 ;;
net-bootstrap) get_config_info; update_boot_images; bootstrap ;;
*) usage ;;
install) install ;;
install-x11) install_libraries_apt; install ;;
install-macosx) install_libraries_port; install ;;
self-update) update; make_boot_image; bootstrap;;
quick-update) update; refresh_image ;;
update) update; update_bootstrap ;;
bootstrap) get_config_info; bootstrap ;;
net-bootstrap) get_config_info; update_boot_images; bootstrap ;;
*) usage ;;
esac