Skip to content

Commit 5d1dd8e

Browse files
authored
Merge pull request #496 from savi-lang/add/trace-data-mutable
Add `TraceData.Mutable` and `TraceData.Mutator`.
2 parents 1442cb7 + 9f86124 commit 5d1dd8e

File tree

5 files changed

+493
-1
lines changed

5 files changed

+493
-1
lines changed

core/Array.savi

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,74 @@
315315
)
316316
)
317317

318+
:is TraceData.Mutable
319+
:fun ref trace_data_mutable(trace TraceData.Mutator)
320+
trace.array_truncate(identity_digest_of @, @size) -> (s | @truncate(s))
321+
trace.array(identity_digest_of @, @size) -> (i |
322+
case (
323+
| i < @size |
324+
// If it's within the existing bounds of the array, allow the mutator
325+
// the option to replace the current value at that index.
326+
case A <: (
327+
| Bool | trace.replace_bool(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
328+
| U64 | trace.replace_u64(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
329+
| U32 | trace.replace_u32(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
330+
| U16 | trace.replace_u16(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
331+
| U8 | trace.replace_u8(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
332+
| I64 | trace.replace_i64(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
333+
| I32 | trace.replace_i32(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
334+
| I16 | trace.replace_i16(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
335+
| I8 | trace.replace_i8(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
336+
| F64 | trace.replace_f64(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
337+
| F32 | trace.replace_f32(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
338+
| String'val | trace.replace_string(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
339+
| Bytes'val | trace.replace_bytes(@_ptr._get_at(i)) -> (v | @_ptr._assign_at(i, v))
340+
| String'box | trace.set_string -> (v | @_ptr._assign_at(i, v.clone))
341+
| Bytes'box | trace.set_bytes -> (v | @_ptr._assign_at(i, v.clone))
342+
| TraceData.Mutable | @_ptr._get_at(i).trace_data_mutable(trace)
343+
| trace.array_index_cannot_be_modified
344+
)
345+
| i == @size |
346+
// If it's just one element beyond the bounds of the array, allow the
347+
// mutator the option to set a new value to push onto the end.
348+
case A <: (
349+
| None | trace.set_none -> (v | @ << None)
350+
| Bool | trace.set_bool -> (v | @ << Bool[v])
351+
| U64 | trace.set_u64 -> (v | @ << U64[v])
352+
| U32 | trace.set_u32 -> (v | @ << U32[v])
353+
| U16 | trace.set_u16 -> (v | @ << U16[v])
354+
| U8 | trace.set_u8 -> (v | @ << U8[v])
355+
| I64 | trace.set_i64 -> (v | @ << I64[v])
356+
| I32 | trace.set_i32 -> (v | @ << I32[v])
357+
| I16 | trace.set_i16 -> (v | @ << I16[v])
358+
| I8 | trace.set_i8 -> (v | @ << I8[v])
359+
| F64 | trace.set_f64 -> (v | @ << F64[v])
360+
| F32 | trace.set_f32 -> (v | @ << F32[v])
361+
| String'val | trace.set_string -> (v | @ << v)
362+
| Bytes'val | trace.set_bytes -> (v | @ << v)
363+
| String'box | trace.set_string -> (v | @ << v.clone)
364+
| Bytes'box | trace.set_bytes -> (v | @ << v.clone)
365+
| TraceData.Mutable |
366+
if A <: _EmptyConstructableRef (
367+
// If the element is constructable with no arguments, that's the
368+
// only case where we can make a new one and push it onto the array.
369+
new = A.new
370+
@ << new
371+
new.trace_data_mutable(trace)
372+
|
373+
// Otherwise we can't mutate there.
374+
trace.array_index_is_invalid
375+
)
376+
|
377+
// If it's not an element type we can support, report that.
378+
trace.array_index_cannot_be_modified
379+
)
380+
|
381+
// If it's well beyond the bounds of the array, we can't mutate there.
382+
trace.array_index_is_invalid
383+
)
384+
)
385+
318386
:: Return a copy of the array that has its elements sorted by value.
319387
:: If the element type is not aliasable, or not Comparable, it will be empty.
320388

0 commit comments

Comments
 (0)