-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathlexUtil.wyv
50 lines (41 loc) · 1.6 KB
/
lexUtil.wyv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
module lexUtil
import javascript:stdlib.support.regexUtils
import wyvern.collections.llist
import wyvern.runtime
type List = llist.LinkedList
def getIndent(input:String) : String
val lineMatch = regexUtils.doMatch(input, "[ \\t]+")
if (lineMatch.found)
lineMatch.matched
else
""
def splitLines(input:String) : llist.Cons[String]
val lineMatch = regexUtils.doMatch(input, "[^\\n]*\\n")
if (lineMatch.found)
splitLines(lineMatch.after).push(lineMatch.matched)
else
llist.Singleton[String](input)
// true if the string contains only whitespace characters
def allWhitespace(input:String):Boolean
val lineMatch = regexUtils.doMatch(input, "[ \\t\\n]*")
if (lineMatch.found)
lineMatch.after == ""
else
false
def getCommonLeadingWhitespace(lines:List[String]):String
val nonemptyLineIndents:List[String] = lines.filter(s:String => !allWhitespace(s)).map[String](s:String => getIndent(s))
def minLength(s1:String, s2:String):String
if (s1.length() < s2.length())
s1
else
s2
match nonemptyLineIndents:
n:llist.Nil => ""
c:llist.Cons => c.next.reduce((s1:String, s2:String) => minLength(s1, s2), c.value)
def stripLeadingWhitespace(s:String):String
val lines = splitLines(s)
val leadingLength = getCommonLeadingWhitespace(lines).length()
val strippedLines = lines.map[String](s => s.substring(leadingLength, s.length()))
match strippedLines:
c:llist.Cons => c.next.reduce((s1:String, s2:String) => s1 + s2, c.value)
// Nil impossible