Require Import Sail.Values. Require Import Coq.Strings.Ascii. Local Open Scope Z. 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 =? 0)}) := match s with | EmptyString => None | String h t => match hex_char h with | None => None | Some i => if i =? 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 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.