Add local 'let in' bindings

This commit is contained in:
Louis Gesbert 2022-07-26 13:40:43 +02:00
parent 1d9af3cc02
commit f35f18b295
15 changed files with 217 additions and 158 deletions

View File

@ -421,6 +421,7 @@ and expression =
| MemCollection of expression Marked.pos * expression Marked.pos
| TestMatchCase of expression Marked.pos * match_case_pattern Marked.pos
| FunCall of expression Marked.pos * expression Marked.pos
| LetIn of ident Marked.pos * expression Marked.pos * expression Marked.pos
| Builtin of builtin_expression
| Literal of literal
| EnumInject of

View File

@ -117,7 +117,7 @@ let disambiguate_constructor
(** Usage: [translate_expr scope ctxt expr]
Translates [expr] into its desugared equivalent. [scope] is used to
disambiguate the scope and subscopes variables than occur in the expresion *)
disambiguate the scope and subscopes variables than occur in the expression *)
let rec translate_expr
(scope : Scopelang.Ast.ScopeName.t)
(inside_definition_of : Desugared.Ast.ScopeDef.t Marked.pos option)
@ -367,6 +367,17 @@ let rec translate_expr
Bindlib.box_apply2
(fun f arg -> Desugared.Ast.EApp (f, [arg]), pos)
(rec_helper f) (rec_helper arg)
| LetIn (x, e1, e2) ->
let ctxt, v = Name_resolution.add_def_local_var ctxt (Marked.unmark x) in
let tau = Scopelang.Ast.TAny, Marked.get_mark x in
let fn =
Desugared.Ast.make_abs [| v |]
(translate_expr scope inside_definition_of ctxt e2)
[tau] pos
in
Bindlib.box_apply2
(fun fn arg -> Desugared.Ast.(EApp (fn, [arg]), pos))
fn (rec_helper e1)
| StructLit (s_name, fields) ->
let s_uid =
try Desugared.Ast.IdentMap.find (Marked.unmark s_name) ctxt.struct_idmap

View File

@ -164,6 +164,9 @@ module R = Re.Pcre
#ifndef MR_RULE
#define MR_RULE MS_RULE
#endif
#ifndef MR_LET
#define MR_LET MS_LET
#endif
#ifndef MR_EXISTS
#define MR_EXISTS MS_EXISTS
#endif
@ -308,6 +311,7 @@ let token_list : (string * token) list =
(MS_FIXED, FIXED);
(MS_BY, BY);
(MS_RULE, RULE);
(MS_LET, LET);
(MS_EXISTS, EXISTS);
(MS_IN, IN);
(MS_SUCH, SUCH);
@ -522,6 +526,9 @@ let rec lex_code (lexbuf : lexbuf) : token =
| MR_RULE ->
L.update_acc lexbuf;
RULE
| MR_LET ->
L.update_acc lexbuf;
LET
| MR_EXISTS ->
L.update_acc lexbuf;
EXISTS

View File

@ -67,6 +67,7 @@
#define MS_FIXED "fixed"
#define MS_BY "by"
#define MS_RULE "rule"
#define MS_LET "let"
#define MS_EXISTS "exists"
#define MS_IN "in"
#define MS_SUCH "such"

View File

@ -86,6 +86,7 @@
#define MS_BY "par"
#define MS_RULE "règle"
#define MR_RULE "r", 0xE8, "gle"
#define MS_LET "soit"
#define MS_EXISTS "existe"
#define MS_IN "dans"
#define MS_SUCH "tel"

View File

@ -71,7 +71,9 @@
#define MS_FIXED "staloprzecinkowa"
#define MS_BY "przez"
#define MS_RULE "zasada"
#define MS_LET "niech"
#define MS_EXISTS "istnieje"
(* "in" or "w" ? *)
#define MS_IN "in"
#define MS_SUCH "takie ze"
#define MR_SUCH "takie", space_plus, "ze"

File diff suppressed because it is too large Load Diff

View File

@ -352,6 +352,9 @@ let (pos, i,e1) = i_in_e1 in
| IF e1 = expression THEN e2 = expression ELSE e3 = expression {
(IfThenElse (e1, e2, e3), Pos.from_lpos $sloc)
}
| LET id = ident DEFINED_AS e1 = expression IN e2 = expression {
(LetIn (id, e1, e2), Pos.from_lpos $sloc)
}
| e = logical_expression { e }
condition:

View File

@ -45,7 +45,7 @@
%token LESSER_MONEY GREATER_MONEY LESSER_EQUAL_MONEY GREATER_EQUAL_MONEY
%token LESSER_DATE GREATER_DATE LESSER_EQUAL_DATE GREATER_EQUAL_DATE
%token LESSER_DURATION GREATER_DURATION LESSER_EQUAL_DURATION GREATER_EQUAL_DURATION
%token EXISTS IN SUCH THAT
%token LET EXISTS IN SUCH THAT
%token DOT AND OR XOR LPAREN RPAREN EQUAL
%token CARDINAL ASSERTION FIXED BY YEAR MONTH DAY
%token PLUS MINUS MULT DIV

View File

@ -23,7 +23,7 @@
'("#")
'("contexte" "entrée" "sortie" "interne"
"champ d'application" "si et seulement si" "dépend de" "déclaration" "inclus" "collection" "contenu" "optionnel" "structure" "énumération" "contexte" "entrée" "sortie" "interne" "règle" "sous condition" "condition" "donnée" "conséquence" "rempli" "égal à" "assertion" "définition" "état" "étiquette" "exception")
'(("\\<\\(selon\\|sous\s+forme\\|fixé\\|par\\|décroissante\\|croissante\\|varie\\|avec\\|on\s+a\\|dans\\|tel\s+que\\|existe\\|pour\\|tout\\|de\\|si\\|alors\\|sinon\\|initial\\)\\>" . font-lock-builtin-face)
'(("\\<\\(selon\\|sous\s+forme\\|fixé\\|par\\|décroissante\\|croissante\\|varie\\|avec\\|on\s+a\\|soit\\|dans\\|tel\s+que\\|existe\\|pour\\|tout\\|de\\|si\\|alors\\|sinon\\|initial\\)\\>" . font-lock-builtin-face)
("\\<\\(vrai\\|faux\\)\\>" . font-lock-constant-face)
("\\<\\([0-9][0-9 ]*\\(,[0-9]*\\|\\)\\)\\>" . font-lock-constant-face)
("\\(->\\|+.\\|+@\\|+^\\|+€\\|+\\|-.\\|-@\\|-^\\|-€\\|-\\|*.\\|*@\\|*^\\|*€\\|*\\|/.\\|/@\\|/^\\|/€\\|/\\|!\\|>.\\|>=.\\|<=.\\|<.\\|>@\\|>=@\\|<=@\\|<@\\|>€\\|>=€\\|<=€\\|<€\\|>^\\|>=^\\|<=^\\|<^\\|>\\|>=\\|<=\\|<\\|=\\)" . font-lock-keyword-face)
@ -42,7 +42,7 @@
'("#")
'("context" "input" "output" "internal"
"scope" "depends on" "declaration" "includes" "collection" "content" "optional" "structure" "enumeration" "context" "input" "output" "internal" "rule" "under condition" "condition" "data" "consequence" "fulfilled" "equals" "assertion" "definition" "state" "label" "exception")
'(("\\<\\(match\\|with\s+pattern\\|fixed\\|by\\|decreasing\\|increasing\\|varies\\|with\\|we\s+have\\|in\\|such\s+that\\|exists\\|for\\|all\\|of\\|if\\|then\\|else\\|initial\\)\\>" . font-lock-builtin-face)
'(("\\<\\(match\\|with\s+pattern\\|fixed\\|by\\|decreasing\\|increasing\\|varies\\|with\\|we\s+have\\|let\\|in\\|such\s+that\\|exists\\|for\\|all\\|of\\|if\\|then\\|else\\|initial\\)\\>" . font-lock-builtin-face)
("|[0-9]\\+-[0-9]\\+-[0-9]\\+|" . font-lock-constant-face)
("\\<\\(true\\|false\\)\\>" . font-lock-constant-face)
("\\<\\([0-9][0-9,]*\\(\\.[0-9]*\\|\\)\\)\\>" . font-lock-constant-face)

View File

@ -198,7 +198,7 @@ code : context {
}
: pattern {
regex \= \b(match|with\s+pattern|fixed|by|decreasing|increasing|varies|with|we\s+have|in|such\s+that|exists|for|all|of|if|then|else|initial)\b
regex \= \b(match|with\s+pattern|fixed|by|decreasing|increasing|varies|with|we\s+have|let|in|such\s+that|exists|for|all|of|if|then|else|initial)\b
styles [] = .keyword_expression ;
}

View File

@ -198,7 +198,7 @@ code : context {
}
: pattern {
regex \= \b(selon|sous\s+forme|fixé|par|décroissante|croissante|varie|avec|on\s+a|dans|tel\s+que|existe|pour|tout|de|si|alors|sinon|initial)\b
regex \= \b(selon|sous\s+forme|fixé|par|décroissante|croissante|varie|avec|on\s+a|soit|dans|tel\s+que|existe|pour|tout|de|si|alors|sinon|initial)\b
styles [] = .keyword_expression ;
}

View File

@ -198,7 +198,7 @@ code : context {
}
: pattern {
regex \= \b(pasuje|ze\s+wzorem|staloprzecinkowa|przez|malejacy|rosnacy|rozna|wraz z|mamy|w|takich ze|istnieje|dla|wszystkie|z|jezeli|wtedy|inaczej|poczatkowy)\b
regex \= \b(pasuje|ze\s+wzorem|staloprzecinkowa|przez|malejacy|rosnacy|rozna|wraz z|mamy|niech|in|takich ze|istnieje|dla|wszystkie|z|jezeli|wtedy|inaczej|poczatkowy)\b
styles [] = .keyword_expression ;
}

View File

@ -0,0 +1,30 @@
## Article
```catala
declaration scope S:
context output a content A
context output b content B
declaration structure A:
data x content decimal
data y content B
declaration structure B:
data y content boolean
data z content decimal
scope S:
definition b equals let b equals 42 in B { -- y: true -- z: integer_to_decimal of b}
definition a equals
let b equals
if b.B.y
then B { -- y: false -- z: -1. }
else B { -- y: true -- z: -2. }
in
let a equals 2. *. b.z in
A { -- x: a -- y : b }
```
```catala-test {id="S.Interpret"}
catala Interpret -s S
```

View File

@ -0,0 +1,3 @@
[RESULT] Computation successful! Results:
[RESULT] a = A {"x"= -2.; "y"= B {"y"= false; "z"= -1.}}
[RESULT] b = B {"y"= true; "z"= 42.}