///|
fn Scanner::number(self : Scanner) -> Token? {
let start = self.pos
let mut end = start
if self.at(start) == 48 &&
(upper(self.at(start + 1)) == 88 || upper(self.at(start + 1)) == 66) {
let digits = if upper(self.at(start + 1)) == 88 {
"0123456789ABCDEFabcdef"
} else {
"01"
}
end = self.span(start + 2, digits)
return Some(self.take(if end == start + 2 { "n" } else { "1" }, start, end))
}
while digit(self.at(end)) {
end += 1
}
if self.at(end) == 46 {
end += 1
while digit(self.at(end)) {
end += 1
}
if end == start + 1 {
return Some(self.take(".", start, end))
}
}
let mut have_e = false
let mut have_exp = false
if upper(self.at(end)) == 69 {
have_e = true
end += 1
if self.at(end) == 43 || self.at(end) == 45 {
end += 1
}
while digit(self.at(end)) {
have_exp = true
end += 1
}
}
if upper(self.at(end)) == 68 || upper(self.at(end)) == 70 {
let next = self.at(end + 1)
if end + 1 == self.data.length() ||
white(next) ||
next == 59 ||
upper(next) == 85 {
end += 1
}
}
self.pos = end
if have_e && !have_exp {
None
} else {
Some(self.take("1", start, end))
}
}
///|
fn Scanner::binary_string(self : Scanner, binary : Bool) -> Token {
let start = self.pos
if start + 2 >= self.data.length() || self.at(start + 1) != 39 {
return self.word()
}
let end = self.span(
start + 2,
if binary {
"01"
} else {
"0123456789ABCDEFabcdef"
},
)
if self.at(end) != 39 {
return self.word()
}
self.take("1", start, end + 1)
}
///|
fn Scanner::qstring(self : Scanner, offset : Int) -> Token {
let start = self.pos + offset
if start + 2 >= self.data.length() ||
upper(self.at(start)) != 81 ||
self.at(start + 1) != 39 ||
self.at(start + 2) < 33 {
return self.word()
}
let ch = self.at(start + 2)
let delim = match ch {
40 => 41
91 => 93
123 => 125
60 => 62
_ => ch
}
let end = self.find_pair(start + 3, self.data.length(), delim, 39)
let t = self.take(
"s",
start + 3,
if end < 0 {
self.data.length()
} else {
end
},
)
t.open = 113
if end >= 0 {
t.close = 113
self.pos = end + 2
}
t
}
///|
fn Scanner::money(self : Scanner) -> Token {
let start = self.pos
if start + 1 == self.data.length() {
return self.take("n", start, start + 1)
}
let end = self.span(start + 1, "0123456789.,")
if end > start + 1 {
if end == start + 2 && self.at(start + 1) == 46 {
return self.word()
}
return self.take("1", start, end)
}
let tag_end = if self.at(start + 1) == 36 {
start + 1
} else {
self.span(start + 1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
}
if self.at(tag_end) != 36 || tag_end == start {
return self.take("n", start, start + 1)
}
if tag_end == start + 1 && self.at(start + 1) != 36 {
return self.take("n", start, start + 1)
}
let length = tag_end - start + 1
let mut close = tag_end + 1
while close + length <= self.data.length() {
if byte_slice(self.data, close, close + length) ==
byte_slice(self.data, start, tag_end + 1) {
break
}
close += 1
}
let found = close + length <= self.data.length()
let t = self.take(
"s",
tag_end + 1,
if found {
close
} else {
self.data.length()
},
)
t.open = 36
if found {
t.close = 36
self.pos = close + length
}
t
}