This seems quite messy. And also a bit prone to error as well. I think it would make more sense to support the following symbols for asserting max length.
Assert length
MAX_LENGTH
- Maximum bit_length of the serialized definition.
MIN_LENGTH
- Minimum bit_length for the serialized defintiion.
@assert MAX_LENGTH <= 400*8
# Definition here
or to assert that a type is statically sized
@assert MAX_LENGTH == MIN_LENGTH
# Defintion here
Aligned
If we want to make sure things are aligned we should do so with primitives that relates to alignment. With the following directives @align <offset?>
we can express alignment in an ergonomic way even in situations where it was previously not possible (e.g. right after a dynamically sized field).
uint2 data1
@align -5 # Aligns to end
uint5 data2
@align # Due to last datatype being aligned to end, does nothing
uint7[<=1] data3
@align end # equals to `@align [ - bit_length(uint7) ]`
uint7 data4
@align data # equals to `@align [- log(1)]`
uint8[<=1] data5
Examples
Your example would then look like the following
@assert MAX_LENGTH == MIN_LENGTH
@assert MAX_LENGTH ==8*17
uint7 node_id
@align
uint8[16] unique_id
The other example would be
@assert MAX_LENGTH <= 8*400
uint7 node_id
@align data
uint8[<=16] unique_id