summaryrefslogtreecommitdiff
path: root/lib/coq/String.v
diff options
context:
space:
mode:
Diffstat (limited to 'lib/coq/String.v')
-rw-r--r--lib/coq/String.v212
1 files changed, 212 insertions, 0 deletions
diff --git a/lib/coq/String.v b/lib/coq/String.v
new file mode 100644
index 00000000..207aac5f
--- /dev/null
+++ b/lib/coq/String.v
@@ -0,0 +1,212 @@
+Require Import Sail.Values.
+Require Import Coq.Strings.Ascii.
+
+Definition string_sub (s : string) (start : Z) (len : Z) : string :=
+ String.substring (Z.to_nat start) (Z.to_nat len) s.
+
+Definition string_startswith s expected :=
+ let prefix := String.substring 0 (String.length expected) s in
+ generic_eq prefix expected.
+
+Definition string_drop s (n : Z) `{ArithFact (n >=? 0)} :=
+ let n := Z.to_nat n in
+ String.substring n (String.length s - n) s.
+
+Definition string_take s (n : Z) `{ArithFact (n >=? 0)} :=
+ let n := Z.to_nat n in
+ String.substring 0 n s.
+
+Definition string_length s : {n : Z & ArithFact (n >=? 0)} :=
+ build_ex (Z.of_nat (String.length s)).
+
+Definition string_append := String.append.
+
+Local Open Scope char_scope.
+Local Definition hex_char (c : Ascii.ascii) : option Z :=
+match c with
+| "0" => Some 0
+| "1" => Some 1
+| "2" => Some 2
+| "3" => Some 3
+| "4" => Some 4
+| "5" => Some 5
+| "6" => Some 6
+| "7" => Some 7
+| "8" => Some 8
+| "9" => Some 9
+| "a" => Some 10
+| "b" => Some 11
+| "c" => Some 12
+| "d" => Some 13
+| "e" => Some 14
+| "f" => Some 15
+| _ => None
+end.
+Local Close Scope char_scope.
+Local Fixpoint more_digits (s : string) (base : Z) (acc : Z) (len : nat) : Z * nat :=
+match s with
+| EmptyString => (acc, len)
+| String "_" t => more_digits t base acc (S len)
+| String h t =>
+ match hex_char h with
+ | None => (acc, len)
+ | Some i =>
+ if i <? base
+ then more_digits t base (base * acc + i) (S len)
+ else (acc, len)
+ end
+end.
+Local Definition int_of (s : string) (base : Z) (len : nat) : option (Z * {n : Z & ArithFact (n >=? 0)}) :=
+match s with
+| EmptyString => None
+| String h t =>
+ match hex_char h with
+ | None => None
+ | Some i =>
+ if i <? base
+ then
+ let (i, len') := more_digits t base i (S len) in
+ Some (i, build_ex (Z.of_nat len'))
+ else None
+ end
+end.
+
+(* I've stuck closely to OCaml's int_of_string, because that's what's currently
+ used elsewhere. *)
+
+Definition maybe_int_of_prefix (s : string) : option (Z * {n : Z & ArithFact (n >=? 0)}) :=
+match s with
+| EmptyString => None
+| String "0" (String ("x"|"X") t) => int_of t 16 2
+| String "0" (String ("o"|"O") t) => int_of t 8 2
+| String "0" (String ("b"|"B") t) => int_of t 2 2
+| String "0" (String "u" t) => int_of t 10 2
+| String "-" t =>
+ match int_of t 10 1 with
+ | None => None
+ | Some (i,len) => Some (-i,len)
+ end
+| _ => int_of s 10 0
+end.
+
+Definition maybe_int_of_string (s : string) : option Z :=
+match maybe_int_of_prefix s with
+| None => None
+| Some (i,len) =>
+ if projT1 len =? projT1 (string_length s)
+ then Some i
+ else None
+end.
+
+Fixpoint n_leading_spaces (s:string) : nat :=
+ match s with
+ | EmptyString => 0
+ | String " " t => S (n_leading_spaces t)
+ | _ => 0
+ end.
+
+Definition opt_spc_matches_prefix s : option (unit * {n : Z & ArithFact (n >=? 0)}) :=
+ Some (tt, build_ex (Z.of_nat (n_leading_spaces s))).
+
+Definition spc_matches_prefix s : option (unit * {n : Z & ArithFact (n >=? 0)}) :=
+ match n_leading_spaces s with
+ | O => None
+ | S n => Some (tt, build_ex (Z.of_nat (S n)))
+ end.
+
+Definition hex_bits_n_matches_prefix sz `{ArithFact (sz >=? 0)} s : option (mword sz * {n : Z & ArithFact (n >=? 0)}) :=
+ match maybe_int_of_prefix s with
+ | None => None
+ | Some (n, len) =>
+ if andb (0 <=? n) (n <? pow 2 sz)
+ then Some (of_int sz n, len)
+ else None
+ end.
+
+Definition hex_bits_1_matches_prefix s := hex_bits_n_matches_prefix 1 s.
+Definition hex_bits_2_matches_prefix s := hex_bits_n_matches_prefix 2 s.
+Definition hex_bits_3_matches_prefix s := hex_bits_n_matches_prefix 3 s.
+Definition hex_bits_4_matches_prefix s := hex_bits_n_matches_prefix 4 s.
+Definition hex_bits_5_matches_prefix s := hex_bits_n_matches_prefix 5 s.
+Definition hex_bits_6_matches_prefix s := hex_bits_n_matches_prefix 6 s.
+Definition hex_bits_7_matches_prefix s := hex_bits_n_matches_prefix 7 s.
+Definition hex_bits_8_matches_prefix s := hex_bits_n_matches_prefix 8 s.
+Definition hex_bits_9_matches_prefix s := hex_bits_n_matches_prefix 9 s.
+Definition hex_bits_10_matches_prefix s := hex_bits_n_matches_prefix 10 s.
+Definition hex_bits_11_matches_prefix s := hex_bits_n_matches_prefix 11 s.
+Definition hex_bits_12_matches_prefix s := hex_bits_n_matches_prefix 12 s.
+Definition hex_bits_13_matches_prefix s := hex_bits_n_matches_prefix 13 s.
+Definition hex_bits_14_matches_prefix s := hex_bits_n_matches_prefix 14 s.
+Definition hex_bits_15_matches_prefix s := hex_bits_n_matches_prefix 15 s.
+Definition hex_bits_16_matches_prefix s := hex_bits_n_matches_prefix 16 s.
+Definition hex_bits_17_matches_prefix s := hex_bits_n_matches_prefix 17 s.
+Definition hex_bits_18_matches_prefix s := hex_bits_n_matches_prefix 18 s.
+Definition hex_bits_19_matches_prefix s := hex_bits_n_matches_prefix 19 s.
+Definition hex_bits_20_matches_prefix s := hex_bits_n_matches_prefix 20 s.
+Definition hex_bits_21_matches_prefix s := hex_bits_n_matches_prefix 21 s.
+Definition hex_bits_22_matches_prefix s := hex_bits_n_matches_prefix 22 s.
+Definition hex_bits_23_matches_prefix s := hex_bits_n_matches_prefix 23 s.
+Definition hex_bits_24_matches_prefix s := hex_bits_n_matches_prefix 24 s.
+Definition hex_bits_25_matches_prefix s := hex_bits_n_matches_prefix 25 s.
+Definition hex_bits_26_matches_prefix s := hex_bits_n_matches_prefix 26 s.
+Definition hex_bits_27_matches_prefix s := hex_bits_n_matches_prefix 27 s.
+Definition hex_bits_28_matches_prefix s := hex_bits_n_matches_prefix 28 s.
+Definition hex_bits_29_matches_prefix s := hex_bits_n_matches_prefix 29 s.
+Definition hex_bits_30_matches_prefix s := hex_bits_n_matches_prefix 30 s.
+Definition hex_bits_31_matches_prefix s := hex_bits_n_matches_prefix 31 s.
+Definition hex_bits_32_matches_prefix s := hex_bits_n_matches_prefix 32 s.
+Definition hex_bits_33_matches_prefix s := hex_bits_n_matches_prefix 33 s.
+Definition hex_bits_48_matches_prefix s := hex_bits_n_matches_prefix 48 s.
+Definition hex_bits_64_matches_prefix s := hex_bits_n_matches_prefix 64 s.
+
+Local Definition zero : N := Ascii.N_of_ascii "0".
+Local Fixpoint string_of_N (limit : nat) (n : N) (acc : string) : string :=
+match limit with
+| O => acc
+| S limit' =>
+ let (d,m) := N.div_eucl n 10 in
+ let acc := String (Ascii.ascii_of_N (m + zero)) acc in
+ if N.ltb 0 d then string_of_N limit' d acc else acc
+end.
+Local Fixpoint pos_limit p :=
+match p with
+| xH => S O
+| xI p | xO p => S (pos_limit p)
+end.
+Definition string_of_int (z : Z) : string :=
+match z with
+| Z0 => "0"
+| Zpos p => string_of_N (pos_limit p) (Npos p) ""
+| Zneg p => String "-" (string_of_N (pos_limit p) (Npos p) "")
+end.
+
+Local Definition asciiA : N := Ascii.N_of_ascii "A".
+Local Fixpoint hex_string_of_N (limit : nat) (n : N) (acc : string) : string :=
+match limit with
+| O => acc
+| S limit' =>
+ let (d,m) := N.div_eucl n 16 in
+ let digit := if 10 <=? m then m - 10 + asciiA else m + zero in
+ let acc := String (Ascii.ascii_of_N digit) acc in
+ if N.ltb 0 d then hex_string_of_N limit' d acc else acc
+end%N.
+Definition hex_string_of_int (z : Z) : string :=
+match z with
+| Z0 => "0"
+| Zpos p => hex_string_of_N (pos_limit p) (Npos p) ""
+| Zneg p => String "-" (hex_string_of_N (pos_limit p) (Npos p) "")
+end.
+
+Definition decimal_string_of_bv {a} `{Bitvector a} (bv : a) : string :=
+ match unsigned bv with
+ | None => "?"
+ | Some i => string_of_int i
+ end.
+
+Definition decimal_string_of_bits {n} (bv : mword n) : string := decimal_string_of_bv bv.
+
+
+(* Some aliases for compatibility. *)
+Definition dec_str := string_of_int.
+Definition hex_str := hex_string_of_int.
+Definition concat_str := String.append.