From 849c49280f8e2d1f924a41d5afcf11b18b3aa421 Mon Sep 17 00:00:00 2001 From: Akos Hajdu Date: Tue, 8 Jun 2021 01:21:36 -0700 Subject: [PATCH] [erl-frontend] make guard sequence expression list list Summary: Adapted the AST to reflect the official [documentation](https://erlang.org/doc/apps/erts/absform.html): a clause can have a *guard sequence*, which is a list of *guards*. Each *guard* is a list of *guard tests*. A *guard test* is a (restricted) expression. Therefore, in the AST we now have `guard_test = expression`, and a clause has `guard_test list list`. Furthermore, the JSON translator simply applies `to_expression` to the 2D list, instead of flattening one level with `andalso`. Using `andalso` to flatten was wrong because it handles exceptions differently, see [note](https://learnyousomeerlang.com/syntax-in-functions#guards-guards). Reviewed By: rgrig Differential Revision: D28936558 fbshipit-source-id: 510930998 --- infer/src/erlang/ErlangAst.ml | 4 ++-- infer/src/erlang/ErlangJsonParser.ml | 18 ++++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/infer/src/erlang/ErlangAst.ml b/infer/src/erlang/ErlangAst.ml index 48fa11862..a1871cbe2 100644 --- a/infer/src/erlang/ErlangAst.ml +++ b/infer/src/erlang/ErlangAst.ml @@ -113,11 +113,11 @@ and association = {kind: association_kind; key: expression; value: expression} and pattern = expression -and guard = expression +and guard_test = expression (** {2 S8.5 Clauses} *) -and 'pat clause = {line: line; patterns: 'pat list; guards: guard list; body: body} +and 'pat clause = {line: line; patterns: 'pat list; guards: guard_test list list; body: body} and case_clause = pattern clause diff --git a/infer/src/erlang/ErlangJsonParser.ml b/infer/src/erlang/ErlangJsonParser.ml index acae5a040..41b7da599 100644 --- a/infer/src/erlang/ErlangJsonParser.ml +++ b/infer/src/erlang/ErlangJsonParser.ml @@ -432,19 +432,9 @@ and to_catch_pattern json : Ast.catch_pattern option = unknown "catch_pattern" json -and to_guards line json : Ast.expression list option = - let andalso e1 e2 = {Ast.line; simple_expression= BinaryOperator (e1, AndAlso, e2)} in - let to_dnf_term xs = - let* atom_guards = to_list ~f:to_expression (one_list xs) in - match atom_guards with - | [] -> - unknown "empty_guard?" json - | [e] -> - Some e - | e :: es -> - Some (List.fold ~init:e ~f:andalso es) - in - json |> one_list |> to_list ~f:to_dnf_term +and to_guards json : Ast.expression list list option = + let to_guard xs = to_list ~f:to_expression xs in + to_list ~f:to_guard json and to_clause : 'pat. 'pat parser -> 'pat Ast.clause parser = @@ -453,7 +443,7 @@ and to_clause : 'pat. 'pat parser -> 'pat Ast.clause parser = | `List [`String "clause"; anno; patterns; guards; body] -> let* line = to_line anno in let* patterns = to_list ~f:to_pat patterns in - let* guards = to_guards line guards in + let* guards = to_guards guards in let body = one_list body in let* body = to_body body in Some {Ast.line; patterns; guards; body}