Skip to content

Commit cac5f18

Browse files
Add vocabs (#17)
Add support for - circular - infix - qw - pair-rocket - sequences.extras - sequences.repeating We use a small patch to avoid bringing in help / help.markup and their dependencies.
1 parent 13dd82e commit cac5f18

6 files changed

Lines changed: 166 additions & 4 deletions

File tree

Dockerfile

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ RUN git clone https://github.com/factor/factor.git && \
1919
git checkout ${FACTOR_COMMIT}
2020
WORKDIR /opt/factor
2121

22+
# Patch extra/shuffle to drop the dependency on help / help.markup (for $shuffle docs)
23+
COPY patches/shuffle-drop-help.patch /tmp/shuffle-drop-help.patch
24+
RUN git apply /tmp/shuffle-drop-help.patch
25+
2226
# Bootstrap a headless image: drop the GUI (ui, ui.tools), the in-image help
2327
# system (help, handbook), and the dev-tools component (tools) from the bootstrap
2428
# component set.
@@ -29,14 +33,22 @@ RUN sed -i 's#-i="\$BOOT_IMAGE"#-i="$BOOT_IMAGE" -exclude="'"${FACTOR_EXCLUDE}"'
2933
RUN ./build.sh net-bootstrap
3034

3135
# Precompile tools.test AND the common exercise vocabs into factor.image, then re-save it.
32-
RUN ./factor -e='USING: accessors arrays ascii assocs bit-arrays calendar calendar.english combinators combinators.short-circuit command-line concurrency.combinators concurrency.locks continuations debugger deques destructors disjoint-sets dlists formatting fry generic grouping hash-sets hashtables heaps io io.encodings.utf8 io.files io.streams.string kernel lexer locals macros make math math.bitwise math.combinatorics math.constants math.functions math.order math.parser math.primes math.statistics namespaces prettyprint.config quotations random random.mersenne-twister ranges regexp sequences sets sorting source-files.errors.debugger splitting splitting.monotonic strings system tools.test tr typed unicode vectors vocabs vocabs.loader memory ; save'
36+
RUN ./factor -e='USING: accessors arrays ascii assocs bit-arrays calendar calendar.english circular combinators combinators.short-circuit command-line concurrency.combinators concurrency.locks continuations debugger deques destructors disjoint-sets dlists formatting fry generic grouping hash-sets hashtables heaps infix io io.encodings.utf8 io.files io.streams.string kernel lexer locals macros make math math.bitwise math.combinatorics math.constants math.functions math.order math.parser math.primes math.statistics namespaces pair-rocket prettyprint.config quotations qw random random.mersenne-twister ranges regexp sequences sequences.repeating sets sorting source-files.errors.debugger splitting splitting.monotonic strings system tools.test tr typed unicode vectors vocabs vocabs.loader memory ; save'
3337

3438
# Remove files not needed at runtime
3539
RUN rm -rf .git build vm src misc Factor.app \
3640
factor.image.fresh boot.*.image libfactor.a libfactor-ffi-test.so \
37-
extra GNUmakefile Nmakefile LICENSE.txt README.md \
41+
GNUmakefile Nmakefile LICENSE.txt README.md \
3842
build.sh build.cmd unmaintained
3943

44+
# Keep only the extra/ source that sequences.extras needs to compile on demand:
45+
# itself plus extra/assocs.extras and extra/shuffle.
46+
RUN find extra -mindepth 1 -maxdepth 1 \
47+
! -name sequences ! -name assocs ! -name shuffle \
48+
-exec rm -rf {} + && \
49+
find extra/sequences -mindepth 1 -maxdepth 1 ! -name extras -exec rm -rf {} + && \
50+
find extra/assocs -mindepth 1 -maxdepth 1 ! -name extras -exec rm -rf {} +
51+
4052
# Prune basis subdirs that exercism tests cannot reach, one category per rm so
4153
# each vocab is named exactly once. Source files only — any bytecode already in
4254
# factor.image is unaffected. A few pruned vocabs (bit-arrays, disjoint-sets,
@@ -79,8 +91,8 @@ RUN cd basis && rm -rf \
7991
base16 base24 base32 base36 base45 base58 base62 base64 base85 base91 \
8092
base92 checksums compression crypto hex-strings
8193

82-
# Specialised data structures (bit-arrays, disjoint-sets, heaps, dlists are
83-
# precompiled above, so pruning their source here is safe)
94+
# Specialised data structures (bit-arrays, disjoint-sets, heaps, dlists, circular
95+
# are precompiled above, so pruning their source here is safe)
8496
RUN cd basis && rm -rf \
8597
biassocs bit-arrays bit-sets bit-vectors bitstreams bloom-filters boxes \
8698
circular columns cuckoo-filters disjoint-sets dlists heaps interval-maps \

patches/shuffle-drop-help.patch

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
diff --git a/extra/shuffle/shuffle.factor b/extra/shuffle/shuffle.factor
2+
index da69307ce7..d4c0eab80e 100644
3+
--- a/extra/shuffle/shuffle.factor
4+
+++ b/extra/shuffle/shuffle.factor
5+
@@ -2,8 +2,7 @@
6+
! See https://factorcode.org/license.txt for BSD license.
7+
8+
USING: accessors assocs combinators combinators.short-circuit
9+
-definitions effects effects.parser generalizations help
10+
-help.markup kernel math parser ranges sequences
11+
+definitions effects effects.parser generalizations kernel math parser ranges sequences
12+
sequences.generalizations stack-checker.backend
13+
stack-checker.known-words stack-checker.values words ;
14+
15+
@@ -26,7 +25,6 @@ SYNTAX: SHUFFLE:
16+
scan-new-word scan-effect {
17+
[ [ '[ _ shuffle-effect ] ] keep define-declared ]
18+
[ "shuffle" set-word-prop ]
19+
- [ drop { $shuffle } swap set-word-help ]
20+
} 2cleave ;
21+
22+
PREDICATE: shuffle-word < word
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
USING: accessors command-line continuations debugger io kernel
2+
lexer namespaces sequences source-files.errors.debugger
3+
system tools.test vocabs vocabs.loader ;
4+
IN: exercism-tools
5+
6+
SYNTAX: STOP-HERE
7+
lexer get [ text>> length ] keep line<< ;
8+
9+
SYNTAX: TASK:
10+
lexer get next-line ;
11+
12+
! Label the test that follows with its description. The marker lets the
13+
! wrapper strip this line from captured output and attach it to the next
14+
! test as a name, rather than leaving it in the previous test's output.
15+
: description ( str -- )
16+
"###DESC### " write print ;
17+
18+
! Print one failure block in a stable, parser-friendly form. Bracketed by
19+
! markers so a wrapper can split the stream reliably and avoid Factor's
20+
! noisy callstack output (which is interleaved with subsequent failures).
21+
:: print-failure ( failure -- )
22+
"###FAIL_BEGIN###" print
23+
failure error-location print
24+
failure error>> [ error. ] [ 2drop ] recover
25+
"###FAIL_END###" print
26+
flush ;
27+
28+
: print-failures ( -- )
29+
test-failures get [ print-failure ] each ;
30+
31+
: run-exercism-tests ( -- )
32+
command-line get first
33+
[ require ] [ test ] bi
34+
test-failures get empty?
35+
[ 0 exit ] [ print-failures 1 exit ] if ;
36+
37+
MAIN: run-exercism-tests
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"version": 3,
3+
"status": "pass",
4+
"tests": [
5+
{
6+
"name": "qw builds a sequence of strings",
7+
"status": "pass",
8+
"test_code": "{ { \"apple\" \"orange\" \"lime\" } } [ fruits ] unit-test"
9+
},
10+
{
11+
"name": "infix add sums two numbers",
12+
"status": "pass",
13+
"test_code": "{ 7 } [ 3 4 add ] unit-test"
14+
},
15+
{
16+
"name": "take-while keeps the leading run",
17+
"status": "pass",
18+
"test_code": "{ { 1 2 } } [ { 1 2 3 4 1 } small-prefix ] unit-test"
19+
},
20+
{
21+
"name": "interpolate fills in the name",
22+
"status": "pass",
23+
"test_code": "{ \"Hello, World!\" } [ \"World\" greeting ] unit-test"
24+
},
25+
{
26+
"name": "cycle repeats a sequence to length",
27+
"status": "pass",
28+
"test_code": "{ { 1 2 3 1 2 } } [ { 1 2 3 } 5 padded-cycle ] unit-test"
29+
},
30+
{
31+
"name": "circular indexing wraps around",
32+
"status": "pass",
33+
"test_code": "{ 20 } [ 4 { 10 20 30 } wrap-nth ] unit-test"
34+
},
35+
{
36+
"name": "pair-rocket builds an assoc",
37+
"status": "pass",
38+
"test_code": "{ H{ { \"ada\" 1 } { \"bob\" 2 } } } [ scores ] unit-test"
39+
}
40+
]
41+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
USING: exercism-tools tools.test wishlist-vocabs ;
2+
IN: wishlist-vocabs.tests
3+
4+
"qw builds a sequence of strings" description
5+
{ { "apple" "orange" "lime" } } [ fruits ] unit-test
6+
7+
"infix add sums two numbers" description
8+
{ 7 } [ 3 4 add ] unit-test
9+
10+
"take-while keeps the leading run" description
11+
{ { 1 2 } } [ { 1 2 3 4 1 } small-prefix ] unit-test
12+
13+
"interpolate fills in the name" description
14+
{ "Hello, World!" } [ "World" greeting ] unit-test
15+
16+
"cycle repeats a sequence to length" description
17+
{ { 1 2 3 1 2 } } [ { 1 2 3 } 5 padded-cycle ] unit-test
18+
19+
"circular indexing wraps around" description
20+
{ 20 } [ 4 { 10 20 30 } wrap-nth ] unit-test
21+
22+
"pair-rocket builds an assoc" description
23+
{ H{ { "ada" 1 } { "bob" 2 } } } [ scores ] unit-test
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
USING: arrays circular hashtables infix interpolate kernel math
2+
namespaces pair-rocket qw sequences sequences.extras
3+
sequences.repeating ;
4+
IN: wishlist-vocabs
5+
6+
! qw{ ... } reads a whitespace-separated literal sequence of strings (qw).
7+
: fruits ( -- seq ) qw{ apple orange lime } ;
8+
9+
! Standard infix arithmetic over locals (infix).
10+
INFIX:: add ( x y -- z ) x + y ;
11+
12+
! take-while keeps the leading run satisfying the predicate (sequences.extras);
13+
! it returns a slice, so >array normalizes it for an exact unit-test compare.
14+
: small-prefix ( seq -- arr ) [ 3 < ] take-while >array ;
15+
16+
! ${var} string interpolation, reading from a dynamic variable (interpolate).
17+
: greeting ( name -- str )
18+
[ "name" set "Hello, ${name}!" interpolate>string ] with-scope ;
19+
20+
! cycle repeats a sequence up to a given length (sequences.repeating).
21+
: padded-cycle ( seq n -- arr ) cycle >array ;
22+
23+
! <circular> wraps a sequence so indices read modulo its length (circular).
24+
: wrap-nth ( n seq -- elt ) <circular> nth ;
25+
26+
! => pairs each key with the next value, building assoc literals (pair-rocket).
27+
: scores ( -- assoc ) { "ada" => 1 "bob" => 2 } >hashtable ;

0 commit comments

Comments
 (0)