mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-08 07:51:43 +03:00
Fix decimal parsing
This commit is contained in:
parent
b20b2f97be
commit
1c86c8298b
@ -328,8 +328,8 @@ type literal_date = {
|
||||
}]
|
||||
|
||||
type literal_number =
|
||||
| Int of (Runtime.integer[@opaque])
|
||||
| Dec of (Runtime.integer[@opaque]) * (Runtime.integer[@opaque])
|
||||
| Int of (string[@opaque])
|
||||
| Dec of (string[@opaque]) * (string[@opaque])
|
||||
[@@deriving
|
||||
visitors { variety = "map"; name = "literal_number_map"; nude = true },
|
||||
visitors { variety = "iter"; name = "literal_number_iter"; nude = true }]
|
||||
@ -340,8 +340,8 @@ type literal_unit = Percent | Year | Month | Day
|
||||
visitors { variety = "iter"; name = "literal_unit_iter"; nude = true }]
|
||||
|
||||
type money_amount = {
|
||||
money_amount_units : (Runtime.integer[@opaque]);
|
||||
money_amount_cents : (Runtime.integer[@opaque]);
|
||||
money_amount_units : (string[@opaque]);
|
||||
money_amount_cents : (string[@opaque]);
|
||||
}
|
||||
[@@deriving
|
||||
visitors { variety = "map"; name = "money_amount_map"; nude = true },
|
||||
|
@ -181,65 +181,41 @@ let rec translate_expr
|
||||
| Literal l ->
|
||||
let untyped_term =
|
||||
match l with
|
||||
| LNumber ((Int i, _), None) -> Desugared.Ast.ELit (Dcalc.Ast.LInt i)
|
||||
| LNumber ((Int i, _), None) ->
|
||||
Desugared.Ast.ELit (Dcalc.Ast.LInt (Runtime.integer_of_string i))
|
||||
| LNumber ((Int i, _), Some (Percent, _)) ->
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LRat
|
||||
Runtime.(decimal_of_integer i /& decimal_of_string "100"))
|
||||
Runtime.(decimal_of_string i /& decimal_of_string "100"))
|
||||
| LNumber ((Dec (i, f), _), None) ->
|
||||
let digits_f =
|
||||
try
|
||||
int_of_float
|
||||
(ceil
|
||||
(float_of_int (Runtime.integer_log2 f)
|
||||
*. log 2.0 /. log 10.0))
|
||||
with Invalid_argument _ -> 0
|
||||
in
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LRat
|
||||
Runtime.(
|
||||
decimal_of_integer i
|
||||
+& decimal_of_integer f
|
||||
/& decimal_of_integer
|
||||
(integer_exponentiation (integer_of_int 10) digits_f)))
|
||||
(Dcalc.Ast.LRat Runtime.(decimal_of_string (i ^ "." ^ f)))
|
||||
| LNumber ((Dec (i, f), _), Some (Percent, _)) ->
|
||||
let digits_f =
|
||||
try
|
||||
int_of_float
|
||||
(ceil
|
||||
(float_of_int (Runtime.integer_log2 f)
|
||||
*. log 2.0 /. log 10.0))
|
||||
with Invalid_argument _ -> 0
|
||||
in
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LRat
|
||||
Runtime.(
|
||||
(decimal_of_integer i
|
||||
+& decimal_of_integer f
|
||||
/& decimal_of_integer
|
||||
(integer_exponentiation (integer_of_int 10) digits_f)
|
||||
)
|
||||
/& decimal_of_string "100"))
|
||||
decimal_of_string (i ^ "." ^ f) /& decimal_of_string "100"))
|
||||
| LBool b -> Desugared.Ast.ELit (Dcalc.Ast.LBool b)
|
||||
| LMoneyAmount i ->
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LMoney
|
||||
Runtime.(
|
||||
money_of_cents_integer
|
||||
((i.money_amount_units *! integer_of_int 100)
|
||||
+! i.money_amount_cents)))
|
||||
(integer_of_string i.money_amount_units
|
||||
*! integer_of_int 100
|
||||
+! integer_of_string i.money_amount_cents)))
|
||||
| LNumber ((Int i, _), Some (Year, _)) ->
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LDuration
|
||||
(Runtime.duration_of_numbers (Runtime.integer_to_int i) 0 0))
|
||||
(Runtime.duration_of_numbers (int_of_string i) 0 0))
|
||||
| LNumber ((Int i, _), Some (Month, _)) ->
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LDuration
|
||||
(Runtime.duration_of_numbers 0 (Runtime.integer_to_int i) 0))
|
||||
(Runtime.duration_of_numbers 0 (int_of_string i) 0))
|
||||
| LNumber ((Int i, _), Some (Day, _)) ->
|
||||
Desugared.Ast.ELit
|
||||
(Dcalc.Ast.LDuration
|
||||
(Runtime.duration_of_numbers 0 0 (Runtime.integer_to_int i)))
|
||||
(Runtime.duration_of_numbers 0 0 (int_of_string i)))
|
||||
| LNumber ((Dec (_, _), _), Some ((Year | Month | Day), _)) ->
|
||||
Errors.raise_spanned_error pos
|
||||
"Impossible to specify decimal amounts of days, months or years"
|
||||
|
@ -564,7 +564,7 @@ let rec lex_code (lexbuf : lexbuf) : token =
|
||||
| _ -> ()
|
||||
done;
|
||||
L.update_acc lexbuf;
|
||||
MONEY_AMOUNT (Runtime.integer_of_string (Buffer.contents units), Runtime.integer_of_string (Buffer.contents cents))
|
||||
MONEY_AMOUNT (Buffer.contents units, Buffer.contents cents)
|
||||
| Plus digit, MC_DECIMAL_SEPARATOR, Star digit ->
|
||||
let rex =
|
||||
Re.(compile @@ whole_string @@ seq [
|
||||
@ -575,7 +575,7 @@ let rec lex_code (lexbuf : lexbuf) : token =
|
||||
let dec_parts = R.get_substring (R.exec ~rex (Utf8.lexeme lexbuf)) in
|
||||
L.update_acc lexbuf;
|
||||
DECIMAL_LITERAL
|
||||
(Runtime.integer_of_string (dec_parts 1), Runtime.integer_of_string (dec_parts 2))
|
||||
(dec_parts 1, dec_parts 2)
|
||||
| "<=@" ->
|
||||
L.update_acc lexbuf;
|
||||
LESSER_EQUAL_DATE
|
||||
@ -743,7 +743,7 @@ let rec lex_code (lexbuf : lexbuf) : token =
|
||||
| Plus digit ->
|
||||
(* Integer literal*)
|
||||
L.update_acc lexbuf;
|
||||
INT_LITERAL (Runtime.integer_of_string (Utf8.lexeme lexbuf))
|
||||
INT_LITERAL (Utf8.lexeme lexbuf)
|
||||
| _ -> L.raise_lexer_error (Pos.from_lpos prev_pos) prev_lexeme
|
||||
|
||||
let rec lex_directive_args (lexbuf : lexbuf) : token =
|
||||
|
@ -127,7 +127,7 @@ unit_literal:
|
||||
| DAY { (Day, Pos.from_lpos $sloc) }
|
||||
|
||||
date_int:
|
||||
| d = INT_LITERAL { (Runtime.integer_to_int d, Pos.from_lpos $sloc) }
|
||||
| d = INT_LITERAL { (int_of_string d, Pos.from_lpos $sloc) }
|
||||
|
||||
literal:
|
||||
| l = num_literal u = option(unit_literal) {
|
||||
|
@ -31,10 +31,10 @@
|
||||
%token<string> LAW_TEXT
|
||||
%token<string> CONSTRUCTOR IDENT
|
||||
%token<string> END_CODE
|
||||
%token<Runtime.integer> INT_LITERAL
|
||||
%token<string> INT_LITERAL
|
||||
%token TRUE FALSE
|
||||
%token<Runtime.integer * Runtime.integer> DECIMAL_LITERAL
|
||||
%token<Runtime.integer * Runtime.integer> MONEY_AMOUNT
|
||||
%token<string * string> DECIMAL_LITERAL
|
||||
%token<string * string> MONEY_AMOUNT
|
||||
%token BEGIN_CODE TEXT
|
||||
%token COLON ALT DATA VERTICAL
|
||||
%token OF INTEGER COLLECTION
|
||||
|
@ -0,0 +1,3 @@
|
||||
[RESULT] Computation successful! Results:
|
||||
[RESULT] x = 4.
|
||||
[RESULT] y = 1.04
|
12
tests/test_dec/good/zero_after_comma.catala_en
Normal file
12
tests/test_dec/good/zero_after_comma.catala_en
Normal file
@ -0,0 +1,12 @@
|
||||
## Article
|
||||
|
||||
```catala
|
||||
declaration scope A:
|
||||
context output x content decimal
|
||||
context output y content decimal
|
||||
|
||||
scope A:
|
||||
definition x equals 4.0
|
||||
definition y equals 1.0 +. (x /. 100.0)
|
||||
assertion y = 1.04
|
||||
```
|
Loading…
Reference in New Issue
Block a user