diff --git a/AST.ml b/AST.ml index e34624bc7..82d4394c2 100644 --- a/AST.ml +++ b/AST.ml @@ -505,6 +505,7 @@ and expr = | ESet of set_expr | EConstr of constr_expr | ERecord of record_expr +| EProj of projection reg | EMap of map_expr | EVar of Lexer.lexeme reg | ECall of fun_call @@ -542,8 +543,8 @@ and map_lookup = { } and path = - Name of variable -| RecordPath of record_projection reg + Name of variable +| Path of projection reg and logic_expr = BoolExpr of bool_expr @@ -612,8 +613,7 @@ and constr_expr = | ConstrApp of (constr * arguments) reg and record_expr = - RecordInj of record_injection reg -| RecordProj of record_projection reg + RecordInj of record_injection reg and record_injection = { opening : kwd_record; @@ -628,14 +628,18 @@ and field_assign = { field_expr : expr } -and record_projection = { +and projection = { record_name : variable; selector : dot; - field_path : (field_name, dot) nsepseq + field_path : (selection, dot) nsepseq } +and selection = + FieldName of field_name +| Component of (Lexer.lexeme * Z.t) reg + and tuple_expr = - TupleInj of tuple_injection + TupleInj of tuple_injection and tuple_injection = (expr, comma) nsepseq par reg @@ -694,6 +698,7 @@ let rec expr_to_region = function | ERecord e -> record_expr_to_region e | EMap e -> map_expr_to_region e | ETuple e -> tuple_expr_to_region e +| EProj {region; _} | EVar {region; _} | ECall {region; _} | EBytes {region; _} @@ -754,12 +759,11 @@ and constr_expr_to_region = function | SomeApp {region; _} -> region and record_expr_to_region = function - RecordInj {region; _} -| RecordProj {region; _} -> region + RecordInj {region; _} -> region let path_to_region = function Name var -> var.region -| RecordPath {region; _} -> region +| Path {region; _} -> region let instr_to_region = function Single Cond {region; _} @@ -805,7 +809,7 @@ let local_decl_to_region = function | LocalConst {region; _} | LocalVar {region; _} -> region -let lhs_to_region = function +let lhs_to_region : lhs -> Region.t = function Path path -> path_to_region path | MapPath {region; _} -> region @@ -813,6 +817,10 @@ let rhs_to_region = function Expr e -> expr_to_region e | NoneExpr r -> r +let selection_to_region = function + FieldName {region; _} +| Component {region; _} -> region + (* Printing the tokens with their source regions *) let printf = Printf.printf @@ -1215,6 +1223,7 @@ and print_expr = function | ESet e -> print_set_expr e | EConstr e -> print_constr_expr e | ERecord e -> print_record_expr e +| EProj e -> print_projection e | EMap e -> print_map_expr e | EVar v -> print_var v | ECall e -> print_fun_call e @@ -1245,8 +1254,8 @@ and print_map_lookup {path; index} = print_token rbracket "]" and print_path = function - Name var -> print_var var -| RecordPath path -> print_record_projection path + Name var -> print_var var +| Path path -> print_projection path and print_logic_expr = function BoolExpr e -> print_bool_expr e @@ -1308,8 +1317,7 @@ and print_constr_expr = function | ConstrApp e -> print_constr_app e and print_record_expr = function - RecordInj e -> print_record_injection e -| RecordProj e -> print_record_projection e + RecordInj e -> print_record_injection e and print_record_injection {value; _} = let {opening; fields; terminator; closing} = value in @@ -1324,14 +1332,18 @@ and print_field_assign {value; _} = print_token equal "="; print_expr field_expr -and print_record_projection {value; _} = +and print_projection {value; _} = let {record_name; selector; field_path} = value in print_var record_name; print_token selector "."; print_field_path field_path and print_field_path sequence = - print_nsepseq "." print_var sequence + print_nsepseq "." print_selection sequence + +and print_selection = function + FieldName name -> print_var name +| Component int -> print_int int and print_record_patch node = let {kwd_patch; path; kwd_with; record_inj} = node in diff --git a/AST.mli b/AST.mli index 02efd31ef..405f68f92 100644 --- a/AST.mli +++ b/AST.mli @@ -489,6 +489,7 @@ and expr = | ESet of set_expr | EConstr of constr_expr | ERecord of record_expr +| EProj of projection reg | EMap of map_expr | EVar of Lexer.lexeme reg | ECall of fun_call @@ -526,8 +527,8 @@ and map_lookup = { } and path = - Name of variable -| RecordPath of record_projection reg + Name of variable +| Path of projection reg and logic_expr = BoolExpr of bool_expr @@ -596,8 +597,7 @@ and constr_expr = | ConstrApp of (constr * arguments) reg and record_expr = - RecordInj of record_injection reg -| RecordProj of record_projection reg + RecordInj of record_injection reg and record_injection = { opening : kwd_record; @@ -612,12 +612,16 @@ and field_assign = { field_expr : expr } -and record_projection = { +and projection = { record_name : variable; selector : dot; - field_path : (field_name, dot) nsepseq + field_path : (selection, dot) nsepseq } +and selection = + FieldName of field_name +| Component of (Lexer.lexeme * Z.t) reg + and tuple_expr = TupleInj of tuple_injection @@ -667,6 +671,7 @@ val path_to_region : path -> Region.t val lhs_to_region : lhs -> Region.t val rhs_to_region : rhs -> Region.t val if_clause_to_region : if_clause -> Region.t +val selection_to_region : selection -> Region.t (* Printing *) diff --git a/Parser.mly b/Parser.mly index 35c5dceb1..ddce8306e 100644 --- a/Parser.mly +++ b/Parser.mly @@ -936,6 +936,7 @@ core_expr: | fun_call { ECall $1 } | map_expr { EMap $1 } | record_expr { ERecord $1 } +| projection { EProj $1 } | Constr arguments { let region = cover $1.region $2.region in EConstr (ConstrApp {region; value = $1,$2}) @@ -948,20 +949,32 @@ core_expr: map_expr: map_lookup { MapLookUp $1 } -path: - var { Name $1 } -| record_projection { RecordPath $1 } - map_lookup: path brackets(expr) { let region = cover (path_to_region $1) $2.region in let value = {path=$1; index=$2} - in {region; value} - } + in {region; value}} + +path: + var { Name $1 } +| projection { Path $1 } record_expr: - record_injection { RecordInj $1 } -| record_projection { RecordProj $1 } + record_injection { RecordInj $1 } + +projection: + record_name DOT nsepseq(selection,DOT) { + let stop = nsepseq_to_region selection_to_region $3 in + let region = cover $1.region stop + and value = { + record_name = $1; + selector = $2; + field_path = $3} + in {region; value}} + +selection: + field_name { FieldName $1 } +| Int { Component $1 } record_injection: Record series(field_assignment,End) { @@ -972,8 +985,7 @@ record_injection: fields = first, others; terminator; closing} - in {region; value} - } + in {region; value}} field_assignment: field_name EQUAL expr { @@ -985,17 +997,6 @@ field_assignment: in {region; value} } -record_projection: - record_name DOT nsepseq(field_name,DOT) { - let stop = nsepseq_to_region (fun x -> x.region) $3 in - let region = cover $1.region stop - and value = { - record_name = $1; - selector = $2; - field_path = $3} - in {region; value} - } - fun_call: fun_name arguments { let region = cover $1.region $2.region @@ -1050,8 +1051,7 @@ list_expr: elements = None; terminator = None; closing = RBracket $3} - in {region; value} - } + in {region; value}} nil: par(typed_empty_list) { $1 } @@ -1060,8 +1060,7 @@ typed_empty_list: Nil COLON type_expr { {nil = $1; colon = $2; - list_type = $3} - } + list_type = $3}} none_expr: par(typed_none_expr) { $1 } @@ -1070,8 +1069,7 @@ typed_none_expr: C_None COLON type_expr { {c_None = $1; colon = $2; - opt_type = $3} - } + opt_type = $3}} (* Patterns *) @@ -1094,8 +1092,7 @@ core_pattern: | tuple_patt { PTuple $1 } | C_Some par(core_pattern) { let region = cover $1 $2.region - in PSome {region; value = $1,$2} - } + in PSome {region; value = $1,$2}} list_patt: brackets(sepseq(core_pattern,COMMA)) { Sugar $1 }