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 3812 - (download) (annotate)
Wed May 4 13:16:31 2016 UTC (2 years, 10 months ago) by jhr
File size: 9175 byte(s)
  working on 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 : TargetOptions.t,	(* 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
    structure Tgt = TargetOptions

    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 platform = ref Tgt.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" = (platform := Tgt.SEQUENTIAL)
	| parseTargetOpt "sequential" = (platform := Tgt.SEQUENTIAL)
        | parseTargetOpt "parallel" = (platform := Tgt.PARALLEL)
        | parseTargetOpt "pthread" = (platform := Tgt.PARALLEL)
        | parseTargetOpt "cl" = if Paths.clEnabled
            then (platform := Tgt.OPENCL)
            else raise Usage "cl target not supported by this version"
        | parseTargetOpt "opencl" = if Paths.clEnabled
            then (platform := Tgt.OPENCL)
            else raise Usage "cl target not supported by this version"
        | parseTargetOpt "cuda" = if Paths.cudaEnabled
            then (platform := Tgt.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"
            },
	    mkOptionFlag {ctl = Ctl.enableLog, short = "", long = SOME "log"},
	    mkOptionFlag {ctl = Ctl.collectStats, short = "", long = SOME "stats"},
	    mkOptionFlag {ctl = Ctl.verbose, short = "", long = SOME "verbose"},
            targetOptDesc
          ]

  (* create the list of options that control compiler internals *)
    val ctlOptions = let
	  val optimizeFlags = List.map mkOpt Ctl.optimizeControls
	  val dumpFlags = List.map mkOpt Ctl.dumpControls @ [
		{ short = "", long = ["dump-all"],
		  desc = setFlag (Ctl.dumpAll, true),
		  help = "dump out all intermediate representations to the log file"
		}]
	  val checkFlags = List.map mkOpt Ctl.checkControls @ [
		{ short = "", long = ["check-all"],
		  desc = setFlag (Ctl.checkAll, true),
		  help = "always check intermediate representations"
		}]
	  in
	    { short = "", long = ["force-bsp"],
		desc = setFlag (bspFlg, true),
		help = "execute strands in BSP mode"
	      } :: optimizeFlags @ dumpFlags @ checkFlags
	  end

    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 : Tgt.t = {
                  srcFile = srcFile,
                  outDir = outDir,
                  outBase = outBase,
                  exec = !standaloneFlg,
                  snapshot = not(!standaloneFlg) andalso !snapshotFlg,
                  platform = !platform,
                  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