Merge branch 'dev' of gitlab.com:ligolang/ligo into rinderknecht@michelson

This commit is contained in:
Christian Rinderknecht 2020-04-25 20:51:33 +02:00
commit 9618a48848
53 changed files with 12707 additions and 9241 deletions

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
},
"dependencies": {
"@docusaurus/plugin-sitemap": "^2.0.0-alpha.37",
"@ligo/syntax": "file:src/@ligo/syntax"
"@ligo/syntax": "file:src/@ligo/syntax",
"@ligolang/compact-ligo-ide": "^3.0.3"
}
}

View File

@ -5,10 +5,13 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {useEffect, useState, useRef} from 'react';
import React, { useEffect, useState, useRef } from 'react';
import classnames from 'classnames';
import Highlight, {defaultProps} from 'prism-react-renderer';
const {Prism} = require("prism-react-renderer");
import Highlight, { defaultProps } from 'prism-react-renderer';
import { CompactLigoIde } from '@ligolang/compact-ligo-ide';
const { Prism } = require("prism-react-renderer");
Prism.languages = {
...Prism.languages,
pascaligo: {
@ -59,7 +62,8 @@ Prism.languages = {
'punctuation': /\(\.|\.\)|[()\[\]:;,.]/
},
reasonligo:
{...Prism.languages.reason,
{
...Prism.languages.reason,
'comment': [
/(^|[^\\])\/\*[\s\S]*?\*\//,
/\(\*[\s\S]*?\*\)/,
@ -67,12 +71,14 @@ Prism.languages = {
]
},
cameligo: {...Prism.languages.ocaml,
cameligo: {
...Prism.languages.ocaml,
'comment': [
/(^|[^\\])\/\*[\s\S]*?\*\//,
/\(\*[\s\S]*?\*\)/,
/\/\/.*/
]}
]
}
};
import defaultTheme from 'prism-react-renderer/themes/palenight';
import Clipboard from 'clipboard';
@ -84,10 +90,10 @@ import styles from './styles.module.css';
const highlightLinesRangeRegex = /{([\d,-]+)}/;
export default ({children, className: languageClassName, metastring}) => {
export default ({ children, className: languageClassName, metastring }) => {
const {
siteConfig: {
themeConfig: {prism = {}},
themeConfig: { prism = {} },
},
} = useDocusaurusContext();
@ -108,7 +114,7 @@ export default ({children, className: languageClassName, metastring}) => {
const button = useRef(null);
let highlightLines = [];
const {isDarkTheme} = useThemeContext();
const { isDarkTheme } = useThemeContext();
const lightModeTheme = prism.theme || defaultTheme;
const darkModeTheme = prism.darkTheme || lightModeTheme;
const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme;
@ -134,6 +140,21 @@ export default ({children, className: languageClassName, metastring}) => {
};
}, [button.current, target.current]);
// Compact Ligo IDE support - begin
if (languageClassName === 'language-compactLigoIde') {
const theme = isDarkTheme ? 'dark' : 'light';
const webIdeUrlRegex = /webIdeUrl=(.*)/;
if (metastring && webIdeUrlRegex.test(metastring)) {
const webIdeUrl = metastring.match(webIdeUrlRegex)[1];
return <CompactLigoIde webIdeUrl={webIdeUrl} theme={theme}>{children}</CompactLigoIde>
}
return <CompactLigoIde theme={theme}>{children}</CompactLigoIde>
}
// Compact Ligo IDE support -- end
let language =
languageClassName && languageClassName.replace(/language-/, '');
@ -155,7 +176,7 @@ export default ({children, className: languageClassName, metastring}) => {
theme={prismTheme}
code={children.trim()}
language={language}>
{({className, style, tokens, getLineProps, getTokenProps}) => (
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre className={classnames(className, styles.codeBlock)}>
<button
ref={button}
@ -172,7 +193,7 @@ export default ({children, className: languageClassName, metastring}) => {
line[0].content = '\n'; // eslint-disable-line no-param-reassign
}
const lineProps = getLineProps({line, key: i});
const lineProps = getLineProps({ line, key: i });
if (highlightLines.includes(i + 1)) {
lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`;
@ -181,7 +202,7 @@ export default ({children, className: languageClassName, metastring}) => {
return (
<div key={i} {...lineProps}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({token, key})} />
<span key={key} {...getTokenProps({ token, key })} />
))}
</div>
);

View File

@ -1058,3 +1058,11 @@ a:hover {
.boolean-example-table > .example .codeBlockLines_src-theme-CodeBlock- {
background-color: transparent;
}
.compactLigoIde {
height: 400px;
}
.compactLigoIde pre {
border-radius: 0px;
}

View File

@ -224,15 +224,27 @@ let print_ast_typed =
let doc = "Subcommand: Print the typed AST.\n Warning: Intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
let optimize =
let open Arg in
let docv = "ENTRY_POINT" in
let doc = "Apply Mini-C optimizations as if compiling $(docv)" in
let info =
info ~docv ~doc ["optimize"] in
value @@ opt (some string) None info
let print_mini_c =
let f source_file syntax display_format = (
let f source_file syntax display_format optimize = (
toplevel ~display_format @@
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
let%bind mini_c = Compile.Of_typed.compile typed in
ok @@ Format.asprintf "%a\n" Compile.Of_mini_c.pretty_print mini_c
match optimize with
| None -> ok @@ Format.asprintf "%a\n" Compile.Of_mini_c.pretty_print mini_c
| Some entry_point ->
let%bind mini_c = Compile.Of_mini_c.aggregate_contract mini_c entry_point in
ok @@ Format.asprintf "%a\n" Mini_c.PP.expression mini_c
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
let term = Term.(const f $ source_file 0 $ syntax $ display_format $ optimize) in
let cmdname = "print-mini-c" in
let doc = "Subcommand: Print Mini-C. Warning: Intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)

View File

@ -10,6 +10,7 @@ exception Should_exit_bad
let () = Unix.putenv "TERM" "dumb"
let run_ligo args =
Var.reset_counter ();
let argv = Array.of_list ("ligo" :: args) in
let result = Cli.run ~argv () in
Term.exit_status_of_result result

View File

@ -7,16 +7,16 @@ let bad_contract basename =
let%expect_test _ =
run_ligo_good [ "measure-contract" ; contract "coase.ligo" ; "main" ] ;
[%expect {| 1872 bytes |}] ;
[%expect {| 1874 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "multisig.ligo" ; "main" ] ;
[%expect {| 1187 bytes |}] ;
[%expect {| 1163 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "multisig-v2.ligo" ; "main" ] ;
[%expect {| 2886 bytes |}] ;
[%expect {| 2867 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "vote.mligo" ; "main" ] ;
[%expect {| 581 bytes |}] ;
[%expect {| 617 bytes |}] ;
run_ligo_good [ "compile-parameter" ; contract "coase.ligo" ; "main" ; "Buy_single (record card_to_buy = 1n end)" ] ;
[%expect {| (Left (Left 1)) |}] ;
@ -122,16 +122,18 @@ let%expect_test _ =
PAIR ;
PAIR ;
DUP ;
DIP { DUP } ;
SWAP ;
CDR ;
DIP { DIP 7 { DUP } ;
DIG 7 ;
DIP { DIP 6 { DUP } ;
DIG 6 ;
SENDER ;
PAIR ;
SOME ;
DIP { DIP { DUP } ; SWAP ; CAR ; CDR } } ;
DIP { DUP ; CAR ; CDR } } ;
UPDATE ;
DIP { DUP } ;
SWAP ;
DIP { DUP } ;
SWAP ;
DIP { DUP ; CDR ; SWAP ; CAR ; CAR } ;
SWAP ;
PAIR ;
@ -148,7 +150,7 @@ let%expect_test _ =
DUP ;
NIL operation ;
PAIR ;
DIP { DROP 11 } }
DIP { DROP 12 } }
{ DUP ;
DIP { DIP 2 { DUP } ; DIG 2 } ;
PAIR ;
@ -317,10 +319,16 @@ let%expect_test _ =
COMPARE ;
NEQ ;
IF { PUSH string "Counters does not match" ; FAILWITH }
{ DIP 2 { DUP } ;
DIG 2 ;
{ DUP ;
DIP { DIP 2 { DUP } ; DIG 2 ; CAR ; CAR } ;
PAIR ;
DIP { DIP { DUP } ; SWAP ; CDR ; CAR ; CHAIN_ID ; SWAP ; PAIR } ;
PAIR ;
PACK ;
DIP 3 { DUP } ;
DIG 3 ;
CDR ;
DIP { DIP { DUP } ; SWAP ; CAR ; CAR ; PUSH nat 0 ; SWAP ; PAIR } ;
DIP { DIP 2 { DUP } ; DIG 2 ; CAR ; CAR ; PUSH nat 0 ; SWAP ; PAIR } ;
ITER { SWAP ;
PAIR ;
DUP ;
@ -347,16 +355,7 @@ let%expect_test _ =
COMPARE ;
EQ ;
IF { DUP ;
DIP { DIP 3 { DUP } ;
DIG 3 ;
CDR ;
DIP { DIP 7 { DUP } ;
DIG 7 ;
DIP { DIP 9 { DUP } ; DIG 9 ; CAR ; CAR } ;
PAIR ;
DIP { DIP 8 { DUP } ; DIG 8 ; CDR ; CAR ; CHAIN_ID ; SWAP ; PAIR } ;
PAIR ;
PACK } } ;
DIP { DIP 3 { DUP } ; DIG 3 ; CDR ; DIP { DIP 7 { DUP } ; DIG 7 } } ;
CHECK_SIGNATURE ;
IF { DIP 5 { DUP } ;
DIG 5 ;
@ -389,46 +388,31 @@ let%expect_test _ =
{ DUP } ;
DIP 5 { DUP } ;
DIG 5 ;
DIP 6 { DUP } ;
DIG 6 ;
CAR ;
DIP 2 { DUP } ;
DIG 2 ;
CAR ;
SWAP ;
CDR ;
SWAP ;
PAIR ;
SWAP ;
CDR ;
SWAP ;
PAIR ;
DUP ;
DIP { DUP } ;
SWAP ;
CAR ;
DIP 3 { DUP } ;
DIG 3 ;
CDR ;
SWAP ;
CAR ;
DIP { DUP ; CDR ; SWAP ; CAR ; CDR } ;
PAIR ;
PAIR ;
DIP { DUP } ;
SWAP ;
CDR ;
DIP { DUP ; CDR ; SWAP ; CAR ; CAR } ;
SWAP ;
PAIR ;
PAIR ;
CAR ;
DIP { DROP 7 } } ;
DIP { DROP 6 } } ;
DUP ;
CDR ;
DIP { DIP 2 { DUP } ; DIG 2 ; CDR ; CDR } ;
DIP { DIP 3 { DUP } ; DIG 3 ; CDR ; CDR } ;
COMPARE ;
LT ;
IF { PUSH string "Not enough signatures passed the check" ; FAILWITH }
{ DIP 2 { DUP } ;
DIG 2 ;
DIP 3 { DUP } ;
{ DIP 3 { DUP } ;
DIG 3 ;
DIP 4 { DUP } ;
DIG 4 ;
CAR ;
CDR ;
PUSH nat 1 ;
@ -437,16 +421,16 @@ let%expect_test _ =
SWAP ;
PAIR ;
PAIR ;
DIP 3 { DUP } ;
DIG 3 ;
DIP 4 { DUP } ;
DIG 4 ;
DIP { DUP } ;
SWAP ;
DIP { DROP 2 } } ;
DIP 3 { DUP } ;
DIG 3 ;
DIP 4 { DUP } ;
DIG 4 ;
DIP { DUP } ;
SWAP ;
DIP { DROP 3 } } ;
DIP { DROP 4 } } ;
DIP { DUP } ;
SWAP ;
UNIT ;
@ -576,21 +560,23 @@ let%expect_test _ =
DIP { DUP } ;
SWAP ;
DIP { DROP 2 } } ;
DIP 2 { DUP } ;
DIG 2 ;
CAR ;
DIP { DUP } ;
PAIR ;
DIP 2 { DUP } ;
DIG 2 ;
SWAP ;
PUSH bool True ;
SENDER ;
UPDATE ;
DIP 3 { DUP } ;
DIG 3 ;
DIP 2 { DUP } ;
DIG 2 ;
SWAP ;
CAR ;
PAIR ;
CDR ;
DIP { DUP } ;
SWAP ;
PAIR ;
DIP { DROP 2 } } ;
DIP { DROP 3 } } ;
DUP ;
CAR ;
DIP { DUP } ;
@ -697,12 +683,9 @@ let%expect_test _ =
{ DIP { DUP } ; SWAP } ;
DIP 3 { DUP } ;
DIG 3 ;
DIP 4 { DUP } ;
DIG 4 ;
CAR ;
DIP 2 { DUP } ;
DIG 2 ;
DIP { DROP ; CDR } ;
CDR ;
DIP { DUP } ;
SWAP ;
PAIR ;
CAR ;
DIP { DROP 4 } } ;
@ -887,14 +870,16 @@ let%expect_test _ =
PAIR ;
DUP ;
CDR ;
DIP { DUP } ;
SWAP ;
NOW ;
SENDER ;
DIP 3 { DUP } ;
DIG 3 ;
CAR ;
IF_LEFT
{ DIP { DUP } ;
SWAP ;
DIP 2 { DUP } ;
DIG 2 ;
{ DIP 3 { DUP } ;
DIG 3 ;
DIP 4 { DUP } ;
DIG 4 ;
CAR ;
CAR ;
CDR ;
@ -906,10 +891,10 @@ let%expect_test _ =
PAIR ;
PAIR ;
DIP { DROP } }
{ DIP { DUP } ;
SWAP ;
DIP 2 { DUP } ;
DIG 2 ;
{ DIP 3 { DUP } ;
DIG 3 ;
DIP 4 { DUP } ;
DIG 4 ;
CDR ;
CDR ;
PUSH nat 1 ;
@ -921,12 +906,9 @@ let%expect_test _ =
PAIR ;
DIP { DROP } } ;
DUP ;
DIP { DUP } ;
SWAP ;
CDR ;
CAR ;
PUSH bool True ;
SENDER ;
DIP 2 { DUP } ;
DIG 2 ;
DIP { DIP { DUP } ; SWAP ; CDR ; CAR ; PUSH bool True } ;
UPDATE ;
DIP { DUP ; CAR ; SWAP ; CDR ; CDR } ;
PAIR ;
@ -934,7 +916,7 @@ let%expect_test _ =
PAIR ;
NIL operation ;
PAIR ;
DIP { DROP 4 } } ;
DIP { DROP 6 } } ;
DIP { DROP } } } |}]
let%expect_test _ =
@ -950,6 +932,32 @@ let%expect_test _ =
PAIR ;
DIP { DROP 2 } } } |}]
let%expect_test _ =
run_ligo_good [ "compile-contract" ; contract "amount_lambda.mligo" ; "main" ] ;
(* AMOUNT should occur inside the second lambda, but not the first lambda *)
[%expect {|
{ parameter bool ;
storage (lambda unit mutez) ;
code { DUP ;
CAR ;
IF { AMOUNT ;
DUP ;
LAMBDA
(pair mutez unit)
mutez
{ DUP ; CAR ; SWAP ; CDR ; DIP { DUP } ; SWAP ; DIP { DROP 2 } } ;
SWAP ;
APPLY ;
DIP { DROP } }
{ LAMBDA unit mutez { DROP ; AMOUNT } } ;
NIL operation ;
PAIR ;
DIP { DROP } } } |}]
let%expect_test _ =
run_ligo_good [ "print-ast-typed" ; contract "sequence.mligo" ; ];
[%expect {| const y = lambda (_) return let x = +1 in let _ = let x = +2 in UNIT() in let _ = let x = +23 in UNIT() in let _ = let x = +42 in UNIT() in x |}]
let%expect_test _ =
run_ligo_bad [ "compile-contract" ; contract "bad_type_operator.ligo" ; "main" ] ;
[%expect {|
@ -963,16 +971,6 @@ let%expect_test _ =
* Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
* Check the changelog by running 'ligo changelog' |}]
let%expect_test _ =
run_ligo_good [ "run-function" ; contract "failwith.ligo" ; "failer" ; "1" ] ;
[%expect {|
failwith("some_string") |}]
let%expect_test _ =
run_ligo_good [ "run-function" ; contract "failwith.ligo" ; "failer" ; "1" ; "--format=json" ] ;
[%expect {|
{"status":"ok","content":"failwith(\"some_string\")"} |}]
let%expect_test _ =
run_ligo_bad [ "compile-contract" ; contract "bad_address_format.religo" ; "main" ] ;
[%expect {|
@ -1084,7 +1082,7 @@ let%expect_test _ =
let%expect_test _ =
run_ligo_bad [ "compile-contract" ; bad_contract "create_contract_toplevel.mligo" ; "main" ] ;
[%expect {|
ligo: in file "create_contract_toplevel.mligo", line 4, character 35 to line 8, character 8. No free variable allowed in this lambda: variable 'store' {"expression":"CREATE_CONTRACT(lambda (#P:Some(( nat * string ))) : None return\n let rhs#727 = #P in\n let p = rhs#727.0 in\n let s = rhs#727.1 in\n ( LIST_EMPTY() : (type_operator: list(operation)) , store ) ,\n NONE() : (type_operator: option(key_hash)) ,\n 300000000mutez ,\n \"un\")","location":"in file \"create_contract_toplevel.mligo\", line 4, character 35 to line 8, character 8"}
ligo: in file "create_contract_toplevel.mligo", line 4, character 35 to line 8, character 8. No free variable allowed in this lambda: variable 'store' {"expression":"CREATE_CONTRACT(lambda (#P:Some(( nat * string ))) : None return\n let rhs#2 = #P in\n let p = rhs#2.0 in\n let s = rhs#2.1 in\n ( LIST_EMPTY() : (type_operator: list(operation)) , store ) ,\n NONE() : (type_operator: option(key_hash)) ,\n 300000000mutez ,\n \"un\")","location":"in file \"create_contract_toplevel.mligo\", line 4, character 35 to line 8, character 8"}
If you're not sure how to fix this error, you can
@ -1097,7 +1095,7 @@ ligo: in file "create_contract_toplevel.mligo", line 4, character 35 to line 8,
run_ligo_bad [ "compile-contract" ; bad_contract "create_contract_var.mligo" ; "main" ] ;
[%expect {|
ligo: in file "create_contract_var.mligo", line 6, character 35 to line 10, character 5. No free variable allowed in this lambda: variable 'a' {"expression":"CREATE_CONTRACT(lambda (#P:Some(( nat * int ))) : None return\n let rhs#730 = #P in\n let p = rhs#730.0 in\n let s = rhs#730.1 in\n ( LIST_EMPTY() : (type_operator: list(operation)) , a ) ,\n NONE() : (type_operator: option(key_hash)) ,\n 300000000mutez ,\n 1)","location":"in file \"create_contract_var.mligo\", line 6, character 35 to line 10, character 5"}
ligo: in file "create_contract_var.mligo", line 6, character 35 to line 10, character 5. No free variable allowed in this lambda: variable 'a' {"expression":"CREATE_CONTRACT(lambda (#P:Some(( nat * int ))) : None return\n let rhs#2 = #P in\n let p = rhs#2.0 in\n let s = rhs#2.1 in\n ( LIST_EMPTY() : (type_operator: list(operation)) , a ) ,\n NONE() : (type_operator: option(key_hash)) ,\n 300000000mutez ,\n 1)","location":"in file \"create_contract_var.mligo\", line 6, character 35 to line 10, character 5"}
If you're not sure how to fix this error, you can

View File

@ -8,11 +8,11 @@ let bad_contract basename =
let%expect_test _ =
run_ligo_good [ "run-function" ; contract "failwith.ligo" ; "failer" ; "1" ] ;
[%expect {|
failwith("some_string") |}];
failwith(42) |}];
run_ligo_good [ "run-function" ; contract "failwith.ligo" ; "failer" ; "1" ; "--format=json" ] ;
[%expect {|
{"status":"ok","content":"failwith(\"some_string\")"} |}];
{"status":"ok","content":"failwith(42)"} |}];
run_ligo_good [ "dry-run" ; contract "subtle_nontail_fail.mligo" ; "main" ; "()" ; "()" ] ;

View File

@ -189,4 +189,17 @@ let%expect_test _ =
* Visit our documentation: https://ligolang.org/docs/intro/introduction
* 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' |}];
* Check the changelog by running 'ligo changelog' |}]
let%expect_test _ =
run_ligo_bad [ "compile-contract" ; "../../test/contracts/negative/failwith_wrong_type.ligo" ; "main" ] ;
[%expect {|
ligo: in file "failwith_wrong_type.ligo", line 2, characters 19-46. Failwith with disallowed type: Expected arguments with one of the following combinations of types: failwith(string) or failwith(nat) or failwith(int) but got this combination instead: failwith((type_operator: list(int)))
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/introduction
* 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' |}]

View File

@ -34,3 +34,15 @@ let aggregate_and_compile_expression = fun program exp ->
let pretty_print program =
Mini_c.PP.program program
(* TODO refactor? *)
let aggregate = fun program form ->
let%bind aggregated = aggregate_entry program form in
ok @@ Self_mini_c.all_expression aggregated
let aggregate_contract = fun (program : Types.program) name ->
let%bind (exp, idx) = get_entry program name in
let program' = List.take idx program in
aggregate program' (ContractForm exp)

View File

@ -933,6 +933,17 @@ sequence_or_record_in:
| None ->
PaRecord {r_elts = ($1, []); r_terminator = None}
}
| field_name more_field_assignments {
let value = {
field_name = $1;
assignment = ghost;
field_expr = EVar $1 }
in
let field_name = {$1 with value} in
let (comma, elts) = $2 in
let r_elts = Utils.nsepseq_cons field_name comma elts in
PaRecord {r_elts; r_terminator = None}
}
sequence_or_record:
"{" sequence_or_record_in "}" {

View File

@ -474,14 +474,29 @@ and transpile_annotated_expression (ae:AST.expression) : expression result =
let expr = List.fold_left aux record' path in
ok expr
| E_record_update {record; path; update} ->
let%bind ty' = transpile_type (get_type_expression record) in
let rec aux res (r,p,up) =
let ty = get_type_expression r in
let%bind ty_lmap =
trace_strong (corner_case ~loc:__LOC__ "not a record") @@
get_t_record (get_type_expression record) in
get_t_record (ty) in
let%bind ty' = transpile_type (ty) in
let%bind ty'_lmap = Ast_typed.Helpers.bind_map_lmap_t transpile_type ty_lmap in
let%bind path =
let%bind p' =
trace_strong (corner_case ~loc:__LOC__ "record access") @@
record_access_to_lr ty' ty'_lmap path in
record_access_to_lr ty' ty'_lmap p in
let res' = res @ p' in
match (up:AST.expression).expression_content with
| AST.E_record_update {record=record'; path=path'; update=update'} -> (
match record'.expression_content with
| AST.E_record_accessor {record;path} ->
if (AST.Misc.equal_variables record r && path = p) then
aux res' (record',path',update')
else ok @@ (up,res')
| _ -> ok @@ (up,res')
)
| _ -> ok @@ (up,res')
in
let%bind (update, path) = aux [] (record, path, update) in
let path = List.map snd path in
let%bind update = transpile_annotated_expression update in
let%bind record = transpile_annotated_expression record in

View File

@ -25,12 +25,13 @@ let is_pure_constant : constant' -> bool =
| C_SOME
| C_UPDATE | C_MAP_FIND_OPT | C_MAP_ADD | C_MAP_UPDATE
| C_INT | C_ABS | C_IS_NAT
| C_BALANCE | C_AMOUNT | C_ADDRESS | C_NOW | C_SOURCE | C_SENDER | C_CHAIN_ID
| C_ADDRESS
| C_SET_MEM | C_SET_ADD | C_SET_REMOVE | C_SLICE
| C_SHA256 | C_SHA512 | C_BLAKE2b | C_CHECK_SIGNATURE
| C_HASH_KEY | C_BYTES_PACK | C_CONCAT
-> true
(* unfortunately impure: *)
| C_BALANCE | C_AMOUNT | C_NOW | C_SOURCE | C_SENDER | C_CHAIN_ID
| C_ADD | C_SUB |C_MUL|C_DIV|C_MOD | C_LSL | C_LSR
(* impure: *)
| C_ASSERTION | C_ASSERT_INFERRED

View File

@ -634,22 +634,22 @@ let rec compile_expression :
| ESeq s -> (
let (s , loc) = r_split s in
let items : Raw.expr list = pseq_to_list s.elements in
(match items with
(match List.rev items with
[] -> return @@ e_skip ~loc ()
| expr::more ->
let expr' = compile_expression expr in
let apply (e1: Raw.expr) (e2: expression Trace.result) =
let%bind a = compile_expression e1 in
let%bind e2' = e2 in
return @@ e_sequence a e2'
in List.fold_right apply more expr')
let apply e1 e2 =
let%bind a = compile_expression e2 in
let%bind e1' = e1 in
return @@ e_sequence a e1'
in List.fold_left apply expr' more)
)
| ECond c -> (
let (c , loc) = r_split c in
let%bind expr = compile_expression c.test in
let%bind match_true = compile_expression c.ifso in
let%bind match_false = compile_expression c.ifnot in
return @@ e_matching ~loc expr (Match_bool {match_true; match_false})
return @@ e_cond ~loc expr match_true match_false
)
and compile_fun lamb' : expr result =

View File

@ -398,7 +398,7 @@ let rec compile_expression (t:Raw.expr) : expr result =
let%bind expr = compile_expression c.test in
let%bind match_true = compile_expression c.ifso in
let%bind match_false = compile_expression c.ifnot in
return @@ e_matching expr ~loc (Match_bool {match_true; match_false})
return @@ e_cond ~loc expr match_true match_false
| ECase c -> (
let (c , loc) = r_split c in
@ -860,7 +860,7 @@ and compile_single_instruction : Raw.instruction -> (_ -> expression result) res
let%bind match_true = match_true None in
let%bind match_false = match_false None in
return_statement @@ e_matching expr ~loc (Match_bool {match_true; match_false})
return_statement @@ e_cond ~loc expr match_true match_false
)
| Assign a -> (
let (a , loc) = r_split a in

View File

@ -52,8 +52,16 @@ let repair_mutable_variable_in_matching (match_body : O.expression) (element_nam
| E_constant {cons_name=C_MAP_FOLD;arguments= _}
| E_constant {cons_name=C_SET_FOLD;arguments= _}
| E_constant {cons_name=C_LIST_FOLD;arguments= _}
| E_cond _
| E_matching _ -> ok @@ (false, (decl_var,free_var),ass_exp)
| _ -> ok (true, (decl_var, free_var),ass_exp)
| E_constant _
| E_skip
| E_literal _ | E_variable _
| E_application _ | E_lambda _| E_recursive _
| E_constructor _ | E_record _| E_record_accessor _|E_record_update _
| E_ascription _ | E_sequence _ | E_tuple _ | E_tuple_accessor _ | E_tuple_update _
| E_map _ | E_big_map _ |E_list _ | E_set _ |E_look_up _
-> ok (true, (decl_var, free_var),ass_exp)
)
(element_names,[])
match_body in
@ -88,8 +96,16 @@ and repair_mutable_variable_in_loops (for_body : O.expression) (element_names :
| E_constant {cons_name=C_MAP_FOLD;arguments= _}
| E_constant {cons_name=C_SET_FOLD;arguments= _}
| E_constant {cons_name=C_LIST_FOLD;arguments= _}
| E_cond _
| E_matching _ -> ok @@ (false,(decl_var,free_var),ass_exp)
| _ -> ok (true,(decl_var, free_var),ass_exp)
| E_constant _
| E_skip
| E_literal _ | E_variable _
| E_application _ | E_lambda _| E_recursive _
| E_constructor _ | E_record _| E_record_accessor _|E_record_update _
| E_ascription _ | E_sequence _ | E_tuple _ | E_tuple_accessor _ | E_tuple_update _
| E_map _ | E_big_map _ |E_list _ | E_set _ |E_look_up _
-> ok (true, (decl_var, free_var),ass_exp)
)
(element_names,[])
for_body in
@ -102,12 +118,14 @@ and store_mutable_variable (free_vars : I.expression_variable list) =
let aux var = (O.Label (Var.to_name var), O.e_variable var) in
O.e_record @@ O.LMap.of_list (List.map aux free_vars)
and restore_mutable_variable (expr : O.expression->O.expression_content) (free_vars : O.expression_variable list) (env : O.expression_variable) =
and restore_mutable_variable (expr : O.expression->O.expression) (free_vars : O.expression_variable list) (env : O.expression_variable) =
let aux (f: O.expression -> O.expression) (ev: O.expression_variable) =
fun expr -> f (O.e_let_in (ev,None) true false (O.e_record_accessor (O.e_variable env) (Label (Var.to_name ev))) expr)
in
let ef = List.fold_left aux (fun e -> e) free_vars in
expr (ef (O.e_skip ()))
fun e -> match e with
| None -> expr (ef (O.e_skip ()))
| Some e -> expr (ef e)
let rec compile_type_expression : I.type_expression -> O.type_expression result =
@ -189,77 +207,86 @@ and compile_type_operator : I.type_operator -> O.type_operator result =
let rec compile_expression : I.expression -> O.expression result =
fun e ->
let return expr = ok @@ O.make_e ~loc:e.location expr in
let%bind e = compile_expression' e in
ok @@ e None
and compile_expression' : I.expression -> (O.expression option -> O.expression) result =
fun e ->
let return expr = ok @@ function
| None -> expr
| Some e -> O.e_sequence expr e
in
let loc = e.location in
match e.expression_content with
| I.E_literal literal -> return @@ O.E_literal literal
| I.E_literal literal -> return @@ O.e_literal ~loc literal
| I.E_constant {cons_name;arguments} ->
let%bind arguments = bind_map_list compile_expression arguments in
return @@ O.E_constant {cons_name;arguments}
| I.E_variable name -> return @@ O.E_variable name
return @@ O.e_constant ~loc cons_name arguments
| I.E_variable name -> return @@ O.e_variable ~loc name
| I.E_application {lamb;args} ->
let%bind lamb = compile_expression lamb in
let%bind args = compile_expression args in
return @@ O.E_application {lamb;args}
return @@ O.e_application ~loc lamb args
| I.E_lambda lambda ->
let%bind lambda = compile_lambda lambda in
return @@ O.E_lambda lambda
return @@ O.make_e ~loc (O.E_lambda lambda)
| I.E_recursive {fun_name;fun_type;lambda} ->
let%bind fun_type = compile_type_expression fun_type in
let%bind lambda = compile_lambda lambda in
return @@ O.E_recursive {fun_name;fun_type;lambda}
return @@ O.e_recursive ~loc fun_name fun_type lambda
| I.E_let_in {let_binder;inline;rhs;let_result} ->
let (binder,ty_opt) = let_binder in
let%bind ty_opt = bind_map_option compile_type_expression ty_opt in
let%bind rhs = compile_expression rhs in
let%bind let_result = compile_expression let_result in
return @@ O.E_let_in {let_binder=(binder,ty_opt);mut=false;inline;rhs;let_result}
return @@ O.e_let_in ~loc (binder,ty_opt) false inline rhs let_result
| I.E_constructor {constructor;element} ->
let%bind element = compile_expression element in
return @@ O.E_constructor {constructor;element}
return @@ O.e_constructor ~loc constructor element
| I.E_matching m ->
let%bind m = compile_matching m in
return @@ m
ok @@ m
| I.E_record record ->
let record = I.LMap.to_kv_list record in
let%bind record =
bind_map_list (fun (k,v) ->
let%bind v =compile_expression v in
let%bind v = compile_expression v in
ok @@ (k,v)
) record
in
return @@ O.E_record (O.LMap.of_list record)
return @@ O.e_record ~loc (O.LMap.of_list record)
| I.E_record_accessor {record;path} ->
let%bind record = compile_expression record in
return @@ O.E_record_accessor {record;path}
return @@ O.e_record_accessor ~loc record path
| I.E_record_update {record;path;update} ->
let%bind record = compile_expression record in
let%bind update = compile_expression update in
return @@ O.E_record_update {record;path;update}
return @@ O.e_record_update ~loc record path update
| I.E_map map ->
let%bind map = bind_map_list (
bind_map_pair compile_expression
) map
in
return @@ O.E_map map
return @@ O.e_map ~loc map
| I.E_big_map big_map ->
let%bind big_map = bind_map_list (
bind_map_pair compile_expression
) big_map
in
return @@ O.E_big_map big_map
return @@ O.e_big_map ~loc big_map
| I.E_list lst ->
let%bind lst = bind_map_list compile_expression lst in
return @@ O.E_list lst
return @@ O.e_list ~loc lst
| I.E_set set ->
let%bind set = bind_map_list compile_expression set in
return @@ O.E_set set
return @@ O.e_set ~loc set
| I.E_look_up look_up ->
let%bind look_up = bind_map_pair compile_expression look_up in
return @@ O.E_look_up look_up
let%bind (a,b) = bind_map_pair compile_expression look_up in
return @@ O.e_look_up ~loc a b
| I.E_ascription {anno_expr; type_annotation} ->
let%bind anno_expr = compile_expression anno_expr in
let%bind type_annotation = compile_type_expression type_annotation in
return @@ O.E_ascription {anno_expr; type_annotation}
return @@ O.e_annotation ~loc anno_expr type_annotation
| I.E_cond {condition;then_clause;else_clause} ->
let%bind condition = compile_expression condition in
let%bind then_clause' = compile_expression then_clause in
@ -274,43 +301,32 @@ let rec compile_expression : I.expression -> O.expression result =
if (List.length free_vars != 0) then
let cond_expr = O.e_cond condition then_clause else_clause in
let return_expr = fun expr ->
O.E_let_in {let_binder=(env,None); mut=false; inline=false;rhs=(store_mutable_variable free_vars);
let_result=O.e_let_in (env,None) false false cond_expr @@
O.e_let_in (env,None) false false (store_mutable_variable free_vars) @@
O.e_let_in (env,None) false false cond_expr @@
expr
}
in
return @@ restore_mutable_variable return_expr free_vars env
ok @@ restore_mutable_variable return_expr free_vars env
else
return @@ O.E_cond {condition; then_clause=then_clause'; else_clause=else_clause'}
return @@ O.e_cond ~loc condition then_clause' else_clause'
| I.E_sequence {expr1; expr2} ->
let%bind expr1 = compile_expression expr1 in
let%bind expr2 = compile_expression expr2 in
ok @@ add_to_end expr1 expr2
| I.E_skip -> return @@ O.E_skip
let%bind expr1 = compile_expression' expr1 in
let%bind expr2 = compile_expression' expr2 in
ok @@ fun e -> (match e with
| None -> expr1 (Some (expr2 None))
| Some e -> expr1 (Some (expr2 (Some e)))
)
| I.E_skip -> return @@ O.e_skip ~loc ()
| I.E_tuple tuple ->
let%bind tuple = bind_map_list compile_expression tuple in
return @@ O.E_tuple (tuple)
return @@ O.e_tuple ~loc tuple
| I.E_tuple_accessor {tuple;path} ->
let%bind tuple = compile_expression tuple in
return @@ O.E_tuple_accessor {tuple;path}
return @@ O.e_tuple_accessor ~loc tuple path
| I.E_tuple_update {tuple;path;update} ->
let%bind tuple = compile_expression tuple in
let%bind update = compile_expression update in
return @@ O.E_tuple_update {tuple;path;update}
| I.E_assign ass ->
let%bind content = compile_assign ass @@ O.e_skip () in
return @@ content
| I.E_for f ->
let%bind f = compile_for f in
return @@ f
| I.E_for_each fe ->
let%bind fe = compile_for_each fe in
return @@ fe
| I.E_while w ->
let%bind w = compile_while w in
return @@ w
and compile_assign {variable; access_path; expression} expr =
return @@ O.e_tuple_update ~loc tuple path update
| I.E_assign {variable; access_path; expression} ->
let accessor ?loc s a =
match a with
I.Access_tuple _i -> failwith "adding tuple soon"
@ -338,7 +354,20 @@ and compile_assign {variable; access_path; expression} expr =
let%bind (_,rhs) = bind_fold_list aux (O.e_variable variable, fun e -> ok @@ e) access_path in
let%bind expression = compile_expression expression in
let%bind rhs = rhs @@ expression in
ok @@ O.E_let_in {let_binder=(variable,None); mut=true; rhs; let_result=expr;inline = false}
ok @@ fun expr -> (match expr with
| None -> O.e_let_in ~loc (variable,None) true false rhs (O.e_skip ())
| Some e -> O.e_let_in ~loc (variable, None) true false rhs e
)
| I.E_for f ->
let%bind f = compile_for f in
ok @@ f
| I.E_for_each fe ->
let%bind fe = compile_for_each fe in
ok @@ fe
| I.E_while w ->
let%bind w = compile_while w in
ok @@ w
and compile_lambda : I.lambda -> O.lambda result =
fun {binder;input_type;output_type;result}->
@ -347,8 +376,12 @@ and compile_lambda : I.lambda -> O.lambda result =
let%bind result = compile_expression result in
ok @@ O.{binder;input_type;output_type;result}
and compile_matching : I.matching -> O.expression_content result =
and compile_matching : I.matching -> (O.expression option -> O.expression) result =
fun {matchee;cases} ->
let return expr = ok @@ function
| None -> expr
| Some e -> O.e_sequence expr e
in
let%bind matchee = compile_expression matchee in
match cases with
| I.Match_bool {match_true;match_false} ->
@ -364,14 +397,13 @@ and compile_matching : I.matching -> O.expression_content result =
if (List.length free_vars != 0) then
let match_expr = O.e_matching matchee (O.Match_bool {match_true; match_false}) in
let return_expr = fun expr ->
O.E_let_in {let_binder=(env,None); mut=false; inline=false;rhs=(store_mutable_variable free_vars);
let_result=O.e_let_in (env,None) false false match_expr @@
O.e_let_in (env,None) false false (store_mutable_variable free_vars) @@
O.e_let_in (env,None) false false match_expr @@
expr
}
in
ok @@ restore_mutable_variable return_expr free_vars env
else
ok @@ O.E_matching {matchee;cases=O.Match_bool {match_true=match_true';match_false=match_false'}}
return @@ O.e_matching matchee @@ O.Match_bool {match_true=match_true';match_false=match_false'}
| I.Match_option {match_none;match_some} ->
let%bind match_none' = compile_expression match_none in
let (n,expr,tv) = match_some in
@ -385,14 +417,13 @@ and compile_matching : I.matching -> O.expression_content result =
if (List.length free_vars != 0) then
let match_expr = O.e_matching matchee (O.Match_option {match_none; match_some=(n,expr,tv)}) in
let return_expr = fun expr ->
O.E_let_in {let_binder=(env,None); mut=false; inline=false;rhs=(store_mutable_variable free_vars);
let_result=O.e_let_in (env,None) false false match_expr @@
O.e_let_in (env,None) false false (store_mutable_variable free_vars) @@
O.e_let_in (env,None) false false match_expr @@
expr
}
in
ok @@ restore_mutable_variable return_expr free_vars env
else
ok @@ O.E_matching {matchee; cases=O.Match_option {match_none=match_none'; match_some=(n,expr',tv)}}
return @@ O.e_matching matchee @@ O.Match_option {match_none=match_none'; match_some=(n,expr',tv)}
| I.Match_list {match_nil;match_cons} ->
let%bind match_nil' = compile_expression match_nil in
let (hd,tl,expr,tv) = match_cons in
@ -406,17 +437,16 @@ and compile_matching : I.matching -> O.expression_content result =
if (List.length free_vars != 0) then
let match_expr = O.e_matching matchee (O.Match_list {match_nil; match_cons=(hd,tl,expr,tv)}) in
let return_expr = fun expr ->
O.E_let_in {let_binder=(env,None); mut=false; inline=false;rhs=(store_mutable_variable free_vars);
let_result=O.e_let_in (env,None) false false match_expr @@
O.e_let_in (env,None) false false (store_mutable_variable free_vars) @@
O.e_let_in (env,None) false false match_expr @@
expr
}
in
ok @@ restore_mutable_variable return_expr free_vars env
else
ok @@ O.E_matching {matchee;cases=O.Match_list {match_nil=match_nil'; match_cons=(hd,tl,expr',tv)}}
return @@ O.e_matching matchee @@ O.Match_list {match_nil=match_nil'; match_cons=(hd,tl,expr',tv)}
| I.Match_tuple ((lst,expr), tv) ->
let%bind expr = compile_expression expr in
ok @@ O.E_matching {matchee; cases=O.Match_tuple ((lst,expr), tv)}
return @@ O.e_matching matchee @@ O.Match_tuple ((lst,expr), tv)
| I.Match_variant (lst,tv) ->
let env = Var.fresh () in
let aux fv ((c,n),expr) =
@ -429,15 +459,14 @@ and compile_matching : I.matching -> O.expression_content result =
let free_vars = List.sort_uniq Var.compare @@ List.concat fv in
if (List.length free_vars == 0) then (
let cases = List.map (fun case -> let (a,_,b) = case in (a,b)) cases in
ok @@ O.E_matching{matchee; cases=O.Match_variant (cases,tv)}
return @@ O.e_matching matchee @@ O.Match_variant (cases,tv)
) else (
let cases = List.map (fun case -> let (a,b,_) = case in (a,b)) cases in
let match_expr = O.e_matching matchee @@ O.Match_variant (cases,tv) in
let return_expr = fun expr ->
O.E_let_in {let_binder=(env,None); mut=false; inline=false; rhs=(store_mutable_variable free_vars);
let_result=O.e_let_in (env,None) false false match_expr @@
O.e_let_in (env,None) false false (store_mutable_variable free_vars) @@
O.e_let_in (env,None) false false match_expr @@
expr
}
in
ok @@ restore_mutable_variable return_expr free_vars env
)
@ -469,11 +498,10 @@ and compile_while I.{condition;body} =
let loop = O.e_constant C_FOLD_WHILE [aux_func; O.e_variable env_rec] in
let let_binder = (env_rec,None) in
let return_expr = fun expr ->
O.E_let_in {let_binder; mut=false; inline=false; rhs=init_rec; let_result=
O.e_let_in let_binder false false init_rec @@
O.e_let_in let_binder false false loop @@
O.e_let_in let_binder false false (O.e_record_accessor (O.e_variable env_rec) (Label"0")) @@
expr
}
in
ok @@ restore_mutable_variable return_expr captured_name_list env_rec
@ -515,23 +543,23 @@ and compile_for I.{binder;start;final;increment;body} =
let%bind start = compile_expression start in
let let_binder = (env_rec,None) in
let return_expr = fun expr ->
O.E_let_in {let_binder=(binder, Some (O.t_int ()));mut=false; inline=false;rhs=start;let_result=
O.e_let_in (binder, Some (O.t_int ())) false false start @@
O.e_let_in let_binder false false init_rec @@
O.e_let_in let_binder false false loop @@
O.e_let_in let_binder false false (O.e_record_accessor (O.e_variable env_rec) (Label "0")) @@
expr
}
in
ok @@ restore_mutable_variable return_expr captured_name_list env_rec
and compile_for_each I.{binder;collection;collection_type; body} =
let env_rec = Var.fresh () in
let args = Var.fresh () in
let%bind element_names = ok @@ match snd binder with
| Some v -> [fst binder;v]
| None -> [fst binder]
in
let env = Var.fresh () in
let%bind body = compile_expression body in
let%bind ((_,free_vars), body) = repair_mutable_variable_in_loops body element_names args in
let for_body = add_to_end body @@ (O.e_record_accessor (O.e_variable args) (Label "0")) in
@ -555,10 +583,10 @@ and compile_for_each I.{binder;collection;collection_type; body} =
| Map -> ok @@ O.C_MAP_FOLD | Set -> ok @@ O.C_SET_FOLD | List -> ok @@ O.C_LIST_FOLD
in
let fold = fun expr ->
O.E_let_in {let_binder=(env,None);mut=false; inline=false;rhs=(O.e_constant op_name [lambda; collect ; init_record]);
let_result=expr;}
O.e_let_in (env_rec,None) false false (O.e_constant op_name [lambda; collect ; init_record]) expr
in
ok @@ restore_mutable_variable fold free_vars env
ok @@ restore_mutable_variable fold free_vars env_rec
let compile_declaration : I.declaration Location.wrap -> _ =
fun {wrap_content=declaration;location} ->
let return decl = ok @@ Location.wrap ~loc:location decl in
@ -639,18 +667,18 @@ and uncompile_type_operator : O.type_operator -> I.type_operator result =
let%bind (i,o) = bind_map_pair uncompile_type_expression (i,o) in
ok @@ I.TC_arrow (i,o)
let rec uncompile_expression : O.expression -> I.expression result =
let rec uncompile_expression' : O.expression -> I.expression result =
fun e ->
let return expr = ok @@ I.make_e ~loc:e.location expr in
match e.expression_content with
O.E_literal lit -> return @@ I.E_literal lit
| O.E_constant {cons_name;arguments} ->
let%bind arguments = bind_map_list uncompile_expression arguments in
let%bind arguments = bind_map_list uncompile_expression' arguments in
return @@ I.E_constant {cons_name;arguments}
| O.E_variable name -> return @@ I.E_variable name
| O.E_application {lamb; args} ->
let%bind lamb = uncompile_expression lamb in
let%bind args = uncompile_expression args in
let%bind lamb = uncompile_expression' lamb in
let%bind args = uncompile_expression' args in
return @@ I.E_application {lamb; args}
| O.E_lambda lambda ->
let%bind lambda = uncompile_lambda lambda in
@ -662,75 +690,75 @@ let rec uncompile_expression : O.expression -> I.expression result =
| O.E_let_in {let_binder;inline;rhs;let_result} ->
let (binder,ty_opt) = let_binder in
let%bind ty_opt = bind_map_option uncompile_type_expression ty_opt in
let%bind rhs = uncompile_expression rhs in
let%bind let_result = uncompile_expression let_result in
let%bind rhs = uncompile_expression' rhs in
let%bind let_result = uncompile_expression' let_result in
return @@ I.E_let_in {let_binder=(binder,ty_opt);inline;rhs;let_result}
| O.E_constructor {constructor;element} ->
let%bind element = uncompile_expression element in
let%bind element = uncompile_expression' element in
return @@ I.E_constructor {constructor;element}
| O.E_matching {matchee; cases} ->
let%bind matchee = uncompile_expression matchee in
let%bind matchee = uncompile_expression' matchee in
let%bind cases = uncompile_matching cases in
return @@ I.E_matching {matchee;cases}
| O.E_record record ->
let record = I.LMap.to_kv_list record in
let%bind record =
bind_map_list (fun (k,v) ->
let%bind v = uncompile_expression v in
let%bind v = uncompile_expression' v in
ok @@ (k,v)
) record
in
return @@ I.E_record (O.LMap.of_list record)
| O.E_record_accessor {record;path} ->
let%bind record = uncompile_expression record in
let%bind record = uncompile_expression' record in
return @@ I.E_record_accessor {record;path}
| O.E_record_update {record;path;update} ->
let%bind record = uncompile_expression record in
let%bind update = uncompile_expression update in
let%bind record = uncompile_expression' record in
let%bind update = uncompile_expression' update in
return @@ I.E_record_update {record;path;update}
| O.E_tuple tuple ->
let%bind tuple = bind_map_list uncompile_expression tuple in
let%bind tuple = bind_map_list uncompile_expression' tuple in
return @@ I.E_tuple tuple
| O.E_tuple_accessor {tuple;path} ->
let%bind tuple = uncompile_expression tuple in
let%bind tuple = uncompile_expression' tuple in
return @@ I.E_tuple_accessor {tuple;path}
| O.E_tuple_update {tuple;path;update} ->
let%bind tuple = uncompile_expression tuple in
let%bind update = uncompile_expression update in
let%bind tuple = uncompile_expression' tuple in
let%bind update = uncompile_expression' update in
return @@ I.E_tuple_update {tuple;path;update}
| O.E_map map ->
let%bind map = bind_map_list (
bind_map_pair uncompile_expression
bind_map_pair uncompile_expression'
) map
in
return @@ I.E_map map
| O.E_big_map big_map ->
let%bind big_map = bind_map_list (
bind_map_pair uncompile_expression
bind_map_pair uncompile_expression'
) big_map
in
return @@ I.E_big_map big_map
| O.E_list lst ->
let%bind lst = bind_map_list uncompile_expression lst in
let%bind lst = bind_map_list uncompile_expression' lst in
return @@ I.E_list lst
| O.E_set set ->
let%bind set = bind_map_list uncompile_expression set in
let%bind set = bind_map_list uncompile_expression' set in
return @@ I.E_set set
| O.E_look_up look_up ->
let%bind look_up = bind_map_pair uncompile_expression look_up in
let%bind look_up = bind_map_pair uncompile_expression' look_up in
return @@ I.E_look_up look_up
| O.E_ascription {anno_expr; type_annotation} ->
let%bind anno_expr = uncompile_expression anno_expr in
let%bind anno_expr = uncompile_expression' anno_expr in
let%bind type_annotation = uncompile_type_expression type_annotation in
return @@ I.E_ascription {anno_expr; type_annotation}
| O.E_cond {condition;then_clause;else_clause} ->
let%bind condition = uncompile_expression condition in
let%bind then_clause = uncompile_expression then_clause in
let%bind else_clause = uncompile_expression else_clause in
let%bind condition = uncompile_expression' condition in
let%bind then_clause = uncompile_expression' then_clause in
let%bind else_clause = uncompile_expression' else_clause in
return @@ I.E_cond {condition; then_clause; else_clause}
| O.E_sequence {expr1; expr2} ->
let%bind expr1 = uncompile_expression expr1 in
let%bind expr2 = uncompile_expression expr2 in
let%bind expr1 = uncompile_expression' expr1 in
let%bind expr2 = uncompile_expression' expr2 in
return @@ I.E_sequence {expr1; expr2}
| O.E_skip -> return @@ I.E_skip
@ -738,32 +766,32 @@ and uncompile_lambda : O.lambda -> I.lambda result =
fun {binder;input_type;output_type;result}->
let%bind input_type = bind_map_option uncompile_type_expression input_type in
let%bind output_type = bind_map_option uncompile_type_expression output_type in
let%bind result = uncompile_expression result in
let%bind result = uncompile_expression' result in
ok @@ I.{binder;input_type;output_type;result}
and uncompile_matching : O.matching_expr -> I.matching_expr result =
fun m ->
match m with
| O.Match_bool {match_true;match_false} ->
let%bind match_true = uncompile_expression match_true in
let%bind match_false = uncompile_expression match_false in
let%bind match_true = uncompile_expression' match_true in
let%bind match_false = uncompile_expression' match_false in
ok @@ I.Match_bool {match_true;match_false}
| O.Match_list {match_nil;match_cons} ->
let%bind match_nil = uncompile_expression match_nil in
let%bind match_nil = uncompile_expression' match_nil in
let (hd,tl,expr,tv) = match_cons in
let%bind expr = uncompile_expression expr in
let%bind expr = uncompile_expression' expr in
ok @@ I.Match_list {match_nil; match_cons=(hd,tl,expr,tv)}
| O.Match_option {match_none;match_some} ->
let%bind match_none = uncompile_expression match_none in
let%bind match_none = uncompile_expression' match_none in
let (n,expr,tv) = match_some in
let%bind expr = uncompile_expression expr in
let%bind expr = uncompile_expression' expr in
ok @@ I.Match_option {match_none; match_some=(n,expr,tv)}
| O.Match_tuple ((lst,expr), tv) ->
let%bind expr = uncompile_expression expr in
let%bind expr = uncompile_expression' expr in
ok @@ O.Match_tuple ((lst,expr), tv)
| O.Match_variant (lst,tv) ->
let%bind lst = bind_map_list (
fun ((c,n),expr) ->
let%bind expr = uncompile_expression expr in
let%bind expr = uncompile_expression' expr in
ok @@ ((c,n),expr)
) lst
in

View File

@ -702,9 +702,21 @@ module Typer = struct
[i ; j ; s] ()
let failwith_ = typer_1_opt "FAILWITH" @@ fun t opt ->
let%bind () =
Assert.assert_true @@
(is_t_string t) in
let%bind _ =
if eq_1 t (t_string ())
then ok ()
else if eq_1 t (t_nat ())
then ok ()
else if eq_1 t (t_int ())
then ok ()
else
fail @@ Operator_errors.typeclass_error "Failwith with disallowed type" "failwith"
[
[t_string()] ;
[t_nat()] ;
[t_int()] ;
]
[t] () in
let default = t_unit () in
ok @@ Simple_utils.Option.unopt ~default opt

View File

@ -118,7 +118,7 @@ let e_lambda ?loc binder input_type output_type result : expression = make_e ?lo
let e_recursive ?loc fun_name fun_type lambda = make_e ?loc @@ E_recursive {fun_name; fun_type; lambda}
let e_let_in ?loc (binder, ascr) mut inline rhs let_result = make_e ?loc @@ E_let_in { let_binder = (binder, ascr) ; rhs ; let_result; inline; mut }
let e_constructor ?loc s a : expression = make_e ?loc @@ E_constructor { constructor = Constructor s; element = a}
let e_constructor ?loc s a : expression = make_e ?loc @@ E_constructor { constructor = s; element = a}
let e_matching ?loc a b : expression = make_e ?loc @@ E_matching {matchee=a;cases=b}
let e_record ?loc map : expression = make_e ?loc @@ E_record map

View File

@ -68,7 +68,7 @@ val e_some : ?loc:Location.t -> expression -> expression
val e_none : ?loc:Location.t -> unit -> expression
val e_variable : ?loc:Location.t -> expression_variable -> expression
val e_constructor : ?loc:Location.t -> string -> expression -> expression
val e_constructor : ?loc:Location.t -> constructor' -> expression -> expression
val e_constant : ?loc:Location.t -> constant' -> expression list -> expression
val e_lambda : ?loc:Location.t -> expression_variable -> type_expression option -> type_expression option -> expression -> expression

View File

@ -527,3 +527,8 @@ let program_environment (program : program) : full_environment =
let last_declaration = Location.unwrap List.(hd @@ rev program) in
match last_declaration with
| Declaration_constant { binder=_ ; expr=_ ; inline=_ ; post_env } -> post_env
let equal_variables a b : bool =
match a.expression_content, b.expression_content with
| E_variable a, E_variable b -> Var.equal a b
| _, _ -> false

View File

@ -10,6 +10,8 @@ val merge_annotation : type_expression option -> type_expression option -> error
(* No information about what made it fail *)
val type_expression_eq : ( type_expression * type_expression ) -> bool
val equal_variables : expression -> expression -> bool
module Free_variables : sig
type bindings = expression_variable list

View File

@ -0,0 +1,11 @@
(* should return a constant function *)
let f1 (x : unit) : unit -> tez =
let amt : tez = Current.amount in
fun (x : unit) -> amt
(* should return an impure function *)
let f2 (x : unit) : unit -> tez =
fun (x : unit) -> Current.amount
let main (b,s : bool * (unit -> tez)) : operation list * (unit -> tez) =
(([] : operation list), (if b then f1 () else f2 ()))

View File

@ -29,7 +29,7 @@ function foobar (const i : int) : int is
}
else
case p of
Zero (n) -> failwith ("wooo")
Zero (n) -> failwith(42n)
| Pos (n) -> skip
end
} with
@ -39,5 +39,5 @@ function foobar (const i : int) : int is
end
function failer (const p : int) : int is block {
if p = 1 then failwith ("some_string") else skip
if p = 1 then failwith (42) else skip
} with p

View File

@ -0,0 +1,2 @@
const bad : unit = failwith((nil : list(int)))

View File

@ -0,0 +1,8 @@
let y (_ : unit) : nat =
let x : nat = 1n in
begin
(let x : nat = 2n in unit) ;
(let x : nat = 23n in unit) ;
(let x : nat = 42n in unit) ;
x
end

View File

@ -1192,6 +1192,10 @@ let condition_religo () : unit result =
] in
ok ()
let sequence_mligo () : unit result =
let%bind program = mtype_file "./contracts/sequence.mligo" in
expect_eq program "y" (e_unit ()) (e_nat 1)
let eq_bool_common program =
let%bind _ =
bind_map_list (fun ( a , b , expected ) ->
@ -2390,6 +2394,7 @@ let main = test_suite "Integration (End to End)" [
test "condition (ligo)" condition ;
test "condition (mligo)" condition_mligo ;
test "condition (religo)" condition_religo ;
test "sequence (mligo" sequence_mligo ;
test "eq bool (ligo)" eq_bool ;
test "eq bool (mligo)" eq_bool_mligo ;
test "eq bool (religo)" eq_bool_religo ;

View File

@ -0,0 +1,8 @@
{
"presets": [
"@babel/preset-react",
"@babel/preset-env",
"@babel/preset-typescript"
],
"plugins": ["@babel/plugin-transform-react-jsx"]
}

6
tools/compact-ligo-ide/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*.log
node_modules/
lib/
.cache/
dist/

View File

@ -0,0 +1,9 @@
src
demo
*.lock
.babelrc
.gitignore
webpack.config.js
tsconfig.json
webpack.config.js

View File

@ -0,0 +1,194 @@
A React component for embedding Ligo code snippets on a page.
# Quick start
1. Install package `yarn add @ligolang/compact-ligo-ide`
2. Add `CompactLigoIde` component to a page
```jsx
import { Code, Language } from "@ligolang/compact-ligo-ide";
const App = () => {
const codeWithConfig = `(*_*
name: CameLigo Contract
dryRun:
entrypoint: main
parameters: Increment 2
storage: 0
*_*)
// variant defining pseudo multi-entrypoint actions
type action is
| Increment of int
| Decrement of int
function add (const a : int ; const b : int) : int is
block { skip } with a + b
function subtract (const a : int ; const b : int) : int is
block { skip } with a - b
// real entrypoint that re-routes the flow based
// on the action provided
function main (const p : action ; const s : int) :
(list(operation) * int) is
block { skip } with ((nil : list(operation)),
case p of
| Increment(n) -> add(s, n)
| Decrement(n) -> subtract(s, n)
end)`;
const editor = {
title: 'Smart Contract',
language: Language.CameLigo
};
const compile = {
entrypoint: 'main'
};
const dryRun = {
entrypoint: 'main',
parameters: 'Increment 1',
storage: '0'
};
const deploy = {
entrypoint: 'main',
storage: '0'
};
const evaluateFunction = {
entrypoint: 'add',
parameters: '5, 3'
};
return <CompactLigoIde
theme="light"
editor={editor}
compile={compile}
dryRun={dryRun}
deploy={deploy}
evaluateFunction={evaluateFunction}>
{codeWithConfig}
</CompactLigoIde>
};
```
3. Apply styling
```css
<style type="text/css">
.compactLigoIde {
height: 600px;
width: 600px;
}
</style>
```
# Configuration
Compact Ligo IDE can be configured via component parameters and/or by passing configuration as a child. The example above illustrastes how to do so.
## Available configuration
```js
interface CompactLigoIdeProps {
editor?: Partial<EditorConfig>;
compile?: Partial<CompileConfig>;
dryRun?: Partial<DryRunConfig>;
deploy?: Partial<DeployConfig>;
evaluateFunction?: Partial<EvaluateFunctionConfig>;
evaluateValue?: Partial<EvaluateValueConfig>;
result?: string;
webIdeUrl?: string;
theme?: "dark" | "light";
children?: string;
}
interface EditorConfig {
language: Language;
code: string;
dirty: boolean;
title: string;
}
interface CompileConfig {
entrypoint: string;
}
interface DryRunConfig {
entrypoint: string;
parameters: string;
storage: string;
}
interface DeployConfig {
entrypoint: string;
storage: string;
}
interface EvaluateFunctionConfig {
entrypoint: string;
parameters: string;
}
interface EvaluateValueConfig {
entrypoint: string;
}
```
Alternatively, the component can be configured by passing the configuration like so:
```
(*_*
name: PascaLIGO Contract
language: pascaligo
compile:
entrypoint: main
dryRun:
entrypoint: main
parameters: Increment (1)
storage: 0
deploy:
entrypoint: main
storage: 0
evaluateValue:
entrypoint: ""
evaluateFunction:
entrypoint: add
parameters: (5, 6)
*_*)
// variant defining pseudo multi-entrypoint actions
type action is
| Increment of int
| Decrement of int
function add (const a : int ; const b : int) : int is
block { skip } with a + b
function subtract (const a : int ; const b : int) : int is
block { skip } with a - b
// real entrypoint that re-routes the flow based
// on the action provided
function main (const p : action ; const s : int) :
(list(operation) * int) is
block { skip } with ((nil : list(operation)),
case p of
| Increment(n) -> add(s, n)
| Decrement(n) -> subtract(s, n)
end)
```
# Contribute
## Starting dev server
1. Install dependencies with `yarn install`
2. Run `yarn start`
3. Open http://localhost:1234 in a browser
## Build package
Run `yarn build`.
## Publish package
Run `npm publish --access=public`.

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>React TypeScript App</title>
<style type="text/css">
.compactLigoIde {
height: 400px;
width: 600px;
}
</style>
</head>
<body>
<div id="root"></div>
<script src="./index.tsx"></script>
</body>
</html>

View File

@ -0,0 +1,73 @@
import React, { useState } from 'react';
import { render } from 'react-dom';
import { CompactLigoIde, Language } from '../src';
const App = () => {
const codeWithConfig = `(*_*
name: CameLigo Contract
dryRun:
entrypoint: main
parameters: Increment 2
storage: 0
*_*)
// variant defining pseudo multi-entrypoint actions
type action is
| Increment of int
| Decrement of int
function add (const a : int ; const b : int) : int is
block { skip } with a + b
function subtract (const a : int ; const b : int) : int is
block { skip } with a - b
// real entrypoint that re-routes the flow based
// on the action provided
function main (const p : action ; const s : int) :
(list(operation) * int) is
block { skip } with ((nil : list(operation)),
case p of
| Increment(n) -> add(s, n)
| Decrement(n) -> subtract(s, n)
end)`;
const editor = {
title: 'Smart Contract',
language: Language.CameLigo
};
const compile = {
entrypoint: 'main'
};
const dryRun = {
entrypoint: 'main',
parameters: 'Increment 1',
storage: '0'
};
const deploy = {
entrypoint: 'main',
storage: '0'
};
const evaluateFunction = {
entrypoint: 'add',
parameters: '5, 3'
};
const [theme, setTheme] = useState('light');
return <>
<button onClick={() => theme === 'light' ? setTheme('dark') : setTheme('light')}>Toggle Theme</button>
<CompactLigoIde
theme={theme}
editor={editor}
compile={compile}
dryRun={dryRun}
deploy={deploy}
evaluateFunction={evaluateFunction}>
{codeWithConfig}
</CompactLigoIde>
</>;
};
render(<App />, document.getElementById("root"));

View File

@ -0,0 +1,55 @@
{
"name": "@ligolang/compact-ligo-ide",
"version": "3.0.3",
"main": "./lib/index.js",
"scripts": {
"start": "parcel ./demo/index.html",
"build": "webpack"
},
"typings": "./typings/index.d.ts",
"files": [
"lib",
"typings/index.d.ts"
],
"license": "ISC",
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.7",
"@babel/plugin-transform-react-jsx": "^7.8.3",
"@babel/preset-env": "^7.8.7",
"@babel/preset-react": "^7.8.3",
"@babel/preset-typescript": "^7.8.3",
"@types/node": "^13.9.5",
"@types/react": "^16.9.23",
"@types/react-dom": "^16.9.5",
"@types/styled-components": "^5.0.1",
"babel-loader": "8.0.6",
"css-loader": "^3.4.2",
"parcel-bundler": "^1.12.4",
"path": "^0.12.7",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"style-loader": "^1.1.3",
"typescript": "^3.8.3",
"webpack": "4.41.5",
"webpack-cli": "^3.3.11",
"webpack-node-externals": "^1.7.2"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/react-fontawesome": "^0.1.9",
"@types/react-helmet": "^5.0.15",
"@types/styled-theming": "^2.2.2",
"axios": "^0.19.2",
"monaco-editor": "npm:@ligolang/monaco-editor@0.18.1",
"react-helmet": "^5.2.1",
"styled-components": "^5.0.1",
"styled-theming": "^2.2.0",
"yaml": "^1.9.2"
}
}

View File

@ -0,0 +1,145 @@
import axios from 'axios';
import React from 'react';
import styled, { ThemeProvider } from 'styled-components';
import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Editor } from './editor';
import { CompactLigoIdeProps, DEFAULT_COMPACT_LIGO_IDE_PROPS, ShareParams } from '../types';
import YAML from 'yaml';
const Container = styled.div`
position: relative;
display: flex;
flex-direction: column;
`;
const Button = styled.div`
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
position: absolute;
width: 60px;
height: 30px;
top: 0;
right: 0;
z-index: 1;
padding: 5px;
color: white;
:hover {
background: #fc683a;
}
`;
const Icon = styled(FontAwesomeIcon)`
pointer-events: none;
margin-left: 3px;
`;
const OutputContainer = styled.div`
position: relative;
`;
const Output = styled.pre`
background-color: rgba(14, 116, 255, 1);
color: white;
padding: 20px;
margin: 0;
overflow: auto;
max-height: 200px;
`;
function parseConfig(content: string): CompactLigoIdeProps {
const METADATA_REGEX = /\(\*_\*([^]*?)\*_\*\)\s*/;
const match = content.match(METADATA_REGEX);
if (!match || !match[1]) {
return { editor: { code: content } };
}
try {
const config = YAML.parse(match[1]);
return {
editor: {
title: config.name,
language: config.language,
code: content.replace(METADATA_REGEX, '')
},
compile: { ...config.compile },
dryRun: { ...config.dryRun },
deploy: { ...config.deploy },
evaluateFunction: { ...config.evaluateFunction },
evaluateValue: { ...config.evaluateValue }
};
} catch (ex) {
throw new Error(`Unable to parse configuration.`);
}
}
export function CompactLigoIde(props: CompactLigoIdeProps) {
const yamlConfig = props.children ? parseConfig(props.children) : {};
const shareParams: ShareParams = {
editor: {
...DEFAULT_COMPACT_LIGO_IDE_PROPS.editor,
...yamlConfig.editor,
...props.editor
},
compile: {
...DEFAULT_COMPACT_LIGO_IDE_PROPS.compile,
...yamlConfig.compile,
...props.compile
},
dryRun: {
...DEFAULT_COMPACT_LIGO_IDE_PROPS.dryRun,
...yamlConfig.dryRun,
...props.dryRun
},
deploy: {
...DEFAULT_COMPACT_LIGO_IDE_PROPS.deploy,
...yamlConfig.deploy,
...props.deploy
},
evaluateFunction: {
...DEFAULT_COMPACT_LIGO_IDE_PROPS.evaluateFunction,
...yamlConfig.evaluateFunction,
...props.evaluateFunction
},
evaluateValue: {
...DEFAULT_COMPACT_LIGO_IDE_PROPS.evaluateValue,
...yamlConfig.evaluateValue,
...props.evaluateValue
}
};
const result = props.result || DEFAULT_COMPACT_LIGO_IDE_PROPS.result;
const webIdeUrl = props.webIdeUrl || DEFAULT_COMPACT_LIGO_IDE_PROPS.webIdeUrl;
const theme = props.theme || DEFAULT_COMPACT_LIGO_IDE_PROPS.theme;
async function openInIde() {
const response = await axios.post(`${webIdeUrl}/api/share`, { ...shareParams });
const { hash } = await response.data;
window.open(`${webIdeUrl}/p/${hash}`, "_blank");
}
return (
<ThemeProvider theme={{ mode: theme }}>
<Container className="compactLigoIde">
<Editor
value={shareParams.editor.code}
language={shareParams.editor.language}
></Editor>
<OutputContainer>
<Output>{result}</Output>
<Button onClick={openInIde} title="Open in Ligo Web IDE">
<span>IDE<Icon icon={faExternalLinkAlt} /></span>
</Button>
</OutputContainer>
</Container>
</ThemeProvider>
);
};

View File

@ -0,0 +1,83 @@
import * as monaco from 'monaco-editor';
import React, { useEffect, useRef, useState } from 'react';
import { Helmet } from 'react-helmet';
import styled, { withTheme } from 'styled-components';
const Container = styled.div`
flex: 2;
`;
export const Editor = withTheme(
(props: {
value: string;
language?: string;
onChange?: (value: string) => void;
theme: { mode: string };
}) => {
let containerRef = useRef(null);
const isLightTheme = props.theme.mode === 'light';
const background = isLightTheme ? "#eff7ff" : "#3b454e40";
const lineHighlightBackground = isLightTheme ? "#cee3ff" : "#63768840";
const lineNumberColor = "#888";
const model = monaco.editor.createModel(props.value, props.language);
monaco.editor.defineTheme("ligoTheme", {
base: "vs",
inherit: true,
rules: [],
colors: {
"editor.background": background,
"editor.lineHighlightBackground": lineHighlightBackground,
"editorLineNumber.foreground": lineNumberColor
}
});
monaco.editor.setTheme("ligoTheme");
useEffect(() => {
const cleanupFunc: Array<() => void> = [];
const htmlElement = (containerRef.current as unknown) as HTMLElement;
const editor = monaco.editor.create(htmlElement, {
readOnly: true,
model: model,
automaticLayout: true,
minimap: {
enabled: false
}
});
const { dispose } = editor.onDidChangeModelContent(() => {
if (props.onChange) {
props.onChange(editor.getValue());
}
});
cleanupFunc.push(dispose);
return function cleanUp() {
cleanupFunc.forEach(f => f());
};
}, []);
return (
<Container ref={containerRef}>
<Helmet>
<style type="text/css">
{`
.monaco-editor .current-line ~ .line-numbers {
color: ${lineNumberColor};
}
.monaco-editor .margin-view-overlays .current-line,
.monaco-editor .view-overlays .current-line {
background-color: ${lineHighlightBackground};
}
`}
</style>
</Helmet>
</Container>
);
}
);

View File

@ -0,0 +1,2 @@
export { CompactLigoIde } from './components/compact-ligo-ide';
export * from './types';

View File

@ -0,0 +1,105 @@
export enum Language {
PascaLigo = 'pascaligo',
CameLigo = 'cameligo',
ReasonLigo = 'reasonligo'
};
export interface ShareParams {
editor: EditorConfig;
compile: CompileConfig;
dryRun: DryRunConfig;
deploy: DeployConfig;
evaluateFunction: EvaluateFunctionConfig;
evaluateValue: EvaluateValueConfig;
}
export interface EditorConfig {
language: Language;
code: string;
dirty: boolean;
title: string;
}
export interface CompileConfig {
entrypoint: string;
}
export interface DryRunConfig {
entrypoint: string;
parameters: string;
storage: string;
}
export interface DeployConfig {
entrypoint: string;
storage: string;
}
export interface EvaluateFunctionConfig {
entrypoint: string;
parameters: string;
}
export interface EvaluateValueConfig {
entrypoint: string;
}
export interface CompactLigoIdeProps {
editor?: Partial<EditorConfig>;
compile?: Partial<CompileConfig>;
dryRun?: Partial<DryRunConfig>;
deploy?: Partial<DeployConfig>;
evaluateFunction?: Partial<EvaluateFunctionConfig>;
evaluateValue?: Partial<EvaluateValueConfig>;
result?: string;
webIdeUrl?: string;
theme?: "dark" | "light";
children?: string;
}
export const DEFAULT_EDITOR_CONFIG: EditorConfig = {
code: "",
language: Language.PascaLigo,
dirty: true,
title: ""
};
export const DEFAULT_COMPILE_CONFIG: CompileConfig = {
entrypoint: ""
};
export const DEFAULT_DRY_RUN_CONFIG: DryRunConfig = {
entrypoint: "",
parameters: "",
storage: ""
};
export const DEFAULT_DEPLOY_CONFIG: DeployConfig = {
entrypoint: "",
storage: ""
};
export const DEFAULT_EVALUATE_FUNCTION_CONFIG: EvaluateFunctionConfig = {
entrypoint: "",
parameters: ""
};
export const DEFAULT_EVALUATE_VALUE_CONFIG: EvaluateValueConfig = {
entrypoint: ""
};
export const DEFAULT_SHARE_PARAMS: ShareParams = {
editor: DEFAULT_EDITOR_CONFIG,
compile: DEFAULT_COMPILE_CONFIG,
dryRun: DEFAULT_DRY_RUN_CONFIG,
deploy: DEFAULT_DEPLOY_CONFIG,
evaluateFunction: DEFAULT_EVALUATE_FUNCTION_CONFIG,
evaluateValue: DEFAULT_EVALUATE_VALUE_CONFIG
};
export const DEFAULT_COMPACT_LIGO_IDE_PROPS: (ShareParams & CompactLigoIdeProps) = {
...DEFAULT_SHARE_PARAMS,
result: '',
webIdeUrl: process.env.NODE_ENV === 'production' ? 'https://ide.ligolang.org' : 'http://localhost:8080',
theme: 'light'
};

View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}

View File

@ -0,0 +1,5 @@
import { StatelessComponent } from 'react';
declare const Boilerplate: StatelessComponent;
export { Boilerplate };

View File

@ -0,0 +1,29 @@
const path = require('path');
const nodeExternals = require("webpack-node-externals");
module.exports = {
mode: 'production',
entry: './src/index.tsx',
output: {
path: path.resolve('lib'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.(t|j)sx?$/,
exclude: /(node_modules)/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
]
},
externals: [nodeExternals()],
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="180" height="180">
<path d="M180 90C180 139.706 139.706 180 90 180C40.2944 180 0 139.706 0 90C0 40.2944 40.2944 0 90 0C139.706 0 180 40.2944 180 90Z" fill="#C4C4C4"/>
</mask>
<g mask="url(#mask0)">
<path d="M0 0H89.8213C139.625 0 179.998 40.3736 179.998 90.1769V180H0V0Z" fill="#3AA0FF"/>
<mask id="mask1" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="180" height="180">
<path d="M0 0H89.8213C139.625 0 179.998 40.3736 179.998 90.1769V180H0V0Z" fill="#C4C4C4"/>
</mask>
<g mask="url(#mask1)">
<path d="M-97.3224 277.21L218.678 -38.7931L358.935 101.465L42.934 417.468L-97.3224 277.21Z" fill="#2888FF"/>
</g>
<path d="M63.2759 116.724V0H0V116.724V180H63.2759H179.998V116.724H63.2759Z" fill="#0E74FF"/>
<mask id="mask2" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="180" height="180">
<path d="M63.2759 116.724V0H0V116.724V180H63.2759H179.998V116.724H63.2759Z" fill="black"/>
</mask>
<g mask="url(#mask2)">
<path d="M-77.562 257.039L238.438 -58.9644L378.695 81.2934L62.6944 397.297L-77.562 257.039Z" fill="#0540FF"/>
</g>
<mask id="mask3" mask-type="alpha" maskUnits="userSpaceOnUse" x="90" y="0" width="90" height="91">
<path d="M90.0007 0.000366211C139.706 0.000366211 180 40.2952 180 90.0004H90.0007V0.000366211Z" fill="#AAA4A4"/>
</mask>
<g mask="url(#mask3)">
<path d="M125.584 -44.9172H224.893V54.3931H125.584V-44.9172Z" fill="#B4DBFF"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/logo.svg" />
<link rel="icon" href="%PUBLIC_URL%/circle.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="The LIGO Playground for learning LIGO" />

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,13 +1,14 @@
import React from 'react';
import styled, { css } from 'styled-components';
import styled from 'styled-components';
const Container = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.2em 1em;
padding: 0.5em 1em;
font-family: 'DM Sans', 'Open Sans', sans-serif;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.3);
`;
@ -16,42 +17,27 @@ const Group = styled.div`
align-items: center;
`;
const Logo = styled.div`
font-size: 1.25em;
const Logo = styled.img`
height: 32px;
`;
const Link = styled.a`
text-decoration: none;
color: black;
padding: 0.5em 1em;
padding: 0em 1em;
&:hover {
color: #3aa0ff;
color: #0e74ff;
}
${(props: { versionStyle?: boolean }) =>
props.versionStyle &&
css`
background-color: #efefef;
font-weight: 600;
margin-left: 3em;
&:hover {
color: black;
}
`}
`;
export const HeaderComponent = () => {
return (
<Container>
<Group>
<Link href="https://ligolang.org">
<Logo>LIGO</Logo>
</Link>
<Link versionStyle href="https://ligolang.org/versions">
next
</Link>
<a href="https://ligolang.org">
<Logo src="logo.svg" />
</a>
</Group>
<Group>
<Link href="https://ligolang.org/docs/intro/installation">Docs</Link>

View File

@ -12,8 +12,10 @@ import generateCommand, { GenerateCommandState } from './generate-command';
import loading, { LoadingState } from './loading';
import result, { ResultState } from './result';
import share, { ShareState } from './share';
import version, { VersionState } from './version';
export interface AppState {
version: VersionState;
editor: EditorState;
share: ShareState;
compile: CompileState;
@ -40,5 +42,6 @@ export default combineReducers({
result,
command,
examples,
loading
loading,
version
});

View File

@ -0,0 +1,13 @@
export interface VersionState {
revision: string;
branch: string;
}
const DEFAULT_STATE: VersionState = {
revision: 'dev',
branch: 'dev'
};
export default (state = DEFAULT_STATE): VersionState => {
return state;
};

View File

@ -650,6 +650,15 @@
"@types/node": "*"
}
},
"@types/cors": {
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz",
"integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==",
"dev": true,
"requires": {
"@types/express": "*"
}
},
"@types/express": {
"version": "4.17.3",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz",
@ -752,12 +761,14 @@
"@types/node": {
"version": "10.14.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.21.tgz",
"integrity": "sha512-nuFlRdBiqbF+PJIEVxm2jLFcQWN7q7iWEJGsBV4n7v1dbI9qXB8im2pMMKMCUZe092sQb5SQft2DHfuQGK5hqQ=="
"integrity": "sha512-nuFlRdBiqbF+PJIEVxm2jLFcQWN7q7iWEJGsBV4n7v1dbI9qXB8im2pMMKMCUZe092sQb5SQft2DHfuQGK5hqQ==",
"dev": true
},
"@types/node-fetch": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.5.tgz",
"integrity": "sha512-IWwjsyYjGw+em3xTvWVQi5MgYKbRs0du57klfTaZkv/B24AEQ/p/IopNeqIYNy3EsfHOpg8ieQSDomPcsYMHpA==",
"dev": true,
"requires": {
"@types/node": "*",
"form-data": "^3.0.0"
@ -1056,7 +1067,8 @@
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
},
"atob": {
"version": "2.1.2",
@ -1225,6 +1237,11 @@
"file-uri-to-path": "1.0.0"
}
},
"bintrees": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz",
"integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ="
},
"bip39": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz",
@ -1672,6 +1689,7 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
@ -1767,6 +1785,15 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"create-error-class": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
@ -1965,7 +1992,8 @@
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"depd": {
"version": "1.1.2",
@ -2415,6 +2443,17 @@
}
}
},
"express-prometheus-middleware": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/express-prometheus-middleware/-/express-prometheus-middleware-0.8.5.tgz",
"integrity": "sha512-DhQZzp8RDZYh72zJCIr8/t5wY15hHpNQXAnr7xpuizOk+nolLDTpcqCIdHfkgXOwK/I29tMydiJzX686N6bzyw==",
"requires": {
"express": "^4.16.3",
"prom-client": "^11.1.1",
"response-time": "^2.3.2",
"url-value-parser": "^2.0.0"
}
},
"express-winston": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/express-winston/-/express-winston-4.0.3.tgz",
@ -2646,6 +2685,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
"integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@ -5165,6 +5205,11 @@
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-copy": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
@ -5256,6 +5301,11 @@
"ee-first": "1.1.1"
}
},
"on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -5533,6 +5583,14 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"prom-client": {
"version": "11.5.3",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.3.tgz",
"integrity": "sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==",
"requires": {
"tdigest": "^0.1.1"
}
},
"prompts": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz",
@ -5879,6 +5937,15 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true
},
"response-time": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/response-time/-/response-time-2.3.2.tgz",
"integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=",
"requires": {
"depd": "~1.1.0",
"on-headers": "~1.0.1"
}
},
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
@ -6551,6 +6618,14 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
"tdigest": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz",
"integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=",
"requires": {
"bintrees": "1.0.1"
}
},
"teeny-request": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.2.tgz",
@ -7131,6 +7206,11 @@
"prepend-http": "^1.0.1"
}
},
"url-value-parser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/url-value-parser/-/url-value-parser-2.0.1.tgz",
"integrity": "sha512-bexECeREBIueboLGM3Y1WaAzQkIn+Tca/Xjmjmfd0S/hFHSCEoFkNh0/D0l9G4K74MkEP/lLFRlYnxX3d68Qgw=="
},
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",

View File

@ -19,6 +19,8 @@
"@types/node": "10",
"@types/tmp": "^0.1.0",
"@types/winston": "^2.4.4",
"@types/cors": "^2.8.6",
"@types/node-fetch": "^2.5.4",
"jest": "^24.9.0",
"nodemon": "^1.19.3",
"ts-jest": "^24.1.0",
@ -32,10 +34,11 @@
"@google-cloud/storage": "^4.0.0",
"@hapi/joi": "^16.1.7",
"@taquito/taquito": "^6.1.0-beta.0",
"@types/node-fetch": "^2.5.4",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"escape-html": "^1.0.3",
"express": "^4.17.1",
"express-prometheus-middleware": "^0.8.5",
"express-winston": "^4.0.1",
"node-fetch": "^2.6.0",
"sanitize-html": "^1.20.1",

View File

@ -1,3 +1,4 @@
import cors from 'cors';
import express from 'express';
import fs from 'fs';
import { dirname, join } from 'path';
@ -13,12 +14,26 @@ import { shareHandler } from './handlers/share';
import { sharedLinkHandler } from './handlers/shared-link';
import { loadDefaultState } from './load-state';
import { errorLoggerMiddleware, loggerMiddleware } from './logger';
require('./metrics');
var bodyParser = require('body-parser');
var escape = require('escape-html');
const bodyParser = require('body-parser');
const escape = require('escape-html');
const prometheus = require('express-prometheus-middleware');
const app = express();
const port = 8080;
const APP_PORT = 8080;
const metrics = express();
const METRICS_PORT = 8081;
const corsOptions = {
origin: [
'https://ligolang.org',
'http://localhost:3000',
'http://localhost:1234'
],
optionsSuccessStatus: 200
};
const appRootDirectory =
process.env['STATIC_ASSETS'] ||
@ -27,6 +42,15 @@ const appBundleDirectory = join(appRootDirectory, 'build');
app.use(bodyParser.json());
app.use(loggerMiddleware);
app.use(
prometheus({
metricsPath: '/metrics',
collectDefaultMetrics: true,
collectDefaultBuckets: true,
requestDurationBuckets: [0.5, 0.6, 0.7, 1, 10, 20, 30, 60],
metricsApp: metrics
})
);
const file = fs.readFileSync(join(appBundleDirectory, 'index.html'));
@ -46,6 +70,9 @@ app.use('^/$', async (_, res) =>
res.send(template(JSON.stringify(await loadDefaultState(appBundleDirectory))))
);
app.use(express.static(appBundleDirectory));
app.options('/api/share', cors(corsOptions));
app.get(
`/p/:hash([0-9a-zA-Z\-\_]+)`,
sharedLinkHandler(appBundleDirectory, template)
@ -54,13 +81,17 @@ app.post('/api/compile-contract', compileContractHandler);
app.post('/api/compile-expression', compileExpressionHandler);
app.post('/api/compile-storage', compileStorageHandler);
app.post('/api/dry-run', dryRunHandler);
app.post('/api/share', shareHandler);
app.post('/api/share', cors(corsOptions), shareHandler);
app.post('/api/evaluate-value', evaluateValueHandler);
app.post('/api/run-function', runFunctionHandler);
app.post('/api/deploy', deployHandler);
app.use(errorLoggerMiddleware);
app.listen(port, () => {
console.log(`Listening on: ${port}`);
app.listen(APP_PORT, () => {
console.log(`API listening on: ${APP_PORT}`);
});
metrics.listen(METRICS_PORT, () => {
console.log(`Metrics listening on: ${METRICS_PORT}`);
});

View File

@ -19,6 +19,10 @@ export async function loadDefaultState(appBundleDirectory: string) {
);
const examplesList = JSON.parse(examples);
const defaultState = {
version: {
branch: process.env['GIT_TAG'],
revision: process.env['GIT_COMMIT']
},
compile: {},
dryRun: {},
deploy: {},

View File

@ -0,0 +1,7 @@
const client = require('prom-client');
const gauge = new client.Gauge({
name: 'ligo_webide_build_info',
help: 'Ligo Web IDE build info',
labelNames: ['branch', 'revision']
}).labels(process.env['GIT_TAG'], process.env['GIT_COMMIT']);
gauge.set(1);

View File

@ -1471,6 +1471,13 @@
dependencies:
"@types/node" "*"
"@types/cors@^2.8.6":
version "2.8.6"
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.6.tgz#cfaab33c49c15b1ded32f235111ce9123009bd02"
integrity sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==
dependencies:
"@types/express" "*"
"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
@ -2582,6 +2589,11 @@ binary-extensions@^1.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==
bintrees@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.1.tgz#0e655c9b9c2435eaab68bf4027226d2b55a34524"
integrity sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=
bip39@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32"
@ -3491,6 +3503,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
cors@^2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
dependencies:
object-assign "^4"
vary "^1"
cosmiconfig@^5.0.0, cosmiconfig@^5.2.0, cosmiconfig@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
@ -4013,7 +4033,7 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
depd@~1.1.2:
depd@~1.1.0, depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
@ -4763,6 +4783,16 @@ expect@^24.9.0:
jest-message-util "^24.9.0"
jest-regex-util "^24.9.0"
express-prometheus-middleware@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/express-prometheus-middleware/-/express-prometheus-middleware-0.8.5.tgz#097b2871184e2bba997c5ce6db4eec289b61e192"
integrity sha512-DhQZzp8RDZYh72zJCIr8/t5wY15hHpNQXAnr7xpuizOk+nolLDTpcqCIdHfkgXOwK/I29tMydiJzX686N6bzyw==
dependencies:
express "^4.16.3"
prom-client "^11.1.1"
response-time "^2.3.2"
url-value-parser "^2.0.0"
express-winston@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/express-winston/-/express-winston-4.0.1.tgz#98c74d099b9a7fdeedc56eb839c223968bc33990"
@ -4771,7 +4801,7 @@ express-winston@^4.0.1:
chalk "^2.4.1"
lodash "^4.17.10"
express@^4.16.2, express@^4.17.1:
express@^4.16.2, express@^4.16.3, express@^4.17.1:
version "4.17.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
@ -8210,7 +8240,7 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@4.1.1, object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@ -8323,7 +8353,7 @@ on-finished@~2.3.0:
dependencies:
ee-first "1.1.1"
on-headers@~1.0.2:
on-headers@~1.0.1, on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
@ -9504,6 +9534,13 @@ progress@^2.0.0, progress@^2.0.1:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
prom-client@^11.1.1:
version "11.5.3"
resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-11.5.3.tgz#5fedfce1083bac6c2b223738e966d0e1643756f8"
integrity sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==
dependencies:
tdigest "^0.1.1"
promise-inflight@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
@ -10291,6 +10328,14 @@ resolve@1.12.0, resolve@1.x, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0,
dependencies:
path-parse "^1.0.6"
response-time@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/response-time/-/response-time-2.3.2.tgz#ffa71bab952d62f7c1d49b7434355fbc68dffc5a"
integrity sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=
dependencies:
depd "~1.1.0"
on-headers "~1.0.1"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@ -11301,6 +11346,13 @@ tar@^4:
safe-buffer "^5.1.2"
yallist "^3.0.3"
tdigest@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.1.tgz#2e3cb2c39ea449e55d1e6cd91117accca4588021"
integrity sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=
dependencies:
bintrees "1.0.1"
teeny-request@^5.2.1:
version "5.3.0"
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-5.3.0.tgz#c80287b5a51a7c25eef2347ff5467c95e07dac5a"
@ -11825,6 +11877,11 @@ url-parse@^1.4.3:
querystringify "^2.1.1"
requires-port "^1.0.0"
url-value-parser@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/url-value-parser/-/url-value-parser-2.0.1.tgz#c8179a095ab9ec1f5aa17ca36af5af396b4e95ed"
integrity sha512-bexECeREBIueboLGM3Y1WaAzQkIn+Tca/Xjmjmfd0S/hFHSCEoFkNh0/D0l9G4K74MkEP/lLFRlYnxX3d68Qgw==
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@ -11893,7 +11950,7 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vary@~1.1.2:
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=