Merge branch 'master' of git://factorcode.org/git/factor
commit
0f09d0ef2e
|
@ -1,5 +1,5 @@
|
||||||
USING: arrays calendar kernel math sequences tools.test
|
USING: arrays calendar kernel math sequences tools.test
|
||||||
continuations system math.order threads ;
|
continuations system math.order threads accessors ;
|
||||||
IN: calendar.tests
|
IN: calendar.tests
|
||||||
|
|
||||||
[ f ] [ 2004 12 32 0 0 0 instant <timestamp> valid-timestamp? ] unit-test
|
[ f ] [ 2004 12 32 0 0 0 instant <timestamp> valid-timestamp? ] unit-test
|
||||||
|
@ -163,3 +163,10 @@ IN: calendar.tests
|
||||||
[ t ] [ now 50 milliseconds sleep now before? ] unit-test
|
[ t ] [ now 50 milliseconds sleep now before? ] unit-test
|
||||||
[ t ] [ now 50 milliseconds sleep now swap after? ] unit-test
|
[ t ] [ now 50 milliseconds sleep now swap after? ] unit-test
|
||||||
[ t ] [ now 50 milliseconds sleep now 50 milliseconds sleep now swapd between? ] unit-test
|
[ t ] [ now 50 milliseconds sleep now 50 milliseconds sleep now swapd between? ] unit-test
|
||||||
|
|
||||||
|
[ 4 12 ] [ 2009 easter [ month>> ] [ day>> ] bi ] unit-test
|
||||||
|
[ 4 2 ] [ 1961 easter [ month>> ] [ day>> ] bi ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ now dup midnight eq? ] unit-test
|
||||||
|
[ f ] [ now dup easter eq? ] unit-test
|
||||||
|
[ f ] [ now dup beginning-of-year eq? ] unit-test
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2007 Doug Coleman.
|
! Copyright (C) 2007 Doug Coleman.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays classes.tuple combinators combinators.short-circuit
|
USING: accessors arrays classes.tuple combinators
|
||||||
kernel locals math math.functions math.order namespaces sequences strings
|
combinators.short-circuit kernel locals math math.functions
|
||||||
summary system threads vocabs.loader ;
|
math.order sequences summary system threads vocabs.loader ;
|
||||||
IN: calendar
|
IN: calendar
|
||||||
|
|
||||||
HOOK: gmt-offset os ( -- hours minutes seconds )
|
HOOK: gmt-offset os ( -- hours minutes seconds )
|
||||||
|
@ -94,26 +94,50 @@ CONSTANT: day-abbreviations3
|
||||||
:: julian-day-number ( year month day -- n )
|
:: julian-day-number ( year month day -- n )
|
||||||
#! Returns a composite date number
|
#! Returns a composite date number
|
||||||
#! Not valid before year -4800
|
#! Not valid before year -4800
|
||||||
[let* | a [ 14 month - 12 /i ]
|
14 month - 12 /i :> a
|
||||||
y [ year 4800 + a - ]
|
year 4800 + a - :> y
|
||||||
m [ month 12 a * + 3 - ] |
|
month 12 a * + 3 - :> m
|
||||||
|
|
||||||
day 153 m * 2 + 5 /i + 365 y * +
|
day 153 m * 2 + 5 /i + 365 y * +
|
||||||
y 4 /i + y 100 /i - y 400 /i + 32045 -
|
y 4 /i + y 100 /i - y 400 /i + 32045 - ;
|
||||||
] ;
|
|
||||||
|
|
||||||
:: julian-day-number>date ( n -- year month day )
|
:: julian-day-number>date ( n -- year month day )
|
||||||
#! Inverse of julian-day-number
|
#! Inverse of julian-day-number
|
||||||
[let* | a [ n 32044 + ]
|
n 32044 + :> a
|
||||||
b [ 4 a * 3 + 146097 /i ]
|
4 a * 3 + 146097 /i :> b
|
||||||
c [ a 146097 b * 4 /i - ]
|
a 146097 b * 4 /i - :> c
|
||||||
d [ 4 c * 3 + 1461 /i ]
|
4 c * 3 + 1461 /i :> d
|
||||||
e [ c 1461 d * 4 /i - ]
|
c 1461 d * 4 /i - :> e
|
||||||
m [ 5 e * 2 + 153 /i ] |
|
5 e * 2 + 153 /i :> m
|
||||||
|
|
||||||
100 b * d + 4800 -
|
100 b * d + 4800 -
|
||||||
m 10 /i + m 3 +
|
m 10 /i + m 3 +
|
||||||
12 m 10 /i * -
|
12 m 10 /i * -
|
||||||
e 153 m * 2 + 5 /i - 1+
|
e 153 m * 2 + 5 /i - 1+ ;
|
||||||
] ;
|
|
||||||
|
GENERIC: easter ( obj -- obj' )
|
||||||
|
|
||||||
|
:: easter-month-day ( year -- month day )
|
||||||
|
year 19 mod :> a
|
||||||
|
year 100 /mod :> c :> b
|
||||||
|
b 4 /mod :> e :> d
|
||||||
|
b 8 + 25 /i :> f
|
||||||
|
b f - 1 + 3 /i :> g
|
||||||
|
19 a * b + d - g - 15 + 30 mod :> h
|
||||||
|
c 4 /mod :> k :> i
|
||||||
|
32 2 e * + 2 i * + h - k - 7 mod :> l
|
||||||
|
a 11 h * + 22 l * + 451 /i :> m
|
||||||
|
|
||||||
|
h l + 7 m * - 114 + 31 /mod 1 + :> day :> month
|
||||||
|
month day ;
|
||||||
|
|
||||||
|
M: integer easter ( year -- timestamp )
|
||||||
|
dup easter-month-day <date> ;
|
||||||
|
|
||||||
|
M: timestamp easter ( timestamp -- timestamp )
|
||||||
|
clone
|
||||||
|
dup year>> easter-month-day
|
||||||
|
swapd >>day swap >>month ;
|
||||||
|
|
||||||
: >date< ( timestamp -- year month day )
|
: >date< ( timestamp -- year month day )
|
||||||
[ year>> ] [ month>> ] [ day>> ] tri ;
|
[ year>> ] [ month>> ] [ day>> ] tri ;
|
||||||
|
|
|
@ -5,7 +5,7 @@ continuations effects namespaces.private io io.streams.string
|
||||||
memory system threads tools.test math accessors combinators
|
memory system threads tools.test math accessors combinators
|
||||||
specialized-arrays.float alien.libraries io.pathnames
|
specialized-arrays.float alien.libraries io.pathnames
|
||||||
io.backend ;
|
io.backend ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.alien
|
||||||
|
|
||||||
<<
|
<<
|
||||||
: libfactor-ffi-tests-path ( -- string )
|
: libfactor-ffi-tests-path ( -- string )
|
||||||
|
|
|
@ -4,7 +4,7 @@ sequences sequences.private tools.test namespaces.private
|
||||||
slots.private sequences.private byte-arrays alien
|
slots.private sequences.private byte-arrays alien
|
||||||
alien.accessors layouts words definitions compiler.units io
|
alien.accessors layouts words definitions compiler.units io
|
||||||
combinators vectors grouping make ;
|
combinators vectors grouping make ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.codegen
|
||||||
|
|
||||||
! Originally, this file did black box testing of templating
|
! Originally, this file did black box testing of templating
|
||||||
! optimization. We now have a different codegen, but the tests
|
! optimization. We now have a different codegen, but the tests
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: tools.test quotations math kernel sequences
|
USING: tools.test quotations math kernel sequences
|
||||||
assocs namespaces make compiler.units compiler ;
|
assocs namespaces make compiler.units compiler ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.curry
|
||||||
|
|
||||||
[ 3 ] [ 5 [ [ 2 - ] curry call ] compile-call ] unit-test
|
[ 3 ] [ 5 [ [ 2 - ] curry call ] compile-call ] unit-test
|
||||||
[ 3 ] [ [ 5 [ 2 - ] curry call ] compile-call ] unit-test
|
[ 3 ] [ [ 5 [ 2 - ] curry call ] compile-call ] unit-test
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.float
|
||||||
USING: compiler.units compiler kernel kernel.private memory math
|
USING: compiler.units compiler kernel kernel.private memory math
|
||||||
math.private tools.test math.floats.private ;
|
math.private tools.test math.floats.private ;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel classes.mixin arrays ;
|
kernel classes.mixin arrays ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.folding
|
||||||
|
|
||||||
! Calls to generic words were not folded away.
|
! Calls to generic words were not folded away.
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ sbufs strings.private slots.private alien math.order
|
||||||
alien.accessors alien.c-types alien.syntax alien.strings
|
alien.accessors alien.c-types alien.syntax alien.strings
|
||||||
namespaces libc sequences.private io.encodings.ascii
|
namespaces libc sequences.private io.encodings.ascii
|
||||||
classes compiler ;
|
classes compiler ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.intrinsics
|
||||||
|
|
||||||
! Make sure that intrinsic ops compile to correct code.
|
! Make sure that intrinsic ops compile to correct code.
|
||||||
[ ] [ 1 [ drop ] compile-call ] unit-test
|
[ ] [ 1 [ drop ] compile-call ] unit-test
|
||||||
|
|
|
@ -5,7 +5,7 @@ quotations classes classes.algebra classes.tuple.private
|
||||||
continuations growable namespaces hints alien.accessors
|
continuations growable namespaces hints alien.accessors
|
||||||
compiler.tree.builder compiler.tree.optimizer sequences.deep
|
compiler.tree.builder compiler.tree.optimizer sequences.deep
|
||||||
compiler ;
|
compiler ;
|
||||||
IN: optimizer.tests
|
IN: compiler.tests.optimizer
|
||||||
|
|
||||||
GENERIC: xyz ( obj -- obj )
|
GENERIC: xyz ( obj -- obj )
|
||||||
M: array xyz xyz ;
|
M: array xyz xyz ;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.peg-regression-2
|
||||||
USING: peg.ebnf strings tools.test ;
|
USING: peg.ebnf strings tools.test ;
|
||||||
|
|
||||||
GENERIC: <times> ( times -- term' )
|
GENERIC: <times> ( times -- term' )
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
! end of a compilation unit.
|
! end of a compilation unit.
|
||||||
|
|
||||||
USING: kernel accessors peg.ebnf ;
|
USING: kernel accessors peg.ebnf ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.peg-regression
|
||||||
|
|
||||||
TUPLE: pipeline-expr background ;
|
TUPLE: pipeline-expr background ;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USING: accessors compiler compiler.units tools.test math parser
|
USING: accessors compiler compiler.units tools.test math parser
|
||||||
kernel sequences sequences.private classes.mixin generic
|
kernel sequences sequences.private classes.mixin generic
|
||||||
definitions arrays words assocs eval strings ;
|
definitions arrays words assocs eval strings ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine1
|
||||||
|
|
||||||
GENERIC: method-redefine-generic-1 ( a -- b )
|
GENERIC: method-redefine-generic-1 ( a -- b )
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ M: integer method-redefine-generic-1 3 + ;
|
||||||
|
|
||||||
[ 6 ] [ method-redefine-test-1 ] unit-test
|
[ 6 ] [ method-redefine-test-1 ] unit-test
|
||||||
|
|
||||||
[ ] [ "IN: compiler.tests USE: math M: fixnum method-redefine-generic-1 4 + ;" eval( -- ) ] unit-test
|
[ ] [ "IN: compiler.tests.redefine1 USE: math M: fixnum method-redefine-generic-1 4 + ;" eval( -- ) ] unit-test
|
||||||
|
|
||||||
[ 7 ] [ method-redefine-test-1 ] unit-test
|
[ 7 ] [ method-redefine-test-1 ] unit-test
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ M: integer method-redefine-generic-2 3 + ;
|
||||||
|
|
||||||
[ 6 ] [ method-redefine-test-2 ] unit-test
|
[ 6 ] [ method-redefine-test-2 ] unit-test
|
||||||
|
|
||||||
[ ] [ "IN: compiler.tests USE: kernel USE: math M: fixnum method-redefine-generic-2 4 + ; USE: strings M: string method-redefine-generic-2 drop f ;" eval( -- ) ] unit-test
|
[ ] [ "IN: compiler.tests.redefine1 USE: kernel USE: math M: fixnum method-redefine-generic-2 4 + ; USE: strings M: string method-redefine-generic-2 drop f ;" eval( -- ) ] unit-test
|
||||||
|
|
||||||
[ 7 ] [ method-redefine-test-2 ] unit-test
|
[ 7 ] [ method-redefine-test-2 ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel ;
|
kernel ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine10
|
||||||
|
|
||||||
! Mixin redefinition did not recompile all necessary words.
|
! Mixin redefinition did not recompile all necessary words.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel classes.mixin arrays ;
|
kernel classes.mixin arrays ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine11
|
||||||
|
|
||||||
! Mixin redefinition did not recompile all necessary words.
|
! Mixin redefinition did not recompile all necessary words.
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine2
|
||||||
USING: compiler compiler.units tools.test math parser kernel
|
USING: compiler compiler.units tools.test math parser kernel
|
||||||
sequences sequences.private classes.mixin generic definitions
|
sequences sequences.private classes.mixin generic definitions
|
||||||
arrays words assocs eval words.symbol ;
|
arrays words assocs eval words.symbol ;
|
||||||
|
|
||||||
DEFER: redefine2-test
|
DEFER: redefine2-test
|
||||||
|
|
||||||
[ ] [ "USE: sequences USE: kernel IN: compiler.tests TUPLE: redefine2-test ; M: redefine2-test nth 2drop 3 ; INSTANCE: redefine2-test sequence" eval( -- ) ] unit-test
|
[ ] [ "USE: sequences USE: kernel IN: compiler.tests.redefine2 TUPLE: redefine2-test ; M: redefine2-test nth 2drop 3 ; INSTANCE: redefine2-test sequence" eval( -- ) ] unit-test
|
||||||
|
|
||||||
[ t ] [ \ redefine2-test symbol? ] unit-test
|
[ t ] [ \ redefine2-test symbol? ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine3
|
||||||
USING: accessors compiler compiler.units tools.test math parser
|
USING: accessors compiler compiler.units tools.test math parser
|
||||||
kernel sequences sequences.private classes.mixin generic
|
kernel sequences sequences.private classes.mixin generic
|
||||||
definitions arrays words assocs eval ;
|
definitions arrays words assocs eval ;
|
||||||
|
@ -18,7 +18,7 @@ M: empty-mixin sheeple drop "wake up" ;
|
||||||
[ t ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
|
[ t ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
|
||||||
[ f ] [ empty-mixin \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
|
[ f ] [ empty-mixin \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
|
||||||
|
|
||||||
[ ] [ "IN: compiler.tests USE: arrays INSTANCE: array empty-mixin" eval( -- ) ] unit-test
|
[ ] [ "IN: compiler.tests.redefine3 USE: arrays INSTANCE: array empty-mixin" eval( -- ) ] unit-test
|
||||||
|
|
||||||
[ "wake up" ] [ sheeple-test ] unit-test
|
[ "wake up" ] [ sheeple-test ] unit-test
|
||||||
[ f ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
|
[ f ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine4
|
||||||
USING: io.streams.string kernel tools.test eval ;
|
USING: io.streams.string kernel tools.test eval ;
|
||||||
|
|
||||||
: declaration-test-1 ( -- a ) 3 ; flushable
|
: declaration-test-1 ( -- a ) 3 ; flushable
|
||||||
|
@ -7,6 +7,6 @@ USING: io.streams.string kernel tools.test eval ;
|
||||||
|
|
||||||
[ "" ] [ [ declaration-test ] with-string-writer ] unit-test
|
[ "" ] [ [ declaration-test ] with-string-writer ] unit-test
|
||||||
|
|
||||||
[ ] [ "IN: compiler.tests USE: io : declaration-test-1 ( -- a ) \"X\" write f ;" eval( -- ) ] unit-test
|
[ ] [ "IN: compiler.tests.redefine4 USE: io : declaration-test-1 ( -- a ) \"X\" write f ;" eval( -- ) ] unit-test
|
||||||
|
|
||||||
[ "X" ] [ [ declaration-test ] with-string-writer ] unit-test
|
[ "X" ] [ [ declaration-test ] with-string-writer ] unit-test
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel ;
|
kernel ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine5
|
||||||
|
|
||||||
! Regression: if dispatch was eliminated but method was not inlined,
|
! Regression: if dispatch was eliminated but method was not inlined,
|
||||||
! compiled usage information was not recorded.
|
! compiled usage information was not recorded.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel ;
|
kernel ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine6
|
||||||
|
|
||||||
! Mixin redefinition did not recompile all necessary words.
|
! Mixin redefinition did not recompile all necessary words.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel ;
|
kernel ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine7
|
||||||
|
|
||||||
! Mixin redefinition did not recompile all necessary words.
|
! Mixin redefinition did not recompile all necessary words.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel ;
|
kernel ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine8
|
||||||
|
|
||||||
! Mixin redefinition did not recompile all necessary words.
|
! Mixin redefinition did not recompile all necessary words.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: eval tools.test compiler.units vocabs multiline words
|
USING: eval tools.test compiler.units vocabs multiline words
|
||||||
kernel generic.math ;
|
kernel generic.math ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.redefine9
|
||||||
|
|
||||||
! Mixin redefinition did not recompile all necessary words.
|
! Mixin redefinition did not recompile all necessary words.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.reload
|
||||||
USE: vocabs.loader
|
USE: vocabs.loader
|
||||||
|
|
||||||
! "parser" reload
|
! "parser" reload
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USING: compiler compiler.units tools.test kernel kernel.private
|
USING: compiler compiler.units tools.test kernel kernel.private
|
||||||
sequences.private math.private math combinators strings alien
|
sequences.private math.private math combinators strings alien
|
||||||
arrays memory vocabs parser eval ;
|
arrays memory vocabs parser eval ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.simple
|
||||||
|
|
||||||
! Test empty word
|
! Test empty word
|
||||||
[ ] [ [ ] compile-call ] unit-test
|
[ ] [ [ ] compile-call ] unit-test
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: math.private kernel combinators accessors arrays
|
USING: math.private kernel combinators accessors arrays
|
||||||
generalizations tools.test ;
|
generalizations tools.test ;
|
||||||
IN: compiler.tests
|
IN: compiler.tests.spilling
|
||||||
|
|
||||||
: float-spill-bug ( a -- b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b )
|
: float-spill-bug ( a -- b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.stack-trace
|
||||||
USING: compiler tools.test namespaces sequences
|
USING: compiler tools.test namespaces sequences
|
||||||
kernel.private kernel math continuations continuations.private
|
kernel.private kernel math continuations continuations.private
|
||||||
words splitting grouping sorting accessors ;
|
words splitting grouping sorting accessors ;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
IN: compiler.tests
|
IN: compiler.tests.tuples
|
||||||
USING: kernel tools.test compiler.units compiler ;
|
USING: kernel tools.test compiler.units compiler ;
|
||||||
|
|
||||||
TUPLE: color red green blue ;
|
TUPLE: color red green blue ;
|
||||||
|
|
|
@ -62,6 +62,8 @@ SYMBOL: max-stack-items
|
||||||
|
|
||||||
SYMBOL: error-summary?
|
SYMBOL: error-summary?
|
||||||
|
|
||||||
|
t error-summary? set-global
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: title. ( string -- )
|
: title. ( string -- )
|
||||||
|
|
|
@ -46,8 +46,8 @@ CONSTANT: homo-sapiens
|
||||||
}
|
}
|
||||||
|
|
||||||
: make-cumulative ( freq -- chars floats )
|
: make-cumulative ( freq -- chars floats )
|
||||||
dup keys >byte-array
|
[ keys >byte-array ]
|
||||||
swap values >double-array unclip [ + ] accumulate swap suffix ;
|
[ values >double-array ] bi unclip [ + ] accumulate swap suffix ;
|
||||||
|
|
||||||
:: select-random ( seed chars floats -- seed elt )
|
:: select-random ( seed chars floats -- seed elt )
|
||||||
floats seed random -rot
|
floats seed random -rot
|
||||||
|
@ -55,7 +55,7 @@ CONSTANT: homo-sapiens
|
||||||
chars nth-unsafe ; inline
|
chars nth-unsafe ; inline
|
||||||
|
|
||||||
: make-random-fasta ( seed len chars floats -- seed )
|
: make-random-fasta ( seed len chars floats -- seed )
|
||||||
[ rot drop select-random ] 2curry B{ } map-as print ; inline
|
[ rot drop select-random ] 2curry "" map-as print ; inline
|
||||||
|
|
||||||
: write-description ( desc id -- )
|
: write-description ( desc id -- )
|
||||||
">" write write bl print ; inline
|
">" write write bl print ; inline
|
||||||
|
@ -71,7 +71,7 @@ CONSTANT: homo-sapiens
|
||||||
|
|
||||||
:: make-repeat-fasta ( k len alu -- k' )
|
:: make-repeat-fasta ( k len alu -- k' )
|
||||||
[let | kn [ alu length ] |
|
[let | kn [ alu length ] |
|
||||||
len [ k + kn mod alu nth-unsafe ] B{ } map-as print
|
len [ k + kn mod alu nth-unsafe ] "" map-as print
|
||||||
k len +
|
k len +
|
||||||
] ; inline
|
] ; inline
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: arrays morse strings tools.test ;
|
USING: arrays morse strings tools.test ;
|
||||||
IN: morse.tests
|
IN: morse.tests
|
||||||
|
|
||||||
[ CHAR: ? ] [ CHAR: \\ ch>morse ] unit-test
|
[ "?" ] [ CHAR: \\ ch>morse ] unit-test
|
||||||
[ "..." ] [ CHAR: s ch>morse ] unit-test
|
[ "..." ] [ CHAR: s ch>morse ] unit-test
|
||||||
[ CHAR: s ] [ "..." morse>ch ] unit-test
|
[ CHAR: s ] [ "..." morse>ch ] unit-test
|
||||||
[ CHAR: \s ] [ "..--..--.." morse>ch ] unit-test
|
[ CHAR: \s ] [ "..--..--.." morse>ch ] unit-test
|
||||||
|
@ -41,3 +41,4 @@ IN: morse.tests
|
||||||
MORSE] ] unit-test
|
MORSE] ] unit-test
|
||||||
! [ ] [ "sos" 0.075 play-as-morse* ] unit-test
|
! [ ] [ "sos" 0.075 play-as-morse* ] unit-test
|
||||||
! [ ] [ "Factor rocks!" play-as-morse ] unit-test
|
! [ ] [ "Factor rocks!" play-as-morse ] unit-test
|
||||||
|
! [ ] [ "\n" play-as-morse ] unit-test
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
USING: accessors ascii assocs biassocs combinators hashtables kernel lists literals math namespaces make multiline openal parser sequences splitting strings synth synth.buffers ;
|
USING: accessors ascii assocs biassocs combinators hashtables kernel lists literals math namespaces make multiline openal parser sequences splitting strings synth synth.buffers ;
|
||||||
IN: morse
|
IN: morse
|
||||||
|
|
||||||
|
ERROR: no-morse-code ch ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
CONSTANT: dot-char CHAR: .
|
CONSTANT: dot-char CHAR: .
|
||||||
CONSTANT: dash-char CHAR: -
|
CONSTANT: dash-char CHAR: -
|
||||||
CONSTANT: char-gap-char CHAR: \s
|
CONSTANT: char-gap-char CHAR: \s
|
||||||
CONSTANT: word-gap-char CHAR: /
|
CONSTANT: word-gap-char CHAR: /
|
||||||
CONSTANT: unknown-char CHAR: ?
|
CONSTANT: unknown-char "?"
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
@ -74,10 +76,10 @@ CONSTANT: morse-code-table $[
|
||||||
]
|
]
|
||||||
|
|
||||||
: ch>morse ( ch -- morse )
|
: ch>morse ( ch -- morse )
|
||||||
ch>lower morse-code-table at [ unknown-char ] unless* ;
|
ch>lower morse-code-table at unknown-char or ;
|
||||||
|
|
||||||
: morse>ch ( str -- ch )
|
: morse>ch ( str -- ch )
|
||||||
morse-code-table value-at [ char-gap-char ] unless* ;
|
morse-code-table value-at char-gap-char or ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
|
@ -148,12 +150,13 @@ CONSTANT: beep-freq 880
|
||||||
source get source-play
|
source get source-play
|
||||||
] with-scope ; inline
|
] with-scope ; inline
|
||||||
|
|
||||||
: play-char ( ch -- )
|
: play-char ( string -- )
|
||||||
[ intra-char-gap ] [
|
[ intra-char-gap ] [
|
||||||
{
|
{
|
||||||
{ dot-char [ dot ] }
|
{ dot-char [ dot ] }
|
||||||
{ dash-char [ dash ] }
|
{ dash-char [ dash ] }
|
||||||
{ word-gap-char [ intra-char-gap ] }
|
{ word-gap-char [ intra-char-gap ] }
|
||||||
|
[ drop intra-char-gap ]
|
||||||
} case
|
} case
|
||||||
] interleave ;
|
] interleave ;
|
||||||
|
|
||||||
|
|
162
vm/code_gc.c
162
vm/code_gc.c
|
@ -1,5 +1,10 @@
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
||||||
|
static void clear_free_list(F_HEAP *heap)
|
||||||
|
{
|
||||||
|
memset(&heap->free,0,sizeof(F_HEAP_FREE_LIST));
|
||||||
|
}
|
||||||
|
|
||||||
/* This malloc-style heap code is reasonably generic. Maybe in the future, it
|
/* This malloc-style heap code is reasonably generic. Maybe in the future, it
|
||||||
will be used for the data heap too, if we ever get incremental
|
will be used for the data heap too, if we ever get incremental
|
||||||
mark/sweep/compact GC. */
|
mark/sweep/compact GC. */
|
||||||
|
@ -8,17 +13,23 @@ void new_heap(F_HEAP *heap, CELL size)
|
||||||
heap->segment = alloc_segment(align_page(size));
|
heap->segment = alloc_segment(align_page(size));
|
||||||
if(!heap->segment)
|
if(!heap->segment)
|
||||||
fatal_error("Out of memory in new_heap",size);
|
fatal_error("Out of memory in new_heap",size);
|
||||||
heap->free_list = NULL;
|
|
||||||
|
clear_free_list(heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is no previous block, next_free becomes the head of the free list,
|
void add_to_free_list(F_HEAP *heap, F_FREE_BLOCK *block)
|
||||||
else its linked in */
|
|
||||||
INLINE void update_free_list(F_HEAP *heap, F_FREE_BLOCK *prev, F_FREE_BLOCK *next_free)
|
|
||||||
{
|
{
|
||||||
if(prev)
|
if(block->block.size < FREE_LIST_COUNT * BLOCK_SIZE_INCREMENT)
|
||||||
prev->next_free = next_free;
|
{
|
||||||
|
int index = block->block.size / BLOCK_SIZE_INCREMENT;
|
||||||
|
block->next_free = heap->free.small[index];
|
||||||
|
heap->free.small[index] = block;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
heap->free_list = next_free;
|
{
|
||||||
|
block->next_free = heap->free.large;
|
||||||
|
heap->free.large = block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called after reading the code heap from the image file, and after code GC.
|
/* Called after reading the code heap from the image file, and after code GC.
|
||||||
|
@ -28,7 +39,11 @@ compiling.limit. */
|
||||||
void build_free_list(F_HEAP *heap, CELL size)
|
void build_free_list(F_HEAP *heap, CELL size)
|
||||||
{
|
{
|
||||||
F_BLOCK *prev = NULL;
|
F_BLOCK *prev = NULL;
|
||||||
F_FREE_BLOCK *prev_free = NULL;
|
|
||||||
|
clear_free_list(heap);
|
||||||
|
|
||||||
|
size = (size + BLOCK_SIZE_INCREMENT - 1) & ~(BLOCK_SIZE_INCREMENT - 1);
|
||||||
|
|
||||||
F_BLOCK *scan = first_block(heap);
|
F_BLOCK *scan = first_block(heap);
|
||||||
F_FREE_BLOCK *end = (F_FREE_BLOCK *)(heap->segment->start + size);
|
F_FREE_BLOCK *end = (F_FREE_BLOCK *)(heap->segment->start + size);
|
||||||
|
|
||||||
|
@ -38,8 +53,7 @@ void build_free_list(F_HEAP *heap, CELL size)
|
||||||
switch(scan->status)
|
switch(scan->status)
|
||||||
{
|
{
|
||||||
case B_FREE:
|
case B_FREE:
|
||||||
update_free_list(heap,prev_free,(F_FREE_BLOCK *)scan);
|
add_to_free_list(heap,(F_FREE_BLOCK *)scan);
|
||||||
prev_free = (F_FREE_BLOCK *)scan;
|
|
||||||
break;
|
break;
|
||||||
case B_ALLOCATED:
|
case B_ALLOCATED:
|
||||||
break;
|
break;
|
||||||
|
@ -58,10 +72,9 @@ void build_free_list(F_HEAP *heap, CELL size)
|
||||||
{
|
{
|
||||||
end->block.status = B_FREE;
|
end->block.status = B_FREE;
|
||||||
end->block.size = heap->segment->end - (CELL)end;
|
end->block.size = heap->segment->end - (CELL)end;
|
||||||
end->next_free = NULL;
|
|
||||||
|
|
||||||
/* add final free block */
|
/* add final free block */
|
||||||
update_free_list(heap,prev_free,end);
|
add_to_free_list(heap,end);
|
||||||
}
|
}
|
||||||
/* This branch is taken if the newly loaded image fits exactly, or
|
/* This branch is taken if the newly loaded image fits exactly, or
|
||||||
after code GC */
|
after code GC */
|
||||||
|
@ -70,62 +83,87 @@ void build_free_list(F_HEAP *heap, CELL size)
|
||||||
/* even if there's no room at the end of the heap for a new
|
/* even if there's no room at the end of the heap for a new
|
||||||
free block, we might have to jigger it up by a few bytes in
|
free block, we might have to jigger it up by a few bytes in
|
||||||
case prev + prev->size */
|
case prev + prev->size */
|
||||||
if(prev)
|
if(prev) prev->size = heap->segment->end - (CELL)prev;
|
||||||
prev->size = heap->segment->end - (CELL)prev;
|
|
||||||
|
|
||||||
/* this is the last free block */
|
|
||||||
update_free_list(heap,prev_free,NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void assert_free_block(F_FREE_BLOCK *block)
|
||||||
|
{
|
||||||
|
if(block->block.status != B_FREE)
|
||||||
|
critical_error("Invalid block in free list",(CELL)block);
|
||||||
|
}
|
||||||
|
|
||||||
|
F_FREE_BLOCK *find_free_block(F_HEAP *heap, CELL size)
|
||||||
|
{
|
||||||
|
CELL attempt = size;
|
||||||
|
|
||||||
|
while(attempt < FREE_LIST_COUNT * BLOCK_SIZE_INCREMENT)
|
||||||
|
{
|
||||||
|
int index = attempt / BLOCK_SIZE_INCREMENT;
|
||||||
|
F_FREE_BLOCK *block = heap->free.small[index];
|
||||||
|
if(block)
|
||||||
|
{
|
||||||
|
assert_free_block(block);
|
||||||
|
heap->free.small[index] = block->next_free;
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
attempt *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
F_FREE_BLOCK *prev = NULL;
|
||||||
|
F_FREE_BLOCK *block = heap->free.large;
|
||||||
|
|
||||||
|
while(block)
|
||||||
|
{
|
||||||
|
assert_free_block(block);
|
||||||
|
if(block->block.size >= size)
|
||||||
|
{
|
||||||
|
if(prev)
|
||||||
|
prev->next_free = block->next_free;
|
||||||
|
else
|
||||||
|
heap->free.large = block->next_free;
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = block;
|
||||||
|
block = block->next_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
F_FREE_BLOCK *split_free_block(F_HEAP *heap, F_FREE_BLOCK *block, CELL size)
|
||||||
|
{
|
||||||
|
if(block->block.size != size )
|
||||||
|
{
|
||||||
|
/* split the block in two */
|
||||||
|
F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)block + size);
|
||||||
|
split->block.status = B_FREE;
|
||||||
|
split->block.size = block->block.size - size;
|
||||||
|
split->next_free = block->next_free;
|
||||||
|
block->block.size = size;
|
||||||
|
add_to_free_list(heap,split);
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a block of memory from the mark and sweep GC heap */
|
/* Allocate a block of memory from the mark and sweep GC heap */
|
||||||
F_BLOCK *heap_allot(F_HEAP *heap, CELL size)
|
F_BLOCK *heap_allot(F_HEAP *heap, CELL size)
|
||||||
{
|
{
|
||||||
F_FREE_BLOCK *prev = NULL;
|
size = (size + BLOCK_SIZE_INCREMENT - 1) & ~(BLOCK_SIZE_INCREMENT - 1);
|
||||||
F_FREE_BLOCK *scan = heap->free_list;
|
|
||||||
|
|
||||||
size = (size + 31) & ~31;
|
F_FREE_BLOCK *block = find_free_block(heap,size);
|
||||||
|
if(block)
|
||||||
while(scan)
|
|
||||||
{
|
{
|
||||||
if(scan->block.status != B_FREE)
|
block = split_free_block(heap,block,size);
|
||||||
critical_error("Invalid block in free list",(CELL)scan);
|
|
||||||
|
|
||||||
if(scan->block.size < size)
|
block->block.status = B_ALLOCATED;
|
||||||
{
|
return &block->block;
|
||||||
prev = scan;
|
|
||||||
scan = scan->next_free;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we found a candidate block */
|
|
||||||
F_FREE_BLOCK *next_free;
|
|
||||||
|
|
||||||
if(scan->block.size - size <= sizeof(F_BLOCK) * 2)
|
|
||||||
{
|
|
||||||
/* too small to be split */
|
|
||||||
next_free = scan->next_free;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* split the block in two */
|
|
||||||
F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)scan + size);
|
|
||||||
split->block.status = B_FREE;
|
|
||||||
split->block.size = scan->block.size - size;
|
|
||||||
split->next_free = scan->next_free;
|
|
||||||
scan->block.size = size;
|
|
||||||
next_free = split;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update the free list */
|
|
||||||
update_free_list(heap,prev,next_free);
|
|
||||||
|
|
||||||
/* this is our new block */
|
|
||||||
scan->block.status = B_ALLOCATED;
|
|
||||||
return &scan->block;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +200,10 @@ void unmark_marked(F_HEAP *heap)
|
||||||
|
|
||||||
/* After code GC, all referenced code blocks have status set to B_MARKED, so any
|
/* After code GC, all referenced code blocks have status set to B_MARKED, so any
|
||||||
which are allocated and not marked can be reclaimed. */
|
which are allocated and not marked can be reclaimed. */
|
||||||
void free_unmarked(F_HEAP *heap)
|
void free_unmarked(F_HEAP *heap, HEAP_ITERATOR iter)
|
||||||
{
|
{
|
||||||
|
clear_free_list(heap);
|
||||||
|
|
||||||
F_BLOCK *prev = NULL;
|
F_BLOCK *prev = NULL;
|
||||||
F_BLOCK *scan = first_block(heap);
|
F_BLOCK *scan = first_block(heap);
|
||||||
|
|
||||||
|
@ -183,10 +223,15 @@ void free_unmarked(F_HEAP *heap)
|
||||||
case B_FREE:
|
case B_FREE:
|
||||||
if(prev && prev->status == B_FREE)
|
if(prev && prev->status == B_FREE)
|
||||||
prev->size += scan->size;
|
prev->size += scan->size;
|
||||||
|
else
|
||||||
|
prev = scan;
|
||||||
break;
|
break;
|
||||||
case B_MARKED:
|
case B_MARKED:
|
||||||
|
if(prev && prev->status == B_FREE)
|
||||||
|
add_to_free_list(heap,(F_FREE_BLOCK *)prev);
|
||||||
scan->status = B_ALLOCATED;
|
scan->status = B_ALLOCATED;
|
||||||
prev = scan;
|
prev = scan;
|
||||||
|
iter(scan);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
critical_error("Invalid scan->status",(CELL)scan);
|
critical_error("Invalid scan->status",(CELL)scan);
|
||||||
|
@ -195,7 +240,8 @@ void free_unmarked(F_HEAP *heap)
|
||||||
scan = next_block(heap,scan);
|
scan = next_block(heap,scan);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_free_list(heap,heap->segment->size);
|
if(prev && prev->status == B_FREE)
|
||||||
|
add_to_free_list(heap,(F_FREE_BLOCK *)prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute total sum of sizes of free blocks, and size of largest free block */
|
/* Compute total sum of sizes of free blocks, and size of largest free block */
|
||||||
|
|
14
vm/code_gc.h
14
vm/code_gc.h
|
@ -1,14 +1,24 @@
|
||||||
|
#define FREE_LIST_COUNT 16
|
||||||
|
#define BLOCK_SIZE_INCREMENT 32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
F_FREE_BLOCK *small[FREE_LIST_COUNT];
|
||||||
|
F_FREE_BLOCK *large;
|
||||||
|
} F_HEAP_FREE_LIST;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
F_SEGMENT *segment;
|
F_SEGMENT *segment;
|
||||||
F_FREE_BLOCK *free_list;
|
F_HEAP_FREE_LIST free;
|
||||||
} F_HEAP;
|
} F_HEAP;
|
||||||
|
|
||||||
|
typedef void (*HEAP_ITERATOR)(F_BLOCK *compiled);
|
||||||
|
|
||||||
void new_heap(F_HEAP *heap, CELL size);
|
void new_heap(F_HEAP *heap, CELL size);
|
||||||
void build_free_list(F_HEAP *heap, CELL size);
|
void build_free_list(F_HEAP *heap, CELL size);
|
||||||
F_BLOCK *heap_allot(F_HEAP *heap, CELL size);
|
F_BLOCK *heap_allot(F_HEAP *heap, CELL size);
|
||||||
void mark_block(F_BLOCK *block);
|
void mark_block(F_BLOCK *block);
|
||||||
void unmark_marked(F_HEAP *heap);
|
void unmark_marked(F_HEAP *heap);
|
||||||
void free_unmarked(F_HEAP *heap);
|
void free_unmarked(F_HEAP *heap, HEAP_ITERATOR iter);
|
||||||
void heap_usage(F_HEAP *heap, CELL *used, CELL *total_free, CELL *max_free);
|
void heap_usage(F_HEAP *heap, CELL *used, CELL *total_free, CELL *max_free);
|
||||||
CELL heap_size(F_HEAP *heap);
|
CELL heap_size(F_HEAP *heap);
|
||||||
CELL compute_heap_forwarding(F_HEAP *heap);
|
CELL compute_heap_forwarding(F_HEAP *heap);
|
||||||
|
|
|
@ -416,13 +416,6 @@ void end_gc(CELL gc_elapsed)
|
||||||
reset_generations(NURSERY,collecting_gen);
|
reset_generations(NURSERY,collecting_gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(collecting_gen == TENURED)
|
|
||||||
{
|
|
||||||
/* now that all reachable code blocks have been marked,
|
|
||||||
deallocate the rest */
|
|
||||||
free_unmarked(&code_heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
collecting_aging_again = false;
|
collecting_aging_again = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +484,7 @@ void garbage_collection(CELL gen,
|
||||||
code_heap_scans++;
|
code_heap_scans++;
|
||||||
|
|
||||||
if(collecting_gen == TENURED)
|
if(collecting_gen == TENURED)
|
||||||
update_code_heap_roots();
|
free_unmarked(&code_heap,(HEAP_ITERATOR)update_literal_references);
|
||||||
else
|
else
|
||||||
copy_code_heap_roots();
|
copy_code_heap_roots();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue