Commit | Line | Data |
---|---|---|
629a09ae DV |
1 | if (typeof JSDOC == "undefined") JSDOC = {}; |
2 | ||
3 | /** | |
4 | @constructor | |
5 | */ | |
6 | JSDOC.TokenStream = function(tokens) { | |
7 | this.tokens = (tokens || []); | |
8 | this.rewind(); | |
9 | } | |
10 | ||
11 | /** | |
12 | @constructor | |
13 | @private | |
14 | */ | |
15 | function VoidToken(/**String*/type) { | |
16 | this.toString = function() {return "<VOID type=\""+type+"\">"}; | |
17 | this.is = function(){return false;} | |
18 | } | |
19 | ||
20 | JSDOC.TokenStream.prototype.rewind = function() { | |
21 | this.cursor = -1; | |
22 | } | |
23 | ||
24 | /** | |
25 | @type JSDOC.Token | |
26 | */ | |
27 | JSDOC.TokenStream.prototype.look = function(/**Number*/n, /**Boolean*/considerWhitespace) { | |
28 | if (typeof n == "undefined") n = 0; | |
29 | ||
30 | if (considerWhitespace == true) { | |
31 | if (this.cursor+n < 0 || this.cursor+n > this.tokens.length) return {}; | |
32 | return this.tokens[this.cursor+n]; | |
33 | } | |
34 | else { | |
35 | var count = 0; | |
36 | var i = this.cursor; | |
37 | ||
38 | while (true) { | |
39 | if (i < 0) return new JSDOC.Token("", "VOID", "START_OF_STREAM"); | |
40 | else if (i > this.tokens.length) return new JSDOC.Token("", "VOID", "END_OF_STREAM"); | |
41 | ||
42 | if (i != this.cursor && (this.tokens[i] === undefined || this.tokens[i].is("WHIT"))) { | |
43 | if (n < 0) i--; else i++; | |
44 | continue; | |
45 | } | |
46 | ||
47 | if (count == Math.abs(n)) { | |
48 | return this.tokens[i]; | |
49 | } | |
50 | count++; | |
51 | (n < 0)? i-- : i++; | |
52 | } | |
53 | ||
54 | return new JSDOC.Token("", "VOID", "STREAM_ERROR"); // because null isn't an object and caller always expects an object | |
55 | } | |
56 | } | |
57 | ||
58 | /** | |
59 | @type JSDOC.Token|JSDOC.Token[] | |
60 | */ | |
61 | JSDOC.TokenStream.prototype.next = function(/**Number*/howMany) { | |
62 | if (typeof howMany == "undefined") howMany = 1; | |
63 | if (howMany < 1) return null; | |
64 | var got = []; | |
65 | ||
66 | for (var i = 1; i <= howMany; i++) { | |
67 | if (this.cursor+i >= this.tokens.length) { | |
68 | return null; | |
69 | } | |
70 | got.push(this.tokens[this.cursor+i]); | |
71 | } | |
72 | this.cursor += howMany; | |
73 | ||
74 | if (howMany == 1) { | |
75 | return got[0]; | |
76 | } | |
77 | else return got; | |
78 | } | |
79 | ||
80 | /** | |
81 | @type JSDOC.Token[] | |
82 | */ | |
83 | JSDOC.TokenStream.prototype.balance = function(/**String*/start, /**String*/stop) { | |
84 | if (!stop) stop = JSDOC.Lang.matching(start); | |
85 | ||
86 | var depth = 0; | |
87 | var got = []; | |
88 | var started = false; | |
89 | ||
90 | while ((token = this.look())) { | |
91 | if (token.is(start)) { | |
92 | depth++; | |
93 | started = true; | |
94 | } | |
95 | ||
96 | if (started) { | |
97 | got.push(token); | |
98 | } | |
99 | ||
100 | if (token.is(stop)) { | |
101 | depth--; | |
102 | if (depth == 0) return got; | |
103 | } | |
104 | if (!this.next()) break; | |
105 | } | |
106 | } | |
107 | ||
108 | JSDOC.TokenStream.prototype.getMatchingToken = function(/**String*/start, /**String*/stop) { | |
109 | var depth = 0; | |
110 | var cursor = this.cursor; | |
111 | ||
112 | if (!start) { | |
113 | start = JSDOC.Lang.matching(stop); | |
114 | depth = 1; | |
115 | } | |
116 | if (!stop) stop = JSDOC.Lang.matching(start); | |
117 | ||
118 | while ((token = this.tokens[cursor])) { | |
119 | if (token.is(start)) { | |
120 | depth++; | |
121 | } | |
122 | ||
123 | if (token.is(stop) && cursor) { | |
124 | depth--; | |
125 | if (depth == 0) return this.tokens[cursor]; | |
126 | } | |
127 | cursor++; | |
128 | } | |
129 | } | |
130 | ||
131 | JSDOC.TokenStream.prototype.insertAhead = function(/**JSDOC.Token*/token) { | |
132 | this.tokens.splice(this.cursor+1, 0, token); | |
133 | } |