September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,55 @@
# String creation
x = "hello world"
# String destruction
x = nil
# String assignment with a null byte
x = "a\0b"
IO.inspect x #=> <<97, 0, 98>>
IO.puts String.length(x) #=> 3
# string comparison
if x == "hello" do
IO.puts "equal"
else
IO.puts "not equal" #=> not equal
end
y = "bc"
if x < y do
IO.puts "#{x} is lexicographically less than #{y}" #=> a b is lexicographically less than bc
end
# string cloning
xx = x
IO.puts x == xx #=> true same length and content)
# check if empty
if x=="" do
IO.puts "is empty"
end
if String.length(x)==0 do
IO.puts "is empty"
end
# append a byte
IO.puts x <> "\07" #=> a b 7
IO.inspect x <> "\07" #=> <<97, 0, 98, 0, 55>>
# substring
IO.puts String.slice("elixir", 1..3) #=> lix
IO.puts String.slice("elixir", 2, 3) #=> ixi
# replace bytes
IO.puts String.replace("a,b,c", ",", "-") #=> a-b-c
# string interpolation
a = "abc"
n = 100
IO.puts "#{a} : #{n}" #=> abc : 100
# join strings
a = "hel"
b = "lo w"
c = "orld"
IO.puts a <> b <> c #=> hello world

View file

@ -0,0 +1,90 @@
class ByteString(private val bytes: ByteArray) : Comparable<ByteString> {
val length get() = bytes.size
fun isEmpty() = bytes.isEmpty()
operator fun plus(other: ByteString): ByteString = ByteString(bytes + other.bytes)
operator fun plus(byte: Byte) = ByteString(bytes + byte)
operator fun get(index: Int): Byte {
require (index in 0 until length)
return bytes[index]
}
fun toByteArray() = bytes
fun copy() = ByteString(bytes.copyOf())
override fun compareTo(other: ByteString) = this.toString().compareTo(other.toString())
override fun equals(other: Any?): Boolean {
if (other == null || other !is ByteString) return false
return compareTo(other) == 0
}
override fun hashCode() = this.toString().hashCode()
fun substring(startIndex: Int) = ByteString(bytes.sliceArray(startIndex until length))
fun substring(startIndex: Int, endIndex: Int) =
ByteString(bytes.sliceArray(startIndex until endIndex))
fun replace(oldByte: Byte, newByte: Byte): ByteString {
val ba = ByteArray(length) { if (bytes[it] == oldByte) newByte else bytes[it] }
return ByteString(ba)
}
fun replace(oldValue: ByteString, newValue: ByteString) =
this.toString().replace(oldValue.toString(), newValue.toString()).toByteString()
override fun toString(): String {
val chars = CharArray(length)
for (i in 0 until length) {
chars[i] = when (bytes[i]) {
in 0..127 -> bytes[i].toChar()
else -> (256 + bytes[i]).toChar()
}
}
return chars.joinToString("")
}
}
fun String.toByteString(): ByteString {
val bytes = ByteArray(this.length)
for (i in 0 until this.length) {
bytes[i] = when (this[i].toInt()) {
in 0..127 -> this[i].toByte()
in 128..255 -> (this[i] - 256).toByte()
else -> '?'.toByte() // say
}
}
return ByteString(bytes)
}
/* property to be used as an abbreviation for String.toByteString() */
val String.bs get() = this.toByteString()
fun main(args: Array<String>) {
val ba = byteArrayOf(65, 66, 67)
val ba2 = byteArrayOf(68, 69, 70)
val bs = ByteString(ba)
val bs2 = ByteString(ba2)
val bs3 = bs + bs2
val bs4 = "GHI£€".toByteString()
println("The length of $bs is ${bs.length}")
println("$bs + $bs2 = $bs3")
println("$bs + D = ${bs + 68}")
println("$bs == ABC is ${bs == bs.copy()}")
println("$bs != ABC is ${bs != bs.copy()}")
println("$bs >= $bs2 is ${bs > bs2}")
println("$bs <= $bs2 is ${bs < bs2}")
println("$bs is ${if (bs.isEmpty()) "empty" else "not empty"}")
println("ABC[1] = ${bs[1].toChar()}")
println("ABC as a byte array is ${bs.toByteArray().contentToString()}")
println("ABCDEF(1..5) = ${bs3.substring(1)}")
println("ABCDEF(2..4) = ${bs3.substring(2,5)}")
println("ABCDEF with C replaced by G is ${bs3.replace(67, 71)}")
println("ABCDEF with CD replaced by GH is ${bs3.replace("CD".bs, "GH".bs)}")
println("GHI£€ as a ByteString is $bs4")
}

View file

@ -1,5 +1,4 @@
# Perl 6 is perfectly fine with NUL *characters* in strings:
my Str $s = 'nema' ~ 0.chr ~ 'problema!';
say $s;
@ -10,9 +9,9 @@ my Str $str = "My God, it's full of chars!";
my Buf $buf = Buf.new(255, 0, 1, 2, 3);
say $buf;
# Strs can be encoded into Bufs …
my Buf $this = 'foo'.encode('ascii');
# … and Bufs can be decoded into Strs …
# Strs can be encoded into Blobs …
my Blob $this = 'round-trip'.encode('ascii');
# … and Blobs can be decoded into Strs …
my Str $that = $this.decode('ascii');
# So it's all there. Nevertheless, let's solve this task explicitly
@ -23,7 +22,7 @@ class ByteStr {
# … that keeps an array of bytes, and we delegate some
# straight-forward stuff directly to this attribute:
# (Note: "has byte @.bytes" would be nicer, but that is
# not yet implemented in rakudo or niecza.)
# not yet implemented in Rakudo.)
has Int @.bytes handles(< Bool elems gist push >);
# A handful of methods …
@ -43,11 +42,11 @@ class ByteStr {
# A couple of operators for our new type:
multi infix:<cmp>(ByteStr $x, ByteStr $y) { $x.bytes cmp $y.bytes }
multi infix:<~> (ByteStr $x, ByteStr $y) { ByteStr.new(:bytes($x.bytes, $y.bytes)) }
multi infix:<~> (ByteStr $x, ByteStr $y) { ByteStr.new(:bytes(|$x.bytes, |$y.bytes)) }
# create some byte strings (destruction not needed due to garbage collection)
my ByteStr $b0 = ByteStr.new;
my ByteStr $b1 = ByteStr.new(:bytes( 'foo'.ords, 0, 10, 'bar'.ords ));
my ByteStr $b1 = ByteStr.new(:bytes( |'foo'.ords, 0, 10, |'bar'.ords ));
# assignment ($b1 and $b2 contain the same ByteStr object afterwards):
my ByteStr $b2 = $b1;
@ -69,14 +68,15 @@ say 'b1 is ', $b1 ?? 'not empty' !! 'empty';
# appending a byte:
$b1.push: 123;
say 'appended = ', $b1;
# extracting a substring:
my $sub = $b1.substr(2, 4);
say 'sub = ', $sub;
say 'substr = ', $sub;
# replacing a byte:
$b2.replace(102 => 103);
say $b2;
say 'replaced = ', $b2;
# joining:
my ByteStr $b3 = $b1 ~ $sub;

View file

@ -0,0 +1,21 @@
Data(0,.Int,1,2,3) // bytes
Data(0,String,1,2,3) // same
Data(0,Int,"foo","bar") //-->foobar\0
d:=Data(0,String,"foo","bar") //-->foo\0bar\0\0
d==d // -->True: byte by byte comparison
d.copy() //-->clone
d.len() //-->8, 0 if empty
d.append("1").len(); //-->10 // or d+"1"
Data(0,Int,"foo","bar").len() //-->6
Data(0,Int,"foo","bar").append("1").len() //-->7
d.readString(4) //-->"bar"
d.readNthString(2) //-->"1"
d[2,4] //-->"o", really "o\0ba" but String sees the null
while(Void!=(n:=d.findString("bar"))){ d[n,4]="hoho" }
d.bytes() //-->L(102,111,111,0,104,111,104,111,0,49,0)
d2:=Data(0,Int,"sam");
d.append(d2).text // or d+d2