Merge branch 'master' of git://factorcode.org/git/factor
commit
db224d4abd
|
@ -3,7 +3,7 @@ USING: alien alien.c-types alien.syntax compiler kernel
|
||||||
namespaces namespaces tools.test sequences inference words
|
namespaces namespaces tools.test sequences inference words
|
||||||
arrays parser quotations continuations inference.backend effects
|
arrays parser quotations continuations inference.backend effects
|
||||||
namespaces.private io io.streams.string memory system threads
|
namespaces.private io io.streams.string memory system threads
|
||||||
tools.test ;
|
tools.test math ;
|
||||||
|
|
||||||
FUNCTION: void ffi_test_0 ;
|
FUNCTION: void ffi_test_0 ;
|
||||||
[ ] [ ffi_test_0 ] unit-test
|
[ ] [ ffi_test_0 ] unit-test
|
||||||
|
@ -354,3 +354,14 @@ FUNCTION: double ffi_test_36 ( test-struct-12 x ) ;
|
||||||
] alien-callback ;
|
] alien-callback ;
|
||||||
|
|
||||||
[ ] [ callback-8 callback_test_1 ] unit-test
|
[ ] [ callback-8 callback_test_1 ] unit-test
|
||||||
|
|
||||||
|
: callback-9
|
||||||
|
"int" { "int" "int" "int" } "cdecl" [
|
||||||
|
+ + 1+
|
||||||
|
] alien-callback ;
|
||||||
|
|
||||||
|
FUNCTION: int ffi_test_37 ( void* func ) ;
|
||||||
|
|
||||||
|
[ 1 ] [ callback-9 ffi_test_37 ] unit-test
|
||||||
|
|
||||||
|
[ 7 ] [ callback-9 ffi_test_37 ] unit-test
|
||||||
|
|
|
@ -403,7 +403,6 @@ TUPLE: callback-context ;
|
||||||
: generate-callback ( node -- )
|
: generate-callback ( node -- )
|
||||||
dup xt>> dup [
|
dup xt>> dup [
|
||||||
init-templates
|
init-templates
|
||||||
%save-word-xt
|
|
||||||
%prologue-later
|
%prologue-later
|
||||||
dup alien-stack-frame [
|
dup alien-stack-frame [
|
||||||
dup registers>objects
|
dup registers>objects
|
||||||
|
|
|
@ -27,10 +27,6 @@ SYMBOL: bootstrap-time
|
||||||
diff
|
diff
|
||||||
[ "bootstrap." prepend require ] each ;
|
[ "bootstrap." prepend require ] each ;
|
||||||
|
|
||||||
! : compile-remaining ( -- )
|
|
||||||
! "Compiling remaining words..." print flush
|
|
||||||
! vocabs [ words [ compiled? not ] subset compile ] each ;
|
|
||||||
|
|
||||||
: count-words ( pred -- )
|
: count-words ( pred -- )
|
||||||
all-words swap subset length number>string write ;
|
all-words swap subset length number>string write ;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ USING: arrays compiler kernel kernel.private math
|
||||||
hashtables.private math.private namespaces sequences
|
hashtables.private math.private namespaces sequences
|
||||||
sequences.private tools.test namespaces.private slots.private
|
sequences.private tools.test namespaces.private slots.private
|
||||||
sequences.private byte-arrays alien alien.accessors layouts
|
sequences.private byte-arrays alien alien.accessors layouts
|
||||||
words definitions compiler.units io combinators ;
|
words definitions compiler.units io combinators vectors ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests
|
||||||
|
|
||||||
! Oops!
|
! Oops!
|
||||||
|
@ -246,3 +246,12 @@ TUPLE: my-tuple ;
|
||||||
} cleave ;
|
} cleave ;
|
||||||
|
|
||||||
[ t ] [ \ float-spill-bug compiled? ] unit-test
|
[ t ] [ \ float-spill-bug compiled? ] unit-test
|
||||||
|
|
||||||
|
! Regression
|
||||||
|
: dispatch-alignment-regression ( -- c )
|
||||||
|
{ tuple vector } 3 slot { word } declare
|
||||||
|
dup 1 slot 0 fixnum-bitand { [ ] } dispatch ;
|
||||||
|
|
||||||
|
[ t ] [ \ dispatch-alignment-regression compiled? ] unit-test
|
||||||
|
|
||||||
|
[ vector ] [ dispatch-alignment-regression ] unit-test
|
||||||
|
|
|
@ -56,7 +56,7 @@ HOOK: %call cpu ( word -- )
|
||||||
HOOK: %jump-label cpu ( label -- )
|
HOOK: %jump-label cpu ( label -- )
|
||||||
|
|
||||||
! Test if vreg is 'f' or not
|
! Test if vreg is 'f' or not
|
||||||
HOOK: %jump-t cpu ( label -- )
|
HOOK: %jump-f cpu ( label -- )
|
||||||
|
|
||||||
HOOK: %dispatch cpu ( -- )
|
HOOK: %dispatch cpu ( -- )
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,8 @@ M: ppc %call ( label -- ) BL ;
|
||||||
|
|
||||||
M: ppc %jump-label ( label -- ) B ;
|
M: ppc %jump-label ( label -- ) B ;
|
||||||
|
|
||||||
M: ppc %jump-t ( label -- )
|
M: ppc %jump-f ( label -- )
|
||||||
0 "flag" operand f v>operand CMPI BNE ;
|
0 "flag" operand f v>operand CMPI BEQ ;
|
||||||
|
|
||||||
M: ppc %dispatch ( -- )
|
M: ppc %dispatch ( -- )
|
||||||
[
|
[
|
||||||
|
|
|
@ -217,11 +217,11 @@ IN: cpu.ppc.intrinsics
|
||||||
2array define-if-intrinsics ;
|
2array define-if-intrinsics ;
|
||||||
|
|
||||||
{
|
{
|
||||||
{ fixnum< BLT }
|
{ fixnum< BGE }
|
||||||
{ fixnum<= BLE }
|
{ fixnum<= BGT }
|
||||||
{ fixnum> BGT }
|
{ fixnum> BLE }
|
||||||
{ fixnum>= BGE }
|
{ fixnum>= BLT }
|
||||||
{ eq? BEQ }
|
{ eq? BNE }
|
||||||
} [
|
} [
|
||||||
first2 define-fixnum-jump
|
first2 define-fixnum-jump
|
||||||
] each
|
] each
|
||||||
|
@ -356,11 +356,11 @@ IN: cpu.ppc.intrinsics
|
||||||
{ { float "x" } { float "y" } } define-if-intrinsic ;
|
{ { float "x" } { float "y" } } define-if-intrinsic ;
|
||||||
|
|
||||||
{
|
{
|
||||||
{ float< BLT }
|
{ float< BGE }
|
||||||
{ float<= BLE }
|
{ float<= BGT }
|
||||||
{ float> BGT }
|
{ float> BLE }
|
||||||
{ float>= BGE }
|
{ float>= BLT }
|
||||||
{ float= BEQ }
|
{ float= BNE }
|
||||||
} [
|
} [
|
||||||
first2 define-float-jump
|
first2 define-float-jump
|
||||||
] each
|
] each
|
||||||
|
|
|
@ -16,7 +16,6 @@ IN: cpu.x86.32
|
||||||
M: x86.32 ds-reg ESI ;
|
M: x86.32 ds-reg ESI ;
|
||||||
M: x86.32 rs-reg EDI ;
|
M: x86.32 rs-reg EDI ;
|
||||||
M: x86.32 stack-reg ESP ;
|
M: x86.32 stack-reg ESP ;
|
||||||
M: x86.32 xt-reg ECX ;
|
|
||||||
M: x86.32 stack-save-reg EDX ;
|
M: x86.32 stack-save-reg EDX ;
|
||||||
|
|
||||||
M: temp-reg v>operand drop EBX ;
|
M: temp-reg v>operand drop EBX ;
|
||||||
|
@ -267,7 +266,7 @@ os windows? [
|
||||||
EDX 26 SHR
|
EDX 26 SHR
|
||||||
EDX 1 AND
|
EDX 1 AND
|
||||||
{ EAX EBX ECX EDX } [ POP ] each
|
{ EAX EBX ECX EDX } [ POP ] each
|
||||||
JNE
|
JE
|
||||||
] { } define-if-intrinsic
|
] { } define-if-intrinsic
|
||||||
|
|
||||||
"-no-sse2" cli-args member? [
|
"-no-sse2" cli-args member? [
|
||||||
|
|
|
@ -11,7 +11,6 @@ IN: cpu.x86.64
|
||||||
M: x86.64 ds-reg R14 ;
|
M: x86.64 ds-reg R14 ;
|
||||||
M: x86.64 rs-reg R15 ;
|
M: x86.64 rs-reg R15 ;
|
||||||
M: x86.64 stack-reg RSP ;
|
M: x86.64 stack-reg RSP ;
|
||||||
M: x86.64 xt-reg RCX ;
|
|
||||||
M: x86.64 stack-save-reg RSI ;
|
M: x86.64 stack-save-reg RSI ;
|
||||||
|
|
||||||
M: temp-reg v>operand drop RBX ;
|
M: temp-reg v>operand drop RBX ;
|
||||||
|
|
|
@ -9,7 +9,6 @@ IN: cpu.x86.architecture
|
||||||
HOOK: ds-reg cpu
|
HOOK: ds-reg cpu
|
||||||
HOOK: rs-reg cpu
|
HOOK: rs-reg cpu
|
||||||
HOOK: stack-reg cpu
|
HOOK: stack-reg cpu
|
||||||
HOOK: xt-reg cpu
|
|
||||||
HOOK: stack-save-reg cpu
|
HOOK: stack-save-reg cpu
|
||||||
|
|
||||||
: stack@ stack-reg swap [+] ;
|
: stack@ stack-reg swap [+] ;
|
||||||
|
@ -47,13 +46,13 @@ M: x86 stack-frame ( n -- i )
|
||||||
3 cells + 16 align cell - ;
|
3 cells + 16 align cell - ;
|
||||||
|
|
||||||
M: x86 %save-word-xt ( -- )
|
M: x86 %save-word-xt ( -- )
|
||||||
xt-reg 0 MOV rc-absolute-cell rel-this ;
|
temp-reg v>operand 0 MOV rc-absolute-cell rel-this ;
|
||||||
|
|
||||||
: factor-area-size 4 cells ;
|
: factor-area-size 4 cells ;
|
||||||
|
|
||||||
M: x86 %prologue ( n -- )
|
M: x86 %prologue ( n -- )
|
||||||
dup cell + PUSH
|
dup cell + PUSH
|
||||||
xt-reg PUSH
|
temp-reg v>operand PUSH
|
||||||
stack-reg swap 2 cells - SUB ;
|
stack-reg swap 2 cells - SUB ;
|
||||||
|
|
||||||
M: x86 %epilogue ( n -- )
|
M: x86 %epilogue ( n -- )
|
||||||
|
@ -76,8 +75,8 @@ M: x86 %call ( label -- ) CALL ;
|
||||||
|
|
||||||
M: x86 %jump-label ( label -- ) JMP ;
|
M: x86 %jump-label ( label -- ) JMP ;
|
||||||
|
|
||||||
M: x86 %jump-t ( label -- )
|
M: x86 %jump-f ( label -- )
|
||||||
"flag" operand f v>operand CMP JNE ;
|
"flag" operand f v>operand CMP JE ;
|
||||||
|
|
||||||
: code-alignment ( -- n )
|
: code-alignment ( -- n )
|
||||||
building get length dup cell align swap - ;
|
building get length dup cell align swap - ;
|
||||||
|
|
|
@ -212,11 +212,11 @@ IN: cpu.x86.intrinsics
|
||||||
2array define-if-intrinsics ;
|
2array define-if-intrinsics ;
|
||||||
|
|
||||||
{
|
{
|
||||||
{ fixnum< JL }
|
{ fixnum< JGE }
|
||||||
{ fixnum<= JLE }
|
{ fixnum<= JG }
|
||||||
{ fixnum> JG }
|
{ fixnum> JLE }
|
||||||
{ fixnum>= JGE }
|
{ fixnum>= JL }
|
||||||
{ eq? JE }
|
{ eq? JNE }
|
||||||
} [
|
} [
|
||||||
first2 define-fixnum-jump
|
first2 define-fixnum-jump
|
||||||
] each
|
] each
|
||||||
|
|
|
@ -27,11 +27,11 @@ IN: cpu.x86.sse2
|
||||||
{ { float "x" } { float "y" } } define-if-intrinsic ;
|
{ { float "x" } { float "y" } } define-if-intrinsic ;
|
||||||
|
|
||||||
{
|
{
|
||||||
{ float< JB }
|
{ float< JAE }
|
||||||
{ float<= JBE }
|
{ float<= JA }
|
||||||
{ float> JA }
|
{ float> JBE }
|
||||||
{ float>= JAE }
|
{ float>= JB }
|
||||||
{ float= JE }
|
{ float= JNE }
|
||||||
} [
|
} [
|
||||||
first2 define-float-jump
|
first2 define-float-jump
|
||||||
] each
|
] each
|
||||||
|
|
|
@ -131,14 +131,14 @@ M: #loop generate-node
|
||||||
|
|
||||||
: generate-if ( node label -- next )
|
: generate-if ( node label -- next )
|
||||||
<label> [
|
<label> [
|
||||||
>r >r node-children first2 generate-branch
|
>r >r node-children first2 swap generate-branch
|
||||||
r> r> end-false-branch resolve-label
|
r> r> end-false-branch resolve-label
|
||||||
generate-branch
|
generate-branch
|
||||||
init-templates
|
init-templates
|
||||||
] keep resolve-label iterate-next ;
|
] keep resolve-label iterate-next ;
|
||||||
|
|
||||||
M: #if generate-node
|
M: #if generate-node
|
||||||
[ <label> dup %jump-t ]
|
[ <label> dup %jump-f ]
|
||||||
H{ { +input+ { { f "flag" } } } }
|
H{ { +input+ { { f "flag" } } } }
|
||||||
with-template
|
with-template
|
||||||
generate-if ;
|
generate-if ;
|
||||||
|
@ -189,13 +189,13 @@ M: #dispatch generate-node
|
||||||
"if-intrinsics" set-word-prop ;
|
"if-intrinsics" set-word-prop ;
|
||||||
|
|
||||||
: if>boolean-intrinsic ( quot -- )
|
: if>boolean-intrinsic ( quot -- )
|
||||||
"true" define-label
|
"false" define-label
|
||||||
"end" define-label
|
"end" define-label
|
||||||
"true" get swap call
|
"false" get swap call
|
||||||
f "if-scratch" get load-literal
|
|
||||||
"end" get %jump-label
|
|
||||||
"true" resolve-label
|
|
||||||
t "if-scratch" get load-literal
|
t "if-scratch" get load-literal
|
||||||
|
"end" get %jump-label
|
||||||
|
"false" resolve-label
|
||||||
|
f "if-scratch" get load-literal
|
||||||
"end" resolve-label
|
"end" resolve-label
|
||||||
"if-scratch" get phantom-push ; inline
|
"if-scratch" get phantom-push ; inline
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,7 @@ M: float-regs move-spec drop float ;
|
||||||
M: float-regs operand-class* drop float ;
|
M: float-regs operand-class* drop float ;
|
||||||
|
|
||||||
! Temporary register for stack shuffling
|
! Temporary register for stack shuffling
|
||||||
TUPLE: temp-reg reg-class>> ;
|
SINGLETON: temp-reg
|
||||||
|
|
||||||
: temp-reg T{ temp-reg f int-regs } ;
|
|
||||||
|
|
||||||
M: temp-reg move-spec drop f ;
|
M: temp-reg move-spec drop f ;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
IN: generic.standard.engines.tuple
|
! Copyright (c) 2008 Slava Pestov
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel classes.tuple.private hashtables assocs sorting
|
USING: kernel classes.tuple.private hashtables assocs sorting
|
||||||
accessors combinators sequences slots.private math.parser words
|
accessors combinators sequences slots.private math.parser words
|
||||||
effects namespaces generic generic.standard.engines
|
effects namespaces generic generic.standard.engines
|
||||||
classes.algebra math math.private quotations arrays ;
|
classes.algebra math math.private kernel.private
|
||||||
|
quotations arrays ;
|
||||||
|
IN: generic.standard.engines.tuple
|
||||||
|
|
||||||
TUPLE: echelon-dispatch-engine n methods ;
|
TUPLE: echelon-dispatch-engine n methods ;
|
||||||
|
|
||||||
|
@ -27,14 +30,7 @@ TUPLE: tuple-dispatch-engine echelons ;
|
||||||
|
|
||||||
: <tuple-dispatch-engine> ( methods -- engine )
|
: <tuple-dispatch-engine> ( methods -- engine )
|
||||||
echelon-sort
|
echelon-sort
|
||||||
[
|
[ dupd <echelon-dispatch-engine> ] assoc-map
|
||||||
over zero? [
|
|
||||||
dup assoc-empty?
|
|
||||||
[ drop f ] [ values first ] if
|
|
||||||
] [
|
|
||||||
dupd <echelon-dispatch-engine>
|
|
||||||
] if
|
|
||||||
] assoc-map [ nip ] assoc-subset
|
|
||||||
\ tuple-dispatch-engine boa ;
|
\ tuple-dispatch-engine boa ;
|
||||||
|
|
||||||
: convert-tuple-methods ( assoc -- assoc' )
|
: convert-tuple-methods ( assoc -- assoc' )
|
||||||
|
@ -48,52 +44,51 @@ M: trivial-tuple-dispatch-engine engine>quot
|
||||||
>alist V{ } clone [ hashcode 1array ] distribute-buckets
|
>alist V{ } clone [ hashcode 1array ] distribute-buckets
|
||||||
[ <trivial-tuple-dispatch-engine> ] map ;
|
[ <trivial-tuple-dispatch-engine> ] map ;
|
||||||
|
|
||||||
|
: word-hashcode% [ 1 slot ] % ;
|
||||||
|
|
||||||
: class-hash-dispatch-quot ( methods -- quot )
|
: class-hash-dispatch-quot ( methods -- quot )
|
||||||
#! 1 slot == word hashcode
|
|
||||||
[
|
[
|
||||||
[ dup 1 slot ] %
|
\ dup ,
|
||||||
|
word-hashcode%
|
||||||
hash-methods [ engine>quot ] map hash-dispatch-quot %
|
hash-methods [ engine>quot ] map hash-dispatch-quot %
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
||||||
: tuple-dispatch-engine-word-name ( engine -- string )
|
: engine-word-name ( -- string )
|
||||||
[
|
generic get word-name "/tuple-dispatch-engine" append ;
|
||||||
generic get word-name %
|
|
||||||
"/tuple-dispatch-engine/" %
|
|
||||||
n>> #
|
|
||||||
] "" make ;
|
|
||||||
|
|
||||||
PREDICATE: tuple-dispatch-engine-word < word
|
PREDICATE: engine-word < word
|
||||||
"tuple-dispatch-generic" word-prop generic? ;
|
"tuple-dispatch-generic" word-prop generic? ;
|
||||||
|
|
||||||
M: tuple-dispatch-engine-word stack-effect
|
M: engine-word stack-effect
|
||||||
"tuple-dispatch-generic" word-prop
|
"tuple-dispatch-generic" word-prop
|
||||||
[ extra-values ] [ stack-effect ] bi
|
[ extra-values ] [ stack-effect ] bi
|
||||||
dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
|
dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
|
||||||
|
|
||||||
M: tuple-dispatch-engine-word compiled-crossref?
|
M: engine-word compiled-crossref?
|
||||||
drop t ;
|
drop t ;
|
||||||
|
|
||||||
: remember-engine ( word -- )
|
: remember-engine ( word -- )
|
||||||
generic get "engines" word-prop push ;
|
generic get "engines" word-prop push ;
|
||||||
|
|
||||||
: <tuple-dispatch-engine-word> ( engine -- word )
|
: <engine-word> ( -- word )
|
||||||
tuple-dispatch-engine-word-name f <word>
|
engine-word-name f <word>
|
||||||
[ generic get "tuple-dispatch-generic" set-word-prop ]
|
dup generic get "tuple-dispatch-generic" set-word-prop ;
|
||||||
[ remember-engine ]
|
|
||||||
[ ]
|
|
||||||
tri ;
|
|
||||||
|
|
||||||
: define-tuple-dispatch-engine-word ( engine quot -- word )
|
: define-engine-word ( quot -- word )
|
||||||
>r <tuple-dispatch-engine-word> dup r> define ;
|
>r <engine-word> dup r> define ;
|
||||||
|
|
||||||
|
: array-nth% 2 + , [ slot { word } declare ] % ;
|
||||||
|
|
||||||
|
: tuple-layout-superclasses ( obj -- array )
|
||||||
|
{ tuple } declare
|
||||||
|
1 slot { tuple-layout } declare
|
||||||
|
4 slot { array } declare ; inline
|
||||||
|
|
||||||
: tuple-dispatch-engine-body ( engine -- quot )
|
: tuple-dispatch-engine-body ( engine -- quot )
|
||||||
#! 1 slot == tuple-layout
|
|
||||||
#! 2 slot == 0 array-nth
|
|
||||||
#! 4 slot == layout-superclasses
|
|
||||||
[
|
[
|
||||||
picker %
|
picker %
|
||||||
[ 1 slot 4 slot ] %
|
[ tuple-layout-superclasses ] %
|
||||||
[ n>> 2 + , [ slot ] % ]
|
[ n>> array-nth% ]
|
||||||
[
|
[
|
||||||
methods>> [
|
methods>> [
|
||||||
<trivial-tuple-dispatch-engine> engine>quot
|
<trivial-tuple-dispatch-engine> engine>quot
|
||||||
|
@ -104,25 +99,54 @@ M: tuple-dispatch-engine-word compiled-crossref?
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
||||||
M: echelon-dispatch-engine engine>quot
|
M: echelon-dispatch-engine engine>quot
|
||||||
dup tuple-dispatch-engine-body
|
dup n>> zero? [
|
||||||
define-tuple-dispatch-engine-word
|
methods>> dup assoc-empty?
|
||||||
1quotation ;
|
[ drop default get ] [ values first engine>quot ] if
|
||||||
|
] [
|
||||||
|
[
|
||||||
|
picker %
|
||||||
|
[ tuple-layout-superclasses ] %
|
||||||
|
[ n>> array-nth% ]
|
||||||
|
[
|
||||||
|
methods>> [
|
||||||
|
<trivial-tuple-dispatch-engine> engine>quot
|
||||||
|
] [
|
||||||
|
class-hash-dispatch-quot
|
||||||
|
] if-small? %
|
||||||
|
] bi
|
||||||
|
] [ ] make
|
||||||
|
] if ;
|
||||||
|
|
||||||
: >=-case-quot ( alist -- quot )
|
: >=-case-quot ( alist -- quot )
|
||||||
default get [ drop ] prepend swap
|
default get [ drop ] prepend swap
|
||||||
[ >r [ dupd fixnum>= ] curry r> \ drop prefix ] assoc-map
|
[ >r [ dupd fixnum>= ] curry r> \ drop prefix ] assoc-map
|
||||||
alist>quot ;
|
alist>quot ;
|
||||||
|
|
||||||
|
: tuple-layout-echelon ( obj -- array )
|
||||||
|
{ tuple } declare
|
||||||
|
1 slot { tuple-layout } declare
|
||||||
|
5 slot ; inline
|
||||||
|
|
||||||
|
: unclip-last [ 1 head* ] [ peek ] bi ;
|
||||||
|
|
||||||
M: tuple-dispatch-engine engine>quot
|
M: tuple-dispatch-engine engine>quot
|
||||||
#! 1 slot == tuple-layout
|
|
||||||
#! 5 slot == layout-echelon
|
|
||||||
[
|
[
|
||||||
picker %
|
picker %
|
||||||
[ 1 slot 5 slot ] %
|
[ tuple-layout-echelon ] %
|
||||||
echelons>>
|
|
||||||
[
|
[
|
||||||
tuple assumed set
|
tuple assumed set
|
||||||
[ engine>quot dup default set ] assoc-map
|
echelons>> dup empty? [
|
||||||
|
unclip-last
|
||||||
|
[
|
||||||
|
[
|
||||||
|
engine>quot define-engine-word
|
||||||
|
[ remember-engine ] [ 1quotation ] bi
|
||||||
|
dup default set
|
||||||
|
] assoc-map
|
||||||
|
]
|
||||||
|
[ first2 engine>quot 2array ] bi*
|
||||||
|
suffix
|
||||||
|
] unless
|
||||||
] with-scope
|
] with-scope
|
||||||
>=-case-quot %
|
>=-case-quot %
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
|
@ -251,6 +251,14 @@ HOOK: my-tuple-hook my-var ( -- x )
|
||||||
|
|
||||||
M: sequence my-tuple-hook my-hook ;
|
M: sequence my-tuple-hook my-hook ;
|
||||||
|
|
||||||
|
TUPLE: m-t-h-a ;
|
||||||
|
|
||||||
|
M: m-t-h-a my-tuple-hook "foo" ;
|
||||||
|
|
||||||
|
TUPLE: m-t-h-b < m-t-h-a ;
|
||||||
|
|
||||||
|
M: m-t-h-b my-tuple-hook "bar" ;
|
||||||
|
|
||||||
[ f ] [
|
[ f ] [
|
||||||
\ my-tuple-hook [ "engines" word-prop ] keep prefix
|
\ my-tuple-hook [ "engines" word-prop ] keep prefix
|
||||||
[ 1quotation infer ] map all-equal?
|
[ 1quotation infer ] map all-equal?
|
||||||
|
|
|
@ -15,7 +15,7 @@ GENERIC: inline? ( word -- ? )
|
||||||
M: method-body inline?
|
M: method-body inline?
|
||||||
"method-generic" word-prop inline? ;
|
"method-generic" word-prop inline? ;
|
||||||
|
|
||||||
M: tuple-dispatch-engine-word inline?
|
M: engine-word inline?
|
||||||
"tuple-dispatch-generic" word-prop inline? ;
|
"tuple-dispatch-generic" word-prop inline? ;
|
||||||
|
|
||||||
M: word inline?
|
M: word inline?
|
||||||
|
@ -130,25 +130,27 @@ TUPLE: too-many->r ;
|
||||||
|
|
||||||
TUPLE: too-many-r> ;
|
TUPLE: too-many-r> ;
|
||||||
|
|
||||||
: check-r> ( -- )
|
: check-r> ( n -- )
|
||||||
meta-r get empty?
|
meta-r get length >
|
||||||
[ \ too-many-r> inference-error ] when ;
|
[ \ too-many-r> inference-error ] when ;
|
||||||
|
|
||||||
: infer->r ( -- )
|
: infer->r ( n -- )
|
||||||
1 ensure-values
|
dup ensure-values
|
||||||
#>r
|
#>r
|
||||||
1 0 pick node-inputs
|
over 0 pick node-inputs
|
||||||
pop-d push-r
|
over [ drop pop-d ] map reverse [ push-r ] each
|
||||||
0 1 pick node-outputs
|
0 pick pick node-outputs
|
||||||
node, ;
|
node,
|
||||||
|
drop ;
|
||||||
|
|
||||||
: infer-r> ( -- )
|
: infer-r> ( n -- )
|
||||||
check-r>
|
dup check-r>
|
||||||
#r>
|
#r>
|
||||||
0 1 pick node-inputs
|
0 pick pick node-inputs
|
||||||
pop-r push-d
|
over [ drop pop-r ] map reverse [ push-d ] each
|
||||||
1 0 pick node-outputs
|
over 0 pick node-outputs
|
||||||
node, ;
|
node,
|
||||||
|
drop ;
|
||||||
|
|
||||||
: undo-infer ( -- )
|
: undo-infer ( -- )
|
||||||
recorded get [ f "inferred-effect" set-word-prop ] each ;
|
recorded get [ f "inferred-effect" set-word-prop ] each ;
|
||||||
|
@ -199,18 +201,18 @@ M: object constructor drop f ;
|
||||||
dup infer-uncurry
|
dup infer-uncurry
|
||||||
constructor [
|
constructor [
|
||||||
peek-d reify-curry
|
peek-d reify-curry
|
||||||
infer->r
|
1 infer->r
|
||||||
peek-d reify-curry
|
peek-d reify-curry
|
||||||
infer-r>
|
1 infer-r>
|
||||||
2 1 <effect> swap #call consume/produce
|
2 1 <effect> swap #call consume/produce
|
||||||
] when* ;
|
] when* ;
|
||||||
|
|
||||||
: reify-curries ( n -- )
|
: reify-curries ( n -- )
|
||||||
meta-d get reverse [
|
meta-d get reverse [
|
||||||
dup special? [
|
dup special? [
|
||||||
over [ infer->r ] times
|
over infer->r
|
||||||
dup reify-curry
|
dup reify-curry
|
||||||
over [ infer-r> ] times
|
over infer-r>
|
||||||
] when 2drop
|
] when 2drop
|
||||||
] 2each ;
|
] 2each ;
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,9 @@ IN: inference.known-words
|
||||||
{ swap T{ effect f 2 { 1 0 } } }
|
{ swap T{ effect f 2 { 1 0 } } }
|
||||||
} [ define-shuffle ] assoc-each
|
} [ define-shuffle ] assoc-each
|
||||||
|
|
||||||
\ >r [ infer->r ] "infer" set-word-prop
|
\ >r [ 1 infer->r ] "infer" set-word-prop
|
||||||
|
|
||||||
\ r> [ infer-r> ] "infer" set-word-prop
|
\ r> [ 1 infer-r> ] "infer" set-word-prop
|
||||||
|
|
||||||
\ declare [
|
\ declare [
|
||||||
1 ensure-values
|
1 ensure-values
|
||||||
|
@ -81,8 +81,8 @@ M: curried infer-call
|
||||||
|
|
||||||
M: composed infer-call
|
M: composed infer-call
|
||||||
infer-uncurry
|
infer-uncurry
|
||||||
infer->r peek-d infer-call
|
1 infer->r peek-d infer-call
|
||||||
terminated? get [ infer-r> peek-d infer-call ] unless ;
|
terminated? get [ 1 infer-r> peek-d infer-call ] unless ;
|
||||||
|
|
||||||
M: object infer-call
|
M: object infer-call
|
||||||
\ literal-expected inference-warning ;
|
\ literal-expected inference-warning ;
|
||||||
|
|
|
@ -26,7 +26,7 @@ ARTICLE: "threads-yield" "Yielding and suspending threads"
|
||||||
{ $subsection resume }
|
{ $subsection resume }
|
||||||
{ $subsection resume-with } ;
|
{ $subsection resume-with } ;
|
||||||
|
|
||||||
ARTICLE: "thread-state" "Thread-local state"
|
ARTICLE: "thread-state" "Thread-local state and variables"
|
||||||
"Threads form a class of objects:"
|
"Threads form a class of objects:"
|
||||||
{ $subsection thread }
|
{ $subsection thread }
|
||||||
"The current thread:"
|
"The current thread:"
|
||||||
|
@ -36,6 +36,8 @@ ARTICLE: "thread-state" "Thread-local state"
|
||||||
{ $subsection tget }
|
{ $subsection tget }
|
||||||
{ $subsection tset }
|
{ $subsection tset }
|
||||||
{ $subsection tchange }
|
{ $subsection tchange }
|
||||||
|
"Each thread has its own independent set of thread-local variables and newly-spawned threads begin with an empty set."
|
||||||
|
$nl
|
||||||
"Global hashtable of all threads, keyed by " { $link thread-id } ":"
|
"Global hashtable of all threads, keyed by " { $link thread-id } ":"
|
||||||
{ $subsection threads }
|
{ $subsection threads }
|
||||||
"Threads have an identity independent of continuations. If a continuation is refied in one thread and then resumed in another thread, the code running in that continuation will observe a change in the value output by " { $link self } "." ;
|
"Threads have an identity independent of continuations. If a continuation is refied in one thread and then resumed in another thread, the code running in that continuation will observe a change in the value output by " { $link self } "." ;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
USING: namespaces io tools.test threads kernel ;
|
USING: namespaces io tools.test threads kernel
|
||||||
|
concurrency.combinators math ;
|
||||||
IN: threads.tests
|
IN: threads.tests
|
||||||
|
|
||||||
3 "x" set
|
3 "x" set
|
||||||
|
@ -16,3 +17,13 @@ yield
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ f ] [ f get-global ] unit-test
|
[ f ] [ f get-global ] unit-test
|
||||||
|
|
||||||
|
{ { 0 3 6 9 12 15 18 21 24 27 } } [
|
||||||
|
10 [
|
||||||
|
0 "i" tset
|
||||||
|
[
|
||||||
|
"i" [ yield 3 + ] tchange
|
||||||
|
] times yield
|
||||||
|
"i" tget
|
||||||
|
] parallel-map
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -27,7 +27,7 @@ mailbox variables sleep-entry ;
|
||||||
tnamespace set-at ;
|
tnamespace set-at ;
|
||||||
|
|
||||||
: tchange ( key quot -- )
|
: tchange ( key quot -- )
|
||||||
tnamespace change-at ; inline
|
tnamespace swap change-at ; inline
|
||||||
|
|
||||||
: threads 41 getenv ;
|
: threads 41 getenv ;
|
||||||
|
|
||||||
|
|
|
@ -61,3 +61,5 @@ IN: farkup.tests
|
||||||
[ "<p><img src=\"lol.jpg\" alt=\"teh lol\"/></p>" ] [ "[[image:lol.jpg|teh lol]]" convert-farkup ] unit-test
|
[ "<p><img src=\"lol.jpg\" alt=\"teh lol\"/></p>" ] [ "[[image:lol.jpg|teh lol]]" convert-farkup ] unit-test
|
||||||
[ "<p><a href=\"lol.com\"></a></p>" ] [ "[[lol.com]]" convert-farkup ] unit-test
|
[ "<p><a href=\"lol.com\"></a></p>" ] [ "[[lol.com]]" convert-farkup ] unit-test
|
||||||
[ "<p><a href=\"lol.com\">haha</a></p>" ] [ "[[lol.com|haha]]" convert-farkup ] unit-test
|
[ "<p><a href=\"lol.com\">haha</a></p>" ] [ "[[lol.com|haha]]" convert-farkup ] unit-test
|
||||||
|
|
||||||
|
[ ] [ "[{}]" convert-farkup drop ] unit-test
|
||||||
|
|
|
@ -161,6 +161,6 @@ SYMBOL: html
|
||||||
"id" "onclick" "style" "valign" "accesskey"
|
"id" "onclick" "style" "valign" "accesskey"
|
||||||
"src" "language" "colspan" "onchange" "rel"
|
"src" "language" "colspan" "onchange" "rel"
|
||||||
"width" "selected" "onsubmit" "xmlns" "lang" "xml:lang"
|
"width" "selected" "onsubmit" "xmlns" "lang" "xml:lang"
|
||||||
"media"
|
"media" "title"
|
||||||
] [ define-attribute-word ] each
|
] [ define-attribute-word ] each
|
||||||
] with-compilation-unit
|
] with-compilation-unit
|
||||||
|
|
|
@ -394,16 +394,18 @@ body ;
|
||||||
[ unparse-cookies "set-cookie" pick set-at ] when*
|
[ unparse-cookies "set-cookie" pick set-at ] when*
|
||||||
write-header ;
|
write-header ;
|
||||||
|
|
||||||
: body>quot ( body -- quot )
|
GENERIC: write-response-body* ( body -- )
|
||||||
{
|
|
||||||
{ [ dup not ] [ drop [ ] ] }
|
M: f write-response-body* drop ;
|
||||||
{ [ dup string? ] [ [ write ] curry ] }
|
|
||||||
{ [ dup callable? ] [ ] }
|
M: string write-response-body* write ;
|
||||||
[ [ stdio get stream-copy ] curry ]
|
|
||||||
} cond ;
|
M: callable write-response-body* call ;
|
||||||
|
|
||||||
|
M: object write-response-body* stdio get stream-copy ;
|
||||||
|
|
||||||
: write-response-body ( response -- response )
|
: write-response-body ( response -- response )
|
||||||
dup body>> body>quot call ;
|
dup body>> write-response-body* ;
|
||||||
|
|
||||||
M: response write-response ( respose -- )
|
M: response write-response ( respose -- )
|
||||||
write-response-version
|
write-response-version
|
||||||
|
|
|
@ -68,10 +68,7 @@ M: user-saver dispose
|
||||||
<action>
|
<action>
|
||||||
[ blank-values ] >>init
|
[ blank-values ] >>init
|
||||||
|
|
||||||
[
|
[ form edit-form ] >>display
|
||||||
"text/html" <content>
|
|
||||||
[ form edit-form ] >>body
|
|
||||||
] >>display
|
|
||||||
|
|
||||||
[
|
[
|
||||||
blank-values
|
blank-values
|
||||||
|
@ -120,10 +117,7 @@ SYMBOL: user-exists?
|
||||||
<action>
|
<action>
|
||||||
[ blank-values ] >>init
|
[ blank-values ] >>init
|
||||||
|
|
||||||
[
|
[ form edit-form ] >>display
|
||||||
"text/html" <content>
|
|
||||||
[ form edit-form ] >>body
|
|
||||||
] >>display
|
|
||||||
|
|
||||||
[
|
[
|
||||||
blank-values
|
blank-values
|
||||||
|
@ -174,10 +168,7 @@ SYMBOL: previous-page
|
||||||
dup email>> "email" set-value
|
dup email>> "email" set-value
|
||||||
] >>init
|
] >>init
|
||||||
|
|
||||||
[
|
[ form edit-form ] >>display
|
||||||
"text/html" <content>
|
|
||||||
[ form edit-form ] >>body
|
|
||||||
] >>display
|
|
||||||
|
|
||||||
[
|
[
|
||||||
blank-values
|
blank-values
|
||||||
|
@ -262,10 +253,7 @@ SYMBOL: lost-password-from
|
||||||
<action>
|
<action>
|
||||||
[ blank-values ] >>init
|
[ blank-values ] >>init
|
||||||
|
|
||||||
[
|
[ form edit-form ] >>display
|
||||||
"text/html" <content>
|
|
||||||
[ form edit-form ] >>body
|
|
||||||
] >>display
|
|
||||||
|
|
||||||
[
|
[
|
||||||
blank-values
|
blank-values
|
||||||
|
@ -314,10 +302,7 @@ SYMBOL: lost-password-from
|
||||||
] H{ } make-assoc values set
|
] H{ } make-assoc values set
|
||||||
] >>init
|
] >>init
|
||||||
|
|
||||||
[
|
[ <recover-form-3> edit-form ] >>display
|
||||||
"text/html" <content>
|
|
||||||
[ <recover-form-3> edit-form ] >>body
|
|
||||||
] >>display
|
|
||||||
|
|
||||||
[
|
[
|
||||||
blank-values
|
blank-values
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel namespaces boxes sequences strings
|
USING: accessors kernel namespaces boxes sequences strings
|
||||||
io io.streams.string
|
io io.streams.string
|
||||||
|
http
|
||||||
http.server
|
http.server
|
||||||
http.server.templating ;
|
http.server.templating ;
|
||||||
IN: http.server.boilerplate
|
IN: http.server.boilerplate
|
||||||
|
@ -27,6 +28,8 @@ SYMBOL: style
|
||||||
: write-style ( -- )
|
: write-style ( -- )
|
||||||
style get >string write ;
|
style get >string write ;
|
||||||
|
|
||||||
|
SYMBOL: nested-template?
|
||||||
|
|
||||||
SYMBOL: next-template
|
SYMBOL: next-template
|
||||||
|
|
||||||
: call-next-template ( -- )
|
: call-next-template ( -- )
|
||||||
|
@ -39,9 +42,15 @@ M: f call-template drop call-next-template ;
|
||||||
title get [ <box> title set ] unless
|
title get [ <box> title set ] unless
|
||||||
style get [ SBUF" " clone style set ] unless
|
style get [ SBUF" " clone style set ] unless
|
||||||
|
|
||||||
swap with-string-writer next-template set
|
[
|
||||||
|
[
|
||||||
call-template
|
nested-template? on
|
||||||
|
write-response-body*
|
||||||
|
] with-string-writer
|
||||||
|
next-template set
|
||||||
|
]
|
||||||
|
[ call-template ]
|
||||||
|
bi*
|
||||||
] with-scope ; inline
|
] with-scope ; inline
|
||||||
|
|
||||||
M: boilerplate call-responder
|
M: boilerplate call-responder
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
IN: http.server.components.tests
|
IN: http.server.components.tests
|
||||||
USING: http.server.components http.server.forms
|
USING: http.server.components http.server.forms
|
||||||
http.server.validators namespaces tools.test kernel accessors
|
http.server.validators namespaces tools.test kernel accessors
|
||||||
tuple-syntax mirrors http.server.actions
|
tuple-syntax mirrors
|
||||||
http.server.templating.fhtml
|
http http.server.actions http.server.templating.fhtml
|
||||||
io.streams.string io.streams.null ;
|
io.streams.string io.streams.null ;
|
||||||
|
|
||||||
\ render-edit must-infer
|
|
||||||
|
|
||||||
validation-failed? off
|
validation-failed? off
|
||||||
|
|
||||||
[ 3 ] [ "3" "n" <number> validate ] unit-test
|
[ 3 ] [ "3" "n" <number> validate ] unit-test
|
||||||
|
@ -65,9 +63,9 @@ TUPLE: test-tuple text number more-text ;
|
||||||
"hi" >>default
|
"hi" >>default
|
||||||
add-field ;
|
add-field ;
|
||||||
|
|
||||||
[ ] [ <test-tuple> <mirror> values set <test-form> view-form ] unit-test
|
[ ] [ <test-tuple> <mirror> values set <test-form> view-form write-response-body drop ] unit-test
|
||||||
|
|
||||||
[ ] [ <test-tuple> <mirror> values set <test-form> edit-form ] unit-test
|
[ ] [ <test-tuple> <mirror> values set <test-form> edit-form write-response-body drop ] unit-test
|
||||||
|
|
||||||
[ TUPLE{ test-tuple number: 123 more-text: "hi" } ] [
|
[ TUPLE{ test-tuple number: 123 more-text: "hi" } ] [
|
||||||
<test-tuple> from-tuple
|
<test-tuple> from-tuple
|
||||||
|
|
|
@ -7,9 +7,12 @@ continuations math ;
|
||||||
IN: http.server.components
|
IN: http.server.components
|
||||||
|
|
||||||
! Renderer protocol
|
! Renderer protocol
|
||||||
|
GENERIC: render-summary* ( value renderer -- )
|
||||||
GENERIC: render-view* ( value renderer -- )
|
GENERIC: render-view* ( value renderer -- )
|
||||||
GENERIC: render-edit* ( value id renderer -- )
|
GENERIC: render-edit* ( value id renderer -- )
|
||||||
|
|
||||||
|
M: object render-summary* render-view* ;
|
||||||
|
|
||||||
TUPLE: field type ;
|
TUPLE: field type ;
|
||||||
|
|
||||||
C: <field> field
|
C: <field> field
|
||||||
|
@ -235,3 +238,35 @@ TUPLE: text < string ;
|
||||||
|
|
||||||
: <text> ( id -- component )
|
: <text> ( id -- component )
|
||||||
text new-text ;
|
text new-text ;
|
||||||
|
|
||||||
|
! List components
|
||||||
|
SYMBOL: +plain+
|
||||||
|
SYMBOL: +ordered+
|
||||||
|
SYMBOL: +unordered+
|
||||||
|
|
||||||
|
TUPLE: list-renderer component type ;
|
||||||
|
|
||||||
|
C: <list-renderer> list-renderer
|
||||||
|
|
||||||
|
: render-list ( value component -- )
|
||||||
|
[ render-summary* ] curry each ;
|
||||||
|
|
||||||
|
: render-ordered-list ( value component -- )
|
||||||
|
[ <li> render-summary* </li> ] curry each ;
|
||||||
|
|
||||||
|
: render-unordered-list ( value component -- )
|
||||||
|
[ <li> render-summary* </li> ] curry each ;
|
||||||
|
|
||||||
|
M: list-renderer render-view*
|
||||||
|
[ component>> ] [ type>> ] bi {
|
||||||
|
{ +plain+ [ render-list ] }
|
||||||
|
{ +ordered+ [ <ol> render-ordered-list </ol> ] }
|
||||||
|
{ +unordered+ [ <ul> render-unordered-list </ul> ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
TUPLE: list < component ;
|
||||||
|
|
||||||
|
: <list> ( id component type -- list )
|
||||||
|
<list-renderer> list swap new-component ;
|
||||||
|
|
||||||
|
M: list component-string drop ;
|
||||||
|
|
|
@ -15,10 +15,7 @@ IN: http.server.crud
|
||||||
|
|
||||||
[ "id" get ctor call select-tuple from-tuple ] >>init
|
[ "id" get ctor call select-tuple from-tuple ] >>init
|
||||||
|
|
||||||
[
|
[ form view-form ] >>display ;
|
||||||
"text/html" <content>
|
|
||||||
[ form view-form ] >>body
|
|
||||||
] >>display ;
|
|
||||||
|
|
||||||
: <id-redirect> ( id next -- response )
|
: <id-redirect> ( id next -- response )
|
||||||
swap number>string "id" associate <permanent-redirect> ;
|
swap number>string "id" associate <permanent-redirect> ;
|
||||||
|
@ -36,10 +33,7 @@ IN: http.server.crud
|
||||||
if
|
if
|
||||||
] >>init
|
] >>init
|
||||||
|
|
||||||
[
|
[ form edit-form ] >>display
|
||||||
"text/html" <content>
|
|
||||||
[ form edit-form ] >>body
|
|
||||||
] >>display
|
|
||||||
|
|
||||||
[
|
[
|
||||||
f ctor call from-tuple
|
f ctor call from-tuple
|
||||||
|
@ -64,13 +58,10 @@ IN: http.server.crud
|
||||||
|
|
||||||
:: <list-action> ( form ctor -- action )
|
:: <list-action> ( form ctor -- action )
|
||||||
<action>
|
<action>
|
||||||
[
|
|
||||||
"text/html" <content>
|
|
||||||
[
|
[
|
||||||
blank-values
|
blank-values
|
||||||
|
|
||||||
f ctor call select-tuples "list" set-value
|
f ctor call select-tuples "list" set-value
|
||||||
|
|
||||||
form view-form
|
form view-form
|
||||||
] >>body
|
|
||||||
] >>display ;
|
] >>display ;
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
! Copyright (C) 2008 Slava Pestov
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel accessors assocs namespaces io.files sequences fry
|
USING: kernel accessors assocs namespaces io.files sequences fry
|
||||||
|
http.server
|
||||||
http.server.actions
|
http.server.actions
|
||||||
http.server.components
|
http.server.components
|
||||||
http.server.validators
|
http.server.validators
|
||||||
|
@ -17,8 +20,11 @@ M: form init V{ } clone >>components ;
|
||||||
: add-field ( form component -- form )
|
: add-field ( form component -- form )
|
||||||
dup id>> pick components>> set-at ;
|
dup id>> pick components>> set-at ;
|
||||||
|
|
||||||
|
: set-components ( form -- )
|
||||||
|
components>> components set ;
|
||||||
|
|
||||||
: with-form ( form quot -- )
|
: with-form ( form quot -- )
|
||||||
>r components>> components r> with-variable ; inline
|
[ [ set-components ] [ call ] bi* ] with-scope ; inline
|
||||||
|
|
||||||
: set-defaults ( form -- )
|
: set-defaults ( form -- )
|
||||||
[
|
[
|
||||||
|
@ -29,14 +35,16 @@ M: form init V{ } clone >>components ;
|
||||||
] assoc-each
|
] assoc-each
|
||||||
] with-form ;
|
] with-form ;
|
||||||
|
|
||||||
: view-form ( form -- )
|
: <form-response> ( form template -- response )
|
||||||
dup view-template>> '[ , call-template ] with-form ;
|
[ components>> components set ]
|
||||||
|
[ "text/html" <content> swap >>body ]
|
||||||
|
bi* ;
|
||||||
|
|
||||||
: edit-form ( form -- )
|
: view-form ( form -- response )
|
||||||
dup edit-template>> '[ , call-template ] with-form ;
|
dup view-template>> <form-response> ;
|
||||||
|
|
||||||
: summary-form ( form -- )
|
: edit-form ( form -- response )
|
||||||
dup summary-template>> '[ , call-template ] with-form ;
|
dup edit-template>> <form-response> ;
|
||||||
|
|
||||||
: validate-param ( id component -- )
|
: validate-param ( id component -- )
|
||||||
[ [ params get at ] [ validate ] bi* ]
|
[ [ params get at ] [ validate ] bi* ]
|
||||||
|
@ -52,19 +60,19 @@ M: form init V{ } clone >>components ;
|
||||||
: validate-form ( form -- )
|
: validate-form ( form -- )
|
||||||
(validate-form) [ validation-failed ] when ;
|
(validate-form) [ validation-failed ] when ;
|
||||||
|
|
||||||
! List components
|
: render-form ( value form template -- )
|
||||||
TUPLE: list-renderer form ;
|
[
|
||||||
|
[ from-tuple ]
|
||||||
|
[ set-components ]
|
||||||
|
[ call-template ]
|
||||||
|
tri*
|
||||||
|
] with-scope ;
|
||||||
|
|
||||||
C: <list-renderer> list-renderer
|
M: form render-summary*
|
||||||
|
dup summary-template>> render-form ;
|
||||||
|
|
||||||
M: list-renderer render-view*
|
M: form render-view*
|
||||||
form>> [
|
dup view-template>> render-form ;
|
||||||
[ >r from-tuple r> summary-form ] with-scope
|
|
||||||
] curry each ;
|
|
||||||
|
|
||||||
TUPLE: list < component ;
|
M: form render-edit*
|
||||||
|
dup edit-template>> render-form ;
|
||||||
: <list> ( id form -- list )
|
|
||||||
list swap <list-renderer> new-component ;
|
|
||||||
|
|
||||||
M: list component-string drop ;
|
|
||||||
|
|
|
@ -156,13 +156,19 @@ SYMBOL: tags
|
||||||
[
|
[
|
||||||
V{ } clone tags set
|
V{ } clone tags set
|
||||||
|
|
||||||
|
nested-template? get [
|
||||||
|
process-template
|
||||||
|
] [
|
||||||
{
|
{
|
||||||
[ xml-prolog write-prolog ]
|
[ xml-prolog write-prolog ]
|
||||||
[ xml-before write-chunk ]
|
[ xml-before write-chunk ]
|
||||||
[ process-template ]
|
[ process-template ]
|
||||||
[ xml-after write-chunk ]
|
[ xml-after write-chunk ]
|
||||||
} cleave
|
} cleave
|
||||||
|
] if
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
M: chloe call-template
|
M: chloe call-template
|
||||||
path>> utf8 <file-reader> read-xml process-chloe ;
|
path>> utf8 <file-reader> read-xml process-chloe ;
|
||||||
|
|
||||||
|
INSTANCE: chloe template
|
||||||
|
|
|
@ -94,3 +94,5 @@ M: fhtml call-template ( filename -- )
|
||||||
[ <fhtml> serve-template ]
|
[ <fhtml> serve-template ]
|
||||||
"application/x-factor-server-page"
|
"application/x-factor-server-page"
|
||||||
pick special>> set-at ;
|
pick special>> set-at ;
|
||||||
|
|
||||||
|
INSTANCE: fhtml template
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
USING: accessors kernel fry io.encodings.utf8 io.files
|
USING: accessors kernel fry io.encodings.utf8 io.files
|
||||||
http.server ;
|
http http.server ;
|
||||||
IN: http.server.templating
|
IN: http.server.templating
|
||||||
|
|
||||||
|
MIXIN: template
|
||||||
|
|
||||||
GENERIC: call-template ( template -- )
|
GENERIC: call-template ( template -- )
|
||||||
|
|
||||||
|
M: template write-response-body* call-template ;
|
||||||
|
|
||||||
: template-convert ( template output -- )
|
: template-convert ( template output -- )
|
||||||
utf8 [ call-template ] with-file-writer ;
|
utf8 [ call-template ] with-file-writer ;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
IN: locals.backend.tests
|
||||||
|
USING: tools.test locals.backend kernel arrays ;
|
||||||
|
|
||||||
|
[ 3 ] [ 3 >r 1 get-local r> drop ] unit-test
|
||||||
|
|
||||||
|
[ 4 ] [ 3 4 >r >r 2 get-local 2 drop-locals ] unit-test
|
||||||
|
|
||||||
|
: get-local-test-1 3 >r 1 get-local r> drop ;
|
||||||
|
|
||||||
|
{ 0 1 } [ get-local-test-1 ] must-infer-as
|
||||||
|
|
||||||
|
[ 3 ] [ get-local-test-1 ] unit-test
|
||||||
|
|
||||||
|
: get-local-test-2 3 4 >r >r 2 get-local 2 drop-locals ;
|
||||||
|
|
||||||
|
{ 0 1 } [ get-local-test-2 ] must-infer-as
|
||||||
|
|
||||||
|
[ 4 ] [ get-local-test-2 ] unit-test
|
||||||
|
|
||||||
|
: get-local-test-3 3 4 >r >r 2 get-local r> r> 2array ;
|
||||||
|
|
||||||
|
{ 0 2 } [ get-local-test-3 ] must-infer-as
|
||||||
|
|
||||||
|
[ 4 { 3 4 } ] [ get-local-test-3 ] unit-test
|
||||||
|
|
||||||
|
: get-local-test-4 3 4 >r >r r> r> dup swap >r swap >r r> r> 2array ;
|
||||||
|
|
||||||
|
{ 0 2 } [ get-local-test-4 ] must-infer-as
|
||||||
|
|
||||||
|
[ 4 { 3 4 } ] [ get-local-test-4 ] unit-test
|
||||||
|
|
||||||
|
[ 1 2 ] [ 1 2 2 load-locals r> r> ] unit-test
|
||||||
|
|
||||||
|
: load-locals-test-1 1 2 2 load-locals r> r> ;
|
||||||
|
|
||||||
|
{ 0 2 } [ load-locals-test-1 ] must-infer-as
|
||||||
|
|
||||||
|
[ 1 2 ] [ load-locals-test-1 ] unit-test
|
|
@ -0,0 +1,37 @@
|
||||||
|
USING: math kernel slots.private inference.known-words
|
||||||
|
inference.backend sequences effects words ;
|
||||||
|
IN: locals.backend
|
||||||
|
|
||||||
|
: load-locals ( n -- )
|
||||||
|
dup zero? [ drop ] [ swap >r 1- load-locals ] if ;
|
||||||
|
|
||||||
|
: get-local ( n -- value )
|
||||||
|
dup zero? [ drop dup ] [ r> swap 1- get-local swap >r ] if ;
|
||||||
|
|
||||||
|
: local-value 2 slot ; inline
|
||||||
|
|
||||||
|
: set-local-value 2 set-slot ; inline
|
||||||
|
|
||||||
|
: drop-locals ( n -- )
|
||||||
|
dup zero? [ drop ] [ r> drop 1- drop-locals ] if ;
|
||||||
|
|
||||||
|
\ load-locals [
|
||||||
|
pop-literal nip
|
||||||
|
[ dup reverse <effect> infer-shuffle ]
|
||||||
|
[ infer->r ]
|
||||||
|
bi
|
||||||
|
] "infer" set-word-prop
|
||||||
|
|
||||||
|
\ get-local [
|
||||||
|
pop-literal nip
|
||||||
|
[ infer-r> ]
|
||||||
|
[ dup 0 prefix <effect> infer-shuffle ]
|
||||||
|
[ infer->r ]
|
||||||
|
tri
|
||||||
|
] "infer" set-word-prop
|
||||||
|
|
||||||
|
\ drop-locals [
|
||||||
|
pop-literal nip
|
||||||
|
[ infer-r> ]
|
||||||
|
[ { } <effect> infer-shuffle ] bi
|
||||||
|
] "infer" set-word-prop
|
|
@ -82,6 +82,8 @@ IN: locals.tests
|
||||||
|
|
||||||
0 write-test-1 "q" set
|
0 write-test-1 "q" set
|
||||||
|
|
||||||
|
{ 1 1 } "q" get must-infer-as
|
||||||
|
|
||||||
[ 1 ] [ 1 "q" get call ] unit-test
|
[ 1 ] [ 1 "q" get call ] unit-test
|
||||||
|
|
||||||
[ 2 ] [ 1 "q" get call ] unit-test
|
[ 2 ] [ 1 "q" get call ] unit-test
|
||||||
|
|
|
@ -4,7 +4,8 @@ USING: kernel namespaces sequences sequences.private assocs math
|
||||||
inference.transforms parser words quotations debugger macros
|
inference.transforms parser words quotations debugger macros
|
||||||
arrays macros splitting combinators prettyprint.backend
|
arrays macros splitting combinators prettyprint.backend
|
||||||
definitions prettyprint hashtables prettyprint.sections sets
|
definitions prettyprint hashtables prettyprint.sections sets
|
||||||
sequences.private effects generic compiler.units accessors ;
|
sequences.private effects generic compiler.units accessors
|
||||||
|
locals.backend ;
|
||||||
IN: locals
|
IN: locals
|
||||||
|
|
||||||
! Inspired by
|
! Inspired by
|
||||||
|
@ -56,95 +57,80 @@ TUPLE: quote local ;
|
||||||
|
|
||||||
C: <quote> quote
|
C: <quote> quote
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
! read-local
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
: local-index ( obj args -- n )
|
: local-index ( obj args -- n )
|
||||||
[ dup quote? [ quote-local ] when eq? ] with find drop ;
|
[ dup quote? [ quote-local ] when eq? ] with find drop ;
|
||||||
|
|
||||||
: read-local ( obj args -- quot )
|
: read-local-quot ( obj args -- quot )
|
||||||
local-index 1+
|
local-index 1+ [ get-local ] curry ;
|
||||||
dup [ r> ] <repetition> concat [ dup ] append
|
|
||||||
swap [ swap >r ] <repetition> concat append ;
|
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
! localize
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
: localize-writer ( obj args -- quot )
|
: localize-writer ( obj args -- quot )
|
||||||
>r "local-reader" word-prop r> read-local [ 0 swap set-array-nth ] append ;
|
>r "local-reader" word-prop r>
|
||||||
|
read-local-quot [ set-local-value ] append ;
|
||||||
|
|
||||||
: localize ( obj args -- quot )
|
: localize ( obj args -- quot )
|
||||||
{
|
{
|
||||||
{ [ over local? ] [ read-local ] }
|
{ [ over local? ] [ read-local-quot ] }
|
||||||
{ [ over quote? ] [ >r quote-local r> read-local ] }
|
{ [ over quote? ] [ >r quote-local r> read-local-quot ] }
|
||||||
{ [ over local-word? ] [ read-local [ call ] append ] }
|
{ [ over local-word? ] [ read-local-quot [ call ] append ] }
|
||||||
{ [ over local-reader? ] [ read-local [ 0 swap array-nth ] append ] }
|
{ [ over local-reader? ] [ read-local-quot [ local-value ] append ] }
|
||||||
{ [ over local-writer? ] [ localize-writer ] }
|
{ [ over local-writer? ] [ localize-writer ] }
|
||||||
{ [ over \ lambda eq? ] [ 2drop [ ] ] }
|
{ [ over \ lambda eq? ] [ 2drop [ ] ] }
|
||||||
{ [ t ] [ drop 1quotation ] }
|
{ [ t ] [ drop 1quotation ] }
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
! point-free
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
UNION: special local quote local-word local-reader local-writer ;
|
UNION: special local quote local-word local-reader local-writer ;
|
||||||
|
|
||||||
: load-local ( arg -- quot )
|
: load-locals-quot ( args -- quot )
|
||||||
local-reader? [ 1array >r ] [ >r ] ? ;
|
dup [ local-reader? ] contains? [
|
||||||
|
<reversed> [
|
||||||
|
local-reader? [ 1array >r ] [ >r ] ?
|
||||||
|
] map concat
|
||||||
|
] [
|
||||||
|
length [ load-locals ] curry >quotation
|
||||||
|
] if ;
|
||||||
|
|
||||||
: load-locals ( quot args -- quot )
|
: drop-locals-quot ( args -- quot )
|
||||||
nip <reversed> [ load-local ] map concat ;
|
length [ drop-locals ] curry ;
|
||||||
|
|
||||||
: drop-locals ( args -- args quot )
|
|
||||||
dup length [ r> drop ] <repetition> concat ;
|
|
||||||
|
|
||||||
: point-free-body ( quot args -- newquot )
|
: point-free-body ( quot args -- newquot )
|
||||||
>r 1 head-slice* r> [ localize ] curry map concat ;
|
>r 1 head-slice* r> [ localize ] curry map concat ;
|
||||||
|
|
||||||
: point-free-end ( quot args -- newquot )
|
: point-free-end ( quot args -- newquot )
|
||||||
over peek special?
|
over peek special?
|
||||||
[ drop-locals >r >r peek r> localize r> append ]
|
[ dup drop-locals-quot >r >r peek r> localize r> append ]
|
||||||
[ drop-locals nip swap peek suffix ]
|
[ dup drop-locals-quot nip swap peek suffix ]
|
||||||
if ;
|
if ;
|
||||||
|
|
||||||
: (point-free) ( quot args -- newquot )
|
: (point-free) ( quot args -- newquot )
|
||||||
[ load-locals ] [ point-free-body ] [ point-free-end ]
|
[ nip load-locals-quot ]
|
||||||
|
[ point-free-body ]
|
||||||
|
[ point-free-end ]
|
||||||
2tri 3append >quotation ;
|
2tri 3append >quotation ;
|
||||||
|
|
||||||
: point-free ( quot args -- newquot )
|
: point-free ( quot args -- newquot )
|
||||||
over empty? [ drop ] [ (point-free) ] if ;
|
over empty? [ drop ] [ (point-free) ] if ;
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
! free-vars
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
UNION: lexical local local-reader local-writer local-word ;
|
UNION: lexical local local-reader local-writer local-word ;
|
||||||
|
|
||||||
GENERIC: free-vars ( form -- vars )
|
GENERIC: free-vars* ( form -- )
|
||||||
|
|
||||||
: add-if-free ( vars object -- vars )
|
: free-vars ( form -- vars )
|
||||||
|
[ free-vars* ] { } make prune ;
|
||||||
|
|
||||||
|
: add-if-free ( object -- )
|
||||||
{
|
{
|
||||||
{ [ dup local-writer? ] [ "local-reader" word-prop suffix ] }
|
{ [ dup local-writer? ] [ "local-reader" word-prop , ] }
|
||||||
{ [ dup lexical? ] [ suffix ] }
|
{ [ dup lexical? ] [ , ] }
|
||||||
{ [ dup quote? ] [ quote-local suffix ] }
|
{ [ dup quote? ] [ local>> , ] }
|
||||||
{ [ t ] [ free-vars append ] }
|
{ [ t ] [ free-vars* ] }
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
M: object free-vars drop { } ;
|
M: object free-vars* drop ;
|
||||||
|
|
||||||
M: quotation free-vars { } [ add-if-free ] reduce ;
|
M: quotation free-vars* [ add-if-free ] each ;
|
||||||
|
|
||||||
M: lambda free-vars
|
M: lambda free-vars*
|
||||||
dup vars>> swap body>> free-vars diff ;
|
[ vars>> ] [ body>> ] bi free-vars diff % ;
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
! lambda-rewrite
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
GENERIC: lambda-rewrite* ( obj -- )
|
GENERIC: lambda-rewrite* ( obj -- )
|
||||||
|
|
||||||
|
@ -172,8 +158,8 @@ M: lambda block-vars vars>> ;
|
||||||
M: lambda block-body body>> ;
|
M: lambda block-body body>> ;
|
||||||
|
|
||||||
M: lambda local-rewrite*
|
M: lambda local-rewrite*
|
||||||
dup vars>> swap body>>
|
[ vars>> ] [ body>> ] bi
|
||||||
[ local-rewrite* \ call , ] [ ] make <lambda> , ;
|
[ [ local-rewrite* ] each ] [ ] make <lambda> , ;
|
||||||
|
|
||||||
M: block lambda-rewrite*
|
M: block lambda-rewrite*
|
||||||
#! Turn free variables into bound variables, curry them
|
#! Turn free variables into bound variables, curry them
|
||||||
|
@ -188,8 +174,6 @@ M: object lambda-rewrite* , ;
|
||||||
|
|
||||||
M: object local-rewrite* , ;
|
M: object local-rewrite* , ;
|
||||||
|
|
||||||
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
|
|
||||||
: make-local ( name -- word )
|
: make-local ( name -- word )
|
||||||
"!" ?tail [
|
"!" ?tail [
|
||||||
<local-reader>
|
<local-reader>
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
! Copyright (c) 2008 Eric Mertens
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: arrays assocs combinators kernel math sequences math.ranges locals ;
|
||||||
|
IN: project-euler.076
|
||||||
|
|
||||||
|
! http://projecteuler.net/index.php?section=problems&id=76
|
||||||
|
|
||||||
|
! DESCRIPTION
|
||||||
|
! -----------
|
||||||
|
|
||||||
|
! How many different ways can one hundred be written as a
|
||||||
|
! sum of at least two positive integers?
|
||||||
|
|
||||||
|
! SOLUTION
|
||||||
|
! --------
|
||||||
|
|
||||||
|
! This solution uses dynamic programming and the following
|
||||||
|
! recurence relation:
|
||||||
|
|
||||||
|
! ways(0,_) = 1
|
||||||
|
! ways(_,0) = 0
|
||||||
|
! ways(n,i) = ways(n-i,i) + ways(n,i-1)
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: init ( n -- table )
|
||||||
|
[1,b] [ 0 2array 0 ] H{ } map>assoc
|
||||||
|
1 { 0 0 } pick set-at ;
|
||||||
|
|
||||||
|
: use ( n i -- n i )
|
||||||
|
[ - dup ] keep min ; inline
|
||||||
|
|
||||||
|
: ways ( n i table -- )
|
||||||
|
over zero? [
|
||||||
|
3drop
|
||||||
|
] [
|
||||||
|
[ [ 1- 2array ] dip at ]
|
||||||
|
[ [ use 2array ] dip at + ]
|
||||||
|
[ [ 2array ] dip set-at ] 3tri
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
:: each-subproblem ( n quot -- )
|
||||||
|
n [1,b] [ dup [1,b] quot with each ] each ; inline
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: (euler076) ( n -- m )
|
||||||
|
dup init
|
||||||
|
[ [ ways ] curry each-subproblem ]
|
||||||
|
[ [ dup 2array ] dip at 1- ] 2bi ;
|
||||||
|
|
||||||
|
: euler076 ( -- m )
|
||||||
|
100 (euler076) ;
|
|
@ -0,0 +1,55 @@
|
||||||
|
! Copyright (c) 2008 Eric Mertens
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel math math.ranges sequences sequences.lib ;
|
||||||
|
|
||||||
|
IN: project-euler.116
|
||||||
|
|
||||||
|
! http://projecteuler.net/index.php?section=problems&id=116
|
||||||
|
|
||||||
|
! DESCRIPTION
|
||||||
|
! -----------
|
||||||
|
|
||||||
|
! A row of five black square tiles is to have a number of its tiles replaced
|
||||||
|
! with coloured oblong tiles chosen from red (length two), green (length
|
||||||
|
! three), or blue (length four).
|
||||||
|
|
||||||
|
! If red tiles are chosen there are exactly seven ways this can be done.
|
||||||
|
! If green tiles are chosen there are three ways.
|
||||||
|
! And if blue tiles are chosen there are two ways.
|
||||||
|
|
||||||
|
! Assuming that colours cannot be mixed there are 7 + 3 + 2 = 12 ways of
|
||||||
|
! replacing the black tiles in a row measuring five units in length.
|
||||||
|
|
||||||
|
! How many different ways can the black tiles in a row measuring fifty units in
|
||||||
|
! length be replaced if colours cannot be mixed and at least one coloured tile
|
||||||
|
! must be used?
|
||||||
|
|
||||||
|
! SOLUTION
|
||||||
|
! --------
|
||||||
|
|
||||||
|
! This solution uses a simple dynamic programming approach using the
|
||||||
|
! following recurence relation
|
||||||
|
|
||||||
|
! ways(n,_) = 0 | n < 0
|
||||||
|
! ways(0,_) = 1
|
||||||
|
! ways(n,i) = ways(n-i,i) + ways(n-1,i)
|
||||||
|
! solution(n) = ways(n,1) - 1 + ways(n,2) - 1 + ways(n,3) - 1
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: nth* ( n seq -- elt/0 )
|
||||||
|
[ length swap - 1- ] keep ?nth 0 or ;
|
||||||
|
|
||||||
|
: next ( colortile seq -- )
|
||||||
|
[ nth* ] [ peek + ] [ push ] tri ;
|
||||||
|
|
||||||
|
: ways ( length colortile -- permutations )
|
||||||
|
V{ 1 } clone [ [ next ] 2curry times ] keep peek 1- ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: (euler116) ( length -- permutations )
|
||||||
|
3 [1,b] [ ways ] with sigma ;
|
||||||
|
|
||||||
|
: euler116 ( -- permutations )
|
||||||
|
50 (euler116) ;
|
|
@ -0,0 +1,42 @@
|
||||||
|
! Copyright (c) 2008 Eric Mertens
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel math splitting sequences ;
|
||||||
|
|
||||||
|
IN: project-euler.117
|
||||||
|
|
||||||
|
! http://projecteuler.net/index.php?section=problems&id=117
|
||||||
|
|
||||||
|
! DESCRIPTION
|
||||||
|
! -----------
|
||||||
|
|
||||||
|
! Using a combination of black square tiles and oblong tiles chosen
|
||||||
|
! from: red tiles measuring two units, green tiles measuring three
|
||||||
|
! units, and blue tiles measuring four units, it is possible to tile a
|
||||||
|
! row measuring five units in length in exactly fifteen different ways.
|
||||||
|
|
||||||
|
! How many ways can a row measuring fifty units in length be tiled?
|
||||||
|
|
||||||
|
! SOLUTION
|
||||||
|
! --------
|
||||||
|
|
||||||
|
! This solution uses a simple dynamic programming approach using the
|
||||||
|
! following recurence relation
|
||||||
|
|
||||||
|
! ways(i) = 1 | i <= 0
|
||||||
|
! ways(i) = ways(i-4) + ways(i-3) + ways(i-2) + ways(i-1)
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: short ( seq n -- seq n )
|
||||||
|
over length min ;
|
||||||
|
|
||||||
|
: next ( seq -- )
|
||||||
|
[ 4 short tail* sum ] keep push ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: (euler117) ( n -- m )
|
||||||
|
V{ 1 } clone tuck [ next ] curry times peek ;
|
||||||
|
|
||||||
|
: euler117 ( -- m )
|
||||||
|
50 (euler117) ;
|
|
@ -0,0 +1,44 @@
|
||||||
|
! Copyright (c) 2008 Eric Mertens
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel math sequences locals ;
|
||||||
|
IN: project-euler.150
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
! sequence helper functions
|
||||||
|
|
||||||
|
: partial-sums ( seq -- seq )
|
||||||
|
0 [ + ] accumulate swap suffix ; inline
|
||||||
|
|
||||||
|
: generate ( n quot -- seq )
|
||||||
|
[ drop ] swap compose map ; inline
|
||||||
|
|
||||||
|
: map-infimum ( seq quot -- min )
|
||||||
|
[ min ] compose 0 swap reduce ; inline
|
||||||
|
|
||||||
|
|
||||||
|
! triangle generator functions
|
||||||
|
|
||||||
|
: next ( t -- new-t s )
|
||||||
|
615949 * 797807 + 1 20 shift mod dup 1 19 shift - ; inline
|
||||||
|
|
||||||
|
: sums-triangle ( -- seq )
|
||||||
|
0 1000 [ 1+ [ next ] generate partial-sums ] map nip ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
:: (euler150) ( m -- n )
|
||||||
|
[let | table [ sums-triangle ] |
|
||||||
|
m [| x |
|
||||||
|
x 1+ [| y |
|
||||||
|
m x - [| z |
|
||||||
|
x z + table nth
|
||||||
|
[ y z + 1+ swap nth ]
|
||||||
|
[ y swap nth ] bi -
|
||||||
|
] map partial-sums infimum
|
||||||
|
] map-infimum
|
||||||
|
] map-infimum
|
||||||
|
] ;
|
||||||
|
|
||||||
|
: euler150 ( -- n )
|
||||||
|
1000 (euler150) ;
|
|
@ -12,17 +12,16 @@ TUPLE: blum-blum-shub x n ;
|
||||||
: generate-bbs-primes ( numbits -- p q )
|
: generate-bbs-primes ( numbits -- p q )
|
||||||
[ [ random-prime ] curry [ 4 mod 3 = ] generate ] dup bi ;
|
[ [ random-prime ] curry [ 4 mod 3 = ] generate ] dup bi ;
|
||||||
|
|
||||||
|
: next-bbs-bit ( bbs -- bit )
|
||||||
|
[ [ x>> 2 ] [ n>> ] bi ^mod dup ] keep (>>x) 1 bitand ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
: <blum-blum-shub> ( numbits -- blum-blum-shub )
|
: <blum-blum-shub> ( numbits -- blum-blum-shub )
|
||||||
generate-bbs-primes *
|
generate-bbs-primes *
|
||||||
[ find-relative-prime ] keep
|
[ find-relative-prime ] keep
|
||||||
blum-blum-shub boa ;
|
blum-blum-shub boa ;
|
||||||
|
|
||||||
: next-bbs-bit ( bbs -- bit )
|
|
||||||
[ [ x>> 2 ] [ n>> ] bi ^mod ] keep
|
|
||||||
over >>x drop 1 bitand ;
|
|
||||||
|
|
||||||
PRIVATE>
|
|
||||||
|
|
||||||
M: blum-blum-shub random-32* ( bbs -- r )
|
M: blum-blum-shub random-32* ( bbs -- r )
|
||||||
0 32 rot
|
0 32 rot
|
||||||
[ next-bbs-bit swap 1 shift bitor ] curry times ;
|
[ next-bbs-bit swap 1 shift bitor ] curry times ;
|
||||||
|
|
|
@ -226,3 +226,10 @@ IN: regexp-tests
|
||||||
[ t ] [ "s@f" "[a-z.-]@[a-z]" f <regexp> matches? ] unit-test
|
[ t ] [ "s@f" "[a-z.-]@[a-z]" f <regexp> matches? ] unit-test
|
||||||
[ f ] [ "a" "[a-z.-]@[a-z]" f <regexp> matches? ] unit-test
|
[ f ] [ "a" "[a-z.-]@[a-z]" f <regexp> matches? ] unit-test
|
||||||
[ t ] [ ".o" "\\.[a-z]" f <regexp> matches? ] unit-test
|
[ t ] [ ".o" "\\.[a-z]" f <regexp> matches? ] unit-test
|
||||||
|
|
||||||
|
! Bug in parsing word
|
||||||
|
[ t ] [
|
||||||
|
"a"
|
||||||
|
R' a'
|
||||||
|
matches?
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -290,10 +290,11 @@ TUPLE: regexp source parser ignore-case? ;
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
: parse-regexp ( accum end -- accum )
|
: parse-regexp ( accum end -- accum )
|
||||||
lexer get dup skip-blank [
|
lexer get dup skip-blank
|
||||||
[ index* dup 1+ swap ] 2keep swapd subseq swap
|
[ [ index* dup 1+ swap ] 2keep swapd subseq swap ] change-lexer-column
|
||||||
] change-lexer-column
|
lexer get dup still-parsing-line?
|
||||||
lexer get (parse-token) parse-options <regexp> parsed ;
|
[ (parse-token) parse-options ] [ drop f ] if
|
||||||
|
<regexp> parsed ;
|
||||||
|
|
||||||
: R! CHAR: ! parse-regexp ; parsing
|
: R! CHAR: ! parse-regexp ; parsing
|
||||||
: R" CHAR: " parse-regexp ; parsing
|
: R" CHAR: " parse-regexp ; parsing
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
USING: rss io kernel io.files tools.test io.encodings.utf8 ;
|
USING: rss io kernel io.files tools.test io.encodings.utf8
|
||||||
|
calendar ;
|
||||||
IN: rss.tests
|
IN: rss.tests
|
||||||
|
|
||||||
: load-news-file ( filename -- feed )
|
: load-news-file ( filename -- feed )
|
||||||
|
@ -35,7 +36,7 @@ IN: rss.tests
|
||||||
"http://example.org/2005/04/02/atom"
|
"http://example.org/2005/04/02/atom"
|
||||||
"\n <div xmlns=\"http://www.w3.org/1999/xhtml\">\n <p><i>[Update: The Atom draft is finished.]</i></p>\n </div>\n "
|
"\n <div xmlns=\"http://www.w3.org/1999/xhtml\">\n <p><i>[Update: The Atom draft is finished.]</i></p>\n </div>\n "
|
||||||
|
|
||||||
"2003-12-13T08:29:29-04:00"
|
T{ timestamp f 2003 12 13 8 29 29 -4 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ] [ "extra/rss/atom.xml" resource-path load-news-file ] unit-test
|
} ] [ "extra/rss/atom.xml" resource-path load-news-file ] unit-test
|
||||||
|
|
|
@ -4,10 +4,8 @@ IN: rss
|
||||||
USING: xml.utilities kernel assocs xml.generator
|
USING: xml.utilities kernel assocs xml.generator
|
||||||
strings sequences xml.data xml.writer
|
strings sequences xml.data xml.writer
|
||||||
io.streams.string combinators xml xml.entities io.files io
|
io.streams.string combinators xml xml.entities io.files io
|
||||||
http.client namespaces xml.generator hashtables ;
|
http.client namespaces xml.generator hashtables
|
||||||
|
calendar.format accessors continuations ;
|
||||||
: ?children>string ( tag/f -- string/f )
|
|
||||||
[ children>string ] [ f ] if* ;
|
|
||||||
|
|
||||||
: any-tag-named ( tag names -- tag-inside )
|
: any-tag-named ( tag names -- tag-inside )
|
||||||
f -rot [ tag-named nip dup ] with find 2drop ;
|
f -rot [ tag-named nip dup ] with find 2drop ;
|
||||||
|
@ -25,7 +23,7 @@ C: <entry> entry
|
||||||
[ "link" tag-named children>string ] keep
|
[ "link" tag-named children>string ] keep
|
||||||
[ "description" tag-named children>string ] keep
|
[ "description" tag-named children>string ] keep
|
||||||
f "date" "http://purl.org/dc/elements/1.1/" <name>
|
f "date" "http://purl.org/dc/elements/1.1/" <name>
|
||||||
tag-named ?children>string
|
tag-named dup [ children>string rfc3339>timestamp ] when
|
||||||
<entry> ;
|
<entry> ;
|
||||||
|
|
||||||
: rss1.0 ( xml -- feed )
|
: rss1.0 ( xml -- feed )
|
||||||
|
@ -41,7 +39,7 @@ C: <entry> entry
|
||||||
[ "link" tag-named ] keep
|
[ "link" tag-named ] keep
|
||||||
[ "guid" tag-named dupd ? children>string ] keep
|
[ "guid" tag-named dupd ? children>string ] keep
|
||||||
[ "description" tag-named children>string ] keep
|
[ "description" tag-named children>string ] keep
|
||||||
"pubDate" tag-named children>string <entry> ;
|
"pubDate" tag-named children>string rfc3339>timestamp <entry> ;
|
||||||
|
|
||||||
: rss2.0 ( xml -- feed )
|
: rss2.0 ( xml -- feed )
|
||||||
"channel" tag-named
|
"channel" tag-named
|
||||||
|
@ -59,7 +57,7 @@ C: <entry> entry
|
||||||
[ children>string ] if
|
[ children>string ] if
|
||||||
] keep
|
] keep
|
||||||
{ "published" "updated" "issued" "modified" } any-tag-named
|
{ "published" "updated" "issued" "modified" } any-tag-named
|
||||||
children>string <entry> ;
|
children>string rfc3339>timestamp <entry> ;
|
||||||
|
|
||||||
: atom1.0 ( xml -- feed )
|
: atom1.0 ( xml -- feed )
|
||||||
[ "title" tag-named children>string ] keep
|
[ "title" tag-named children>string ] keep
|
||||||
|
@ -78,10 +76,10 @@ C: <entry> entry
|
||||||
|
|
||||||
: download-feed ( url -- feed )
|
: download-feed ( url -- feed )
|
||||||
#! Retrieve an news syndication file, return as a feed tuple.
|
#! Retrieve an news syndication file, return as a feed tuple.
|
||||||
http-get-stream rot success? [
|
http-get-stream swap code>> success? [
|
||||||
nip read-feed
|
read-feed
|
||||||
] [
|
] [
|
||||||
2drop "Error retrieving newsfeed file" throw
|
dispose "Error retrieving newsfeed file" throw
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
! Atom generation
|
! Atom generation
|
||||||
|
@ -95,7 +93,7 @@ C: <entry> entry
|
||||||
"entry" [
|
"entry" [
|
||||||
dup entry-title "title" { { "type" "html" } } simple-tag*,
|
dup entry-title "title" { { "type" "html" } } simple-tag*,
|
||||||
"link" over entry-link "href" associate contained*,
|
"link" over entry-link "href" associate contained*,
|
||||||
dup entry-pub-date "published" simple-tag,
|
dup entry-pub-date timestamp>rfc3339 "published" simple-tag,
|
||||||
entry-description [ "content" { { "type" "html" } } simple-tag*, ] when*
|
entry-description [ "content" { { "type" "html" } } simple-tag*, ] when*
|
||||||
] tag, ;
|
] tag, ;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
|
||||||
|
USING: kernel arrays strings sequences sequences.deep peg peg.ebnf ;
|
||||||
|
|
||||||
|
IN: shell.parser
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
TUPLE: incantation command stdin stdout background ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
TUPLE: single-quoted-expr expr ;
|
||||||
|
TUPLE: double-quoted-expr expr ;
|
||||||
|
TUPLE: back-quoted-expr expr ;
|
||||||
|
TUPLE: glob-expr expr ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: <single-quoted-expr> single-quoted-expr boa ;
|
||||||
|
: <double-quoted-expr> double-quoted-expr boa ;
|
||||||
|
: <back-quoted-expr> back-quoted-expr boa ;
|
||||||
|
: <glob-expr> glob-expr boa ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
EBNF: expr
|
||||||
|
|
||||||
|
space = " "
|
||||||
|
|
||||||
|
tab = "\t"
|
||||||
|
|
||||||
|
white = (space | tab)
|
||||||
|
|
||||||
|
whitespace = (white)* => [[ drop ignore ]]
|
||||||
|
|
||||||
|
squote = "'"
|
||||||
|
|
||||||
|
single-quoted = squote (!(squote) .)* squote => [[ second >string <single-quoted-expr> ]]
|
||||||
|
|
||||||
|
dquote = '"'
|
||||||
|
|
||||||
|
double-quoted = dquote (!(dquote) .)* dquote => [[ second >string <double-quoted-expr> ]]
|
||||||
|
|
||||||
|
bquote = "`"
|
||||||
|
|
||||||
|
back-quoted = bquote (!(bquote) .)* bquote => [[ second >string <back-quoted-expr> ]]
|
||||||
|
|
||||||
|
glob-char = ("*" | "?")
|
||||||
|
|
||||||
|
non-glob-char = !(glob-char | white) .
|
||||||
|
|
||||||
|
glob-beginning-string = (non-glob-char)* [[ >string ]]
|
||||||
|
|
||||||
|
glob-rest-string = (non-glob-char)+ [[ >string ]]
|
||||||
|
|
||||||
|
glob = glob-beginning-string glob-char (glob-rest-string | glob-char)* => [[ flatten concat <glob-expr> ]]
|
||||||
|
|
||||||
|
other = (!(white | "&" | ">" | ">>" | "<") .)+ => [[ >string ]]
|
||||||
|
|
||||||
|
element = (single-quoted | double-quoted | back-quoted | glob | other)
|
||||||
|
|
||||||
|
to-file = ">" whitespace other => [[ second ]]
|
||||||
|
|
||||||
|
in-file = "<" whitespace other => [[ second ]]
|
||||||
|
|
||||||
|
ap-file = ">>" whitespace other => [[ second ]]
|
||||||
|
|
||||||
|
redirection = (in-file)? whitespace (to-file | ap-file)?
|
||||||
|
|
||||||
|
line = (element whitespace)+ (in-file)? whitespace (to-file | ap-file)? whitespace ("&")? => [[ first4 incantation boa ]]
|
||||||
|
|
||||||
|
;EBNF
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
|
||||||
|
USING: kernel words continuations namespaces debugger sequences combinators
|
||||||
|
io io.files io.launcher
|
||||||
|
accessors multi-methods newfx shell.parser ;
|
||||||
|
|
||||||
|
IN: shell
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: cd ( args -- )
|
||||||
|
dup empty?
|
||||||
|
[ drop home set-current-directory ]
|
||||||
|
[ first set-current-directory ]
|
||||||
|
if ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: pwd ( args -- )
|
||||||
|
drop
|
||||||
|
current-directory get
|
||||||
|
print ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: swords ( -- seq ) { "cd" "pwd" } ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
GENERIC: expand ( expr -- expr )
|
||||||
|
|
||||||
|
METHOD: expand { single-quoted-expr } expr>> ;
|
||||||
|
|
||||||
|
METHOD: expand { double-quoted-expr } expr>> ;
|
||||||
|
|
||||||
|
METHOD: expand { object } ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: expansion ( command -- command ) [ expand ] map ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: run-incantation ( incantation -- )
|
||||||
|
<process>
|
||||||
|
over command>> expansion >>command
|
||||||
|
over stdin>> >>stdin
|
||||||
|
over stdout>> >>stdout
|
||||||
|
swap background>>
|
||||||
|
[ run-detached drop ]
|
||||||
|
[ [ try-process ] [ print-error drop ] recover ]
|
||||||
|
if ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: chant ( incantation -- )
|
||||||
|
dup command>> first swords member-of?
|
||||||
|
[ command>> unclip "shell" lookup execute ]
|
||||||
|
[ run-incantation ]
|
||||||
|
if ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: prompt ( -- )
|
||||||
|
current-directory get write
|
||||||
|
" $ " write
|
||||||
|
flush ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: shell ( -- )
|
||||||
|
prompt
|
||||||
|
readln
|
||||||
|
{
|
||||||
|
{ [ dup f = ] [ drop ] }
|
||||||
|
{ [ dup "exit" = ] [ drop ] }
|
||||||
|
{ [ dup "" = ] [ drop shell ] }
|
||||||
|
{ [ dup expr ] [ expr ast>> chant shell ] }
|
||||||
|
{ [ t ] [ drop shell ] }
|
||||||
|
}
|
||||||
|
cond ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
: ix ( -- ) shell ;
|
||||||
|
|
||||||
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
MAIN: ix
|
|
@ -9,6 +9,15 @@ quotations io.launcher words.private tools.deploy.config
|
||||||
bootstrap.image io.encodings.utf8 accessors ;
|
bootstrap.image io.encodings.utf8 accessors ;
|
||||||
IN: tools.deploy.backend
|
IN: tools.deploy.backend
|
||||||
|
|
||||||
|
: copy-vm ( executable bundle-name extension -- vm )
|
||||||
|
[ prepend-path ] dip append vm over copy-file ;
|
||||||
|
|
||||||
|
: copy-fonts ( name dir -- )
|
||||||
|
append-path "fonts/" resource-path swap copy-tree-into ;
|
||||||
|
|
||||||
|
: image-name ( vocab bundle-name -- str )
|
||||||
|
prepend-path ".image" append ;
|
||||||
|
|
||||||
: (copy-lines) ( stream -- )
|
: (copy-lines) ( stream -- )
|
||||||
dup stream-readln dup
|
dup stream-readln dup
|
||||||
[ print flush (copy-lines) ] [ 2drop ] if ;
|
[ print flush (copy-lines) ] [ 2drop ] if ;
|
||||||
|
|
|
@ -7,7 +7,12 @@ ARTICLE: "tools.deploy" "Application deployment"
|
||||||
$nl
|
$nl
|
||||||
"For example, we can deploy the " { $vocab-link "hello-world" } " demo which comes with Factor:"
|
"For example, we can deploy the " { $vocab-link "hello-world" } " demo which comes with Factor:"
|
||||||
{ $code "\"hello-ui\" deploy" }
|
{ $code "\"hello-ui\" deploy" }
|
||||||
"On Mac OS X, this yields a program named " { $snippet "Hello world.app" } ". On Windows, it yields a directory named " { $snippet "Hello world" } " containing a program named " { $snippet "hello-ui.exe" } ". In both cases, running the program displays a window with a message."
|
{ $list
|
||||||
|
{ "On Mac OS X, this yields a program named " { $snippet "Hello world.app" } "." }
|
||||||
|
{ "On Windows, it yields a directory named " { $snippet "Hello world" } " containing a program named " { $snippet "hello-ui.exe" } "." }
|
||||||
|
{ "On Unix-like systems (Linux, BSD, Solaris, etc), it yields a directory named " { $snippet "Hello world" } " containing a program named " { $snippet "hello-ui" } "." }
|
||||||
|
}
|
||||||
|
"In all cases, running the program displays a window with a message."
|
||||||
$nl
|
$nl
|
||||||
"The deployment tool works by bootstrapping a fresh image, loading the vocabulary into this image, then applying various heuristics to strip the image down to minimal size."
|
"The deployment tool works by bootstrapping a fresh image, loading the vocabulary into this image, then applying various heuristics to strip the image down to minimal size."
|
||||||
$nl
|
$nl
|
||||||
|
|
|
@ -7,3 +7,4 @@ IN: tools.deploy
|
||||||
|
|
||||||
os macosx? [ "tools.deploy.macosx" require ] when
|
os macosx? [ "tools.deploy.macosx" require ] when
|
||||||
os winnt? [ "tools.deploy.windows" require ] when
|
os winnt? [ "tools.deploy.windows" require ] when
|
||||||
|
os unix? [ "tools.deploy.unix" require ] when
|
|
@ -14,13 +14,6 @@ IN: tools.deploy.macosx
|
||||||
bundle-dir over append-path -rot
|
bundle-dir over append-path -rot
|
||||||
"Contents" prepend-path append-path copy-tree ;
|
"Contents" prepend-path append-path copy-tree ;
|
||||||
|
|
||||||
: copy-vm ( executable bundle-name -- vm )
|
|
||||||
"Contents/MacOS/" append-path prepend-path vm over copy-file ;
|
|
||||||
|
|
||||||
: copy-fonts ( name -- )
|
|
||||||
"fonts/" resource-path
|
|
||||||
swap "Contents/Resources/" append-path copy-tree-into ;
|
|
||||||
|
|
||||||
: app-plist ( executable bundle-name -- assoc )
|
: app-plist ( executable bundle-name -- assoc )
|
||||||
[
|
[
|
||||||
"6.0" "CFBundleInfoDictionaryVersion" set
|
"6.0" "CFBundleInfoDictionaryVersion" set
|
||||||
|
@ -40,8 +33,8 @@ IN: tools.deploy.macosx
|
||||||
: create-app-dir ( vocab bundle-name -- vm )
|
: create-app-dir ( vocab bundle-name -- vm )
|
||||||
dup "Frameworks" copy-bundle-dir
|
dup "Frameworks" copy-bundle-dir
|
||||||
dup "Resources/English.lproj/MiniFactor.nib" copy-bundle-dir
|
dup "Resources/English.lproj/MiniFactor.nib" copy-bundle-dir
|
||||||
dup copy-fonts
|
dup "Contents/Resources/" copy-fonts
|
||||||
2dup create-app-plist copy-vm ;
|
2dup create-app-plist "Contents/MacOS/" append-path "" copy-vm ;
|
||||||
|
|
||||||
: deploy.app-image ( vocab bundle-name -- str )
|
: deploy.app-image ( vocab bundle-name -- str )
|
||||||
[ % "/Contents/Resources/" % % ".image" % ] "" make ;
|
[ % "/Contents/Resources/" % % ".image" % ] "" make ;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
James Cash
|
|
@ -0,0 +1 @@
|
||||||
|
Deploying minimal stand-alone binaries on *nix-like systems
|
|
@ -0,0 +1 @@
|
||||||
|
tools
|
|
@ -0,0 +1,23 @@
|
||||||
|
! Copyright (C) 2008 James Cash
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: io io.files io.backend kernel namespaces sequences
|
||||||
|
system tools.deploy.backend tools.deploy.config assocs
|
||||||
|
hashtables prettyprint ;
|
||||||
|
IN: tools.deploy.linux
|
||||||
|
|
||||||
|
: create-app-dir ( vocab bundle-name -- vm )
|
||||||
|
dup "" copy-fonts
|
||||||
|
"" copy-vm ;
|
||||||
|
|
||||||
|
: bundle-name ( -- str )
|
||||||
|
deploy-name get ;
|
||||||
|
|
||||||
|
M: linux deploy* ( vocab -- )
|
||||||
|
"." resource-path [
|
||||||
|
dup deploy-config [
|
||||||
|
[ bundle-name create-app-dir ] keep
|
||||||
|
[ bundle-name image-name ] keep
|
||||||
|
namespace make-deploy-image
|
||||||
|
bundle-name normalize-path [ "Binary deployed to " % % "." % ] "" make print
|
||||||
|
] bind
|
||||||
|
] with-directory ;
|
|
@ -5,13 +5,6 @@ tools.deploy.backend tools.deploy.config assocs hashtables
|
||||||
prettyprint windows.shell32 windows.user32 ;
|
prettyprint windows.shell32 windows.user32 ;
|
||||||
IN: tools.deploy.windows
|
IN: tools.deploy.windows
|
||||||
|
|
||||||
: copy-vm ( executable bundle-name -- vm )
|
|
||||||
prepend-path ".exe" append
|
|
||||||
vm over copy-file ;
|
|
||||||
|
|
||||||
: copy-fonts ( bundle-name -- )
|
|
||||||
"fonts/" resource-path swap copy-tree-into ;
|
|
||||||
|
|
||||||
: copy-dlls ( bundle-name -- )
|
: copy-dlls ( bundle-name -- )
|
||||||
{ "freetype6.dll" "zlib1.dll" "factor.dll" }
|
{ "freetype6.dll" "zlib1.dll" "factor.dll" }
|
||||||
[ resource-path ] map
|
[ resource-path ] map
|
||||||
|
@ -19,11 +12,8 @@ IN: tools.deploy.windows
|
||||||
|
|
||||||
: create-exe-dir ( vocab bundle-name -- vm )
|
: create-exe-dir ( vocab bundle-name -- vm )
|
||||||
dup copy-dlls
|
dup copy-dlls
|
||||||
dup copy-fonts
|
dup "" copy-fonts
|
||||||
copy-vm ;
|
".exe" copy-vm ;
|
||||||
|
|
||||||
: image-name ( vocab bundle-name -- str )
|
|
||||||
prepend-path ".image" append ;
|
|
||||||
|
|
||||||
M: winnt deploy*
|
M: winnt deploy*
|
||||||
"." resource-path [
|
"." resource-path [
|
||||||
|
|
|
@ -138,7 +138,6 @@ SYMBOL: +stopped+
|
||||||
>n ndrop >c c>
|
>n ndrop >c c>
|
||||||
continue continue-with
|
continue continue-with
|
||||||
stop yield suspend sleep (spawn)
|
stop yield suspend sleep (spawn)
|
||||||
suspend
|
|
||||||
} [
|
} [
|
||||||
dup [ execute break ] curry
|
dup [ execute break ] curry
|
||||||
"step-into" set-word-prop
|
"step-into" set-word-prop
|
||||||
|
|
|
@ -111,7 +111,7 @@ M: method-body word-completion-string
|
||||||
|
|
||||||
USE: generic.standard.engines.tuple
|
USE: generic.standard.engines.tuple
|
||||||
|
|
||||||
M: tuple-dispatch-engine-word word-completion-string
|
M: engine-word word-completion-string
|
||||||
"engine-generic" word-prop word-completion-string ;
|
"engine-generic" word-prop word-completion-string ;
|
||||||
|
|
||||||
: use-if-necessary ( word seq -- )
|
: use-if-necessary ( word seq -- )
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-size: 150%;
|
font-size: 150%;
|
||||||
color: #000000;3
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-button {
|
.link-button {
|
||||||
|
|
|
@ -53,7 +53,7 @@ todo "TODO"
|
||||||
: <todo-list-form> ( -- form )
|
: <todo-list-form> ( -- form )
|
||||||
"todo-list" <form>
|
"todo-list" <form>
|
||||||
"todo-list" todo-template >>view-template
|
"todo-list" todo-template >>view-template
|
||||||
"list" <todo-form> <list>
|
"list" <todo-form> +plain+ <list>
|
||||||
add-field ;
|
add-field ;
|
||||||
|
|
||||||
TUPLE: todo-responder < dispatcher ;
|
TUPLE: todo-responder < dispatcher ;
|
||||||
|
|
|
@ -36,9 +36,13 @@ TAGS>
|
||||||
f \ modes set-global ;
|
f \ modes set-global ;
|
||||||
|
|
||||||
MEMO: (load-mode) ( name -- rule-sets )
|
MEMO: (load-mode) ( name -- rule-sets )
|
||||||
modes at mode-file
|
modes at [
|
||||||
|
mode-file
|
||||||
"extra/xmode/modes/" prepend
|
"extra/xmode/modes/" prepend
|
||||||
resource-path utf8 <file-reader> parse-mode ;
|
resource-path utf8 <file-reader> parse-mode
|
||||||
|
] [
|
||||||
|
"text" (load-mode)
|
||||||
|
] if* ;
|
||||||
|
|
||||||
SYMBOL: rule-sets
|
SYMBOL: rule-sets
|
||||||
|
|
||||||
|
|
|
@ -250,3 +250,13 @@ double ffi_test_36(struct test_struct_12 x)
|
||||||
{
|
{
|
||||||
return x.x;
|
return x.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ffi_test_37(int (*f)(int, int, int))
|
||||||
|
{
|
||||||
|
static int global_var = 0;
|
||||||
|
printf("ffi_test_37\n");
|
||||||
|
global_var = f(global_var,global_var * 2,global_var * 3);
|
||||||
|
printf("global_var is %d\n",global_var);
|
||||||
|
fflush(stdout);
|
||||||
|
return global_var;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue