Re: Factor

Factor: the language, the theory, and the practice.


Tuesday, April 2, 2013

#command-line #files

I’ve used Factor to build several common unix programs including copy, cat, fortune, wc, and others.

Today, I wanted to show how to build the mv (“move”) program using the simple file manipulation words available in Factor. If we look at the man page, we can see that its usage is two-fold:

  1. Rename a source file to a destination file
  2. Move source file(s) to a destination directory

We can make a nice usage string to display if the arguments are not correct:

: usage ( -- )
    "Usage: move source ... target" print ;

Moving files into a directory (and displaying the usage if the destination is not a directory):

: move-to-dir ( args -- )
    dup last file-info directory?
    [ unclip-last move-files-into ] [ drop usage ] if ;

If we specify two arguments, we are either moving a single file into a directory, or renaming a file using the move-file word:

: move-to-file ( args -- )
    dup last file-info directory?
    [ move-to-dir ] [ first2 move-file ] if ;

A “main” word checks the number of arguments and performs the appropriate action:

: run-move ( -- )
    command-line get dup length {
        { [ dup 2 > ] [ drop move-to-dir  ] }
        { [ dup 2 = ] [ drop move-to-file ] }
        [ 2drop usage ]
    } cond ;

MAIN: run-move

An improvement that could be made would be producing better error messages when files don’t exist. Something like the errors mv produces:

$ mv src dst
mv: rename src to dst: No such file or directory

The code for this is available on my GitHub.