Merge branch 'rinderknecht@code_inclusion' into 'dev'
Improved code injection See merge request ligolang/ligo!680
This commit is contained in:
commit
fb4a888867
@ -227,27 +227,27 @@ and field_pattern = {
|
||||
}
|
||||
|
||||
and expr =
|
||||
ECase of expr case reg
|
||||
| ECond of cond_expr reg
|
||||
| EAnnot of annot_expr par reg
|
||||
| ELogic of logic_expr
|
||||
| EArith of arith_expr
|
||||
| EString of string_expr
|
||||
| EList of list_expr
|
||||
| EConstr of constr_expr
|
||||
| ERecord of record reg
|
||||
| EProj of projection reg
|
||||
| EUpdate of update reg
|
||||
| EVar of variable
|
||||
| ECall of (expr * expr nseq) reg
|
||||
| EBytes of (string * Hex.t) reg
|
||||
| EUnit of the_unit reg
|
||||
| ETuple of (expr, comma) nsepseq reg
|
||||
| EPar of expr par reg
|
||||
| ELetIn of let_in reg
|
||||
| EFun of fun_expr reg
|
||||
| ESeq of expr injection reg
|
||||
| ECodeInsert of code_insert reg
|
||||
ECase of expr case reg
|
||||
| ECond of cond_expr reg
|
||||
| EAnnot of annot_expr par reg
|
||||
| ELogic of logic_expr
|
||||
| EArith of arith_expr
|
||||
| EString of string_expr
|
||||
| EList of list_expr
|
||||
| EConstr of constr_expr
|
||||
| ERecord of record reg
|
||||
| EProj of projection reg
|
||||
| EUpdate of update reg
|
||||
| EVar of variable
|
||||
| ECall of (expr * expr nseq) reg
|
||||
| EBytes of (string * Hex.t) reg
|
||||
| EUnit of the_unit reg
|
||||
| ETuple of (expr, comma) nsepseq reg
|
||||
| EPar of expr par reg
|
||||
| ELetIn of let_in reg
|
||||
| EFun of fun_expr reg
|
||||
| ESeq of expr injection reg
|
||||
| ECodeInj of code_inj reg
|
||||
|
||||
and annot_expr = expr * colon * type_expr
|
||||
|
||||
@ -400,13 +400,16 @@ and cond_expr = {
|
||||
ifnot : expr
|
||||
}
|
||||
|
||||
and code_insert = {
|
||||
lbracket : lbracket;
|
||||
percent : percent;
|
||||
language : string reg;
|
||||
code : expr;
|
||||
rbracket : rbracket;
|
||||
(* Code injection. Note how the field [language] wraps a region in
|
||||
another: the outermost region covers the header "[%<language>" and
|
||||
the innermost covers the <language>. *)
|
||||
|
||||
and code_inj = {
|
||||
language : string reg reg;
|
||||
code : expr;
|
||||
rbracket : rbracket;
|
||||
}
|
||||
|
||||
(* Projecting regions from some nodes of the AST *)
|
||||
|
||||
let rec last to_region = function
|
||||
@ -490,8 +493,8 @@ let expr_to_region = function
|
||||
| ECond {region;_} | ETuple {region;_} | ECase {region;_}
|
||||
| ECall {region;_} | EVar {region; _} | EProj {region; _}
|
||||
| EUnit {region;_} | EPar {region;_} | EBytes {region; _}
|
||||
| ESeq {region; _} | ERecord {region; _} | EUpdate {region; _}
|
||||
| ECodeInsert {region; _} -> region
|
||||
| ESeq {region; _} | ERecord {region; _} | EUpdate {region; _}
|
||||
| ECodeInj {region; _} -> region
|
||||
|
||||
let declaration_to_region = function
|
||||
| Let {region;_}
|
||||
|
@ -29,9 +29,22 @@ type lexeme = string
|
||||
(* TOKENS *)
|
||||
|
||||
type t =
|
||||
(* Symbols *)
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
ARROW of Region.t (* "->" *)
|
||||
Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
| Lang of lexeme Region.reg Region.reg
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
| ARROW of Region.t (* "->" *)
|
||||
| CONS of Region.t (* "::" *)
|
||||
| CAT of Region.t (* "^" *)
|
||||
(*| APPEND (* "@" *)*)
|
||||
@ -42,7 +55,6 @@ type t =
|
||||
| PLUS of Region.t (* "+" *)
|
||||
| SLASH of Region.t (* "/" *)
|
||||
| TIMES of Region.t (* "*" *)
|
||||
| PERCENT of Region.t (* "%" *)
|
||||
|
||||
(* Compounds *)
|
||||
|
||||
@ -77,18 +89,6 @@ type t =
|
||||
| BOOL_OR of Region.t (* "||" *)
|
||||
| BOOL_AND of Region.t (* "&&" *)
|
||||
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
(*| And*)
|
||||
@ -155,6 +155,7 @@ val mk_verbatim : lexeme -> Region.t -> token
|
||||
val mk_bytes : lexeme -> Region.t -> token
|
||||
val mk_constr : lexeme -> Region.t -> token
|
||||
val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
|
||||
val mk_lang : lexeme Region.reg -> Region.t -> token
|
||||
val eof : Region.t -> token
|
||||
|
||||
(* Predicates *)
|
||||
|
@ -13,9 +13,22 @@ module SSet = Utils.String.Set
|
||||
(* TOKENS *)
|
||||
|
||||
type t =
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
| Lang of lexeme Region.reg Region.reg
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
ARROW of Region.t (* "->" *)
|
||||
| ARROW of Region.t (* "->" *)
|
||||
| CONS of Region.t (* "::" *)
|
||||
| CAT of Region.t (* "^" *)
|
||||
(*| APPEND (* "@" *)*)
|
||||
@ -26,7 +39,6 @@ type t =
|
||||
| PLUS of Region.t (* "+" *)
|
||||
| SLASH of Region.t (* "/" *)
|
||||
| TIMES of Region.t (* "*" *)
|
||||
| PERCENT of Region.t (* "%" *)
|
||||
|
||||
(* Compounds *)
|
||||
|
||||
@ -61,18 +73,6 @@ type t =
|
||||
| BOOL_OR of Region.t (* "||" *)
|
||||
| BOOL_AND of Region.t (* "&&" *)
|
||||
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
(*| And*)
|
||||
@ -113,26 +113,28 @@ let proj_token = function
|
||||
(* Literals *)
|
||||
|
||||
String Region.{region; value} ->
|
||||
region, sprintf "String %s" value
|
||||
region, sprintf "String %S" value
|
||||
| Verbatim Region.{region; value} ->
|
||||
region, sprintf "Verbatim {|%s|}" value
|
||||
region, sprintf "Verbatim %S" value
|
||||
| Bytes Region.{region; value = s,b} ->
|
||||
region,
|
||||
sprintf "Bytes (\"%s\", \"0x%s\")" s (Hex.show b)
|
||||
sprintf "Bytes (%S, \"0x%s\")" s (Hex.show b)
|
||||
| Int Region.{region; value = s,n} ->
|
||||
region, sprintf "Int (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Int (%S, %s)" s (Z.to_string n)
|
||||
| Nat Region.{region; value = s,n} ->
|
||||
region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Nat (%S, %s)" s (Z.to_string n)
|
||||
| Mutez Region.{region; value = s,n} ->
|
||||
region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Mutez (%S, %s)" s (Z.to_string n)
|
||||
| Ident Region.{region; value} ->
|
||||
region, sprintf "Ident %s" value
|
||||
region, sprintf "Ident %S" value
|
||||
| Constr Region.{region; value} ->
|
||||
region, sprintf "Constr %s" value
|
||||
region, sprintf "Constr %S" value
|
||||
| Attr Region.{region; value} ->
|
||||
region, sprintf "Attr \"%s\"" value
|
||||
region, sprintf "Attr %S" value
|
||||
| Lang Region.{region; value} ->
|
||||
region, sprintf "Lang %S" (value.Region.value)
|
||||
|
||||
(* Symbols *)
|
||||
(* Symbols *)
|
||||
|
||||
| ARROW region -> region, "ARROW"
|
||||
| CONS region -> region, "CONS"
|
||||
@ -141,7 +143,6 @@ let proj_token = function
|
||||
| PLUS region -> region, "PLUS"
|
||||
| SLASH region -> region, "SLASH"
|
||||
| TIMES region -> region, "TIMES"
|
||||
| PERCENT region -> region, "PERCENT"
|
||||
| LPAR region -> region, "LPAR"
|
||||
| RPAR region -> region, "RPAR"
|
||||
| LBRACKET region -> region, "LBRACKET"
|
||||
@ -206,6 +207,7 @@ let to_lexeme = function
|
||||
| Ident id -> id.Region.value
|
||||
| Constr id -> id.Region.value
|
||||
| Attr a -> a.Region.value
|
||||
| Lang lang -> Region.(lang.value.value)
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -216,7 +218,6 @@ let to_lexeme = function
|
||||
| PLUS _ -> "+"
|
||||
| SLASH _ -> "/"
|
||||
| TIMES _ -> "*"
|
||||
| PERCENT _ -> "%"
|
||||
| LPAR _ -> "("
|
||||
| RPAR _ -> ")"
|
||||
| LBRACKET _ -> "["
|
||||
@ -478,7 +479,6 @@ let mk_sym lexeme region =
|
||||
| "-" -> Ok (MINUS region)
|
||||
| "*" -> Ok (TIMES region)
|
||||
| "/" -> Ok (SLASH region)
|
||||
| "%" -> Ok (PERCENT region)
|
||||
| "<" -> Ok (LT region)
|
||||
| "<=" -> Ok (LE region)
|
||||
| ">" -> Ok (GT region)
|
||||
@ -512,6 +512,10 @@ let mk_attr header lexeme region =
|
||||
if header = "[@" then Error Invalid_attribute
|
||||
else Ok (Attr Region.{value=lexeme; region})
|
||||
|
||||
(* Language injection *)
|
||||
|
||||
let mk_lang lang region = Lang Region.{value=lang; region}
|
||||
|
||||
(* Predicates *)
|
||||
|
||||
let is_string = function String _ -> true | _ -> false
|
||||
@ -573,7 +577,7 @@ let check_right_context token next_token buffer : unit =
|
||||
else ()
|
||||
else
|
||||
if is_bytes token
|
||||
then if is_string next || is_ident next
|
||||
then if is_string next || is_ident next
|
||||
then fail region Missing_break
|
||||
else if is_int next
|
||||
then fail region Odd_lengthed_bytes
|
||||
|
@ -5,15 +5,16 @@
|
||||
|
||||
(* Literals *)
|
||||
|
||||
%token <string Region.reg> String "<string>"
|
||||
%token <string Region.reg> Verbatim "<verbatim>"
|
||||
%token <(LexToken.lexeme * Hex.t) Region.reg> Bytes "<bytes>"
|
||||
%token <(string * Z.t) Region.reg> Int "<int>"
|
||||
%token <(string * Z.t) Region.reg> Nat "<nat>"
|
||||
%token <(string * Z.t) Region.reg> Mutez "<mutez>"
|
||||
%token <string Region.reg> Ident "<ident>"
|
||||
%token <string Region.reg> Constr "<constr>"
|
||||
%token <string Region.reg> Attr "<attr>"
|
||||
%token <string Region.reg> String "<string>"
|
||||
%token <string Region.reg> Verbatim "<verbatim>"
|
||||
%token <(LexToken.lexeme * Hex.t) Region.reg> Bytes "<bytes>"
|
||||
%token <(string * Z.t) Region.reg> Int "<int>"
|
||||
%token <(string * Z.t) Region.reg> Nat "<nat>"
|
||||
%token <(string * Z.t) Region.reg> Mutez "<mutez>"
|
||||
%token <string Region.reg> Ident "<ident>"
|
||||
%token <string Region.reg> Constr "<constr>"
|
||||
%token <string Region.reg> Attr "<attr>"
|
||||
%token <LexToken.lexeme Region.reg Region.reg> Lang "<lang>"
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -21,7 +22,6 @@
|
||||
%token <Region.t> PLUS "+"
|
||||
%token <Region.t> SLASH "/"
|
||||
%token <Region.t> TIMES "*"
|
||||
%token <Region.t> PERCENT "%"
|
||||
|
||||
%token <Region.t> LPAR "("
|
||||
%token <Region.t> RPAR ")"
|
||||
|
@ -121,11 +121,10 @@ type_decl:
|
||||
"type" type_name "=" type_expr {
|
||||
Scoping.check_reserved_name $2;
|
||||
let region = cover $1 (type_expr_to_region $4) in
|
||||
let value = {
|
||||
kwd_type = $1;
|
||||
name = $2;
|
||||
eq = $3;
|
||||
type_expr = $4}
|
||||
let value = {kwd_type = $1;
|
||||
name = $2;
|
||||
eq = $3;
|
||||
type_expr = $4}
|
||||
in {region; value} }
|
||||
|
||||
type_expr:
|
||||
@ -583,7 +582,7 @@ core_expr:
|
||||
| sequence { ESeq $1 }
|
||||
| record_expr { ERecord $1 }
|
||||
| update_record { EUpdate $1 }
|
||||
| code_insert { ECodeInsert $1 }
|
||||
| code_inj { ECodeInj $1 }
|
||||
| par(expr) { EPar $1 }
|
||||
| par(annot_expr) { EAnnot $1 }
|
||||
|
||||
@ -708,13 +707,8 @@ last_expr:
|
||||
seq_expr:
|
||||
disj_expr_level | if_then_else (seq_expr) { $1 }
|
||||
|
||||
code_insert:
|
||||
"[" "%" Constr expr "]" {
|
||||
let region = cover $1 $5 in
|
||||
let value = {
|
||||
lbracket =$1;
|
||||
percent =$2;
|
||||
language =$3;
|
||||
code =$4;
|
||||
rbracket =$5}
|
||||
code_inj:
|
||||
"<lang>" expr "]" {
|
||||
let region = cover $1.region $3
|
||||
and value = {language=$1; code=$2; rbracket=$3}
|
||||
in {region; value} }
|
||||
|
@ -89,12 +89,6 @@ let print_pvar state {region; value} =
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
let print_uident state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: Uident %s\n"
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
let print_string state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: String %S\n"
|
||||
@ -103,7 +97,7 @@ let print_string state {region; value} =
|
||||
|
||||
let print_verbatim state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: Verbatim {|%s|}\n"
|
||||
sprintf "%s: Verbatim %S\n"
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
@ -211,7 +205,7 @@ and print_cartesian state Region.{value;_} =
|
||||
print_nsepseq state "*" print_type_expr value
|
||||
|
||||
and print_variant state {value = {constr; arg}; _} =
|
||||
print_uident state constr;
|
||||
print_constr state constr;
|
||||
match arg with
|
||||
None -> ()
|
||||
| Some (kwd_of, t_expr) ->
|
||||
@ -340,7 +334,7 @@ and print_some_app_pattern state {value; _} =
|
||||
|
||||
and print_constr_app_pattern state node =
|
||||
let {value=constr, p_opt; _} = node in
|
||||
print_uident state constr;
|
||||
print_constr state constr;
|
||||
match p_opt with
|
||||
None -> ()
|
||||
| Some pattern -> print_pattern state pattern
|
||||
@ -366,7 +360,7 @@ and print_expr state = function
|
||||
| ESeq seq -> print_sequence state seq
|
||||
| ERecord e -> print_record_expr state e
|
||||
| EConstr e -> print_constr_expr state e
|
||||
| ECodeInsert e -> print_code_insert state e
|
||||
| ECodeInj e -> print_code_inj state e
|
||||
|
||||
and print_constr_expr state = function
|
||||
ENone e -> print_none_expr state e
|
||||
@ -519,13 +513,15 @@ and print_comp_expr state = function
|
||||
and print_record_expr state e =
|
||||
print_ne_injection state print_field_assign e
|
||||
|
||||
and print_code_insert state {value; _} =
|
||||
let {lbracket;percent;language;code;rbracket} : code_insert = value in
|
||||
print_token state lbracket "[";
|
||||
print_token state percent "%";
|
||||
print_string state language;
|
||||
print_expr state code;
|
||||
print_token state rbracket "]"
|
||||
and print_code_inj state {value; _} =
|
||||
let {language; code; rbracket} = value in
|
||||
let {value=lang; region} = language in
|
||||
let header_stop = region#start#shift_bytes 1 in
|
||||
let header_reg = Region.make ~start:region#start ~stop:header_stop in
|
||||
print_token state header_reg "[%";
|
||||
print_string state lang;
|
||||
print_expr state code;
|
||||
print_token state rbracket "]"
|
||||
|
||||
and print_field_assign state {value; _} =
|
||||
let {field_name; assignment; field_expr} = value in
|
||||
@ -871,9 +867,9 @@ and pp_expr state = function
|
||||
| ESeq {value; region} ->
|
||||
pp_loc_node state "ESeq" region;
|
||||
pp_injection pp_expr state value
|
||||
| ECodeInsert {value; region} ->
|
||||
pp_loc_node state "ECodeInsert" region;
|
||||
pp_code_insert state value
|
||||
| ECodeInj {value; region} ->
|
||||
pp_loc_node state "ECodeInj" region;
|
||||
pp_code_inj state value
|
||||
|
||||
and pp_fun_expr state node =
|
||||
let {binders; lhs_type; body; _} = node in
|
||||
@ -895,16 +891,16 @@ and pp_fun_expr state node =
|
||||
pp_expr (state#pad 1 0) body
|
||||
in ()
|
||||
|
||||
and pp_code_insert state (rc : code_insert) =
|
||||
and pp_code_inj state rc =
|
||||
let () =
|
||||
let state = state#pad 3 0 in
|
||||
let state = state#pad 2 0 in
|
||||
pp_node state "<language>";
|
||||
pp_string (state#pad 1 0) rc.language in
|
||||
pp_string (state#pad 1 0) rc.language.value in
|
||||
let () =
|
||||
let state = state#pad 3 1 in
|
||||
let state = state#pad 2 1 in
|
||||
pp_node state "<code>";
|
||||
pp_expr (state#pad 1 0) rc.code in
|
||||
()
|
||||
pp_expr (state#pad 1 0) rc.code
|
||||
in ()
|
||||
|
||||
and pp_let_in state node =
|
||||
let {binding; body; attributes; kwd_rec; _} = node in
|
||||
|
@ -52,22 +52,22 @@ and pp_let_binding (binding : let_binding) =
|
||||
in prefix 2 1 (lhs ^^ string " =") (pp_expr let_rhs)
|
||||
|
||||
and pp_pattern = function
|
||||
PConstr p -> pp_pconstr p
|
||||
| PUnit _ -> string "()"
|
||||
| PFalse _ -> string "false"
|
||||
| PTrue _ -> string "true"
|
||||
| PVar v -> pp_ident v
|
||||
| PInt i -> pp_int i
|
||||
| PNat n -> pp_nat n
|
||||
| PBytes b -> pp_bytes b
|
||||
| PString s -> pp_string s
|
||||
PConstr p -> pp_pconstr p
|
||||
| PUnit _ -> string "()"
|
||||
| PFalse _ -> string "false"
|
||||
| PTrue _ -> string "true"
|
||||
| PVar v -> pp_ident v
|
||||
| PInt i -> pp_int i
|
||||
| PNat n -> pp_nat n
|
||||
| PBytes b -> pp_bytes b
|
||||
| PString s -> pp_string s
|
||||
| PVerbatim s -> pp_verbatim s
|
||||
| PWild _ -> string "_"
|
||||
| PList l -> pp_plist l
|
||||
| PTuple t -> pp_ptuple t
|
||||
| PPar p -> pp_ppar p
|
||||
| PRecord r -> pp_precord r
|
||||
| PTyped t -> pp_ptyped t
|
||||
| PWild _ -> string "_"
|
||||
| PList l -> pp_plist l
|
||||
| PTuple t -> pp_ptuple t
|
||||
| PPar p -> pp_ppar p
|
||||
| PRecord r -> pp_precord r
|
||||
| PTyped t -> pp_ptyped t
|
||||
|
||||
and pp_pconstr = function
|
||||
PNone _ -> string "None"
|
||||
@ -152,7 +152,7 @@ and pp_expr = function
|
||||
| ELetIn e -> pp_let_in e
|
||||
| EFun e -> pp_fun e
|
||||
| ESeq e -> pp_seq e
|
||||
| ECodeInsert e -> pp_code_insert e
|
||||
| ECodeInj e -> pp_code_inj e
|
||||
|
||||
and pp_case_expr {value; _} =
|
||||
let {expr; cases; _} = value in
|
||||
@ -314,11 +314,11 @@ and pp_update {value; _} =
|
||||
string "{" ^^ record ^^ string " with"
|
||||
^^ nest 2 (break 1 ^^ updates ^^ string "}")
|
||||
|
||||
and pp_code_insert {value; _} =
|
||||
and pp_code_inj {value; _} =
|
||||
let {language; code; _} = value in
|
||||
let language = pp_string language
|
||||
and code = pp_expr code in
|
||||
string "[%" ^^ language ^^ string " " ^^ code ^^ string " ]"
|
||||
let language = pp_string language.value
|
||||
and code = pp_expr code in
|
||||
string "[%" ^^ language ^/^ code ^^ string "]"
|
||||
|
||||
and pp_field_path_assign {value; _} =
|
||||
let {field_path; field_expr; _} = value in
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -82,7 +82,6 @@ type rbrace = Region.t (* "}" *)
|
||||
type lbracket = Region.t (* "[" *)
|
||||
type rbracket = Region.t (* "]" *)
|
||||
type cons = Region.t (* "#" *)
|
||||
type percent = Region.t (* "%" *)
|
||||
type vbar = Region.t (* "|" *)
|
||||
type arrow = Region.t (* "->" *)
|
||||
type assign = Region.t (* ":=" *)
|
||||
@ -427,12 +426,14 @@ and for_collect = {
|
||||
block : block reg
|
||||
}
|
||||
|
||||
and code_insert = {
|
||||
lbracket : lbracket;
|
||||
percent : percent;
|
||||
language : string reg;
|
||||
code : expr;
|
||||
rbracket : rbracket;
|
||||
(* Code injection. Note how the field [language] wraps a region in
|
||||
another: the outermost region covers the header "[%<language>" and
|
||||
the innermost covers the <language>. *)
|
||||
|
||||
and code_inj = {
|
||||
language : string reg reg;
|
||||
code : expr;
|
||||
rbracket : rbracket;
|
||||
}
|
||||
|
||||
and collection =
|
||||
@ -443,27 +444,27 @@ and collection =
|
||||
(* Expressions *)
|
||||
|
||||
and expr =
|
||||
ECase of expr case reg
|
||||
| ECond of cond_expr reg
|
||||
| EAnnot of annot_expr par reg
|
||||
| ELogic of logic_expr
|
||||
| EArith of arith_expr
|
||||
| EString of string_expr
|
||||
| EList of list_expr
|
||||
| ESet of set_expr
|
||||
| EConstr of constr_expr
|
||||
| ERecord of record reg
|
||||
| EProj of projection reg
|
||||
| EUpdate of update reg
|
||||
| EMap of map_expr
|
||||
| EVar of Lexer.lexeme reg
|
||||
| ECall of fun_call
|
||||
| EBytes of (Lexer.lexeme * Hex.t) reg
|
||||
| EUnit of c_Unit
|
||||
| ETuple of tuple_expr
|
||||
| EPar of expr par reg
|
||||
| EFun of fun_expr reg
|
||||
| ECodeInsert of code_insert reg
|
||||
ECase of expr case reg
|
||||
| ECond of cond_expr reg
|
||||
| EAnnot of annot_expr par reg
|
||||
| ELogic of logic_expr
|
||||
| EArith of arith_expr
|
||||
| EString of string_expr
|
||||
| EList of list_expr
|
||||
| ESet of set_expr
|
||||
| EConstr of constr_expr
|
||||
| ERecord of record reg
|
||||
| EProj of projection reg
|
||||
| EUpdate of update reg
|
||||
| EMap of map_expr
|
||||
| EVar of Lexer.lexeme reg
|
||||
| ECall of fun_call
|
||||
| EBytes of (Lexer.lexeme * Hex.t) reg
|
||||
| EUnit of c_Unit
|
||||
| ETuple of tuple_expr
|
||||
| EPar of expr par reg
|
||||
| EFun of fun_expr reg
|
||||
| ECodeInj of code_inj reg
|
||||
|
||||
and annot_expr = expr * colon * type_expr
|
||||
|
||||
@ -680,17 +681,17 @@ let rec expr_to_region = function
|
||||
| ERecord e -> record_expr_to_region e
|
||||
| EMap e -> map_expr_to_region e
|
||||
| ETuple e -> tuple_expr_to_region e
|
||||
| EUpdate {region; _}
|
||||
| EProj {region; _}
|
||||
| EVar {region; _}
|
||||
| ECall {region; _}
|
||||
| EBytes {region; _}
|
||||
| EUnit region
|
||||
| ECase {region;_}
|
||||
| ECond {region; _}
|
||||
| EPar {region; _}
|
||||
| EFun {region; _}
|
||||
| ECodeInsert {region; _} -> region
|
||||
| EUpdate {region; _}
|
||||
| EProj {region; _}
|
||||
| EVar {region; _}
|
||||
| ECall {region; _}
|
||||
| EBytes {region; _}
|
||||
| EUnit region
|
||||
| ECase {region;_}
|
||||
| ECond {region; _}
|
||||
| EPar {region; _}
|
||||
| EFun {region; _}
|
||||
| ECodeInj {region; _} -> region
|
||||
|
||||
and tuple_expr_to_region {region; _} = region
|
||||
|
||||
|
@ -44,6 +44,7 @@ type t =
|
||||
| Mutez of (lexeme * Z.t) Region.reg
|
||||
| Ident of lexeme Region.reg
|
||||
| Constr of lexeme Region.reg
|
||||
| Lang of lexeme Region.reg Region.reg
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -73,7 +74,6 @@ type t =
|
||||
| DOT of Region.t (* "." *)
|
||||
| WILD of Region.t (* "_" *)
|
||||
| CAT of Region.t (* "^" *)
|
||||
| PERCENT of Region.t (* "%" *)
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
@ -162,6 +162,7 @@ val mk_verbatim : lexeme -> Region.t -> token
|
||||
val mk_bytes : lexeme -> Region.t -> token
|
||||
val mk_constr : lexeme -> Region.t -> token
|
||||
val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
|
||||
val mk_lang : lexeme Region.reg -> Region.t -> token
|
||||
val eof : Region.t -> token
|
||||
|
||||
(* Predicates *)
|
||||
|
@ -32,6 +32,7 @@ type t =
|
||||
| Mutez of (lexeme * Z.t) Region.reg
|
||||
| Ident of lexeme Region.reg
|
||||
| Constr of lexeme Region.reg
|
||||
| Lang of lexeme Region.reg Region.reg
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -61,7 +62,6 @@ type t =
|
||||
| DOT of Region.t
|
||||
| WILD of Region.t
|
||||
| CAT of Region.t
|
||||
| PERCENT of Region.t (* "%" *)
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
@ -126,26 +126,23 @@ let proj_token = function
|
||||
region, sprintf "String %S" value
|
||||
|
||||
| Verbatim Region.{region; value} ->
|
||||
region, sprintf "Verbatim {|%s|}" value
|
||||
region, sprintf "Verbatim %S" value
|
||||
|
||||
| Bytes Region.{region; value = s,b} ->
|
||||
region,
|
||||
sprintf "Bytes (\"%s\", \"0x%s\")" s (Hex.show b)
|
||||
sprintf "Bytes (%S, \"0x%s\")" s (Hex.show b)
|
||||
| Int Region.{region; value = s,n} ->
|
||||
region, sprintf "Int (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Int (%S, %s)" s (Z.to_string n)
|
||||
| Nat Region.{region; value = s,n} ->
|
||||
region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Nat (%S, %s)" s (Z.to_string n)
|
||||
| Mutez Region.{region; value = s,n} ->
|
||||
region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Mutez (%S, %s)" s (Z.to_string n)
|
||||
| Ident Region.{region; value} ->
|
||||
region, sprintf "Ident \"%s\"" value
|
||||
region, sprintf "Ident %S" value
|
||||
| Constr Region.{region; value} ->
|
||||
region, sprintf "Constr \"%s\"" value
|
||||
|
||||
(*
|
||||
| Attr {header; string={region; value}} ->
|
||||
region, sprintf "Attr (\"%s\",\"%s\")" header value
|
||||
*)
|
||||
region, sprintf "Constr %S" value
|
||||
| Lang Region.{region; value} ->
|
||||
region, sprintf "Lang %S" (value.Region.value)
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -175,7 +172,6 @@ let proj_token = function
|
||||
| DOT region -> region, "DOT"
|
||||
| WILD region -> region, "WILD"
|
||||
| CAT region -> region, "CAT"
|
||||
| PERCENT region -> region, "PERCENT"
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
@ -232,14 +228,15 @@ let proj_token = function
|
||||
let to_lexeme = function
|
||||
(* Literals *)
|
||||
|
||||
String s -> String.escaped s.Region.value
|
||||
String s -> String.escaped s.Region.value
|
||||
| Verbatim v -> String.escaped v.Region.value
|
||||
| Bytes b -> fst b.Region.value
|
||||
| Bytes b -> fst b.Region.value
|
||||
| Int i
|
||||
| Nat i
|
||||
| Mutez i -> fst i.Region.value
|
||||
| Mutez i -> fst i.Region.value
|
||||
| Ident id
|
||||
| Constr id -> id.Region.value
|
||||
| Constr id -> id.Region.value
|
||||
| Lang lang -> Region.(lang.value.value)
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -269,7 +266,6 @@ let to_lexeme = function
|
||||
| DOT _ -> "."
|
||||
| WILD _ -> "_"
|
||||
| CAT _ -> "^"
|
||||
| PERCENT _ -> "%"
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
@ -521,7 +517,6 @@ let mk_sym lexeme region =
|
||||
| "-" -> Ok (MINUS region)
|
||||
| "*" -> Ok (TIMES region)
|
||||
| "/" -> Ok (SLASH region)
|
||||
| "%" -> Ok (PERCENT region)
|
||||
| "<" -> Ok (LT region)
|
||||
| "<=" -> Ok (LE region)
|
||||
| ">" -> Ok (GT region)
|
||||
@ -552,6 +547,10 @@ type attr_err = Invalid_attribute
|
||||
|
||||
let mk_attr _ _ _ = Error Invalid_attribute
|
||||
|
||||
(* Language injection *)
|
||||
|
||||
let mk_lang lang region = Lang Region.{value=lang; region}
|
||||
|
||||
(* Predicates *)
|
||||
|
||||
let is_string = function String _ -> true | _ -> false
|
||||
@ -613,7 +612,7 @@ let check_right_context token next_token buffer : unit =
|
||||
else ()
|
||||
else
|
||||
if is_bytes token
|
||||
then if is_string next || is_ident next
|
||||
then if is_string next || is_ident next
|
||||
then fail region Missing_break
|
||||
else if is_int next
|
||||
then fail region Odd_lengthed_bytes
|
||||
|
@ -5,14 +5,15 @@
|
||||
|
||||
(* Literals *)
|
||||
|
||||
%token <LexToken.lexeme Region.reg> String "<string>"
|
||||
%token <LexToken.lexeme Region.reg> Verbatim "<verbatim>"
|
||||
%token <(LexToken.lexeme * Hex.t) Region.reg> Bytes "<bytes>"
|
||||
%token <(LexToken.lexeme * Z.t) Region.reg> Int "<int>"
|
||||
%token <(LexToken.lexeme * Z.t) Region.reg> Nat "<nat>"
|
||||
%token <(LexToken.lexeme * Z.t) Region.reg> Mutez "<mutez>"
|
||||
%token <LexToken.lexeme Region.reg> Ident "<ident>"
|
||||
%token <LexToken.lexeme Region.reg> Constr "<constr>"
|
||||
%token <LexToken.lexeme Region.reg> String "<string>"
|
||||
%token <LexToken.lexeme Region.reg> Verbatim "<verbatim>"
|
||||
%token <(LexToken.lexeme * Hex.t) Region.reg> Bytes "<bytes>"
|
||||
%token <(LexToken.lexeme * Z.t) Region.reg> Int "<int>"
|
||||
%token <(LexToken.lexeme * Z.t) Region.reg> Nat "<nat>"
|
||||
%token <(LexToken.lexeme * Z.t) Region.reg> Mutez "<mutez>"
|
||||
%token <LexToken.lexeme Region.reg> Ident "<ident>"
|
||||
%token <LexToken.lexeme Region.reg> Constr "<constr>"
|
||||
%token <LexToken.lexeme Region.reg Region.reg> Lang "<lang>"
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -42,7 +43,6 @@
|
||||
%token <Region.t> DOT "."
|
||||
%token <Region.t> WILD "_"
|
||||
%token <Region.t> CAT "^"
|
||||
%token <Region.t> PERCENT "%"
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
|
@ -846,7 +846,7 @@ core_expr:
|
||||
| set_expr { ESet $1 }
|
||||
| record_expr { ERecord $1 }
|
||||
| update_record { EUpdate $1 }
|
||||
| code_insert_expr { ECodeInsert $1 }
|
||||
| code_inj { ECodeInj $1 }
|
||||
| "<constr>" arguments {
|
||||
let region = cover $1.region $2.region in
|
||||
EConstr (ConstrApp {region; value = $1, Some $2})
|
||||
@ -965,15 +965,10 @@ update_record:
|
||||
let value = {record=$1; kwd_with=$2; updates}
|
||||
in {region; value} }
|
||||
|
||||
code_insert_expr:
|
||||
"[" "%" Constr expr "]" {
|
||||
let region = cover $1 $5 in
|
||||
let value = {
|
||||
lbracket =$1;
|
||||
percent =$2;
|
||||
language =$3;
|
||||
code =$4;
|
||||
rbracket =$5}
|
||||
code_inj:
|
||||
"<lang>" expr "]" {
|
||||
let region = cover $1.region $3
|
||||
and value = {language=$1; code=$2; rbracket=$3}
|
||||
in {region; value} }
|
||||
|
||||
field_assignment:
|
||||
|
@ -76,26 +76,32 @@ let print_token state region lexeme =
|
||||
|
||||
let print_var state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: Ident \"%s\"\n"
|
||||
sprintf "%s: Ident %S\n"
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
let print_constr state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: Constr \"%s\"\n"
|
||||
sprintf "%s: Constr %S\n"
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
let print_string state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: String %s\n"
|
||||
sprintf "%s: String %S\n"
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
let print_verbatim state {region; value} =
|
||||
let line =
|
||||
sprintf "%s: Verbatim %S\n"
|
||||
(compact state region) value
|
||||
in Buffer.add_string state#buffer line
|
||||
|
||||
let print_bytes state {region; value} =
|
||||
let lexeme, abstract = value in
|
||||
let line =
|
||||
sprintf "%s: Bytes (\"%s\", \"0x%s\")\n"
|
||||
sprintf "%s: Bytes (%S, \"0x%s\")\n"
|
||||
(compact state region) lexeme
|
||||
(Hex.show abstract)
|
||||
in Buffer.add_string state#buffer line
|
||||
@ -103,7 +109,7 @@ let print_bytes state {region; value} =
|
||||
let print_int state {region; value} =
|
||||
let lexeme, abstract = value in
|
||||
let line =
|
||||
sprintf "%s: Int (\"%s\", %s)\n"
|
||||
sprintf "%s: Int (%S, %s)\n"
|
||||
(compact state region) lexeme
|
||||
(Z.to_string abstract)
|
||||
in Buffer.add_string state#buffer line
|
||||
@ -111,7 +117,7 @@ let print_int state {region; value} =
|
||||
let print_nat state {region; value} =
|
||||
let lexeme, abstract = value in
|
||||
let line =
|
||||
sprintf "%s: Nat (\"%s\", %s)\n"
|
||||
sprintf "%s: Nat (%S, %s)\n"
|
||||
(compact state region) lexeme
|
||||
(Z.to_string abstract)
|
||||
in Buffer.add_string state#buffer line
|
||||
@ -236,13 +242,15 @@ and print_fun_expr state {value; _} =
|
||||
print_token state kwd_is "is";
|
||||
print_expr state return
|
||||
|
||||
and print_code_insert state {value; _} =
|
||||
let {lbracket;percent;language;code;rbracket} : code_insert = value in
|
||||
print_token state lbracket "[";
|
||||
print_token state percent "%";
|
||||
print_string state language;
|
||||
print_expr state code;
|
||||
print_token state rbracket "]"
|
||||
and print_code_inj state {value; _} =
|
||||
let {language; code; rbracket} = value in
|
||||
let {value=lang; region} = language in
|
||||
let header_stop = region#start#shift_bytes 1 in
|
||||
let header_reg = Region.make ~start:region#start ~stop:header_stop in
|
||||
print_token state header_reg "[%";
|
||||
print_string state lang;
|
||||
print_expr state code;
|
||||
print_token state rbracket "]"
|
||||
|
||||
and print_parameters state {value; _} =
|
||||
let {lpar; inside; rpar} = value in
|
||||
@ -466,7 +474,7 @@ and print_expr state = function
|
||||
| ETuple e -> print_tuple_expr state e
|
||||
| EPar e -> print_par_expr state e
|
||||
| EFun e -> print_fun_expr state e
|
||||
| ECodeInsert e -> print_code_insert state e
|
||||
| ECodeInj e -> print_code_inj state e
|
||||
|
||||
and print_annot_expr state node =
|
||||
let {inside; _} : annot_expr par = node in
|
||||
@ -608,7 +616,7 @@ and print_string_expr state = function
|
||||
| String s ->
|
||||
print_string state s
|
||||
| Verbatim v ->
|
||||
print_string state v
|
||||
print_verbatim state v
|
||||
|
||||
and print_list_expr state = function
|
||||
ECons {value = {arg1; op; arg2}; _} ->
|
||||
@ -1020,16 +1028,16 @@ and pp_fun_expr state (expr: fun_expr) =
|
||||
pp_expr (state#pad 1 0) expr.return
|
||||
in ()
|
||||
|
||||
and pp_code_insert state (rc : code_insert) =
|
||||
and pp_code_inj state rc =
|
||||
let () =
|
||||
let state = state#pad 3 0 in
|
||||
let state = state#pad 2 0 in
|
||||
pp_node state "<language>";
|
||||
pp_string (state#pad 1 0) rc.language in
|
||||
pp_string (state#pad 1 0) rc.language.value in
|
||||
let () =
|
||||
let state = state#pad 3 1 in
|
||||
let state = state#pad 2 1 in
|
||||
pp_node state "<code>";
|
||||
pp_expr (state#pad 1 0) rc.code in
|
||||
()
|
||||
pp_expr (state#pad 1 0) rc.code
|
||||
in ()
|
||||
|
||||
and pp_parameters state {value; _} =
|
||||
let params = Utils.nsepseq_to_list value.inside in
|
||||
@ -1510,9 +1518,9 @@ and pp_expr state = function
|
||||
| EFun {value; region} ->
|
||||
pp_loc_node state "EFun" region;
|
||||
pp_fun_expr state value;
|
||||
| ECodeInsert {value; region} ->
|
||||
pp_loc_node state "ECodeInsert" region;
|
||||
pp_code_insert state value;
|
||||
| ECodeInj {value; region} ->
|
||||
pp_loc_node state "ECodeInj" region;
|
||||
pp_code_inj state value;
|
||||
|
||||
and pp_list_expr state = function
|
||||
ECons {value; region} ->
|
||||
|
@ -377,7 +377,7 @@ and pp_expr = function
|
||||
| ETuple e -> pp_tuple_expr e
|
||||
| EPar e -> pp_par pp_expr e
|
||||
| EFun e -> pp_fun_expr e
|
||||
| ECodeInsert e -> pp_code_insert e
|
||||
| ECodeInj e -> pp_code_inj e
|
||||
|
||||
and pp_annot_expr {value; _} =
|
||||
let expr, _, type_expr = value.inside in
|
||||
@ -492,11 +492,11 @@ and pp_update {value; _} =
|
||||
and record = pp_path record in
|
||||
record ^^ string " with" ^^ nest 2 (break 1 ^^ updates)
|
||||
|
||||
and pp_code_insert {value; _} =
|
||||
and pp_code_inj {value; _} =
|
||||
let {language; code; _} = value in
|
||||
let language = pp_string language
|
||||
and code = pp_expr code in
|
||||
string "[%" ^^ language ^^ string " " ^^ code ^^ string " ]"
|
||||
let language = pp_string language.value
|
||||
and code = pp_expr code in
|
||||
string "[%" ^^ language ^/^ code ^^ string "]"
|
||||
|
||||
and pp_field_path_assign {value; _} =
|
||||
let {field_path; field_expr; _} = value in
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,9 +29,22 @@ type lexeme = string
|
||||
(* TOKENS *)
|
||||
|
||||
type t =
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
| Lang of lexeme Region.reg Region.reg
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
CAT of Region.t (* "++" *)
|
||||
| CAT of Region.t (* "++" *)
|
||||
|
||||
(* Arithmetics *)
|
||||
|
||||
@ -39,7 +52,6 @@ type t =
|
||||
| PLUS of Region.t (* "+" *)
|
||||
| SLASH of Region.t (* "/" *)
|
||||
| TIMES of Region.t (* "*" *)
|
||||
| PERCENT of Region.t (* "%" *)
|
||||
|
||||
(* Compounds *)
|
||||
|
||||
@ -80,18 +92,6 @@ type t =
|
||||
| BOOL_AND of Region.t (* "&&" *)
|
||||
| NOT of Region.t (* ! *)
|
||||
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
| Else of Region.t
|
||||
@ -147,13 +147,14 @@ val mk_int : lexeme -> Region.t -> (token, int_err) result
|
||||
val mk_nat : lexeme -> Region.t -> (token, nat_err) result
|
||||
val mk_mutez : lexeme -> Region.t -> (token, int_err) result
|
||||
val mk_ident : lexeme -> Region.t -> (token, ident_err) result
|
||||
val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
|
||||
val mk_sym : lexeme -> Region.t -> (token, sym_err) result
|
||||
val mk_kwd : lexeme -> Region.t -> (token, kwd_err) result
|
||||
val mk_string : lexeme -> Region.t -> token
|
||||
val mk_verbatim : lexeme -> Region.t -> token
|
||||
val mk_bytes : lexeme -> Region.t -> token
|
||||
val mk_constr : lexeme -> Region.t -> token
|
||||
val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
|
||||
val mk_lang : lexeme Region.reg -> Region.t -> token
|
||||
val eof : Region.t -> token
|
||||
|
||||
(* Predicates *)
|
||||
|
@ -15,9 +15,22 @@ let sprintf = Printf.sprintf
|
||||
(* TOKENS *)
|
||||
|
||||
type t =
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
| Lang of lexeme Region.reg Region.reg
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
CAT of Region.t (* "++" *)
|
||||
| CAT of Region.t (* "++" *)
|
||||
|
||||
(* Arithmetics *)
|
||||
|
||||
@ -25,7 +38,6 @@ type t =
|
||||
| PLUS of Region.t (* "+" *)
|
||||
| SLASH of Region.t (* "/" *)
|
||||
| TIMES of Region.t (* "*" *)
|
||||
| PERCENT of Region.t (* "%" *)
|
||||
|
||||
(* Compounds *)
|
||||
|
||||
@ -66,18 +78,6 @@ type t =
|
||||
| BOOL_AND of Region.t (* "&&" *)
|
||||
| NOT of Region.t (* ! *)
|
||||
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mutez of (string * Z.t) Region.reg
|
||||
| String of string Region.reg
|
||||
| Verbatim of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
| Attr of string Region.reg
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
| Else of Region.t
|
||||
@ -109,22 +109,26 @@ let proj_token = function
|
||||
(* Literals *)
|
||||
|
||||
String Region.{region; value} ->
|
||||
region, sprintf "String %s" value
|
||||
region, sprintf "String %S" value
|
||||
| Verbatim Region.{region; value} ->
|
||||
region, sprintf "Verbatim {|%s|}" value
|
||||
region, sprintf "Verbatim %S" value
|
||||
| Bytes Region.{region; value = s,b} ->
|
||||
region,
|
||||
sprintf "Bytes (\"%s\", \"0x%s\")" s (Hex.show b)
|
||||
sprintf "Bytes (%S, \"0x%s\")" s (Hex.show b)
|
||||
| Int Region.{region; value = s,n} ->
|
||||
region, sprintf "Int (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Int (%S, %s)" s (Z.to_string n)
|
||||
| Nat Region.{region; value = s,n} ->
|
||||
region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Nat (%S, %s)" s (Z.to_string n)
|
||||
| Mutez Region.{region; value = s,n} ->
|
||||
region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n)
|
||||
region, sprintf "Mutez (%S, %s)" s (Z.to_string n)
|
||||
| Ident Region.{region; value} ->
|
||||
region, sprintf "Ident %s" value
|
||||
region, sprintf "Ident %S" value
|
||||
| Constr Region.{region; value} ->
|
||||
region, sprintf "Constr %s" value
|
||||
region, sprintf "Constr %S" value
|
||||
| Attr Region.{region; value} ->
|
||||
region, sprintf "Attr %S" value
|
||||
| Lang Region.{region; value} ->
|
||||
region, sprintf "Lang %S" (value.Region.value)
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -133,7 +137,6 @@ let proj_token = function
|
||||
| PLUS region -> region, "PLUS"
|
||||
| SLASH region -> region, "SLASH"
|
||||
| TIMES region -> region, "TIMES"
|
||||
| PERCENT region -> region, "PERCENT"
|
||||
| LPAR region -> region, "LPAR"
|
||||
| RPAR region -> region, "RPAR"
|
||||
| LBRACKET region -> region, "LBRACKET"
|
||||
@ -170,7 +173,6 @@ let proj_token = function
|
||||
| Type region -> region, "Type"
|
||||
| C_None region -> region, "C_None"
|
||||
| C_Some region -> region, "C_Some"
|
||||
| Attr Region.{region; value} -> region, sprintf "Attr %s" value
|
||||
| EOF region -> region, "EOF"
|
||||
|
||||
let to_lexeme = function
|
||||
@ -185,6 +187,7 @@ let to_lexeme = function
|
||||
| Ident id -> id.Region.value
|
||||
| Constr id -> id.Region.value
|
||||
| Attr a -> a.Region.value
|
||||
| Lang lang -> Region.(lang.value.value)
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -193,7 +196,6 @@ let to_lexeme = function
|
||||
| PLUS _ -> "+"
|
||||
| SLASH _ -> "/"
|
||||
| TIMES _ -> "*"
|
||||
| PERCENT _ -> "%"
|
||||
| LPAR _ -> "("
|
||||
| RPAR _ -> ")"
|
||||
| LBRACKET _ -> "["
|
||||
@ -432,7 +434,6 @@ let mk_sym lexeme region =
|
||||
| "+" -> Ok (PLUS region)
|
||||
| "/" -> Ok (SLASH region)
|
||||
| "*" -> Ok (TIMES region)
|
||||
| "%" -> Ok (PERCENT region)
|
||||
| "[" -> Ok (LBRACKET region)
|
||||
| "]" -> Ok (RBRACKET region)
|
||||
| "{" -> Ok (LBRACE region)
|
||||
@ -488,6 +489,10 @@ let mk_attr header lexeme region =
|
||||
Ok (Attr Region.{value=lexeme; region})
|
||||
else Error Invalid_attribute
|
||||
|
||||
(* Language injection *)
|
||||
|
||||
let mk_lang lang region = Lang Region.{value=lang; region}
|
||||
|
||||
(* Predicates *)
|
||||
|
||||
let is_string = function String _ -> true | _ -> false
|
||||
@ -549,7 +554,7 @@ let check_right_context token next_token buffer : unit =
|
||||
else ()
|
||||
else
|
||||
if is_bytes token
|
||||
then if is_string next || is_ident next
|
||||
then if is_string next || is_ident next
|
||||
then fail region Missing_break
|
||||
else if is_int next
|
||||
then fail region Odd_lengthed_bytes
|
||||
|
@ -5,15 +5,16 @@
|
||||
|
||||
(* Literals *)
|
||||
|
||||
%token <string Region.reg> String "<string>"
|
||||
%token <string Region.reg> Verbatim "<verbatim>"
|
||||
%token <(LexToken.lexeme * Hex.t) Region.reg> Bytes "<bytes>"
|
||||
%token <(string * Z.t) Region.reg> Int "<int>"
|
||||
%token <(string * Z.t) Region.reg> Nat "<nat>"
|
||||
%token <(string * Z.t) Region.reg> Mutez "<mutez>"
|
||||
%token <string Region.reg> Ident "<ident>"
|
||||
%token <string Region.reg> Constr "<constr>"
|
||||
%token <string Region.reg> Attr "<attr>"
|
||||
%token <string Region.reg> String "<string>"
|
||||
%token <string Region.reg> Verbatim "<verbatim>"
|
||||
%token <(LexToken.lexeme * Hex.t) Region.reg> Bytes "<bytes>"
|
||||
%token <(string * Z.t) Region.reg> Int "<int>"
|
||||
%token <(string * Z.t) Region.reg> Nat "<nat>"
|
||||
%token <(string * Z.t) Region.reg> Mutez "<mutez>"
|
||||
%token <string Region.reg> Ident "<ident>"
|
||||
%token <string Region.reg> Constr "<constr>"
|
||||
%token <string Region.reg> Attr "<attr>"
|
||||
%token <LexToken.lexeme Region.reg Region.reg> Lang "<lang>"
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
@ -21,7 +22,6 @@
|
||||
%token <Region.t> PLUS "+"
|
||||
%token <Region.t> SLASH "/"
|
||||
%token <Region.t> TIMES "*"
|
||||
%token <Region.t> PERCENT "%"
|
||||
|
||||
%token <Region.t> LPAR "("
|
||||
%token <Region.t> RPAR ")"
|
||||
|
@ -801,20 +801,20 @@ call_expr:
|
||||
in ECall {region; value} }
|
||||
|
||||
common_expr:
|
||||
"<int>" { EArith (Int $1) }
|
||||
| "<mutez>" { EArith (Mutez $1) }
|
||||
| "<nat>" { EArith (Nat $1) }
|
||||
| "<bytes>" { EBytes $1 }
|
||||
| "<ident>" | module_field { EVar $1 }
|
||||
| projection { EProj $1 }
|
||||
| "_" { EVar {value = "_"; region = $1} }
|
||||
| update_record { EUpdate $1 }
|
||||
| "<string>" { EString (String $1) }
|
||||
| "<verbatim>" { EString (Verbatim $1) }
|
||||
| unit { EUnit $1 }
|
||||
| "false" { ELogic (BoolExpr (False $1)) }
|
||||
| "true" { ELogic (BoolExpr (True $1)) }
|
||||
| code_insert { ECodeInsert $1 }
|
||||
"<int>" { EArith (Int $1) }
|
||||
| "<mutez>" { EArith (Mutez $1) }
|
||||
| "<nat>" { EArith (Nat $1) }
|
||||
| "<bytes>" { EBytes $1 }
|
||||
| "<ident>" | module_field { EVar $1 }
|
||||
| projection { EProj $1 }
|
||||
| "_" { EVar {value = "_"; region = $1} }
|
||||
| update_record { EUpdate $1 }
|
||||
| "<string>" { EString (String $1) }
|
||||
| "<verbatim>" { EString (Verbatim $1) }
|
||||
| unit { EUnit $1 }
|
||||
| "false" { ELogic (BoolExpr (False $1)) }
|
||||
| "true" { ELogic (BoolExpr (True $1)) }
|
||||
| code_inj { ECodeInj $1 }
|
||||
|
||||
core_expr_2:
|
||||
common_expr { $1 }
|
||||
@ -920,15 +920,10 @@ update_record:
|
||||
rbrace = $6}
|
||||
in {region; value} }
|
||||
|
||||
code_insert:
|
||||
"[" "%" Constr expr "]" {
|
||||
let region = cover $1 $5 in
|
||||
let value = {
|
||||
lbracket =$1;
|
||||
percent =$2;
|
||||
language =$3;
|
||||
code =$4;
|
||||
rbracket =$5}
|
||||
code_inj:
|
||||
"<lang>" expr "]" {
|
||||
let region = cover $1.region $3
|
||||
and value = {language=$1; code=$2; rbracket=$3}
|
||||
in {region; value} }
|
||||
|
||||
expr_with_let_expr:
|
||||
|
@ -159,7 +159,7 @@ and pp_expr = function
|
||||
| ELetIn e -> pp_let_in e
|
||||
| EFun e -> pp_fun e
|
||||
| ESeq e -> pp_seq e
|
||||
| ECodeInsert e -> pp_code_insert e
|
||||
| ECodeInj e -> pp_code_inj e
|
||||
|
||||
and pp_case_expr {value; _} =
|
||||
let {expr; cases; _} = value in
|
||||
@ -180,7 +180,7 @@ and pp_clause {value; _} =
|
||||
and pp_cond_expr {value; _} =
|
||||
let {test; ifso; kwd_else; ifnot; _} = value in
|
||||
let if_then =
|
||||
string "if" ^^ string " (" ^^ pp_expr test ^^ string ")" ^^ string " {" ^^ break 0
|
||||
string "if" ^^ string " (" ^^ pp_expr test ^^ string ")" ^^ string " {" ^^ break 0
|
||||
^^ group (nest 2 (break 2 ^^ pp_expr ifso)) ^^ hardline ^^ string "}" in
|
||||
if kwd_else#is_ghost then
|
||||
if_then
|
||||
@ -320,11 +320,11 @@ and pp_update {value; _} =
|
||||
string "{..." ^^ record ^^ string ","
|
||||
^^ nest 2 (break 1 ^^ updates ^^ string "}")
|
||||
|
||||
and pp_code_insert {value; _} =
|
||||
and pp_code_inj {value; _} =
|
||||
let {language; code; _} = value in
|
||||
let language = pp_string language
|
||||
and code = pp_expr code in
|
||||
string "[%" ^^ language ^^ string " " ^^ code ^^ string " ]"
|
||||
let language = pp_string language.value
|
||||
and code = pp_expr code in
|
||||
string "[%" ^^ language ^/^ code ^^ string "]"
|
||||
|
||||
and pp_field_path_assign {value; _} =
|
||||
let {field_path; field_expr; _} = value in
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -79,6 +79,7 @@ module type TOKEN =
|
||||
val mk_bytes : lexeme -> Region.t -> token
|
||||
val mk_constr : lexeme -> Region.t -> token
|
||||
val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
|
||||
val mk_lang : lexeme Region.reg -> Region.t -> token
|
||||
val eof : Region.t -> token
|
||||
|
||||
(* Predicates *)
|
||||
|
@ -43,6 +43,7 @@ module type TOKEN =
|
||||
val mk_bytes : lexeme -> Region.t -> token
|
||||
val mk_constr : lexeme -> Region.t -> token
|
||||
val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
|
||||
val mk_lang : lexeme Region.reg -> Region.t -> token
|
||||
val eof : Region.t -> token
|
||||
|
||||
(* Predicates *)
|
||||
@ -273,6 +274,15 @@ module Make (Token : TOKEN) : (S with module Token = Token) =
|
||||
let token = Token.mk_constr lexeme region
|
||||
in state#enqueue token
|
||||
|
||||
let mk_lang lang state buffer =
|
||||
let region, _, state = state#sync buffer in
|
||||
let start = region#start#shift_bytes 1 in
|
||||
let stop = region#stop in
|
||||
let lang_reg = Region.make ~start ~stop in
|
||||
let lang = Region.{value=lang; region=lang_reg} in
|
||||
let token = Token.mk_lang lang region
|
||||
in state#enqueue token
|
||||
|
||||
let mk_sym state buffer =
|
||||
let region, lexeme, state = state#sync buffer in
|
||||
match Token.mk_sym lexeme region with
|
||||
@ -314,7 +324,7 @@ let esc = "\\n" | "\\\"" | "\\\\" | "\\b"
|
||||
|
||||
let common_sym = ';' | ',' | '(' | ')' | '[' | ']' | '{' | '}'
|
||||
| '=' | ':' | '|' | "->" | '.' | '_' | '^'
|
||||
| '+' | '-' | '*' | '/' | '%' | '<' | "<=" | '>' | ">="
|
||||
| '+' | '-' | '*' | '/' | '<' | "<=" | '>' | ">="
|
||||
let pascaligo_sym = "=/=" | '#' | ":="
|
||||
let cameligo_sym = "<>" | "::" | "||" | "&&"
|
||||
let reasonligo_sym = '!' | "=>" | "!=" | "==" | "++" | "..." | "||" | "&&"
|
||||
@ -388,6 +398,7 @@ and scan state = parse
|
||||
| eof { mk_eof state lexbuf }
|
||||
| "[@" (attr as a) "]" { mk_attr "[@" a state lexbuf }
|
||||
| "[@@" (attr as a) "]" { mk_attr "[@@" a state lexbuf }
|
||||
| "[%" (attr as l) { mk_lang l state lexbuf }
|
||||
|
||||
(* Management of #include preprocessing directives
|
||||
|
||||
@ -512,7 +523,7 @@ and scan_string thread state = parse
|
||||
|
||||
and scan_verbatim thread state = parse
|
||||
| eof { fail thread#opening Unterminated_verbatim}
|
||||
| "|}" { let _, _, state = state#sync lexbuf
|
||||
| "|}" { let _, _, state = state#sync lexbuf
|
||||
in thread, state }
|
||||
| _ as c { let _, _, state = state#sync lexbuf in
|
||||
scan_verbatim (thread#push_char c) state lexbuf }
|
||||
|
@ -487,19 +487,17 @@ in trace (abstracting_expr_tracer t) @@
|
||||
return @@ e_sequence a e1'
|
||||
in List.fold_left apply expr' more)
|
||||
)
|
||||
| ECond c -> (
|
||||
| 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_cond ~loc expr match_true match_false
|
||||
)
|
||||
| ECodeInsert ci -> (
|
||||
let (ci, loc) = r_split ci in
|
||||
let language = ci.language.value in
|
||||
let%bind code = compile_expression ci.code in
|
||||
return @@ e_raw_code ~loc language code
|
||||
)
|
||||
| ECodeInj ci ->
|
||||
let ci, loc = r_split ci in
|
||||
let language = ci.language.value.value in
|
||||
let%bind code = compile_expression ci.code
|
||||
in ok @@ e_raw_code ~loc language code
|
||||
|
||||
and compile_fun lamb' : (expr , abs_error) result =
|
||||
let return x = ok x in
|
||||
|
@ -16,8 +16,9 @@ open Operators.Concrete_to_imperative.Pascaligo
|
||||
|
||||
let r_split = Location.r_split
|
||||
|
||||
let return = ok
|
||||
|
||||
let rec compile_type_expression : CST.type_expr -> _ result = fun te ->
|
||||
let return te = ok @@ te in
|
||||
match te with
|
||||
TSum sum ->
|
||||
let (nsepseq, loc) = r_split sum in
|
||||
@ -36,7 +37,7 @@ let rec compile_type_expression : CST.type_expr -> _ result = fun te ->
|
||||
let aux (field : CST.field_decl CST.reg) =
|
||||
let (f, _) = r_split field in
|
||||
let%bind type_expr = compile_type_expression f.field_type in
|
||||
ok @@ (f.field_name.value,type_expr)
|
||||
return @@ (f.field_name.value,type_expr)
|
||||
in
|
||||
let%bind record = bind_map_list aux lst in
|
||||
return @@ t_record_ez ~loc record
|
||||
@ -51,7 +52,7 @@ let rec compile_type_expression : CST.type_expr -> _ result = fun te ->
|
||||
| _ -> None
|
||||
in
|
||||
let ((operator,args), loc) = r_split app in
|
||||
(* this is a bad design, michelson_or and pair should be an operator
|
||||
(* this is a bad design, michelson_or and pair should be an operator
|
||||
see AnnotType *)
|
||||
(match operator.value with
|
||||
| "michelson_or" ->
|
||||
@ -66,7 +67,7 @@ let rec compile_type_expression : CST.type_expr -> _ result = fun te ->
|
||||
get_t_string_singleton_opt d in
|
||||
let%bind a' = compile_type_expression a in
|
||||
let%bind c' = compile_type_expression c in
|
||||
ok @@ t_michelson_or ~loc a' b' c' d'
|
||||
return @@ t_michelson_or ~loc a' b' c' d'
|
||||
)
|
||||
| _ -> fail @@ michelson_type_wrong_arity loc operator.value)
|
||||
| "michelson_pair" ->
|
||||
@ -81,7 +82,7 @@ let rec compile_type_expression : CST.type_expr -> _ result = fun te ->
|
||||
get_t_string_singleton_opt d in
|
||||
let%bind a' = compile_type_expression a in
|
||||
let%bind c' = compile_type_expression c in
|
||||
ok @@ t_michelson_pair ~loc a' b' c' d'
|
||||
return @@ t_michelson_pair ~loc a' b' c' d'
|
||||
)
|
||||
| _ -> fail @@ michelson_type_wrong_arity loc operator.value)
|
||||
| _ ->
|
||||
@ -104,14 +105,14 @@ let rec compile_type_expression : CST.type_expr -> _ result = fun te ->
|
||||
| TVar var ->
|
||||
let (name,loc) = r_split var in
|
||||
(match type_constants name with
|
||||
Some const -> return @@ t_constant ~loc const
|
||||
Some const -> return @@ t_constant ~loc const
|
||||
| None -> return @@ t_variable_ez ~loc name
|
||||
)
|
||||
| TString _s -> fail @@ unsupported_string_singleton te
|
||||
|
||||
let compile_selection (selection : CST.selection) =
|
||||
match selection with
|
||||
FieldName name ->
|
||||
FieldName name ->
|
||||
let (name, loc) = r_split name in
|
||||
(Access_record name, loc)
|
||||
| Component comp ->
|
||||
@ -119,12 +120,11 @@ let compile_selection (selection : CST.selection) =
|
||||
(Access_tuple index, loc)
|
||||
|
||||
let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error) result = fun e ->
|
||||
let return e = ok @@ e in
|
||||
let compile_tuple_expression (tuple_expr : CST.tuple_expr) =
|
||||
let (lst, loc) = r_split tuple_expr in
|
||||
let%bind lst = bind_map_list compile_expression @@ npseq_to_list lst.inside in
|
||||
match lst with
|
||||
hd::[] -> return @@ hd
|
||||
match lst with
|
||||
hd::[] -> return hd
|
||||
| lst -> return @@ e_tuple ~loc lst
|
||||
in
|
||||
let compile_path (path : CST.path) =
|
||||
@ -153,7 +153,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
match e with
|
||||
EVar var ->
|
||||
let (var, loc) = r_split var in
|
||||
(match constants var with
|
||||
(match constants var with
|
||||
Some const -> return @@ e_constant ~loc const []
|
||||
| None -> return @@ e_variable_ez ~loc var
|
||||
)
|
||||
@ -187,7 +187,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
| Div slash -> compile_bin_op C_DIV slash
|
||||
| Mod mod_ -> compile_bin_op C_MOD mod_
|
||||
| Neg minus -> compile_un_op C_NEG minus
|
||||
| Int i ->
|
||||
| Int i ->
|
||||
let ((_,i), loc) = r_split i in
|
||||
return @@ e_int_z ~loc i
|
||||
| Nat n ->
|
||||
@ -208,7 +208,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
| False reg -> let loc = Location.lift reg in return @@ e_false ~loc ()
|
||||
)
|
||||
| CompExpr ce -> (
|
||||
match ce with
|
||||
match ce with
|
||||
Lt lt -> compile_bin_op C_LT lt
|
||||
| Leq le -> compile_bin_op C_LE le
|
||||
| Gt gt -> compile_bin_op C_GT gt
|
||||
@ -222,7 +222,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
| ECall {value=(EVar var,args);region} ->
|
||||
let loc = Location.lift region in
|
||||
let (var, loc_var) = r_split var in
|
||||
(match constants var with
|
||||
(match constants var with
|
||||
Some const ->
|
||||
let (args, _) = r_split args in
|
||||
let%bind args = bind_map_list compile_expression @@ npseq_to_list args.inside in
|
||||
@ -241,15 +241,15 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
compile_tuple_expression lst
|
||||
| ERecord record ->
|
||||
let (record, loc) = r_split record in
|
||||
let aux (fa : CST.field_assignment CST.reg) =
|
||||
let aux (fa : CST.field_assignment CST.reg) =
|
||||
let (fa, _) = r_split fa in
|
||||
let (name, _) = r_split fa.field_name in
|
||||
let (name, _) = r_split fa.field_name in
|
||||
let%bind expr = compile_expression fa.field_expr in
|
||||
ok @@ (name, expr)
|
||||
return (name, expr)
|
||||
in
|
||||
let%bind record = bind_map_list aux @@ npseq_to_list record.ne_elements in
|
||||
return @@ e_record_ez ~loc record
|
||||
| EProj proj ->
|
||||
| EProj proj ->
|
||||
let (proj, loc) = r_split proj in
|
||||
let (var, _loc_var) = r_split proj.struct_name in
|
||||
let var = e_variable_ez ~loc var in
|
||||
@ -270,11 +270,11 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let (path, _) = List.split @@ List.map compile_selection @@ npseq_to_list proj.field_path in
|
||||
(Access_record proj.struct_name.value)::path
|
||||
)
|
||||
in
|
||||
ok @@ (path, expr, loc)
|
||||
in
|
||||
return (path, expr, loc)
|
||||
in
|
||||
let%bind updates = bind_map_list aux @@ npseq_to_list updates.ne_elements in
|
||||
let aux e (path, update, loc) = e_update ~loc e path update in
|
||||
let%bind updates = bind_map_list aux @@ npseq_to_list updates.ne_elements in
|
||||
let aux e (path, update, loc) = e_update ~loc e path update in
|
||||
return @@ List.fold_left aux record updates
|
||||
| EFun func ->
|
||||
let compile_param (param : CST.param_decl) =
|
||||
@ -283,12 +283,12 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let (p, _) = r_split p in
|
||||
let (var, _loc) = r_split p.var in
|
||||
let%bind p_type = bind_map_option (compile_type_expression <@ snd) p.param_type in
|
||||
ok @@ (var, p_type)
|
||||
return (var, p_type)
|
||||
| ParamVar p ->
|
||||
let (p, _) = r_split p in
|
||||
let (var, _loc) = r_split p.var in
|
||||
let%bind p_type = bind_map_option (compile_type_expression <@ snd) p.param_type in
|
||||
ok @@ (var, p_type)
|
||||
return (var, p_type)
|
||||
in
|
||||
let (func, loc) = r_split func in
|
||||
let (param, loc_par) = r_split func.param in
|
||||
@ -297,7 +297,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let%bind ret_type = bind_map_option (compile_type_expression <@ snd )func.ret_type in
|
||||
let%bind body = compile_expression func.return in
|
||||
let (lambda, fun_type) = match param_type with
|
||||
ty::[] ->
|
||||
ty::[] ->
|
||||
e_lambda ~loc (Var.of_name @@ List.hd param) ty ret_type body,
|
||||
Option.map (fun (a,b) -> t_function a b)@@ Option.bind_pair (ty,ret_type)
|
||||
(* Cannot be empty *)
|
||||
@ -305,7 +305,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let lst = Option.bind_list lst in
|
||||
let input_type = Option.map t_tuple lst in
|
||||
let binder = Var.fresh ~name:"parameter" () in
|
||||
e_lambda ~loc binder input_type (ret_type) @@
|
||||
e_lambda ~loc binder input_type (ret_type) @@
|
||||
e_matching_tuple_ez ~loc:loc_par (e_variable binder) param lst body,
|
||||
Option.map (fun (a,b) -> t_function a b)@@ Option.bind_pair (input_type,ret_type)
|
||||
in
|
||||
@ -317,7 +317,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
return @@ e_some ~loc args
|
||||
| EConstr (NoneExpr reg) ->
|
||||
let loc = Location.lift reg in
|
||||
return @@ e_none ~loc ()
|
||||
return @@ e_none ~loc ()
|
||||
| EConstr (ConstrApp constr) ->
|
||||
let ((constr,args_o), loc) = r_split constr in
|
||||
let%bind args_o = bind_map_option compile_tuple_expression args_o in
|
||||
@ -341,8 +341,8 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let%bind then_clause = compile_expression cond.ifso in
|
||||
let%bind else_clause = compile_expression cond.ifnot in
|
||||
return @@ e_cond ~loc test then_clause else_clause
|
||||
| EList lst -> (
|
||||
match lst with
|
||||
| EList lst -> (
|
||||
match lst with
|
||||
ECons cons ->
|
||||
let (cons, loc) = r_split cons in
|
||||
let%bind a = compile_expression cons.arg1 in
|
||||
@ -356,7 +356,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
in
|
||||
let%bind lst = bind_map_list compile_expression lst in
|
||||
return @@ e_list ~loc lst
|
||||
| ENil nil ->
|
||||
| ENil nil ->
|
||||
let loc = Location.lift nil in
|
||||
return @@ e_list ~loc []
|
||||
(* Is seems that either ENil is redondant or EListComp should be an nsepseq and not a sepseq *)
|
||||
@ -368,7 +368,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let set =
|
||||
Option.unopt ~default:[] @@
|
||||
Option.map npseq_to_list si.elements
|
||||
in
|
||||
in
|
||||
let%bind set = bind_map_list compile_expression set in
|
||||
return @@ e_set ~loc set
|
||||
| SetMem sm ->
|
||||
@ -394,7 +394,7 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let (binding, _) = r_split binding in
|
||||
let%bind key = compile_expression binding.source in
|
||||
let%bind value = compile_expression binding.image in
|
||||
ok @@ (key,value)
|
||||
return (key,value)
|
||||
in
|
||||
let%bind map = bind_map_list aux lst in
|
||||
return @@ e_map ~loc map
|
||||
@ -406,71 +406,70 @@ let rec compile_expression : CST.expr -> (AST.expr , Errors_pascaligo.abs_error)
|
||||
let (binding, _) = r_split binding in
|
||||
let%bind key = compile_expression binding.source in
|
||||
let%bind value = compile_expression binding.image in
|
||||
ok @@ (key,value)
|
||||
return (key,value)
|
||||
in
|
||||
let%bind map = bind_map_list aux lst in
|
||||
return @@ e_big_map ~loc map
|
||||
)
|
||||
| ECodeInsert ci ->
|
||||
| ECodeInj ci ->
|
||||
let (ci, loc) = r_split ci in
|
||||
let (language, _) = r_split ci.language in
|
||||
let (language, _) = r_split language in
|
||||
let%bind code = compile_expression ci.code in
|
||||
return @@ e_raw_code ~loc language code
|
||||
|
||||
and compile_matching_expr : type a.(a -> _ result) -> a CST.case_clause CST.reg List.Ne.t -> _ =
|
||||
fun compiler cases ->
|
||||
let compile_pattern pattern = ok @@ pattern
|
||||
in
|
||||
let return e = ok @@ e in
|
||||
let compile_pattern pattern = return pattern in
|
||||
let compile_simple_pattern (pattern : CST.pattern) =
|
||||
match pattern with
|
||||
PVar var ->
|
||||
PVar var ->
|
||||
let (var, _) = r_split var in
|
||||
ok @@ Var.of_name var
|
||||
return @@ Var.of_name var
|
||||
| _ -> fail @@ unsupported_non_var_pattern pattern
|
||||
in
|
||||
let compile_list_pattern (cases : (CST.pattern * _) list) =
|
||||
match cases with
|
||||
match cases with
|
||||
[(PList PNil _, match_nil);(PList PCons cons, econs)]
|
||||
| [(PList PCons cons, econs);(PList PNil _, match_nil)] ->
|
||||
let (cons,_) = r_split cons in
|
||||
let%bind (hd,tl) = match snd @@ List.split (snd cons) with
|
||||
tl::[] -> ok @@ (fst cons,tl)
|
||||
let%bind (hd,tl) = match snd @@ List.split (snd cons) with
|
||||
tl::[] -> return (fst cons,tl)
|
||||
| _ -> fail @@ unsupported_deep_list_patterns @@ fst cons
|
||||
in
|
||||
let%bind (hd,tl) = bind_map_pair compile_simple_pattern (hd,tl) in
|
||||
let match_cons = (hd,tl,econs) in
|
||||
ok @@ (match_nil,match_cons)
|
||||
return (match_nil,match_cons)
|
||||
| _ -> fail @@ unsupported_deep_list_patterns @@ fst @@ List.hd cases
|
||||
in
|
||||
let compile_simple_tuple_pattern (tuple : CST.tuple_pattern) =
|
||||
let (lst, _) = r_split tuple in
|
||||
match lst.inside with
|
||||
match lst.inside with
|
||||
hd,[] -> compile_simple_pattern hd
|
||||
| _ -> fail @@ unsupported_deep_tuple_patterns tuple
|
||||
in
|
||||
let compile_constr_pattern (constr : CST.pattern) =
|
||||
match constr with
|
||||
PConstr c ->
|
||||
( match c with
|
||||
( match c with
|
||||
PUnit _ ->
|
||||
fail @@ unsupported_pattern_type constr
|
||||
| PFalse _ -> ok @@ (Constructor "false", Var.of_name "_")
|
||||
| PTrue _ -> ok @@ (Constructor "true", Var.of_name "_")
|
||||
| PNone _ -> ok @@ (Constructor "None", Var.of_name "_")
|
||||
| PFalse _ -> return (Constructor "false", Var.of_name "_")
|
||||
| PTrue _ -> return (Constructor "true", Var.of_name "_")
|
||||
| PNone _ -> return (Constructor "None", Var.of_name "_")
|
||||
| PSomeApp some ->
|
||||
let (some,_) = r_split some in
|
||||
let (_, pattern) = some in
|
||||
let (pattern,_) = r_split pattern in
|
||||
let%bind pattern = compile_simple_pattern pattern.inside in
|
||||
ok @@ (Constructor "Some", pattern)
|
||||
return (Constructor "Some", pattern)
|
||||
| PConstrApp constr ->
|
||||
let (constr, _) = r_split constr in
|
||||
let (constr, patterns) = constr in
|
||||
let (constr, _) = r_split constr in
|
||||
let%bind pattern = bind_map_option compile_simple_tuple_pattern patterns in
|
||||
let pattern = Option.unopt ~default:(Var.of_name "_") pattern in
|
||||
ok (Constructor constr, pattern)
|
||||
return (Constructor constr, pattern)
|
||||
)
|
||||
| _ -> fail @@ unsupported_pattern_type constr
|
||||
in
|
||||
@ -478,7 +477,7 @@ fun compiler cases ->
|
||||
let (case, _loc) = r_split case in
|
||||
let%bind pattern = compile_pattern case.pattern in
|
||||
let%bind expr = compiler case.rhs in
|
||||
ok (pattern, expr)
|
||||
return (pattern, expr)
|
||||
in
|
||||
let%bind cases = bind_map_ne_list aux cases in
|
||||
match cases with
|
||||
@ -488,19 +487,18 @@ fun compiler cases ->
|
||||
return @@ AST.Match_variable (var, None, expr)
|
||||
| (PTuple tuple, _expr), [] ->
|
||||
fail @@ unsupported_tuple_pattern @@ CST.PTuple tuple
|
||||
| (PList _, _), _ ->
|
||||
| (PList _, _), _ ->
|
||||
let%bind (match_nil,match_cons) = compile_list_pattern @@ List.Ne.to_list cases in
|
||||
return @@ AST.Match_list {match_nil;match_cons}
|
||||
| (PConstr _,_), _ ->
|
||||
| (PConstr _,_), _ ->
|
||||
let (pattern, lst) = List.split @@ List.Ne.to_list cases in
|
||||
let%bind constrs = bind_map_list compile_constr_pattern pattern in
|
||||
return @@ AST.Match_variant (List.combine constrs lst)
|
||||
| (p, _), _ -> fail @@ unsupported_pattern_type p
|
||||
|
||||
let compile_attribute_declaration attributes =
|
||||
match attributes with
|
||||
None -> ok @@ false
|
||||
| Some _ -> ok @@ true
|
||||
|
||||
let compile_attribute_declaration = function
|
||||
None -> return false
|
||||
| Some _ -> return true
|
||||
|
||||
let compile_parameters (params : CST.parameters) =
|
||||
let compile_param_decl (param : CST.param_decl) =
|
||||
@ -509,38 +507,38 @@ let compile_parameters (params : CST.parameters) =
|
||||
let (pc, _loc) = r_split pc in
|
||||
let (var, _) = r_split pc.var in
|
||||
let%bind param_type = bind_map_option (compile_type_expression <@ snd) pc.param_type in
|
||||
ok @@ (var, param_type)
|
||||
return (var, param_type)
|
||||
| ParamVar pv ->
|
||||
let (pv, _loc) = r_split pv in
|
||||
let (var, _) = r_split pv.var in
|
||||
let%bind param_type = bind_map_option (compile_type_expression <@ snd) pv.param_type in
|
||||
ok @@ (var, param_type)
|
||||
return (var, param_type)
|
||||
in
|
||||
let (params, _loc) = r_split params in
|
||||
let params = npseq_to_list params.inside in
|
||||
bind_map_list compile_param_decl params
|
||||
|
||||
let rec compile_instruction : ?next: AST.expression -> CST.instruction -> _ result = fun ?next instruction ->
|
||||
let return expr = match next with
|
||||
Some e -> ok @@ e_sequence expr e
|
||||
| None -> ok @@ expr
|
||||
let return expr = match next with
|
||||
Some e -> return @@ e_sequence expr e
|
||||
| None -> return expr
|
||||
in
|
||||
let compile_tuple_expression (tuple_expr : CST.tuple_expr) =
|
||||
let (lst, loc) = r_split tuple_expr in
|
||||
let%bind lst = bind_map_list compile_expression @@ npseq_to_list lst.inside in
|
||||
match lst with
|
||||
hd::[] -> ok @@ hd
|
||||
| lst -> ok @@ e_tuple ~loc lst
|
||||
match lst with
|
||||
hd::[] -> return hd
|
||||
| lst -> return @@ e_tuple ~loc lst
|
||||
in
|
||||
let compile_if_clause : ?next:AST.expression -> CST.if_clause -> _ = fun ?next if_clause ->
|
||||
match if_clause with
|
||||
ClauseInstr i -> compile_instruction ?next i
|
||||
| ClauseBlock (LongBlock block) -> compile_block ?next block
|
||||
| ClauseBlock (ShortBlock block) ->
|
||||
| ClauseBlock (ShortBlock block) ->
|
||||
(* This looks like it should be the job of the parser *)
|
||||
let CST.{lbrace; inside; rbrace} = block.value in
|
||||
let region = block.region in
|
||||
let enclosing = CST.Block (Region.ghost, lbrace, rbrace)
|
||||
let enclosing = CST.Block (Region.ghost, lbrace, rbrace)
|
||||
and (statements,terminator) = inside in
|
||||
let value = CST.{enclosing;statements;terminator} in
|
||||
let block : _ CST.reg = {value; region} in
|
||||
@ -548,18 +546,18 @@ let rec compile_instruction : ?next: AST.expression -> CST.instruction -> _ resu
|
||||
|
||||
in
|
||||
let compile_path : CST.path -> _ = fun path ->
|
||||
match path with
|
||||
Name var ->
|
||||
match path with
|
||||
Name var ->
|
||||
let (var,loc) = r_split var in
|
||||
let str = e_variable_ez ~loc var in
|
||||
ok @@ (str, var, [])
|
||||
ok (str, var, [])
|
||||
| Path proj ->
|
||||
let (proj, loc) = r_split proj in
|
||||
let (var, loc_var) = r_split proj.struct_name in
|
||||
let path = List.map compile_selection @@ npseq_to_list proj.field_path in
|
||||
let path = List.map compile_selection @@ npseq_to_list proj.field_path in
|
||||
let (path, _) = List.split path in
|
||||
let str = e_accessor ~loc (e_variable_ez ~loc:loc_var var) path in
|
||||
ok @@ (str, var, path)
|
||||
ok (str, var, path)
|
||||
in
|
||||
let compile_lhs : CST.lhs -> _ = fun lhs ->
|
||||
match lhs with
|
||||
@ -600,20 +598,20 @@ let rec compile_instruction : ?next: AST.expression -> CST.instruction -> _ resu
|
||||
let (binder, _) = r_split fl.binder in
|
||||
let%bind start = compile_expression fl.init in
|
||||
let%bind bound = compile_expression fl.bound in
|
||||
let%bind increment = Option.unopt ~default:(ok @@ e_int_z Z.one) @@
|
||||
let%bind increment = Option.unopt ~default:(ok @@ e_int_z Z.one) @@
|
||||
Option.map (compile_expression <@ snd) fl.step
|
||||
in
|
||||
let%bind body = compile_block fl.block in
|
||||
return @@ e_for_ez ~loc binder start bound increment body
|
||||
return @@ e_for_ez ~loc binder start bound increment body
|
||||
| Loop (For (ForCollect el)) ->
|
||||
let (el, loc) = r_split el in
|
||||
let binder =
|
||||
let binder =
|
||||
let (key, _) = r_split el.var in
|
||||
let value = Option.map (fun x -> fst (r_split (snd x))) el.bind_to in
|
||||
(key,value)
|
||||
in
|
||||
let%bind collection = compile_expression el.expr in
|
||||
let (collection_type, _) = match el.collection with
|
||||
let (collection_type, _) = match el.collection with
|
||||
Map loc -> (Map, loc) | Set loc -> (Set, loc) | List loc -> (List, loc)
|
||||
in
|
||||
let%bind body = compile_block el.block in
|
||||
@ -621,7 +619,7 @@ let rec compile_instruction : ?next: AST.expression -> CST.instruction -> _ resu
|
||||
| ProcCall {value=(EVar var,args);region} ->
|
||||
let loc = Location.lift region in
|
||||
let (var, loc_var) = r_split var in
|
||||
(match constants var with
|
||||
(match constants var with
|
||||
Some const ->
|
||||
let (args, _) = r_split args in
|
||||
let%bind args = bind_map_list compile_expression @@ npseq_to_list args.inside in
|
||||
@ -637,7 +635,7 @@ let rec compile_instruction : ?next: AST.expression -> CST.instruction -> _ resu
|
||||
let%bind func = compile_expression func in
|
||||
let%bind args = compile_tuple_expression args in
|
||||
return @@ e_application ~loc func args
|
||||
| Skip s ->
|
||||
| Skip s ->
|
||||
let loc = Location.lift s in
|
||||
return @@ e_skip ~loc ()
|
||||
| RecordPatch rp ->
|
||||
@ -696,7 +694,7 @@ and compile_data_declaration : next:AST.expression -> ?attr:CST.attr_decl -> CST
|
||||
ok @@ e_let_in_ez ~loc name type_ attr init next in
|
||||
match data_decl with
|
||||
LocalConst const_decl ->
|
||||
let (cd, loc) = r_split const_decl in
|
||||
let (cd, loc) = r_split const_decl in
|
||||
let (name, _) = r_split cd.name in
|
||||
let%bind type_ = bind_map_option (compile_type_expression <@ snd)cd.const_type in
|
||||
let%bind init = compile_expression cd.init in
|
||||
@ -714,41 +712,40 @@ and compile_data_declaration : next:AST.expression -> ?attr:CST.attr_decl -> CST
|
||||
|
||||
and compile_statement : ?next:AST.expression -> CST.attr_decl option -> CST.statement -> _ result = fun ?next attr statement ->
|
||||
match statement with
|
||||
Instr i ->
|
||||
Instr i ->
|
||||
let%bind i = compile_instruction ?next i in
|
||||
ok @@ (Some i, None)
|
||||
| Data dd ->
|
||||
return (Some i, None)
|
||||
| Data dd ->
|
||||
let next = Option.unopt ~default:(e_skip ()) next in
|
||||
let%bind dd = compile_data_declaration ~next ?attr dd in
|
||||
ok @@ (Some dd, None)
|
||||
| Attr at -> ok @@ (next, Some at)
|
||||
|
||||
return (Some dd, None)
|
||||
| Attr at -> return (next, Some at)
|
||||
|
||||
and compile_block : ?next:AST.expression -> CST.block CST.reg -> _ result = fun ?next block ->
|
||||
let (block', _loc) = r_split block in
|
||||
let statements = npseq_to_list block'.statements in
|
||||
let aux (next,attr) statement =
|
||||
let%bind (statement, attr) = compile_statement ?next attr statement in
|
||||
ok @@ (statement,attr)
|
||||
return (statement,attr)
|
||||
in
|
||||
let%bind (block', _) = bind_fold_right_list aux (next,None) statements in
|
||||
match block' with
|
||||
Some block -> ok @@ block
|
||||
Some block -> return block
|
||||
| None -> fail @@ block_start_with_attribute block
|
||||
|
||||
and compile_fun_decl ({kwd_recursive; fun_name; param; ret_type; block_with; return=r; attributes}: CST.fun_decl) =
|
||||
and compile_fun_decl ({kwd_recursive; fun_name; param; ret_type; block_with; return=r; attributes}: CST.fun_decl) =
|
||||
let%bind attr = compile_attribute_declaration attributes in
|
||||
let (fun_name, loc) = r_split fun_name in
|
||||
let%bind ret_type = bind_map_option (compile_type_expression <@ snd) ret_type in
|
||||
let%bind param = compile_parameters param in
|
||||
let%bind r = compile_expression r in
|
||||
let (param, param_type) = List.split param in
|
||||
let%bind body = Option.unopt ~default:(ok @@ r) @@
|
||||
Option.map (compile_block ~next:r <@ fst) block_with
|
||||
let%bind body = Option.unopt ~default:(return r) @@
|
||||
Option.map (compile_block ~next:r <@ fst) block_with
|
||||
in
|
||||
(* This handle the parameter case *)
|
||||
let (lambda,fun_type) = (match param_type with
|
||||
ty::[] ->
|
||||
ty::[] ->
|
||||
let lambda : AST.lambda = {
|
||||
binder = (Var.of_name @@ List.hd param);
|
||||
input_type = ty ;
|
||||
@ -771,18 +768,19 @@ and compile_fun_decl ({kwd_recursive; fun_name; param; ret_type; block_with; ret
|
||||
in
|
||||
(* This handle the recursion *)
|
||||
let%bind func = match kwd_recursive with
|
||||
Some reg ->
|
||||
Some reg ->
|
||||
let%bind fun_type = trace_option (untyped_recursive_fun loc) @@ fun_type in
|
||||
ok @@ e_recursive_ez ~loc:(Location.lift reg) fun_name fun_type lambda
|
||||
| None ->
|
||||
ok @@ make_e ~loc @@ E_lambda lambda
|
||||
return @@ e_recursive_ez ~loc:(Location.lift reg) fun_name fun_type lambda
|
||||
| None ->
|
||||
return @@ make_e ~loc @@ E_lambda lambda
|
||||
in
|
||||
ok @@ (fun_name,fun_type, attr, func)
|
||||
return (fun_name,fun_type, attr, func)
|
||||
|
||||
(* Currently attributes are badly proccess, some adaptation are made to accomodate this
|
||||
maked as ATR *)
|
||||
let compile_declaration : (CST.attr_decl option * _) -> CST.declaration -> _ = fun (attr, lst) decl ->
|
||||
let return ?attr reg decl = ok @@ (attr, (Location.wrap ~loc:(Location.lift reg) decl)::lst) in (*ATR*)
|
||||
let return ?attr reg decl =
|
||||
return (attr, (Location.wrap ~loc:(Location.lift reg) decl)::lst) in (*ATR*)
|
||||
match decl with
|
||||
TypeDecl {value={name; type_expr; _};region} ->
|
||||
(* Todo : if attr isn't none, send warning *)
|
||||
@ -800,8 +798,8 @@ let compile_declaration : (CST.attr_decl option * _) -> CST.declaration -> _ = f
|
||||
let value = {value with attributes = attr} in (*ATR*)
|
||||
let%bind (fun_name,fun_type,attr,lambda) = compile_fun_decl value in
|
||||
return region @@ AST.Declaration_constant (Var.of_name fun_name, fun_type, attr, lambda)
|
||||
| AttrDecl decl -> ok @@ (Some decl, lst) (*ATR*)
|
||||
|
||||
| AttrDecl decl -> ok (Some decl, lst) (*ATR*)
|
||||
|
||||
(* This should be change to the commented function when attributes are fixed
|
||||
let compile_program : CST.ast -> _ result = fun t ->
|
||||
bind_map_list compile_declaration @@ nseq_to_list t.decl
|
||||
@ -811,4 +809,4 @@ let compile_program : CST.ast -> _ result =
|
||||
let declarations = List.rev @@ nseq_to_list t.decl in
|
||||
let attr = (None, []) in
|
||||
let%bind (_, declarations) = bind_fold_list compile_declaration attr declarations in
|
||||
ok @@ declarations
|
||||
return declarations
|
||||
|
Loading…
Reference in New Issue
Block a user