400 -} |
400 -} |
401 |
401 |
402 {-# LANGUAGE OverloadedStrings #-} |
402 {-# LANGUAGE OverloadedStrings #-} |
403 |
403 |
404 module Isabelle.Symbol ( |
404 module Isabelle.Symbol ( |
|
405 Symbol, eof, is_eof, not_eof, |
|
406 |
405 is_ascii_letter, is_ascii_digit, is_ascii_hex, is_ascii_quasi, |
407 is_ascii_letter, is_ascii_digit, is_ascii_hex, is_ascii_quasi, |
406 is_ascii_blank, is_ascii_line_terminator, is_ascii_letdig, |
408 is_ascii_blank, is_ascii_line_terminator, is_ascii_letdig, |
407 is_ascii_identifier, |
409 is_ascii_identifier, |
408 |
410 |
409 Symbol, explode |
411 explode |
410 ) |
412 ) |
411 where |
413 where |
412 |
414 |
413 import Data.Word (Word8) |
415 import Data.Word (Word8) |
414 import qualified Isabelle.Bytes as Bytes |
416 import qualified Isabelle.Bytes as Bytes |
415 import Isabelle.Bytes (Bytes) |
417 import Isabelle.Bytes (Bytes) |
416 |
418 |
417 |
419 |
|
420 {- type -} |
|
421 |
|
422 type Symbol = Bytes |
|
423 |
|
424 eof :: Symbol |
|
425 eof = "" |
|
426 |
|
427 is_eof, not_eof :: Symbol -> Bool |
|
428 is_eof = Bytes.null |
|
429 not_eof = not . is_eof |
|
430 |
|
431 |
418 {- ASCII characters -} |
432 {- ASCII characters -} |
419 |
433 |
420 is_ascii_letter :: Char -> Bool |
434 is_ascii_letter :: Char -> Bool |
421 is_ascii_letter c = 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' |
435 is_ascii_letter c = 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' |
422 |
436 |
442 is_ascii_identifier s = |
456 is_ascii_identifier s = |
443 not (null s) && is_ascii_letter (head s) && all is_ascii_letdig s |
457 not (null s) && is_ascii_letter (head s) && all is_ascii_letdig s |
444 |
458 |
445 |
459 |
446 {- explode symbols: ASCII, UTF8, named -} |
460 {- explode symbols: ASCII, UTF8, named -} |
447 |
|
448 type Symbol = Bytes |
|
449 |
461 |
450 is_utf8 :: Word8 -> Bool |
462 is_utf8 :: Word8 -> Bool |
451 is_utf8 b = b >= 128 |
463 is_utf8 b = b >= 128 |
452 |
464 |
453 is_utf8_trailer :: Word8 -> Bool |
465 is_utf8_trailer :: Word8 -> Bool |
1254 count_line "\n" line = if_valid line (line + 1) |
1266 count_line "\n" line = if_valid line (line + 1) |
1255 count_line _ line = line |
1267 count_line _ line = line |
1256 |
1268 |
1257 count_column :: Symbol -> Int -> Int |
1269 count_column :: Symbol -> Int -> Int |
1258 count_column "\n" column = if_valid column 1 |
1270 count_column "\n" column = if_valid column 1 |
1259 count_column _ column = if_valid column (column + 1) |
1271 count_column s column = if Symbol.not_eof s then if_valid column (column + 1) else column |
1260 |
1272 |
1261 count_offset :: Symbol -> Int -> Int |
1273 count_offset :: Symbol -> Int -> Int |
1262 count_offset _ offset = if_valid offset (offset + 1) |
1274 count_offset s offset = if Symbol.not_eof s then if_valid offset (offset + 1) else offset |
1263 |
1275 |
1264 symbol :: Symbol -> T -> T |
1276 symbol :: Symbol -> T -> T |
1265 symbol s pos = |
1277 symbol s pos = |
1266 pos { |
1278 pos { |
1267 _line = count_line s (_line pos), |
1279 _line = count_line s (_line pos), |