1 (* Copyright (C
) 1999-2006 Henry Cejtin
, Matthew Fluet
, Suresh
2 * Jagannathan
, and Stephen Weeks
.
4 * MLton is released under a BSD
-style license
.
5 * See the file MLton
-LICENSE for details
.
15 fun pos (T
{pos
, ...}) = pos
18 val numChars
: int = 15
20 fun layout (T
{string, pos
}) =
21 String.layout (String.substring1 (string, {start
= pos
, length
= numChars
}))
24 fun length (T
{string, ...}) = String.size
string
25 fun isAtBeginning (m
: t
): bool = pos m
= 0
26 fun isAtEnd (m
: t
): bool = pos m
= length m
- 1
27 fun diff (m
: t
, m
': t
): int = pos m
- pos m
'
29 fun fromString s
= T
{string = s
, pos
= 0}
30 fun fromFile f
= fromString (File
.contents f
)
32 fun beginning (T
{string, ...}) = T
{string = string, pos
= 0}
34 exception BackwardChars
35 fun backwardChars (T
{string, pos
},n
) =
37 in if pos
< 0 then raise BackwardChars
38 else T
{string = string, pos
= pos
}
40 fun backwardChar m
= backwardChars (m
, 1)
41 val backwardChar
= Trace
.trace ("Mark.backwardChar", layout
, layout
) backwardChar
43 exception ForwardChars
44 fun forwardChars (T
{string, pos
},n
) =
46 in if pos
> String.size
string then raise ForwardChars
47 else T
{string = string, pos
= pos
}
49 fun forwardChar m
= forwardChars (m
, 1)
50 val forwardChar
= Trace
.trace ("Mark.forwardChar", layout
, layout
) forwardChar
52 fun charAt (T
{string, pos
}) = String.sub (string, pos
)
54 fun lookingAtChar (m
, c
) = Char.equals (charAt m
, c
)
57 fun searchChar
move (m
, c
) =
60 if lookingAtChar (m
, c
) then m
else loop (move m
)
64 val searchCharForward
= searchChar forwardChar
65 fun searchCharBackward (m
, c
) =
66 searchChar
backwardChar (backwardChar m
, c
)
69 fun bol m
= forwardChar (searchCharBackward (m
, #
"\n"))
70 handle _
=> beginning m
72 fun eol m
= searchCharForward (m
, #
"\n")
74 fun whatColumn m
= diff (m
, bol m
)
76 fun numColumns m
= diff (eol m
, bol m
)
81 fun moves (m
as T
{string, pos
}, n
: int) =
85 if n
<= 0 then forwardChars (m
, Int.min (c
, numColumns m
))
86 else loop (move m
, n
- 1)
89 fun move m
= moves (m
, 1)
93 val (previousLine
, previousLines
) = moveLines (bol
o backwardChar
)
94 val (nextLine
, nextLines
) = moveLines (forwardChar
o eol
)
97 fun lookingAtString (T
{string, pos
}, string') =
99 val len
= String.size
string
100 val len
' = String.size
string'
101 fun loop (pos
, pos
') =
103 andalso (pos
' >= len
'
104 orelse (Char.equals (String.sub (string, pos
),
105 String.sub (string', pos
'))
106 andalso loop (pos
+ 1, pos
' + 1)))
109 val lookingAtString
=
110 Trace
.trace2 ("Mark.lookingAtString", layout
, String.layout
, Bool.layout
)
114 fun makeSearch
move (m
, s
) =
117 if lookingAtString (m
, s
)
118 then forwardChars (m
, String.size s
)
119 else (search (move m
) handle _
=> raise Search
)
123 val search
= makeSearch forwardChar
124 val searchBackward
= makeSearch backwardChar
127 let fun skip m
= if p (charAt m
) then skip (forwardChar m
)
132 fun skipUntil p
= skip (not
o p
)
134 val skipSpaces
= skip
Char.isSpace
135 val skipUntilSpace
= skipUntil
Char.isSpace
137 fun substring (T
{string, pos
}, T
{pos
=pos
', ...}) =
138 String.substring2 (string, {start
=pos
, finish
=pos
'})
140 fun num (fromString
, exn
) m
=
141 let val m
= skipSpaces m
142 val m
' = skipUntilSpace m
143 in case fromString (substring (m
, m
')) of
149 val int = num (Int.fromString
, Int)
152 val real = num (Real.fromString
, Real)
154 val real = Trace
.trace ("Mark.real", layout
, Layout
.tuple2 (layout
, Real.layout
)) real
156 val op < = fn (m
, m
') => pos m
< pos m
'
158 val equals
= fn (m
, m
') => pos m
= pos m
'
160 val {>, >=, <=, min
, max
, compare
} =
161 Relation
.lessEqual
{< = op <, equals
= op =}