Skip to content

Commit

Permalink
Support nested bitstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-phillips committed Aug 24, 2024
1 parent e1d7971 commit 1f2df36
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/compiler/internal/generator/expressions.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,18 @@ fn generate_bitstring_segment_option(
python.SizeValueOption(expression) ->
generate_expression(expression)
|> string_builder.prepend("\"SizeValue\", ")

python.UnitOption(integer) ->
integer
|> int.to_string
|> string_builder.from_string
|> string_builder.prepend("\"Unit\", ")

python.FloatOption -> string_builder.from_string("\"Float\", None")
python.BigOption -> string_builder.from_string("\"Big\", None")
python.LittleOption -> string_builder.from_string("\"Little\", None")
python.NativeOption -> string_builder.from_string("\"Native\", None")
python.BitStringOption -> string_builder.from_string("\"BitString\", None")
}
|> string_builder.prepend("(")
|> string_builder.append(")")
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/internal/transformer/statements.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,9 @@ fn fold_bitsting_segment_option(
glance.BigOption -> internal.map_state_prepend(state, python.BigOption)
glance.NativeOption ->
internal.map_state_prepend(state, python.NativeOption)
glance.BitStringOption ->
internal.map_state_prepend(state, python.BitStringOption)

glance.UnitOption(size) ->
internal.map_state_prepend(state, python.UnitOption(size))
glance.SizeOption(size) ->
Expand All @@ -570,9 +573,11 @@ fn fold_bitsting_segment_option(
python.SizeValueOption,
)
}

glance.SignedOption | glance.UnsignedOption -> {
panic as "Signed and unsigned are not valid when constructing bitstrings"
}

_ -> {
pprint.debug(option)
todo as "Some bitstring segment options not supported yet"
Expand Down
1 change: 1 addition & 0 deletions src/compiler/python.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub type BitStringSegmentOption {
FloatOption
LittleOption
BigOption
BitStringOption
NativeOption
}

Expand Down
14 changes: 11 additions & 3 deletions src/python_prelude.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ def gleam_bitstring_segment_to_bytes(segment) -> bytes:
endianness = sys.byteorder
case('Float', None):
type = 'float'
case('Integer', None):
type = 'int'
case('BitString', None):
type = 'bitstring'
case _:
raise Exception(f'Unexpected bitstring option {option}')
Expand All @@ -85,13 +89,15 @@ def gleam_bitstring_segment_to_bytes(segment) -> bytes:
size = 8
case 'float':
size = 64
case 'bitstring':
size = len(value)
if unit == None:
match type:
case 'int':
unit = 1
case 'float':
case 'int' | 'float':
unit = 1
case 'bitstring':
unit = 8
bitsize = unit * size
if bitsize % 8:
Expand All @@ -118,6 +124,8 @@ def gleam_bitstring_segment_to_bytes(segment) -> bytes:
case _:
raise Exception('bitstring floats must be 32 or 64 bits')
return struct.pack(f'{order}{fmt}', value)
case 'bitstring':
return value
raise Exception('Unexpected bitstring encountered')
"
Expand Down
18 changes: 18 additions & 0 deletions test/bitstring_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,21 @@ def main():
return gleam_bitstring_segments_to_bytes((64.888889, [(\"SizeValue\", 32), (\"Float\", None)]))",
)
}

pub fn bitstring_test() {
// TODO: Pretty sure this should be :bits, not :bit_string,
// but glance has a bug:
// https://github.com/lpil/glance/issues/22
"pub fn main() {
<<<<3>>:bit_string>>
}
"
|> compiler.compile
|> should.be_ok
|> should.equal(
"from gleam_builtins import *
def main():
return gleam_bitstring_segments_to_bytes((gleam_bitstring_segments_to_bytes((3, [])), [(\"BitString\", None)]))",
)
}

0 comments on commit 1f2df36

Please sign in to comment.