Skip to content

Commit 5063353

Browse files
committed
Add versions of repeat_until_full for other index sizes
1 parent 688f6ec commit 5063353

File tree

8 files changed

+69
-30
lines changed

8 files changed

+69
-30
lines changed

fathom/src/core.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,22 @@ def_prims! {
381381
FormatArray64Map => "array64_map",
382382
/// Repeat a format until the length of the given parse scope is reached.
383383
FormatRepeatUntilEnd => "repeat_until_end",
384-
/// Repeat a format until the array is filled.
384+
/// Repeat a format until the array with 8-bit indices is filled.
385385
///
386386
/// The value read by the format is replicated according to a supplied function.
387-
FormatRepeatUntilFull => "repeat_until_full",
387+
FormatRepeatUntilFull8 => "repeat_until_full8",
388+
/// Repeat a format until the array with 16-bit indices is filled.
389+
///
390+
/// The value read by the format is replicated according to a supplied function.
391+
FormatRepeatUntilFull16 => "repeat_until_full16",
392+
/// Repeat a format until the array with 32-bit indices is filled.
393+
///
394+
/// The value read by the format is replicated according to a supplied function.
395+
FormatRepeatUntilFull32 => "repeat_until_full32",
396+
/// Repeat a format until the array with 64-bit indices is filled.
397+
///
398+
/// The value read by the format is replicated according to a supplied function.
399+
FormatRepeatUntilFull64 => "repeat_until_full64",
388400
/// Limit the format to an unsigned 8-bit byte length.
389401
FormatLimit8 => "limit8",
390402
/// Limit the format to an unsigned 16-bit byte length.

fathom/src/core/binary.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -411,19 +411,22 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
411411
(Prim::FormatF32Le, []) => read_const(reader, span, read_f32le, Const::F32),
412412
(Prim::FormatF64Be, []) => read_const(reader, span, read_f64be, Const::F64),
413413
(Prim::FormatF64Le, []) => read_const(reader, span, read_f64le, Const::F64),
414-
(Prim::FormatArray8, [FunApp(len), FunApp(format)]) => self.read_array(reader, span, len, format),
415-
(Prim::FormatArray16, [FunApp(len), FunApp(format)]) => self.read_array(reader, span, len, format),
416-
(Prim::FormatArray32, [FunApp(len), FunApp(format)]) => self.read_array(reader, span, len, format),
414+
(Prim::FormatArray8, [FunApp(len), FunApp(format)]) |
415+
(Prim::FormatArray16, [FunApp(len), FunApp(format)]) |
416+
(Prim::FormatArray32, [FunApp(len), FunApp(format)]) |
417417
(Prim::FormatArray64, [FunApp(len), FunApp(format)]) => self.read_array(reader, span, len, format),
418-
(Prim::FormatArray8Map, [_, _, FunApp(map_fn), FunApp(array)]) => self.array_map(reader, span, map_fn, array),
419-
(Prim::FormatArray16Map, [_, _, FunApp(map_fn), FunApp(array)]) => self.array_map(reader, span, map_fn, array),
420-
(Prim::FormatArray32Map, [_, _, FunApp(map_fn), FunApp(array)]) => self.array_map(reader, span, map_fn, array),
418+
(Prim::FormatArray8Map, [_, _, FunApp(map_fn), FunApp(array)]) |
419+
(Prim::FormatArray16Map, [_, _, FunApp(map_fn), FunApp(array)]) |
420+
(Prim::FormatArray32Map, [_, _, FunApp(map_fn), FunApp(array)]) |
421421
(Prim::FormatArray64Map, [_, _, FunApp(map_fn), FunApp(array)]) => self.array_map(reader, span, map_fn, array),
422422
(Prim::FormatRepeatUntilEnd, [FunApp(format)]) => self.read_repeat_until_end(reader, format),
423-
(Prim::FormatRepeatUntilFull, [FunApp(len), FunApp(format), FunApp(replicate)]) => self.read_repeat_until_full(reader, len, replicate, format),
424-
(Prim::FormatLimit8, [FunApp(limit), FunApp(format)]) => self.read_limit(reader, limit, format),
425-
(Prim::FormatLimit16, [FunApp(limit), FunApp(format)]) => self.read_limit(reader, limit, format),
426-
(Prim::FormatLimit32, [FunApp(limit), FunApp(format)]) => self.read_limit(reader, limit, format),
423+
(Prim::FormatRepeatUntilFull8, [FunApp(len), FunApp(format), FunApp(replicate)]) |
424+
(Prim::FormatRepeatUntilFull16, [FunApp(len), FunApp(format), FunApp(replicate)]) |
425+
(Prim::FormatRepeatUntilFull32, [FunApp(len), FunApp(format), FunApp(replicate)]) |
426+
(Prim::FormatRepeatUntilFull64, [FunApp(len), FunApp(format), FunApp(replicate)]) => self.read_repeat_until_full(reader, len, replicate, format),
427+
(Prim::FormatLimit8, [FunApp(limit), FunApp(format)]) |
428+
(Prim::FormatLimit16, [FunApp(limit), FunApp(format)]) |
429+
(Prim::FormatLimit32, [FunApp(limit), FunApp(format)]) |
427430
(Prim::FormatLimit64, [FunApp(limit), FunApp(format)]) => self.read_limit(reader, limit, format),
428431
(Prim::FormatLink, [FunApp(pos), FunApp(format)]) => self.read_link(span, pos, format),
429432
(Prim::FormatDeref, [FunApp(format), FunApp(r#ref)]) => self.read_deref(format, r#ref),
@@ -529,9 +532,7 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
529532
_ => return Err(ReadError::InvalidValue(len.span())),
530533
}
531534
.ok_or_else(|| ReadError::InvalidValue(len.span()))?;
532-
533-
// TODO: Do we need to force replicate as well?
534-
// let replicate = self.elim_env().force(replicate);
535+
let replicate = self.elim_env().force(replicate);
535536

536537
let mut elems = Vec::with_capacity(len);
537538
while elems.len() < len {
@@ -544,9 +545,11 @@ impl<'arena, 'env, 'data> Context<'arena, 'env, 'data> {
544545
_ => return Err(ReadError::InvalidValue(replicate.span())),
545546
};
546547

547-
// Push it that many times onto the array
548-
// TODO: Error/limit if this exceeds len?
549-
elems.extend(std::iter::repeat(elem).take(usize::from(repeat)));
548+
// Push it that many times onto the array, limiting to the length of the
549+
// output array.
550+
elems.extend(
551+
std::iter::repeat(elem).take(usize::from(repeat).min(len - elems.len())),
552+
);
550553
}
551554
Err(err) => return Err(err),
552555
};

fathom/src/core/semantics.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,9 +869,18 @@ impl<'arena, 'env> ElimEnv<'arena, 'env> {
869869
(Prim::FormatRepeatUntilEnd, [Elim::FunApp(elem)]) => {
870870
Value::prim(Prim::ArrayType, [self.format_repr(elem)])
871871
}
872-
(Prim::FormatRepeatUntilFull, [Elim::FunApp(len), Elim::FunApp(elem), _]) => {
872+
(Prim::FormatRepeatUntilFull8, [Elim::FunApp(len), Elim::FunApp(elem), _]) => {
873+
Value::prim(Prim::Array8Type, [len.clone(), self.format_repr(elem)])
874+
}
875+
(Prim::FormatRepeatUntilFull16, [Elim::FunApp(len), Elim::FunApp(elem), _]) => {
873876
Value::prim(Prim::Array16Type, [len.clone(), self.format_repr(elem)])
874877
}
878+
(Prim::FormatRepeatUntilFull32, [Elim::FunApp(len), Elim::FunApp(elem), _]) => {
879+
Value::prim(Prim::Array32Type, [len.clone(), self.format_repr(elem)])
880+
}
881+
(Prim::FormatRepeatUntilFull64, [Elim::FunApp(len), Elim::FunApp(elem), _]) => {
882+
Value::prim(Prim::Array64Type, [len.clone(), self.format_repr(elem)])
883+
}
875884
(Prim::FormatLink, [_, Elim::FunApp(elem)]) => {
876885
Value::prim(Prim::RefType, [elem.clone()])
877886
}

fathom/src/surface/elaboration.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,11 @@ impl<'arena> RigidEnv<'arena> {
230230
env.define_prim_fun(FormatRepeatUntilEnd, [&FORMAT_TYPE], &FORMAT_TYPE);
231231

232232
// repeat_until_full16 : U16 -> fun (A : Format) -> (Repr A -> U16) -> Format
233-
env.define_prim(
234-
FormatRepeatUntilFull,
233+
let repeat_until_full = |index_type| {
235234
scope.to_scope(core::Term::FunType(
236235
Span::Empty,
237-
None,
238-
&U16_TYPE,
236+
env.name("len"),
237+
index_type,
239238
scope.to_scope(core::Term::FunType(
240239
Span::Empty,
241240
env.name("A"),
@@ -251,13 +250,23 @@ impl<'arena> RigidEnv<'arena> {
251250
&Term::Prim(Span::Empty, FormatRepr),
252251
&VAR0,
253252
)),
254-
&U16_TYPE,
253+
index_type,
255254
)),
256255
&FORMAT_TYPE,
257256
)),
258257
)),
259-
)),
260-
);
258+
))
259+
};
260+
261+
let repeat_until_full8 = repeat_until_full(&U8_TYPE);
262+
let repeat_until_full16 = repeat_until_full(&U16_TYPE);
263+
let repeat_until_full32 = repeat_until_full(&U32_TYPE);
264+
let repeat_until_full64 = repeat_until_full(&U64_TYPE);
265+
env.define_prim(FormatRepeatUntilFull8, repeat_until_full8);
266+
env.define_prim(FormatRepeatUntilFull16, repeat_until_full16);
267+
env.define_prim(FormatRepeatUntilFull32, repeat_until_full32);
268+
env.define_prim(FormatRepeatUntilFull64, repeat_until_full64);
269+
261270
env.define_prim_fun(FormatLimit8, [&U8_TYPE, &FORMAT_TYPE], &FORMAT_TYPE);
262271
env.define_prim_fun(FormatLimit16, [&U16_TYPE, &FORMAT_TYPE], &FORMAT_TYPE);
263272
env.define_prim_fun(FormatLimit32, [&U32_TYPE, &FORMAT_TYPE], &FORMAT_TYPE);

formats/opentype.fathom

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2821,7 +2821,7 @@ def simple_glyph = fun (number_of_contours : U16) => (
28212821
},
28222822

28232823
/// Array of flag elements.
2824-
flags <- repeat_until_full number_of_coords flag flag_repeat,
2824+
flags <- repeat_until_full16 number_of_coords flag flag_repeat,
28252825

28262826
let read_coord = fun (is_short : Repr flag -> Bool) => fun (is_same : Repr flag -> Bool) => fun (f : Repr flag) => {
28272827
coord <- match (is_short f) {

formats/opentype.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ let y_is_same : _ number_of_contours = flag_is_set 0x20;
402402
true => array16_index (_ number_of_contours end_pts_of_contours instruction_length instructions) (_ number_of_contours end_pts_of_contours instruction_length instructions) (number_of_contours - (1 :
403403
U16)) end_pts_of_contours + (1 : U16),
404404
},
405-
flags <- repeat_until_full number_of_coords flag flag_repeat,
405+
flags <- repeat_until_full16 number_of_coords flag flag_repeat,
406406
let read_coord : ({ flag : U8, repeat : U8 } -> Bool) -> ({
407407
flag : U8,
408408
repeat : U8,

tests/succeed/primitives.fathom

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ let _ = array16 : U16 -> Format -> Format;
5656
let _ = array32 : U32 -> Format -> Format;
5757
let _ = array64 : U64 -> Format -> Format;
5858
let _ = repeat_until_end : Format -> Format;
59-
let _ = repeat_until_full : U16 -> fun (A : Format) -> (Repr A -> U16) -> Format;
59+
let _ = repeat_until_full8 : U8 -> fun (A : Format) -> (Repr A -> U8) -> Format;
60+
let _ = repeat_until_full16 : U16 -> fun (A : Format) -> (Repr A -> U16) -> Format;
61+
let _ = repeat_until_full32 : U32 -> fun (A : Format) -> (Repr A -> U32) -> Format;
62+
let _ = repeat_until_full64 : U64 -> fun (A : Format) -> (Repr A -> U64) -> Format;
6063
let _ = array8 : U8 -> Format -> Format;
6164
let _ = array16 : U16 -> Format -> Format;
6265
let _ = array32 : U32 -> Format -> Format;

tests/succeed/primitives.snap

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ let _ : _ = array16;
5353
let _ : _ = array32;
5454
let _ : _ = array64;
5555
let _ : _ = repeat_until_end;
56-
let _ : _ = repeat_until_full;
56+
let _ : _ = repeat_until_full8;
57+
let _ : _ = repeat_until_full16;
58+
let _ : _ = repeat_until_full32;
59+
let _ : _ = repeat_until_full64;
5760
let _ : _ = array8;
5861
let _ : _ = array16;
5962
let _ : _ = array32;

0 commit comments

Comments
 (0)