Skip to content

Commit 6c2faba

Browse files
authored
Add ByteArray support on Chez (#791)
1 parent 454c938 commit 6c2faba

File tree

5 files changed

+95
-11
lines changed

5 files changed

+95
-11
lines changed

effekt/jvm/src/test/scala/effekt/StdlibTests.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ class StdlibJavaScriptTests extends StdlibTests {
2222
abstract class StdlibChezTests extends StdlibTests {
2323
override def ignored: List[File] = List(
2424
// Not implemented yet
25-
examplesDir / "stdlib" / "bytearray",
2625
examplesDir / "stdlib" / "io",
2726
examplesDir / "stdlib" / "stream" / "characters.effekt",
2827
examplesDir / "stdlib" / "stream" / "fuse_newlines.effekt"
Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
Equal()
2+
Greater()
3+
Less()
4+
Equal()
5+
6+
Equal()
7+
Greater()
8+
Greater()
9+
210
Equal()
311
Greater()
4-
Less()
12+
Less()
13+
Equal()
14+
Equal()
15+
16+
Greater()
17+
Less()
18+
Greater()
19+
Less()
20+
21+
Less()
22+
Greater()
23+
Less()
24+
Greater()

examples/stdlib/bytearray/bytearray_compare.effekt

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,51 @@ module examples/pos/bytearray_compare
33
import bytearray
44

55
def main() = {
6-
val b1 = fromString("Hey")
7-
val b2 = fromString("Hey")
8-
val b3 = fromString("He")
9-
val b4 = fromString("Heys")
10-
println(compareByteArray(b1, b1))
11-
println(compareByteArray(b1, b2))
12-
println(compareByteArray(b1, b3))
13-
println(compareByteArray(b1, b4))
6+
val empty: ByteArray = "".fromString
7+
val zeros: ByteArray = bytearray::allocate(8)
8+
each(0, zeros.size) { i =>
9+
zeros.unsafeSet(i, 0.toByte)
10+
}
11+
val abcs: ByteArray = bytearray::allocate(8)
12+
each(0, abcs.size) { i =>
13+
abcs.unsafeSet(i, (97 + i).toByte)
14+
}
15+
16+
println(empty.compareByteArray(empty))
17+
println(zeros.compareByteArray(empty))
18+
println(empty.compareByteArray(zeros))
19+
println(zeros.compareByteArray(zeros))
20+
21+
println("")
22+
23+
println(abcs.compareByteArray(abcs))
24+
println(abcs.compareByteArray(zeros))
25+
println(abcs.compareByteArray(empty))
26+
27+
println("")
28+
29+
val hey1: ByteArray = "Hey".fromString
30+
val hey2: ByteArray = "Hey".fromString
31+
val he: ByteArray = "He".fromString
32+
val heys: ByteArray = "Heys".fromString
33+
34+
println(hey1.compareByteArray(hey1))
35+
println(hey1.compareByteArray(empty))
36+
println(empty.compareByteArray(hey1))
37+
println(hey1.compareByteArray(hey2))
38+
println(hey2.compareByteArray(hey1))
39+
40+
println("")
41+
42+
println(hey1.compareByteArray(he))
43+
println(he.compareByteArray(hey1))
44+
println(he.compareByteArray(empty))
45+
println(empty.compareByteArray(he))
46+
47+
println("")
48+
49+
println(hey1.compareByteArray(heys))
50+
println(heys.compareByteArray(hey1))
51+
println(he.compareByteArray(heys))
52+
println(heys.compareByteArray(he))
1453
}

libraries/common/bytearray.effekt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module bytearray
66
extern type ByteArray
77
// = llvm "%Pos"
88
// = js "Uint8Array"
9-
9+
// = chez "bytevector"
1010

1111
/// Allocates a new bytearray with the given `size`, its values are undefined.
1212
extern global def allocate(size: Int): ByteArray =
@@ -15,27 +15,31 @@ extern global def allocate(size: Int): ByteArray =
1515
%arr = call %Pos @c_bytearray_new(%Int ${size})
1616
ret %Pos %arr
1717
"""
18+
chez "(make-bytevector ${size})"
1819

1920
extern pure def size(arr: ByteArray): Int =
2021
js "${arr}.length"
2122
llvm """
2223
%size = call %Int @c_bytearray_size(%Pos ${arr})
2324
ret %Int %size
2425
"""
26+
chez "(bytevector-length ${arr})"
2527

2628
extern global def unsafeGet(arr: ByteArray, index: Int): Byte =
2729
js "(${arr})[${index}]"
2830
llvm """
2931
%byte = call %Byte @c_bytearray_get(%Pos ${arr}, %Int ${index})
3032
ret %Byte %byte
3133
"""
34+
chez "(bytevector-u8-ref ${arr} ${index})"
3235

3336
extern global def unsafeSet(arr: ByteArray, index: Int, value: Byte): Unit =
3437
js "bytearray$set(${arr}, ${index}, ${value})"
3538
llvm """
3639
%z = call %Pos @c_bytearray_set(%Pos ${arr}, %Int ${index}, %Byte ${value})
3740
ret %Pos %z
3841
"""
42+
chez "(bytevector-u8-set! ${arr} ${index} ${value})"
3943

4044
def resize(source: ByteArray, size: Int): ByteArray = {
4145
val target = allocate(size)
@@ -75,13 +79,15 @@ extern pure def fromString(str: String): ByteArray =
7579
llvm """
7680
ret %Pos ${str}
7781
"""
82+
chez "(string->utf8 ${str})"
7883

7984
extern pure def toString(arr: ByteArray): String =
8085
js "(new TextDecoder('utf-8').decode(${arr}))"
8186
// assuming the buffer is already in UTF-8
8287
llvm """
8388
ret %Pos ${arr}
8489
"""
90+
chez "(utf8->string ${arr})"
8591

8692
extern js """
8793
function bytearray$set(bytes, index, value) {
@@ -106,12 +112,29 @@ extern js """
106112
}
107113
"""
108114

115+
extern chez """
116+
(define (bytearray$compare b1 b2)
117+
(let ([len1 (bytevector-length b1)]
118+
[len2 (bytevector-length b2)]
119+
[minlen (min (bytevector-length b1) (bytevector-length b2))])
120+
(let loop ([i 0])
121+
(cond
122+
[(= i minlen)
123+
(cond [(< len1 len2) -1]
124+
[(> len1 len2) 1]
125+
[else 0])]
126+
[(< (bytevector-u8-ref b1 i) (bytevector-u8-ref b2 i)) -1]
127+
[(> (bytevector-u8-ref b1 i) (bytevector-u8-ref b2 i)) 1]
128+
[else (loop (+ i 1))]))))
129+
"""
130+
109131
extern pure def compareByteArrayImpl(b1: ByteArray, b2: ByteArray): Int =
110132
js "bytearray$compare(${b1}, ${b2})"
111133
llvm """
112134
%x = call %Int @c_bytearray_compare(%Pos ${b1}, %Pos ${b2})
113135
ret %Int %x
114136
"""
137+
chez "(bytearray$compare ${b1} ${b2})"
115138

116139
def compareByteArray(b1: ByteArray, b2: ByteArray): Ordering =
117140
compareByteArrayImpl(b1, b2) match {

libraries/common/effekt.effekt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ extern pure def show(value: Char): String =
9090

9191
extern pure def show(value: Byte): String =
9292
js "'' + ${value}"
93+
chez "(string ${value})"
9394
llvm """
9495
%z = call %Pos @c_bytearray_show_Byte(i8 ${value})
9596
ret %Pos %z
@@ -647,11 +648,13 @@ extern pure def bitwiseXor(x: Int, y: Int): Int =
647648
extern pure def toByte(n: Int): Byte =
648649
js "${n}"
649650
llvm "%z = trunc %Int ${n} to %Byte ret %Byte %z"
651+
chez "${n}"
650652

651653
extern pure def toInt(n: Byte): Int =
652654
js "${n}"
653655
llvm "%z = zext %Byte ${n} to %Int ret %Int %z"
654656
vm "effekt::toInt(Byte)"
657+
chez "${n}"
655658

656659

657660
// Undefined and Null

0 commit comments

Comments
 (0)