diff --git a/src/frontend/Ast.ml b/src/frontend/Ast.ml index b1ed952251..d0dbfb617c 100644 --- a/src/frontend/Ast.ml +++ b/src/frontend/Ast.ml @@ -296,7 +296,9 @@ let rec id_of_lvalue {lval; _} = token before the current statement and all the whitespace between two statements appears as if it were part of the second statement. get_first_loc tries to skip the leading whitespace and approximate the location - of the first token in the statement. *) + of the first token in the statement. + TODO: See if $sloc works better than $loc for this +*) let rec get_loc_expr (e : untyped_expression) = match e.expr with diff --git a/src/frontend/Input_warnings.ml b/src/frontend/Input_warnings.ml index 24549667f8..ebeb65c9c5 100644 --- a/src/frontend/Input_warnings.ml +++ b/src/frontend/Input_warnings.ml @@ -19,3 +19,19 @@ let deprecated token (pos, message) = Middle.Location_span.of_positions_opt begin_pos end_pos |> Option.value ~default:Middle.Location_span.empty in add_warning span message + +let drop_array_future () = + match !warnings with + | ( _ + , "Variable name 'array' will be a reserved word starting in Stan 2.32.0. \ + Please rename it!" ) + :: tl -> + warnings := tl + | _ -> () + +let future_keyword kwrd version (pos1, pos2) = + add_warning + (Option.value ~default:Middle.Location_span.empty + (Middle.Location_span.of_positions_opt pos1 pos2) ) + ( "Variable name '" ^ kwrd ^ "' will be a reserved word starting in Stan " + ^ version ^ ". Please rename it!" ) diff --git a/src/frontend/Input_warnings.mli b/src/frontend/Input_warnings.mli index b11857c392..a198b629ce 100644 --- a/src/frontend/Input_warnings.mli +++ b/src/frontend/Input_warnings.mli @@ -17,3 +17,12 @@ val deprecated : string -> Lexing.position * string -> unit val empty : string -> unit (** Register that an empty file is being lexxed *) + +val future_keyword : + string -> string -> Lexing.position * Lexing.position -> unit +(** Warn on a keyword which will be reserved in the future*) + +val drop_array_future : unit -> unit +(** Hack: Remove the most recent warning about array as a future keyword. + Needed due to the {e other} hack of how we currently parse arrays. +*) diff --git a/src/frontend/parser.mly b/src/frontend/parser.mly index d4fce160ae..23dd7bd9aa 100644 --- a/src/frontend/parser.mly +++ b/src/frontend/parser.mly @@ -21,6 +21,11 @@ let rec iterate_n f x = function | n -> iterate_n f (f x) (n - 1) let nest_unsized_array basic_type n = iterate_n (fun t -> UnsizedType.UArray t) basic_type n + +(* $sloc and $symbolstartpos generates code using !=, which + Core_kernel considers to be an error. + *) +let (!=) = Stdlib.(!=) %} %token FUNCTIONBLOCK DATABLOCK TRANSFORMEDDATABLOCK PARAMETERSBLOCK @@ -93,7 +98,7 @@ program: let () = match (ofb, odb, otdb, opb, otpb, omb, ogb) with | None, None, None, None, None, None, None -> - Input_warnings.empty (fst $loc).pos_fname + Input_warnings.empty ($startpos).pos_fname | _ -> () in { functionblock= ofb @@ -160,11 +165,19 @@ generated_quantities_block: identifier: | id=IDENTIFIER { build_id id $loc } | TRUNCATE { build_id "T" $loc} - | OFFSET { build_id "offset" $loc} - | MULTIPLIER { build_id "multiplier" $loc} - | LOWER { build_id "lower" $loc} - | UPPER { build_id "upper" $loc} - | ARRAY { build_id "array" $loc} + | id_and_v = future_keyword + { + let id, v = id_and_v in + Input_warnings.future_keyword id.name v $loc; + id + } + +future_keyword: + | OFFSET { build_id "offset" $loc, "2.32.0" } + | MULTIPLIER { build_id "multiplier" $loc, "2.32.0" } + | LOWER { build_id "lower" $loc, "2.32.0" } + | UPPER { build_id "upper" $loc, "2.32.0" } + | ARRAY { build_id "array" $loc, "2.32.0" } decl_identifier: | id=identifier { id } @@ -342,6 +355,7 @@ decl(type_rule, rhs): in let dims = match dims_opt with | Some ({expr= Indexed ({expr= Variable {name="array"; _}; _}, ixs); _}) -> + Input_warnings.drop_array_future () ; (match int_ixs ixs with | Some sizes -> sizes | None -> error "Dimensions should be expressions, not multiple or range indexing.") @@ -358,27 +372,7 @@ decl(type_rule, rhs): ; is_global } ; smeta= { - loc= - (* From the docs: - We remark that, if the current production has an empty right-hand side, - then $startpos and $endpos are equal, and (by convention) are the end - position of the most recently parsed symbol (that is, the symbol that - happens to be on top of the automaton’s stack when this production is - reduced). If the current production has a nonempty right-hand side, - then $startpos is the same as $startpos($1) and $endpos is the same - as $endpos($n), where n is the length of the right-hand side. - - - So when dims_opt is empty, it uses the preview token as its startpos, - but that makes the whole declaration think it starts at the previous - token. Sadly, $sloc and $symbolstartpos generates code using !=, which - Core_kernel considers to be an error. - *) - let startpos = match dims_opt with - | None -> $startpos(ty) - | Some _ -> $startpos - in - Location_span.of_positions_exn (startpos, $endpos) + loc= Location_span.of_positions_exn $sloc } }) )} diff --git a/test/integration/bad/lang/stanc.expected b/test/integration/bad/lang/stanc.expected index fd55ade1df..324bfb20ed 100644 --- a/test/integration/bad/lang/stanc.expected +++ b/test/integration/bad/lang/stanc.expected @@ -630,6 +630,8 @@ Syntax error in 'incomplete.stan', line 2, column 18 to column 19, parsing error Found an incomplete binary expression - are you missing the right hand side? $ ../../../../../install/default/bin/stanc incomplete2.stan +Warning in 'incomplete2.stan', line 2, column 9: Variable name 'upper' will + be a reserved word starting in Stan 2.32.0. Please rename it! Syntax error in 'incomplete2.stan', line 2, column 17 to column 22, parsing error: ------------------------------------------------- 1: transformed data { @@ -679,6 +681,8 @@ Syntax error in 'incomplete5.stan', line 3, column 0 to column 0, parsing error: Ill-formed block. Expected a statement, variable declaration, or just "}". $ ../../../../../install/default/bin/stanc incomplete6.stan +Warning in 'incomplete6.stan', line 2, column 8: Variable name 'upper' will + be a reserved word starting in Stan 2.32.0. Please rename it! Syntax error in 'incomplete6.stan', line 3, column 16 to column 21, parsing error: ------------------------------------------------- 1: transformed data { diff --git a/test/integration/bad/new/stanc.expected b/test/integration/bad/new/stanc.expected index a1ff7a582a..7ec7342b20 100644 --- a/test/integration/bad/new/stanc.expected +++ b/test/integration/bad/new/stanc.expected @@ -1198,6 +1198,9 @@ Syntax error in 'ill-formed-statement23.stan', line 1, column 35 to column 39, p Ill-formed statement. Expected statement after "else". $ ../../../../../install/default/bin/stanc ill-formed-statement24.stan +Warning in 'ill-formed-statement24.stan', line 1, column 30: Variable name + 'upper' will be a reserved word starting in Stan 2.32.0. Please rename + it! Syntax error in 'ill-formed-statement24.stan', line 1, column 35 to column 36, parsing error: ------------------------------------------------- 1: transformed data { if ( 1 ) ; upper} @@ -1214,6 +1217,9 @@ Syntax error in 'ill-formed-statement25.stan', line 1, column 34 to column 38, p Ill-formed statement. Expected statement after else. $ ../../../../../install/default/bin/stanc ill-formed-statement26.stan +Warning in 'ill-formed-statement26.stan', line 1, column 29: Variable name + 'upper' will be a reserved word starting in Stan 2.32.0. Please rename + it! Syntax error in 'ill-formed-statement26.stan', line 1, column 34 to column 34, parsing error: ------------------------------------------------- 1: transformed data { if ( T) ; upper diff --git a/test/integration/good/pretty.expected b/test/integration/good/pretty.expected index 4ed973431b..aa1bf602b3 100644 --- a/test/integration/good/pretty.expected +++ b/test/integration/good/pretty.expected @@ -3023,6 +3023,11 @@ Warning in 'deprecated_syntax.stan', line 40, column 2: increment_log_prob(...); Warning in 'deprecated_syntax.stan', line 42, column 11: get_lp() function is deprecated. It will be removed in Stan 2.32.0. Use target() instead. This can be done automatically with stanc --print-canonical +Warning in 'deprecated_syntax.stan', line 46, column 6: Variable name + 'offset' will be a reserved word starting in Stan 2.32.0. Please rename + it! +Warning in 'deprecated_syntax.stan', line 47, column 6: Variable name 'array' + will be a reserved word starting in Stan 2.32.0. Please rename it! Warning in 'deprecated_syntax.stan', line 51, column 2: Comments beginning with # are deprecated and this syntax will be removed in Stan 2.32.0. Use // to begin line comments; this can be done automatically using stanc @@ -3942,6 +3947,14 @@ data { int offset; } +Warning in 'identifiers.stan', line 2, column 6: Variable name 'upper' will + be a reserved word starting in Stan 2.32.0. Please rename it! +Warning in 'identifiers.stan', line 3, column 6: Variable name 'lower' will + be a reserved word starting in Stan 2.32.0. Please rename it! +Warning in 'identifiers.stan', line 4, column 6: Variable name 'multiplier' + will be a reserved word starting in Stan 2.32.0. Please rename it! +Warning in 'identifiers.stan', line 5, column 6: Variable name 'offset' will + be a reserved word starting in Stan 2.32.0. Please rename it! $ ../../../../install/default/bin/stanc --auto-format if-else-formatting.stan generated quantities { // make sure pp_recursive_ifthenelse properly places else @@ -6289,6 +6302,15 @@ model { array[1, 2, 3] real abc; } +Warning in 'unreserved-array-keyword.stan', line 2, column 24: Variable name + 'array' will be a reserved word starting in Stan 2.32.0. Please rename + it! +Warning in 'unreserved-array-keyword.stan', line 2, column 40: Variable name + 'array' will be a reserved word starting in Stan 2.32.0. Please rename + it! +Warning in 'unreserved-array-keyword.stan', line 6, column 7: Variable name + 'array' will be a reserved word starting in Stan 2.32.0. Please rename + it! $ ../../../../install/default/bin/stanc --auto-format user-defined-lpdf-fun.stan functions { real bar_lpmf(int y, real z) {