Added instruction 'fail'. I changed the grammar and AST for local functions and removed global mutable variables.

This commit is contained in:
Christian Rinderknecht 2019-02-28 15:46:34 +01:00
parent 4893fe8826
commit 45d18f7b12
No known key found for this signature in database
GPG Key ID: 9446816CFD267040
11 changed files with 381 additions and 298 deletions

142
AST.ml
View File

@ -36,6 +36,7 @@ let sepseq_to_region to_region = function
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_const = Region.t type kwd_const = Region.t
type kwd_down = Region.t type kwd_down = Region.t
type kwd_fail = Region.t
type kwd_if = Region.t type kwd_if = Region.t
type kwd_in = Region.t type kwd_in = Region.t
type kwd_is = Region.t type kwd_is = Region.t
@ -137,6 +138,7 @@ type 'a braces = (lbrace * 'a * rbrace) reg
type t = < type t = <
types : type_decl list; types : type_decl list;
constants : const_decl reg list;
parameter : parameter_decl; parameter : parameter_decl;
storage : storage_decl; storage : storage_decl;
operations : operations_decl; operations : operations_decl;
@ -185,48 +187,58 @@ and lambda_decl =
and fun_decl = < and fun_decl = <
kwd_function : kwd_function; kwd_function : kwd_function;
var : variable; name : variable;
param : parameters; param : parameters;
colon : colon; colon : colon;
ret_type : type_expr; ret_type : type_expr;
kwd_is : kwd_is; kwd_is : kwd_is;
body : block reg; local_decls : local_decl list;
block : block reg;
kwd_with : kwd_with; kwd_with : kwd_with;
return : expr return : expr
> >
and proc_decl = < and proc_decl = <
kwd_procedure : kwd_procedure; kwd_procedure : kwd_procedure;
var : variable; name : variable;
param : parameters; param : parameters;
kwd_is : kwd_is; kwd_is : kwd_is;
body : block reg local_decls : local_decl list;
block : block reg
> >
and parameters = (param_decl, semi) nsepseq par and parameters = (param_decl, semi) nsepseq par
and param_decl = (var_kind * variable * colon * type_expr) reg and param_decl =
ParamConst of (kwd_const * variable * colon * type_expr) reg
and var_kind = | ParamVar of (kwd_var * variable * colon * type_expr) reg
Mutable of kwd_var
| Const of kwd_const
and block = < and block = <
decls : value_decls;
opening : kwd_begin; opening : kwd_begin;
instr : instructions; instr : instructions;
close : kwd_end close : kwd_end
> >
and value_decls = (var_decl reg, semi) sepseq reg and local_decl =
LocalLam of lambda_decl
| LocalConst of const_decl reg
| LocalVar of var_decl reg
and const_decl = <
kwd_const : kwd_const;
name : variable;
colon : colon;
vtype : type_expr;
equal : equal;
init : expr
>
and var_decl = < and var_decl = <
kind : var_kind; kwd_var : kwd_var;
var : variable; name : variable;
colon : colon; colon : colon;
vtype : type_expr; vtype : type_expr;
setter : Region.t; (* "=" or ":=" *) asgnmnt : asgnmnt;
init : expr init : expr
> >
and instructions = (instruction, semi) nsepseq reg and instructions = (instruction, semi) nsepseq reg
@ -242,6 +254,7 @@ and single_instr =
| Loop of loop | Loop of loop
| ProcCall of fun_call | ProcCall of fun_call
| Null of kwd_null | Null of kwd_null
| Fail of (kwd_fail * expr) reg
and conditional = < and conditional = <
kwd_if : kwd_if; kwd_if : kwd_if;
@ -428,10 +441,6 @@ let expr_to_region = function
| MapLookUp {region; _} | MapLookUp {region; _}
| ParExpr {region; _} -> region | ParExpr {region; _} -> region
let var_kind_to_region = function
Mutable region
| Const region -> region
let instr_to_region = function let instr_to_region = function
Single Cond {region;_} Single Cond {region;_}
| Single Match {region; _} | Single Match {region; _}
@ -441,6 +450,7 @@ let instr_to_region = function
| Single Loop For ForCollect {region; _} | Single Loop For ForCollect {region; _}
| Single ProcCall {region; _} | Single ProcCall {region; _}
| Single Null region | Single Null region
| Single Fail {region; _}
| Block {region; _} -> region | Block {region; _} -> region
let core_pattern_to_region = function let core_pattern_to_region = function
@ -458,6 +468,12 @@ let core_pattern_to_region = function
| PList Raw {region; _} | PList Raw {region; _}
| PTuple {region; _} -> region | PTuple {region; _} -> region
let local_decl_to_region = function
LocalLam FunDecl {region; _}
| LocalLam ProcDecl {region; _}
| LocalConst {region; _}
| LocalVar {region; _} -> region
(* Printing the tokens with their source regions *) (* Printing the tokens with their source regions *)
let printf = Printf.printf let printf = Printf.printf
@ -589,22 +605,24 @@ and print_lambda_decl = function
| ProcDecl proc_decl -> print_proc_decl proc_decl | ProcDecl proc_decl -> print_proc_decl proc_decl
and print_fun_decl {value=node; _} = and print_fun_decl {value=node; _} =
print_token node#kwd_function "function"; print_token node#kwd_function "function";
print_var node#var; print_var node#name;
print_parameters node#param; print_parameters node#param;
print_token node#colon ":"; print_token node#colon ":";
print_type_expr node#ret_type; print_type_expr node#ret_type;
print_token node#kwd_is "is"; print_token node#kwd_is "is";
print_block node#body; print_local_decls node#local_decls;
print_token node#kwd_with "with"; print_block node#block;
print_expr node#return print_token node#kwd_with "with";
print_expr node#return
and print_proc_decl {value=node; _} = and print_proc_decl {value=node; _} =
print_token node#kwd_procedure "procedure"; print_token node#kwd_procedure "procedure";
print_var node#var; print_var node#name;
print_parameters node#param; print_parameters node#param;
print_token node#kwd_is "is"; print_token node#kwd_is "is";
print_block node#body print_local_decls node#local_decls;
print_block node#block
and print_parameters {value=node; _} = and print_parameters {value=node; _} =
let lpar, sequence, rpar = node in let lpar, sequence, rpar = node in
@ -612,36 +630,51 @@ and print_parameters {value=node; _} =
print_nsepseq ";" print_param_decl sequence; print_nsepseq ";" print_param_decl sequence;
print_token rpar ")" print_token rpar ")"
and print_param_decl {value=node; _} = and print_param_decl = function
let var_kind, variable, colon, type_expr = node in ParamConst param_const -> print_param_const param_const
print_var_kind var_kind; | ParamVar param_var -> print_param_var param_var
and print_param_const {value=node; _} =
let kwd_const, variable, colon, type_expr = node in
print_token kwd_const "const";
print_var variable; print_var variable;
print_token colon ":"; print_token colon ":";
print_type_expr type_expr print_type_expr type_expr
and print_var_kind = function and print_param_var {value=node; _} =
Mutable kwd_var -> print_token kwd_var "var" let kwd_var, variable, colon, type_expr = node in
| Const kwd_const -> print_token kwd_const "const" print_token kwd_var "var";
print_var variable;
print_token colon ":";
print_type_expr type_expr
and print_block {value=node; _} = and print_block {value=node; _} =
print_value_decls node#decls;
print_token node#opening "begin"; print_token node#opening "begin";
print_instructions node#instr; print_instructions node#instr;
print_token node#close "end" print_token node#close "end"
and print_value_decls {value=sequence; _} = and print_local_decls sequence =
print_sepseq ";" print_var_decl sequence List.iter print_local_decl sequence
and print_var_decl {value=node; _} = and print_local_decl = function
let setter = LocalLam decl -> print_lambda_decl decl
match node#kind with | LocalConst decl -> print_const_decl decl
Mutable _ -> ":=" | LocalVar decl -> print_var_decl decl
| Const _ -> "=" in
print_var_kind node#kind; and print_const_decl {value=node; _} =
print_var node#var; print_token node#kwd_const "const";
print_var node#name;
print_token node#colon ":"; print_token node#colon ":";
print_type_expr node#vtype; print_type_expr node#vtype;
print_token node#setter setter; print_token node#equal "=";
print_expr node#init
and print_var_decl {value=node; _} =
print_token node#kwd_var "var";
print_var node#name;
print_token node#colon ":";
print_type_expr node#vtype;
print_token node#asgnmnt ":=";
print_expr node#init print_expr node#init
and print_instructions {value=sequence; _} = and print_instructions {value=sequence; _} =
@ -658,6 +691,11 @@ and print_single_instr = function
| Loop loop -> print_loop loop | Loop loop -> print_loop loop
| ProcCall fun_call -> print_fun_call fun_call | ProcCall fun_call -> print_fun_call fun_call
| Null kwd_null -> print_token kwd_null "null" | Null kwd_null -> print_token kwd_null "null"
| Fail {value; _} -> print_fail value
and print_fail (kwd_fail, expr) =
print_token kwd_fail "fail";
print_expr expr
and print_conditional node = and print_conditional node =
print_token node#kwd_if "if"; print_token node#kwd_if "if";

52
AST.mli
View File

@ -24,6 +24,7 @@ val sepseq_to_region : ('a -> Region.t) -> ('a,'sep) sepseq -> Region.t
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_const = Region.t type kwd_const = Region.t
type kwd_down = Region.t type kwd_down = Region.t
type kwd_fail = Region.t
type kwd_if = Region.t type kwd_if = Region.t
type kwd_in = Region.t type kwd_in = Region.t
type kwd_is = Region.t type kwd_is = Region.t
@ -125,6 +126,7 @@ type 'a braces = (lbrace * 'a * rbrace) reg
type t = < type t = <
types : type_decl list; types : type_decl list;
constants : const_decl reg list;
parameter : parameter_decl; parameter : parameter_decl;
storage : storage_decl; storage : storage_decl;
operations : operations_decl; operations : operations_decl;
@ -173,48 +175,59 @@ and lambda_decl =
and fun_decl = < and fun_decl = <
kwd_function : kwd_function; kwd_function : kwd_function;
var : variable; name : variable;
param : parameters; param : parameters;
colon : colon; colon : colon;
ret_type : type_expr; ret_type : type_expr;
kwd_is : kwd_is; kwd_is : kwd_is;
body : block reg; local_decls : local_decl list;
block : block reg;
kwd_with : kwd_with; kwd_with : kwd_with;
return : expr return : expr
> >
and proc_decl = < and proc_decl = <
kwd_procedure : kwd_procedure; kwd_procedure : kwd_procedure;
var : variable; name : variable;
param : parameters; param : parameters;
kwd_is : kwd_is; kwd_is : kwd_is;
body : block reg local_decls : local_decl list;
block : block reg
> >
and parameters = (param_decl, semi) nsepseq par and parameters = (param_decl, semi) nsepseq par
and param_decl = (var_kind * variable * colon * type_expr) reg and param_decl =
ParamConst of (kwd_const * variable * colon * type_expr) reg
and var_kind = | ParamVar of (kwd_var * variable * colon * type_expr) reg
Mutable of kwd_var
| Const of kwd_const
and block = < and block = <
decls : value_decls;
opening : kwd_begin; opening : kwd_begin;
instr : instructions; instr : instructions;
close : kwd_end close : kwd_end
> >
and value_decls = (var_decl reg, semi) sepseq reg and local_decl =
LocalLam of lambda_decl
| LocalConst of const_decl reg
| LocalVar of var_decl reg
and const_decl = <
kwd_const : kwd_const;
name : variable;
colon : colon;
vtype : type_expr;
equal : equal;
init : expr
>
and var_decl = < and var_decl = <
kind : var_kind; kwd_var : kwd_var;
var : variable; name : variable;
colon : colon; colon : colon;
vtype : type_expr; vtype : type_expr;
setter : Region.t; (* "=" or ":=" *) asgnmnt : asgnmnt;
init : expr init : expr
> >
and instructions = (instruction, semi) nsepseq reg and instructions = (instruction, semi) nsepseq reg
@ -230,6 +243,7 @@ and single_instr =
| Loop of loop | Loop of loop
| ProcCall of fun_call | ProcCall of fun_call
| Null of kwd_null | Null of kwd_null
| Fail of (kwd_fail * expr) reg
and conditional = < and conditional = <
kwd_if : kwd_if; kwd_if : kwd_if;
@ -373,12 +387,12 @@ val type_expr_to_region : type_expr -> Region.t
val expr_to_region : expr -> Region.t val expr_to_region : expr -> Region.t
val var_kind_to_region : var_kind -> Region.t
val instr_to_region : instruction -> Region.t val instr_to_region : instruction -> Region.t
val core_pattern_to_region : core_pattern -> Region.t val core_pattern_to_region : core_pattern -> Region.t
val local_decl_to_region : local_decl -> Region.t
(* Printing *) (* Printing *)
val print_tokens : t -> unit val print_tokens : t -> unit

View File

@ -14,16 +14,21 @@ let help () =
printf "Usage: %s [<option> ...] [<input>.li | \"-\"]\n" file; printf "Usage: %s [<option> ...] [<input>.li | \"-\"]\n" file;
print_endline "where <input>.li is the Ligo source file (default: stdin),"; print_endline "where <input>.li is the Ligo source file (default: stdin),";
print_endline "and each <option> (if any) is one of the following:"; print_endline "and each <option> (if any) is one of the following:";
print_endline " -c, --copy Print lexemes of tokens and markup (lexer)"; print_endline " -c, --copy Print lexemes of tokens and markup (lexer)";
print_endline " -t, --tokens Print tokens (lexer)"; print_endline " -t, --tokens Print tokens (lexer)";
print_endline " -u, --units Print tokens and markup (lexer)"; print_endline " -u, --units Print tokens and markup (lexer)";
print_endline " -q, --quiet No output, except errors (default)"; print_endline " -q, --quiet No output, except errors (default)";
print_endline " --columns Columns for source locations"; print_endline " --columns Columns for source locations";
print_endline " --bytes Bytes for source locations"; print_endline " --bytes Bytes for source locations";
print_endline " -v, --verbose=<stage> cmdline, parser"; print_endline " --verbose=<stages> cmdline, parser";
print_endline " -h, --help This help"; print_endline " --version Commit hash on stdout";
print_endline " -h, --help This help";
exit 0 exit 0
(* Version *)
let version () = printf "%s\n" Version.version; exit 0
(* Specifying the command-line options a la GNU *) (* Specifying the command-line options a la GNU *)
let copy = ref false let copy = ref false
@ -44,14 +49,15 @@ let add_verbose d =
let specs = let specs =
let open! Getopt in [ let open! Getopt in [
'c', "copy", set copy true, None; 'c', "copy", set copy true, None;
't', "tokens", set tokens true, None; 't', "tokens", set tokens true, None;
'u', "units", set units true, None; 'u', "units", set units true, None;
'q', "quiet", set quiet true, None; 'q', "quiet", set quiet true, None;
noshort, "columns", set columns true, None; noshort, "columns", set columns true, None;
noshort, "bytes", set bytes true, None; noshort, "bytes", set bytes true, None;
'v', "verbose", None, Some add_verbose; noshort, "verbose", None, Some add_verbose;
'h', "help", Some help, None 'h', "help", Some help, None;
noshort, "version", Some version, None
] ]
;; ;;
@ -115,7 +121,7 @@ let input =
then if Sys.file_exists file_path then if Sys.file_exists file_path
then Some file_path then Some file_path
else abort "Source file not found." else abort "Source file not found."
else abort "Source file lacks the extension .ti." else abort "Source file lacks the extension .li."
(* Exporting remaining options as non-mutable values *) (* Exporting remaining options as non-mutable values *)

View File

@ -67,33 +67,34 @@ type t =
(* Keywords *) (* Keywords *)
| Begin of Region.t | Begin of Region.t (* "begin" *)
| Const of Region.t | Const of Region.t (* "const" *)
| Down of Region.t | Down of Region.t (* "down" *)
| If of Region.t | Fail of Region.t (* "fail" *)
| In of Region.t | If of Region.t (* "if" *)
| Is of Region.t | In of Region.t (* "in" *)
| For of Region.t | Is of Region.t (* "is" *)
| Function of Region.t | For of Region.t (* "for" *)
| Parameter of Region.t | Function of Region.t (* "function" *)
| Storage of Region.t | Parameter of Region.t (* "parameter" *)
| Type of Region.t | Storage of Region.t (* "storage" *)
| Of of Region.t | Type of Region.t (* "type" *)
| Operations of Region.t | Of of Region.t (* "of" *)
| Var of Region.t | Operations of Region.t (* "operations" *)
| End of Region.t | Var of Region.t (* "var" *)
| Then of Region.t | End of Region.t (* "end" *)
| Else of Region.t | Then of Region.t (* "then" *)
| Match of Region.t | Else of Region.t (* "else" *)
| Null of Region.t | Match of Region.t (* "match" *)
| Procedure of Region.t | Null of Region.t (* "null" *)
| Record of Region.t | Procedure of Region.t (* "procedure" *)
| Step of Region.t | Record of Region.t (* "record" *)
| To of Region.t | Step of Region.t (* "step" *)
| Mod of Region.t | To of Region.t (* "to" *)
| Not of Region.t | Mod of Region.t (* "mod" *)
| While of Region.t | Not of Region.t (* "not" *)
| With of Region.t | While of Region.t (* "while" *)
| With of Region.t (* "with" *)
(* Data constructors *) (* Data constructors *)

View File

@ -69,6 +69,7 @@ type t =
| Begin of Region.t | Begin of Region.t
| Const of Region.t | Const of Region.t
| Down of Region.t | Down of Region.t
| Fail of Region.t
| If of Region.t | If of Region.t
| In of Region.t | In of Region.t
| Is of Region.t | Is of Region.t
@ -187,6 +188,7 @@ let proj_token = function
| Begin region -> region, "Begin" | Begin region -> region, "Begin"
| Const region -> region, "Const" | Const region -> region, "Const"
| Down region -> region, "Down" | Down region -> region, "Down"
| Fail region -> region, "Fail"
| If region -> region, "If" | If region -> region, "If"
| In region -> region, "In" | In region -> region, "In"
| Is region -> region, "Is" | Is region -> region, "Is"
@ -270,6 +272,7 @@ let to_lexeme = function
| Begin _ -> "begin" | Begin _ -> "begin"
| Const _ -> "const" | Const _ -> "const"
| Down _ -> "down" | Down _ -> "down"
| Fail _ -> "fail"
| If _ -> "if" | If _ -> "if"
| In _ -> "in" | In _ -> "in"
| Is _ -> "is" | Is _ -> "is"
@ -321,6 +324,7 @@ let keywords = [
(fun reg -> Begin reg); (fun reg -> Begin reg);
(fun reg -> Const reg); (fun reg -> Const reg);
(fun reg -> Down reg); (fun reg -> Down reg);
(fun reg -> Fail reg);
(fun reg -> If reg); (fun reg -> If reg);
(fun reg -> In reg); (fun reg -> In reg);
(fun reg -> Is reg); (fun reg -> Is reg);
@ -544,6 +548,7 @@ let is_kwd = function
| Begin _ | Begin _
| Const _ | Const _
| Down _ | Down _
| Fail _
| If _ | If _
| In _ | In _
| Is _ | Is _

View File

@ -166,14 +166,15 @@ module Make (Token: TOKEN) : (S with module Token = Token) =
(* When scanning structured constructs, like strings and comments, (* When scanning structured constructs, like strings and comments,
we need to keep the region of the opening symbol (like double we need to keep the region of the opening symbol (like double
quote, "#" or "/*") in order to report any error more quote, "#" or "(*") in order to report any error more
precisely. Since ocamllex is byte-oriented, we need to store precisely. Since ocamllex is byte-oriented, we need to store
the parsed bytes are characters in an accumulator [acc] and the parsed bytes as characters in an accumulator [acc] and
also its length [len], so, we are done, it is easy to build the also its length [len], so, we are done, it is easy to build the
string making up the structured construct with [mk_str] (see string making up the structured construct with [mk_str] (see
above). above).
The resulting data structure is called a _thread_. The resulting data structure is called a _thread_.
(Note for Emacs: "*)".)
*) *)
type thread = { type thread = {
@ -350,7 +351,7 @@ module Make (Token: TOKEN) : (S with module Token = Token) =
Hint: Add or remove a digit.\n" Hint: Add or remove a digit.\n"
| Unterminated_comment -> | Unterminated_comment ->
"Unterminated comment.\n\ "Unterminated comment.\n\
Hint: Close with \"*/\".\n" Hint: Close with \"*)\".\n"
| Orphan_minus -> | Orphan_minus ->
"Orphan minus sign.\n\ "Orphan minus sign.\n\
Hint: Remove the trailing space.\n" Hint: Remove the trailing space.\n"
@ -476,8 +477,8 @@ and scan state = parse
let thread = {opening; len=1; acc=['"']} in let thread = {opening; len=1; acc=['"']} in
scan_string thread state lexbuf |> mk_string |> enqueue } scan_string thread state lexbuf |> mk_string |> enqueue }
| "/*" { let opening, _, state = sync state lexbuf in | "(*" { let opening, _, state = sync state lexbuf in
let thread = {opening; len=2; acc=['*';'/']} in let thread = {opening; len=2; acc=['*';'(']} in
let state = scan_block thread state lexbuf |> push_block let state = scan_block thread state lexbuf |> push_block
in scan state lexbuf } in scan state lexbuf }
@ -535,14 +536,15 @@ and scan_string thread state = parse
(* Finishing a block comment (* Finishing a block comment
(Note for Emacs: ("(*")
The lexing of block comments must take care of embedded block The lexing of block comments must take care of embedded block
comments that may occur within, as well as strings, so no substring comments that may occur within, as well as strings, so no substring
"*/" may inadvertantly close the block. This is the purpose of the "*)" may inadvertently close the block. This is the purpose
first case of the scanner [scan_block]. of the first case of the scanner [scan_block].
*) *)
and scan_block thread state = parse and scan_block thread state = parse
'"' | "/*" { let opening = thread.opening in '"' | "(*" { let opening = thread.opening in
let opening', lexeme, state = sync state lexbuf in let opening', lexeme, state = sync state lexbuf in
let thread = push_string lexeme thread in let thread = push_string lexeme thread in
let thread = {thread with opening=opening'} in let thread = {thread with opening=opening'} in
@ -551,7 +553,7 @@ and scan_block thread state = parse
let thread, state = next thread state lexbuf in let thread, state = next thread state lexbuf in
let thread = {thread with opening} let thread = {thread with opening}
in scan_block thread state lexbuf } in scan_block thread state lexbuf }
| "*/" { let _, lexeme, state = sync state lexbuf | "*)" { let _, lexeme, state = sync state lexbuf
in push_string lexeme thread, state } in push_string lexeme thread, state }
| nl as nl { let () = Lexing.new_line lexbuf | nl as nl { let () = Lexing.new_line lexbuf
and state = {state with pos = state.pos#new_line nl} and state = {state with pos = state.pos#new_line nl}

View File

@ -5,80 +5,81 @@
(* Literals *) (* Literals *)
%token <LexToken.lexeme Region.reg> String %token <LexToken.lexeme Region.reg> String
%token <(LexToken.lexeme * MBytes.t) Region.reg> Bytes %token <(LexToken.lexeme * MBytes.t) Region.reg> Bytes
%token <(LexToken.lexeme * Z.t) Region.reg> Int %token <(LexToken.lexeme * Z.t) Region.reg> Int
%token <LexToken.lexeme Region.reg> Ident %token <LexToken.lexeme Region.reg> Ident
%token <LexToken.lexeme Region.reg> Constr %token <LexToken.lexeme Region.reg> Constr
(* Symbols *) (* Symbols *)
%token <Region.t> SEMI %token <Region.t> SEMI (* ";" *)
%token <Region.t> COMMA %token <Region.t> COMMA (* "," *)
%token <Region.t> LPAR %token <Region.t> LPAR (* "(" *)
%token <Region.t> RPAR %token <Region.t> RPAR (* ")" *)
%token <Region.t> LBRACE %token <Region.t> LBRACE (* "{" *)
%token <Region.t> RBRACE %token <Region.t> RBRACE (* "}" *)
%token <Region.t> LBRACKET %token <Region.t> LBRACKET (* "[" *)
%token <Region.t> RBRACKET %token <Region.t> RBRACKET (* "]" *)
%token <Region.t> CONS %token <Region.t> CONS (* "<:" *)
%token <Region.t> VBAR %token <Region.t> VBAR (* "|" *)
%token <Region.t> ARROW %token <Region.t> ARROW (* "->" *)
%token <Region.t> ASGNMNT %token <Region.t> ASGNMNT (* ":=" *)
%token <Region.t> EQUAL %token <Region.t> EQUAL (* "=" *)
%token <Region.t> COLON %token <Region.t> COLON (* ":" *)
%token <Region.t> OR %token <Region.t> OR (* "||" *)
%token <Region.t> AND %token <Region.t> AND (* "&&" *)
%token <Region.t> LT %token <Region.t> LT (* "<" *)
%token <Region.t> LEQ %token <Region.t> LEQ (* "<=" *)
%token <Region.t> GT %token <Region.t> GT (* ">" *)
%token <Region.t> GEQ %token <Region.t> GEQ (* ">=" *)
%token <Region.t> NEQ %token <Region.t> NEQ (* "=/=" *)
%token <Region.t> PLUS %token <Region.t> PLUS (* "+" *)
%token <Region.t> MINUS %token <Region.t> MINUS (* "-" *)
%token <Region.t> SLASH %token <Region.t> SLASH (* "/" *)
%token <Region.t> TIMES %token <Region.t> TIMES (* "*" *)
%token <Region.t> DOT %token <Region.t> DOT (* "." *)
%token <Region.t> WILD %token <Region.t> WILD (* "_" *)
%token <Region.t> CAT %token <Region.t> CAT (* "^" *)
(* Keywords *) (* Keywords *)
%token <Region.t> Begin %token <Region.t> Begin (* "begin" *)
%token <Region.t> Const %token <Region.t> Const (* "const" *)
%token <Region.t> Down %token <Region.t> Down (* "down" *)
%token <Region.t> If %token <Region.t> Fail (* "fail" *)
%token <Region.t> In %token <Region.t> If (* "if" *)
%token <Region.t> Is %token <Region.t> In (* "in" *)
%token <Region.t> For %token <Region.t> Is (* "is" *)
%token <Region.t> Function %token <Region.t> For (* "for" *)
%token <Region.t> Parameter %token <Region.t> Function (* "function" *)
%token <Region.t> Storage %token <Region.t> Parameter (* "parameter" *)
%token <Region.t> Type %token <Region.t> Storage (* "storage" *)
%token <Region.t> Of %token <Region.t> Type (* "type" *)
%token <Region.t> Operations %token <Region.t> Of (* "of" *)
%token <Region.t> Var %token <Region.t> Operations (* "operations" *)
%token <Region.t> End %token <Region.t> Var (* "var" *)
%token <Region.t> Then %token <Region.t> End (* "end" *)
%token <Region.t> Else %token <Region.t> Then (* "then" *)
%token <Region.t> Match %token <Region.t> Else (* "else" *)
%token <Region.t> Null %token <Region.t> Match (* "match" *)
%token <Region.t> Procedure %token <Region.t> Null (* "null" *)
%token <Region.t> Record %token <Region.t> Procedure (* "procedure" *)
%token <Region.t> Step %token <Region.t> Record (* "record" *)
%token <Region.t> To %token <Region.t> Step (* "step" *)
%token <Region.t> Mod %token <Region.t> To (* "to" *)
%token <Region.t> Not %token <Region.t> Mod (* "mod" *)
%token <Region.t> While %token <Region.t> Not (* "not" *)
%token <Region.t> With %token <Region.t> While (* "while" *)
%token <Region.t> With (* "with" *)
(* Data constructors *) (* Data constructors *)
%token <Region.t> C_False %token <Region.t> C_False (* "False" *)
%token <Region.t> C_None %token <Region.t> C_None (* "None" *)
%token <Region.t> C_Some %token <Region.t> C_Some (* "Some" *)
%token <Region.t> C_True %token <Region.t> C_True (* "True" *)
%token <Region.t> C_Unit %token <Region.t> C_Unit (* "Unit" *)
(* Virtual tokens *) (* Virtual tokens *)

View File

@ -7,6 +7,8 @@ open AST
(* END HEADER *) (* END HEADER *)
%} %}
(* See [ParToken.mly] for the definition of tokens. *)
(* Entry points *) (* Entry points *)
%start program %start program
@ -86,21 +88,24 @@ sepseq(X,Sep):
program: program:
seq(type_decl) seq(type_decl)
seq(const_decl)
parameter_decl parameter_decl
storage_decl storage_decl
operations_decl operations_decl
seq(lambda_decl) seq(lambda_decl)
block block
EOF { EOF
object {
method types = $1 object
method parameter = $2 method types = $1
method storage = $3 method constants = $2
method operations = $4 method parameter = $3
method lambdas = $5 method storage = $4
method block = $6 method operations = $5
method eof = $7 method lambdas = $6
end method block = $7
method eof = $8
end
} }
parameter_decl: parameter_decl:
@ -173,14 +178,15 @@ variant:
record_type: record_type:
Record Record
nsepseq(field_decl,SEMI) nsepseq(field_decl,SEMI)
End { End
let region = cover $1 $3 {
in {region; value = $1,$2,$3} let region = cover $1 $3
in {region; value = $1,$2,$3}
} }
field_decl: field_decl:
field_name COLON type_expr { field_name COLON type_expr {
let stop = type_expr_to_region $3 in let stop = type_expr_to_region $3 in
let region = cover $1.region stop let region = cover $1.region stop
in {region; value = $1,$2,$3} in {region; value = $1,$2,$3}
} }
@ -193,101 +199,105 @@ lambda_decl:
fun_decl: fun_decl:
Function fun_name parameters COLON type_expr Is Function fun_name parameters COLON type_expr Is
seq(local_decl)
block block
With expr { With expr
let region = cover $1 (expr_to_region $9) in {
let value = let region = cover $1 (expr_to_region $10) in
object let value =
method kwd_function = $1 object
method var = $2 method kwd_function = $1
method param = $3 method name = $2
method colon = $4 method param = $3
method ret_type = $5 method colon = $4
method kwd_is = $6 method ret_type = $5
method body = $7 method kwd_is = $6
method kwd_with = $8 method local_decls = $7
method return = $9 method block = $8
end method kwd_with = $9
in {region; value} method return = $10
end
in {region; value}
} }
proc_decl: proc_decl:
Procedure fun_name parameters Is Procedure fun_name parameters Is
block { seq(local_decl)
let region = cover $1 $5.region in block
let value = {
object let region = cover $1 $6.region in
method kwd_procedure = $1 let value =
method var = $2 object
method param = $3 method kwd_procedure = $1
method kwd_is = $4 method name = $2
method body = $5 method param = $3
end method kwd_is = $4
in {region; value} method local_decls = $5
method block = $6
end
in {region; value}
} }
parameters: parameters:
par(nsepseq(param_decl,SEMI)) { $1 } par(nsepseq(param_decl,SEMI)) { $1 }
param_decl: param_decl:
var_kind var COLON type_expr { Var var COLON type_expr {
let start = var_kind_to_region $1 in
let stop = type_expr_to_region $4 in let stop = type_expr_to_region $4 in
let region = cover start stop let region = cover $1 stop
in {region; value = $1,$2,$3,$4} in ParamVar {region; value = $1,$2,$3,$4}
}
| Const var COLON type_expr {
let stop = type_expr_to_region $4 in
let region = cover $1 stop
in ParamConst {region; value = $1,$2,$3,$4}
} }
var_kind:
Var { Mutable $1 }
| Const { Const $1 }
block: block:
value_decls
Begin Begin
instructions instructions
End { End
let region = cover $1.region $4 in {
let value = let region = cover $1 $3 in
object let value =
method decls = $1 object
method opening = $2 method opening = $1
method instr = $3 method instr = $2
method close = $4 method close = $3
end end
in {region; value} in {region; value}
} }
value_decls: local_decl:
sepseq(var_decl,SEMI) { lambda_decl { LocalLam $1 }
let region = sepseq_to_region (fun x -> x.region) $1 | const_decl { LocalConst $1 }
in {region; value=$1} | var_decl { LocalVar $1 }
const_decl:
Const var COLON type_expr EQUAL expr {
let region = cover $1 (expr_to_region $6) in
let value = object
method kwd_const = $1
method name = $2
method colon = $3
method vtype = $4
method equal = $5
method init = $6
end
in {region; value}
} }
var_decl: var_decl:
Var var COLON type_expr ASGNMNT expr { Var var COLON type_expr ASGNMNT expr {
let region = cover $1 (expr_to_region $6) in let region = cover $1 (expr_to_region $6) in
let value = let value = object
object method kwd_var = $1
method kind = Mutable $1 method name = $2
method var = $2 method colon = $3
method colon = $3 method vtype = $4
method vtype = $4 method asgnmnt = $5
method setter = $5 method init = $6
method init = $6 end
end
in {region; value}
}
| Const var COLON type_expr EQUAL expr {
let region = cover $1 (expr_to_region $6) in
let value =
object
method kind = Const $1
method var = $2
method colon = $3
method vtype = $4
method setter = $5
method init = $6
end
in {region; value} in {region; value}
} }
@ -308,6 +318,10 @@ single_instr:
| loop { Loop $1 } | loop { Loop $1 }
| proc_call { ProcCall $1 } | proc_call { ProcCall $1 }
| Null { Null $1 } | Null { Null $1 }
| Fail expr {
let region = cover $1 (expr_to_region $2)
in Fail {region; value = $1,$2}
}
proc_call: proc_call:
fun_call { $1 } fun_call { $1 }

View File

@ -3,18 +3,19 @@ type u is t
type v is record foo: key; bar: mutez; baz: address end type v is record foo: key; bar: mutez; baz: address end
type w is K of v * u type w is K of v * u
parameter p : v parameter p : v # Line comment
storage w storage w
operations u operations u
function f (const x : int) : int is (* Block comment *)
var y : int := 5 - x;
const z : int = 6
begin
y := x + y
end with y * 2
procedure g (const l : list (int)) is procedure g (const l : list (int)) is
function f (const x : int) : int is
var y : int := 5 - x
const z : int = 6
begin
y := x + y
end with y * 2
begin begin
match l with match l with
[] -> null [] -> null
@ -23,5 +24,6 @@ procedure g (const l : list (int)) is
end end
begin begin
g (Unit) g (Unit) (*;
fail K (3, "foo")*)
end end

View File

@ -1 +1 @@
let version = "7445e9c0" let version = "4893fe8"

View File

@ -1,19 +1,19 @@
opam-version: "2.0" opam-version : "2.0"
version: "1.0" version : "1.0"
maintainer: "gabriel.alfour@gmail.com" maintainer : "gabriel.alfour@gmail.com"
authors: [ "Galfour" ] authors : [ "Galfour" ]
homepage: "https://gitlab.com/gabriel.alfour/ligo-parser" homepage : "https://gitlab.com/gabriel.alfour/ligo-parser"
bug-reports: "https://gitlab.com/gabriel.alfour/ligo-parser/issues" bug-reports : "https://gitlab.com/gabriel.alfour/ligo-parser/issues"
dev-repo: "git+https://gitlab.com/gabriel.alfour/ligo-parser.git" dev-repo : "git+https://gitlab.com/gabriel.alfour/ligo-parser.git"
license: "MIT" license : "MIT"
depends: [
"dune" depends : [ "dune" "menhir" "hex" "zarith" "getopt" "uutf" ]
"menhir"
"hex" "zarith" "getopt" "uutf" build : [
] [ "sh" "-c" "printf 'let version = \"%s\"' \"$(git describe --always --dirty --abbrev=0)\" > Version.ml" ]
build: [ [ "dune" "build" "-p" name "-j" jobs ]
[ "dune" "build" "-p" name "-j" jobs ] ]
]
url { url {
src: "https://gitlab.com/gabriel.alfour/ligo-parser/-/archive/master/ligo-parser.tar.gz" src: "https://gitlab.com/gabriel.alfour/ligo-parser/-/archive/master/ligo-parser.tar.gz"
} }