Skip to content

Commit

Permalink
Merge pull request #463 from savi-lang/change/macro-precedence
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Macros now have weaker parsing precedence.
  • Loading branch information
jemc committed Jun 17, 2023
2 parents d463d42 + 7dafb72 commit 200238d
Show file tree
Hide file tree
Showing 53 changed files with 583 additions and 532 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ clean: PHONY
rm -rf $(BUILD) $(MAKE_VAR_CACHE) lib/libsavi_runtime

# Run the full test suite.
spec.all: PHONY spec.self-hosted.all spec.compiler.all spec.language spec.core spec.unit.all spec.integration.all
spec.all: PHONY spec.compiler.all spec.language spec.core spec.unit.all spec.integration.all
# TODO: spec.all: PHONY spec.self-hosted.all spec.compiler.all spec.language spec.core spec.unit.all spec.integration.all

# Run the specs that are written in markdown (mostly compiler pass tests).
# Run the given compiler-spec target (or all targets).
Expand Down
68 changes: 34 additions & 34 deletions core/Array.savi
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@

:new (space USize = 0)
@_size = 0
if (space > 0) (@_ptr_allocate(space) | @_ptr_set_null)
if space > 0 (@_ptr_allocate(space) | @_ptr_set_null)

:new iso new_iso(space USize = 0) // TODO: use recover instead of this hack
@_size = 0
if (space > 0) (@_ptr_allocate(space) | @_ptr_set_null)
if space > 0 (@_ptr_allocate(space) | @_ptr_set_null)

:fun size: @_size
:fun space: @_space
Expand All @@ -43,7 +43,7 @@
from = from.at_most(to)
size = to - from

space = if (to == @_size) (
space = if to == @_size (
// If our new final address lines up with the current final address,
// then we can keep any extra bytes allocated beyond the current size.
// We'll only trim off the left side.
Expand All @@ -54,7 +54,7 @@
size
)

ptr = if (space == 0) (
ptr = if space == 0 (
// If the new allocation space is zero, use a null pointer to avoid issue.
CPointer(A)._null
|
Expand All @@ -69,7 +69,7 @@
from = from.at_most(to)
size = to - from

if (to == @_size) (
if to == @_size (
// If our new final address lines up with the current final address,
// then we can keep any extra bytes allocated beyond the current size.
// We'll only trim off the left side.
Expand All @@ -82,7 +82,7 @@

@_size = size

if (@_space == 0) (
if @_space == 0 (
// If the new allocation space is zero, use a null pointer to avoid issue.
@_ptr = CPointer(A)._null
|
Expand All @@ -96,7 +96,7 @@
:: The size (number of actual elements present in the array) does not change.

:fun ref reserve(space USize)
if (@_space < space) \
if @_space < space \
@_ptr_reallocate(space)
@

Expand All @@ -106,7 +106,7 @@
:: if the element type isn't aliasable, the cloned array will be empty.

:fun clone @'iso
if (A <: alias) (
if A <: alias (
array = @new_iso(@size)
_ptr_tag CPointer(A)'tag = @_ptr // TODO: this indirection shouldn't be needed
array._clone_from(_ptr_tag, @size)
Expand All @@ -120,15 +120,15 @@
other_ptr._unsafe._copy_to(@_ptr, size)

:fun "[]!"(index) @->(A'aliased)
if (@size <= index) error!
if @size <= index error!
@_ptr._get_at(index)

:fun ref "[]=!"(index, value)
if (@size <= index) error!
if @size <= index error!
@_ptr._assign_at(index, --value)

:fun ref "[]<<=!"(index, value)
if (@size <= index) error!
if @size <= index error!
@_ptr._displace_at(index, --value)

:fun ref "<<"(value): @push(--value)
Expand All @@ -145,13 +145,13 @@
:: Return the first element in the array.
:: Raises an error if the array is empty.
:fun first! @->(A'aliased)
error! if (@size == 0)
error! if @size == 0
@_ptr._get_at(0)

:: Assign the given value to replace the first element in the array.
:: Raises an error if the array is empty.
:fun ref "first=!"(value A)
error! if (@size == 0)
error! if @size == 0
@_ptr._assign_at(0, --value)

:: Return the last element in the array.
Expand All @@ -170,8 +170,8 @@
// value/identity instead of structural equality (e.g. Array(U8))
equal_so_far = (@size == other.size)
index USize = 0
while (equal_so_far && index < @_size) (
equal_so_far = if (A <: Equatable(A)'read) (
while equal_so_far && index < @_size (
equal_so_far = if A <: Equatable(A)'read (
@_ptr._get_at(index) == other._ptr._get_at(index)
|
@_ptr._get_at(index) === other._ptr._get_at(index)
Expand All @@ -182,7 +182,7 @@

:fun ref replace_at!(index)
:yields A for A
error! if (@size <= index)
error! if @size <= index

new_value = yield @_ptr._get_at_no_alias(index)
new_value_alias = new_value
Expand All @@ -197,13 +197,13 @@
:: Elements at all later indexes will be shifted one index to make room
:: for the insertion of the new element.
:fun ref insert_at!(index, value)
error! if (@_size < index)
error! if @_size < index

// Make sure the buffer is large enough to hold another element.
@reserve(@_size + 1)

// Copy the tail of later elements forward, to make room for the element.
if (@_size > index) (
if @_size > index (
tail_size = @size - index
@_ptr._offset(index)._copy_to(@_ptr._offset(index + 1), tail_size)
)
Expand All @@ -222,10 +222,10 @@
::
:: If you want to return the removed element, use `remove_at!` instead.
:fun ref delete_at!(index)
error! if (@size <= index)
error! if @size <= index
tail_size = @size - index - 1

if (tail_size > 0) (
if tail_size > 0 (
@_ptr._offset(index + 1)._copy_to(@_ptr._offset(index), tail_size)
)

Expand All @@ -240,11 +240,11 @@
::
:: If you want to discard the removed element, use `delete_at!` instead.
:fun ref remove_at!(index) A
error! if (@size <= index)
error! if @size <= index
element = @_ptr._get_at_no_alias(index)
tail_size = @size - index - 1

if (tail_size > 0) (
if tail_size > 0 (
@_ptr._offset(index + 1)._copy_to(@_ptr._offset(index), tail_size)
)

Expand All @@ -257,7 +257,7 @@
stride USize = 1
)
index = from
while (index < to.at_most(@_size)) (
while index < to.at_most(@_size) (
yield (@_ptr._get_at(index), index)
index += stride
)
Expand All @@ -270,7 +270,7 @@
)
try (
index USize = from.at_most(@_size) -! 1
while (index >= to) (
while index >= to (
yield (@_ptr._get_at(index), index)
index = index.at_most(@_size) -! stride
)
Expand All @@ -290,8 +290,8 @@
// False
is_found = False
index USize = 0
while (!is_found && index < @_size) (
is_found = if (A <: Equatable(A)'read) (
while !is_found && index < @_size (
is_found = if A <: Equatable(A)'read (
@_ptr._get_at(index) == expected
|
@_ptr._get_at(index) === expected
Expand Down Expand Up @@ -329,13 +329,13 @@
if @_sort_in_place(0, @size.isize - 1) (@ | @clear)

:fun ref _sort_in_place(lo_pivot ISize, hi_pivot ISize) Bool // TODO: should be actually private
if (A <: Comparable(A)'read) (
if (lo_pivot < hi_pivot) (
if A <: Comparable(A)'read (
if lo_pivot < hi_pivot (
// Choose the outermost elements as pivots, ensuring that the higher
// of the two is on the right, swapping to make it so if needed.
lo_pivot_value = @_ptr._get_at(lo_pivot.usize)
hi_pivot_value = @_ptr._get_at(hi_pivot.usize)
if (lo_pivot_value > hi_pivot_value) (
if lo_pivot_value > hi_pivot_value (
@_ptr._assign_at(lo_pivot.usize, hi_pivot_value)
@_ptr._assign_at(hi_pivot.usize, lo_pivot_value)
lo_pivot_value = @_ptr._get_at(lo_pivot.usize)
Expand All @@ -350,7 +350,7 @@
scan = lo

// Scan the range, swapping as necessary.
while (scan <= hi) (scan_value = @_ptr._get_at(scan.usize)
while scan <= hi (scan_value = @_ptr._get_at(scan.usize)
case (
// When we scan a value less than our pivot, swap the value downward.
| scan_value < lo_pivot_value |
Expand All @@ -360,7 +360,7 @@
// When we scan a value greater than our pivot, swap the value upward.
| scan_value >= hi_pivot_value |
// First move `hi` cursor until it's greater than the `hi_pivot`.
while (@_ptr._get_at(hi.usize) > hi_pivot_value && scan < hi) (
while @_ptr._get_at(hi.usize) > hi_pivot_value && scan < hi (
hi -= 1
)

Expand All @@ -371,7 +371,7 @@
// Possibly swap the just-swapped value downward if it needs to be.
// Note that `scan_value` here is the previous `hi` value.
scan_value = @_ptr._get_at(scan.usize)
if (scan_value < lo_pivot_value) (
if scan_value < lo_pivot_value (
@_ptr_swap(scan.usize, lo.usize) // TODO: these swap operations can be optimized by leveraging earlier pointer reads, though it will be more verbose
lo += 1
)
Expand All @@ -398,8 +398,8 @@
)

:fun ref swap!(index_1, index_2)
error! if (@size <= index_1)
error! if (@size <= index_2)
error! if @size <= index_1
error! if @size <= index_2
@_ptr_swap(index_1, index_2)

:fun ref _ptr_swap(index_1 USize, index_2 USize)
Expand Down
28 changes: 14 additions & 14 deletions core/BitArray.savi
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@

:new (space USize = 0)
@_size = 0
if (space > 0) (@_ptr_allocate(space) | @_ptr_set_null)
if space > 0 (@_ptr_allocate(space) | @_ptr_set_null)

:new iso new_iso(space USize = 0) // TODO: use recover instead of this hack
@_size = 0
if (space > 0) (@_ptr_allocate(space) | @_ptr_set_null)
if space > 0 (@_ptr_allocate(space) | @_ptr_set_null)

:fun size: @_size
:fun space: @_space
Expand All @@ -70,7 +70,7 @@
:: Reserve enough total space for the given number of bits.
:: The size (number of actual bits present in the array) does not change.
:fun ref reserve(space USize)
if (@_space < space) @_ptr_reallocate(space)
if @_space < space @_ptr_reallocate(space)
@

:: Create a clone of this bit array, containing all of the same bit values.
Expand All @@ -92,15 +92,15 @@
Array(U64).val_from_cpointer(@_ptr._unsafe, @_u64_space, @_u64_space)

:fun "[]!"(index)
error! if (@size <= index)
error! if @size <= index
@_ptr_get_at(index)

:fun ref "[]=!"(index, value)
error! if (@size <= index)
error! if @size <= index
@_ptr_assign_at(index, value)

:fun ref "[]<<=!"(index, value)
error! if (@size <= index)
error! if @size <= index
@_ptr_displace_at(index, value)

:fun ref "<<"(value): @push(value)
Expand All @@ -117,13 +117,13 @@
:: Return the first bit in the bit array.
:: Raises an error if the bit array is empty.
:fun first!
error! if (@size == 0)
error! if @size == 0
@_ptr._get_at(0)

:: AssigU64 the given value to replace the first bit in the bit array.
:: Raises an error if the bit array is empty.
:fun ref "first=!"(value)
error! if (@size == 0)
error! if @size == 0
@_ptr._assign_at(0, value)

:: Return the last bit in the bit array.
Expand All @@ -147,7 +147,7 @@
)
to = @_size.at_most(to)
index = from
while (index < to.at_most(@_size)) (
while index < to.at_most(@_size) (
yield (@_ptr_get_at(index), index)
index += stride
)
Expand All @@ -160,16 +160,16 @@
)
try (
index USize = from.at_most(@_size) -! 1
while (index >= to) (
while index >= to (
yield (@_ptr_get_at(index), index)
index = index.at_most(@_size) -! stride
)
)
None

:fun ref swap!(index_1, index_2)
error! if (@size <= index_1)
error! if (@size <= index_2)
error! if @size <= index_1
error! if @size <= index_2
@_ptr_swap(index_1, index_2)

:fun ref _ptr_swap(index_1 USize, index_2 USize)
Expand All @@ -189,14 +189,14 @@
:: in that last bit index position should now check it at its new position,
:: which is the bit index that had its value deleted by this operation.
:fun ref delete_by_moving_last!(index)
error! if (index >= @_size)
error! if index >= @_size

// The number of bits will decrease by one.
@_size -= 1

// If the index we wanted to remove was the last index,
// there's nothing left to do - it was removed by changing the size.
return if (index == @_size)
return if index == @_size

// Otherwise we need to grab the value from the last index
// and assign it to the position of the value we are deleting.
Expand Down
2 changes: 1 addition & 1 deletion core/Bytes.Format.savi
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
:fun _emit_ascii(out String'ref, byte_address USize) None
try (
byte = @_value[byte_address]!
if (byte > 0x20 && byte < 0x7f) (
if byte > 0x20 && byte < 0x7f (
out.push_byte(byte)
|
out.push_byte('.')
Expand Down
Loading

0 comments on commit 200238d

Please sign in to comment.