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

View File

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

View File

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

View File

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

View File

@ -166,14 +166,15 @@ module Make (Token: TOKEN) : (S with module Token = Token) =
(* When scanning structured constructs, like strings and comments,
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
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
string making up the structured construct with [mk_str] (see
above).
The resulting data structure is called a _thread_.
(Note for Emacs: "*)".)
*)
type thread = {
@ -350,7 +351,7 @@ module Make (Token: TOKEN) : (S with module Token = Token) =
Hint: Add or remove a digit.\n"
| Unterminated_comment ->
"Unterminated comment.\n\
Hint: Close with \"*/\".\n"
Hint: Close with \"*)\".\n"
| Orphan_minus ->
"Orphan minus sign.\n\
Hint: Remove the trailing space.\n"
@ -476,8 +477,8 @@ and scan state = parse
let thread = {opening; len=1; acc=['"']} in
scan_string thread state lexbuf |> mk_string |> enqueue }
| "/*" { let opening, _, state = sync state lexbuf in
let thread = {opening; len=2; acc=['*';'/']} in
| "(*" { let opening, _, state = sync state lexbuf in
let thread = {opening; len=2; acc=['*';'(']} in
let state = scan_block thread state lexbuf |> push_block
in scan state lexbuf }
@ -535,14 +536,15 @@ and scan_string thread state = parse
(* Finishing a block comment
(Note for Emacs: ("(*")
The lexing of block comments must take care of embedded block
comments that may occur within, as well as strings, so no substring
"*/" may inadvertantly close the block. This is the purpose of the
first case of the scanner [scan_block].
"*)" may inadvertently close the block. This is the purpose
of the first case of the scanner [scan_block].
*)
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 thread = push_string lexeme thread 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 = {thread with opening}
in scan_block thread state lexbuf }
| "*/" { let _, lexeme, state = sync state lexbuf
| "*)" { let _, lexeme, state = sync state lexbuf
in push_string lexeme thread, state }
| nl as nl { let () = Lexing.new_line lexbuf
and state = {state with pos = state.pos#new_line nl}

View File

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

View File

@ -7,6 +7,8 @@ open AST
(* END HEADER *)
%}
(* See [ParToken.mly] for the definition of tokens. *)
(* Entry points *)
%start program
@ -86,21 +88,24 @@ sepseq(X,Sep):
program:
seq(type_decl)
seq(const_decl)
parameter_decl
storage_decl
operations_decl
seq(lambda_decl)
block
EOF {
object
method types = $1
method parameter = $2
method storage = $3
method operations = $4
method lambdas = $5
method block = $6
method eof = $7
end
EOF
{
object
method types = $1
method constants = $2
method parameter = $3
method storage = $4
method operations = $5
method lambdas = $6
method block = $7
method eof = $8
end
}
parameter_decl:
@ -173,14 +178,15 @@ variant:
record_type:
Record
nsepseq(field_decl,SEMI)
End {
let region = cover $1 $3
in {region; value = $1,$2,$3}
End
{
let region = cover $1 $3
in {region; value = $1,$2,$3}
}
field_decl:
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
in {region; value = $1,$2,$3}
}
@ -193,101 +199,105 @@ lambda_decl:
fun_decl:
Function fun_name parameters COLON type_expr Is
seq(local_decl)
block
With expr {
let region = cover $1 (expr_to_region $9) in
let value =
object
method kwd_function = $1
method var = $2
method param = $3
method colon = $4
method ret_type = $5
method kwd_is = $6
method body = $7
method kwd_with = $8
method return = $9
end
in {region; value}
With expr
{
let region = cover $1 (expr_to_region $10) in
let value =
object
method kwd_function = $1
method name = $2
method param = $3
method colon = $4
method ret_type = $5
method kwd_is = $6
method local_decls = $7
method block = $8
method kwd_with = $9
method return = $10
end
in {region; value}
}
proc_decl:
Procedure fun_name parameters Is
block {
let region = cover $1 $5.region in
let value =
object
method kwd_procedure = $1
method var = $2
method param = $3
method kwd_is = $4
method body = $5
end
in {region; value}
seq(local_decl)
block
{
let region = cover $1 $6.region in
let value =
object
method kwd_procedure = $1
method name = $2
method param = $3
method kwd_is = $4
method local_decls = $5
method block = $6
end
in {region; value}
}
parameters:
par(nsepseq(param_decl,SEMI)) { $1 }
param_decl:
var_kind var COLON type_expr {
let start = var_kind_to_region $1 in
Var var COLON type_expr {
let stop = type_expr_to_region $4 in
let region = cover start stop
in {region; value = $1,$2,$3,$4}
let region = cover $1 stop
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:
value_decls
Begin
instructions
End {
let region = cover $1.region $4 in
let value =
object
method decls = $1
method opening = $2
method instr = $3
method close = $4
end
in {region; value}
End
{
let region = cover $1 $3 in
let value =
object
method opening = $1
method instr = $2
method close = $3
end
in {region; value}
}
value_decls:
sepseq(var_decl,SEMI) {
let region = sepseq_to_region (fun x -> x.region) $1
in {region; value=$1}
local_decl:
lambda_decl { LocalLam $1 }
| const_decl { LocalConst $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 var COLON type_expr ASGNMNT expr {
let region = cover $1 (expr_to_region $6) in
let value =
object
method kind = Mutable $1
method var = $2
method colon = $3
method vtype = $4
method setter = $5
method init = $6
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
let value = object
method kwd_var = $1
method name = $2
method colon = $3
method vtype = $4
method asgnmnt = $5
method init = $6
end
in {region; value}
}
@ -308,6 +318,10 @@ single_instr:
| loop { Loop $1 }
| proc_call { ProcCall $1 }
| Null { Null $1 }
| Fail expr {
let region = cover $1 (expr_to_region $2)
in Fail {region; value = $1,$2}
}
proc_call:
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 w is K of v * u
parameter p : v
parameter p : v # Line comment
storage w
operations u
function f (const x : int) : int is
var y : int := 5 - x;
const z : int = 6
begin
y := x + y
end with y * 2
(* Block comment *)
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
match l with
[] -> null
@ -23,5 +24,6 @@ procedure g (const l : list (int)) is
end
begin
g (Unit)
g (Unit) (*;
fail K (3, "foo")*)
end

View File

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

View File

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