Library zoo.common.format
Require Import Stdlib.Strings.Ascii.
Require Import stdpp.gmap.
Require Import zoo.prelude.
Require Import zoo.common.string.
Require Import zoo.options.
Implicit Type str pref suff var val : string.
Definition format۰env :=
gmap string string.
Implicit Type env : format۰env.
Module parse.
Notation assign :=
"="%char.
Notation sep :=
";"%char.
Notation hole_beg :=
"{"%char.
Notation hole_end :=
"}"%char.
Definition binding str :=
let '(var, val) := split_on assign str in
let val := default var val in
(var, val).
Variant insideness :=
| Inside
| Outside.
Fixpoint go env str res :=
match str with
| "" ⇒
Some (String.rev res)
| String hole_beg str ⇒
hole env str res ""
| String chr str ⇒
go env str (String chr res)
end
with hole env str res acc :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_variable env str res acc ""
| String hole_end str ⇒
match env !! String.rev acc with
| None ⇒
go env str (acc +:+ res)
| Some val ⇒
go env str (String.rev val +:+ res)
end
| String sep str ⇒
match env !! String.rev acc with
| None ⇒
hole' env str res ""
| Some val ⇒
hole_finish env str (String.rev val +:+ res) Outside
end
| String chr str ⇒
hole env str res (String chr acc)
end
with hole' env str res acc :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_variable env str res acc ""
| String hole_end str ⇒
go env str (acc +:+ res)
| String sep str ⇒
hole_finish env str (acc +:+ res) Outside
| String chr str ⇒
hole' env str res (String chr acc)
end
with hole_variable env str res acc var :=
match str with
| "" ⇒
None
| String hole_end str ⇒
match env !! String.rev var with
| None ⇒
hole_next env str res Outside
| Some val ⇒
hole' env str res (String.rev val +:+ acc)
end
| String chr str ⇒
hole_variable env str res acc (String chr var)
end
with hole_finish env str res state :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_finish env str res Inside
| String hole_end str ⇒
if state is Inside then
hole_finish env str res Outside
else
go env str res
| String _ str ⇒
hole_finish env str res state
end
with hole_next env str res state :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_next env str res Inside
| String hole_end str ⇒
if state is Inside then
hole_next env str res Outside
else
go env str res
| String sep str ⇒
hole' env str res ""
| String _ str ⇒
hole_next env str res state
end.
Definition format env str :=
go env str "".
End parse.
Definition format۰env۰of_bindings bdgs env :=
foldr (λ p, <[p.1 := p.2]>) env bdgs.
Definition format۰env۰of_strings strs :=
format۰env۰of_bindings (parse.binding <$> strs).
Definition format۰env۰of_string str :=
format۰env۰of_strings (String.words str).
Definition format fmt env :=
parse.format env fmt.
Goal format "{}" ∅ = Some "".
Goal format "{}" {["":="!"]} = Some "!".
Goal format "{1}" {["1":="one"]} = Some "one".
Goal format "{1}" ∅ = Some "1".
Goal format "{1} {2}" {["1":="one";"2":="two"]} = Some "one two".
Goal format "{1;∅}" ∅ = Some "∅".
Goal format "{1;∅}" {["1":="one"]} = Some "one".
Goal format "{1;}" ∅ = Some "".
Goal format "{1;}" {["1":="one"]} = Some "one".
Goal format "{({1});∅}" ∅ = Some "∅".
Goal format "{({1});∅}" {["1":="one"]} = Some "(one)".
Goal format "{({1});({2})}" ∅ = Some "".
Goal format "{({1});({2})}" {["1":="one"]} = Some "(one)".
Goal format "{({1});({2})}" {["2":="two"]} = Some "(two)".
Goal format "{({1});({2});∅}" ∅ = Some "∅".
Goal format "{({1});({2});∅}" {["1":="one"]} = Some "(one)".
Goal format "{({1});({2});∅}" {["2":="two"]} = Some "(two)".
Goal format "{{1}-{2}}" ∅ = Some "".
Goal format "{{1}-{2}}" {["1":="one"]} = Some "".
Goal format "{{1}-{2}}" {["2":="two"]} = Some "".
Goal format "{{1}-{2}}" {["1":="one";"2":="two"]} = Some "one-two".
Goal format "{{1}-{2};∅}" ∅ = Some "∅".
Goal format "{{1}-{2};∅}" {["1":="one"]} = Some "∅".
Goal format "{{1}-{2};∅}" {["2":="two"]} = Some "∅".
Goal format "{{1}-{2};∅}" {["1":="one";"2":="two"]} = Some "one-two".
Require Import stdpp.gmap.
Require Import zoo.prelude.
Require Import zoo.common.string.
Require Import zoo.options.
Implicit Type str pref suff var val : string.
Definition format۰env :=
gmap string string.
Implicit Type env : format۰env.
Module parse.
Notation assign :=
"="%char.
Notation sep :=
";"%char.
Notation hole_beg :=
"{"%char.
Notation hole_end :=
"}"%char.
Definition binding str :=
let '(var, val) := split_on assign str in
let val := default var val in
(var, val).
Variant insideness :=
| Inside
| Outside.
Fixpoint go env str res :=
match str with
| "" ⇒
Some (String.rev res)
| String hole_beg str ⇒
hole env str res ""
| String chr str ⇒
go env str (String chr res)
end
with hole env str res acc :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_variable env str res acc ""
| String hole_end str ⇒
match env !! String.rev acc with
| None ⇒
go env str (acc +:+ res)
| Some val ⇒
go env str (String.rev val +:+ res)
end
| String sep str ⇒
match env !! String.rev acc with
| None ⇒
hole' env str res ""
| Some val ⇒
hole_finish env str (String.rev val +:+ res) Outside
end
| String chr str ⇒
hole env str res (String chr acc)
end
with hole' env str res acc :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_variable env str res acc ""
| String hole_end str ⇒
go env str (acc +:+ res)
| String sep str ⇒
hole_finish env str (acc +:+ res) Outside
| String chr str ⇒
hole' env str res (String chr acc)
end
with hole_variable env str res acc var :=
match str with
| "" ⇒
None
| String hole_end str ⇒
match env !! String.rev var with
| None ⇒
hole_next env str res Outside
| Some val ⇒
hole' env str res (String.rev val +:+ acc)
end
| String chr str ⇒
hole_variable env str res acc (String chr var)
end
with hole_finish env str res state :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_finish env str res Inside
| String hole_end str ⇒
if state is Inside then
hole_finish env str res Outside
else
go env str res
| String _ str ⇒
hole_finish env str res state
end
with hole_next env str res state :=
match str with
| "" ⇒
None
| String hole_beg str ⇒
hole_next env str res Inside
| String hole_end str ⇒
if state is Inside then
hole_next env str res Outside
else
go env str res
| String sep str ⇒
hole' env str res ""
| String _ str ⇒
hole_next env str res state
end.
Definition format env str :=
go env str "".
End parse.
Definition format۰env۰of_bindings bdgs env :=
foldr (λ p, <[p.1 := p.2]>) env bdgs.
Definition format۰env۰of_strings strs :=
format۰env۰of_bindings (parse.binding <$> strs).
Definition format۰env۰of_string str :=
format۰env۰of_strings (String.words str).
Definition format fmt env :=
parse.format env fmt.
Goal format "{}" ∅ = Some "".
Goal format "{}" {["":="!"]} = Some "!".
Goal format "{1}" {["1":="one"]} = Some "one".
Goal format "{1}" ∅ = Some "1".
Goal format "{1} {2}" {["1":="one";"2":="two"]} = Some "one two".
Goal format "{1;∅}" ∅ = Some "∅".
Goal format "{1;∅}" {["1":="one"]} = Some "one".
Goal format "{1;}" ∅ = Some "".
Goal format "{1;}" {["1":="one"]} = Some "one".
Goal format "{({1});∅}" ∅ = Some "∅".
Goal format "{({1});∅}" {["1":="one"]} = Some "(one)".
Goal format "{({1});({2})}" ∅ = Some "".
Goal format "{({1});({2})}" {["1":="one"]} = Some "(one)".
Goal format "{({1});({2})}" {["2":="two"]} = Some "(two)".
Goal format "{({1});({2});∅}" ∅ = Some "∅".
Goal format "{({1});({2});∅}" {["1":="one"]} = Some "(one)".
Goal format "{({1});({2});∅}" {["2":="two"]} = Some "(two)".
Goal format "{{1}-{2}}" ∅ = Some "".
Goal format "{{1}-{2}}" {["1":="one"]} = Some "".
Goal format "{{1}-{2}}" {["2":="two"]} = Some "".
Goal format "{{1}-{2}}" {["1":="one";"2":="two"]} = Some "one-two".
Goal format "{{1}-{2};∅}" ∅ = Some "∅".
Goal format "{{1}-{2};∅}" {["1":="one"]} = Some "∅".
Goal format "{{1}-{2};∅}" {["2":="two"]} = Some "∅".
Goal format "{{1}-{2};∅}" {["1":="one";"2":="two"]} = Some "one-two".