Skip to content

Commit fc37156

Browse files
[aslspec] adding source locations
1 parent ce8f8ce commit fc37156

File tree

10 files changed

+593
-389
lines changed

10 files changed

+593
-389
lines changed

asllib/aslspec/AST.ml

Lines changed: 172 additions & 60 deletions
Large diffs are not rendered by default.

asllib/aslspec/ASTUtils.ml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ and vars_of_opt_named_type_terms opt_named_terms =
3636

3737
let variant_to_label_opt { TypeVariant.term } =
3838
match term with
39-
| Label label -> Some label
39+
| Label { label } -> Some label
4040
| Tuple { label_opt } | Record { label_opt } -> label_opt
4141
| _ -> None
4242

@@ -50,3 +50,31 @@ let sort_record_fields fields =
5050
(fun { Term.name = name1 } { Term.name = name2 } ->
5151
String.compare name1 name2)
5252
fields
53+
54+
let loc_of_expr =
55+
let open Expr in
56+
function
57+
| Var { loc }
58+
| FieldAccess { loc }
59+
| ListIndex { loc }
60+
| Record { loc }
61+
| RecordUpdate { loc }
62+
| UnresolvedApplication { loc }
63+
| Tuple { loc }
64+
| Relation { loc }
65+
| Map { loc }
66+
| Transition { loc }
67+
| Indexed { loc }
68+
| NamedExpr { loc } ->
69+
loc
70+
71+
let loc_of_term =
72+
let open Term in
73+
function
74+
| Label { loc }
75+
| TypeOperator { loc }
76+
| Tuple { loc }
77+
| Record { loc }
78+
| Function { loc }
79+
| ConstantsSet { loc } ->
80+
loc

asllib/aslspec/ASTUtils.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ val is_operator : elem -> bool
2222

2323
val sort_record_fields : Term.record_field list -> Term.record_field list
2424
(** [sort_record_fields fields] returns [fields] sorted by field name. *)
25+
26+
val loc_of_expr : Expr.t -> source_location
27+
(** [loc_of_expr expr] returns the source location of [expr]. *)
28+
29+
val loc_of_term : Term.t -> source_location
30+
(** [loc_of_term term] returns the source location of [term]. *)

asllib/aslspec/PP.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ let type_operator_to_token =
5353
let rec pp_type_term fmt =
5454
let open Term in
5555
function
56-
| Label name -> pp_print_string fmt name
56+
| Label { label } -> pp_print_string fmt label
5757
| TypeOperator { op; term } ->
5858
fprintf fmt "%s(%a)"
5959
(type_operator_to_token op |> tok_str)
@@ -65,10 +65,10 @@ let rec pp_type_term fmt =
6565
| Record { label_opt; fields } ->
6666
let label = Option.value label_opt ~default:"" in
6767
fprintf fmt "%s[%a]" label pp_record_fields fields
68-
| ConstantsSet constants ->
68+
| ConstantsSet { labels } ->
6969
fprintf fmt "%s(%a)" (tok_str CONSTANTS_SET)
7070
(pp_sep_list ~sep:"," pp_print_string)
71-
constants
71+
labels
7272
| Function { from_type; to_type; total } ->
7373
let keyword = if total then tok_str FUN else tok_str PARTIAL in
7474
fprintf fmt "%s %a -> %a" keyword pp_opt_named_type_term from_type
@@ -108,7 +108,7 @@ let pp_output_opt fmt is_output = if is_output then fprintf fmt "--@," else ()
108108
let rec pp_expr fmt =
109109
let open Expr in
110110
function
111-
| Var name -> pp_print_string fmt name
111+
| Var { id } -> pp_print_string fmt id
112112
| UnresolvedApplication { lhs; args } ->
113113
fprintf fmt "%a(%a)" pp_expr lhs (pp_comma_list pp_expr) args
114114
| Tuple { label_opt; args } ->

asllib/aslspec/SpecParser.mly

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ let check_balanced_braces s =
4242
if not (scan 0 0) then
4343
let msg = Format.sprintf "unbalanced braces in string: %s" s in
4444
raise (SpecError msg)
45+
46+
(** Converts Menhir's [$sloc] pair into a [source_location] record. *)
47+
let loc (start_pos, end_pos) = { AST.start_pos; end_pos }
4548
%}
4649

4750
%type <AST.t> spec
@@ -167,7 +170,7 @@ let some(x) == ~ = x ; <Some>
167170
let terminated_by(x, y) == terminated(y, x)
168171

169172
(* Position annotation *)
170-
let annotated(x) == desc = x; { { desc; pos_start=$symbolstartpos; pos_end=$endpos } }
173+
let annotated(x) == desc = x; { { desc; pos_start=$symbolstartpos; pos_end=$endpos; version } }
171174

172175
(* ------------------------------------------------------------------------- *)
173176
(* Parameterized lists *)
@@ -225,7 +228,7 @@ let type_kind := TYPEDEF; { Term.TypeKind_Generic }
225228
let type_definition :=
226229
| ~=type_kind; type_name=IDENTIFIER; ~=type_attributes; ~=type_variants_with_attributes;
227230
{ check_definition_name type_name;
228-
Elem_Type (Type.make type_kind type_name type_variants_with_attributes type_attributes) }
231+
Elem_Type (Type.make (loc $loc) type_kind type_name type_variants_with_attributes type_attributes) }
229232
| type_kind; type_name=IDENTIFIER; type_attributes; list1(type_variant_with_attributes);
230233
{ let msg = Format.sprintf "Definition of 'typedef %s' is missing '='" type_name in
231234
raise (SpecError msg) }
@@ -234,13 +237,13 @@ let relation_definition :=
234237
~=relation_category; ~=relation_property; name=IDENTIFIER; input=plist0(opt_named_type_term); ARROW; output=type_variants;
235238
~=relation_attributes; ~=opt_relation_rule;
236239
{ check_definition_name name;
237-
Elem_Relation (Relation.make name relation_property relation_category input output relation_attributes opt_relation_rule) }
240+
Elem_Relation (Relation.make (loc $loc) name relation_property relation_category input output relation_attributes opt_relation_rule) }
238241

239242
let operator_definition :=
240243
~=is_variadic; OPERATOR; name=IDENTIFIER; ~=parameters; input=plist0(opt_named_type_term); ARROW; output=type_term;
241244
~=operator_attributes;
242245
{ check_definition_name name;
243-
Elem_Relation (Relation.make_operator name parameters input output is_variadic operator_attributes) }
246+
Elem_Relation (Relation.make_operator (loc $loc) name parameters input output is_variadic operator_attributes) }
244247

245248
let is_variadic :=
246249
| VARIADIC; { true }
@@ -252,7 +255,7 @@ let parameters :=
252255

253256
let constant_definition := CONSTANT; name=IDENTIFIER; ~=opt_type; att=type_attributes; ~=opt_value_and_attributes;
254257
{ check_definition_name name;
255-
Elem_Constant (Constant.make name opt_type opt_value_and_attributes att) }
258+
Elem_Constant (Constant.make (loc $loc) name opt_type opt_value_and_attributes att) }
256259

257260
let opt_type :=
258261
| { None }
@@ -347,22 +350,22 @@ let type_variants :=
347350
let type_variant := VDASH; term=type_term; { term }
348351

349352
let type_term_with_attributes := ~=type_term; ~=type_attributes;
350-
{ TypeVariant.make TypeKind_Generic type_term type_attributes }
353+
{ TypeVariant.make (loc $sloc) TypeKind_Generic type_term type_attributes }
351354

352355
let type_term :=
353-
| name=IDENTIFIER; { check_definition_name name; Label name }
354-
| op=type_operator; LPAR; ~=opt_named_type_term; RPAR; { Term.make_type_operation op opt_named_type_term }
355-
| LPAR; args=tclist1(opt_named_type_term); RPAR; { Tuple {label_opt = None; args} }
356+
| name=IDENTIFIER; { check_definition_name name; Term.make_label (loc $sloc) name }
357+
| op=type_operator; LPAR; ~=opt_named_type_term; RPAR; { Term.make_type_operation (loc $sloc) op opt_named_type_term }
358+
| LPAR; args=tclist1(opt_named_type_term); RPAR; { Term.make_tuple (loc $sloc) args }
356359
| label=IDENTIFIER; LPAR; args=tclist1(opt_named_type_term); RPAR;
357360
{ check_definition_name label;
358-
Tuple {label_opt = Some label; args} }
359-
| LBRACKET; fields=tclist1(record_field); RBRACKET; { Term.make_record fields }
361+
Term.make_labelled_tuple (loc $sloc) label args }
362+
| LBRACKET; fields=tclist1(record_field); RBRACKET; { Term.make_record (loc $sloc) fields }
360363
| label=IDENTIFIER; LBRACKET; fields=tclist1(record_field); RBRACKET;
361364
{ check_definition_name label;
362-
Term.make_labelled_record label fields }
363-
| CONSTANTS_SET; LPAR; constants=tclist1(IDENTIFIER); RPAR; { ConstantsSet constants }
364-
| FUN; from_type=opt_named_type_term; ARROW; to_type=opt_named_type_term; { Function {from_type; to_type; total = true}}
365-
| PARTIAL; from_type=opt_named_type_term; ARROW; to_type=opt_named_type_term; { Function {from_type; to_type; total = false}}
365+
Term.make_labelled_record (loc $sloc) label fields }
366+
| CONSTANTS_SET; LPAR; labels=tclist1(IDENTIFIER); RPAR; { ConstantsSet {loc=(loc $sloc); labels} }
367+
| FUN; from_type=opt_named_type_term; ARROW; to_type=opt_named_type_term; { Function {loc=(loc $sloc); from_type; to_type; total = true}}
368+
| PARTIAL; from_type=opt_named_type_term; ARROW; to_type=opt_named_type_term; { Function {loc=(loc $sloc); from_type; to_type; total = false}}
366369

367370
let type_operator :=
368371
| POWERSET; { Powerset }
@@ -379,7 +382,7 @@ let opt_named_type_term ==
379382
| ~=type_term; { (None, type_term) }
380383

381384
let record_field := ~=named_type_term; ~=type_attributes;
382-
{ Term.make_record_field named_type_term type_attributes }
385+
{ Term.make_record_field (loc $sloc) named_type_term type_attributes }
383386

384387
let math_layout :=
385388
| IDENTIFIER; { Unspecified }
@@ -391,7 +394,7 @@ let math_layout :=
391394
let render_types :=
392395
RENDER; name=IDENTIFIER; ~=render_types_attributes; EQ; pointers=clist1(type_subset_pointer);
393396
{ check_definition_name name;
394-
Elem_RenderTypes (TypesRender.make name pointers render_types_attributes) }
397+
Elem_RenderTypes (TypesRender.make (loc $sloc) name pointers render_types_attributes) }
395398

396399
let type_subset_pointer :=
397400
| type_name=IDENTIFIER; LPAR; MINUS; RPAR; { (type_name, []) }
@@ -427,35 +430,35 @@ let judgment :=
427430

428431
let index_judgement :=
429432
| INDEX; LPAR; index=IDENTIFIER; COMMA; list_var=IDENTIFIER; COLON; body=transition_expr; RPAR;
430-
{ Expr.Indexed { index; list_var; body } }
433+
{ Expr.Indexed { loc=(loc $sloc); index; list_var; body } }
431434

432-
let var_expr := id=IDENTIFIER; { Expr.make_var id }
435+
let var_expr := id=IDENTIFIER; { Expr.make_var (loc $sloc) id }
433436

434437
let expr :=
435438
| var_expr
436439
| args=plist1(expr);
437-
{ Expr.make_tuple args }
440+
{ Expr.make_tuple (loc $sloc) args }
438441
| lhs=expr; args=plist0(expr);
439-
{ Expr.make_application lhs args }
442+
{ Expr.make_application (loc $sloc) lhs args }
440443
| base=expr; DOT; field=IDENTIFIER;
441-
{ Expr.FieldAccess { base; field } }
444+
{ Expr.FieldAccess { loc=(loc $sloc); base; field } }
442445
| list_var=IDENTIFIER; LBRACKET; index=expr; RBRACKET;
443-
{ Expr.make_list_index list_var index }
446+
{ Expr.make_list_index (loc $sloc) list_var index }
444447
| label_opt=ioption(IDENTIFIER); LBRACKET; fields=tclist1(field_and_value); RBRACKET;
445-
{ Expr.make_record label_opt fields }
448+
{ Expr.make_record (loc $sloc) label_opt fields }
446449
| base=expr; LPAR; fields=tclist1(field_and_value); RPAR;
447-
{ Expr.make_record_update base fields }
450+
{ Expr.make_record_update (loc $sloc) base fields }
448451
| lhs=expr; ~=infix_expr_operator; rhs=expr;
449-
{ Expr.make_operator_application infix_expr_operator [lhs; rhs] }
452+
{ Expr.make_operator_application (loc $sloc) infix_expr_operator [lhs; rhs] }
450453
| IF; cond=expr; THEN; then_branch=expr; ELSE; else_branch=expr;
451-
{ Expr.make_operator_application "if_then_else" [cond; then_branch; else_branch] }
454+
{ Expr.make_operator_application (loc $sloc) "if_then_else" [cond; then_branch; else_branch] }
452455
| cond_expr
453456

454457
let cond_expr :=
455458
| COND; LPAR; cases=tclist1(cond_case); RPAR;
456-
{ Expr.make_operator_application "cond_op" cases }
459+
{ Expr.make_operator_application (loc $sloc) "cond_op" cases }
457460
let cond_case :=
458-
| condition=expr; COLON; result=expr; { Expr.make_operator_application "cond_case" [condition; result] }
461+
| condition=expr; COLON; result=expr; { Expr.make_operator_application (loc $sloc) "cond_case" [condition; result] }
459462

460463
let maybe_output_expr ==
461464
| { false }
@@ -464,25 +467,25 @@ let maybe_output_expr ==
464467
let judgment_expr :=
465468
| transition_expr
466469
| LPAR; ~=transition_expr; RPAR;
467-
{ Expr.make_tuple [ transition_expr ] }
470+
{ Expr.make_tuple (loc $sloc) [ transition_expr ] }
468471
| index_judgement
469472
| LPAR; ~=index_judgement; RPAR;
470-
{ Expr.make_tuple [ index_judgement ] }
473+
{ Expr.make_tuple (loc $sloc) [ index_judgement ] }
471474

472475
let transition_expr :=
473476
| lhs=expr; ARROW; rhs=transition_output_expr; ~=short_circuit;
474-
{ Expr.Transition { lhs; rhs; short_circuit } }
477+
{ Expr.Transition { loc=(loc $sloc); lhs; rhs; short_circuit } }
475478

476479
let transition_output_expr :=
477480
| var_expr
478481
| args=plist1(transition_output_expr);
479-
{ Expr.make_tuple args }
480-
| label=IDENTIFIER; args=plist1(transition_output_expr);
481-
{ Expr.make_application (Expr.make_var label) args }
482+
{ Expr.make_tuple (loc $sloc) args }
483+
| label_as_var=var_expr; args=plist1(transition_output_expr);
484+
{ Expr.make_application (loc $sloc) label_as_var args }
482485
| list_var=IDENTIFIER; LBRACKET; index=transition_output_expr; RBRACKET;
483-
{ Expr.make_list_index list_var index }
486+
{ Expr.make_list_index (loc $sloc) list_var index }
484487
| lhs=transition_output_expr; ~=infix_expr_operator; rhs=transition_output_expr;
485-
{ Expr.make_operator_application infix_expr_operator [lhs; rhs] }
488+
{ Expr.make_operator_application (loc $sloc) infix_expr_operator [lhs; rhs] }
486489

487490
let short_circuit :=
488491
| { None } (* Short-circuiting expressions will be inserted automatically. *)
@@ -492,10 +495,9 @@ let short_circuit :=
492495
{ Some alternatives }
493496

494497
let short_circuit_expr :=
495-
| id=IDENTIFIER;
496-
{ Expr.make_var id }
497-
| lhs=IDENTIFIER; args=plist0(IDENTIFIER);
498-
{ Expr.make_application (Expr.make_var lhs) (List.map Expr.make_var args) }
498+
| var_expr
499+
| lhs=var_expr; args=plist0(var_expr);
500+
{ Expr.make_application (loc $sloc) lhs args }
499501

500502
let infix_expr_operator ==
501503
| COLON_EQ; { "assign" }
@@ -528,9 +530,9 @@ let judgment_attribute :=
528530

529531
let render_rule :=
530532
| RENDER; RULE; name=IDENTIFIER; EQ; relation_name=IDENTIFIER; rule_name=pared(rule_name);
531-
{ check_definition_name name; Elem_RenderRule (RuleRender.make ~name ~relation_name rule_name) }
533+
{ check_definition_name name; Elem_RenderRule (RuleRender.make (loc $sloc) ~name ~relation_name rule_name) }
532534
| RENDER; RULE; name=IDENTIFIER;
533-
{ check_definition_name name; Elem_RenderRule (RuleRender.make ~name ~relation_name:name []) }
535+
{ check_definition_name name; Elem_RenderRule (RuleRender.make (loc $sloc) ~name ~relation_name:name []) }
534536
(** Stands for the entire rule for the given relation. *)
535537

536538
let rule_name :=

0 commit comments

Comments
 (0)