readNumber reads an integer/float
(buf []byte)
| 1166 | |
| 1167 | // readNumber reads an integer/float |
| 1168 | func (t *Tokenizer) readNumber(buf []byte) (models.Token, error) { |
| 1169 | var start int |
| 1170 | if buf == nil { |
| 1171 | start = t.pos.Index |
| 1172 | } else { |
| 1173 | start = t.pos.Index - len(buf) |
| 1174 | } |
| 1175 | |
| 1176 | // Read integer part |
| 1177 | for t.pos.Index < len(t.input) { |
| 1178 | r, size := utf8.DecodeRune(t.input[t.pos.Index:]) |
| 1179 | if r < '0' || r > '9' { |
| 1180 | break |
| 1181 | } |
| 1182 | t.pos.AdvanceRune(r, size) |
| 1183 | } |
| 1184 | |
| 1185 | if t.pos.Index >= len(t.input) { |
| 1186 | return models.Token{ |
| 1187 | Type: models.TokenTypeNumber, |
| 1188 | Value: string(t.input[start:t.pos.Index]), |
| 1189 | }, nil |
| 1190 | } |
| 1191 | |
| 1192 | // Look for decimal point |
| 1193 | r, size := utf8.DecodeRune(t.input[t.pos.Index:]) |
| 1194 | if r == '.' { |
| 1195 | t.pos.AdvanceRune(r, size) |
| 1196 | |
| 1197 | // Must have at least one digit after decimal |
| 1198 | if t.pos.Index >= len(t.input) { |
| 1199 | value := string(t.input[start:t.pos.Index]) |
| 1200 | return models.Token{}, errors.InvalidNumberError(value+" (expected digit after decimal point)", t.getCurrentPosition(), string(t.input)) |
| 1201 | } |
| 1202 | |
| 1203 | r, _ = utf8.DecodeRune(t.input[t.pos.Index:]) |
| 1204 | if r < '0' || r > '9' { |
| 1205 | value := string(t.input[start:t.pos.Index]) |
| 1206 | return models.Token{}, errors.InvalidNumberError(value+" (expected digit after decimal point)", t.getCurrentPosition(), string(t.input)) |
| 1207 | } |
| 1208 | |
| 1209 | // Read fractional part |
| 1210 | for t.pos.Index < len(t.input) { |
| 1211 | r, size = utf8.DecodeRune(t.input[t.pos.Index:]) |
| 1212 | if r < '0' || r > '9' { |
| 1213 | _ = size // Mark as intentionally unused |
| 1214 | break |
| 1215 | } |
| 1216 | t.pos.AdvanceRune(r, size) |
| 1217 | } |
| 1218 | } |
| 1219 | |
| 1220 | // Look for exponent |
| 1221 | if t.pos.Index < len(t.input) { |
| 1222 | r, size = utf8.DecodeRune(t.input[t.pos.Index:]) |
| 1223 | if r == 'e' || r == 'E' { |
| 1224 | t.pos.AdvanceRune(r, size) |
| 1225 |
no test coverage detected