1 USING: accessors continuations debugger environment eval globs
2 io io.directories io.encodings.utf8 io.launcher io.pathnames
3 io.pipes kernel namespaces sequences sequences.deep shell.parser
8 [ home ] [ first ] if-empty set-current-directory ;
11 drop current-directory get print ;
13 CONSTANT: swords { "cd" "pwd" }
15 GENERIC: expand ( expr -- expr )
19 M: single-quoted-expr expand expr>> ;
21 M: double-quoted-expr expand expr>> ;
23 M: variable-expr expand expr>> os-env ;
25 M: glob-expr expand expr>> glob ;
27 M: factor-expr expand expr>> eval>string ;
31 M: back-quoted-expr expand
32 expr>> expr command>> expansion
33 utf8 [ read-contents ] with-process-reader
36 : expansion ( command -- command ) [ expand ] map flatten ;
38 : run-sword ( basic-expr -- )
39 command>> expansion unclip
40 "shell" lookup-word execute( arguments -- ) ;
42 : run-foreground ( process -- )
43 [ try-process ] [ print-error drop ] recover ;
45 : run-background ( process -- )
48 : run-basic-expr ( basic-expr -- )
50 over command>> expansion >>command
52 over stdout>> >>stdout
54 [ run-background ] [ run-foreground ] if ;
56 : basic-chant ( basic-expr -- )
57 dup command>> first swords member?
58 [ run-sword ] [ run-basic-expr ] if ;
60 : pipeline-chant ( pipeline-chant -- )
61 commands>> run-pipeline drop ;
64 dup basic-expr? [ basic-chant ] [ pipeline-chant ] if ;
67 current-directory get write " $ " write flush ;
72 dup { f "exit" } member? [
76 expr [ chant ] [ "ix: ignoring input" print ] if*
81 prompt readln handle ;