summaryrefslogtreecommitdiff
path: root/stream.sml
diff options
context:
space:
mode:
authorVladimir Azarov <avm@intermediate-node.net>2025-03-24 22:37:21 +0100
committerVladimir Azarov <avm@intermediate-node.net>2025-03-24 22:37:21 +0100
commit226f58656b4b7f92f6de9a817ab9106937e061e9 (patch)
treed2e4c23e520d99c59685d18b24058f8a45def43e /stream.sml
parent87217fe5ba58f5199d30586b5d9bec104dece445 (diff)
Simplified stream
Diffstat (limited to 'stream.sml')
-rw-r--r--stream.sml155
1 files changed, 40 insertions, 115 deletions
diff --git a/stream.sml b/stream.sml
index 10b02cc..92deb61 100644
--- a/stream.sml
+++ b/stream.sml
@@ -2,20 +2,12 @@ structure Stream :> STREAM = struct
type fileId = int
type fileOffset = int
type pos = fileId * fileOffset
- type convPos = string * int * int option
+ type ppos = string * int * int option
+ type fileInfo = fileId * string * string
- type filesInfo = (fileId * string * string) list
+ exception UngetcError
- exception EndOfStream
- exception EndOfFile
-
- (* unreachable *)
- exception InvalidStream
- exception InvalidStreamAdvance
-
- exception LineWithoutNl
-
- fun pos2str (pos, line, col) =
+ fun ppos2str (pos, line, col) =
let
val % = Int.toString
in
@@ -24,14 +16,9 @@ structure Stream :> STREAM = struct
| NONE => pos ^ ":" ^ %line
end
- type t = {
- (* stack of file ids, file offsets and file contents *)
- stack: (fileId * fileOffset * string) list,
- (* list of file ids, file names and file contents *)
- allFiles: filesInfo
- }
+ type t = fileId * string * fileOffset * string
- fun extractFilesInfo (s: t) = #allFiles s
+ fun recycle (fid, fname, _, contents) = (fid, fname, contents)
fun calcFilePos s offset =
let
@@ -46,20 +33,13 @@ structure Stream :> STREAM = struct
calc s 0 offset (1, 1)
end
- fun printPos fileList (id, pos) =
+ fun printPos (_, fname, contents) (_, pos) =
let
- val triple = List.find (fn (fid, _, _) => fid = id) fileList
+ val (line, col) = calcFilePos contents pos
+ val line = Int.toString line
+ val col = Int.toString col
in
- case triple of
- NONE => raise InvalidStream
- | SOME (_, fname, contents) =>
- let
- val (line, col) = calcFilePos contents pos
- val line = Int.toString line
- val col = Int.toString col
- in
- print $ fname ^ ":" ^ line ^ ":" ^ col ^ ": "
- end
+ print $ fname ^ ":" ^ line ^ ":" ^ col ^ ": "
end
fun readFile fname =
@@ -72,114 +52,59 @@ structure Stream :> STREAM = struct
s
end
- fun getchar
- ({ stack = (id, off, contents) :: rest, allFiles }: t)
- : (char * t) =
+ fun getchar (S as (fid, fname, off, contents)) =
if off < String.size contents then
- (String.sub (contents, off),
- { stack = (id, off + 1, contents) :: rest, allFiles })
+ (SOME $ String.sub (contents, off), (fid, fname, off + 1, contents))
else
- raise EndOfFile
- | getchar _ = raise EndOfStream
+ (NONE, S)
- fun ungetc
- ({ stack = (id, off, contents) :: rest, allFiles }) =
+ fun ungetc (fid, fname, off, contents) =
if off = 0 then
- raise InvalidStream
+ raise UngetcError
else
- { stack = (id, off - 1, contents) :: rest, allFiles }
- | ungetc _ = raise InvalidStream
-
- fun readline { stack = (fid, off, contents) :: rest, allFiles } =
- let
- val prevIsSlash =
- off > 0 andalso String.sub (contents, off - 1) = #"\\"
-
- open String
- fun read prevIsSlash offset acc =
- let
- val c = sub (contents, offset)
- in
- if offset = size contents then
- raise LineWithoutNl
- else if c = #"\n" then
- if prevIsSlash then
- read (c = #"\\") (offset + 1) (#" " :: tl acc)
- else
- (implode $ rev acc, offset + 1)
- else
- read (c = #"\\") (offset + 1) (c :: acc)
- end
-
- val (arg, newOffset) = read prevIsSlash off []
- in
- (arg, { stack = (fid, newOffset, contents) :: rest, allFiles })
- end
- | readline _ = raise InvalidStream
+ (fid, fname, off - 1, contents)
- fun getOffset ({ stack = (_, off, _) :: _, ... }: t) = off
- | getOffset _ = raise InvalidStream
+ fun getOffset (_, _, off, _) = off
- fun getPosAfterCharRead
- ({ stack = (id, off, _) :: _, ... }: t) = (id, off - 1)
- | getPosAfterCharRead _ = raise InvalidStream
+ fun getPosAfterCharRead (fid, _, off, _) = (fid, off - 1)
- fun getPposFromPos (id, pos)
- { stack = (_, _, _) :: _, allFiles} =
+ fun getPposFromPos (_, pos) (_, fname, _, contents) =
let
- val (fname, contents) =
- case List.find (fn (fid, _, _) => fid = id) allFiles of
- NONE => raise InvalidStream
- | SOME (_, fname, contents) => (fname, contents)
-
val (line, col) = calcFilePos contents pos
in
(fname, line, SOME col)
end
- | getPposFromPos _ _ = raise InvalidStream
- fun getPos ({ stack = (id, off, _) :: _, ... }: t) = (id, off)
- | getPos _ = raise InvalidStream
+ fun pposWithoutCol (fname, line, SOME _) = (fname, line, NONE)
+ | pposWithoutCol (_, _, NONE) = raise Unreachable
- fun getSubstr startOff endOff
- ({ stack = (_, _, contents) :: _, ... }: t) =
- String.substring (contents, startOff, endOff - startOff)
- | getSubstr _ _ _ = raise InvalidStream
+ fun getPos (id, _, off, _) = (id, off)
- fun advanceToNewFile
- ({ stack = (_, off, contents) :: rest, allFiles }: t) =
- if off = String.size contents then
- { stack = rest, allFiles }
- else
- raise InvalidStreamAdvance
- | advanceToNewFile _ = raise InvalidStreamAdvance
+ fun getSubstr startOff endOff (_, _, _, contents) =
+ String.substring (contents, startOff, endOff - startOff)
fun streamInit fname =
let
val contents = readFile fname
in
- { allFiles = [(0, fname, contents)], stack = [(0, 0, contents)] }
+ (0, fname, 0, contents)
end
- fun isFirstOnLine (id, offset) (stream: t) =
- case List.find (fn (fid, _, _) => id = fid) (#allFiles stream) of
- NONE => raise InvalidStream
- | SOME (_, _, contents) =>
+ fun isFirstOnLine (_, offset) ((_, _, _, contents) : t) =
+ let
+ fun returnToNL ~1 = true
+ | returnToNL offset =
let
- fun returnToNL ~1 = true
- | returnToNL offset =
- let
- val chr = String.sub (contents, offset)
- in
- if chr = #"\n" then
- true
- else if Char.isSpace chr then
- returnToNL (offset - 1)
- else
- false
- end
+ val chr = String.sub (contents, offset)
in
- returnToNL (offset - 1)
+ if chr = #"\n" then
+ true
+ else if Char.isSpace chr then
+ returnToNL (offset - 1)
+ else
+ false
end
-
+ in
+ returnToNL (offset - 1)
+ end
end