mirror of
https://github.com/CatalaLang/catala.git
synced 2024-09-19 16:28:12 +03:00
Cleanup a bit the generation of the HandleExceptions operator
this behaviour in part duplicates the work of `-O`, but it's lighter-weight, and it's often more convenient to debug code without `-O` (which still has impact on traces generation) ; and this removes one or two levels of obfuscation when you read the intermediate code.
This commit is contained in:
parent
3cbfa5f258
commit
35c862f906
@ -59,7 +59,6 @@ let rec translate_default
|
|||||||
(mark_default : 'm mark) : 'm A.expr boxed =
|
(mark_default : 'm mark) : 'm A.expr boxed =
|
||||||
(* Since the program is well typed, all exceptions have as type [option 't] *)
|
(* Since the program is well typed, all exceptions have as type [option 't] *)
|
||||||
let pos = Expr.mark_pos mark_default in
|
let pos = Expr.mark_pos mark_default in
|
||||||
let exceptions = List.map translate_expr exceptions in
|
|
||||||
let ty_option = Expr.maybe_ty mark_default in
|
let ty_option = Expr.maybe_ty mark_default in
|
||||||
let ty_array = TArray ty_option, pos in
|
let ty_array = TArray ty_option, pos in
|
||||||
let ty_alpha =
|
let ty_alpha =
|
||||||
@ -69,13 +68,28 @@ let rec translate_default
|
|||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
in
|
in
|
||||||
let mark_alpha = Expr.with_ty mark_default ty_alpha in
|
let mark_alpha = Expr.with_ty mark_default ty_alpha in
|
||||||
Expr.ematch ~name:Expr.option_enum
|
let if_just_then_cons =
|
||||||
~e:
|
let none =
|
||||||
(Expr.eappop
|
Expr.einj ~cons:Expr.none_constr ~name:Expr.option_enum
|
||||||
~op:(Op.HandleExceptions, Expr.pos cons)
|
~e:(Expr.elit LUnit (Expr.with_ty mark_default (TLit TUnit, pos)))
|
||||||
~tys:[ty_array]
|
mark_default
|
||||||
~args:[Expr.earray exceptions (Expr.with_ty mark_default ty_array)]
|
in
|
||||||
mark_default)
|
match just with
|
||||||
|
| ELit (LBool b), _ -> if b then translate_expr cons else none
|
||||||
|
| just ->
|
||||||
|
Expr.eifthenelse (translate_expr just) (translate_expr cons)
|
||||||
|
(Expr.einj
|
||||||
|
~e:(Expr.elit LUnit (Expr.with_ty mark_default (TLit TUnit, pos)))
|
||||||
|
~cons:Expr.none_constr ~name:Expr.option_enum mark_default)
|
||||||
|
mark_default
|
||||||
|
in
|
||||||
|
let match_some e =
|
||||||
|
match just with
|
||||||
|
| ELit (LBool false), _ ->
|
||||||
|
(* in this case we can just forward the option in the argument *)
|
||||||
|
e
|
||||||
|
| _ ->
|
||||||
|
Expr.ematch ~name:Expr.option_enum ~e
|
||||||
~cases:
|
~cases:
|
||||||
(EnumConstructor.Map.of_list
|
(EnumConstructor.Map.of_list
|
||||||
[
|
[
|
||||||
@ -87,17 +101,26 @@ let rec translate_default
|
|||||||
~e:(Expr.evar x mark_alpha) mark_default)
|
~e:(Expr.evar x mark_alpha) mark_default)
|
||||||
[ty_alpha] pos );
|
[ty_alpha] pos );
|
||||||
(* None -> if just then cons else None *)
|
(* None -> if just then cons else None *)
|
||||||
( Expr.none_constr,
|
Expr.none_constr, Expr.thunk_term if_just_then_cons;
|
||||||
Expr.thunk_term
|
|
||||||
(Expr.eifthenelse (translate_expr just) (translate_expr cons)
|
|
||||||
(Expr.einj
|
|
||||||
~e:
|
|
||||||
(Expr.elit LUnit
|
|
||||||
(Expr.with_ty mark_default (TLit TUnit, pos)))
|
|
||||||
~cons:Expr.none_constr ~name:Expr.option_enum mark_default)
|
|
||||||
mark_default) );
|
|
||||||
])
|
])
|
||||||
mark_default
|
mark_default
|
||||||
|
in
|
||||||
|
match exceptions with
|
||||||
|
| [] -> if_just_then_cons
|
||||||
|
| [((EInj { cons; _ }, _) as e)] ->
|
||||||
|
if EnumConstructor.equal cons Expr.none_constr then
|
||||||
|
Expr.thunk_term if_just_then_cons
|
||||||
|
else if EnumConstructor.equal cons Expr.some_constr then translate_expr e
|
||||||
|
else assert false
|
||||||
|
| [single_exception] -> match_some (translate_expr single_exception)
|
||||||
|
| exceptions ->
|
||||||
|
let exceptions = List.map translate_expr exceptions in
|
||||||
|
match_some
|
||||||
|
(Expr.eappop
|
||||||
|
~op:(Op.HandleExceptions, Expr.pos cons)
|
||||||
|
~tys:[ty_array]
|
||||||
|
~args:[Expr.earray exceptions (Expr.with_ty mark_default ty_array)]
|
||||||
|
mark_default)
|
||||||
|
|
||||||
and translate_expr (e : 'm D.expr) : 'm A.expr boxed =
|
and translate_expr (e : 'm D.expr) : 'm A.expr boxed =
|
||||||
match e with
|
match e with
|
||||||
|
@ -22,15 +22,10 @@ typedef struct Foo {
|
|||||||
double y;
|
double y;
|
||||||
} Foo;
|
} Foo;
|
||||||
|
|
||||||
typedef struct Array_3 {
|
typedef struct Array_1 {
|
||||||
double * content2;
|
double * content;
|
||||||
int length2;
|
int length;
|
||||||
} Array_3;
|
} Array_1;
|
||||||
|
|
||||||
typedef struct Array_2 {
|
|
||||||
Option_2 * content1;
|
|
||||||
int length1;
|
|
||||||
} Array_2;
|
|
||||||
|
|
||||||
enum Bar_code {
|
enum Bar_code {
|
||||||
Bar_No,
|
Bar_No,
|
||||||
@ -47,7 +42,7 @@ typedef struct Bar {
|
|||||||
|
|
||||||
typedef struct Baz {
|
typedef struct Baz {
|
||||||
double b;
|
double b;
|
||||||
Array_3 c;
|
Array_1 c;
|
||||||
} Baz;
|
} Baz;
|
||||||
|
|
||||||
enum Option_3_code {
|
enum Option_3_code {
|
||||||
@ -59,7 +54,7 @@ typedef struct Option_3 {
|
|||||||
enum Option_3_code code;
|
enum Option_3_code code;
|
||||||
union {
|
union {
|
||||||
void* /* unit */ None_3;
|
void* /* unit */ None_3;
|
||||||
Array_3 Some_3;
|
Array_1 Some_3;
|
||||||
} payload;
|
} payload;
|
||||||
} Option_3;
|
} Option_3;
|
||||||
|
|
||||||
@ -76,16 +71,6 @@ typedef struct Option_1 {
|
|||||||
} payload;
|
} payload;
|
||||||
} Option_1;
|
} Option_1;
|
||||||
|
|
||||||
typedef struct Array_4 {
|
|
||||||
Option_3 * content3;
|
|
||||||
int length3;
|
|
||||||
} Array_4;
|
|
||||||
|
|
||||||
typedef struct Array_1 {
|
|
||||||
Option_1 * content;
|
|
||||||
int length;
|
|
||||||
} Array_1;
|
|
||||||
|
|
||||||
typedef struct Tuple_1 {
|
typedef struct Tuple_1 {
|
||||||
Option_1 (*elt_0)(void * /* closure_env */ arg_0_typ, void* /* unit */ arg_1_typ);
|
Option_1 (*elt_0)(void * /* closure_env */ arg_0_typ, void* /* unit */ arg_1_typ);
|
||||||
void * /* closure_env */ elt_1;
|
void * /* closure_env */ elt_1;
|
||||||
@ -107,55 +92,12 @@ Baz baz(Baz_in baz_in) {
|
|||||||
void * /* closure_env */ env;
|
void * /* closure_env */ env;
|
||||||
code = code_and_env.elt_0;
|
code = code_and_env.elt_0;
|
||||||
env = code_and_env.elt_1;
|
env = code_and_env.elt_1;
|
||||||
Array_1 a4;
|
Option_1 a3 = code(env, NULL);
|
||||||
a4.content_field = catala_malloc(sizeof(Array_1));
|
|
||||||
a4.content_field[0] = code(env, NULL);
|
|
||||||
Option_1 a3 = catala_handle_exceptions(a4);
|
|
||||||
switch (a3.code) {
|
switch (a3.code) {
|
||||||
case Option_1_None_1:
|
case Option_1_None_1:
|
||||||
if (1 /* TRUE */) {
|
|
||||||
Bar a3;
|
Bar a3;
|
||||||
option_1 a4;
|
Bar a5 = {Bar_No, {No: NULL}};
|
||||||
option_1 a6;
|
option_1 a4 = {Option_1_Some_1, {Some_1: a5}};
|
||||||
Array_1 a7;
|
|
||||||
a7.content_field = catala_malloc(sizeof(Array_1));
|
|
||||||
|
|
||||||
Option_1 a8 = catala_handle_exceptions(a7);
|
|
||||||
switch (a8.code) {
|
|
||||||
case Option_1_None_1:
|
|
||||||
if (1 /* TRUE */) {
|
|
||||||
Bar a6 = {Bar_No, {No: NULL}};
|
|
||||||
option_1 a6 = {Option_1_Some_1, {Some_1: a6}};
|
|
||||||
|
|
||||||
} else {
|
|
||||||
option_1 a6 = {Option_1_None_1, {None_1: NULL}};
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Option_1_Some_1:
|
|
||||||
Bar x1 = a8.payload.Some_1;
|
|
||||||
option_1 a6 = {Option_1_Some_1, {Some_1: x1}};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Array_1 a5;
|
|
||||||
a5.content_field = catala_malloc(sizeof(Array_1));
|
|
||||||
a5.content_field[0] = a6;
|
|
||||||
Option_1 a9 = catala_handle_exceptions(a5);
|
|
||||||
switch (a9.code) {
|
|
||||||
case Option_1_None_1:
|
|
||||||
if (0 /* FALSE */) {
|
|
||||||
option_1 a4 = {Option_1_None_1, {None_1: NULL}};
|
|
||||||
|
|
||||||
} else {
|
|
||||||
option_1 a4 = {Option_1_None_1, {None_1: NULL}};
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Option_1_Some_1:
|
|
||||||
Bar x1 = a9.payload.Some_1;
|
|
||||||
option_1 a4 = {Option_1_Some_1, {Some_1: x1}};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (a4.code) {
|
switch (a4.code) {
|
||||||
case Option_1_None_1:
|
case Option_1_None_1:
|
||||||
catala_raise_fatal_error (catala_no_value,
|
catala_raise_fatal_error (catala_no_value,
|
||||||
@ -164,11 +106,6 @@ Baz baz(Baz_in baz_in) {
|
|||||||
case Option_1_Some_1: Bar arg = a4.payload.Some_1; a3 = arg; break;
|
case Option_1_Some_1: Bar arg = a4.payload.Some_1; a3 = arg; break;
|
||||||
}
|
}
|
||||||
option_1 a3 = {Option_1_Some_1, {Some_1: a3}};
|
option_1 a3 = {Option_1_Some_1, {Some_1: a3}};
|
||||||
|
|
||||||
} else {
|
|
||||||
option_1 a3 = {Option_1_None_1, {None_1: NULL}};
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Option_1_Some_1:
|
case Option_1_Some_1:
|
||||||
Bar x1 = a3.payload.Some_1;
|
Bar x1 = a3.payload.Some_1;
|
||||||
@ -186,11 +123,62 @@ Baz baz(Baz_in baz_in) {
|
|||||||
a1 = a2;
|
a1 = a2;
|
||||||
double b2;
|
double b2;
|
||||||
option_2 b3;
|
option_2 b3;
|
||||||
option_2 b5;
|
Option_2 b4;
|
||||||
option_2 b7;
|
char /* bool */ b5;
|
||||||
┌─[ERROR]─
|
switch (a1.code) {
|
||||||
│
|
case Bar_No: b5 = 1 /* TRUE */; break;
|
||||||
│ Unexpected error: Not_found
|
case Bar_Yes: Foo _ = a1.payload.Yes; b5 = 0 /* FALSE */; break;
|
||||||
│
|
}
|
||||||
└─
|
if (b5) {
|
||||||
#return code 125#
|
option_2 b4 = {Option_2_Some_2, {Some_2: 42.}};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
option_2 b4 = {Option_2_None_2, {None_2: NULL}};
|
||||||
|
|
||||||
|
}
|
||||||
|
switch (b4.code) {
|
||||||
|
case Option_2_None_2:
|
||||||
|
double b6;
|
||||||
|
switch (a1.code) {
|
||||||
|
case Bar_No: b6 = 0.; break;
|
||||||
|
case Bar_Yes:
|
||||||
|
Foo foo = a1.payload.Yes;
|
||||||
|
double b6;
|
||||||
|
if (foo.x) {b6 = 1.; } else {b6 = 0.; }
|
||||||
|
b6 = (foo.y + b6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
option_2 b3 = {Option_2_Some_2, {Some_2: b6}};
|
||||||
|
break;
|
||||||
|
case Option_2_Some_2:
|
||||||
|
double x1 = b4.payload.Some_2;
|
||||||
|
option_2 b3 = {Option_2_Some_2, {Some_2: x1}};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (b3.code) {
|
||||||
|
case Option_2_None_2:
|
||||||
|
catala_raise_fatal_error (catala_no_value,
|
||||||
|
"tests/backends/simple.catala_en", 12, 10, 12, 11);
|
||||||
|
break;
|
||||||
|
case Option_2_Some_2: double arg = b3.payload.Some_2; b2 = arg; break;
|
||||||
|
}
|
||||||
|
double b1;
|
||||||
|
b1 = b2;
|
||||||
|
array_1 c2;
|
||||||
|
Array_1 c4;
|
||||||
|
c4.content_field = catala_malloc(sizeof(Array_1));
|
||||||
|
c4.content_field[0] = b1;
|
||||||
|
c4.content_field[1] = b1;
|
||||||
|
option_3 c3 = {Option_3_Some_3, {Some_3: c4}};
|
||||||
|
switch (c3.code) {
|
||||||
|
case Option_3_None_3:
|
||||||
|
catala_raise_fatal_error (catala_no_value,
|
||||||
|
"tests/backends/simple.catala_en", 13, 10, 13, 11);
|
||||||
|
break;
|
||||||
|
case Option_3_Some_3: Array_1 arg = c3.payload.Some_3; c2 = arg; break;
|
||||||
|
}
|
||||||
|
Array_1 c1;
|
||||||
|
c1 = c2;
|
||||||
|
Baz Baz = { b1, c1 };
|
||||||
|
return Baz;
|
||||||
|
}
|
||||||
|
@ -91,30 +91,7 @@ class BIn:
|
|||||||
|
|
||||||
def some_name(some_name_in:SomeNameIn):
|
def some_name(some_name_in:SomeNameIn):
|
||||||
i = (some_name_in.i_in)
|
i = (some_name_in.i_in)
|
||||||
o4 = (handle_exceptions([], []))
|
o2 = ((i + integer_of_string("1")))
|
||||||
if o4 is None:
|
|
||||||
if True:
|
|
||||||
o3 = ((i + integer_of_string("1")))
|
|
||||||
else:
|
|
||||||
o3 = (None)
|
|
||||||
else:
|
|
||||||
x = o4
|
|
||||||
o3 = (x)
|
|
||||||
o5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/backends/python_name_clash.catala_en",
|
|
||||||
start_line=10, start_column=23,
|
|
||||||
end_line=10, end_column=28, law_headings=[])],
|
|
||||||
[o3]
|
|
||||||
))
|
|
||||||
if o5 is None:
|
|
||||||
if False:
|
|
||||||
o2 = (None)
|
|
||||||
else:
|
|
||||||
o2 = (None)
|
|
||||||
else:
|
|
||||||
x = o5
|
|
||||||
o2 = (x)
|
|
||||||
if o2 is None:
|
if o2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/backends/python_name_clash.catala_en",
|
filename="tests/backends/python_name_clash.catala_en",
|
||||||
@ -127,30 +104,7 @@ def some_name(some_name_in:SomeNameIn):
|
|||||||
return SomeName(o = o)
|
return SomeName(o = o)
|
||||||
|
|
||||||
def b(b_in:BIn):
|
def b(b_in:BIn):
|
||||||
result4 = (handle_exceptions([], []))
|
result2 = (integer_of_string("1"))
|
||||||
if result4 is None:
|
|
||||||
if True:
|
|
||||||
result3 = (integer_of_string("1"))
|
|
||||||
else:
|
|
||||||
result3 = (None)
|
|
||||||
else:
|
|
||||||
x = result4
|
|
||||||
result3 = (x)
|
|
||||||
result5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/backends/python_name_clash.catala_en",
|
|
||||||
start_line=16, start_column=33,
|
|
||||||
end_line=16, end_column=34, law_headings=[])],
|
|
||||||
[result3]
|
|
||||||
))
|
|
||||||
if result5 is None:
|
|
||||||
if False:
|
|
||||||
result2 = (None)
|
|
||||||
else:
|
|
||||||
result2 = (None)
|
|
||||||
else:
|
|
||||||
x = result5
|
|
||||||
result2 = (x)
|
|
||||||
if result2 is None:
|
if result2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/backends/python_name_clash.catala_en",
|
filename="tests/backends/python_name_clash.catala_en",
|
||||||
@ -160,11 +114,11 @@ def b(b_in:BIn):
|
|||||||
arg = result2
|
arg = result2
|
||||||
result1 = (arg)
|
result1 = (arg)
|
||||||
result = (some_name(SomeNameIn(i_in = result1)))
|
result = (some_name(SomeNameIn(i_in = result1)))
|
||||||
result6 = (SomeName(o = result.o))
|
result3 = (SomeName(o = result.o))
|
||||||
if True:
|
if True:
|
||||||
some_name2 = (result6)
|
some_name2 = (result3)
|
||||||
else:
|
else:
|
||||||
some_name2 = (result6)
|
some_name2 = (result3)
|
||||||
some_name1 = (some_name2)
|
some_name1 = (some_name2)
|
||||||
return B(some_name = some_name1)
|
return B(some_name = some_name1)
|
||||||
```
|
```
|
||||||
|
@ -53,13 +53,7 @@ let scope S (S_in: S_in {x_in: list of integer}): S {y: integer} =
|
|||||||
let get x : list of integer = S_in.x_in in
|
let get x : list of integer = S_in.x_in in
|
||||||
let set y : integer =
|
let set y : integer =
|
||||||
match
|
match
|
||||||
(match
|
(ESome
|
||||||
(handle_exceptions
|
|
||||||
[
|
|
||||||
match (handle_exceptions []) with
|
|
||||||
| ENone →
|
|
||||||
if true then
|
|
||||||
ESome
|
|
||||||
(let weights : list of (integer, integer) =
|
(let weights : list of (integer, integer) =
|
||||||
map (λ (potential_max: integer) →
|
map (λ (potential_max: integer) →
|
||||||
(potential_max,
|
(potential_max,
|
||||||
@ -74,13 +68,7 @@ let scope S (S_in: S_in {x_in: list of integer}): S {y: integer} =
|
|||||||
(potential_max,
|
(potential_max,
|
||||||
let potential_max1 : integer = potential_max in
|
let potential_max1 : integer = potential_max in
|
||||||
potential_max1)
|
potential_max1)
|
||||||
weights).0
|
weights).0)
|
||||||
else ENone ()
|
|
||||||
| ESome x → ESome x
|
|
||||||
])
|
|
||||||
with
|
|
||||||
| ENone → if false then ENone () else ENone ()
|
|
||||||
| ESome x → ESome x)
|
|
||||||
with
|
with
|
||||||
| ENone → error NoValue
|
| ENone → error NoValue
|
||||||
| ESome arg → arg
|
| ESome arg → arg
|
||||||
|
@ -130,11 +130,9 @@ let scope Foo
|
|||||||
let get b : ((closure_env, unit) → option bool, closure_env) =
|
let get b : ((closure_env, unit) → option bool, closure_env) =
|
||||||
Foo_in.b_in
|
Foo_in.b_in
|
||||||
in
|
in
|
||||||
let set b : bool =
|
let set b : bool = match (b.0 b.1 ()) with
|
||||||
match (handle_exceptions [b.0 b.1 ()]) with
|
|
||||||
| ENone → true
|
| ENone → true
|
||||||
| ESome x → x
|
| ESome x → x in
|
||||||
in
|
|
||||||
let set r :
|
let set r :
|
||||||
Result {
|
Result {
|
||||||
r: ((closure_env, integer) → integer, closure_env);
|
r: ((closure_env, integer) → integer, closure_env);
|
||||||
|
@ -26,29 +26,7 @@ end
|
|||||||
|
|
||||||
let s (s_in: S_in.t) : S.t =
|
let s (s_in: S_in.t) : S.t =
|
||||||
let sr: money =
|
let sr: money =
|
||||||
match
|
match (Eoption.ESome (money_of_cents_string "100000"))
|
||||||
(match
|
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/modules/good/mod_def.catala_en";
|
|
||||||
start_line=16; start_column=10; end_line=16; end_column=12;
|
|
||||||
law_headings=["Test modules + inclusions 1"]}|]
|
|
||||||
([|(match
|
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/modules/good/mod_def.catala_en";
|
|
||||||
start_line=29; start_column=24;
|
|
||||||
end_line=29; end_column=30;
|
|
||||||
law_headings=["Test modules + inclusions 1"]}|]
|
|
||||||
([||]))
|
|
||||||
with
|
|
||||||
| Eoption.ENone _ ->
|
|
||||||
( if true then
|
|
||||||
(Eoption.ESome (money_of_cents_string "100000")) else
|
|
||||||
(Eoption.ENone ()))
|
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))|]))
|
|
||||||
with
|
|
||||||
| Eoption.ENone _ ->
|
|
||||||
( if false then (Eoption.ENone ()) else (Eoption.ENone ()))
|
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))
|
|
||||||
with
|
with
|
||||||
| Eoption.ENone _ -> (raise
|
| Eoption.ENone _ -> (raise
|
||||||
(Runtime_ocaml.Runtime.Error (NoValue, [{filename="tests/modules/good/mod_def.catala_en";
|
(Runtime_ocaml.Runtime.Error (NoValue, [{filename="tests/modules/good/mod_def.catala_en";
|
||||||
@ -57,28 +35,7 @@ let s (s_in: S_in.t) : S.t =
|
|||||||
law_headings=["Test modules + inclusions 1"]}])))
|
law_headings=["Test modules + inclusions 1"]}])))
|
||||||
| Eoption.ESome arg -> arg in
|
| Eoption.ESome arg -> arg in
|
||||||
let e1: Enum1.t =
|
let e1: Enum1.t =
|
||||||
match
|
match (Eoption.ESome (Enum1.Maybe ()))
|
||||||
(match
|
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/modules/good/mod_def.catala_en";
|
|
||||||
start_line=17; start_column=10; end_line=17; end_column=12;
|
|
||||||
law_headings=["Test modules + inclusions 1"]}|]
|
|
||||||
([|(match
|
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/modules/good/mod_def.catala_en";
|
|
||||||
start_line=30; start_column=24;
|
|
||||||
end_line=30; end_column=29;
|
|
||||||
law_headings=["Test modules + inclusions 1"]}|]
|
|
||||||
([||]))
|
|
||||||
with
|
|
||||||
| Eoption.ENone _ ->
|
|
||||||
( if true then (Eoption.ESome (Enum1.Maybe ())) else
|
|
||||||
(Eoption.ENone ()))
|
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))|]))
|
|
||||||
with
|
|
||||||
| Eoption.ENone _ ->
|
|
||||||
( if false then (Eoption.ENone ()) else (Eoption.ENone ()))
|
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))
|
|
||||||
with
|
with
|
||||||
| Eoption.ENone _ -> (raise
|
| Eoption.ENone _ -> (raise
|
||||||
(Runtime_ocaml.Runtime.Error (NoValue, [{filename="tests/modules/good/mod_def.catala_en";
|
(Runtime_ocaml.Runtime.Error (NoValue, [{filename="tests/modules/good/mod_def.catala_en";
|
||||||
|
@ -14,10 +14,6 @@ type option_1 = | None_1 of unit | Some_1 of bool
|
|||||||
|
|
||||||
type TestXor_in = { t_in: unit → option_1[None_1: unit | Some_1: bool]; }
|
type TestXor_in = { t_in: unit → option_1[None_1: unit | Some_1: bool]; }
|
||||||
type TestXor = { t: bool; }
|
type TestXor = { t: bool; }
|
||||||
type array_1 = {
|
|
||||||
content: list of option_1[None_1: unit | Some_1: bool];
|
|
||||||
length: integer;
|
|
||||||
}
|
|
||||||
|
|
||||||
let scope TestXor
|
let scope TestXor
|
||||||
(TestXor_in:
|
(TestXor_in:
|
||||||
@ -29,35 +25,12 @@ let scope TestXor
|
|||||||
in
|
in
|
||||||
let set t : bool =
|
let set t : bool =
|
||||||
match
|
match
|
||||||
(match
|
(match (t ()) with
|
||||||
(handle_exceptions { array_1 content = [t ()]; length = 1; })
|
|
||||||
with
|
|
||||||
| None_1 →
|
| None_1 →
|
||||||
if true then
|
|
||||||
Some_1
|
Some_1
|
||||||
(match
|
(match (Some_1 true) with
|
||||||
(match
|
|
||||||
(handle_exceptions
|
|
||||||
{ array_1
|
|
||||||
content =
|
|
||||||
[
|
|
||||||
match
|
|
||||||
(handle_exceptions
|
|
||||||
{ array_1 content = []; length = 0; })
|
|
||||||
with
|
|
||||||
| None_1 →
|
|
||||||
if true then Some_1 true else None_1 ()
|
|
||||||
| Some_1 x → Some_1 x
|
|
||||||
];
|
|
||||||
length = 1;
|
|
||||||
})
|
|
||||||
with
|
|
||||||
| None_1 → if false then None_1 () else None_1 ()
|
|
||||||
| Some_1 x → Some_1 x)
|
|
||||||
with
|
|
||||||
| None_1 → error NoValue
|
| None_1 → error NoValue
|
||||||
| Some_1 arg → arg)
|
| Some_1 arg → arg)
|
||||||
else None_1 ()
|
|
||||||
| Some_1 x → Some_1 x)
|
| Some_1 x → Some_1 x)
|
||||||
with
|
with
|
||||||
| None_1 → error NoValue
|
| None_1 → error NoValue
|
||||||
@ -85,24 +58,7 @@ let scope TestXor2 (TestXor2_in: TestXor2_in): TestXor2 {o: bool} =
|
|||||||
if true then result1 else result1
|
if true then result1 else result1
|
||||||
in
|
in
|
||||||
let set o : bool =
|
let set o : bool =
|
||||||
match
|
match (Some_1 t.t) with
|
||||||
(match
|
|
||||||
(handle_exceptions
|
|
||||||
{ array_1
|
|
||||||
content =
|
|
||||||
[
|
|
||||||
match
|
|
||||||
(handle_exceptions { array_1 content = []; length = 0; })
|
|
||||||
with
|
|
||||||
| None_1 → if true then Some_1 t.t else None_1 ()
|
|
||||||
| Some_1 x → Some_1 x
|
|
||||||
];
|
|
||||||
length = 1;
|
|
||||||
})
|
|
||||||
with
|
|
||||||
| None_1 → if false then None_1 () else None_1 ()
|
|
||||||
| Some_1 x → Some_1 x)
|
|
||||||
with
|
|
||||||
| None_1 → error NoValue
|
| None_1 → error NoValue
|
||||||
| Some_1 arg → arg
|
| Some_1 arg → arg
|
||||||
in
|
in
|
||||||
|
@ -54,42 +54,15 @@ let s (s_in: S_in.t) : S.t =
|
|||||||
let a: unit -> (bool) Eoption.t = s_in.S_in.a_in in
|
let a: unit -> (bool) Eoption.t = s_in.S_in.a_in in
|
||||||
let a1: bool =
|
let a1: bool =
|
||||||
match
|
match
|
||||||
(match
|
(match (a ())
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/name_resolution/good/let_in2.catala_en";
|
|
||||||
start_line=7; start_column=18; end_line=7; end_column=19;
|
|
||||||
law_headings=["Article"]}|] ([|(a ())|]))
|
|
||||||
with
|
with
|
||||||
| Eoption.ENone _ ->
|
| Eoption.ENone _ ->
|
||||||
( if true then
|
|
||||||
(Eoption.ESome
|
(Eoption.ESome
|
||||||
(match
|
(match
|
||||||
(match
|
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/name_resolution/good/let_in2.catala_en";
|
|
||||||
start_line=7; start_column=18;
|
|
||||||
end_line=7; end_column=19;
|
|
||||||
law_headings=["Article"]}|]
|
|
||||||
([|(match
|
|
||||||
(handle_exceptions
|
|
||||||
[|{filename="tests/name_resolution/good/let_in2.catala_en";
|
|
||||||
start_line=11; start_column=5;
|
|
||||||
end_line=13; end_column=6;
|
|
||||||
law_headings=["Article"]}|] ([||]))
|
|
||||||
with
|
|
||||||
| Eoption.ENone _1 ->
|
|
||||||
( if true then
|
|
||||||
(Eoption.ESome (let a1 : bool = false
|
(Eoption.ESome (let a1 : bool = false
|
||||||
in
|
in
|
||||||
(let a2 : bool = (o_or a1 true)
|
(let a2 : bool = (o_or a1 true) in
|
||||||
in
|
a2)))
|
||||||
a2))) else (Eoption.ENone ()))
|
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))|]))
|
|
||||||
with
|
|
||||||
| Eoption.ENone _1 ->
|
|
||||||
( if false then (Eoption.ENone ()) else
|
|
||||||
(Eoption.ENone ()))
|
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))
|
|
||||||
with
|
with
|
||||||
| Eoption.ENone _1 -> (raise
|
| Eoption.ENone _1 -> (raise
|
||||||
(Runtime_ocaml.Runtime.Error (NoValue, [{filename="tests/name_resolution/good/let_in2.catala_en";
|
(Runtime_ocaml.Runtime.Error (NoValue, [{filename="tests/name_resolution/good/let_in2.catala_en";
|
||||||
@ -97,7 +70,7 @@ let s (s_in: S_in.t) : S.t =
|
|||||||
end_line=7; end_column=19;
|
end_line=7; end_column=19;
|
||||||
law_headings=
|
law_headings=
|
||||||
["Article"]}])))
|
["Article"]}])))
|
||||||
| Eoption.ESome arg -> arg)) else (Eoption.ENone ()))
|
| Eoption.ESome arg -> arg))
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))
|
| Eoption.ESome x -> (Eoption.ESome x))
|
||||||
with
|
with
|
||||||
| Eoption.ENone _ -> (raise
|
| Eoption.ENone _ -> (raise
|
||||||
|
@ -126,26 +126,7 @@ let glob2 = A {"y": glob1 >= 30., "z": 123. * 17.}
|
|||||||
|
|
||||||
let S2 (S2_in: S2_in) =
|
let S2 (S2_in: S2_in) =
|
||||||
decl a1 : decimal;
|
decl a1 : decimal;
|
||||||
decl a2 : option decimal;
|
a2 : option decimal = ESome glob3 ¤44.00 + 100.;
|
||||||
decl a3 : option decimal;
|
|
||||||
a4 : option decimal = handle_exceptions [];
|
|
||||||
switch a4:
|
|
||||||
| ENone _ →
|
|
||||||
if true:
|
|
||||||
a3 = ESome glob3 ¤44.00 + 100.
|
|
||||||
else:
|
|
||||||
a3 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a3 = ESome x;
|
|
||||||
a5 : option decimal = handle_exceptions [a3];
|
|
||||||
switch a5:
|
|
||||||
| ENone _ →
|
|
||||||
if false:
|
|
||||||
a2 = ENone ()
|
|
||||||
else:
|
|
||||||
a2 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a2 = ESome x;
|
|
||||||
switch a2:
|
switch a2:
|
||||||
| ENone _ →
|
| ENone _ →
|
||||||
fatal NoValue
|
fatal NoValue
|
||||||
@ -157,26 +138,7 @@ let S2 (S2_in: S2_in) =
|
|||||||
|
|
||||||
let S3 (S3_in: S3_in) =
|
let S3 (S3_in: S3_in) =
|
||||||
decl a1 : decimal;
|
decl a1 : decimal;
|
||||||
decl a2 : option decimal;
|
a2 : option decimal = ESome 50. + glob4 ¤44.00 55.;
|
||||||
decl a3 : option decimal;
|
|
||||||
a4 : option decimal = handle_exceptions [];
|
|
||||||
switch a4:
|
|
||||||
| ENone _ →
|
|
||||||
if true:
|
|
||||||
a3 = ESome 50. + glob4 ¤44.00 55.
|
|
||||||
else:
|
|
||||||
a3 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a3 = ESome x;
|
|
||||||
a5 : option decimal = handle_exceptions [a3];
|
|
||||||
switch a5:
|
|
||||||
| ENone _ →
|
|
||||||
if false:
|
|
||||||
a2 = ENone ()
|
|
||||||
else:
|
|
||||||
a2 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a2 = ESome x;
|
|
||||||
switch a2:
|
switch a2:
|
||||||
| ENone _ →
|
| ENone _ →
|
||||||
fatal NoValue
|
fatal NoValue
|
||||||
@ -188,26 +150,7 @@ let S3 (S3_in: S3_in) =
|
|||||||
|
|
||||||
let S4 (S4_in: S4_in) =
|
let S4 (S4_in: S4_in) =
|
||||||
decl a1 : decimal;
|
decl a1 : decimal;
|
||||||
decl a2 : option decimal;
|
a2 : option decimal = ESome glob5 + 1.;
|
||||||
decl a3 : option decimal;
|
|
||||||
a4 : option decimal = handle_exceptions [];
|
|
||||||
switch a4:
|
|
||||||
| ENone _ →
|
|
||||||
if true:
|
|
||||||
a3 = ESome glob5 + 1.
|
|
||||||
else:
|
|
||||||
a3 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a3 = ESome x;
|
|
||||||
a5 : option decimal = handle_exceptions [a3];
|
|
||||||
switch a5:
|
|
||||||
| ENone _ →
|
|
||||||
if false:
|
|
||||||
a2 = ENone ()
|
|
||||||
else:
|
|
||||||
a2 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a2 = ESome x;
|
|
||||||
switch a2:
|
switch a2:
|
||||||
| ENone _ →
|
| ENone _ →
|
||||||
fatal NoValue
|
fatal NoValue
|
||||||
@ -219,26 +162,7 @@ let S4 (S4_in: S4_in) =
|
|||||||
|
|
||||||
let S (S_in: S_in) =
|
let S (S_in: S_in) =
|
||||||
decl a1 : decimal;
|
decl a1 : decimal;
|
||||||
decl a2 : option decimal;
|
a2 : option decimal = ESome glob1 * glob1;
|
||||||
decl a3 : option decimal;
|
|
||||||
a4 : option decimal = handle_exceptions [];
|
|
||||||
switch a4:
|
|
||||||
| ENone _ →
|
|
||||||
if true:
|
|
||||||
a3 = ESome glob1 * glob1
|
|
||||||
else:
|
|
||||||
a3 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a3 = ESome x;
|
|
||||||
a5 : option decimal = handle_exceptions [a3];
|
|
||||||
switch a5:
|
|
||||||
| ENone _ →
|
|
||||||
if false:
|
|
||||||
a2 = ENone ()
|
|
||||||
else:
|
|
||||||
a2 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
a2 = ESome x;
|
|
||||||
switch a2:
|
switch a2:
|
||||||
| ENone _ →
|
| ENone _ →
|
||||||
fatal NoValue
|
fatal NoValue
|
||||||
@ -247,26 +171,7 @@ let S (S_in: S_in) =
|
|||||||
decl a : decimal;
|
decl a : decimal;
|
||||||
a = a1;
|
a = a1;
|
||||||
decl b1 : A {y: bool; z: decimal};
|
decl b1 : A {y: bool; z: decimal};
|
||||||
decl b2 : option A {y: bool; z: decimal};
|
b2 : option A {y: bool; z: decimal} = ESome glob2;
|
||||||
decl b3 : option A {y: bool; z: decimal};
|
|
||||||
b4 : option A {y: bool; z: decimal} = handle_exceptions [];
|
|
||||||
switch b4:
|
|
||||||
| ENone _ →
|
|
||||||
if true:
|
|
||||||
b3 = ESome glob2
|
|
||||||
else:
|
|
||||||
b3 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
b3 = ESome x;
|
|
||||||
b5 : option A {y: bool; z: decimal} = handle_exceptions [b3];
|
|
||||||
switch b5:
|
|
||||||
| ENone _ →
|
|
||||||
if false:
|
|
||||||
b2 = ENone ()
|
|
||||||
else:
|
|
||||||
b2 = ENone ()
|
|
||||||
| ESome x →
|
|
||||||
b2 = ESome x;
|
|
||||||
switch b2:
|
switch b2:
|
||||||
| ENone _ →
|
| ENone _ →
|
||||||
fatal NoValue
|
fatal NoValue
|
||||||
@ -456,32 +361,7 @@ glob6 = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
def s2(s2_in:S2In):
|
def s2(s2_in:S2In):
|
||||||
a4 = (handle_exceptions([], []))
|
a2 = ((glob3(money_of_cents_string("4400")) + decimal_of_string("100.")))
|
||||||
if a4 is None:
|
|
||||||
if True:
|
|
||||||
a3 = ((glob3(money_of_cents_string("4400")) +
|
|
||||||
decimal_of_string("100.")))
|
|
||||||
else:
|
|
||||||
a3 = (None)
|
|
||||||
else:
|
|
||||||
x = a4
|
|
||||||
a3 = (x)
|
|
||||||
a5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
|
||||||
start_line=53, start_column=24,
|
|
||||||
end_line=53, end_column=43,
|
|
||||||
law_headings=["Test toplevel function defs"])],
|
|
||||||
[a3]
|
|
||||||
))
|
|
||||||
if a5 is None:
|
|
||||||
if False:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
x = a5
|
|
||||||
a2 = (x)
|
|
||||||
if a2 is None:
|
if a2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
||||||
@ -495,33 +375,8 @@ def s2(s2_in:S2In):
|
|||||||
return S2(a = a)
|
return S2(a = a)
|
||||||
|
|
||||||
def s3(s3_in:S3In):
|
def s3(s3_in:S3In):
|
||||||
a4 = (handle_exceptions([], []))
|
a2 = ((decimal_of_string("50.") +
|
||||||
if a4 is None:
|
glob4(money_of_cents_string("4400"), decimal_of_string("55."))))
|
||||||
if True:
|
|
||||||
a3 = ((decimal_of_string("50.") +
|
|
||||||
glob4(money_of_cents_string("4400"),
|
|
||||||
decimal_of_string("55."))))
|
|
||||||
else:
|
|
||||||
a3 = (None)
|
|
||||||
else:
|
|
||||||
x = a4
|
|
||||||
a3 = (x)
|
|
||||||
a5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
|
||||||
start_line=74, start_column=24,
|
|
||||||
end_line=74, end_column=47,
|
|
||||||
law_headings=["Test function def with two args"])],
|
|
||||||
[a3]
|
|
||||||
))
|
|
||||||
if a5 is None:
|
|
||||||
if False:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
x = a5
|
|
||||||
a2 = (x)
|
|
||||||
if a2 is None:
|
if a2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
||||||
@ -535,31 +390,7 @@ def s3(s3_in:S3In):
|
|||||||
return S3(a = a)
|
return S3(a = a)
|
||||||
|
|
||||||
def s4(s4_in:S4In):
|
def s4(s4_in:S4In):
|
||||||
a4 = (handle_exceptions([], []))
|
a2 = ((glob5 + decimal_of_string("1.")))
|
||||||
if a4 is None:
|
|
||||||
if True:
|
|
||||||
a3 = ((glob5 + decimal_of_string("1.")))
|
|
||||||
else:
|
|
||||||
a3 = (None)
|
|
||||||
else:
|
|
||||||
x = a4
|
|
||||||
a3 = (x)
|
|
||||||
a5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
|
||||||
start_line=98, start_column=24,
|
|
||||||
end_line=98, end_column=34,
|
|
||||||
law_headings=["Test inline defs in toplevel defs"])],
|
|
||||||
[a3]
|
|
||||||
))
|
|
||||||
if a5 is None:
|
|
||||||
if False:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
x = a5
|
|
||||||
a2 = (x)
|
|
||||||
if a2 is None:
|
if a2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
||||||
@ -573,31 +404,7 @@ def s4(s4_in:S4In):
|
|||||||
return S4(a = a)
|
return S4(a = a)
|
||||||
|
|
||||||
def s5(s_in:SIn):
|
def s5(s_in:SIn):
|
||||||
a4 = (handle_exceptions([], []))
|
a2 = ((glob1 * glob1))
|
||||||
if a4 is None:
|
|
||||||
if True:
|
|
||||||
a3 = ((glob1 * glob1))
|
|
||||||
else:
|
|
||||||
a3 = (None)
|
|
||||||
else:
|
|
||||||
x = a4
|
|
||||||
a3 = (x)
|
|
||||||
a5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
|
||||||
start_line=18, start_column=24,
|
|
||||||
end_line=18, end_column=37,
|
|
||||||
law_headings=["Test basic toplevel values defs"])],
|
|
||||||
[a3]
|
|
||||||
))
|
|
||||||
if a5 is None:
|
|
||||||
if False:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
a2 = (None)
|
|
||||||
else:
|
|
||||||
x = a5
|
|
||||||
a2 = (x)
|
|
||||||
if a2 is None:
|
if a2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
||||||
@ -608,31 +415,7 @@ def s5(s_in:SIn):
|
|||||||
arg = a2
|
arg = a2
|
||||||
a1 = (arg)
|
a1 = (arg)
|
||||||
a = (a1)
|
a = (a1)
|
||||||
b4 = (handle_exceptions([], []))
|
b2 = (glob6)
|
||||||
if b4 is None:
|
|
||||||
if True:
|
|
||||||
b3 = (glob6)
|
|
||||||
else:
|
|
||||||
b3 = (None)
|
|
||||||
else:
|
|
||||||
x = b4
|
|
||||||
b3 = (x)
|
|
||||||
b5 = (handle_exceptions(
|
|
||||||
[SourcePosition(
|
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
|
||||||
start_line=19, start_column=24,
|
|
||||||
end_line=19, end_column=29,
|
|
||||||
law_headings=["Test basic toplevel values defs"])],
|
|
||||||
[b3]
|
|
||||||
))
|
|
||||||
if b5 is None:
|
|
||||||
if False:
|
|
||||||
b2 = (None)
|
|
||||||
else:
|
|
||||||
b2 = (None)
|
|
||||||
else:
|
|
||||||
x = b5
|
|
||||||
b2 = (x)
|
|
||||||
if b2 is None:
|
if b2 is None:
|
||||||
raise NoValue(SourcePosition(
|
raise NoValue(SourcePosition(
|
||||||
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
filename="tests/name_resolution/good/toplevel_defs.catala_en",
|
||||||
|
@ -24,18 +24,7 @@ $ catala Typecheck --check-invariants
|
|||||||
$ catala Lcalc -s Foo
|
$ catala Lcalc -s Foo
|
||||||
let scope Foo (Foo_in: Foo_in): Foo {bar: integer} =
|
let scope Foo (Foo_in: Foo_in): Foo {bar: integer} =
|
||||||
let set bar : integer =
|
let set bar : integer =
|
||||||
match
|
match (ESome 0) with
|
||||||
(match
|
|
||||||
(handle_exceptions
|
|
||||||
[
|
|
||||||
match (handle_exceptions []) with
|
|
||||||
| ENone → if true then ESome 0 else ENone ()
|
|
||||||
| ESome x → ESome x
|
|
||||||
])
|
|
||||||
with
|
|
||||||
| ENone → if false then ENone () else ENone ()
|
|
||||||
| ESome x → ESome x)
|
|
||||||
with
|
|
||||||
| ENone → error NoValue
|
| ENone → error NoValue
|
||||||
| ESome arg → arg
|
| ESome arg → arg
|
||||||
in
|
in
|
||||||
|
Loading…
Reference in New Issue
Block a user