Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/compiler/options/options.sml
ViewVC logotype

View of /branches/vis15/src/compiler/options/options.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3417 - (download) (annotate)
Thu Nov 12 23:41:06 2015 UTC (3 years, 11 months ago) by jhr
File size: 8762 byte(s)
debugging merge
(* options.sml
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2015 The University of Chicago
 * All rights reserved.
 *)

structure Options : sig

  (* raised if parsing command-line args hits an error (e.g., missing option, syntax, ...).
   * The string is an error message.
   *)
    exception Usage of string

  (* parse the command-line args *)
    val parseCmdLine : string list -> {
            help : bool option,		(* "-h" and "--help" ==> SOME false; "-H" ==> SOME true. *)
            version : bool,		(* "--version" specified? *)
            defs : string list,		(* input-variable definitions *)
            target : Target.desc,	(* collected infromation about the target *)
            file : string		(* source file *)
          }

  (* return a usage message.  The boolean controls whether all options should be
   * included (true ==> long; false ==> short).
   *)
    val usage : string * bool -> string

  end = struct

    structure G = GetOpt
    structure P = OS.Path

    exception Usage of string

  (* option flags that are set by getOpt *)
    val helpFlg = ref(NONE : bool option)	(* SOME false -- short help; SOME true -- long help *)
    val longHelp = ref false
    val versionFlg = ref false
    val debugFlg = ref false
    val doubleFlg = ref false
    val outputOpt : string option ref = ref NONE
    val standaloneFlg = ref false
    val snapshotFlg = ref false
    val prefix : string option ref = ref NONE
    val target = ref Target.SEQUENTIAL
    val bspFlg = ref false

  (* package a boolean control as a GetOpt option descriptor (NoArg) *)
  (** NOTE: this function will be part of the Controls structure as of 110.80 *)
    fun mkOptionFlag {ctl, short, long} = {
	    short = short,
	    long = (case long of NONE => [] | SOME opt => [opt]),
	    desc = G.NoArg(Controls.set' (ctl, true)),
	    help = #help(Controls.info ctl)
	  }

  (** NOTE: this function can use Controls.mkOptionFlag as of 110.80 *)
    fun mkOpt ctl = let
	  val name = if Controls.get ctl
		then "disable-" ^ Controls.name ctl
		else "enable-" ^ Controls.name ctl
	  in
	    mkOptionFlag {ctl = ctl, short = "", long = SOME name}
	  end

  (* create the target option descriptor. *)
    local
      val desc = if Paths.cudaEnabled then ["  cuda      -- generate CUDA code"] else []
      val desc = if Paths.clEnabled then  "  opencl    -- generate OpenCL code" :: desc else desc
      val desc = "  parallel   -- generate parallel code" :: desc
      val desc = "  sequential -- generate sequential code (default)" :: desc
      val desc = "specify the target platform:" :: desc
      fun parseTargetOpt "c" = (target := Target.SEQUENTIAL)
	| parseTargetOpt "sequential" = (target := Target.SEQUENTIAL)
        | parseTargetOpt "parallel" = (target := Target.PARALLEL)
        | parseTargetOpt "pthread" = (target := Target.PARALLEL)
        | parseTargetOpt "cl" = if Paths.clEnabled
            then (target := Target.OPENCL)
            else raise Usage "cl target not supported by this version"
        | parseTargetOpt "opencl" = if Paths.clEnabled
            then (target := Target.OPENCL)
            else raise Usage "cl target not supported by this version"
        | parseTargetOpt "cuda" = if Paths.cudaEnabled
            then (target := Target.CUDA)
            else raise Usage "cuda target not supported by this version"
        | parseTargetOpt opt = raise Usage(concat["unrecognized target \"", opt, "\""])
    in
    val targetOptDesc = {
            short = "",
            long = ["target"],
            desc = G.ReqArg(parseTargetOpt, "target"),
            help = String.concatWith "\n" desc
          }
    end

    fun setFlag (flg, value) = G.NoArg(fn () => (flg := value))

  (* the short list of options, which does not include the compiler controls *)
    val optionList = [
            { short = "h", long = ["help"],
              desc = setFlag (helpFlg, SOME false),
              help = "print command-line options"
            },
            { short = "H", long = [],
              desc = setFlag (helpFlg, SOME true),
              help = "print all command-line options (including compiler controls)"
            },
            { short = "", long = ["version"],
              desc = setFlag (versionFlg, true),
              help = "show the compiler version"
            },
            { short = "", long = ["exec"],
              desc = setFlag (standaloneFlg, true),
              help = "generate a standalone executable"
            },
            { short = "o", long = ["output"],
              desc = G.ReqArg(fn s => outputOpt := SOME s, "file"),
              help = "specify the executable file name"
            },
            { short = "", long = ["namespace"],
              desc = G.ReqArg(fn s => prefix := SOME s, "prefix"),
              help = "specify namespace prefix for generated code"
            },
            { short = "", long = ["snapshot"],
              desc = setFlag (snapshotFlg, true),
              help = "generate code to get a snapshot of strand states"
            },
            { short = "g", long = ["debug"],
              desc = setFlag (debugFlg, true),
              help = "enable debugging information in executable"
            },
            { short = "", long = ["double"],
              desc = setFlag (doubleFlg, true),
              help = "use double-precision floats for reals"
            },
            mkOpt Ctl.enableLog,
	    mkOpt Ctl.collectStats,
            targetOptDesc
          ]

  (* create the list of options that control compiler internals *)
    val ctlOptions = 
	  { short = "", long = ["force-bsp"],
              desc = setFlag (bspFlg, true),
              help = "execute strands in BSP mode"
            } ::
	  (List.map mkOpt [
	      Ctl.dumpAST, Ctl.dumpSimple, Ctl.dumpHighIL, Ctl.dumpMidIl, Ctl.dumpLowIL, Ctl.dumpTreeIL, 
	      Ctl.checkAST, Ctl.checkSimple, Ctl.checkHighIL, Ctl.checkMidIl, Ctl.checkLowIL, Ctl.checkTreeIL
	    ])


    fun parseCmdLine args = let
        (* first we filter out any variable definitions *)
          val (defs, rest) = List.partition CmdLineConstants.isCmdLineConst args
          val (opts, files) = G.getOpt {
                  argOrder = G.RequireOrder,
                  options = optionList @ ctlOptions,
                  errFn = fn s => raise Usage s
                } args
        (* figure out filename pieces *)
          val srcFile = if isSome(!helpFlg) orelse !versionFlg
		then ""
		else (case files
		   of [] => raise Usage "missing file argument"
		    | [f] => f
		    | _ => raise Usage "too many files"
		  (* end case *))
          val (outDir, outBase) = (case !outputOpt
                 of NONE => let
                      val {dir, file} = P.splitDirFile srcFile
                      in
                        case P.splitBaseExt file
                         of {base, ext=SOME "diderot"} => (dir, base)
                          | _ => (dir, file)
                        (* end case *)
                      end
                  | SOME outFile => let
                      val {dir, file} = P.splitDirFile outFile
                      in
                        if !standaloneFlg
                          then (dir, file)
                          else (case P.splitBaseExt file
                             of {base, ext=SOME "o"} => (dir, base)
                              | {base, ext=SOME "obj"} => (dir, base)
                              | _ => (dir, file)
                            (* end case *))
                      end
                (* end case *))
        (* figure out target details *)
          val targetDesc : Target.desc = {
		  version = Version.message,
                  srcFile = srcFile,
                  outDir = outDir,
                  outBase = outBase,
                  exec = !standaloneFlg,
                  snapshot = not(!standaloneFlg) andalso !snapshotFlg,
                  target = !target,
                  namespace = Option.getOpt(!prefix, "Diderot")^"_",
                  double = !doubleFlg,
                  longint = false,              (* currently always false *)
                  debug = !debugFlg,
                  bsp = !bspFlg
                }
          in {
            help = !helpFlg,
            version = !versionFlg,
            defs = defs,
            target = targetDesc,
            file = srcFile
          } end

    fun usage (cmd, long) = G.usageInfo {
            header = concat[
                "usage: ", cmd, " [options] file.diderot\n",
                "  Version: ", Version.message, "\n",
                "  Options:"
              ],
            options = optionList @ ctlOptions
          }

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0