# Interpreter for Brainfuck source code.
class BFInterpreter
# Data cells
- var dr = new Array[Char]
+ var dr = new Array[Byte]
# Data pointer
var dp = 0
# Instruction pointer
var ip = 0
# The program being interpreted
- var program: String
-
- # Contains the set of valid instructions, used in next
- var valid_instr: Set[Char] is noinit
+ var program: Bytes
# Create an interpreter for `program`.
init do
- valid_instr = new HashSet[Char]
- valid_instr.add_all "><[].,+-".chars
- dr.add 0.ascii
+ dr.add 0u8
end
# Create an interpreter for the file located at `path`.
init from_file(path: String) do
var ifs = new FileReader.open(path)
- init(ifs.read_all)
+ init(ifs.read_all_bytes)
end
# Starts the interpretation of the loaded program
loop
if ip >= program.length then break
eval
- next
- end
- end
-
- # Go to the next executable instruction
- fun next do
- ip += 1
- while ip < program.length and not valid_instr.has(program[ip]) do
ip += 1
end
end
+
# Evaluates the current instruction
fun eval do
var instr = program[ip]
- if instr == '.' then printn dr[dp]
- if instr == '[' then
- if dr[dp] == 0.ascii then
+ if instr == '.'.ascii then printn dr[dp].ascii
+ if instr == '['.ascii then
+ if dr[dp] == 0u8 then
ip = find_matching_rbra
return
end
end
- if instr == ']' then
- if dr[dp] != 0.ascii then
+ if instr == ']'.ascii then
+ if dr[dp] != 0u8 then
ip = find_matching_lbra
return
end
end
- if instr == '>' then
+ if instr == '>'.ascii then
dp += 1
- if dp >= dr.length then dr.add(0.ascii)
+ if dp >= dr.length then dr.add(0u8)
end
- if instr == '<' then
+ if instr == '<'.ascii then
dp -= 1
if dp < 0 then abort
end
- if instr == '+' then
- dr[dp] = (dr[dp].ascii + 1).ascii
+ if instr == '+'.ascii then
+ dr[dp] = dr[dp] + 1u8
end
- if instr == '-' then
- dr[dp] = (dr[dp].ascii - 1).ascii
+ if instr == '-'.ascii then
+ dr[dp] = dr[dp] - 1u8
end
- if instr == ',' then
- dr[dp] = getc
+ if instr == ','.ascii then
+ dr[dp] = getc.ascii
end
end
var lbracnt = 0
loop
if pos > program.length then abort
- if program[pos] == ']' then
+ if program[pos] == ']'.ascii then
if lbracnt > 0 then
lbracnt -= 1
else
break
end
end
- if program[pos] == '[' then lbracnt += 1
+ if program[pos] == '['.ascii then lbracnt += 1
pos += 1
end
return pos
var rbracnt = 0
loop
if pos < 0 then abort
- if program[pos] == '[' then
+ if program[pos] == '['.ascii then
if rbracnt > 0 then
rbracnt -= 1
else
break
end
end
- if program[pos] == ']' then rbracnt += 1
+ if program[pos] == ']'.ascii then rbracnt += 1
pos -= 1
end
return pos
else if c >= 'A' and c <= 'I' then
var t = self.get(x,y)
assert t != null
- t.update(c.ascii-'A'.ascii+1)
+ t.update(c.code_point-'A'.code_point+1)
t.fixed = true
x += 1
else if c >= 'a' and c <= 'i' then
var t = self.get(x,y)
assert t != null
- t.update(c.ascii-'a'.ascii+1)
+ t.update(c.code_point-'a'.code_point+1)
x += 1
else if c >= '1' and c <= '9' then
rle = c.to_i
if k == 0 then
if t.fixed then c = '#'
else
- b.add(0x1b.ascii)
+ b.add(0x1b.code_point)
b.add('[')
b.append ansicols[k]
- c = (k + 'a'.ascii - 1).ascii
+ c = (k + 'a'.code_point - 1).code_point
if t.fixed then c = c.to_upper
b.append("m")
end
b.add(c)
if k != 0 then
- b.add(0x1b.ascii)
+ b.add(0x1b.code_point)
b.append("[0m")
end
else
add("\tredef fun trans(char) do\n")
- add("\t\tvar c = char.ascii\n")
+ add("\t\tvar c = char.code_point\n")
var haslast = false
var last = -1
for sym, next in trans do
if f <= 32 then
res = "#{f}"
else
- res = f.ascii.to_s
+ res = f.code_point.to_s
end
var l = last
if f == l then return res
res += " .. "
if l == null then return res
if l <= 32 or l >= 127 then return res + "#{l}"
- return res + l.ascii.to_s
+ return res + l.code_point.to_s
end
end
if text != null then
var nfa = new Automaton.epsilon
for c in text.chars do
- nfa.concat(new Automaton.atom(c.ascii))
+ nfa.concat(new Automaton.atom(c.code_point))
end
return nfa
end
do
var a = new Automaton.epsilon
for c in self.value.chars do
- var b = new Automaton.atom(c.ascii)
+ var b = new Automaton.atom(c.code_point)
a.concat(b)
end
return a
end
redef class Nch_dec
- redef fun value: String do return text.substring_from(1).to_i.ascii.to_s
+ redef fun value: String do return text.substring_from(1).to_i.code_point.to_s
redef fun make_rfa: Automaton
do
- var a = new Automaton.atom(self.value.chars.first.ascii)
+ var a = new Automaton.atom(self.value.chars.first.code_point)
return a
end
end
redef class Nch_hex
- redef fun value: String do return text.substring_from(2).to_hex.ascii.to_s
+ redef fun value: String do return text.substring_from(2).to_hex.code_point.to_s
redef fun make_rfa: Automaton
do
- var a = new Automaton.atom(self.value.chars.first.ascii)
+ var a = new Automaton.atom(self.value.chars.first.code_point)
return a
end
end
exit(1)
abort
end
- var a = new Automaton.cla(c1.chars.first.ascii, c2.chars.first.ascii)
+ var a = new Automaton.cla(c1.chars.first.code_point, c2.chars.first.code_point)
return a
end
end
# * `"0;32"` for green
fun colored_line(color: String): String
do
- var esc = 27.ascii
+ var esc = 27.code_point
var def = "{esc}[0m"
var col = "{esc}[{color}m"
end
redef class ACharValue
- redef fun to_i do return n_char.content.first.ascii
+ redef fun to_i do return n_char.content.first.code_point
end
redef class AStringValue
# legal but no not recommended
- redef fun to_i do return n_string.content.first.ascii
+ redef fun to_i do return n_string.content.first.code_point
end
redef class AHexValue
if sp >= string_len then
dfa_state = -1
else
- var c = string[sp].ascii
+ var c = string[sp].code_point
if c >= 255 then c = 255
sp += 1
continue
end
- out.add(((c.ascii + key[j].ascii - 2 * 'A'.ascii) % 26 + 'A'.ascii).ascii)
+ out.add(((c.ascii + key[j].ascii - 2u8 * 'A'.ascii) % 26u8 + 'A'.ascii).ascii)
j = (j + 1) % key.length
end
continue
end
- out.add(((c.ascii - key[j].ascii + 26) % 26 + 'A'.ascii).ascii)
+ out.add(((c.ascii - key[j].ascii + 26u8) % 26u8 + 'A'.ascii).ascii)
j = (j + 1) % key.length
end
# assert "string".encode_base64 == "c3RyaW5n"
private fun encode_base64(length: Int, padding: nullable Byte): Bytes do
var base64_bytes = once base64_chars
- if padding == null then padding = '='.ascii.to_b
+ if padding == null then padding = '='.ascii
var steps = length / 3
var bytes_in_last_step = length % 3
var result_length = steps * 4
#
# REQUIRE: `length % 4 == 0`
private fun decode_base64(length: Int, padding: nullable Byte): Bytes do
- if padding == null then padding = '='.ascii.to_b
+ if padding == null then padding = '='.ascii
var inv = once inverted_base64_chars
if length == 0 then return new Bytes.empty
assert length % 4 == 0 else print "base64::decode_base64 only supports strings of length multiple of 4"
#write(true, "C0".to_hex)
# instead we use the following which may not be portable
- for s in [count..40[ do write(false, ' '.ascii)
+ for s in [count..40[ do write(false, ' '.code_point)
count = 0
else
- write(false, c.ascii)
+ write(false, c.code_point)
count += 1
end
end
# Compared to `write_string`, this method supports null bytes in `text`.
fun write_block(text: Text)
do
- write_int64 text.length
+ write_int64 text.bytelen
write text
end
do
var length = read_int64
if length == 0 then return ""
- return read(length)
+ return read_bytes(length).to_s
end
# Read a floating point on 32 bits and return it as a `Float`
# The serialized data format uses a dictionary structure similar to BSON:
#
# ~~~raw
-# object = 0x01 # null
-# | 0x02 id attributes # New object
-# | 0x03 id # Ref to object
-# | 0x04 int64 # Int
-# | 0x05 int8 # Bool (int8 != 0)
-# | 0x06 int8 # Char
-# | 0x07 double(64 bits) # Float
-# | 0x08 block # String
-# | 0x09 block # NativeString
-# | 0x0A flat_array; # Array[nullable Object]
+# object = 0x01 # null
+# | 0x02 id attributes # New object
+# | 0x03 id # Ref to object
+# | 0x04 int64 # Int
+# | 0x05 int8 # Bool (int8 != 0)
+# | 0x06 utf8 byte sequence # Char
+# | 0x07 double(64 bits) # Float
+# | 0x08 block # String
+# | 0x09 block # NativeString
+# | 0x0A flat_array; # Array[nullable Object]
#
# block = int64 int8*;
# cstring = int8* 0x00;
# Tree of attributes, deserialized but not yet claimed
private var unclaimed_attributes = new UnrolledList[HashMap[String, nullable Object]]
+ # Buffer for one char
+ private var char_buf: NativeString is lazy do return new NativeString(4)
+
# Read and deserialize the next attribute name and value
#
# A `peeked_char` can suffix the next attribute name.
if kind == kind_bool then return stream.read_bool
if kind == kind_float then return stream.read_double
if kind == kind_char then
+ var bf = char_buf
var b = stream.read_byte
- if b == null then return 0
- return b.to_i.ascii
+ if b == null then return '�'
+ var ln = b.u8len
+ bf[0] = b
+ for i in [1 .. ln[ do
+ b = stream.read_byte
+ if b == null then return '�'
+ bf[i] = b
+ end
+ return bf.to_s_with_length(ln)[0]
end
if kind == kind_string then return stream.read_block
if kind == kind_native_string then return stream.read_block.to_cstring
redef fun serialize_to_binary(v)
do
v.stream.write_byte kind_char
- # Fix when UTF-8
- v.stream.write_byte self.ascii.to_b
+ for i in bytes do v.stream.write_byte i
end
end
var fw = new FileWriter.open(path)
# Write bitmap header
for x in [0..self.bitmap_header.length[ do
- fw.write(self.bitmap_header[x].ascii.to_s)
+ fw.write(self.bitmap_header[x].code_point.to_s)
end
# Write dib header
for x in [0..self.dib_header.length[ do
- fw.write(self.dib_header[x].ascii.to_s)
+ fw.write(self.dib_header[x].code_point.to_s)
end
# Write color table (if any)
# Write data (no padding for now)
var red = pixel >> 16
var green = (pixel & 0x00FF00) >> 8
var blue = pixel & 0x000000FF
- fw.write(red.ascii.to_s)
- fw.write(green.ascii.to_s)
- fw.write(blue.ascii.to_s)
+ fw.write(red.code_point.to_s)
+ fw.write(green.code_point.to_s)
+ fw.write(blue.code_point.to_s)
end
end
fw.close
redef fun substrings do return new LeafSubstrings(self)
- redef fun [](i) do return buf[i].to_i.ascii
+ redef fun [](i) do return buf[i].to_i.code_point
init do
bns = buf.ns
# A ANSI/VT100 escape sequence.
abstract class TermEscape
# The US-ASCII ESC character.
- protected fun esc: Char do return 27.ascii
+ protected fun esc: Char do return 27.code_point
# The Control Sequence Introducer (CSI).
protected fun csi: String do return "{esc}["
#
# ~~~nit
# intrude import core::bytes
- # assert not '/'.ascii.to_b.is_valid_hexdigit
- # assert '0'.ascii.to_b.is_valid_hexdigit
- # assert '9'.ascii.to_b.is_valid_hexdigit
- # assert not ':'.ascii.to_b.is_valid_hexdigit
- # assert not '@'.ascii.to_b.is_valid_hexdigit
- # assert 'A'.ascii.to_b.is_valid_hexdigit
- # assert 'F'.ascii.to_b.is_valid_hexdigit
- # assert not 'G'.ascii.to_b.is_valid_hexdigit
- # assert not '`'.ascii.to_b.is_valid_hexdigit
- # assert 'a'.ascii.to_b.is_valid_hexdigit
- # assert 'f'.ascii.to_b.is_valid_hexdigit
- # assert not 'g'.ascii.to_b.is_valid_hexdigit
+ # 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
# ~~~
private fun is_valid_hexdigit: Bool do
return (self >= 0x30u8 and self <= 0x39u8) or
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 `{ return self >> i; `}
+ # Returns the character equivalent of `self`
+ #
+ # REQUIRE: `self <= 127u8`
+ fun ascii: Char `{ return (uint32_t)self; `}
+
redef fun to_i is intern
redef fun to_f is intern
redef fun to_b do return self
do
assert self >= 0 and self <= 36 # TODO plan for this
if self < 10 then
- return (self + '0'.ascii).ascii
+ return (self + '0'.code_point).code_point
else
- return (self + ('a'.ascii - 10)).ascii
+ return (self - 10 + 'a'.code_point).code_point
end
end
printf("%c", self);
}
`}
- redef fun hash do return ascii
+ redef fun hash do return code_point
redef fun ==(o) is intern
redef fun !=(o) is intern
redef fun distance(c)
do
- var d = self.ascii - c.ascii
+ var d = self.code_point - c.code_point
if d >= 0 then
return d
else
if self == '-' then
return -1
else if is_digit then
- return self.ascii - '0'.ascii
+ return self.code_point - '0'.code_point
else
- return self.to_lower.ascii - 'a'.ascii + 10
+ return self.to_lower.code_point - 'a'.code_point + 10
end
end
fun to_lower: Char
do
if is_upper then
- return (ascii + ('a'.distance('A'))).ascii
+ return (code_point + ('a'.distance('A'))).code_point
else
return self
end
fun to_upper: Char
do
if is_lower then
- return (ascii - ('a'.distance('A'))).ascii
+ return (code_point - ('a'.distance('A'))).code_point
else
return self
end
# assert '\t'.is_whitespace == true
fun is_whitespace: Bool
do
- var i = ascii
+ var i = code_point
return i <= 0x20 or i == 0x7F
end
end
# ~~~
# var w = new StringReader(" Hello, \n\t World!")
# assert w.read_word == "Hello,"
- # assert w.read_char == '\n'.ascii
+ # assert w.read_char == '\n'
# assert w.read_word == "World!"
# assert w.read_word == ""
# ~~~
return null
end
# TODO: Fix when supporting UTF-8
- var c = _buffer[_buffer_pos].to_i.ascii
+ var c = _buffer[_buffer_pos].to_i.code_point
_buffer_pos += 1
return c
end
if c >= '0' and c <= '9' then
res.add('_')
- res.append(c.ascii.to_s)
+ res.append(c.code_point.to_s)
res.add('d')
start = 1
end
continue
end
if underscore then
- res.append('_'.ascii.to_s)
+ res.append('_'.code_point.to_s)
res.add('d')
end
if c >= '0' and c <= '9' then
underscore = true
else
res.add('_')
- res.append(c.ascii.to_s)
+ res.append(c.code_point.to_s)
res.add('d')
underscore = false
end
end
if underscore then
- res.append('_'.ascii.to_s)
+ res.append('_'.code_point.to_s)
res.add('d')
end
return res.to_s
# Three digits are always used to avoid following digits to be interpreted as an element
# of the octal sequence.
#
- # assert "{0.ascii}{1.ascii}{8.ascii}{31.ascii}{32.ascii}".escape_to_c == "\\000\\001\\010\\037 "
+ # assert "{0.code_point}{1.code_point}{8.code_point}{31.code_point}{32.code_point}".escape_to_c == "\\000\\001\\010\\037 "
#
# The exceptions are the common `\t` and `\n`.
fun escape_to_c: String
b.append("\\\'")
else if c == '\\' then
b.append("\\\\")
- else if c.ascii < 32 then
+ else if c.code_point < 32 then
b.add('\\')
- var oct = c.ascii.to_base(8, false)
+ var oct = c.code_point.to_base(8, false)
# Force 3 octal digits since it is the
# maximum allowed in the C specification
if oct.length == 1 then
else if c == ':' or c == ' ' or c == '#' then
b.add('\\')
b.add(c)
- else if c.ascii < 32 or c == ';' or c == '|' or c == '\\' or c == '=' then
- b.append("?{c.ascii.to_base(16, false)}")
+ else if c.code_point < 32 or c == ';' or c == '|' or c == '\\' or c == '=' then
+ b.append("?{c.code_point.to_base(16, false)}")
else
b.add(c)
end
# assert s.length == 2
# var u = s.unescape_nit
# assert u.length == 1
- # assert u.chars[0].ascii == 10 # (the ASCII value of the "new line" character)
+ # assert u.chars[0].code_point == 10 # (the ASCII value of the "new line" character)
fun unescape_nit: String
do
var res = new Buffer.with_cap(self.length)
if c == '%' then
if i + 2 >= length then
# What follows % has been cut off
- buf[l] = '?'.ascii.to_b
+ buf[l] = '?'.ascii
else
i += 1
var hex_s = substring(i, 2)
i += 1
else
# What follows a % is not Hex
- buf[l] = '?'.ascii.to_b
+ buf[l] = '?'.ascii
i -= 1
end
end
- else buf[l] = c.ascii.to_b
+ else buf[l] = c.ascii
i += 1
l += 1
for i in [0..length[ do
var char = chars[i]
- h = (h << 5) + h + char.ascii
+ h = (h << 5) + h + char.code_point
end
hash_cache = h
redef class Char
+ # Returns a sequence with the UTF-8 bytes of `self`
+ #
+ # assert 'a'.bytes == [0x61u8]
+ # assert 'ま'.bytes == [0xE3u8, 0x81u8, 0xBEu8]
+ fun bytes: SequenceRead[Byte] do return to_s.bytes
+
# Length of `self` in a UTF-8 String
private fun u8char_len: Int do
- var c = self.ascii
+ var c = self.code_point
if c < 0x80 then return 1
if c <= 0x7FF then return 2
if c <= 0xFFFF then return 3
end
var ok_c: Bool
var c = char_at(pos)
- var cp = c.ascii
+ var cp = c.code_point
if nxst == 1 then
ok_c = cp >= 0 and cp <= 0x7F
else if nxst == 2 then
redef class Byte
# Gives the length of the UTF-8 char starting with `self`
- private fun u8len: Int do
+ fun u8len: Int do
if self & 0b1000_0000u8 == 0u8 then
return 1
else if self & 0b1110_0000u8 == 0b1100_0000u8 then
rp = 0
end
# TODO: Fix when supporting UTF-8
- ns[rp] = c.ascii.to_b
+ ns[rp] = c.ascii
rp += 1
_bytelen += 1
rpos = rp
x = x % 26
if x < 0 then x += 26
var up = false
- var val = ascii
+ var val = code_point
if is_upper then
up = true
val += 32
val += x
if val > 122 then val -= 26
if up then val -= 32
- return val.ascii
+ return val.code_point
end
end
private class DFAState0
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 8 then return null
if c <= 10 then return dfastate_1
if c <= 31 then return null
return null
end
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 8 then return null
if c <= 10 then return dfastate_1
if c <= 31 then return null
private class DFAState2
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 33 then return dfastate_2
if c <= 34 then return dfastate_29
if c <= 91 then return dfastate_2
private class DFAState4
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_5
return null
return t
end
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 45 then return null
if c <= 46 then return dfastate_24
if c <= 47 then return null
private class DFAState9
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 96 then return null
if c <= 97 then return dfastate_20
return null
private class DFAState10
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 116 then return null
if c <= 117 then return dfastate_17
return null
private class DFAState11
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 113 then return null
if c <= 114 then return dfastate_14
return null
private class DFAState14
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 116 then return null
if c <= 117 then return dfastate_15
return null
private class DFAState15
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 100 then return null
if c <= 101 then return dfastate_16
return null
private class DFAState17
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 107 then return null
if c <= 108 then return dfastate_18
return null
private class DFAState18
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 107 then return null
if c <= 108 then return dfastate_19
return null
private class DFAState20
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 107 then return null
if c <= 108 then return dfastate_21
return null
private class DFAState21
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 114 then return null
if c <= 115 then return dfastate_22
return null
private class DFAState22
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 100 then return null
if c <= 101 then return dfastate_23
return null
private class DFAState24
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_28
return null
private class DFAState25
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 42 then return null
if c <= 43 then return dfastate_26
if c <= 44 then return null
private class DFAState26
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_27
return null
return t
end
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_27
return null
return t
end
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_28
if c <= 68 then return null
private class DFAState30
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 33 then return null
if c <= 34 then return dfastate_2
if c <= 46 then return null
private class DFAState31
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_32
if c <= 64 then return null
private class DFAState32
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_33
if c <= 64 then return null
private class DFAState33
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_34
if c <= 64 then return null
private class DFAState34
super DFAState
redef fun trans(char) do
- var c = char.ascii
+ var c = char.code_point
if c <= 47 then return null
if c <= 57 then return dfastate_2
if c <= 64 then return null
buffer.append "\\\""
else if char == '\/' then
buffer.append "\\/"
- else if char < 16.ascii then
+ else if char < 16.code_point then
if char == '\n' then
buffer.append "\\n"
else if char == '\r' then
buffer.append "\\r"
else if char == '\t' then
buffer.append "\\t"
- else if char == 0x0C.ascii then
+ else if char == 0x0C.code_point then
buffer.append "\\f"
- else if char == 0x08.ascii then
+ else if char == 0x08.code_point then
buffer.append "\\b"
else
- buffer.append "\\u000{char.ascii.to_hex}"
+ buffer.append "\\u000{char.code_point.to_hex}"
end
else if char < ' ' then
- buffer.append "\\u00{char.ascii.to_hex}"
+ buffer.append "\\u00{char.code_point.to_hex}"
else
buffer.add char
end
i += 1
char = text[i]
if char == 'b' then
- char = 0x08.ascii
+ char = 0x08.code_point
else if char == 'f' then
- char = 0x0C.ascii
+ char = 0x0C.code_point
else if char == 'n' then
char = '\n'
else if char == 'r' then
if code >= 128 then
char = '?'
else
- char = code.ascii
+ char = code.code_point
end
i += 4
end
do
var str = number.to_s
for c in str.chars do
- var d = c.ascii-'0'.ascii
+ var d = c.code_point-'0'.code_point
assert d >= 0 and d <= 9
var img = imgs.imgs[d]
blit(img, x, y)
# read the next byte. Else, return `-1`.
fun expect_delimiter: Int do
if accept('"') then
- return '"'.ascii
+ return '"'.code_point
else if accept('\'') then
- return '\''.ascii
+ return '\''.code_point
else
fire_unexpected_char(". Expecting `\"` or `'`")
return -1
# If the last read byte is forbidden, fire a fatal error instead.
fun expect_xml_char(buffer: Buffer): Bool do
if is_xml_char then
- buffer.chars.push(last_char.ascii)
+ buffer.chars.push(last_char.code_point)
read_char
return true
else if eof then
buffer.chars.push(' ')
read_char
return true
- else if last_char == '<'.ascii then
+ else if last_char == '<'.code_point then
return fire_fatal_error("`<` is forbidden in attribute values.")
else
return expect_xml_char(buffer)
# Is the last read byte matches the `NameStartChar` production?
fun is_name_start_char: Bool do
# TODO: Handle code points above 0x7F.
- return ['A'.ascii .. 'Z'.ascii].has(last_char) or
- ['a'.ascii .. 'z'.ascii].has(last_char) or
- last_char == '_'.ascii or
- last_char == ':'.ascii or
+ return ['A'.code_point .. 'Z'.code_point].has(last_char) or
+ ['a'.code_point .. 'z'.code_point].has(last_char) or
+ last_char == '_'.code_point or
+ last_char == ':'.code_point or
last_char > 127
end
fun is_name_char: Bool do
# TODO: Handle code points above 0x7F.
return is_name_start_char or
- last_char == '-'.ascii or
- last_char == '.'.ascii or
+ last_char == '-'.code_point or
+ last_char == '.'.code_point or
is_digit
end
if not is_name_start_char then
return fire_unexpected_char(" at the beginning of a name")
end
- buffer.chars.push(last_char.ascii)
+ buffer.chars.push(last_char.code_point)
read_char
while is_name_char do
- buffer.chars.push(last_char.ascii)
+ buffer.chars.push(last_char.code_point)
read_char
end
return true
# Is the last read byte matches the `[0-9]` production?
fun is_digit: Bool do
- return ['0'.ascii .. '9'.ascii].has(last_char)
+ return ['0'.code_point .. '9'.code_point].has(last_char)
end
# Accept a `[0-9]+` token.
fun accept_digits(buffer: Buffer): Bool do
if is_digit then
loop
- buffer.chars.push(last_char.ascii)
+ buffer.chars.push(last_char.code_point)
read_char
if not is_digit then return true
end
# Is `last_char` matches the `[0-9a-fA-F]` production?
fun is_hex: Bool do
- return ['0'.ascii .. '9'.ascii].has(last_char) or
- ['A'.ascii .. 'Z'.ascii].has(last_char) or
- ['a'.ascii .. 'Z'.ascii].has(last_char)
+ return ['0'.code_point .. '9'.code_point].has(last_char) or
+ ['A'.code_point .. 'Z'.code_point].has(last_char) or
+ ['a'.code_point .. 'Z'.code_point].has(last_char)
end
# Expect a `[0-9a-fA-F]+` token.
fun expect_hex(buffer: Buffer): Bool do
if is_hex then
loop
- buffer.chars.push(last_char.ascii)
+ buffer.chars.push(last_char.code_point)
read_char
if not is_hex then return true
end
else if last_char < 0 then
fire_fatal_error("Internal error: Already at the end of the file.")
return
- else if last_char == '\n'.ascii then
+ else if last_char == '\n'.code_point then
locator.line_number += 1
locator.column_number = 1
else
# XML 1.0 end-of-line handling
# Note: Regardless the XML version, any EOL defined by the
# recommandation MUST be reported as a single LINE FEED.
- if was_cr and last_char == '\n'.ascii then
+ if was_cr and last_char == '\n'.code_point then
# EOL already reported. => Skip this byte.
s = input.read_byte
if s == null then
last_char = s.to_i
end
end
- was_cr = last_char == '\r'.ascii
+ was_cr = last_char == '\r'.code_point
if was_cr then
# Regardless the following byte, '\r' always introduce an EOL.
- last_char = '\n'.ascii
+ last_char = '\n'.code_point
end
end
fun is_int(c: Int): Bool do return last_char == c
# Does the last read byte equal `c`?
- fun is_char(c: Char): Bool do return last_char == c.ascii
+ fun is_char(c: Char): Bool do return last_char == c.code_point
# Expect the specified byte.
fun accept_int(expected: Int): Bool do
# Accept the specified byte.
fun accept(expected: Char): Bool do
- return accept_int(expected.ascii)
+ return accept_int(expected.code_point)
end
# Ensure the last read byte is equal to `expected`.
# Return `true` if and only if the last read byte as the expected value.
fun expect_int(expected: Int, context: String): Bool do
return accept_int(expected) or
- fire_unexpected_char("{context}. Expecting `{expected.ascii}`.")
+ fire_unexpected_char("{context}. Expecting `{expected.code_point}`.")
end
# Ensure the last read byte is equal to `expected`.
if not accept(chars[i]) then
if is_xml_char then
return fire_fatal_error("Unexpected " +
- "`{expected.substring(0, i)}{last_char.ascii.to_s}`" +
+ "`{expected.substring(0, i)}{last_char.code_point.to_s}`" +
"{context}. Expecting `{expected}`.")
else if eof then
return fire_fatal_error("Unexpected end of file{context}. " +
# Return `false`.
fun fire_unexpected_char(rest_of_message: String): Bool do
if is_xml_char then
- return fire_fatal_error("Unexpected character `{last_char.ascii.to_s}`{rest_of_message}.")
+ return fire_fatal_error("Unexpected character `{last_char.code_point.to_s}`{rest_of_message}.")
else if eof then
return fire_fatal_error("Unexpected end of file{rest_of_message}.")
else
if lexer.accept('#') then
if lexer.accept('x') then
if lexer.expect_hex(ref) then
- buffer.chars.add(ref.to_hex.ascii)
+ buffer.chars.add(ref.to_hex.code_point)
return lexer.expect(';', "")
else
return lexer.fire_unexpected_char(
". Expecting an hexadecimal digit")
end
else if lexer.accept_digits(ref) then
- buffer.chars.add(ref.to_i.ascii)
+ buffer.chars.add(ref.to_i.code_point)
return lexer.expect(';', "")
else
return lexer.fire_unexpected_char(" in a character reference. " +
do
var t = mmodule.char_type
- if value.ascii < 128 then
+ if value.code_point < 128 then
return new RuntimeVariable("'{value.to_s.escape_to_c}'", t, t)
else
- return new RuntimeVariable("{value.ascii}", t, t)
+ return new RuntimeVariable("{value.code_point}", t, t)
end
end
b.append("\\\\")
else if c == '`' then
b.append("'")
- else if c.ascii < 32 then
- b.append("\\{c.ascii.to_base(8, false)}")
+ else if c.code_point < 32 then
+ b.append("\\{c.code_point.to_base(8, false)}")
else
b.add(c)
end
return v.bool_instance(recvval >= args[1].to_i)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_i)
- else if pname == "ascii" then
- return v.char_instance(recvval.ascii)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_b" then
end
else if cname == "Char" then
var recv = args[0].val.as(Char)
- if pname == "ascii" then
- return v.int_instance(recv.ascii)
- else if pname == "successor" then
+ if pname == "successor" then
return v.char_instance(recv.successor(args[1].to_i))
else if pname == "predecessor" then
return v.char_instance(recv.predecessor(args[1].to_i))
# * `"0;32"` for green
fun colored_line(color: String): String
do
- var esc = 27.ascii
+ var esc = 27.code_point
var def = "{esc}[0m"
var col = "{esc}[{color}m"
# This does not corrupt the lexer and works perfectly on any character.
#
# TL;DR: Java fucked up, need retarded solution to cope for retarded decision
- var c = string[sp].ascii
+ var c = string[sp].code_point
if c >= 256 then c = 255
sp += 1
# A colored version of the message including the original source line
fun to_color_string: String
do
- var esc = 27.ascii
+ var esc = 27.code_point
#var red = "{esc}[0;31m"
#var bred = "{esc}[1;31m"
#var green = "{esc}[0;32m"
o = _c
(o == null).output
(not o == '\0').output
- #alt3#_c.ascii.output
+ #alt3#_c.code_point.output
end
end
../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--697,3: Error: `kernel#Byte` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:699,1--884,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:886,1--1039,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
-../lib/core/kernel.nit:1041,1--1048,3: Error: `kernel#Pointer` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:601,1--702,3: Error: `kernel#Byte` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:704,1--890,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:892,1--1060,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:1062,1--1069,3: Error: `kernel#Pointer` 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:720)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
11
21
31
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:720)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
11
21
31
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:720)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:725)
11
21
31
Numeric -> Float [dir=back arrowtail=open style=dashed];
Byte [
- label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l}"
+ label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ ascii(): Char\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+ ascii(): 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}"
]
Discrete -> Int [dir=back arrowtail=open style=dashed];
Numeric -> Int [dir=back arrowtail=open style=dashed];
Char [
- label = "{Char||+ to_i(): Int\l+ ascii(): Int\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||+ 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}"
]
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}"
+ label = "{Byte||+ %(i: Byte): Byte\l+ \<\<(i: Int): Byte\l+ \>\>(i: Int): Byte\l+ ascii(): Char\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+ ascii(): 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}"
]
Discrete -> Int [dir=back arrowtail=open style=dashed];
Numeric -> Int [dir=back arrowtail=open style=dashed];
Char [
- label = "{Char||+ to_i(): Int\l+ ascii(): Int\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||+ 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}"
]
Discrete -> Char [dir=back arrowtail=open style=dashed];
var a = "éè"
print(a.length)
for i in [0..a.length[ do
- print("{i} is {a.chars[i]} ({a.chars[i].ascii})")
+ print("{i} is {a.chars[i]} ({a.chars[i].code_point})")
end
import core
var s = "𐏓".as(FlatString)
-print s.items.char_at(0).ascii.to_hex
-print s.items.char_at(4).ascii.to_hex
+print s.items.char_at(0).code_point.to_hex
+print s.items.char_at(4).code_point.to_hex