Module Excmd.Expression
type t
An alias to
AST.expression
, abstracted that mutation may be controlled.
type flag_payload
=
|
Empty
|
Payload of AST.word
Basic getters
val count : t -> int
val command : t -> AST.word
val mem : string -> t -> bool
mem fl expr
returnstrue
ifexpr
contains flagfl
,false
otherwise.Notably, this does not resolve any unresolved words from the parsed expression.
val is_resolved : string -> t -> bool
is_resolved fl expr
returnstrue
ifexpr
contains a flagfl
and the last such flagfl
is already resolved; andfalse
otherwise.
val has_payload : string -> t -> bool
has_payload fl expr
returnstrue
ifexpr
contains a flagfl
, the last such flagfl
is already resolved, and that last flagfl
resolved to astring
payload instead of abool
. Returnsfalse
otherwise.
val flags : t -> string list
flags expr
returns a list of the flags used inexpr
, including only the names of flags - not the payloads.
Resolvers (mutative getters)
val positionals : t -> AST.word list
positionals expr
returns alist
of positional (non-flag) arguments inexpr
.This fully resolves
expr
— any ambiguous words will be consumed as positional arguments, becoming unavailable as flag-payloads.
val iter : (string -> flag_payload -> unit) -> t -> unit
iter f expr
appliesf
to all flags in expressionexpr
.f
receives the flag as its first argument, and the associated, fully-resolved value as the second argument.This fully resolves
expr
— any ambiguous words will be consumed as the values to their associated flags, becoming unavailable as positional arguments.
val iteri : (int -> string -> flag_payload -> unit) -> t -> unit
iteri f expr
, as withiter
, appliesf
to each flag inexpr
. However,f
will also receive the index of each flag as an argument.
val rev_iteri : (int -> string -> flag_payload -> unit) -> t -> unit
rev_iteri f expr
, as withiteri
, appliesf
to each flag inexpr
; except that the flags are observed in reverse order — from the end of the expression, to the start. (This is marginally more efficient than eitheriter
oriteri
.)
val flag : string -> t -> flag_payload option
flag fl expr
finds a flag by the name offl
, resolves it if necessary, and produces the payload there of, if any.This can yield ...
None
, indicating flagfl
was not present at all.Some Empty
, indicating a flagfl
was present, but the last such resolved to having no payload.Some (Payload word)
, indicating a flagfl
was present and the last such became resolved to the payloadword
. This can involve resolution of the word immediately following saidfl
, removing it from the implicitpositionals
.
Other helpers
val pp : t -> unit
Pretty-print a expression. Implementation varies between platforms.
val hydrate : t -> AST.expression
Type-converter between abstract
Expression.t
and concreteAST.expression
.Careful; the operations in this module are intended to maintain safe invariants, consuming components of a
expression
in reasonable ways. You must not devolve one into a rawAST
node, modify it unsafely, and then expect to continue to use the functions in this module.
Note: Resolution of ambiguous words
It's important to note that a expression is a mutable structure, and that accesses intentionally mutate that structure — in particular, a given word in the original parsed string can only be either a positional argument or the argument to a preceding flag.
Any function that accesses either the value of a flag, or accesses the positionals
at all, is going to “resolve” that word in the original source. If the word was ambiguously positioned, that access will result in the datastructure changing — to prevent the word later becoming resolved in an incompatible way.
For example: given the following input command as a Expression.t
,
hello -- where world
... there's two possible ways to interpret the 'world'
, chosen between by the order in which you invoke either positionals
, or flag-value-reading functions (like iter
or find
/flag
):
(* Yields zero positionals, and 'world' as the value associated with the flag '--where'. *)
let expr1 = Parser.expression_of_string "hello --where world" in
let where = Expression.flag "where" expr1 (* Some (Payload 'world') *) in
let xs = Expression.positionals expr1 (* [] *)
(* Yields one positional, 'world', and no value associated with the flag '--where'. *)
let expr2 = Parser.expression_of_string "hello --where world" in
let xs = Expression.positionals expr2 (* ['world'] *) in
let where = Expression.flag "where" expr2 (* Some (Empty) *)
Once any ambiguous words have been so resolved (or when a function is called that inherently resolves all ambiguous words, such as positionals
or iter
), a Expression.t
is considered “fully resolved.” No functions in this module will further mutate such a expression
.