From 7143b82ba88c1f860da0349d9dce85fc6b21bc31 Mon Sep 17 00:00:00 2001
From: Lesenechal Remi <lesenechal.remi@gmail.com>
Date: Mon, 13 Jan 2020 11:37:10 +0100
Subject: [PATCH] support for key and signature literals

---
 .../docs/advanced/timestamps-addresses.md     | 41 +++++++++++++++++++
 src/bin/expect_tests/literals.ml              | 37 +++++++++++++++++
 src/passes/3-self_ast_simplified/literals.ml  | 14 +++++++
 .../tezos_type_annotation.ml                  |  2 +
 src/passes/6-transpiler/untranspiler.ml       | 20 +++++----
 src/passes/8-compiler/uncompiler.ml           |  2 +
 src/stages/common/PP.ml                       |  2 +-
 7 files changed, 109 insertions(+), 9 deletions(-)
 create mode 100644 src/bin/expect_tests/literals.ml

diff --git a/gitlab-pages/docs/advanced/timestamps-addresses.md b/gitlab-pages/docs/advanced/timestamps-addresses.md
index adc11a833..bbd17e2c2 100644
--- a/gitlab-pages/docs/advanced/timestamps-addresses.md
+++ b/gitlab-pages/docs/advanced/timestamps-addresses.md
@@ -71,3 +71,44 @@ const my_account: address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address);
 ```
 <!--END_DOCUSAURUS_CODE_TABS-->
 
+## Signatures
+
+`signature` is a LIGO datatype used for Tezos signature (edsig, spsig).
+
+Here's how you can define a signature:
+
+<!--DOCUSAURUS_CODE_TABS-->
+<!--Pascaligo-->
+```pascaligo group=e
+const my_signature: signature = ("edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7": signature);
+```
+<!--CameLIGO-->
+```cameligo group=e
+let my_signature: signature = ("edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7": signature)
+```
+<!--ReasonLIGO-->
+```reasonligo group=e
+let my_signature: signature = ("edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7": signature);
+```
+<!--END_DOCUSAURUS_CODE_TABS-->
+
+## keys
+
+`key` is a LIGO datatype used for Tezos public key.
+
+Here's how you can define a key:
+
+<!--DOCUSAURUS_CODE_TABS-->
+<!--Pascaligo-->
+```pascaligo group=f
+const my_key: key = ("edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav": key);
+```
+<!--CameLIGO-->
+```cameligo group=f
+let my_key: key = ("edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav": key)
+```
+<!--ReasonLIGO-->
+```reasonligo group=f
+let my_key: key = ("edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav": key);
+```
+<!--END_DOCUSAURUS_CODE_TABS-->
\ No newline at end of file
diff --git a/src/bin/expect_tests/literals.ml b/src/bin/expect_tests/literals.ml
new file mode 100644
index 000000000..9d945c4d0
--- /dev/null
+++ b/src/bin/expect_tests/literals.ml
@@ -0,0 +1,37 @@
+open Cli_expect
+
+let%expect_test _ =
+  run_ligo_good ["interpret" ; "(\"edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7\":signature)" ; "--syntax=pascaligo"] ;
+  [%expect {| signature edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7 |}]
+
+let%expect_test _ =
+  run_ligo_bad ["interpret" ; "(\"thisisnotasignature\":signature)" ; "--syntax=pascaligo"] ;
+  [%expect {|
+    ligo: in file "", line 0, characters 1-32. Badly formatted literal: signature thisisnotasignature {"location":"in file \"\", line 0, characters 1-32"}
+
+
+     If you're not sure how to fix this error, you can
+     do one of the following:
+
+    * Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
+    * Ask a question on our Discord: https://discord.gg/9rhYaEt
+    * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
+    * Check the changelog by running 'ligo changelog' |}]
+
+let%expect_test _ =
+  run_ligo_good ["interpret" ; "(\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav\":key)" ; "--syntax=pascaligo"] ;
+  [%expect {| key edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav |}]
+
+let%expect_test _ =
+  run_ligo_bad ["interpret" ; "(\"thisisnotapublickey\":key)" ; "--syntax=pascaligo"] ;
+  [%expect {|
+    ligo: in file "", line 0, characters 1-26. Badly formatted literal: key thisisnotapublickey {"location":"in file \"\", line 0, characters 1-26"}
+
+
+     If you're not sure how to fix this error, you can
+     do one of the following:
+
+    * Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
+    * Ask a question on our Discord: https://discord.gg/9rhYaEt
+    * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
+    * Check the changelog by running 'ligo changelog' |}]
diff --git a/src/passes/3-self_ast_simplified/literals.ml b/src/passes/3-self_ast_simplified/literals.ml
index edf0faa8a..dbdaa22db 100644
--- a/src/passes/3-self_ast_simplified/literals.ml
+++ b/src/passes/3-self_ast_simplified/literals.ml
@@ -68,6 +68,20 @@ let peephole_expression : expression -> expression result = fun e ->
       Protocol.Alpha_context.Contract.of_b58check s in
     return l
     )
+  | E_literal (Literal_signature s) as l -> (
+    let open Tezos_crypto in
+    let%bind (_sig:Crypto.Signature.t) = 
+      Trace.trace_tzresult (bad_format e) @@
+      Signature.of_b58check s in
+    return l
+    )
+  | E_literal (Literal_key s) as l -> (
+    let open Tezos_crypto in
+    let%bind (_k:Crypto.Signature.public_key) = 
+      Trace.trace_tzresult (bad_format e) @@
+      Signature.Public_key.of_b58check s in
+    return l
+    )
   | E_constant (C_BIG_MAP_LITERAL as cst, lst) -> (
       let%bind elt =
         trace_option (bad_single_arity cst e.location) @@
diff --git a/src/passes/3-self_ast_simplified/tezos_type_annotation.ml b/src/passes/3-self_ast_simplified/tezos_type_annotation.ml
index 32f5fcb5c..81b13f748 100644
--- a/src/passes/3-self_ast_simplified/tezos_type_annotation.ml
+++ b/src/passes/3-self_ast_simplified/tezos_type_annotation.ml
@@ -18,6 +18,8 @@ let peephole_expression : expression -> expression result = fun e ->
   | E_ascription (e' , t) as e -> (
       match (e'.expression , t.type_expression') with
       | (E_literal (Literal_string s) , T_constant (TC_key_hash)) -> return @@ E_literal (Literal_key_hash s)
+      | (E_literal (Literal_string s) , T_constant (TC_signature)) -> return @@ E_literal (Literal_signature s)
+      | (E_literal (Literal_string s) , T_constant (TC_key)) -> return @@ E_literal (Literal_key s)
       | (E_literal (Literal_int i) , T_constant (TC_timestamp)) -> return @@ E_literal (Literal_timestamp i)
       | (E_literal (Literal_string str) , T_constant (TC_timestamp)) ->
         let%bind time =
diff --git a/src/passes/6-transpiler/untranspiler.ml b/src/passes/6-transpiler/untranspiler.ml
index 370c5ecb6..a548003b0 100644
--- a/src/passes/6-transpiler/untranspiler.ml
+++ b/src/passes/6-transpiler/untranspiler.ml
@@ -127,14 +127,18 @@ let rec untranspile (v : value) (t : AST.type_value) : AST.annotated_expression
           get_string v in
         return (E_literal (Literal_key_hash n))
       )
-      | TC_chain_id -> (
-        let%bind n =
-          trace_strong (wrong_mini_c_value "chain_id" v) @@
-          get_string v in
-        return (E_literal (Literal_chain_id n))
-      )
-    |  TC_signature ->
-      fail @@ bad_untranspile "signature" v
+    | TC_chain_id -> (
+      let%bind n =
+        trace_strong (wrong_mini_c_value "chain_id" v) @@
+        get_string v in
+      return (E_literal (Literal_chain_id n))
+    )
+    |  TC_signature -> (
+      let%bind n =
+        trace_strong (wrong_mini_c_value "signature" v) @@
+        get_string v in
+      return (E_literal (Literal_signature n))
+    )
   )
   | T_operator type_operator -> (
     match type_operator with
diff --git a/src/passes/8-compiler/uncompiler.ml b/src/passes/8-compiler/uncompiler.ml
index f261669ab..c3d5a0bc4 100644
--- a/src/passes/8-compiler/uncompiler.ml
+++ b/src/passes/8-compiler/uncompiler.ml
@@ -40,6 +40,8 @@ let rec translate_value (Ex_typed_value (ty, value)) : value result =
     ok @@ D_string (Signature.Public_key_hash.to_b58check n)
   | (Key_t _ ), n ->
     ok @@ D_string (Signature.Public_key.to_b58check n)
+  | (Signature_t _ ), n ->
+    ok @@ D_string (Signature.to_b58check n)
   | (Timestamp_t _), n ->
       let n =
         Z.to_int @@
diff --git a/src/stages/common/PP.ml b/src/stages/common/PP.ml
index 74dd5b78b..7d42e0c7e 100644
--- a/src/stages/common/PP.ml
+++ b/src/stages/common/PP.ml
@@ -162,7 +162,7 @@ and type_constant ppf (tc:type_constant) : unit =
     | TC_address   -> "address"
     | TC_key       -> "key"
     | TC_key_hash  -> "key_hash"
-    | TC_signature -> "signatuer"
+    | TC_signature -> "signature"
     | TC_timestamp -> "timestamp"
     | TC_chain_id  -> "chain_id"
     in