Skip to content

Commit 5f9313e

Browse files
authored
Merge pull request #2049 from JasonGross/ascii
Add .ascii, .asciz
2 parents d838e6d + 29c1d50 commit 5f9313e

File tree

8 files changed

+89
-7
lines changed

8 files changed

+89
-7
lines changed

src/Assembly/Equality.v

+3-1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ Definition RawLine_beq (x y : RawLine) : bool
273273
| INSTR x, INSTR y => NormalInstruction_beq x y
274274
| ALIGN x, ALIGN y => String.eqb x y
275275
| DIRECTIVE x, DIRECTIVE y => String.eqb x y
276+
| ASCII_ z x, ASCII_ z' y => Bool.eqb z z' && String.eqb x y
276277
| SECTION _, _
277278
| GLOBAL _, _
278279
| LABEL _, _
@@ -281,8 +282,9 @@ Definition RawLine_beq (x y : RawLine) : bool
281282
| ALIGN _, _
282283
| DEFAULT_REL, _
283284
| DIRECTIVE _, _
285+
| ASCII_ _ _, _
284286
=> false
285-
end.
287+
end%bool.
286288
Global Arguments RawLine_beq !_ !_ / .
287289

288290
Infix "=?" := RawLine_beq : RawLine_scope.

src/Assembly/Parse.v

+55
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Require Import Crypto.Util.OptionList.
99
Require Import Crypto.Util.Strings.Parse.Common.
1010
Require Import Crypto.Util.Strings.ParseArithmetic.
1111
Require Import Crypto.Util.Strings.String.
12+
Require Crypto.Util.Strings.Ascii.
1213
Require Import Crypto.Util.Strings.Show.
1314
Require Import Crypto.Util.Strings.Show.Enum.
1415
Require Import Crypto.Util.Listable.
@@ -177,6 +178,52 @@ Definition parse_OpPrefix_list : list (string * OpPrefix)
177178
Definition parse_OpPrefix : ParserAction OpPrefix
178179
:= parse_strs parse_OpPrefix_list.
179180

181+
Definition chars_to_escape_list : list (string * ascii)
182+
:= Eval vm_compute in
183+
List.map
184+
(fun '(name, char) => (String name EmptyString, char))
185+
[("b", Ascii.Backspace)
186+
; ("f", Ascii.FormFeed)
187+
; ("n", Ascii.LF)
188+
; ("r", Ascii.CR)
189+
; ("t", Ascii.HorizontalTab)
190+
; ("v", Ascii.VerticalTab)
191+
; ("""", """")
192+
; ("'", "'")
193+
; ("\", "\")
194+
; ("0", Ascii.Null)
195+
]%char.
196+
Definition parse_escaped_char : ParserAction ascii :=
197+
"\" ;;R
198+
(parse_or_else
199+
(parse_map ascii_of_N
200+
(("x" ;;R parse_N_fixed_digits 16 false 2)
201+
|| (parse_N_fixed_digits 8 false 3)))
202+
(parse_strs chars_to_escape_list)).
203+
204+
Definition should_escape (ch : ascii) : bool
205+
:= (List.existsb (Ascii.eqb ch) (List.map snd chars_to_escape_list))
206+
|| negb (Ascii.is_printable ch).
207+
208+
Definition escape_char (ch : ascii) : string :=
209+
match List.find (fun '(escape_str, ch') => Ascii.eqb ch ch') chars_to_escape_list, should_escape ch with
210+
| Some (escape_str, _), _ => "\" ++ escape_str
211+
| None, true =>
212+
let hex := Hex.show_N (Ascii.N_of_ascii ch) in
213+
let hex := String.substring 2 (String.length hex) hex in
214+
let hex := if (String.length hex <? 2)%nat then "0" ++ hex else hex in
215+
let hex := if (String.length hex <? 2)%nat then "0" ++ hex else hex in
216+
"\x" ++ hex
217+
| None, false => String ch EmptyString
218+
end%string.
219+
220+
Definition escape_string (s : string) : string :=
221+
String.concat "" (List.map escape_char (list_ascii_of_string s)).
222+
223+
Definition unescape_string (s : string) : string :=
224+
Option.value (finalize (parse_map string_of_list_ascii ( (parse_or_else parse_escaped_char (fun s => match s with EmptyString => [] | String char s => [(char, s)] end)* ))) s) s.
225+
226+
180227
(** assumes no leading nor trailing whitespace and no comment *)
181228
Definition parse_RawLine {opts : assembly_program_options} : ParserAction RawLine
182229
:= fun s => (
@@ -194,6 +241,10 @@ Definition parse_RawLine {opts : assembly_program_options} : ParserAction RawLin
194241
then [(DEFAULT_REL, "")]
195242
else if String.endswith ":" s
196243
then [(LABEL (substring 0 (pred (String.length s)) s), "")]
244+
else if (String.to_upper mnemonic =? ".ASCII") && (String.startswith """" args) && (String.endswith """" args)
245+
then [(ASCII (unescape_string (String.substring 1 (String.length args - 2) args)), "")]
246+
else if (String.to_upper mnemonic =? ".ASCIZ") && (String.startswith """" args) && (String.endswith """" args)
247+
then [(ASCIZ (unescape_string (String.substring 1 (String.length args - 2) args)), "")]
197248
else if (s =? "")
198249
then [(EMPTY, "")]
199250
else if (List.find (String.eqb (String.to_lower mnemonic))
@@ -381,6 +432,8 @@ Global Instance show_RawLine : Show RawLine
381432
| EMPTY => ""
382433
| INSTR instr => show instr
383434
| DIRECTIVE s => s
435+
| ASCII s => ".ascii """ ++ escape_string s ++ """"
436+
| ASCIZ s => ".asciz """ ++ escape_string s ++ """"
384437
end.
385438

386439
Global Instance show_Line : Show Line
@@ -627,6 +680,8 @@ Fixpoint get_initial_data (ls : Lines) : list (AccessSize * list Z)
627680
=> get_initial_data ls
628681
| SECTION _
629682
| ALIGN _
683+
| ASCII _
684+
| ASCIZ _
630685
=> []
631686
end
632687
end.

src/Assembly/Symbolic.v

+1
Original file line numberDiff line numberDiff line change
@@ -4389,6 +4389,7 @@ Definition SymexRawLine {opts : symbolic_options_computed_opt} {descr:descriptio
43894389
| EMPTY
43904390
| LABEL _
43914391
| DIRECTIVE _
4392+
| ASCII_ _ _
43924393
=> ret tt
43934394
| INSTR instr
43944395
=> SymexNormalInstruction instr

src/Assembly/Syntax.v

+3
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,10 @@ Inductive RawLine :=
281281
| EMPTY
282282
| INSTR (instr : NormalInstruction)
283283
| DIRECTIVE (d : string)
284+
| ASCII_ (null_terminated : bool) (s : string)
284285
.
286+
Notation ASCII := (ASCII_ false).
287+
Notation ASCIZ := (ASCII_ true).
285288
Coercion INSTR : NormalInstruction >-> RawLine.
286289
Record Line := { indent : string ; rawline :> RawLine ; pre_comment_whitespace : string ; comment : option string ; line_number : N}.
287290
Definition Lines := list Line.

src/Assembly/WithBedrock/Semantics.v

+1
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ Definition DenoteRawLine (st : machine_state) (rawline : RawLine) : option machi
474474
| EMPTY
475475
| LABEL _
476476
| DIRECTIVE _
477+
| ASCII_ _ _
477478
=> Some st
478479
| INSTR instr
479480
=> DenoteNormalInstruction st instr

src/Assembly/WithBedrock/SymbolicProofs.v

+4-4
Original file line numberDiff line numberDiff line change
@@ -1374,12 +1374,12 @@ Lemma SymexLines_R {opts : symbolic_options_computed_opt} s m (HR : R s m) asm :
13741374
Proof using Type.
13751375
revert dependent m; revert dependent s; induction asm; cbn [SymexLines DenoteLines]; intros.
13761376
{ inversion H; subst; eauto. }
1377-
destruct a.
1378-
rewrite unfold_bind in H; destruct_one_match_hyp; inversion_ErrorT.
1377+
destruct_head' Line.
1378+
rewrite unfold_bind in *; destruct_one_match_hyp; inversion_ErrorT.
13791379
cbv [SymexLine SymexRawLine DenoteLine DenoteRawLine ret err Crypto.Util.Option.bind] in *; cbn in *.
1380-
destruct_one_match_hyp; inversion_ErrorT; subst; eauto; destruct v.
1380+
destruct_one_match_hyp; inversion_ErrorT; subst; eauto; destruct_head'_prod.
13811381
eapply SymexNornalInstruction_R in E; eauto. destruct E as (m1&Hm1&Rm1&?). rewrite Hm1.
1382-
eapply IHasm in H; eauto. destruct H as (?&?&?&?). eauto 9.
1382+
eapply IHasm in H; eauto. destruct H as (?&?&?&?). break_innermost_match; eauto 9.
13831383
Qed.
13841384
End WithCtx1'.
13851385
End WithFrame.

src/Util/Strings/Ascii.v

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ Local Open Scope char_scope.
1111
Example Null := "000".
1212
Example Backspace := "008".
1313
Example Tab := "009".
14+
Example HorizontalTab := "009".
1415
Example LF := "010".
16+
Example NewLine := "010".
17+
Example VerticalTab := "011".
1518
Example NewPage := "012".
19+
Example FormFeed := "012".
1620
Example CR := "013".
1721
Example Escape := "027".
18-
Example NewLine := "010".
1922

2023
Local Coercion N_of_ascii : ascii >-> N.
2124
Definition ltb (x y : ascii) : bool := N.ltb x y.
@@ -39,3 +42,6 @@ Definition to_upper (ch : ascii) : ascii
3942

4043
Definition is_whitespace (x : ascii) : bool
4144
:= ((x =? " ") || (x =? NewPage) || (x =? LF) || (x =? CR) || (x =? Tab))%char%bool.
45+
46+
Definition is_printable (x : ascii) : bool
47+
:= (" " <=? x) && (x <=? "~").

src/Util/Strings/ParseArithmetic.v

+15-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ Definition parse_digits_gen_step (base : N) : ParserAction N
6464
(String (ascii_of_N (v - 10 + N_of_ascii "a")) "", v)])
6565
(List.map N.of_nat (List.seq 0 (N.to_nat base))))).
6666

67-
6867
(*
6968
Definition parse_oct_digits : ParserAction (list N)
7069
:= Eval cbv -[ParserAction parse_alt_gen parse_impossible parse_str parse_star] in
@@ -92,6 +91,21 @@ Local Coercion inject_Z : Z >-> Q.
9291
Definition parse_N_digits (base : N) (first_digit_numeric : bool) : ParserAction N
9392
:= (parse_map (digits_to_N base) ((parse_digits_gen_step (if first_digit_numeric then N.min 10 base else base);;->{cons}(parse_digits_gen_step base)* ))).
9493

94+
Definition parse_N_fixed_digits (base : N) (first_digit_numeric : bool) (n : nat) : ParserAction N := (
95+
let parse_first_digit := parse_digits_gen_step (if first_digit_numeric then N.min 10 base else base) in
96+
let parse_nil := parse_map (fun _ => nil) "" in
97+
parse_map (digits_to_N base)
98+
match n with
99+
| O => parse_nil
100+
| S n =>
101+
fold_right (fun p ps => p ;;->{cons} ps)
102+
parse_nil
103+
(parse_first_digit :: List.repeat (parse_digits_gen_step base) n)
104+
end)%parse.
105+
106+
Notation parse_oct_char := (parse_digits_gen_step 8 false 1).
107+
Notation parse_hex_char := (parse_digits_gen_step 16 false 1).
108+
95109
Definition parse_num_gen {P P'} (allow_neg : bool) (base : N) (parse_prefix : option (ParserAction P)) (parse_postfix : option (ParserAction P')) : ParserAction Q
96110
:= (let parse_E_exponent
97111
:= (("e" || "E") ;;->{ fun _ v => Qpower 10 v }

0 commit comments

Comments
 (0)