Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the binary and bitstring types #277

Merged
merged 1 commit into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/bif.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ let string = Type.(of_elem (TyList (of_elem TyNumber)))
let pid = Type.(of_elem TyPid)
let port = Type.(of_elem TyPort)
let reference = Type.(of_elem TyReference)
let binary = Type.(of_elem (TyBitstring (0, 8)))
let bitstring = Type.(of_elem (TyBitstring (0, 1)))
let integer = Type.(of_elem TyNumber) (*TODO*)
let pos_integer = Type.(of_elem TyNumber) (*TODO*)
let non_neg_integer = Type.(of_elem TyNumber) (*TODO*)
let atom s = Type.(of_elem (TySingleton (Atom s)))
Expand Down Expand Up @@ -184,4 +187,12 @@ let type_sigs = [
Type.(of_elem (TyFun ([], reference))));
({module_name="erlang"; function_name="ref_to_list"; arity=1},
Type.(of_elem (TyFun ([reference], string))));

(* binary *)
({module_name="erlang"; function_name="binary_to_integer"; arity=1},
Type.(of_elem (TyFun ([binary], integer))));

(* bitstring *)
({module_name="erlang"; function_name="bit_size"; arity=1},
Type.(of_elem (TyFun ([bitstring], pos_integer))));
]
15 changes: 12 additions & 3 deletions lib/type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type t =
| TyFun of t list * t
| TyAnyMap
| TyPid | TyPort | TyReference
| TyBitstring of int * int (* TODO: change to non_neg_int * non_neg_int *)
[@@deriving sexp_of]

(* ref: http://erlang.org/doc/reference_manual/typespec.html *)
Expand All @@ -40,6 +41,7 @@ and pp_t_union_elem = function
| TyPid -> "pid()"
| TyPort -> "port()"
| TyReference -> "reference()"
| TyBitstring (m, n) -> Printf.sprintf "<<_:%d, _:_*%d>>" m n

let bool = TyUnion [TySingleton (Atom "true"); TySingleton (Atom "false")]
let of_elem e = TyUnion [e]
Expand All @@ -54,7 +56,8 @@ and variables_elem = function
| TyAtom
| TySingleton _
| TyAnyMap
| TyPid | TyPort | TyReference -> []
| TyPid | TyPort | TyReference
| TyBitstring _ -> []
| TyList t ->
variables t
| TyTuple ts ->
Expand Down Expand Up @@ -95,6 +98,9 @@ and sup_elems_to_list store = function
| TyReference :: ty1s ->
let store' = List.filter ~f:(function TyReference -> false | _ -> true) store in
sup_elems_to_list (TyReference :: store') ty1s
| TyBitstring (m, n) :: ty1s ->
let store' = List.filter ~f:(function TyBitstring (m', n') -> m = m' && n = n' | _ -> true) store in
sup_elems_to_list (TyBitstring (m, n) :: store') ty1s
| TySingleton (Number n) :: ty1s when List.exists ~f:((=) TyNumber) store ->
sup_elems_to_list store ty1s
| TySingleton (Number n) :: ty1s ->
Expand Down Expand Up @@ -220,6 +226,7 @@ and subst_elem (v, ty0) = function
| TyPid -> TyUnion [TyPid]
| TyPort -> TyUnion [TyPort]
| TyReference -> TyUnion [TyReference]
| TyBitstring (m, n) -> TyUnion [TyBitstring (m, n)]

let solve_constraints_map map =
let subst_all (v, expr) l =
Expand Down Expand Up @@ -303,8 +310,10 @@ let rec of_absform = function
of_elem TyPort
| F.TyPredef {name="reference"; args=[]; _} ->
of_elem TyReference
| F.TyPredef {name="binary"; args=[]; _}
| F.TyPredef {name="bitstring"; args=[]; _}
| F.TyPredef {name="binary"; args=[]; _} ->
of_elem (TyBitstring (0, 8))
| F.TyPredef {name="bitstring"; args=[]; _} ->
of_elem (TyBitstring (0, 1))
| F.TyPredef {name="byte"; args=[]; _}
| F.TyPredef {name="char"; args=[]; _}
| F.TyPredef {name="iodata"; args=[]; _}
Expand Down
Binary file added test/blackbox-test/minimal.plt
Binary file not shown.
6 changes: 6 additions & 0 deletions test/blackbox-test/test-cases/binary_bitstring_error.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-module(binary_bitstring_error).
-export([main/1]).

main(X) ->
_ = binary_to_integer(X), %% binary -> integer.
_ = bit_size(X). %% bitstring -> integer >= 0.
4 changes: 4 additions & 0 deletions test/blackbox-test/test-cases/binary_bitstring_error.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TODO:filename:5: Type error: type mismatch;
found : <<_:0, _:_*1>>
required: <<_:0, _:_*8>>
there is no solution that satisfies subtype constraints