mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-08 07:51:43 +03:00
Toplevel defs: tests & fixes
This commit is contained in:
parent
9b0c7583ec
commit
d66cd1e29c
@ -989,6 +989,8 @@ let translate_scope_decl
|
||||
(input_destructurings rules_with_return_expr)),
|
||||
new_struct_ctx )
|
||||
|
||||
(* TODO: rename "scope" here to avoid confusion, since it now includes toplevel
|
||||
defs and scopes *)
|
||||
let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
|
||||
let scope_dependencies = Scopelang.Dependency.build_program_dep_graph prgm in
|
||||
Scopelang.Dependency.check_for_cycle_in_scope scope_dependencies;
|
||||
|
@ -314,7 +314,7 @@ and evaluate_expr (ctx : decl_ctx) (e : 'm Ast.expr) : 'm Ast.expr =
|
||||
| EVar _ ->
|
||||
Errors.raise_spanned_error (Expr.pos e)
|
||||
"free variable found at evaluation (should not happen if term was \
|
||||
well-typed"
|
||||
well-typed)"
|
||||
| EApp { f = e1; args } -> (
|
||||
let e1 = evaluate_expr ctx e1 in
|
||||
let args = List.map (evaluate_expr ctx) args in
|
||||
|
@ -58,6 +58,16 @@ let scope ctx env scope =
|
||||
{ scope with scope_defs; scope_assertions }
|
||||
|
||||
let program prg =
|
||||
let env =
|
||||
TopdefName.Map.fold
|
||||
(fun name (_e, ty) env -> Typing.Env.add_global_var name ty env)
|
||||
prg.program_globals Typing.Env.empty
|
||||
in
|
||||
let program_globals =
|
||||
TopdefName.Map.map
|
||||
(fun (e, ty) -> Expr.unbox (expr prg.program_ctx env (Expr.box e)), ty)
|
||||
prg.program_globals
|
||||
in
|
||||
let env =
|
||||
ScopeName.Map.fold
|
||||
(fun scope_name scope env ->
|
||||
@ -70,9 +80,9 @@ let program prg =
|
||||
scope.scope_defs ScopeVar.Map.empty
|
||||
in
|
||||
Typing.Env.add_scope scope_name ~vars env)
|
||||
prg.program_scopes Typing.Env.empty
|
||||
prg.program_scopes env
|
||||
in
|
||||
let program_scopes =
|
||||
ScopeName.Map.map (scope prg.program_ctx env) prg.program_scopes
|
||||
in
|
||||
{ prg with program_scopes }
|
||||
{ prg with program_globals; program_scopes }
|
||||
|
@ -98,6 +98,24 @@ let scope ?(debug = false) ctx fmt (name, decl) =
|
||||
SubScopeName.format_t subscope_name Print.punctuation "]"))
|
||||
decl.scope_decl_rules
|
||||
|
||||
let print_topdef ctx ppf name (e, ty) =
|
||||
Format.pp_open_vbox ppf 2;
|
||||
let () =
|
||||
Format.pp_open_hovbox ppf 2;
|
||||
Print.keyword ppf "let";
|
||||
Format.pp_print_space ppf ();
|
||||
TopdefName.format_t ppf name;
|
||||
Print.punctuation ppf ":";
|
||||
Format.pp_print_space ppf ();
|
||||
Print.typ ctx ppf ty;
|
||||
Format.pp_print_space ppf ();
|
||||
Print.punctuation ppf "=";
|
||||
Format.pp_close_box ppf ()
|
||||
in
|
||||
Format.pp_print_cut ppf ();
|
||||
Print.expr ctx ppf e;
|
||||
Format.pp_close_box ppf ()
|
||||
|
||||
let program ?(debug : bool = false) (fmt : Format.formatter) (p : 'm program) :
|
||||
unit =
|
||||
let ctx = p.program_ctx in
|
||||
@ -116,6 +134,11 @@ let program ?(debug : bool = false) (fmt : Format.formatter) (p : 'm program) :
|
||||
enum ctx fmt n e;
|
||||
pp_sep fmt ())
|
||||
ctx.ctx_enums;
|
||||
TopdefName.Map.iter
|
||||
(fun name def ->
|
||||
print_topdef ctx fmt name def;
|
||||
pp_sep fmt ())
|
||||
p.program_globals;
|
||||
Format.pp_print_list ~pp_sep (scope ~debug ctx) fmt
|
||||
(ScopeName.Map.bindings p.program_scopes);
|
||||
Format.pp_close_box fmt ()
|
||||
|
@ -211,7 +211,7 @@ let rec unfold
|
||||
typ, expr, pos, is_main
|
||||
| Topdef (name, typ, expr) ->
|
||||
let pos = Marked.get_mark (TopdefName.get_info name) in
|
||||
typ, Expr.box expr, pos, false
|
||||
typ, Expr.rebox expr, pos, false
|
||||
in
|
||||
let main_scope = if is_main then ScopeVar var else main_scope in
|
||||
let next = unfold ctx next mark main_scope in
|
||||
|
@ -259,6 +259,7 @@ source_file: BEGIN_CODE DECLARATION YEAR
|
||||
## code_item -> DECLARATION . ENUM UIDENT COLON list(addpos(enum_decl_line)) [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION . lident CONTENT typ DEPENDS separated_nonempty_list(COMMA,var_content) DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION . lident CONTENT typ DEPENDS LPAREN separated_nonempty_list(COMMA,var_content) RPAREN DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION . lident CONTENT typ DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## DECLARATION
|
||||
@ -973,7 +974,7 @@ expected the name of the scope being used
|
||||
|
||||
source_file: BEGIN_CODE YEAR
|
||||
##
|
||||
## Ends in an error in state: 368.
|
||||
## Ends in an error in state: 370.
|
||||
##
|
||||
## source_file_item -> BEGIN_CODE . code END_CODE [ LAW_TEXT LAW_HEADING EOF BEGIN_METADATA BEGIN_DIRECTIVE BEGIN_CODE ]
|
||||
##
|
||||
@ -1034,8 +1035,8 @@ source_file: BEGIN_METADATA LAW_TEXT LAW_HEADING
|
||||
## accurate view of the past (what has been recognized so far), they
|
||||
## may provide an INCOMPLETE view of the future (what was expected next).
|
||||
## In state 1, spurious reduction of production nonempty_list(LAW_TEXT) -> LAW_TEXT
|
||||
## In state 357, spurious reduction of production law_text -> nonempty_list(LAW_TEXT)
|
||||
## In state 358, spurious reduction of production option(law_text) -> law_text
|
||||
## In state 359, spurious reduction of production law_text -> nonempty_list(LAW_TEXT)
|
||||
## In state 360, spurious reduction of production option(law_text) -> law_text
|
||||
##
|
||||
|
||||
expected some law text or code block
|
||||
@ -3902,6 +3903,7 @@ source_file: BEGIN_CODE DECLARATION LIDENT YEAR
|
||||
##
|
||||
## code_item -> DECLARATION lident . CONTENT typ DEPENDS separated_nonempty_list(COMMA,var_content) DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION lident . CONTENT typ DEPENDS LPAREN separated_nonempty_list(COMMA,var_content) RPAREN DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION lident . CONTENT typ DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## DECLARATION lident
|
||||
@ -3915,6 +3917,7 @@ source_file: BEGIN_CODE DECLARATION LIDENT CONTENT YEAR
|
||||
##
|
||||
## code_item -> DECLARATION lident CONTENT . typ DEPENDS separated_nonempty_list(COMMA,var_content) DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION lident CONTENT . typ DEPENDS LPAREN separated_nonempty_list(COMMA,var_content) RPAREN DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION lident CONTENT . typ DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## DECLARATION lident CONTENT
|
||||
@ -3928,6 +3931,7 @@ source_file: BEGIN_CODE DECLARATION LIDENT CONTENT BOOLEAN YEAR
|
||||
##
|
||||
## code_item -> DECLARATION lident CONTENT typ . DEPENDS separated_nonempty_list(COMMA,var_content) DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION lident CONTENT typ . DEPENDS LPAREN separated_nonempty_list(COMMA,var_content) RPAREN DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
## code_item -> DECLARATION lident CONTENT typ . DEFINED_AS expression [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## DECLARATION lident CONTENT typ
|
||||
@ -4157,7 +4161,7 @@ expected a binary operator continuing the expression, or a keyword ending the ex
|
||||
|
||||
source_file: BEGIN_DIRECTIVE YEAR
|
||||
##
|
||||
## Ends in an error in state: 359.
|
||||
## Ends in an error in state: 361.
|
||||
##
|
||||
## source_file_item -> BEGIN_DIRECTIVE . LAW_INCLUDE COLON nonempty_list(DIRECTIVE_ARG) option(AT_PAGE) END_DIRECTIVE [ LAW_TEXT LAW_HEADING EOF BEGIN_METADATA BEGIN_DIRECTIVE BEGIN_CODE ]
|
||||
##
|
||||
@ -4169,7 +4173,7 @@ expected a directive, e.g. 'Include: <filename>'
|
||||
|
||||
source_file: BEGIN_DIRECTIVE LAW_INCLUDE YEAR
|
||||
##
|
||||
## Ends in an error in state: 360.
|
||||
## Ends in an error in state: 362.
|
||||
##
|
||||
## source_file_item -> BEGIN_DIRECTIVE LAW_INCLUDE . COLON nonempty_list(DIRECTIVE_ARG) option(AT_PAGE) END_DIRECTIVE [ LAW_TEXT LAW_HEADING EOF BEGIN_METADATA BEGIN_DIRECTIVE BEGIN_CODE ]
|
||||
##
|
||||
@ -4181,7 +4185,7 @@ expected ':', then a file name or 'JORFTEXTNNNNNNNNNNNN'
|
||||
|
||||
source_file: BEGIN_DIRECTIVE LAW_INCLUDE COLON YEAR
|
||||
##
|
||||
## Ends in an error in state: 361.
|
||||
## Ends in an error in state: 363.
|
||||
##
|
||||
## source_file_item -> BEGIN_DIRECTIVE LAW_INCLUDE COLON . nonempty_list(DIRECTIVE_ARG) option(AT_PAGE) END_DIRECTIVE [ LAW_TEXT LAW_HEADING EOF BEGIN_METADATA BEGIN_DIRECTIVE BEGIN_CODE ]
|
||||
##
|
||||
@ -4193,7 +4197,7 @@ expected a file name or 'JORFTEXTNNNNNNNNNNNN'
|
||||
|
||||
source_file: BEGIN_DIRECTIVE LAW_INCLUDE COLON DIRECTIVE_ARG YEAR
|
||||
##
|
||||
## Ends in an error in state: 362.
|
||||
## Ends in an error in state: 364.
|
||||
##
|
||||
## nonempty_list(DIRECTIVE_ARG) -> DIRECTIVE_ARG . [ END_DIRECTIVE AT_PAGE ]
|
||||
## nonempty_list(DIRECTIVE_ARG) -> DIRECTIVE_ARG . nonempty_list(DIRECTIVE_ARG) [ END_DIRECTIVE AT_PAGE ]
|
||||
@ -4206,7 +4210,7 @@ expected a page specification in the form '@p.<number>', or a newline
|
||||
|
||||
source_file: BEGIN_DIRECTIVE LAW_INCLUDE COLON DIRECTIVE_ARG AT_PAGE YEAR
|
||||
##
|
||||
## Ends in an error in state: 366.
|
||||
## Ends in an error in state: 368.
|
||||
##
|
||||
## source_file_item -> BEGIN_DIRECTIVE LAW_INCLUDE COLON nonempty_list(DIRECTIVE_ARG) option(AT_PAGE) . END_DIRECTIVE [ LAW_TEXT LAW_HEADING EOF BEGIN_METADATA BEGIN_DIRECTIVE BEGIN_CODE ]
|
||||
##
|
||||
@ -4218,7 +4222,7 @@ expected a newline
|
||||
|
||||
source_file: LAW_HEADING YEAR
|
||||
##
|
||||
## Ends in an error in state: 371.
|
||||
## Ends in an error in state: 373.
|
||||
##
|
||||
## source_file -> source_file_item . source_file [ # ]
|
||||
##
|
||||
|
@ -604,6 +604,7 @@ let var_content ==
|
||||
let depends_stance ==
|
||||
| DEPENDS ; args = separated_nonempty_list(COMMA,var_content) ; <>
|
||||
| DEPENDS ; LPAREN ; args = separated_nonempty_list(COMMA,var_content) ; RPAREN ; <>
|
||||
| { [] }
|
||||
|
||||
let code_item :=
|
||||
| SCOPE ; c = uident ;
|
||||
|
24
tests/test_name_resolution/bad/toplevel_defs.catala_en
Normal file
24
tests/test_name_resolution/bad/toplevel_defs.catala_en
Normal file
@ -0,0 +1,24 @@
|
||||
## Scope calls are not allowed outside of scopes
|
||||
|
||||
```catala
|
||||
declaration scope S1:
|
||||
output a content decimal
|
||||
|
||||
scope S1:
|
||||
definition a equals 44.2
|
||||
|
||||
declaration glob5 content decimal
|
||||
equals (output of S1).a
|
||||
```
|
||||
|
||||
```catala-test-inline
|
||||
$ catala typecheck
|
||||
[ERROR] Scope calls are not allowed outside of a scope
|
||||
|
||||
┌─⯈ tests/test_name_resolution/bad/toplevel_defs.catala_en:11.10-22:
|
||||
└──┐
|
||||
11 │ equals (output of S1).a
|
||||
│ ‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
└─ Scope calls are not allowed outside of scopes
|
||||
#return code 255#
|
||||
```
|
74
tests/test_name_resolution/good/toplevel_defs.catala_en
Normal file
74
tests/test_name_resolution/good/toplevel_defs.catala_en
Normal file
@ -0,0 +1,74 @@
|
||||
## Test basic toplevel values defs
|
||||
|
||||
```catala
|
||||
declaration glob1 content decimal equals 44.12
|
||||
|
||||
declaration scope S:
|
||||
output a content decimal
|
||||
output b content A
|
||||
|
||||
declaration structure A:
|
||||
data y content boolean
|
||||
data z content decimal
|
||||
|
||||
declaration glob2 content A equals
|
||||
A { --y: glob1 >= 30. --z: 123. * 17. }
|
||||
|
||||
scope S:
|
||||
definition a equals glob1 * glob1
|
||||
definition b equals glob2
|
||||
```
|
||||
|
||||
```catala-test-inline
|
||||
$ catala Interpret -s S
|
||||
[RESULT] Computation successful! Results:
|
||||
[RESULT] a = 1946.5744
|
||||
[RESULT] b = A { "y"= true; "z"= 2091. }
|
||||
```
|
||||
|
||||
## Test toplevel function defs
|
||||
|
||||
```catala
|
||||
declaration glob3 content decimal
|
||||
depends on x content money
|
||||
equals decimal of x + 10.
|
||||
|
||||
declaration scope S2:
|
||||
output a content decimal
|
||||
|
||||
scope S2:
|
||||
definition a equals glob3 of $44 + 100.
|
||||
```
|
||||
|
||||
```catala-test-inline
|
||||
$ catala Interpret -s S2
|
||||
[RESULT] Computation successful! Results:
|
||||
[RESULT] a = 154.
|
||||
```
|
||||
|
||||
## Test function def with two args
|
||||
|
||||
```catala
|
||||
declaration glob4 content decimal
|
||||
depends on x content money, y content decimal
|
||||
equals decimal of x * y + 10.
|
||||
|
||||
declaration scope S3:
|
||||
output a content decimal
|
||||
|
||||
#scope S3:
|
||||
# definition a equals 50 + glob3 of ($44, 55.)
|
||||
# TODO: no syntax yet
|
||||
```
|
||||
|
||||
```catala-test-inline
|
||||
$ catala Interpret -s S3
|
||||
[ERROR] This variable evaluated to an empty term (no rule that defined it applied in this situation)
|
||||
|
||||
┌─⯈ tests/test_name_resolution/good/toplevel_defs.catala_en:57.9-10:
|
||||
└──┐
|
||||
57 │ output a content decimal
|
||||
│ ‾
|
||||
└─ Test function def with two args
|
||||
#return code 255#
|
||||
```
|
Loading…
Reference in New Issue
Block a user