WIP:adding rec keyword
This commit is contained in:
parent
1597d1eaf4
commit
b438f065b5
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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):
|
||||||
|
@ -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";
|
||||||
|
@ -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;
|
||||||
|
@ -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" *)
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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} }
|
||||||
|
@ -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 ":";
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user