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 process-contents
35 : expansion ( command -- command ) [ expand ] map flatten ;
37 : run-sword ( basic-expr -- )
38 command>> expansion unclip
39 "shell" lookup-word execute( arguments -- ) ;
41 : run-foreground ( process -- )
42 [ try-process ] [ print-error drop ] recover ;
44 : run-background ( process -- )
47 : run-basic-expr ( basic-expr -- )
49 over command>> expansion >>command
51 over stdout>> >>stdout
53 [ run-background ] [ run-foreground ] if ;
55 : basic-chant ( basic-expr -- )
56 dup command>> first swords member?
57 [ run-sword ] [ run-basic-expr ] if ;
59 : pipeline-chant ( pipeline-chant -- )
60 commands>> run-pipeline drop ;
63 dup basic-expr? [ basic-chant ] [ pipeline-chant ] if ;
66 current-directory get write " $ " write flush ;
71 dup { f "exit" } member? [
75 expr [ chant ] [ "ix: ignoring input" print ] if*
80 prompt readln handle ;