WIP:adding rec keyword

This commit is contained in:
Pierre-Emmanuel Wulfman 2020-02-20 22:31:47 +01:00
parent 1597d1eaf4
commit b438f065b5
19 changed files with 76 additions and 48 deletions

View File

@ -30,6 +30,7 @@ type kwd_else = Region.t
type kwd_end = Region.t type kwd_end = Region.t
type kwd_false = Region.t type kwd_false = Region.t
type kwd_fun = Region.t type kwd_fun = Region.t
type kwd_rec = Region.t
type kwd_if = Region.t type kwd_if = Region.t
type kwd_in = Region.t type kwd_in = Region.t
type kwd_let = Region.t type kwd_let = Region.t
@ -362,6 +363,7 @@ and 'a case_clause = {
and let_in = { and let_in = {
kwd_let : kwd_let; kwd_let : kwd_let;
kwd_rec : kwd_rec option;
binding : let_binding; binding : let_binding;
kwd_in : kwd_in; kwd_in : kwd_in;
body : expr; body : expr;

View File

@ -95,6 +95,7 @@ type t =
| End of Region.t | End of Region.t
| False of Region.t | False of Region.t
| Fun of Region.t | Fun of Region.t
| Rec of Region.t
| If of Region.t | If of Region.t
| In of Region.t | In of Region.t
| Let of Region.t | Let of Region.t

View File

@ -79,6 +79,7 @@ type t =
| End of Region.t | End of Region.t
| False of Region.t | False of Region.t
| Fun of Region.t | Fun of Region.t
| Rec of Region.t
| If of Region.t | If of Region.t
| In of Region.t | In of Region.t
| Let of Region.t | Let of Region.t
@ -154,6 +155,7 @@ let proj_token = function
| End region -> region, "End" | End region -> region, "End"
| False region -> region, "False" | False region -> region, "False"
| Fun region -> region, "Fun" | Fun region -> region, "Fun"
| Rec region -> region, "Rec"
| If region -> region, "If" | If region -> region, "If"
| In region -> region, "In" | In region -> region, "In"
| Let region -> region, "Let" | Let region -> region, "Let"
@ -213,6 +215,7 @@ let to_lexeme = function
| End _ -> "end" | End _ -> "end"
| False _ -> "false" | False _ -> "false"
| Fun _ -> "fun" | Fun _ -> "fun"
| Rec _ -> "rec"
| If _ -> "if" | If _ -> "if"
| In _ -> "in" | In _ -> "in"
| Let _ -> "let" | Let _ -> "let"

View File

@ -59,6 +59,7 @@
%token <Region.t> End "end" %token <Region.t> End "end"
%token <Region.t> False "false" %token <Region.t> False "false"
%token <Region.t> Fun "fun" %token <Region.t> Fun "fun"
%token <Region.t> Rec "rec"
%token <Region.t> If "if" %token <Region.t> If "if"
%token <Region.t> In "in" %token <Region.t> In "in"
%token <Region.t> Let "let" %token <Region.t> Let "let"

View File

@ -453,15 +453,16 @@ case_clause(right_expr):
{pattern=$1; arrow=$2; rhs=$3} } {pattern=$1; arrow=$2; rhs=$3} }
let_expr(right_expr): let_expr(right_expr):
"let" let_binding seq(Attr) "in" right_expr { "let" ioption("rec") let_binding seq(Attr) "in" right_expr {
let kwd_let = $1 let kwd_let = $1
and binding = $2 and kwd_rec = $2
and attributes = $3 and binding = $3
and kwd_in = $4 and attributes = $4
and body = $5 in and kwd_in = $5
and body = $6 in
let stop = expr_to_region body in let stop = expr_to_region body in
let region = cover kwd_let stop let region = cover kwd_let stop
and value = {kwd_let; binding; kwd_in; body; attributes} and value = {kwd_let; kwd_rec; binding; kwd_in; body; attributes}
in ELetIn {region; value} } in ELetIn {region; value} }
fun_expr(right_expr): fun_expr(right_expr):

View File

@ -544,8 +544,9 @@ and print_case_clause state {value; _} =
print_expr state rhs print_expr state rhs
and print_let_in state {value; _} = and print_let_in state {value; _} =
let {kwd_let; binding; kwd_in; body; attributes} = value in let {kwd_let; kwd_rec; binding; kwd_in; body; attributes} = value in
print_token state kwd_let "let"; print_token state kwd_let "let";
print_token_opt state kwd_rec "rec";
print_let_binding state binding; print_let_binding state binding;
print_attributes state attributes; print_attributes state attributes;
print_token state kwd_in "in"; print_token state kwd_in "in";

View File

@ -37,6 +37,7 @@ type kwd_end = Region.t
type kwd_for = Region.t type kwd_for = Region.t
type kwd_from = Region.t type kwd_from = Region.t
type kwd_function = Region.t type kwd_function = Region.t
type kwd_recursive = 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
@ -201,6 +202,7 @@ and type_tuple = (type_expr, comma) nsepseq par reg
(* Function and procedure declarations *) (* Function and procedure declarations *)
and fun_expr = { and fun_expr = {
kwd_recursive: kwd_recursive option;
kwd_function : kwd_function; kwd_function : kwd_function;
param : parameters; param : parameters;
colon : colon; colon : colon;
@ -210,6 +212,7 @@ and fun_expr = {
} }
and fun_decl = { and fun_decl = {
kwd_recursive: kwd_recursive option;
kwd_function : kwd_function; kwd_function : kwd_function;
fun_name : variable; fun_name : variable;
param : parameters; param : parameters;

View File

@ -89,6 +89,7 @@ type t =
| For of Region.t (* "for" *) | For of Region.t (* "for" *)
| From of Region.t (* "from" *) | From of Region.t (* "from" *)
| Function of Region.t (* "function" *) | Function of Region.t (* "function" *)
| Recursive of Region.t (* "recursive" *)
| If of Region.t (* "if" *) | If of Region.t (* "if" *)
| In of Region.t (* "in" *) | In of Region.t (* "in" *)
| Is of Region.t (* "is" *) | Is of Region.t (* "is" *)

View File

@ -87,6 +87,7 @@ type t =
| For of Region.t (* "for" *) | For of Region.t (* "for" *)
| From of Region.t (* "from" *) | From of Region.t (* "from" *)
| Function of Region.t (* "function" *) | Function of Region.t (* "function" *)
| Recursive of Region.t (* "recursive" *)
| If of Region.t (* "if" *) | If of Region.t (* "if" *)
| In of Region.t (* "in" *) | In of Region.t (* "in" *)
| Is of Region.t (* "is" *) | Is of Region.t (* "is" *)
@ -199,6 +200,7 @@ let proj_token = function
| For region -> region, "For" | For region -> region, "For"
| From region -> region, "From" | From region -> region, "From"
| Function region -> region, "Function" | Function region -> region, "Function"
| Recursive region -> region, "Recursive"
| If region -> region, "If" | If region -> region, "If"
| In region -> region, "In" | In region -> region, "In"
| Is region -> region, "Is" | Is region -> region, "Is"
@ -289,6 +291,7 @@ let to_lexeme = function
| For _ -> "for" | For _ -> "for"
| From _ -> "from" | From _ -> "from"
| Function _ -> "function" | Function _ -> "function"
| Recursive _ -> "recursive"
| If _ -> "if" | If _ -> "if"
| In _ -> "in" | In _ -> "in"
| Is _ -> "is" | Is _ -> "is"

View File

@ -57,6 +57,7 @@
%token <Region.t> False "False" %token <Region.t> False "False"
%token <Region.t> For "for" %token <Region.t> For "for"
%token <Region.t> Function "function" %token <Region.t> Function "function"
%token <Region.t> Recursive "recursive"
%token <Region.t> From "from" %token <Region.t> From "from"
%token <Region.t> If "if" %token <Region.t> If "if"
%token <Region.t> In "in" %token <Region.t> In "in"

View File

@ -237,49 +237,52 @@ field_decl:
fun_expr: fun_expr:
"function" parameters ":" type_expr "is" expr { ioption ("recursive") "function" parameters ":" type_expr "is" expr {
let stop = expr_to_region $6 in let stop = expr_to_region $7 in
let region = cover $1 stop let region = cover $2 stop
and value = {kwd_function = $1; and value = {kwd_recursive= $1;
param = $2; kwd_function = $2;
colon = $3; param = $3;
ret_type = $4; colon = $4;
kwd_is = $5; ret_type = $5;
return = $6} kwd_is = $6;
return = $7}
in {region; value} } in {region; value} }
(* Function declarations *) (* Function declarations *)
open_fun_decl: open_fun_decl:
"function" fun_name parameters ":" type_expr "is" ioption("recursive") "function" fun_name parameters ":" type_expr "is"
block "with" expr { block "with" expr {
Scoping.check_reserved_name $2; Scoping.check_reserved_name $3;
let stop = expr_to_region $9 in let stop = expr_to_region $10 in
let region = cover $1 stop let region = cover $2 stop
and value = {kwd_function = $1; and value = {kwd_recursive= $1;
fun_name = $2; kwd_function = $2;
param = $3; fun_name = $3;
colon = $4; param = $4;
ret_type = $5; colon = $5;
kwd_is = $6; ret_type = $6;
block_with = Some ($7, $8); kwd_is = $7;
return = $9; block_with = Some ($8, $9);
return = $10;
terminator = None; terminator = None;
attributes = None} attributes = None}
in {region; value} in {region; value}
} }
| "function" fun_name parameters ":" type_expr "is" expr { | ioption ("recursive") "function" fun_name parameters ":" type_expr "is" expr {
Scoping.check_reserved_name $2; Scoping.check_reserved_name $3;
let stop = expr_to_region $7 in let stop = expr_to_region $8 in
let region = cover $1 stop let region = cover $2 stop
and value = {kwd_function = $1; and value = {kwd_recursive= $1;
fun_name = $2; kwd_function = $2;
param = $3; fun_name = $3;
colon = $4; param = $4;
ret_type = $5; colon = $5;
kwd_is = $6; ret_type = $6;
kwd_is = $7;
block_with = None; block_with = None;
return = $7; return = $8;
terminator = None; terminator = None;
attributes = None} attributes = None}
in {region; value} } in {region; value} }

View File

@ -218,8 +218,9 @@ and print_fun_decl state {value; _} =
print_terminator state terminator; print_terminator state terminator;
and print_fun_expr state {value; _} = and print_fun_expr state {value; _} =
let {kwd_function; param; colon; let {kwd_recursive; kwd_function; param; colon;
ret_type; kwd_is; return} : fun_expr = value in ret_type; kwd_is; return} : fun_expr = value in
print_token_opt state kwd_recursive "recursive";
print_token state kwd_function "function"; print_token state kwd_function "function";
print_parameters state param; print_parameters state param;
print_token state colon ":"; print_token state colon ":";

View File

@ -95,6 +95,7 @@ type t =
| False of Region.t | False of Region.t
| If of Region.t | If of Region.t
| Let of Region.t | Let of Region.t
| Rec of Region.t
| Switch of Region.t | Switch of Region.t
| Mod of Region.t | Mod of Region.t
| Or of Region.t | Or of Region.t

View File

@ -80,6 +80,7 @@ type t =
| False of Region.t | False of Region.t
| If of Region.t | If of Region.t
| Let of Region.t | Let of Region.t
| Rec of Region.t
| Switch of Region.t | Switch of Region.t
| Mod of Region.t | Mod of Region.t
| Or of Region.t | Or of Region.t
@ -146,6 +147,7 @@ let proj_token = function
| False region -> region, "False" | False region -> region, "False"
| If region -> region, "If" | If region -> region, "If"
| Let region -> region, "Let" | Let region -> region, "Let"
| Rec region -> region, "Rec"
| Switch region -> region, "Switch" | Switch region -> region, "Switch"
| Mod region -> region, "Mod" | Mod region -> region, "Mod"
| NOT region -> region, "!" | NOT region -> region, "!"
@ -197,6 +199,7 @@ let to_lexeme = function
| False _ -> "false" | False _ -> "false"
| If _ -> "if" | If _ -> "if"
| Let _ -> "let" | Let _ -> "let"
| Rec _ -> "rec"
| Mod _ -> "mod" | Mod _ -> "mod"
| NOT _ -> "!" | NOT _ -> "!"
| Or _ -> "or" | Or _ -> "or"

View File

@ -59,6 +59,7 @@
%token <Region.t> False "false" %token <Region.t> False "false"
%token <Region.t> If "if" %token <Region.t> If "if"
%token <Region.t> Let "let" %token <Region.t> Let "let"
%token <Region.t> Rec "rec"
%token <Region.t> Switch "switch" %token <Region.t> Switch "switch"
%token <Region.t> Mod "mod" %token <Region.t> Mod "mod"
%token <Region.t> Or "or" %token <Region.t> Or "or"

View File

@ -650,15 +650,16 @@ case_clause(right_expr):
in {region; value} } in {region; value} }
let_expr(right_expr): let_expr(right_expr):
seq(Attr) "let" let_binding ";" right_expr { seq(Attr) "let" ioption("rec") let_binding ";" right_expr {
let attributes = $1 in let attributes = $1 in
let kwd_let = $2 in let kwd_let = $2 in
let binding = $3 in let kwd_rec = $3 in
let kwd_in = $4 in let binding = $4 in
let body = $5 in let kwd_in = $5 in
let stop = expr_to_region $5 in let body = $6 in
let stop = expr_to_region $6 in
let region = cover $2 stop let region = cover $2 stop
and value = {kwd_let; binding; kwd_in; body; attributes} and value = {kwd_let; kwd_rec; binding; kwd_in; body; attributes}
in ELetIn {region; value} } in ELetIn {region; value} }
disj_expr_level: disj_expr_level:

View File

@ -630,6 +630,7 @@ and simpl_fun lamb' : expr result =
in in
let let_in: Raw.let_in = let let_in: Raw.let_in =
{kwd_let= Region.ghost; {kwd_let= Region.ghost;
kwd_rec= None;
binding= let_in_binding; binding= let_in_binding;
kwd_in= Region.ghost; kwd_in= Region.ghost;
body= lamb.body; body= lamb.body;

View File

@ -1,4 +1,4 @@
// Test while loops in PascaLIGO // Test while loops in PascaLIGO
function fibo (const n : int; const acc: int) : int is recursive function fibo (const n : int; const acc: int) : int is
if n<1 then acc else fibo(n-1,acc+n) if n<1 then acc else fibo(n-1,acc+n)

View File

@ -1,5 +1,5 @@
// Test while loops in PascaLIGO // Test while loops in PascaLIGO
let fibo (n : int) (acc: int) : int = let rec fibo (n : int) (acc: int) : int =
if (n < 1) then acc if (n < 1) then acc
else fibo (n-1) (acc+n) else fibo (n-1) (acc+n)