2019-05-23 19:43:18 +04:00
|
|
|
module Typer = struct
|
|
|
|
|
|
|
|
open Trace
|
|
|
|
open Ast_typed
|
|
|
|
|
|
|
|
module Errors = struct
|
|
|
|
let wrong_param_number = fun name expected got ->
|
|
|
|
let title () = "wrong number of params" in
|
|
|
|
let full () = Format.asprintf "constant name: %s\nexpected: %d\ngot: %d\n"
|
|
|
|
name expected (List.length got) in
|
|
|
|
error title full
|
|
|
|
|
2019-06-05 21:16:54 +04:00
|
|
|
let error_uncomparable_types a b () =
|
|
|
|
let title () = "these types are not comparable" in
|
|
|
|
let message () = "" in
|
|
|
|
let data = [
|
|
|
|
("a" , fun () -> Format.asprintf "%a" PP.type_value a) ;
|
|
|
|
("b" , fun () -> Format.asprintf "%a" PP.type_value b )
|
|
|
|
] in
|
|
|
|
error ~data title message ()
|
|
|
|
end
|
|
|
|
open Errors
|
2019-05-23 19:43:18 +04:00
|
|
|
|
|
|
|
type type_result = string * type_value
|
|
|
|
type typer' = type_value list -> type_value option -> type_result result
|
|
|
|
type typer = string * typer'
|
|
|
|
|
|
|
|
let typer'_0 : name -> (type_value option -> type_value result) -> typer' = fun s f lst tv_opt ->
|
|
|
|
match lst with
|
|
|
|
| [] -> (
|
|
|
|
let%bind tv' = f tv_opt in
|
|
|
|
ok (s , tv')
|
|
|
|
)
|
2019-06-05 21:16:54 +04:00
|
|
|
| _ -> fail @@ wrong_param_number s 0 lst
|
2019-05-23 19:43:18 +04:00
|
|
|
let typer_0 name f : typer = (name , typer'_0 name f)
|
|
|
|
|
|
|
|
let typer'_1 : name -> (type_value -> type_value result) -> typer' = fun s f lst _ ->
|
|
|
|
match lst with
|
|
|
|
| [ a ] -> (
|
|
|
|
let%bind tv' = f a in
|
|
|
|
ok (s , tv')
|
|
|
|
)
|
2019-06-05 21:16:54 +04:00
|
|
|
| _ -> fail @@ wrong_param_number s 1 lst
|
2019-05-23 19:43:18 +04:00
|
|
|
let typer_1 name f : typer = (name , typer'_1 name f)
|
|
|
|
|
|
|
|
let typer'_1_opt : name -> (type_value -> type_value option -> type_value result) -> typer' = fun s f lst tv_opt ->
|
|
|
|
match lst with
|
|
|
|
| [ a ] -> (
|
|
|
|
let%bind tv' = f a tv_opt in
|
|
|
|
ok (s , tv')
|
|
|
|
)
|
2019-06-05 21:16:54 +04:00
|
|
|
| _ -> fail @@ wrong_param_number s 1 lst
|
2019-05-23 19:43:18 +04:00
|
|
|
let typer_1_opt name f : typer = (name , typer'_1_opt name f)
|
|
|
|
|
|
|
|
let typer'_2 : name -> (type_value -> type_value -> type_value result) -> typer' = fun s f lst _ ->
|
|
|
|
match lst with
|
|
|
|
| [ a ; b ] -> (
|
|
|
|
let%bind tv' = f a b in
|
|
|
|
ok (s , tv')
|
|
|
|
)
|
2019-06-05 21:16:54 +04:00
|
|
|
| _ -> fail @@ wrong_param_number s 2 lst
|
2019-05-23 19:43:18 +04:00
|
|
|
let typer_2 name f : typer = (name , typer'_2 name f)
|
|
|
|
|
|
|
|
let typer'_3 : name -> (type_value -> type_value -> type_value -> type_value result) -> typer' = fun s f lst _ ->
|
|
|
|
match lst with
|
|
|
|
| [ a ; b ; c ] -> (
|
|
|
|
let%bind tv' = f a b c in
|
|
|
|
ok (s , tv')
|
|
|
|
)
|
2019-06-05 21:16:54 +04:00
|
|
|
| _ -> fail @@ wrong_param_number s 3 lst
|
2019-05-23 19:43:18 +04:00
|
|
|
let typer_3 name f : typer = (name , typer'_3 name f)
|
|
|
|
|
|
|
|
let constant name cst = typer_0 name (fun _ -> ok cst)
|
|
|
|
|
|
|
|
open Combinators
|
|
|
|
|
|
|
|
let eq_1 a cst = type_value_eq (a , cst)
|
|
|
|
let eq_2 (a , b) cst = type_value_eq (a , cst) && type_value_eq (b , cst)
|
|
|
|
|
|
|
|
let comparator : string -> typer = fun s -> typer_2 s @@ fun a b ->
|
|
|
|
let%bind () =
|
2019-06-05 21:16:54 +04:00
|
|
|
trace_strong (error_uncomparable_types a b) @@
|
2019-05-23 19:43:18 +04:00
|
|
|
Assert.assert_true @@
|
|
|
|
List.exists (eq_2 (a , b)) [
|
|
|
|
t_int () ;
|
|
|
|
t_nat () ;
|
|
|
|
t_tez () ;
|
|
|
|
t_string () ;
|
|
|
|
t_bytes () ;
|
|
|
|
t_address () ;
|
2019-06-11 02:06:00 +04:00
|
|
|
t_timestamp () ;
|
2019-05-23 19:43:18 +04:00
|
|
|
] in
|
|
|
|
ok @@ t_bool ()
|
|
|
|
|
|
|
|
let boolean_operator_2 : string -> typer = fun s -> typer_2 s @@ fun a b ->
|
|
|
|
let%bind () =
|
|
|
|
trace_strong (simple_error "A isn't of type bool") @@
|
|
|
|
Assert.assert_true @@
|
|
|
|
type_value_eq (t_bool () , a) in
|
|
|
|
let%bind () =
|
|
|
|
trace_strong (simple_error "B isn't of type bool") @@
|
|
|
|
Assert.assert_true @@
|
|
|
|
type_value_eq (t_bool () , b) in
|
|
|
|
ok @@ t_bool ()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
module Compiler = struct
|
|
|
|
|
|
|
|
open Tezos_utils.Michelson
|
|
|
|
|
|
|
|
type predicate =
|
|
|
|
| Constant of michelson
|
|
|
|
| Unary of michelson
|
|
|
|
| Binary of michelson
|
|
|
|
| Ternary of michelson
|
|
|
|
let simple_constant c = Constant c
|
|
|
|
let simple_unary c = Unary c
|
|
|
|
let simple_binary c = Binary c
|
|
|
|
let simple_ternary c = Ternary c
|
|
|
|
end
|