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 exprreturns- trueif- exprcontains flag- fl,- falseotherwise.- Notably, this does not resolve any unresolved words from the parsed expression. 
- val is_resolved : string -> t -> bool
- is_resolved fl exprreturns- trueif- exprcontains a flag- fland the last such flag- flis already resolved; and- falseotherwise.
- val has_payload : string -> t -> bool
- has_payload fl exprreturns- trueif- exprcontains a flag- fl, the last such flag- flis already resolved, and that last flag- flresolved to a- stringpayload instead of a- bool. Returns- falseotherwise.
- val flags : t -> string list
- flags exprreturns a list of the flags used in- expr, including only the names of flags - not the payloads.
Resolvers (mutative getters)
- val positionals : t -> AST.word list
- positionals exprreturns a- listof positional (non-flag) arguments in- expr.- 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 exprapplies- fto all flags in expression- expr.- freceives 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 with- iter, applies- fto each flag in- expr. However,- fwill 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 with- iteri, applies- fto each flag in- expr; except that the flags are observed in reverse order — from the end of the expression, to the start. (This is marginally more efficient than either- iteror- iteri.)
- val flag : string -> t -> flag_payload option
- flag fl exprfinds a flag by the name of- fl, resolves it if necessary, and produces the payload there of, if any.- This can yield ... - None, indicating flag- flwas not present at all.
- Some Empty, indicating a flag- flwas present, but the last such resolved to having no payload.
- Some (Payload word), indicating a flag- flwas present and the last such became resolved to the payload- word. This can involve resolution of the word immediately following said- fl, removing it from the implicit- positionals.
 
Other helpers
- val pp : t -> unit
- Pretty-print a expression. Implementation varies between platforms. 
- val hydrate : t -> AST.expression
- Type-converter between abstract - Expression.tand concrete- AST.expression.- Careful; the operations in this module are intended to maintain safe invariants, consuming components of a - expressionin reasonable ways. You must not devolve one into a raw- ASTnode, 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.