Skip to content

Commit 350f850

Browse files
authored
feat(compiler): Rational number type (#1603)
* feat(compiler): Rational number type * added numerator, denominator functions * updated tests * updated docs
1 parent 979a20c commit 350f850

File tree

20 files changed

+997
-108
lines changed

20 files changed

+997
-108
lines changed

compiler/src/codegen/transl_anf.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ let compile_const = (c: Asttypes.constant) =>
527527
| Const_string(_) => failwith("compile_const: Const_string post-ANF")
528528
| Const_char(_) => failwith("compile_const: Const_char post-ANF")
529529
| Const_bigint(_) => failwith("compile_const: Const_bigint post-ANF")
530+
| Const_rational(_) => failwith("compile_const: Const_rational post-ANF")
530531
| Const_int32(i32) => MConstI32(i32)
531532
| Const_int64(i64) => MConstI64(i64)
532533
| Const_uint32(u32) => MConstU32(u32)

compiler/src/middle_end/linearize.re

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ let transl_const =
182182
[BLet(tmp, Comp.number(Const_number_bigint(data)), Nonglobal)]
183183
),
184184
)
185+
| Const_rational(data) =>
186+
Right(
187+
with_bind("rational", tmp =>
188+
[BLet(tmp, Comp.number(Const_number_rational(data)), Nonglobal)]
189+
),
190+
)
185191
| Const_int32(i) =>
186192
Right(with_bind("int32", tmp => [BLet(tmp, Comp.int32(i), Nonglobal)]))
187193
| Const_int64(i) =>

compiler/src/middle_end/matchcomp.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ let equality_type =
539539
| Const_uint32(_)
540540
| Const_uint64(_)
541541
| Const_bigint(_)
542+
| Const_rational(_)
542543
| Const_float32(_)
543544
| Const_float64(_)
544545
| Const_bytes(_)

compiler/src/parsing/ast_helper.re

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ module Constant = {
7272
let wasmf32 = f => PConstWasmF32(f);
7373
let wasmf64 = f => PConstWasmF64(f);
7474
let bigint = i => PConstBigInt(i);
75+
let rational = r => {
76+
let (n, d) =
77+
switch (String.split_on_char('/', r)) {
78+
| [n, d] => (n, d)
79+
| _ => failwith("Impossible: rational literal without forward slash")
80+
};
81+
PConstRational(n, d);
82+
};
7583
let bool = b => PConstBool(b);
7684
let void = PConstVoid;
7785
};

compiler/src/parsing/ast_helper.rei

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ module Constant: {
4848
let wasmf32: string => constant;
4949
let wasmf64: string => constant;
5050
let bigint: string => constant;
51+
let rational: string => constant;
5152
let bool: bool => constant;
5253
let void: constant;
5354
};

compiler/src/parsing/asttypes.re

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ type bigint_data = {
2626
bigint_rep: string,
2727
};
2828

29+
[@deriving (sexp, yojson)]
30+
type rational_data = {
31+
rational_negative: bool,
32+
rational_num_limbs: array(int64),
33+
rational_den_limbs: array(int64),
34+
rational_num_rep: string,
35+
rational_den_rep: string,
36+
};
37+
2938
[@deriving (sexp, yojson)]
3039
type constant =
3140
| Const_number(number_type)
@@ -43,20 +52,15 @@ type constant =
4352
| Const_wasmf32(float)
4453
| Const_wasmf64(float)
4554
| Const_bigint(bigint_data)
55+
| Const_rational(rational_data)
4656
| Const_bool(bool)
4757
| Const_void
4858

4959
[@deriving (sexp, yojson)]
5060
and number_type =
5161
| Const_number_int(int64)
5262
| Const_number_float(float)
53-
| Const_number_rational({
54-
rational_negative: bool,
55-
rational_num_limbs: array(int64),
56-
rational_den_limbs: array(int64),
57-
rational_num_rep: string,
58-
rational_den_rep: string,
59-
})
63+
| Const_number_rational(rational_data)
6064
| Const_number_bigint(bigint_data);
6165

6266
/** Marker for exported/nonexported let bindings */

compiler/src/parsing/lexer.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ let rec token = lexbuf => {
253253
| (unsigned_float, 'w') => positioned(WASMF32(sub_lexeme(lexbuf, 0, -1)))
254254
| (unsigned_float, 'W') => positioned(WASMF64(sub_lexeme(lexbuf, 0, -1)))
255255
| (unsigned_int, 't') => positioned(BIGINT(sub_lexeme(lexbuf, 0, -1)))
256+
| (unsigned_int, '/', Opt('-'), unsigned_int, 'r') =>
257+
positioned(RATIONAL(sub_lexeme(lexbuf, 0, -1)))
256258
| unsigned_int => positioned(NUMBER_INT(Sedlexing.Utf8.lexeme(lexbuf)))
257259
| "primitive" => positioned(PRIMITIVE)
258260
| "foreign" => positioned(FOREIGN)

compiler/src/parsing/parser.mly

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Grain_parsing = struct end
1212
%}
1313

1414

15+
%token <string> RATIONAL
1516
%token <string> NUMBER_INT NUMBER_FLOAT
1617
%token <string> INT32 INT64 UINT32 UINT64 FLOAT32 FLOAT64 BIGINT
1718
%token <string> WASMI32 WASMI64 WASMF32 WASMF64
@@ -208,6 +209,7 @@ const:
208209
| DASH? WASMF32 { Constant.wasmf32 (if Option.is_some $1 then "-" ^ $2 else $2), $sloc }
209210
| DASH? WASMF64 { Constant.wasmf64 (if Option.is_some $1 then "-" ^ $2 else $2), $sloc }
210211
| DASH? BIGINT { Constant.bigint (if Option.is_some $1 then "-" ^ $2 else $2), $sloc }
212+
| DASH? RATIONAL { Constant.rational (if Option.is_some $1 then "-" ^ $2 else $2), $sloc }
211213
| TRUE { Constant.bool true, $loc }
212214
| FALSE { Constant.bool false, $loc }
213215
| VOID { Constant.void, $loc }

compiler/src/parsing/parsetree.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ type constant =
130130
| PConstWasmF32(string)
131131
| PConstWasmF64(string)
132132
| PConstBigInt(string)
133+
| PConstRational(string, string)
133134
| PConstBool(bool)
134135
| PConstVoid
135136
| PConstBytes(string)

compiler/src/parsing/well_formedness.re

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,21 @@ let no_letrec_mut = (errs, super) => {
255255
let no_zero_denominator_rational = (errs, super) => {
256256
let enter_expression = ({pexp_desc: desc, pexp_loc: loc} as e) => {
257257
switch (desc) {
258-
| PExpConstant(PConstNumber(PConstNumberRational(_, d))) when d == "0" =>
258+
| PExpConstant(
259+
PConstNumber(PConstNumberRational(_, d)) | PConstRational(_, d),
260+
)
261+
when d == "0" =>
259262
errs := [RationalZeroDenominator(loc), ...errs^]
260263
| _ => ()
261264
};
262265
super.enter_expression(e);
263266
};
264267
let enter_pattern = ({ppat_desc: desc, ppat_loc: loc} as p) => {
265268
switch (desc) {
266-
| PPatConstant(PConstNumber(PConstNumberRational(_, d))) when d == "0" =>
269+
| PPatConstant(
270+
PConstNumber(PConstNumberRational(_, d)) | PConstRational(_, d),
271+
)
272+
when d == "0" =>
267273
errs := [RationalZeroDenominator(loc), ...errs^]
268274
| _ => ()
269275
};

0 commit comments

Comments
 (0)