It looks like the use of the method `is_tty` in Nit tools triggered the FFI compilation of the `posix` module which fails on Windows. This module imports some headers that are unavailable in the msys2 environment, as used by our test servers.
Pull-Request: #2711
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
# Interpreter for Brainfuck source code.
class BFInterpreter
# Data cells
- var dr = new Array[Byte]
+ var dr = new Array[Int]
# Data pointer
var dp = 0
# Instruction pointer
# Create an interpreter for `program`.
init do
- dr.add 0u8
+ dr.add 0
end
# Create an interpreter for the file located at `path`.
# Evaluates the current instruction
fun eval do
var instr = program[ip]
- if instr == '.'.ascii then printn dr[dp].ascii
- if instr == '['.ascii then
- if dr[dp] == 0u8 then
+ if instr == u'.' then printn dr[dp].code_point
+ if instr == u'[' then
+ if dr[dp] == 0 then
ip = find_matching_rbra
return
end
end
- if instr == ']'.ascii then
- if dr[dp] != 0u8 then
+ if instr == u']' then
+ if dr[dp] != 0 then
ip = find_matching_lbra
return
end
end
- if instr == '>'.ascii then
+ if instr == u'>' then
dp += 1
- if dp >= dr.length then dr.add(0u8)
+ if dp >= dr.length then dr.add(0)
end
- if instr == '<'.ascii then
+ if instr == u'<' then
dp -= 1
if dp < 0 then abort
end
- if instr == '+'.ascii then
- dr[dp] = dr[dp] + 1u8
+ if instr == u'+' then
+ dr[dp] = dr[dp] + 1
end
- if instr == '-'.ascii then
- dr[dp] = dr[dp] - 1u8
+ if instr == u'-' then
+ dr[dp] = dr[dp] - 1
end
- if instr == ','.ascii then
- dr[dp] = getc.ascii
+ if instr == u',' then
+ dr[dp] = getc.code_point
end
end
var lbracnt = 0
loop
if pos > program.length then abort
- if program[pos] == ']'.ascii then
+ if program[pos] == u']' then
if lbracnt > 0 then
lbracnt -= 1
else
break
end
end
- if program[pos] == '['.ascii then lbracnt += 1
+ if program[pos] == u'[' then lbracnt += 1
pos += 1
end
return pos
var rbracnt = 0
loop
if pos < 0 then abort
- if program[pos] == '['.ascii then
+ if program[pos] == u'[' then
if rbracnt > 0 then
rbracnt -= 1
else
break
end
end
- if program[pos] == ']'.ascii then rbracnt += 1
+ if program[pos] == u']' then rbracnt += 1
pos -= 1
end
return pos
if sp >= string_len then
dfa_state = -1
else
- var c = string[sp].ascii
+ var c = string[sp].code_point
sp += 1
var cr = _cr
while sys.stdin.poll_in do
if sys.stdin.eof then return
var c = sys.stdin.read_char
- if c == 'q'.ascii then
+ if c == u'q' then
self.exists = false
return
end
continue
end
- out.add(((c.ascii + key[j].ascii - 2u8 * 'A'.ascii) % 26u8 + 'A'.ascii).ascii)
+ out.add(((c.code_point + key[j].code_point - 2 * u'A') % 26 + u'A').code_point)
j = (j + 1) % key.length
end
continue
end
- out.add(((c.ascii - key[j].ascii + 26u8) % 26u8 + 'A'.ascii).ascii)
+ out.add(((c.code_point - key[j].code_point + 26) % 26 + u'A').code_point)
j = (j + 1) % key.length
end
return res ^-1
end
- fun put_line(y: Int, line: Array[Byte]) do
- for i in [0..line.length[ do line[i] = get_byte(i * 8, y).to_b
+ fun put_line(y: Int, line: Array[Int]) do
+ for i in [0..line.length[ do line[i] = get_byte(i * 8, y)
end
fun work do
redef class Sys
var n = 0
var inv_n: Float is noautoinit
- var data: Array[Array[Byte]] is noautoinit
+ var data: Array[Array[Int]] is noautoinit
var crb: Array[Float] is noautoinit
var cib: Array[Float] is noautoinit
var atomic = new AtomicInt(0)
sys.cib[i] = i.to_f * inv_n - 1.0
sys.crb[i] = i.to_f * inv_n - 1.5
end
-sys.data = new Array[Array[Byte]].with_capacity(n)
-for i in [0..n[ do sys.data[i] = new Array[Byte].filled_with(0.to_b, (n) / 8)
+sys.data = new Array[Array[Int]].with_capacity(n)
+for i in [0..n[ do sys.data[i] = new Array[Int].filled_with(0, (n) / 8)
# Parallel Approach
var actors = new Array[Worker]
# Is `self` a valid Base64 character ?
fun is_base64_char: Bool do
if code_point >= 127 then return false
- return ascii.is_base64_char
+ return code_point.is_base64_char
end
end
-redef class Byte
+redef class Int
# Is `self` a valid Base64 character ?
fun is_base64_char: Bool do
- if self == b'+' then return true
- if self == b'/' then return true
- if self > b'Z' then
- if self < b'a' then return false
- if self <= b'z' then return true
+ if self == u'+' then return true
+ if self == u'/' then return true
+ if self > u'Z' then
+ if self < u'a' then return false
+ if self <= u'z' then return true
return false
end
- if self >= b'A' then return true
- if self <= b'9' and self >= b'0' then return true
+ if self >= u'A' then return true
+ if self <= u'9' and self >= u'0' then return true
return false
end
# Returns the `base64` equivalent of `self`
#
# REQUIRE `self`.`is_base64_char`
- fun to_base64_char: Byte do
- if self == b'+' then return 62u8
- if self == b'/' then return 63u8
- if self > b'Z' then
- if self < b'a' then abort
- if self <= b'z' then return self - 71u8
+ fun to_base64_char: Int do
+ if self == u'+' then return 62
+ if self == u'/' then return 63
+ if self > u'Z' then
+ if self < u'a' then abort
+ if self <= u'z' then return self - 71
abort
end
- if self >= b'A' then return self - 0x41u8
- if self <= b'9' and self >= b'0' then return self + 4u8
+ if self >= u'A' then return self - 0x41
+ if self <= u'9' and self >= u'0' then return self + 4
abort
end
end
var in_off = 0
for s in [0 .. steps[ do
- var ind = ((self[in_off] & 0b1111_1100u8) >> 2).to_i
+ var ind = (self[in_off] & 0b1111_1100) >> 2
result.add base64_bytes[ind]
- ind = ((self[in_off] & 0b0000_0011u8) << 4).to_i | ((self[in_off + 1] & 0b1111_0000u8) >> 4).to_i
+ ind = ((self[in_off] & 0b0000_0011) << 4) | ((self[in_off + 1] & 0b1111_0000) >> 4)
result.add base64_bytes[ind]
- ind = ((self[in_off + 1] & 0b0000_1111u8) << 2).to_i | ((self[in_off + 2] & 0b1100_0000u8) >> 6).to_i
+ ind = ((self[in_off + 1] & 0b0000_1111) << 2) | ((self[in_off + 2] & 0b1100_0000) >> 6)
result.add base64_bytes[ind]
- ind = (self[in_off + 2] & 0b0011_1111u8).to_i
+ ind = (self[in_off + 2] & 0b0011_1111)
result.add base64_bytes[ind]
in_off += 3
end
if bytes_in_last_step == 1 then
- result.add base64_bytes[((self[in_off] & 0b1111_1100u8) >> 2).to_i]
- result.add base64_bytes[((self[in_off] & 0b0000_0011u8) << 4).to_i]
+ result.add base64_bytes[(self[in_off] & 0b1111_1100) >> 2]
+ result.add base64_bytes[(self[in_off] & 0b0000_0011) << 4]
else if bytes_in_last_step == 2 then
- result.add base64_bytes[((self[in_off] & 0b1111_1100u8) >> 2).to_i]
- result.add base64_bytes[(((self[in_off] & 0b0000_0011u8) << 4) | ((self[in_off + 1] & 0b1111_0000u8) >> 4)).to_i]
- result.add base64_bytes[((self[in_off + 1] & 0b0000_1111u8) << 2).to_i]
+ result.add base64_bytes[(self[in_off] & 0b1111_1100) >> 2]
+ result.add base64_bytes[((self[in_off] & 0b0000_0011) << 4) | ((self[in_off + 1] & 0b1111_0000) >> 4)]
+ result.add base64_bytes[(self[in_off + 1] & 0b0000_1111) << 2]
end
var rempad = if bytes_in_last_step > 0 then 3 - bytes_in_last_step else 0
- for i in [0 .. rempad[ do result.add b'='
+ for i in [0 .. rempad[ do result.add u'='
return result
end
if length == 0 then return new Bytes.empty
# Avoids constant unboxing
- var pad = b'='
+ var pad = '='
var result = new Bytes.with_capacity((length / 4 + 1) * 3)
break
end
# Ignore whitespaces
- if b <= 0x20u8 then continue
+ if b <= 0x20 then continue
if not b.is_base64_char then continue
curr <<= 6
curr += b.to_base64_char.to_i
cnt += 1
if cnt == 4 then
- result.add(((curr & 0xFF0000) >> 16).to_b)
- result.add(((curr & 0xFF00) >> 8).to_b)
- result.add((curr & 0xFF).to_b)
+ result.add ((curr & 0xFF0000) >> 16)
+ result.add ((curr & 0xFF00) >> 8)
+ result.add (curr & 0xFF)
curr = 0
cnt = 0
end
var pads = 0
for i in [endpos .. length[ do
var b = self[i]
- if b <= 0x20u8 then continue
+ if b <= 0x20 then continue
pads += 1
end
if cnt == 2 then
curr >>= 4
- result.add(curr.to_b)
+ result.add(curr)
else if cnt == 3 then
curr >>= 2
- result.add(((curr & 0xFF00) >> 8).to_b)
- result.add((curr & 0xFF).to_b)
+ result.add ((curr & 0xFF00) >> 8)
+ result.add (curr & 0xFF)
end
end
return result
var rlen = 0
var opos = length
for i in [0 .. length[ do
- if self[i] == b'=' then
+ if self[i] == u'=' then
opos = i
break
end
if self[i].is_whitespace then continue
- if not self[i].is_base64_char then return new Error("Invalid Base64 character at position {i}: {self[i].ascii}")
+ if not self[i].is_base64_char then return new Error("Invalid Base64 character at position {i}: {self[i].code_point}")
rlen += 1
if rlen > 4 then rlen -= 4
end
var pad = 0
for i in [opos .. length[ do
if self[i].is_whitespace then continue
- if self[i] != b'=' then return new Error("Invalid padding character {self[i].ascii} at position {i}")
+ if self[i] != u'=' then return new Error("Invalid padding character {self[i].code_point} at position {i}")
pad += 1
end
if rlen + pad != 4 then return new Error("Invalid padding length")
# var w = new FileWriter.open("/tmp/data.bin")
# w.write "hello"
# w.write_int64 123456789
-# w.write_byte 3u8
+# w.write_byte 3
# w.write_float 1.25
# w.write_double 1.234567
# w.write_bits(true, false, true)
super BinaryStream
# Write a boolean `value` on a byte, using 0 for `false` and 1 for `true`
- fun write_bool(value: Bool) do write_byte if value then 1u8 else 0u8
+ fun write_bool(value: Bool) do write_byte if value then 1 else 0
# Write up to 8 `Bool` in a byte
#
do
assert bits.length <= 8
- var int = 0u8
+ var int = 0
for b in bits.length.times do
- if bits[b] then int |= 1u8 << (7 - b)
+ if bits[b] then int |= 1 << (7 - b)
end
write_byte int
fun write_string(text: Text)
do
write text
- write_byte 0x00u8
+ write_byte 0x00
end
# Write the length as a 64 bits integer, then the content of `text`
if byte <= 0 then
return buf.to_s
end
- buf.add byte.to_b
+ buf.add byte
end
end
redef class Int
# Utility for `BinaryWriter`
- private fun int64_byte_at(index: Int, big_endian: Bool): Byte `{
+ private fun int64_byte_at(index: Int, big_endian: Bool): Int `{
union {
unsigned char bytes[8];
int64_t val;
redef class Float
# Utility for `BinaryWriter`
- private fun float_byte_at(index: Int, big_endian: Bool): Byte `{
+ private fun float_byte_at(index: Int, big_endian: Bool): Int `{
union {
unsigned char bytes[4];
float val;
`}
# Utility for `BinaryWriter`
- private fun double_byte_at(index: Int, big_endian: Bool): Byte `{
+ private fun double_byte_at(index: Int, big_endian: Bool): Int `{
union {
unsigned char bytes[8];
double val;
# Any kind of entity which can be searched for in a Sequence of Byte
interface BytePattern
# Return the first occurence of `self` in `b`, or -1 if not found
- fun first_index_in(b: SequenceRead[Byte]): Int do return first_index_in_from(b, 0)
+ fun first_index_in(b: SequenceRead[Int]): Int do return first_index_in_from(b, 0)
# Return the first occurence of `self` in `b` starting at `from`, or -1 if not found
- fun first_index_in_from(b: SequenceRead[Byte], from: Int): Int is abstract
+ fun first_index_in_from(b: SequenceRead[Int], from: Int): Int is abstract
# Return the last occurence of `self` in `b`, or -1 if not found
- fun last_index_in(b: SequenceRead[Byte]): Int do return last_index_in_from(b, b.length - 1)
+ fun last_index_in(b: SequenceRead[Int]): Int do return last_index_in_from(b, b.length - 1)
# Return the last occurence of `self` in `b`, or -1 if not found
- fun last_index_in_from(b: SequenceRead[Byte], from: Int): Int is abstract
+ fun last_index_in_from(b: SequenceRead[Int], from: Int): Int is abstract
# Returns the indexes of all the occurences of `self` in `b`
- fun search_all_in(b: SequenceRead[Byte]): SequenceRead[Int] is abstract
+ fun search_all_in(b: SequenceRead[Int]): SequenceRead[Int] is abstract
# Length of the pattern
fun pattern_length: Int is abstract
# Appends `self` to `b`
- fun append_to(b: Sequence[Byte]) is abstract
+ fun append_to(b: Sequence[Int]) is abstract
# Is `self` a prefix for `b` ?
- fun is_prefix(b: SequenceRead[Byte]): Bool is abstract
+ fun is_prefix(b: SequenceRead[Int]): Bool is abstract
# Is `self` a suffix for `b` ?
- fun is_suffix(b: SequenceRead[Byte]): Bool is abstract
+ fun is_suffix(b: SequenceRead[Int]): Bool is abstract
end
-redef class Byte
+redef class Int
super BytePattern
# Write self as a string into `ns` at position `pos`
private fun add_digest_at(ns: CString, pos: Int) do
- var tmp = (0xF0u8 & self) >> 4
- ns[pos] = if tmp >= 0x0Au8 then tmp + 0x37u8 else tmp + 0x30u8
- tmp = 0x0Fu8 & self
- ns[pos + 1] = if tmp >= 0x0Au8 then tmp + 0x37u8 else tmp + 0x30u8
+ var tmp = (0xF0 & self) >> 4
+ ns[pos] = if tmp >= 0x0A then tmp + 0x37 else tmp + 0x30
+ tmp = 0x0F & self
+ ns[pos + 1] = if tmp >= 0x0A then tmp + 0x37 else tmp + 0x30
end
# Is `self` a valid hexadecimal digit (in ASCII)
#
# ~~~nit
# intrude import core::bytes
- # assert not '/'.ascii.is_valid_hexdigit
- # assert '0'.ascii.is_valid_hexdigit
- # assert '9'.ascii.is_valid_hexdigit
- # assert not ':'.ascii.is_valid_hexdigit
- # assert not '@'.ascii.is_valid_hexdigit
- # assert 'A'.ascii.is_valid_hexdigit
- # assert 'F'.ascii.is_valid_hexdigit
- # assert not 'G'.ascii.is_valid_hexdigit
- # assert not '`'.ascii.is_valid_hexdigit
- # assert 'a'.ascii.is_valid_hexdigit
- # assert 'f'.ascii.is_valid_hexdigit
- # assert not 'g'.ascii.is_valid_hexdigit
+ # assert not u'/'.is_valid_hexdigit
+ # assert u'0'.is_valid_hexdigit
+ # assert u'9'.is_valid_hexdigit
+ # assert not u':'.is_valid_hexdigit
+ # assert not u'@'.is_valid_hexdigit
+ # assert u'A'.is_valid_hexdigit
+ # assert u'F'.is_valid_hexdigit
+ # assert not u'G'.is_valid_hexdigit
+ # assert not u'`'.is_valid_hexdigit
+ # assert u'a'.is_valid_hexdigit
+ # assert u'f'.is_valid_hexdigit
+ # assert not u'g'.is_valid_hexdigit
# ~~~
private fun is_valid_hexdigit: Bool do
- return (self >= 0x30u8 and self <= 0x39u8) or
- (self >= 0x41u8 and self <= 0x46u8) or
- (self >= 0x61u8 and self <= 0x66u8)
+ return (self >= 0x30 and self <= 0x39) or
+ (self >= 0x41 and self <= 0x46) or
+ (self >= 0x61 and self <= 0x66)
end
# `self` as a hexdigit to its byte value
#
# ~~~nit
# intrude import core::bytes
- # assert 0x39u8.hexdigit_to_byteval == 0x09u8
- # assert 0x43u8.hexdigit_to_byteval == 0x0Cu8
+ # assert 0x39.hexdigit_to_byteval == 0x09
+ # assert 0x43.hexdigit_to_byteval == 0x0C
# ~~~
#
# REQUIRE: `self.is_valid_hexdigit`
- private fun hexdigit_to_byteval: Byte do
- if self >= 0x30u8 and self <= 0x39u8 then
- return self - 0x30u8
- else if self >= 0x41u8 and self <= 0x46u8 then
- return self - 0x37u8
- else if self >= 0x61u8 and self <= 0x66u8 then
- return self - 0x57u8
+ private fun hexdigit_to_byteval: Int do
+ if self >= 0x30 and self <= 0x39 then
+ return self - 0x30
+ else if self >= 0x41 and self <= 0x46 then
+ return self - 0x37
+ else if self >= 0x61 and self <= 0x66 then
+ return self - 0x57
end
# Happens only if the requirement is not met.
# i.e. this abort is here to please the compiler
redef fun append_to(b) do b.push self
- # assert 'b'.ascii.is_suffix("baqsdb".to_bytes)
- # assert not 'b'.ascii.is_suffix("baqsd".to_bytes)
+ # assert u'b'.is_suffix("baqsdb".to_bytes)
+ # assert not u'b'.is_suffix("baqsd".to_bytes)
redef fun is_suffix(b) do return b.length != 0 and b.last == self
- # assert 'b'.ascii.is_prefix("baqsdb".to_bytes)
- # assert not 'b'.ascii.is_prefix("aqsdb".to_bytes)
+ # assert u'b'.is_prefix("baqsdb".to_bytes)
+ # assert not u'b'.is_prefix("aqsdb".to_bytes)
redef fun is_prefix(b) do return b.length != 0 and b.first == self
+
+ # A signed big-endian representation of `self`
+ #
+ # ~~~
+ # assert 1.to_bytes.hexdigest == "01"
+ # assert 255.to_bytes.hexdigest == "FF"
+ # assert 256.to_bytes.hexdigest == "0100"
+ # assert 65535.to_bytes.hexdigest == "FFFF"
+ # assert 65536.to_bytes.hexdigest == "010000"
+ # ~~~
+ #
+ # Negative values are converted to their two's complement.
+ # Be careful as the result can be ambiguous.
+ #
+ # ~~~
+ # assert (-1).to_bytes.hexdigest == "FF"
+ # assert (-32).to_bytes.hexdigest == "E0"
+ # assert (-512).to_bytes.hexdigest == "FE00"
+ # assert (-65794).to_bytes.hexdigest == "FEFEFE"
+ # ~~~
+ #
+ # Optionally, set `n_bytes` to the desired number of bytes in the output.
+ # This setting can disambiguate the result between positive and negative
+ # integers. Be careful with this parameter as the result may overflow.
+ #
+ # ~~~
+ # assert 1.to_bytes(2).hexdigest == "0001"
+ # assert 65535.to_bytes(2).hexdigest == "FFFF"
+ # assert (-1).to_bytes(2).hexdigest == "FFFF"
+ # assert (-512).to_bytes(4).hexdigest == "FFFFFE00"
+ # assert 0x123456.to_bytes(2).hexdigest == "3456"
+ # ~~~
+ #
+ # For 0, a Bytes object with single nul byte is returned (instead of an empty Bytes object).
+ #
+ # ~~~
+ # assert 0.to_bytes.hexdigest == "00"
+ # ~~~
+ #
+ # For positive integers, `Bytes::to_i` can reverse the operation.
+ #
+ # ~~~
+ # assert 1234.to_bytes.to_i == 1234
+ # ~~~
+ #
+ # Require self >= 0
+ fun to_bytes(n_bytes: nullable Int): Bytes do
+
+ # If 0, force using at least one byte
+ if self == 0 and n_bytes == null then n_bytes = 1
+
+ # Compute the len (log256)
+ var len = 1
+ var max = 256
+ var s = self.abs
+ while s >= max do
+ len += 1
+ max *= 256
+ end
+
+ # Two's complement
+ s = self
+ if self < 0 then
+ var ff = 0
+ for j in [0..len[ do
+ ff *= 0x100
+ ff += 0xFF
+ end
+
+ s = ((-self) ^ ff) + 1
+ end
+
+ # Cut long values
+ if n_bytes != null and len > n_bytes then len = n_bytes
+
+ # Allocate the buffer
+ var cap = n_bytes or else len
+ var res = new Bytes.with_capacity(cap)
+
+ var filler = if self < 0 then 0xFF else 0
+ for i in [0..cap[ do res[i] = filler
+
+ # Fill it starting with the end
+ var i = cap
+ var sum = s
+ while i > cap - len do
+ i -= 1
+ res[i] = sum % 256
+ sum /= 256
+ end
+
+ return res
+ end
end
# A buffer containing Byte-manipulation facilities
#
# Uses Copy-On-Write when persisted
class Bytes
- super AbstractArray[Byte]
+ super AbstractArray[Int]
super BytePattern
# A CString being a char*, it can be used as underlying representation here.
redef fun is_empty do return length == 0
# var b = new Bytes.empty
- # b.add 101u8
- # assert b[0] == 101u8
+ # b.add 101
+ # assert b[0] == 101
redef fun [](i) do
assert i >= 0
assert i < length
fun trim: Bytes do
var st = 0
while st < length do
- if self[st] > 0x20u8 then break
+ if self[st] > 0x20 then break
st += 1
end
if st >= length then return new Bytes.empty
var ed = length - 1
while ed > 0 do
- if self[ed] > 0x20u8 then break
+ if self[ed] > 0x20 then break
ed -= 1
end
return slice(st, ed - st + 1)
var i = 0
var oi = 0
while i < length do
- ns[oi] = 0x5Cu8 # b'\\'
- ns[oi+1] = 0x78u8 # b'x'
+ ns[oi] = u'\\'
+ ns[oi+1] = u'x'
self[i].add_digest_at(ns, oi+2)
i += 1
oi += 4
var oi = 0
while i < length do
var c = self[i]
- var b = 128u8
- while b > 0u8 do
- if c & b == 0u8 then
- ns[oi] = 0x30u8 # b'0'
+ var b = 128
+ while b > 0 do
+ if c & b == 0 then
+ ns[oi] = u'0'
else
- ns[oi] = 0x31u8 # b'1'
+ ns[oi] = u'1'
end
oi += 1
b = b >> 1
end
# Two's complement is `signed`
- if signed == true and not_empty and first > 0x80u8 then
+ if signed == true and not_empty and first > 0x80 then
var ff = 0
for j in [0..length[ do
ff *= 0x100
end
# var b = new Bytes.with_capacity(1)
- # b[0] = 101u8
+ # b[0] = 101
# assert b.to_s == "e"
redef fun []=(i, v) do
if persisted then regen
end
# var b = new Bytes.empty
- # b.add 101u8
+ # b.add 101
# assert b.to_s == "e"
redef fun add(c) do
if persisted then regen
end
# var b = new Bytes.empty
- # b.append([104u8, 101u8, 108u8, 108u8, 111u8])
+ # b.append([104, 101, 108, 108, 111])
# assert b.to_s == "hello"
redef fun append(arr) do
if arr isa Bytes then
end
# var b = new Bytes.empty
- # b.append([0x41u8, 0x41u8, 0x18u8])
+ # b.append([0x41, 0x41, 0x18])
# b.pop
# assert b.to_s == "AA"
redef fun pop do
# Splits the content on self when encountering `b`
#
- # var a = "String is string".to_bytes.split_with('s'.ascii)
+ # var a = "String is string".to_bytes.split_with(u's')
# assert a.length == 3
# assert a[0].hexdigest == "537472696E672069"
# assert a[1].hexdigest == "20"
# Splits `self` in two parts at the first occurence of `b`
#
- # var a = "String is string".to_bytes.split_once_on('s'.ascii)
+ # var a = "String is string".to_bytes.split_once_on(u's')
# assert a[0].hexdigest == "537472696E672069"
# assert a[1].hexdigest == "20737472696E67"
fun split_once_on(b: BytePattern): Array[Bytes] do
# Replaces all the occurences of `this` in `self` by `by`
#
- # var b = "String is string".to_bytes.replace(0x20u8, 0x41u8)
+ # var b = "String is string".to_bytes.replace(0x20, 0x41)
# assert b.hexdigest == "537472696E6741697341737472696E67"
fun replace(pattern: BytePattern, bytes: BytePattern): Bytes do
if is_empty then return new Bytes.empty
var pos = 0
while pos < length do
var b = self[pos]
- if b != '%'.ascii then
+ if b != u'%' then
tmp.add b
pos += 1
continue
end
if length - pos < 2 then
- tmp.add '%'.ascii
+ tmp.add u'%'
pos += 1
continue
end
var bn = self[pos + 1]
var bnn = self[pos + 2]
if not bn.is_valid_hexdigit or not bnn.is_valid_hexdigit then
- tmp.add '%'.ascii
+ tmp.add u'%'
pos += 1
continue
end
end
private class BytesIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
var tgt: CString
redef fun item do return tgt[index]
end
-redef class Int
- # A signed big-endian representation of `self`
- #
- # ~~~
- # assert 1.to_bytes.hexdigest == "01"
- # assert 255.to_bytes.hexdigest == "FF"
- # assert 256.to_bytes.hexdigest == "0100"
- # assert 65535.to_bytes.hexdigest == "FFFF"
- # assert 65536.to_bytes.hexdigest == "010000"
- # ~~~
- #
- # Negative values are converted to their two's complement.
- # Be careful as the result can be ambiguous.
- #
- # ~~~
- # assert (-1).to_bytes.hexdigest == "FF"
- # assert (-32).to_bytes.hexdigest == "E0"
- # assert (-512).to_bytes.hexdigest == "FE00"
- # assert (-65794).to_bytes.hexdigest == "FEFEFE"
- # ~~~
- #
- # Optionally, set `n_bytes` to the desired number of bytes in the output.
- # This setting can disambiguate the result between positive and negative
- # integers. Be careful with this parameter as the result may overflow.
- #
- # ~~~
- # assert 1.to_bytes(2).hexdigest == "0001"
- # assert 65535.to_bytes(2).hexdigest == "FFFF"
- # assert (-1).to_bytes(2).hexdigest == "FFFF"
- # assert (-512).to_bytes(4).hexdigest == "FFFFFE00"
- # assert 0x123456.to_bytes(2).hexdigest == "3456"
- # ~~~
- #
- # For 0, a Bytes object with single nul byte is returned (instead of an empty Bytes object).
- #
- # ~~~
- # assert 0.to_bytes.hexdigest == "00"
- # ~~~
- #
- # For positive integers, `Bytes::to_i` can reverse the operation.
- #
- # ~~~
- # assert 1234.to_bytes.to_i == 1234
- # ~~~
- #
- # Require self >= 0
- fun to_bytes(n_bytes: nullable Int): Bytes do
-
- # If 0, force using at least one byte
- if self == 0 and n_bytes == null then n_bytes = 1
-
- # Compute the len (log256)
- var len = 1
- var max = 256
- var s = self.abs
- while s >= max do
- len += 1
- max *= 256
- end
-
- # Two's complement
- s = self
- if self < 0 then
- var ff = 0
- for j in [0..len[ do
- ff *= 0x100
- ff += 0xFF
- end
-
- s = ((-self) ^ ff) + 1
- end
-
- # Cut long values
- if n_bytes != null and len > n_bytes then len = n_bytes
-
- # Allocate the buffer
- var cap = n_bytes or else len
- var res = new Bytes.with_capacity(cap)
-
- var filler = if self < 0 then 0xFFu8 else 0u8
- for i in [0..cap[ do res[i] = filler
-
- # Fill it starting with the end
- var i = cap
- var sum = s
- while i > cap - len do
- i -= 1
- res[i] = (sum % 256).to_b
- sum /= 256
- end
-
- return res
- end
-end
-
redef class Text
# Returns a mutable copy of `self`'s bytes
#
# ~~~nit
# assert "String".to_bytes isa Bytes
- # assert "String".to_bytes == [83u8, 116u8, 114u8, 105u8, 110u8, 103u8]
+ # assert "String".to_bytes == [83, 116, 114, 105, 110, 103]
# ~~~
fun to_bytes: Bytes do
var b = new Bytes.with_capacity(byte_length)
# Returns a new `Bytes` instance with the digest as content
#
- # assert "0B1F4D".hexdigest_to_bytes == [0x0Bu8, 0x1Fu8, 0x4Du8]
+ # assert "0B1F4D".hexdigest_to_bytes == [0x0B, 0x1F, 0x4D]
# assert "0B1F4D".hexdigest_to_bytes.hexdigest == "0B1F4D"
#
# Characters that are not hexadecimal digits are ignored.
var ret = new Bytes.with_capacity((dlength+1) / 2)
var i = (dlength+1) % 2 # current hex digit (1=high, 0=low)
- var byte = 0u8 # current accumulated byte value
+ var byte = 0 # current accumulated byte value
pos = 0
while pos < max do
# Last digit known: store and restart
ret.add byte
i = 1
- byte = 0u8
+ byte = 0
end
end
pos += 1
else if c == 'x' or c == 'X' then
var hx = substring(i + 1, 2)
if hx.is_hex then
- res.add(hx.to_hex.to_b)
+ res.add hx.to_hex
else
res.add_char(c)
end
while pos < max do
var c = b[pos]
pos += 1
- if c == 0x30u8 or c == 0x31u8 then bitlen += 1 # b'0' or b'1'
+ if c == u'0' or c == u'1' then bitlen += 1
end
# Allocate (and take care of the padding)
var ret = new Bytes.with_capacity((bitlen+7) / 8)
var i = (bitlen+7) % 8 # current bit (7th=128, 0th=1)
- var byte = 0u8 # current accumulated byte value
+ var byte = 0 # current accumulated byte value
pos = 0
while pos < max do
var c = b[pos]
pos += 1
- if c == 0x30u8 then # b'0'
+ if c == u'0' then
byte = byte << 1
- else if c == 0x31u8 then # b'1'
- byte = byte << 1 | 1u8
+ else if c == u'1' then
+ byte = byte << 1 | 1
else
continue
end
# Last bit known: store and restart
ret.add byte
i = 7
- byte = 0u8
+ byte = 0
end
end
return ret
# Joins an array of bytes `arr` separated by `sep`
#
-# assert join_bytes(["String".to_bytes, "is".to_bytes, "string".to_bytes], ' '.ascii).hexdigest == "537472696E6720697320737472696E67"
+# assert join_bytes(["String".to_bytes, "is".to_bytes, "string".to_bytes], u' ').hexdigest == "537472696E6720697320737472696E67"
fun join_bytes(arr: Array[Bytes], sep: nullable BytePattern): Bytes do
if arr.is_empty then return new Bytes.empty
sep = sep or else new Bytes.empty
redef fun add_char_to(c, stream) do
var cp = if c.code_point <= 255 then c else '?'
- stream[0] = cp.ascii
+ stream[0] = cp.code_point
return 1
end
for i in s.chars do
var cp = i.code_point
if cp <= 255 then
- b[pos] = cp.to_b
+ b[pos] = cp
else
- b[pos] = 0x3Fu8
+ b[pos] = 0x3F
end
pos += 1
end
redef fun is_valid_char(ns, len) do
if len == 0 then return 2
if not ns[0].is_valid_utf8_start then return 2
- for i in [1 .. len[ do if ns[i] & 0b1100_0000u8 != 0b1000_0000u8 then return 2
+ for i in [1 .. len[ do if ns[i] & 0b1100_0000 != 0b1000_0000 then return 2
if len != ns[0].u8len then return 1
return 0
end
var p = last_byte
var c = its[p]
var st = _first_byte
- while p >= st and c != '.'.ascii do
+ while p >= st and c != u'.' do
p -= 1
c = its[p]
end
var l = s.last_byte
var its = s._items
var min = s._first_byte
- var sl = '/'.ascii
+ var sl = u'/'
while l > min and its[l] == sl do l -= 1
if l == min then return "/"
var ns = l
return (long)res;
`}
- fun write_byte(value: Byte): Int `{
+ fun write_byte(value: Int): Int `{
unsigned char b = (unsigned char)value;
return fwrite(&b, 1, 1, self);
`}
redef fun to_i32 is intern
redef fun to_u32 is intern
- # Returns `self` as a Char according to its ASCII value.
- fun ascii: Char `{ return (uint32_t)self; `}
-
redef fun distance(i) do return (self - i).to_i
redef fun <=>(other)
redef fun *(i) is intern
redef fun /(i) is intern
- # Returns `self` as a Char according to its ASCII value.
- fun ascii: Char `{ return (uint32_t)self; `}
-
# Modulo of `self` with `i`.
#
# Returns the remainder of division of `self` by `i`.
redef fun zero do return 0.to_u16
redef fun value_of(val) do return val.to_u16
- # Returns `self` as a Char according to its ASCII value.
- fun ascii: Char `{ return (uint32_t)self; `}
-
# `i` bits shift to the left
#
# assert 5u16 << 1 == 10u16
redef fun *(i) is intern
redef fun /(i) is intern
- # Returns `self` as a Char according to its ASCII value.
- fun ascii: Char `{ return (uint32_t)self; `}
-
# Modulo of `self` with `i`.
#
# Returns the remainder of division of `self` by `i`.
redef fun *(i) is intern
redef fun /(i) is intern
- # Returns `self` as a Char according to its ASCII value.
- fun ascii: Char `{ return (uint32_t)self; `}
-
# Modulo of `self` with `i`.
#
# Returns the remainder of division of `self` by `i`.
# assert 5u8 >> 1 == 2u8
fun >>(i: Int): Byte is intern `{ return self >> i; `}
- # Returns the character equivalent of `self`
- #
- # REQUIRE: `self <= 127u8`
- fun ascii: Char is intern `{ return (uint32_t)self; `}
-
redef fun to_i is intern
redef fun to_f is intern
redef fun to_b do return self
# assert 10.abs == 10
# assert 0.abs == 0
fun abs: Int do return if self >= 0 then self else -self
+
+ # Is `self` an ASCII whitespace ?
+ fun is_whitespace: Bool do return self == 0x7F or self <= 0x20
end
# Native characters.
end
end
- # The ascii value of `self`
- #
- # assert 'a'.ascii == 97u8
- # assert '\n'.ascii == 10u8
- #
- # REQUIRE: `is_ascii`
- fun ascii: Byte do return code_point.to_b
-
# The unicode code point value of `self`
#
# assert 'A'.code_point == 65
for i in [0 .. max[ do
var b = raw_read_byte
if b < 0 then break
- buf[i] = b.to_b
+ buf[i] = b
rd += 1
end
return rd
fun write(s: Text) is abstract
# Write a single byte
- fun write_byte(value: Byte) is abstract
+ fun write_byte(value: Int) is abstract
# Write a single char
fun write_char(c: Char) do
#
# writer.write "Strings "
# writer.write_char '&'
-# writer.write_byte 0x20u8
+# writer.write_byte 0x20
# writer.write_bytes "bytes".to_bytes
#
# assert writer.to_s == "\\x53\\x74\\x72\\x69\\x6E\\x67\\x73\\x20\\x26\\x20\\x62\\x79\\x74\\x65\\x73"
# writer = new BytesWriter
#
# # Write just the character first half
-# writer.write_byte 0xC2u8
+# writer.write_byte 0xC2
# assert writer.to_s == "\\xC2"
# assert writer.bytes.to_s == "�"
#
# # Complete the character
-# writer.write_byte 0xA2u8
+# writer.write_byte 0xA2
# assert writer.to_s == "\\xC2\\xA2"
# assert writer.bytes.to_s == "¢"
# ~~~
#
# writer.write "Strings "
# writer.write_char '&'
-# writer.write_byte 0x20u8
+# writer.write_byte 0x20
# writer.write_bytes "bytes".to_bytes
#
# assert writer.to_s == "Strings & bytes"
# Gets a view on the bytes of the Text object
#
# ~~~
- # assert "hello".bytes.to_a == [104u8, 101u8, 108u8, 108u8, 111u8]
+ # assert "hello".bytes.to_a == [104, 101, 108, 108, 111]
# ~~~
- fun bytes: SequenceRead[Byte] is abstract
+ fun bytes: SequenceRead[Int] is abstract
# Number of characters contained in self.
#
else if c == ':' or c == ' ' or c == '#' then
b.add('\\')
b.add(c)
- else if c.code_point < 32 or c == ';' or c == '|' or c == '\\' or c == '=' then
+ else if c.code_point < 32 or c == ';' or c == '|' or c == '\\' then
b.append("?{c.code_point.to_base(16)}")
else
b.add(c)
if c == '%' then
if i + 2 >= length then
# What follows % has been cut off
- buf[l] = '%'.ascii
+ buf[l] = u'%'
else
i += 1
var hex_s = substring(i, 2)
if hex_s.is_hex then
var hex_i = hex_s.to_hex
- buf[l] = hex_i.to_b
+ buf[l] = hex_i
i += 1
else
# What follows a % is not Hex
- buf[l] = '%'.ascii
+ buf[l] = u'%'
i -= 1
end
end
- else buf[l] = c.ascii
+ else buf[l] = c.code_point
i += 1
l += 1
# Abstract class for the SequenceRead compatible
# views on the bytes of any Text
private abstract class StringByteView
- super SequenceRead[Byte]
+ super SequenceRead[Int]
type SELFTYPE: Text
redef fun to_s do
var nslen = byte_to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_byte_to_s(ns, nslen + 1)
return ns.to_s_unsafe(nslen, copy=false, clean=false)
end
# Returns a sequence with the UTF-8 bytes of `self`
#
# ~~~
- # assert 'a'.bytes == [0x61u8]
- # assert 'ま'.bytes == [0xE3u8, 0x81u8, 0xBEu8]
+ # assert 'a'.bytes == [0x61]
+ # assert 'ま'.bytes == [0xE3, 0x81, 0xBE]
# ~~~
- fun bytes: SequenceRead[Byte] do return to_s.bytes
+ fun bytes: SequenceRead[Int] do return to_s.bytes
# Is `self` an UTF-16 surrogate pair ?
fun is_surrogate: Bool do
redef fun to_s do
var nslen = to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_to_s(ns, nslen + 1)
return ns.to_s_unsafe(nslen, copy=false)
end
redef fun to_s do
var nslen = to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_to_s(ns, nslen + 1)
return ns.to_s_unsafe(nslen, copy=false)
end
redef fun to_s do
var nslen = to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_to_s(ns, nslen + 1)
return ns.to_s_unsafe(nslen, copy=false)
end
redef fun to_s do
var nslen = to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_to_s(ns, nslen + 1)
return ns.to_s_unsafe(nslen, copy=false)
end
redef fun to_s do
var nslen = to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_to_s(ns, nslen + 1)
return ns.to_s_unsafe(nslen, copy=false)
end
var its = _items
if dpos == 1 then
- if its[b] & 0x80u8 == 0x00u8 then
+ if its[b] & 0x80 == 0x00 then
b += 1
else
b += its.length_of_char_at(b)
var endlen = 0
while pos <= max do
var c = its[pos]
- if c == b'<' then
+ if c == u'<' then
endlen += 3
- else if c == b'>' then
+ else if c == u'>' then
endlen += 3
- else if c == b'&' then
+ else if c == u'&' then
endlen += 4
- else if c == b'"' then
+ else if c == u'"' then
endlen += 4
- else if c == b'\'' then
+ else if c == u'\'' then
endlen += 4
- else if c == 0x2Fu8 then
+ else if c == 0x2F then
endlen += 4
end
pos += 1
# Special codes:
# Some HTML characters are used as meta-data, they need
# to be replaced by an HTML-Escaped equivalent
- if c == b'<' then
- nits[outpos] = b'&'
- nits[outpos + 1] = b'l'
- nits[outpos + 2] = b't'
- nits[outpos + 3] = b';'
+ if c == u'<' then
+ nits[outpos] = u'&'
+ nits[outpos + 1] = u'l'
+ nits[outpos + 2] = u't'
+ nits[outpos + 3] = u';'
outpos += 4
- else if c == b'>' then
- nits[outpos] = b'&'
- nits[outpos + 1] = b'g'
- nits[outpos + 2] = b't'
- nits[outpos + 3] = b';'
+ else if c == u'>' then
+ nits[outpos] = u'&'
+ nits[outpos + 1] = u'g'
+ nits[outpos + 2] = u't'
+ nits[outpos + 3] = u';'
outpos += 4
- else if c == b'&' then
- nits[outpos] = b'&'
- nits[outpos + 1] = b'a'
- nits[outpos + 2] = b'm'
- nits[outpos + 3] = b'p'
- nits[outpos + 4] = b';'
+ else if c == u'&' then
+ nits[outpos] = u'&'
+ nits[outpos + 1] = u'a'
+ nits[outpos + 2] = u'm'
+ nits[outpos + 3] = u'p'
+ nits[outpos + 4] = u';'
outpos += 5
- else if c == b'"' then
- nits[outpos] = b'&'
- nits[outpos + 1] = b'#'
- nits[outpos + 2] = b'3'
- nits[outpos + 3] = b'4'
- nits[outpos + 4] = b';'
+ else if c == u'"' then
+ nits[outpos] = u'&'
+ nits[outpos + 1] = u'#'
+ nits[outpos + 2] = u'3'
+ nits[outpos + 3] = u'4'
+ nits[outpos + 4] = u';'
outpos += 5
- else if c == b'\'' then
- nits[outpos] = b'&'
- nits[outpos + 1] = b'#'
- nits[outpos + 2] = b'3'
- nits[outpos + 3] = b'9'
- nits[outpos + 4] = b';'
+ else if c == u'\'' then
+ nits[outpos] = u'&'
+ nits[outpos + 1] = u'#'
+ nits[outpos + 2] = u'3'
+ nits[outpos + 3] = u'9'
+ nits[outpos + 4] = u';'
outpos += 5
- else if c == 0x2Fu8 then
- nits[outpos] = b'&'
- nits[outpos + 1] = b'#'
- nits[outpos + 2] = b'4'
- nits[outpos + 3] = b'7'
- nits[outpos + 4] = b';'
+ else if c == u'/' then
+ nits[outpos] = u'&'
+ nits[outpos + 1] = u'#'
+ nits[outpos + 2] = u'4'
+ nits[outpos + 3] = u'7'
+ nits[outpos + 4] = u';'
outpos += 5
else
nits[outpos] = c
var req_esc = 0
while pos <= max do
var c = its[pos]
- if c == b'\n' then
+ if c == u'\n' then
req_esc += 1
- else if c == b'\t' then
+ else if c == u'\t' then
req_esc += 1
- else if c == b'"' then
+ else if c == u'"' then
req_esc += 1
- else if c == b'\'' then
+ else if c == u'\'' then
req_esc += 1
- else if c == b'\\' then
+ else if c == u'\\' then
req_esc += 1
- else if c == 0x3Fu8 then
+ else if c == u'?' then
var j = pos + 1
if j < length then
var next = its[j]
# We ignore `??'` because it will be escaped as `??\'`.
if
- next == 0x21u8 or
- next == 0x28u8 or
- next == 0x29u8 or
- next == 0x2Du8 or
- next == 0x2Fu8 or
- next == 0x3Cu8 or
- next == 0x3Du8 or
- next == 0x3Eu8
+ next == 0x21 or
+ next == 0x28 or
+ next == 0x29 or
+ next == 0x2D or
+ next == 0x2F or
+ next == 0x3C or
+ next == 0x3D or
+ next == 0x3E
then req_esc += 1
end
- else if c < 32u8 then
+ else if c < 32 then
req_esc += 3
end
pos += 1
# * 0x22 => \"
# * 0x27 => \'
# * 0x5C => \\
- if c == b'\t' then
- nns[opos] = b'\\'
- nns[opos + 1] = b't'
+ if c == u'\t' then
+ nns[opos] = u'\\'
+ nns[opos + 1] = u't'
opos += 2
- else if c == b'\n' then
- nns[opos] = b'\\'
- nns[opos + 1] = b'n'
+ else if c == u'\n' then
+ nns[opos] = u'\\'
+ nns[opos + 1] = u'n'
opos += 2
- else if c == b'"' then
- nns[opos] = b'\\'
- nns[opos + 1] = b'"'
+ else if c == u'"' then
+ nns[opos] = u'\\'
+ nns[opos + 1] = u'"'
opos += 2
- else if c == b'\'' then
- nns[opos] = b'\\'
- nns[opos + 1] = b'\''
+ else if c == u'\'' then
+ nns[opos] = u'\\'
+ nns[opos + 1] = u'\''
opos += 2
- else if c == b'\\' then
- nns[opos] = b'\\'
- nns[opos + 1] = b'\\'
+ else if c == u'\\' then
+ nns[opos] = u'\\'
+ nns[opos + 1] = u'\\'
opos += 2
- else if c == 0x3Fu8 then
+ else if c == u'?' then
var j = pos + 1
if j < length then
var next = its[j]
# We ignore `??'` because it will be escaped as `??\'`.
if
- next == 0x21u8 or
- next == 0x28u8 or
- next == 0x29u8 or
- next == 0x2Du8 or
- next == 0x2Fu8 or
- next == 0x3Cu8 or
- next == 0x3Du8 or
- next == 0x3Eu8
+ next == 0x21 or
+ next == 0x28 or
+ next == 0x29 or
+ next == 0x2D or
+ next == 0x2F or
+ next == 0x3C or
+ next == 0x3D or
+ next == 0x3E
then
- nns[opos] = 0x5Cu8
+ nns[opos] = 0x5C
opos += 1
end
end
- nns[opos] = 0x3Fu8
+ nns[opos] = 0x3F
opos += 1
- else if c < 32u8 then
- nns[opos] = b'\\'
- nns[opos + 1] = b'0'
- nns[opos + 2] = ((c & 0x38u8) >> 3) + b'0'
- nns[opos + 3] = (c & 0x07u8) + b'0'
+ else if c < 32 then
+ nns[opos] = u'\\'
+ nns[opos + 1] = u'0'
+ nns[opos + 2] = ((c & 0x38) >> 3) + u'0'
+ nns[opos + 3] = (c & 0x07) + u'0'
opos += 4
else
nns[opos] = c
if dpos == 1 and index < len - 1 then
var its = _items
var c = its[b]
- if c & 0x80u8 == 0x00u8 then
+ if c & 0x80 == 0x00 then
# We want the next, and current is easy.
# So next is easy to find!
b += 1
else if dpos == -1 and index > 1 then
var its = _items
var c = its[b-1]
- if c & 0x80u8 == 0x00u8 then
+ if c & 0x80 == 0x00 then
# We want the previous, and it is easy.
b -= 1
dpos = 0
_position = index
_bytepos = b
- return c.ascii
+ return c.code_point
end
end
if dpos == 0 then
# We know what we want (+0 or +1) just get it now!
var its = _items
var c = its[b]
- if c & 0x80u8 == 0x00u8 then return c.ascii
+ if c & 0x80 == 0x00 then return c.code_point
return items.char_at(b)
end
var i = char_to_byte_index(index)
var items = _items
var b = items[i]
- if b & 0x80u8 == 0x00u8 then return b.ascii
+ if b & 0x80 == 0x00 then return b.code_point
return items.char_at(i)
end
var max = pos + ln
for i in [pos .. max[ do
res <<= 4
- res += its[i].ascii.from_hex
+ res += its[i].code_point.from_hex
end
return res
end
var blen = _byte_length
var new_items = new CString(blen + 1)
_items.copy_to(new_items, blen, _first_byte, 0)
- new_items[blen] = 0u8
+ new_items[blen] = 0
return new_items
end
var its = _items
var fb = _first_byte
var ns = new CString(new_byte_length + 1)
- ns[new_byte_length] = 0u8
+ ns[new_byte_length] = 0
var offset = 0
while i > 0 do
its.copy_to(ns, mybtlen, fb, offset)
redef fun [](idx) do
assert idx < _byte_length and idx >= 0
- return _items[idx + _first_byte].ascii
+ return _items[idx + _first_byte].code_point
end
redef fun substring(from, count) do
return new ASCIIFlatString.full_data(_items, count, from + _first_byte, count)
end
- redef fun fetch_char_at(i) do return _items[i + _first_byte].ascii
+ redef fun fetch_char_at(i) do return _items[i + _first_byte].code_point
end
private class FlatStringCharReverseIterator
end
private class FlatStringByteReverseIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
var target: FlatString
end
private class FlatStringByteIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
var target: FlatString
do
var bln = _byte_length
var new_native = new CString(bln + 1)
- new_native[bln] = 0u8
+ new_native[bln] = 0
if _length > 0 then _items.copy_to(new_native, bln, 0, 0)
return new_native
end
end
private class FlatBufferByteReverseIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
var target: FlatBuffer
end
private class FlatBufferByteIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
var target: FlatBuffer
if copy and (str == null or str.items == self) then
var new_cstr = new CString(byte_length + 1)
copy_to(new_cstr, byte_length, 0, 0)
- new_cstr[byte_length] = 0u8
+ new_cstr[byte_length] = 0
str = new FlatString.full(new_cstr, byte_length, 0, char_length)
end
end
if rem == 0 then break
var b = self[pos]
- if b & 0x80u8 == 0x00u8 then
+ if b & 0x80 == 0x00 then
pos += 1
chr_ln += 1
rem -= 1
var nxst = length_of_char_at(pos)
var ok_st: Bool
if nxst == 1 then
- ok_st = b & 0x80u8 == 0u8
+ ok_st = b & 0x80 == 0
else if nxst == 2 then
- ok_st = b & 0xE0u8 == 0xC0u8
+ ok_st = b & 0xE0 == 0xC0
else if nxst == 3 then
- ok_st = b & 0xF0u8 == 0xE0u8
+ ok_st = b & 0xF0 == 0xE0
else
- ok_st = b & 0xF8u8 == 0xF0u8
+ ok_st = b & 0xF8 == 0xF0
end
if not ok_st then
if replacements == null then replacements = new Array[Int]
var chkln = repl_pos - old_repl
copy_to(ret, chkln, old_repl, off)
off += chkln
- ret[off] = 0xEFu8
- ret[off + 1] = 0xBFu8
- ret[off + 2] = 0xBDu8
+ ret[off] = 0xEF
+ ret[off + 1] = 0xBF
+ ret[off + 2] = 0xBD
old_repl = repl_pos + 1
off += 3
end
private fun set_char_at(pos: Int, c: Char) do
var cp = c.code_point
if cp < 128 then
- self[pos] = cp.to_b
+ self[pos] = cp
return
end
var ln = c.u8char_len
if ln == 2 then
- self[pos] = (0xC0 | ((cp & 0x7C0) >> 6)).to_b
- self[pos + 1] = (0x80 | (cp & 0x3F)).to_b
+ self[pos] = 0xC0 | ((cp & 0x7C0) >> 6)
+ self[pos + 1] = 0x80 | (cp & 0x3F)
else if ln == 3 then
- self[pos] = (0xE0 | ((cp & 0xF000) >> 12)).to_b
- self[pos + 1] = (0x80 | ((cp & 0xFC0) >> 6)).to_b
- self[pos + 2] = (0x80 | (cp & 0x3F)).to_b
+ self[pos] = 0xE0 | ((cp & 0xF000) >> 12)
+ self[pos + 1] = 0x80 | ((cp & 0xFC0) >> 6)
+ self[pos + 2] = 0x80 | (cp & 0x3F)
else if ln == 4 then
- self[pos] = (0xF0 | ((cp & 0x1C0000) >> 18)).to_b
- self[pos + 1] = (0x80 | ((cp & 0x3F000) >> 12)).to_b
- self[pos + 2] = (0x80 | ((cp & 0xFC0) >> 6)).to_b
- self[pos + 3] = (0x80 | (cp & 0x3F)).to_b
+ self[pos] = 0xF0 | ((cp & 0x1C0000) >> 18)
+ self[pos + 1] = 0x80 | ((cp & 0x3F000) >> 12)
+ self[pos + 2] = 0x80 | ((cp & 0xFC0) >> 6)
+ self[pos + 3] = 0x80 | (cp & 0x3F)
end
end
end
var nslen = int_to_s_len
var ns = new CString(nslen + 1)
- ns[nslen] = 0u8
+ ns[nslen] = 0
native_int_to_s(ns, nslen + 1)
return new FlatString.full(ns, nslen, 0, nslen)
end
mypos += 1
end
var ns = new CString(sl + 1)
- ns[sl] = 0u8
+ ns[sl] = 0
i = 0
var off = 0
while i < mypos do
mypos += 1
end
var ns = new CString(sl + 1)
- ns[sl] = 0u8
+ ns[sl] = 0
i = 0
var off = 0
while i < mypos do
#include <string.h>
`}
-redef class Byte
+redef class Int
# Gives the length of the UTF-8 char starting with `self`
fun u8len: Int do
- if self & 0b1000_0000u8 == 0u8 then
+ if self & 0b1000_0000 == 0 then
return 1
- else if self & 0b1110_0000u8 == 0b1100_0000u8 then
+ else if self & 0b1110_0000 == 0b1100_0000 then
return 2
- else if self & 0b1111_0000u8 == 0b1110_0000u8 then
+ else if self & 0b1111_0000 == 0b1110_0000 then
return 3
- else if self & 0b1111_1000u8 == 0b1111_0000u8 then
+ else if self & 0b1111_1000 == 0b1111_0000 then
return 4
else
return 1
# Is `self` a valid UTF-8 sequence start ?
#
# ~~~nit
- # assert 0u8.is_valid_utf8_start
- # assert 0xC0u8.is_valid_utf8_start
- # assert 0xE0u8.is_valid_utf8_start
- # assert 0xF0u8.is_valid_utf8_start
+ # assert 0.is_valid_utf8_start
+ # assert 0xC0.is_valid_utf8_start
+ # assert 0xE0.is_valid_utf8_start
+ # assert 0xF0.is_valid_utf8_start
# ~~~
fun is_valid_utf8_start: Bool do
- if self & 0x80u8 == 0u8 then return true
- if self & 0b1110_0000u8 == 0b1100_0000u8 then return true
- if self & 0b1111_0000u8 == 0b1110_0000u8 then return true
- if self & 0b1111_1000u8 == 0b1111_0000u8 then return true
+ if self & 0x80 == 0 then return true
+ if self & 0b1110_0000 == 0b1100_0000 then return true
+ if self & 0b1111_0000 == 0b1110_0000 then return true
+ if self & 0b1111_1000 == 0b1111_0000 then return true
return false
end
end
fun fast_cstring(index: Int): CString is intern
# Get char at `index`.
- fun [](index: Int): Byte is intern
+ fun [](index: Int): Int is intern
# Set char `item` at index.
- fun []=(index: Int, item: Byte) is intern
+ fun []=(index: Int, item: Int) is intern
# Copy `self` to `dest`.
fun copy_to(dest: CString, length: Int, from: Int, to: Int) is intern
fun cstring_length: Int
do
var l = 0
- while self[l] != 0u8 do l += 1
+ while self[l] != 0 do l += 1
return l
end
# ~~~
fun char_at(pos: Int): Char do
var c = self[pos]
- if c & 0x80u8 == 0u8 then return c.ascii
+ if c & 0x80 == 0 then return c.code_point
var b = fetch_4_hchars(pos)
var ret = 0u32
if b & 0xC00000u32 != 0x800000u32 then return 0xFFFD.code_point
# Gets the length of the character at position `pos` (1 if invalid sequence)
fun length_of_char_at(pos: Int): Int do
var c = self[pos]
- if c & 0x80u8 == 0x00u8 then
+ if c & 0x80 == 0x00 then
return 1
- else if c & 0xE0u8 == 0xC0u8 and self[pos + 1] & 0xC0u8 == 0x80u8 then
+ else if c & 0xE0 == 0xC0 and self[pos + 1] & 0xC0 == 0x80 then
return 2
- else if c & 0xF0u8 == 0xE0u8 and self[pos + 1] & 0xC0u8 == 0x80u8 and self[pos + 2] & 0xC0u8 == 0x80u8 then
+ else if c & 0xF0 == 0xE0 and self[pos + 1] & 0xC0 == 0x80 and self[pos + 2] & 0xC0 == 0x80 then
return 3
- else if c & 0xF8u8 == 0xF0u8 and self[pos + 1] & 0xC0u8 == 0x80u8 and self[pos + 2] & 0xC0u8 == 0x80u8 and self[pos + 3] & 0xC0u8 == 0x80u8 then
+ else if c & 0xF8 == 0xF0 and self[pos + 1] & 0xC0 == 0x80 and self[pos + 2] & 0xC0 == 0x80 and self[pos + 3] & 0xC0 == 0x80 then
return 4
else
return 1
# ~~~raw
# assert "abc".items.find_beginning_of_char_at(2) == 2
# assert "か".items.find_beginning_of_char_at(1) == 0
- # assert [0x41u8, 233u8].to_s.items.find_beginning_of_char_at(1) == 1
+ # assert [0x41, 233].to_s.items.find_beginning_of_char_at(1) == 1
# ~~~
fun find_beginning_of_char_at(pos: Int): Int do
var endpos = pos
var c = self[pos]
- if c & 0x80u8 == 0x00u8 then return pos
- while c & 0xC0u8 == 0x80u8 do
+ if c & 0x80 == 0x00 then return pos
+ while c & 0xC0 == 0x80 do
pos -= 1
c = self[pos]
end
redef fun to_cstring do
var len = _byte_length
var ns = new CString(len + 1)
- ns[len] = 0u8
+ ns[len] = 0
var off = 0
for i in substrings do
var ilen = i._byte_length
# A reverse iterator capable of working with `Rope` objects
private class RopeByteReverseIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
# Current CString
var ns: CString is noautoinit
# Forward iterator on the bytes of a `Rope`
private class RopeByteIterator
- super IndexedIterator[Byte]
+ super IndexedIterator[Int]
# Position in current `String`
var pns: Int is noautoinit
# Accumulate best result
var max = 0.0
- var best = 0.to_b
+ var best = 0
# Iterate on possible values for a byte
var xor_b = new Bytes.with_capacity(1)
for b in [0 .. 255] do
# Need `Bytes` to pass to xor
- xor_b[0] = b.to_b
+ xor_b[0] = b
# Xor and evaluate result
var xored = ciphertext.xorcipher(xor_b)
var result = xored.to_s.english_scoring
if result > max then
max = result
- best = b.to_b
+ best = b
end
end
# assert "this is a test".to_bytes.hamming_distance("wokka wokka!!!".bytes) == 37
# assert "this is a test".to_bytes.hamming_distance("this is a test".bytes) == 0
#
- fun hamming_distance(other: SequenceRead[Byte]): Int do
+ fun hamming_distance(other: SequenceRead[Int]): Int do
var diff = 0
for idx in self.length.times do
var res_byte = self[idx] ^ other[idx]
for bit in [0..8[ do
- if res_byte & 1u8 == 1u8 then diff += 1
+ if res_byte & 1 == 1 then diff += 1
res_byte = res_byte >> 1
end
end
var mod = length % blocksize
if mod == 0 then return self
var pad = blocksize - mod
- var byte = pad.to_b
+ var byte = pad
for i in [0..pad[ do add byte
return self
end
super Cipher
# Cryptographic key used in encryption and decryption.
- var key: Byte = 0.to_b
+ var key: Int = 0
redef fun encrypt do
var key_bytes = new Bytes.with_capacity(1)
# Simple conversion from [0.0..1.0] to [0..255]
var bytes = [for c in color do (c*255.0).round.to_i.clamp(0, 255).to_bytes.last]
- while bytes.length < 4 do bytes.add 255u8
+ while bytes.length < 4 do bytes.add 255
var offset = 4*(x + y*width.to_i)
- for i in [0..4[ do cpixels[offset+i] = bytes[i]
+ for i in [0..4[ do cpixels[offset+i] = bytes[i].to_b
loaded = false
end
do
# Simple conversion from [0.0..1.0] to [0..255]
var bytes = [for c in color do (c*255.0).round.to_i.clamp(0, 255).to_bytes.last]
- while bytes.length < 4 do bytes.add 255u8
+ while bytes.length < 4 do bytes.add 255
var i = 0
for x in [0..width.to_i[ do
for y in [0..height.to_i[ do
- for j in [0..4[ do cpixels[i+j] = bytes[j]
+ for j in [0..4[ do cpixels[i+j] = bytes[j].to_b
i += 4
end
end
redef fun json_need_escape do
var its = items
for i in [first_byte .. last_byte] do
- if its[i] == 0x5Cu8 then return true
+ if its[i] == 0x5C then return true
end
return false
end
`}
# Write the byte `value`
- fun write_byte(value: Byte): Int `{
+ fun write_byte(value: Int): Int `{
unsigned char byt = (unsigned char)value;
return bufferevent_write(self, &byt, 1);
`}
serialize
# Custom type code, in [0..127]
- var typ: Byte
+ var typ: Int
# Data bytes
var data: Bytes
redef fun hash do return typ.hash + data.hash*8
redef fun ==(o) do return o isa MsgPackExt and o.typ == typ and o.data == data
- redef fun to_s do return "<{class_name} typ: {typ}, data: {data.chexdigest}>"
+ redef fun to_s do return "<{class_name} typ: {typ.to_b}, data: {data.chexdigest}>"
end
#
# ~~~
# assert 0x01u8.serialize_msgpack == b"\xD4\x7E\x01"
-# assert b"\xD4\x7E\x01".deserialize_msgpack == 0x01u8
+# assert b"\xD4\x7E\x01".deserialize_msgpack == 1
# ~~~
#
# ## Full objects
else if typ & 0b1000_0000 == 0 or typ & 0b1110_0000 == 0b1110_0000 then
# fixint
var bytes = new Bytes.with_capacity(1)
- bytes.add typ.to_b
+ bytes.add typ
return bytes.to_i(signed=true)
else if typ & 0b1111_0000 == 0b1000_0000 then
# var reader = new BytesReader(b"\xC7\x03\x0A\x0B\x0C\x0D")
# var ext = reader.read_msgpack
# assert ext isa MsgPackExt
- # assert ext.typ == 0x0Au8
+ # assert ext.typ == 0x0a
# assert ext.data == b"\x0B\x0C\x0D"
# ~~~
private fun read_msgpack_fixext_data(len: Int): MsgPackExt
var exttyp = read_byte
if exttyp < 0 then exttyp = 0
var data = read_bytes(len)
- return new MsgPackExt(exttyp.to_b, data)
+ return new MsgPackExt(exttyp, data)
end
# Read the content of a dynamic *ext* including the length on `len_len` bytes
abstract class MsgPackEngine
# *ext type* byte for object definitions, defaults to 0x7Bu8 or '{'
- var ext_typ_obj: Byte = 0x7Bu8 is writable
+ var ext_typ_obj: Int = 0x7B is writable
# *ext type* byte for object references, defaults to 0x7Du8 or '}'
- var ext_typ_ref: Byte = 0x7Du8 is writable
+ var ext_typ_ref: Int = 0x7D is writable
# *ext type* byte to identify a char, defaults to 0x7Cu8 or '~'
- var ext_typ_char: Byte = 0x7Cu8 is writable
+ var ext_typ_char: Int = 0x7C is writable
# *ext type* byte to identify a byte, defaults to 0x7Eu8 or '|'
- var ext_typ_byte: Byte = 0x7Eu8 is writable
+ var ext_typ_byte: Int = 0x7E is writable
end
else
# Write as ext
var bytes = new Bytes.with_capacity(1)
- bytes.add self
+ bytes.add self.to_i
v.stream.write_msgpack_ext(v.ext_typ_byte, bytes)
end
end
redef class Writer
# Write `null`, or nil, in MessagePack format
- fun write_msgpack_null do write_byte 0xC0u8
+ fun write_msgpack_null do write_byte 0xC0
# Write `bool` in MessagePack format
fun write_msgpack_bool(bool: Bool)
- do write_byte(if bool then 0xC3u8 else 0xC2u8)
+ do write_byte(if bool then 0xC3 else 0xC2)
# ---
# Integers
fun write_msgpack_fixint(value: Int)
do
assert value >= -0x20 and value <= 0x7F
- write_byte value.to_b
+ write_byte value
end
# Write `value` over one unsigned byte, following 1 metadata byte
# Require: `value >= 0x00 and value <= 0xFF`
fun write_msgpack_uint8(value: Int)
do
- write_byte 0xCCu8
+ write_byte 0xCC
write_bytes value.to_bytes(n_bytes=1)
end
# Require: `value >= 0x00 and value <= 0xFFFF`
fun write_msgpack_uint16(value: Int)
do
- write_byte 0xCDu8
+ write_byte 0xCD
write_bytes value.to_bytes(n_bytes=2)
end
# Require: `value >= 0x00 and value <= 0xFFFF_FFFF`
fun write_msgpack_uint32(value: Int)
do
- write_byte 0xCEu8
+ write_byte 0xCE
write_bytes value.to_bytes(n_bytes=4)
end
# Require: `value >= 0x00 and value <= 0xFFFF_FFFF_FFFF_FFFF`
fun write_msgpack_uint64(value: Int)
do
- write_byte 0xCFu8
+ write_byte 0xCF
write_bytes value.to_bytes(n_bytes=8)
end
# Require: `value >= -128 and value <= 127`
fun write_msgpack_int8(value: Int)
do
- write_byte 0xD0u8
+ write_byte 0xD0
write_bytes value.to_bytes(n_bytes=1)
end
# Write `value` over two signed bytes, following 1 metadata byte
fun write_msgpack_int16(value: Int)
do
- write_byte 0xD1u8
+ write_byte 0xD1
write_bytes value.to_bytes(n_bytes=2)
end
# Write `value` over 4 signed bytes, following 1 metadata byte
fun write_msgpack_int32(value: Int)
do
- write_byte 0xD2u8
+ write_byte 0xD2
write_bytes value.to_bytes(n_bytes=4)
end
# Write `value` over 8 signed bytes, following 1 metadata byte
fun write_msgpack_int64(value: Int)
do
- write_byte 0xD3u8
+ write_byte 0xD3
write_int64 value
end
# Write `value` as a MessagePack float (losing precision)
fun write_msgpack_float(value: Float)
do
- write_byte 0xCAu8
+ write_byte 0xCA
write_float value
end
# Write `value` as a MessagePack double
fun write_msgpack_double(value: Float)
do
- write_byte 0xCBu8
+ write_byte 0xCB
write_double value
end
var len = text.byte_length
assert len <= 0x1F
- var b = 0b1010_0000u8 | len.to_b
+ var b = 0b1010_0000 | len
write_byte b
write text
var len = text.byte_length
assert len <= 0xFF
- write_byte 0xD9u8
- write_byte len.to_b
+ write_byte 0xD9
+ write_byte len
write text
end
var len = text.byte_length
assert len <= 0xFFFF
- write_byte 0xDAu8
+ write_byte 0xDA
var len_bytes = len.to_bytes
write_byte len_bytes[0]
- write_byte if len_bytes.length > 1 then len_bytes[1] else 0u8
+ write_byte if len_bytes.length > 1 then len_bytes[1] else 0
write text
end
var len = text.byte_length
assert len <= 0xFFFF_FFFF
- write_byte 0xDBu8
+ write_byte 0xDB
var len_bytes = len.to_bytes
write_byte len_bytes[0]
for i in [1..4[ do
- write_byte if len_bytes.length > i then len_bytes[i] else 0u8
+ write_byte if len_bytes.length > i then len_bytes[i] else 0
end
write text
end
var len = data.length
assert len <= 0xFF
- write_byte 0xC4u8
- write_byte len.to_b
+ write_byte 0xC4
+ write_byte len
write_bytes data
end
var len = data.length
assert len <= 0xFFFF
- write_byte 0xC5u8
+ write_byte 0xC5
write_bytes len.to_bytes(n_bytes=2)
write_bytes data
end
var len = data.length
assert len <= 0xFFFF_FFFF
- write_byte 0xC6u8
+ write_byte 0xC6
write_bytes len.to_bytes(n_bytes=4)
write_bytes data
end
fun write_msgpack_fixarray(len: Int)
do
assert len <= 0x0F
- write_byte 0b1001_0000u8 | len.to_b
+ write_byte 0b1001_0000 | len
end
# Write an array header for `len` items, max of 0xFFFF items
fun write_msgpack_array16(len: Int)
do
assert len <= 0xFFFF
- write_byte 0xDCu8
+ write_byte 0xDC
write_bytes len.to_bytes(n_bytes=2)
end
fun write_msgpack_array32(len: Int)
do
assert len <= 0xFFFF_FFFF
- write_byte 0xDDu8
+ write_byte 0xDD
write_bytes len.to_bytes(n_bytes=4)
end
fun write_msgpack_fixmap(len: Int)
do
assert len <= 0x0F
- write_byte 0b1000_0000u8 | len.to_b
+ write_byte 0b1000_0000 | len
end
# Write a map header for `len` key/value pairs, max of 0xFFFF pairs
fun write_msgpack_map16(len: Int)
do
assert len <= 0xFFFF
- write_byte 0xDEu8
+ write_byte 0xDE
write_bytes len.to_bytes(n_bytes=2)
end
fun write_msgpack_map32(len: Int)
do
assert len <= 0xFFFF_FFFF
- write_byte 0xDFu8
+ write_byte 0xDF
write_bytes len.to_bytes(n_bytes=4)
end
#
# ~~~
# var writer = new BytesWriter
- # writer.write_msgpack_ext(0x0Au8, b"\x0B\x0C\x0D")
+ # writer.write_msgpack_ext(0x0A, b"\x0B\x0C\x0D")
# assert writer.bytes == b"\xC7\x03\x0A\x0B\x0C\x0D"
# ~~~
- fun write_msgpack_ext(typ: Byte, bytes: Bytes)
+ fun write_msgpack_ext(typ: Int, bytes: Bytes)
do
var len = bytes.length
if len == 1 then
# Write the header for an application-specific extension of one data byte
#
# After writing the header, clients should write the data byte.
- fun write_msgpack_fixext1(typ: Byte)
+ fun write_msgpack_fixext1(typ: Int)
do
- write_byte 0xD4u8
+ write_byte 0xD4
write_byte typ
end
# Write the header for an application-specific extension of two data bytes
#
# After writing the header, clients should write the two data bytes.
- fun write_msgpack_fixext2(typ: Byte)
+ fun write_msgpack_fixext2(typ: Int)
do
- write_byte 0xD5u8
+ write_byte 0xD5
write_byte typ
end
# Write the header for an application-specific extension of 4 data bytes
#
# After writing the header, clients should write the 4 data bytes.
- fun write_msgpack_fixext4(typ: Byte)
+ fun write_msgpack_fixext4(typ: Int)
do
- write_byte 0xD6u8
+ write_byte 0xD6
write_byte typ
end
# Write the header for an application-specific extension of 8 data bytes
#
# After writing the header, clients should write the 8 data bytes.
- fun write_msgpack_fixext8(typ: Byte)
+ fun write_msgpack_fixext8(typ: Int)
do
- write_byte 0xD7u8
+ write_byte 0xD7
write_byte typ
end
# Write the header for an application-specific extension of 16 data bytes
#
# After writing the header, clients should write the 16 data bytes.
- fun write_msgpack_fixext16(typ: Byte)
+ fun write_msgpack_fixext16(typ: Int)
do
- write_byte 0xD8u8
+ write_byte 0xD8
write_byte typ
end
# After writing the header, clients should write the data bytes.
#
# Require: `len >= 0 and <= 0xFF`
- fun write_msgpack_ext8(typ: Byte, len: Int)
+ fun write_msgpack_ext8(typ, len: Int)
do
assert len >= 0 and len <= 0xFF
- write_byte 0xC7u8
- write_byte len.to_b
+ write_byte 0xC7
+ write_byte len
write_byte typ
end
# After writing the header, clients should write the data bytes.
#
# Require: `len >= 0 and <= 0xFFFF`
- fun write_msgpack_ext16(typ: Byte, len: Int)
+ fun write_msgpack_ext16(typ, len: Int)
do
assert len >= 0 and len <= 0xFFFF
- write_byte 0xC8u8
+ write_byte 0xC8
write_bytes len.to_bytes(n_bytes=2)
write_byte typ
end
# After writing the header, clients should write the data bytes.
#
# Require: `len >= 0 and <= 0xFFFF_FFFF`
- fun write_msgpack_ext32(typ: Byte, len: Int)
+ fun write_msgpack_ext32(typ, len: Int)
do
assert len >= 0 and len <= 0xFFFF_FFFF
- write_byte 0xC9u8
+ write_byte 0xC9
write_bytes len.to_bytes(n_bytes=4)
write_byte typ
end
# Fallback
if bytes == null or bytes.length != bin_length or force_rand == true then
bytes = new Bytes.with_capacity(bin_length)
- for i in bin_length.times do bytes.add 256.rand.to_b
+ for i in bin_length.times do bytes.add 256.rand
end
# Encode in base64 so it is readable
# sha1_hexdigest.
#
# import base64
- # assert "The quick brown fox jumps over the lazy dog".sha1 == [0x2Fu8, 0xD4u8, 0xE1u8, 0xC6u8, 0x7Au8, 0x2Du8, 0x28u8, 0xFCu8, 0xEDu8, 0x84u8, 0x9Eu8, 0xE1u8, 0xBBu8, 0x76u8, 0xE7u8, 0x39u8, 0x1Bu8, 0x93u8, 0xEBu8, 0x12u8]
+ # assert "The quick brown fox jumps over the lazy dog".sha1 == [0x2F, 0xD4, 0xE1, 0xC6, 0x7A, 0x2D, 0x28, 0xFC, 0xED, 0x84, 0x9E, 0xE1, 0xBB, 0x76, 0xE7, 0x39, 0x1B, 0x93, 0xEB, 0x12]
fun sha1: Bytes do
return new Bytes(to_cstring.sha1_intern(byte_length), 20, 20)
end
`}
# Write `value` as a single byte
- fun write_byte(value: Byte): Int `{
+ fun write_byte(value: Int): Int `{
unsigned char byt = (unsigned char)value;
return write(*self, &byt, 1);
`}
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Implementation of BKTree
+#
+# As proposed by W. A. Burkhard and R. M. Keller in
+# "Some approaches to best-match file searching" the BKTree data structure
+# is usefull to speed-up spell checking based on the Levenshtein distance between
+# words.
+#
+# With a BKTree, the complexity to find mispelled words in a dictionnary is *O(log n)*
+# instead of *O(n)* with a dummy list.
+#
+# Example:
+#
+# ~~~
+# # Create a new BKTree
+# var tree = new BKTree
+#
+# # Index some words in the dictionnary for spell checking
+# tree.add("book")
+# tree.add("books")
+# tree.add("cake")
+# tree.add("boo")
+# tree.add("cape")
+# tree.add("boon")
+# tree.add("cook")
+# tree.add("cart")
+#
+# # Search suggestions in the BKTree
+# assert tree.search("caqe").join(", ") == "\{1: cake\}, \{1: cape\}"
+# ~~~
+#
+# See <https://dl.acm.org/citation.cfm?id=362003.362025>.
+module bktree
+
+import abstract_tree
+
+# A BKTree implementation
+#
+# See `add` to insert a new word.
+# See `search` to find matches from a `key`.
+class BKTree
+
+ # Default tolerance used to find matches
+ #
+ # Default is `2`.
+ var default_tolerance = 2 is writable
+
+ # Tree root
+ private var root: nullable BKNode = null
+
+ # Add a `key` in the tree
+ fun add(key: String) do
+ var root = self.root
+ if root == null then
+ self.root = new BKNode(key)
+ return
+ end
+
+ var node = root
+ var dist = node.key.levenshtein_distance(key)
+
+ while node.has_key(dist) do
+ if dist == 0 then return
+ node = node[dist]
+ dist = node.key.levenshtein_distance(key)
+ end
+ node[dist] = new BKNode(key)
+ end
+
+ # Search `key` with a distance of `tolerance` in `self`.
+ #
+ # If `tolerance` is null, the use `default_tolerance` instead.
+ fun search(key: String, tolerance: nullable Int): Array[BKMatch] do
+ var res = new Array[BKMatch]
+ var root = self.root
+ if root != null then
+ if tolerance == null then tolerance = self.default_tolerance
+ search_recursive(root, res, key, tolerance)
+ end
+ default_comparator.sort(res)
+ return res
+ end
+
+ private fun search_recursive(node: BKNode, res: Array[BKMatch], key: String, tolerance: Int) do
+ var dist = node.key.levenshtein_distance(key)
+ var min = dist - tolerance
+ var max = dist + tolerance
+
+ if dist < tolerance then
+ res.add new BKMatch(dist, node.key)
+ end
+
+ for odist, child in node do
+ if odist < min or odist > max then continue
+ search_recursive(child, res, key, tolerance)
+ end
+ end
+end
+
+# A node that goes in a BKTree
+#
+# Each child is mapped from `self` by its distance as an Int.
+private class BKNode
+ super HashMap[Int, BKNode]
+
+ # Key stored in `self`
+ var key: String
+
+ redef fun to_s do return "\{{key}\}"
+end
+
+# A match in a BKTree
+#
+# Used to order results returned by `BKTree::search`.
+class BKMatch
+ super Comparable
+
+ redef type OTHER: BKMatch
+
+ # Distance of `key` from the search query
+ var distance: Int
+
+ # Matched `key`
+ var key: String
+
+ redef fun ==(o) do return o isa BKMatch and distance == o.distance and key == o.key
+
+ redef fun <=>(o) do
+ if distance == o.distance then
+ return key <=> o.key
+ end
+ return distance <=> o.distance
+ end
+
+ redef fun to_s do return "\{{distance}: {key}\}"
+end
return super
end
+ # Increment value for `obj` term
+ #
+ # If the term isn't already in the vector, the new value is 1.0.
+ fun inc(obj: nullable Object) do
+ if has_key(obj) then
+ self[obj] += 1.0
+ else
+ self[obj] = 1.0
+ end
+ end
+
# The norm of the vector.
#
# `||x|| = (x1 ** 2 ... + xn ** 2).sqrt`
# Documents can then be matched to query vectors.
class VSMIndex
+ # Kind of documents stored in this index
+ #
+ # Clients can redefine this type to specialize the index.
+ type DOC: Document
+
# Documents index
+ var documents = new HashSet[DOC]
+
+ # Inversed index
#
- # TODO use a more efficient representation.
- var documents = new HashSet[Document]
+ # Link documents to existing terms.
+ var inversed_index = new HashMap[nullable Object, Array[DOC]]
# Count for all terms in all indexed documents
#
#
# Returns an `IndexMatch` for each indexed document.
# Results are ordered by descending similarity.
- fun match_vector(query: Vector): Array[IndexMatch] do
- var matches = new Array[IndexMatch]
+ fun match_vector(query: Vector): Array[IndexMatch[DOC]] do
+ var documents = new HashSet[DOC]
+ for term, count in query do
+ if inversed_index.has_key(term) then
+ documents.add_all inversed_index[term]
+ end
+ end
+ var matches = new Array[IndexMatch[DOC]]
for doc in documents do
var sim = query.cosine_similarity(doc.tfidf)
if sim == 0.0 then continue
- matches.add new IndexMatch(doc, sim)
+ matches.add new IndexMatch[DOC](doc, sim)
end
sorter.sort(matches)
return matches
#
# When processing batch documents, use `auto_update = false` to disable
# the auto update of the index.
- fun index_document(doc: Document, auto_update: nullable Bool) do
+ fun index_document(doc: DOC, auto_update: nullable Bool) do
for term, count in doc.terms_count do
- if not terms_doc_count.has_key(term) then
- terms_doc_count[term] = 1.0
- else
- terms_doc_count[term] += 1.0
+ terms_doc_count.inc(term)
+ if not inversed_index.has_key(term) then
+ inversed_index[term] = new Array[DOC]
end
+ inversed_index[term].add doc
end
documents.add doc
if auto_update == null or auto_update then update_index
# Return the Document created.
#
# See `index_document`.
- fun index_string(title, uri, string: String, auto_update: nullable Bool): Document do
+ fun index_string(title, uri, string: String, auto_update: nullable Bool): DOC do
var vector = parse_string(string)
var doc = new Document(title, uri, vector)
index_document(doc, auto_update)
# Match the `query` string against all indexed documents
#
# See `match_vector`.
- fun match_string(query: String): Array[IndexMatch] do
+ fun match_string(query: String): Array[IndexMatch[DOC]] do
var vector = parse_string(query)
var doc = new Document("", "", vector)
return match_vector(doc.terms_frequency)
loop
var token = reader.read_word
if token == "" then break
-
- if not vector.has_key(token) then
- vector[token] = 1.0
- else
- vector[token] += 1.0
- end
+ vector.inc(token)
end
return vector
end
# Return the created document or null if `path` is not accepted by `accept_file`.
#
# See `index_document`.
- fun index_file(path: String, auto_update: nullable Bool): nullable Document do
+ fun index_file(path: String, auto_update: nullable Bool): nullable DOC do
if not accept_file(path) then return null
var vector = parse_file(path)
var doc = new Document(path, path, vector)
# A high weight in tf–idf is reached by a high term frequency
# (in the given document) and a low document frequency of the term in the
# whole collection of documents
- var tfidf = new Vector
+ var tfidf: Vector = terms_count is lazy
redef fun to_s do return "{title}"
end
# A match to a `request` in an `Index`
-class IndexMatch
+class IndexMatch[DOC: Document]
super Comparable
# Document matching the `request_vector`
- var document: Document
+ var document: DOC
# Similarity between the `request` and the `doc`.
#
class IndexMatchSorter
super DefaultComparator
- redef type COMPARED: IndexMatch
+ redef type COMPARED: IndexMatch[Document]
redef fun compare(a, b) do
return b.similarity <=> a.similarity
var ans_buffer = new Bytes.with_capacity(msg.byte_length + 2)
# Flag for final frame set to 1
# opcode set to 1 (for text)
- ans_buffer.add(129u8)
+ ans_buffer.add(129)
if msg.length < 126 then
- ans_buffer.add(msg.length.to_b)
+ ans_buffer.add(msg.length)
end
if msg.length >= 126 and msg.length <= 65535 then
- ans_buffer.add(126u8)
- ans_buffer.add((msg.length >> 8).to_b)
- ans_buffer.add(msg.length.to_b)
+ ans_buffer.add(126)
+ ans_buffer.add(msg.length >> 8)
+ ans_buffer.add(msg.length)
end
msg.append_to_bytes(ans_buffer)
return ans_buffer
<div class='card-body' ng-if='mentity.class_name != "MPackage"'>
<h5 class='card-heading'>
<entity-signature mentity='mentity' />
+ <small><br/><entity-namespace namespace='mentity.namespace' /></small>
</h5>
<span class='synopsis' ng-bind-html='mentity.html_synopsis' />
</div>
<entity-card ng-click='vm.selectEnter()' ng-class='{active: vm.activeItem == $index}' ng-mouseover='vm.setActive($index)' mentity='mentity' ng-repeat='mentity in vm.results.results' />
<div class='card' ng-click='vm.selectEnter()' ng-mouseover='vm.setActive(vm.results.results.length)' ng-class='{active: vm.activeItem == vm.results.results.length}'>
<div class='card-body'>
- Show all {{vm.results.total}} results for <a>"{{vm.query}}"</a>
+ Show all {{vm.results.count}} results for <a>"{{vm.query}}"</a>
</div>
</div>
</div>
<br><br>
<div class='container'>
<div ng-if='vm.maintaining.results.length > 0'>
- <h3 id='maintaining'>{{vm.maintaining.total}} maintained projects</h3>
+ <h3 id='maintaining'>{{vm.maintaining.count}} maintained projects</h3>
<div class='card-list'>
<entity-card mentity='package' ng-repeat='package in vm.maintaining.results' />
</div>
</div>
</div>
<div ng-if='vm.contributing.results.length > 0'>
- <h3 id='contributing'>{{vm.contributing.total}} contributed projects</h3>
+ <h3 id='contributing'>{{vm.contributing.count}} contributed projects</h3>
<div class='card-list'>
<entity-card mentity='package' ng-repeat='package in vm.contributing.results' />
</div>
<div class='container'>
<h2>
- {{vm.entities.total}} matches for
+ {{vm.entities.count}} matches for
<a ui-sref='search({q: vm.query})'>{{vm.query}}</a>
</h2>
<div class='card-list'>
NITCOPT=--semi-global
OLDNITCOPT=--semi-global
-OBJS=nitc nitpick nit nitls nitunit nitpm nitx nitlight nitserial nitrestful
+OBJS=nitc nitpick nit nitls nitunit nitpm nitx nitlight nitserial nitrestful nitpackage
SRCS=$(patsubst %,%.nit,$(OBJS))
BINS=$(patsubst %,../bin/%,$(OBJS))
MOREOBJS=nitdoc nitweb nitcatalog nitmetrics nitpretty nitweb
var opt_no_cc = new OptionBool("Do not invoke the C compiler", "--no-cc")
# --no-main
var opt_no_main = new OptionBool("Do not generate main entry point", "--no-main")
+ # --shared-lib
+ var opt_shared_lib = new OptionBool("Compile to a native shared library", "--shared-lib")
# --make-flags
var opt_make_flags = new OptionString("Additional options to the `make` command", "--make-flags")
# --max-c-lines
redef init
do
super
- self.option_context.add_option(self.opt_output, self.opt_dir, self.opt_run, self.opt_no_cc, self.opt_no_main, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening)
+ self.option_context.add_option(self.opt_output, self.opt_dir, self.opt_run, self.opt_no_cc, self.opt_no_main, self.opt_shared_lib, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening)
self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_attr_isset, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_null, self.opt_no_check_all)
self.option_context.add_option(self.opt_typing_test_metrics, self.opt_invocation_metrics, self.opt_isset_checks_metrics)
self.option_context.add_option(self.opt_no_stacktrace)
self.option_context.add_option(self.opt_trace)
opt_no_main.hidden = true
+ opt_shared_lib.hidden = true
end
redef fun process_options(args)
if self.toolcontext.opt_trace.value then makefile.write "LDLIBS += -llttng-ust -ldl\n"
+ if toolcontext.opt_shared_lib.value then
+ makefile.write """
+CFLAGS += -fPIC
+LDFLAGS += -shared -Wl,-soname,{{{outname}}}
+"""
+ end
+
makefile.write "\n# SPECIAL CONFIGURATION FLAGS\n"
if platform.supports_libunwind then
if toolcontext.opt_no_stacktrace.value then
var nat = new_var(mtype)
var byte_esc = new Buffer.with_cap(len * 4)
for i in [0 .. len[ do
- byte_esc.append("\\x{ns[i].to_s.substring_from(2)}")
+ byte_esc.append("\\x{ns[i].to_hex}")
end
self.add("{nat} = \"{byte_esc}\";")
return nat
redef class ACharExpr
redef fun expr(v) do
- if is_ascii then return v.byte_instance(value.as(not null).ascii)
- if is_code_point then return v.int_instance(value.as(not null).code_point)
+ if is_code_point then
+ return v.int_instance(value.as(not null).code_point)
+ end
return v.char_instance(self.value.as(not null))
end
end
var res = self.new_var(mtype)
res.is_exact = true
self.require_declaration("NEW_{nclass.c_name}")
+ length = autobox(length, compiler.mainmodule.int_type)
self.add("{res} = NEW_{nclass.c_name}({length});")
return res
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# An index that contains Nit code
+#
+# Model entities are indexed by their ANode.
+#
+# Vectorization is based on model usage such as:
+# * modules importation
+# * classes spcialization and refinement
+# * methods calls and refinements
+#
+# Example:
+# ~~~nitish
+# # Create the index
+# var index = new CodeIndex(toolcontext)
+# for mentity in mentities do
+# index.index_mentity(mentity)
+# end
+#
+# # Match a piece of code
+# var matches = index.match_code("print \"Hello, World!\"")
+# for match in matches do
+# print match
+# end
+# ~~~
+module code_index
+
+import vsm
+import semantize
+import parser_util
+
+# Index for Nit doc
+class CodeIndex
+ super VSMIndex
+
+ redef type DOC: CodeDocument
+
+ # ToolContext used to parse pieces of code
+ var toolcontext: ToolContext
+
+ # Index `mentity`
+ fun index_mentity(mentity: MEntity) do
+ var terms = vectorize_mentity(mentity)
+ var doc = new CodeDocument(mentity, terms)
+ index_document(doc, false)
+ end
+
+ # Match `code` with the index
+ fun match_code(code: String): Array[IndexMatch[DOC]] do
+ var node = parse_code(code)
+ if node == null then return new Array[IndexMatch[DOC]]
+ return match_node(node)
+ end
+
+ # Match `node` with the index
+ fun match_node(node: ANode): Array[IndexMatch[DOC]] do
+ var vector = vectorize_node(node)
+ return match_vector(vector)
+ end
+
+ # Parse a piece of code
+ private fun parse_code(code: String): nullable AModule do
+ # Try to parse code
+ var node = toolcontext.parse_something(code)
+ if not node isa AModule then return null
+
+ # Load code into model
+ var mbuilder = toolcontext.modelbuilder
+ mbuilder.load_rt_module(null, node, "tmp")
+ mbuilder.run_phases
+ return node
+ end
+
+ # Transform `node` in a Vector
+ private fun vectorize_node(node: ANode): Vector do
+ var visitor = new CodeIndexVisitor
+ visitor.enter_visit(node)
+ return visitor.vector
+ end
+
+ # Transform `mentity` in a Vector
+ private fun vectorize_mentity(mentity: MEntity): Vector do
+ var node = toolcontext.modelbuilder.mentity2node(mentity)
+ if node == null then return new Vector
+ return vectorize_node(node)
+ end
+end
+
+# A specific document for mentities code
+class CodeDocument
+ super Document
+ autoinit(mentity, terms_count)
+
+ # MEntity related to this document
+ var mentity: MEntity
+
+ redef var title = mentity.full_name is lazy
+
+ redef var uri = mentity.location.to_s is lazy
+end
+
+# Code index visitor
+#
+# Used to build a VSM Vector from a Nit ANode.
+private class CodeIndexVisitor
+ super Visitor
+
+ var vector = new Vector
+
+ redef fun visit(node) do
+ node.accept_code_index_visitor(self)
+ end
+end
+
+redef class ANode
+ private fun accept_code_index_visitor(v: CodeIndexVisitor) do
+ visit_all(v)
+ end
+end
+
+redef class AStdImport
+ redef fun accept_code_index_visitor(v) do
+ var mmodule = self.mmodule
+ if mmodule != null then
+ v.vector.inc "import#{mmodule.full_name}"
+ end
+ end
+end
+
+redef class AStdClassdef
+ redef fun accept_code_index_visitor(v) do
+ var mclassdef = self.mclassdef
+ if mclassdef != null then
+ if not mclassdef.is_intro then
+ v.vector.inc "redef#{mclassdef.full_name}"
+ v.vector.inc "redef#{mclassdef.mclass.full_name}"
+ end
+ end
+ visit_all(v)
+ end
+end
+
+redef class ASuperPropdef
+ redef fun accept_code_index_visitor(v) do
+ var mtype = self.n_type.mtype
+ if mtype isa MClassType then
+ v.vector.inc "super#{mtype.mclass.intro.full_name}"
+ v.vector.inc "super#{mtype.mclass.full_name}"
+ end
+ end
+end
+
+redef class APropdef
+ redef fun accept_code_index_visitor(v) do
+ var mpropdef = self.mpropdef
+ if mpropdef != null then
+ if not mpropdef.is_intro then
+ v.vector.inc "redef#{mpropdef.mproperty.intro.full_name}"
+ v.vector.inc "redef#{mpropdef.mproperty.full_name}"
+ end
+ end
+ visit_all(v)
+ end
+end
+
+redef class ASendExpr
+ redef fun accept_code_index_visitor(v) do
+ var callsite = self.callsite
+ if callsite != null then
+ var args = callsite.signaturemap.as(not null).map.length
+ v.vector.inc "call#{callsite.mpropdef.full_name}({args})"
+ v.vector.inc "call#{callsite.mpropdef.mproperty.full_name}({args})"
+ v.vector.inc "call#{callsite.mpropdef.mclassdef.full_name}({args})"
+ v.vector.inc "call#{callsite.mpropdef.mclassdef.mclass.full_name}({args})"
+ end
+ visit_all(v)
+ end
+end
+
+redef class ANewExpr
+ redef fun accept_code_index_visitor(v) do
+ var callsite = self.callsite
+ if callsite != null then
+ var args = callsite.signaturemap.as(not null).map.length
+ v.vector.inc "call#{callsite.mpropdef.full_name}({args})"
+ v.vector.inc "call#{callsite.mpropdef.mproperty.full_name}({args})"
+ v.vector.inc "new#{callsite.mpropdef.mclassdef.full_name}({args})"
+ v.vector.inc "new#{callsite.mpropdef.mclassdef.mclass.full_name}({args})"
+ end
+ visit_all(v)
+ end
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module test_code_index is test
+
+import code_index
+import frontend
+
+class TestCodeIndex
+ test
+
+ # CodeIndex used in tests
+ var test_index: CodeIndex is noinit
+
+ # Initialize test variables
+ #
+ # Must be called before test execution.
+ # FIXME should be before_all
+ fun build_test_env is before do
+ var test_path = "NIT_TESTING_PATH".environ.dirname
+ var test_src = test_path / "../../../tests/test_prog"
+
+ # build model
+ var toolcontext = new ToolContext
+ var model = new Model
+ var modelbuilder = new ModelBuilder(model, toolcontext)
+ var mmodules = modelbuilder.parse_full([test_src])
+ modelbuilder.run_phases
+ toolcontext.run_global_phases(mmodules)
+
+ # create index
+ var index = new CodeIndex(toolcontext)
+ for mmodule in mmodules do
+ index.index_mentity(mmodule)
+ end
+ test_index = index
+ modelbuilder.paths.add test_src
+ end
+
+ fun test_find1 is test do
+ var query = "import game\n"
+ var matches = test_index.match_code(query)
+ assert matches.first.document.mentity.full_name == "test_prog::test_prog"
+ end
+
+ fun test_find2 is test do
+ var query = "import game\nimport rpg\n"
+ var matches = test_index.match_code(query)
+ assert matches.first.document.mentity.full_name == "test_prog::game"
+ end
+
+ fun test_find3 is test do
+ var query = "import game\nclass MyGame\nsuper Game\nredef fun start_game do end\nend\n"
+ var matches = test_index.match_code(query)
+ assert matches.first.document.mentity.full_name == "test_prog::game_examples"
+ end
+
+ fun test_find_error is test do
+ var query = "error"
+ var matches = test_index.match_code(query)
+ assert matches.is_empty
+ end
+end
do
var instance = c_string_instance_len(txt.byte_length+1)
var val = instance.val
- val[txt.byte_length] = 0u8
+ val[txt.byte_length] = 0
txt.to_cstring.copy_to(val, txt.byte_length, 0, 0)
return instance
var recvval = args.first.val.as(CString)
if pname == "[]" then
var arg1 = args[1].to_i
- return v.byte_instance(recvval[arg1])
+ return v.int_instance(recvval[arg1])
else if pname == "[]=" then
var arg1 = args[1].to_i
- recvval[arg1] = args[2].val.as(Byte)
+ recvval[arg1] = args[2].val.as(Int)
return null
else if pname == "copy_to" then
# sig= copy_to(dest: CString, length: Int, from: Int, to: Int)
redef class ACharExpr
redef fun expr(v)
do
- if is_ascii then return v.byte_instance(self.value.as(not null).ascii)
- if is_code_point then return v.int_instance(self.value.as(not null).code_point)
+ if is_code_point then
+ return v.int_instance(self.value.as(not null).code_point)
+ end
return v.char_instance(self.value.as(not null))
end
end
redef fun delimiter_end do return '\''
- # Is the expression returning an ASCII byte value ?
- fun is_ascii: Bool do return prefix == "b"
-
# Is the expression returning a Code Point ?
fun is_code_point: Bool do return prefix == "u"
redef fun is_valid_augmentation do
if suffix != "" then return false
- if is_ascii then return true
if is_code_point then return true
if prefix != "" then return false
return true
return
end
self.value = txt.chars[1]
- if is_ascii and txt.chars[1].code_point > 127 then v.toolcontext.error(self.hot_location, "Syntax Error: usage of byte prefix on multibyte character.")
end
end
if cla != null then mtype = cla.mclass_type
else if nexpr isa ACharExpr then
var cla: nullable MClass
- if nexpr.is_ascii then
- cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte")
- else if nexpr.is_code_point then
+ if nexpr.is_code_point then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int")
else
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Char")
redef class ACharExpr
redef fun accept_typing(v) do
var mclass: nullable MClass = null
- if is_ascii then
- mclass = v.get_mclass(self, "Byte")
- else if is_code_point then
+ if is_code_point then
mclass = v.get_mclass(self, "Int")
else
mclass = v.get_mclass(self, "Char")
../lib/core/kernel.nit:431,1--486,3: Error: `kernel$Numeric` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:492,1--515,3: Error: `kernel$Bool` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:517,1--599,3: Error: `kernel$Float` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:601,1--705,3: Error: `kernel$Byte` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:707,1--885,3: Error: `kernel$Int` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:887,1--1074,3: Error: `kernel$Char` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:1076,1--1093,3: Error: `kernel$Pointer` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:1095,1--1104,3: Error: `kernel$Task` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:601,1--700,3: Error: `kernel$Byte` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:702,1--883,3: Error: `kernel$Int` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:885,1--1064,3: Error: `kernel$Char` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:1066,1--1083,3: Error: `kernel$Pointer` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:1085,1--1094,3: Error: `kernel$Task` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723)
11
21
31
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723)
11
21
31
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723)
11
21
31
CString
-0x4e
+78
Nit
NativeArray
3
CString
-0x4e
+78
Nit
NativeArray
3
Numeric -> Float [dir=back arrowtail=open style=dashed];
Byte [
- label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ ascii(): Char\l+ is_whitespace(): Bool\l}"
+ label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ is_whitespace(): Bool\l}"
]
Discrete -> Byte [dir=back arrowtail=open style=dashed];
Numeric -> Byte [dir=back arrowtail=open style=dashed];
Int [
- label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l+ \>\>(i: Int): Int\l+ code_point(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
+ label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l+ \>\>(i: Int): Int\l+ code_point(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l+ is_whitespace(): Bool\l}"
]
Discrete -> Int [dir=back arrowtail=open style=dashed];
Numeric -> Int [dir=back arrowtail=open style=dashed];
Char [
- label = "{Char||+ +(i: Int): Char\l+ -(i: Int): Char\l+ to_i(): Int\l+ ascii(): Byte\l+ code_point(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
+ label = "{Char||+ +(i: Int): Char\l+ -(i: Int): Char\l+ to_i(): Int\l+ code_point(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
]
Discrete -> Char [dir=back arrowtail=open style=dashed];
Numeric -> Float [dir=back arrowtail=open style=dashed];
Byte [
- label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ ascii(): Char\l+ is_whitespace(): Bool\l}"
+ label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ is_whitespace(): Bool\l}"
]
Discrete -> Byte [dir=back arrowtail=open style=dashed];
Numeric -> Byte [dir=back arrowtail=open style=dashed];
Int [
- label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l+ \>\>(i: Int): Int\l+ code_point(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
+ label = "{Int||+ %(i: Int): Int\l+ \<\<(i: Int): Int\l+ \>\>(i: Int): Int\l+ code_point(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l+ is_whitespace(): Bool\l}"
]
Discrete -> Int [dir=back arrowtail=open style=dashed];
Numeric -> Int [dir=back arrowtail=open style=dashed];
Char [
- label = "{Char||+ +(i: Int): Char\l+ -(i: Int): Char\l+ to_i(): Int\l+ ascii(): Byte\l+ code_point(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
+ label = "{Char||+ +(i: Int): Char\l+ -(i: Int): Char\l+ to_i(): Int\l+ code_point(): Int\l+ is_ascii(): Bool\l+ to_lower(): Char\l+ to_upper(): Char\l+ is_digit(): Bool\l+ is_lower(): Bool\l+ is_upper(): Bool\l+ is_letter(): Bool\l+ is_whitespace(): Bool\l}"
]
Discrete -> Char [dir=back arrowtail=open style=dashed];
String66515A
s9 isa Regex
/
-0x47String/
+71String/
true
false
true
-0x0b
-0x1f
-0x4d
+11
+31
+77
CString
-0x4e
+78
Nit
NativeArray[Int]
3
Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/core/collection/array.nit:991)
CString
-0x4e
+78
Nit
+++ /dev/null
-alt/test_prefixed_chars_alt1.nit:18,17--20: Syntax Error: usage of byte prefix on multibyte character.
à1111111111111111111111111111111111111111éć2222222222222222222222222222222222222222ç
-0xc3 0xa0 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0xc3 0xa9 0xc4 0x87 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0xc3 0xa7
+195 160 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49 195 169 196 135 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 195 167
-[0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c]
-[0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c,0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c,0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c,0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c]
-[0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c,0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c,0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c,0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c]
-[0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54]
-[0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54,0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54,0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54,0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54]
-[0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54,0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54,0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54,0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54]
-[0x54,0x68,0x69,0x73,0x20,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x69,0x73,0x20,0x63,0x6f,0x6f,0x6c]
-[0x6c,0x6f,0x6f,0x63,0x20,0x73,0x69,0x20,0x67,0x6e,0x69,0x72,0x74,0x73,0x20,0x73,0x69,0x68,0x54]
+[84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108]
+[84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108,84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108,84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108,84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108]
+[84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108,84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108,84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108,84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108]
+[108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84]
+[108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84,108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84,108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84,108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84]
+[108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84,108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84,108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84,108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84]
+[84,104,105,115,32,115,116,114,105,110,103,32,105,115,32,99,111,111,108]
+[108,111,111,99,32,115,105,32,103,110,105,114,116,115,32,115,105,104,84]
var w = args.first.to_i
var h = w
-var byte_acc = 0u8
+var byte_acc = 0
var bit_num = 0
print("P4\n{w} {h}")
if zr*zr+zi*zi > limit*limit then
byte_acc = byte_acc << 1
else
- byte_acc = (byte_acc << 1) + 1u8
+ byte_acc = (byte_acc << 1) + 1
end
bit_num = bit_num + 1
if bit_num == 8 then
stdout.write_byte(byte_acc)
- byte_acc = 0u8
+ byte_acc = 0
bit_num = 0
else if x == w - 1 then
byte_acc = byte_acc << (8-w%8)
stdout.write_byte(byte_acc)
- byte_acc = 0u8
+ byte_acc = 0
bit_num = 0
end
end
var narr: Bytes
init do
- for x in [0 .. narr.length[ do narr[x] = 0xFFu8
+ for x in [0 .. narr.length[ do narr[x] = 0xFF
end
fun [](pos: Int): Bool do
pos -= 2
- return (narr[pos / 8] & (1u8 << (7 - pos % 8))) != 0u8
+ return (narr[pos / 8] & (1 << (7 - pos % 8))) != 0
end
fun []=(pos: Int, val: Bool) do
pos -= 2
if val then
- narr[pos / 8] |= 1u8 << (7 - pos % 8)
+ narr[pos / 8] |= 1 << (7 - pos % 8)
else
- narr[pos / 8] &= 0xFFu8 - (1u8 << (7 - pos % 8))
+ narr[pos / 8] &= 0xFF - (1 << (7 - pos % 8))
end
end
end
# See the License for the specific language governing permissions and
# limitations under the License.
-var c1 = b'G'
+var c1 = u'G'
var c2 = u'𐏓'
var s = b"String\x41\x42"
#alt1# writer.big_endian = false
#alt3# writer.big_endian = false
writer.write "hello"
-writer.write_byte 77u8
+writer.write_byte 77
writer.write_float 1.23456789
writer.write_double 1.23456789
writer.write_int64 123456789
l = 0
for i in fb.bytes do
- print "Byte {l} = {i}"
+ print "Byte {l} = 0x{i.to_hex}"
l += 1
end
l = fb.byte_length - 1
for i in fb.bytes.reverse_iterator do
- print "Byte {l} = {i}"
+ print "Byte {l} = 0x{i.to_hex}"
l -= 1
end
# limitations under the License.
var s = new CString(4)
-s[0] = 0x4Eu8
-s[2] = 0x74u8
-s[1] = 0x69u8
-s[3] = 0u8
+s[0] = 0x4E
+s[2] = 0x74
+s[1] = 0x69
+s[3] = 0
print s.class_name
print s[0]
print s.to_s
# See the License for the specific language governing permissions and
# limitations under the License.
-var ascii_char = b'A'
+var ascii_char = u'A'
var unicode_char = u'𐏓'
-#alt1 var bug_ascii = b'𐏓'
-
print ascii_char
print unicode_char