Summary: Expression language for new high-level IR. Reviewed By: jberdine Differential Revision: D4899313 fbshipit-source-id: 2aca792master
parent
e742d5bb7b
commit
0caac1aa93
@ -0,0 +1,93 @@
|
||||
(*
|
||||
* Copyright (c) 2017 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
|
||||
module F = Format
|
||||
module L = Logging
|
||||
|
||||
type t =
|
||||
| AccessPath of AccessPath.Raw.t
|
||||
| UnaryOperator of Unop.t * t * Typ.t option
|
||||
| BinaryOperator of Binop.t * t * t
|
||||
| Exception of t
|
||||
| Closure of Typ.Procname.t * (AccessPath.base * t) list
|
||||
| Constant of Const.t
|
||||
| Cast of Typ.t * t
|
||||
| Sizeof of Typ.t * t option
|
||||
[@@deriving compare]
|
||||
|
||||
let rec pp fmt = function
|
||||
| AccessPath access_path ->
|
||||
AccessPath.Raw.pp fmt access_path
|
||||
| UnaryOperator (op, e, _) ->
|
||||
F.fprintf fmt "%s%a" (Unop.str op) pp e
|
||||
| BinaryOperator(op, e1, e2) ->
|
||||
F.fprintf fmt "%a %s %a" pp e1 (Binop.str Pp.text op) pp e2
|
||||
| Exception e ->
|
||||
F.fprintf fmt "exception %a" pp e
|
||||
| Closure (pname, _) ->
|
||||
F.fprintf fmt "closure(%a)" Typ.Procname.pp pname
|
||||
| Constant c ->
|
||||
(Const.pp Pp.text) fmt c
|
||||
| Cast (typ, e) ->
|
||||
F.fprintf fmt "(%a) %a" (Typ.pp_full Pp.text) typ pp e
|
||||
| Sizeof (typ, length) ->
|
||||
let pp_length fmt = Option.iter ~f:(F.fprintf fmt "[%a]" pp) in
|
||||
F.fprintf fmt "sizeof(%a%a)" (Typ.pp_full Pp.text) typ pp_length length
|
||||
|
||||
let get_access_paths exp0 =
|
||||
let rec get_access_paths_ exp acc =
|
||||
match exp with
|
||||
| AccessPath ap ->
|
||||
ap :: acc
|
||||
| Cast (_, e) | UnaryOperator (_, e, _) | Exception e | Sizeof (_, Some e) ->
|
||||
get_access_paths_ e acc
|
||||
| BinaryOperator (_, e1, e2) ->
|
||||
get_access_paths_ e1 acc
|
||||
|> get_access_paths_ e2
|
||||
| Closure _ | Constant _ | Sizeof _ ->
|
||||
acc in
|
||||
get_access_paths_ exp0 []
|
||||
|
||||
(* convert an SIL expression into an HIL expression. the [lookup_id] function should map an SSA
|
||||
temporary variable to the access path it represents. evaluating the HIL expression should
|
||||
produce the same result as evaluating the SIL expression and replacing the temporary variables
|
||||
using [lookup_id] *)
|
||||
let rec of_sil ~lookup_id (exp : Exp.t) typ = match exp with
|
||||
| Var id ->
|
||||
let ap = match lookup_id (Var.of_id id) with
|
||||
| Some access_path -> access_path
|
||||
| None -> AccessPath.of_id id typ in
|
||||
AccessPath ap
|
||||
| UnOp (op, e, typ_opt) ->
|
||||
UnaryOperator (op, of_sil ~lookup_id e typ, typ_opt)
|
||||
| BinOp (op, e0, e1) ->
|
||||
BinaryOperator (op, of_sil ~lookup_id e0 typ, of_sil ~lookup_id e1 typ)
|
||||
| Exn e ->
|
||||
Exception (of_sil ~lookup_id e typ)
|
||||
| Const c ->
|
||||
Constant c
|
||||
| Cast (cast_typ, e) ->
|
||||
Cast (cast_typ, of_sil ~lookup_id e typ)
|
||||
| Sizeof (sizeof_typ, dynamic_length, _) ->
|
||||
Sizeof (sizeof_typ, Option.map ~f:(fun e -> of_sil ~lookup_id e typ) dynamic_length)
|
||||
| Closure closure ->
|
||||
let environment =
|
||||
List.map
|
||||
~f:(fun (value, pvar, typ) ->
|
||||
AccessPath.base_of_pvar pvar typ, of_sil ~lookup_id value typ)
|
||||
closure.captured_vars in
|
||||
Closure (closure.name, environment)
|
||||
| Lvar _ | Lfield _ | Lindex _ ->
|
||||
match AccessPath.of_lhs_exp exp typ ~f_resolve_id:lookup_id with
|
||||
| Some access_path ->
|
||||
AccessPath access_path
|
||||
| None ->
|
||||
failwithf "Couldn't convert var/field/index expression %a to access path" Exp.pp exp
|
@ -0,0 +1,41 @@
|
||||
(*
|
||||
* Copyright (c) 2017 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
|
||||
module F = Format
|
||||
|
||||
type t =
|
||||
| AccessPath of AccessPath.Raw.t
|
||||
(** access path (e.g., x.f.g or x[i]) *)
|
||||
| UnaryOperator of Unop.t * t * Typ.t option
|
||||
(** Unary operator with type of the result if known *)
|
||||
| BinaryOperator of Binop.t * t * t
|
||||
(** Binary operator *)
|
||||
| Exception of t
|
||||
(** Exception *)
|
||||
| Closure of Typ.Procname.t * (AccessPath.base * t) list
|
||||
(** Name of function + environment *)
|
||||
| Constant of Const.t
|
||||
(** Constants *)
|
||||
| Cast of Typ.t * t
|
||||
(** Type cast *)
|
||||
| Sizeof of Typ.t * t option
|
||||
(** C-style sizeof(), and also used to treate a type as an expression. Refer to [Exp] module for
|
||||
canonical documentation *)
|
||||
[@@deriving compare]
|
||||
|
||||
val pp : F.formatter -> t -> unit
|
||||
|
||||
(** Convert SIL expression to HIL expression *)
|
||||
val of_sil : lookup_id:(Var.t -> AccessPath.Raw.t option) -> Exp.t -> Typ.t -> t
|
||||
|
||||
(** Get all the access paths used in the given HIL expression, including duplicates if a path is
|
||||
used more than once. *)
|
||||
val get_access_paths : t -> AccessPath.Raw.t list
|
Loading…
Reference in new issue