~james/span

ref: de502ca765320a4ac82d4bce88e01936c82bc498 span/cli/driver.ML -rw-r--r-- 2.2 KiB
de502ca7 — james perf(cli): compile binary output and assembly report once 11 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
val root = valOf (OS.Process.getEnv "SPAN_ROOT");
val _ = use (root ^ "/.build/Span.Export/code/span.ML");

fun chars s = map (Span.ascii o IntInf.fromInt o Char.ord) (String.explode s);
fun text cs = String.implode (map (Char.chr o IntInf.toInt o Span.ordinal) cs);

fun read path =
  let
    val stream = if path = "-" then TextIO.stdIn else TextIO.openIn path
    val text = TextIO.inputN (stream, 1048577)
    val _ = if path = "-" then () else TextIO.closeIn stream
  in
    if size text > 1048576 then raise Fail "input exceeds 1 MiB" else text
  end;

fun write path text =
  let
    val stream = BinIO.openOut path
    val _ = BinIO.output (stream, Byte.stringToBytes text)
  in BinIO.closeOut stream end;

fun output (ok, message) =
  (TextIO.output (if ok then TextIO.stdOut else TextIO.stdErr, text message);
   OS.Process.exit (if ok then OS.Process.success else OS.Process.failure));

fun usage () =
  (TextIO.output (TextIO.stdOut,
    "usage: span assemble file [-o binary]\n       span trace file\n       span list file\n       span run file [fuel]\n       span disassemble binary\n\nuse - to read standard input\n");
   OS.Process.exit OS.Process.success);

fun run args =
  case args of
    [] => usage ()
  | ["--help"] => usage ()
  | ["disassemble", file] => output (Span.disassemble (chars (read file)))
  | ["assemble", file, "-o", destination] =>
      let
        val ((ok, bytes), report) = Span.artifact (chars (read file))
      in
        if ok then
          (write destination (text bytes);
           output (true, report))
        else output (false, report)
      end
  | ["run", file] => output (Span.process (map chars ["run", "4096"]) (chars (read file)))
  | ["run", file, fuel] => output (Span.process (map chars ["run", fuel]) (chars (read file)))
  | [mode, file] =>
      if List.exists (fn x => x = mode) ["assemble", "trace", "list"] then
        output (Span.process [chars mode] (chars (read file)))
      else raise Fail "unknown command, use span --help"
  | _ => raise Fail "invalid arguments, use span --help";

fun main () = run (CommandLine.arguments ())
  handle exn =>
    (TextIO.output (TextIO.stdErr, "span: " ^ General.exnMessage exn ^ "\n");
     OS.Process.exit OS.Process.failure);