(* command.sml
 *
 * Sample code for CMSC 32102 Project-1
 *)

structure Command =
  struct

    datatype prog = Prog of {
	prog : string,
	args : string list,
	input : string option,
	output : string option
      }

    datatype cmd
      = Exit
      | Cmd of (prog list * bool)

  (* return a string representation of a command (for debugging) *)
    fun toString (Exit) = "exit"
      | toString (Cmd(progs, bg)) = let
	  fun p2s (Prog{prog, args, input, output}) = let
	      (* build the text up from right to left *)
		val s = (case output
			 of NONE => []
			  | SOME f => [" > ", f]
			(* end case *))
		val s = (case input
			 of NONE => s
			  | SOME f => " < " :: f :: s
			(* end case *))
		val s = List.foldr (fn (arg, s) => " "::arg::s) s args
		val s = prog::s
		in
		  String.concat s
		end
	  fun cmd2s [] = []
	    | cmd2s [prog] = if bg then [p2s prog, " &"] else [p2s prog]
	    | cmd2s (prog::progs) = p2s prog :: " | " :: cmd2s progs
	  in
	    String.concat(cmd2s progs)
	  end

  end;
