16 val COMMAND_START = Value("COMMAND_START") |
16 val COMMAND_START = Value("COMMAND_START") |
17 val COMMENT = Value("COMMENT") |
17 val COMMENT = Value("COMMENT") |
18 val OTHER = Value("OTHER") |
18 val OTHER = Value("OTHER") |
19 } |
19 } |
20 |
20 |
21 def check_start(t: Token, P: Int => Boolean) = { t != null && P(t.start) } |
21 def check_start(t: Token, P: Int => Boolean) = t != null && P(t.start) |
22 def check_stop(t: Token, P: Int => Boolean) = { t != null && P(t.stop) } |
22 def check_stop(t: Token, P: Int => Boolean) = t != null && P(t.stop) |
23 |
23 |
24 def scan(s: Token, f: Token => Boolean): Token = |
24 private def fill(n: Int) = { |
25 { |
25 val blanks = new Array[Char](n) |
26 var current = s |
26 for(i <- 0 to n - 1) blanks(i) = ' ' |
27 while (current != null) { |
27 new String(blanks) |
28 val next = current.next |
28 } |
29 if (next == null || f(next)) return current |
29 def string_from_tokens (tokens: List[Token]): String = { |
30 current = next |
30 tokens match { |
|
31 case Nil => "" |
|
32 case t::tokens => (tokens.foldLeft |
|
33 (t.content, t.stop) |
|
34 ((a, token) => (a._1 + fill(token.start - a._2) + token.content, token.stop)) |
|
35 )._1 |
31 } |
36 } |
32 return null |
|
33 } |
37 } |
|
38 |
34 } |
39 } |
35 |
40 |
36 class Token(var start: Int, var stop: Int, val kind: Token.Kind.Value) |
41 class Token(var start: Int, val content: String, val kind: Token.Kind.Value) { |
37 { |
42 val length = content.length |
38 var next: Token = null |
43 def stop = start + length |
39 var prev: Token = null |
44 override def toString = content + "(" + kind + ")" |
40 var command: Command = null |
|
41 |
|
42 def length = stop - start |
|
43 |
|
44 def shift(offset: Int, bottom_clamp: Int) { |
|
45 start = bottom_clamp max (start + offset) |
|
46 stop = bottom_clamp max (stop + offset) |
|
47 } |
|
48 |
|
49 override def hashCode: Int = (31 + start) * 31 + stop |
|
50 |
|
51 override def equals(obj: Any): Boolean = |
|
52 { |
|
53 if (super.equals(obj)) return true |
|
54 if (null == obj) return false |
|
55 obj match { |
|
56 case other: Token => (start == other.start) && (stop == other.stop) |
|
57 case other: Any => false |
|
58 } |
|
59 } |
|
60 } |
45 } |