Pastey New style numbers and c-comments for get() and value()
- Posted by cargoan
Feb 16, 2015
--- get.e 2015-02-15 15:18:19.632576000 +0100
+++ get.e 2015-02-16 10:50:55.191956000 +0100
@@ -182,73 +182,103 @@
end if
end function
+
+function read_c_comment()
+ sequence comment = get_heredoc("*/")
+ if comment[1] = GET_SUCCESS then
+ return {GET_IGNORE, 0}
+ end if
+ return {GET_FAIL, 0}
+end function
+
+
function get_number()
-- read a number or a comment
-- ch is "live" at entry and exit
plus_or_minus sign, e_sign
- natural ndigits
- integer hex_digit
+ natural ndigits, base
+ integer base_digit
atom mantissa, dec, e_mag
- sequence number_string = { ch }
+ sequence number_string = {}
sign = +1
mantissa = 0
ndigits = 0
+ base = 10
-- process sign
if ch = '-' then
sign = -1
- get_ch()
number_string &= ch
+ get_ch()
if ch='-' then
return read_comment()
end if
elsif ch = '+' then
- get_ch()
number_string &= ch
+ get_ch()
end if
- -- get mantissa
+ while ch = '_' do
+ get_ch()
+ end while
+
+ -- get base
if ch = '#' then
- -- process hex integer and return
+ number_string &= ch
get_ch()
+ base = 16
+ elsif ch = '0' then
number_string &= ch
- while TRUE do
- hex_digit = find(ch, HEX_DIGITS)-1
- if hex_digit >= 0 then
- ndigits += 1
- mantissa = mantissa * 16 + hex_digit
get_ch()
+ if find(ch, "btx") then
+ if ch = 'b' then
+ base = 2
+ elsif ch = 't' then
+ base = 8
+ elsif ch ='x' then
+ base = 16
+ end if
number_string &= ch
+ get_ch()
else
- if ndigits > 0 then
- return {GET_SUCCESS, sign * mantissa}
- else
- return {GET_FAIL, 0}
- end if
+ ndigits += 1
end if
- end while
end if
- -- decimal integer or floating point
- while ch >= '0' and ch <= '9' do
+ -- get mantissa
+ while TRUE do
+ base_digit = find(ch - 32 * (ch >= 'a'), HEX_DIGITS[1..base] & '_') - 1
+ if base_digit >= 0 then
+ if base_digit < base then
ndigits += 1
- mantissa = mantissa * 10 + (ch - '0')
- get_ch()
+ mantissa = mantissa * base + base_digit
number_string &= ch
+ end if
+ get_ch()
+ else
+ exit
+ end if
end while
if ch = '.' then
-- get fraction
- get_ch()
number_string &= ch
- dec = 10
- while ch >= '0' and ch <= '9' do
- ndigits += 1
- mantissa += (ch - '0') / dec
- dec *= 10
get_ch()
+ dec = base
+ while TRUE do
+ base_digit = find(ch - 32 * (ch >= 'a'), HEX_DIGITS[1..base] & '_') - 1
+ if base_digit >= 0 then
+ if base_digit < base then
+ ndigits += 1
+ mantissa += base_digit / dec
+ dec *= base
number_string &= ch
+ end if
+ get_ch()
+ else
+ exit
+ end if
end while
end if
@@ -258,32 +288,35 @@
mantissa = sign * mantissa
- if ch = 'e' or ch = 'E' then
+ if base = 10 and (ch = 'e' or ch = 'E') then
-- get exponent sign
- get_ch()
number_string &= ch
- if ch = '-' then
get_ch()
- number_string &= ch
- elsif ch = '+' then
+ while ch = '_' do
get_ch()
+ end while
+ if ch = '-' or ch = '+' then
number_string &= ch
+ get_ch()
end if
-- get exponent magnitude
- if ch >= '0' and ch <= '9' then
-
- while ch >= '0' and ch <= '9' with entry do
+ ndigits = 0
+ while base_digit > 0 with entry do
+ if base_digit <= base then
+ ndigits += 1
number_string &= ch
- entry
+ end if
get_ch()
+ entry
+ base_digit = find(ch, DIGITS & '_')
end while
+ if ndigits > 0 then
+ mantissa = scientific_to_atom( number_string )
else
return {GET_FAIL, 0} -- no exponent
end if
-
- mantissa = scientific_to_atom( number_string )
end if
return {GET_SUCCESS, mantissa}
@@ -346,6 +379,14 @@
if ch = '}' then
get_ch()
return {GET_SUCCESS, s}
+ elsif ch = '/' then
+ get_ch()
+ if ch = '*' then -- C comment
+ e = read_c_comment()
+ if e[1] != GET_IGNORE then
+ return {GET_FAIL, 0}
+ end if
+ end if
elsif ch!='-' then
exit
else -- comment starts after item and before comma
@@ -368,6 +409,13 @@
return get_heredoc("`")
elsif ch = '\'' then
return get_qchar()
+ elsif ch = '/' then
+ get_ch()
+ if ch = '*' then
+ return read_c_comment()
+ else
+ return {GET_FAIL, 0}
+ end if
else
return {GET_FAIL, 0}
@@ -443,6 +491,14 @@
if ch = '}' then
get_ch()
return {GET_SUCCESS, s, string_next-1-offset-(ch!=-1), leading_whitespace}
+ elsif ch = '/' then -- comment starts after item and before comma
+ get_ch()
+ if ch = '*' then
+ e = read_c_comment()
+ if e[1] != GET_IGNORE then -- it wasn't a comment, this is illegal
+ return {GET_FAIL, 0}
+ end if
+ end if
elsif ch!='-' then
exit
else -- comment starts after item and before comma
@@ -468,6 +524,14 @@
elsif ch = '\'' then
e = get_qchar()
return e & {string_next-1-offset-(ch!=-1), leading_whitespace}
+ elsif ch = '/' then
+ get_ch()
+ if ch = '*' then
+ e = read_c_comment()
+ return e & {string_next-1-offset-(ch!=-1), leading_whitespace}
+ else
+ return {GET_FAIL, 0, string_next-1-offset-(ch!=-1), leading_whitespace}
+ end if
else
return {GET_FAIL, 0, string_next-1-offset-(ch!=-1), leading_whitespace}