1 import Base 2 3 # The global options taken off a command line before the verb sees it: 4 # `--format NAME` (or `--format=NAME`), `--no-input` (never read standard 5 # input: a prompt becomes an error) and `--yes` (answer a confirmation). 6 # `config import` and `profile import` keep `--format`: there it names the 7 # format of the input file. 8 9 type G is Data: 10 G{rest: List<&2, String>, fmt: Maybe<&2, String>, noin: Bool, yes: Bool, err: String, pending: Bool} 11 12 def start() -> G: 13 G{[], None{}, False{}, False{}, "", False{}} 14 15 def with_fmt(+g: G, +v: String) -> G: 16 match g: 17 case G{rest, fmt, noin, yes, err, p}: 18 G{rest, Some{v}, noin, yes, err, False{}} 19 20 def pend(+g: G) -> G: 21 match g: 22 case G{rest, fmt, noin, yes, err, p}: 23 G{rest, fmt, noin, yes, err, True{}} 24 25 def with_noin(+g: G) -> G: 26 match g: 27 case G{rest, fmt, noin, yes, err, p}: 28 G{rest, fmt, True{}, yes, err, p} 29 30 def with_yes(+g: G) -> G: 31 match g: 32 case G{rest, fmt, noin, yes, err, p}: 33 G{rest, fmt, noin, True{}, err, p} 34 35 def keep(+h: String, +g: G) -> G: 36 match g: 37 case G{rest, fmt, noin, yes, err, p}: 38 G{h <> rest, fmt, noin, yes, err, p} 39 40 def is_pending(+g: G) -> Bool: 41 match g: 42 case G{rest, fmt, noin, yes, err, p}: 43 p 44 45 def sel.g(c: Bool, +a: G, +b: G) -> G: 46 match c: 47 case True{}: 48 a 49 case False{}: 50 b 51 52 def free(+keep_fmt: Bool, +h: String, +g: G) -> G: 53 sel.g(Bool.not(keep_fmt) && String.eq(h, "--format"), pend(g), 54 sel.g(Bool.not(keep_fmt) && String.starts_with(h, "--format="), with_fmt(g, String.drop(h, 9n)), 55 sel.g(String.eq(h, "--no-input"), with_noin(g), 56 sel.g(String.eq(h, "--yes"), with_yes(g), 57 keep(h, g))))) 58 59 def step(+keep_fmt: Bool, +h: String, +g: G) -> G: 60 sel.g(is_pending(g), with_fmt(g, h), free(keep_fmt, h, g)) 61 62 def go(+keep_fmt: Bool, args: List<&2, String>, +g: G) -> G: 63 match args: 64 case Nil{}: 65 g 66 case Con{h, t}: 67 go(keep_fmt, t, step(keep_fmt, h, g)) 68 69 def end2(+g: G) -> G: 70 match g: 71 case G{rest, fmt, noin, yes, err, p}: 72 G{List.reverse(&2, String, rest), fmt, noin, yes, Bool.pick(String, p, "argument --format: expected one argument", err), False{}} 73 74 # The words left, the format name given, and the two switches. `keep_fmt`: 75 # leave `--format` where it is. 76 def split(+keep_fmt: Bool, args: List<&2, String>) -> G: 77 end2(go(keep_fmt, args, start()))