Intial import
[gnome.introspection-doc-generator] / JSDOC / TokenStream.js
1 //<script type="text/javscript">
2 JSDOC   = imports['JSDOC.js'].JSDOC;
3 Roo     = imports['Roo.js'].Roo;
4 console = imports['console.js'].console;
5
6 Token = imports['JSDOC/Token.js'].Token;
7 Lang = imports['JSDOC/Lang.js'].Lang;
8
9 /**
10         @constructor
11 */
12  
13 TokenStream = function(tokens) {
14  
15     
16         this.tokens = (tokens || []);
17    // Seed.print(this.tokens.length);
18         this.rewind();
19 }
20
21  
22 Roo.apply( TokenStream.prototype , {
23     
24     rewind : function() {
25         this.cursor = -1;
26     },
27
28     /**
29         @type JSDOC.Token
30     */
31     look : function(/**Number*/n, /**Boolean*/considerWhitespace) {
32         if (typeof n == "undefined") n = 0;
33
34         if (considerWhitespace == true) {
35             if (this.cursor+n < 0 || this.cursor+n > this.tokens.length) return {};
36             return this.tokens[this.cursor+n];
37         }
38         else {
39             var count = 0;
40             var i = this.cursor;
41
42             while (true) {
43                 if (i < 0) return new Token("", "VOID", "START_OF_STREAM");
44                 else if (i > this.tokens.length) return new Token("", "VOID", "END_OF_STREAM");
45
46                 if (i != this.cursor && (this.tokens[i] === undefined || this.tokens[i].is("WHIT"))) {
47                     if (n < 0) i--; else i++;
48                     continue;
49                 }
50                 
51                 if (count == Math.abs(n)) {
52                     return this.tokens[i];
53                 }
54                 count++;
55                 (n < 0)? i-- : i++;
56             }
57
58             return new Token("", "VOID", "STREAM_ERROR"); // because null isn't an object and caller always expects an object
59         }
60     },
61
62     lookFor : function (data)
63     {
64         // non tree version..
65         var i = this.cursor < 0 ? 0 : this.cursor ;
66         
67         while (true) {
68             if (i >= this.tokens.length) return -1;
69             if (this.tokens[i].data == data) {
70                 return i;
71             }
72             i++;
73             
74         }
75         // should not get here!
76         return -1;
77
78     },
79
80
81     /**
82      * look ahead (or back) x number of tokens (which are not comment or whitespace)
83      * ?? used any more?
84      */
85     lookTok : function(/**Number*/n) {
86         if (typeof n == "undefined") n = 1;
87
88         
89         var count = 0;
90         var i = this.cursor;
91
92         while (true) {
93             if (i < 0) return false;
94             else if (i > this.tokens.length) return false;
95
96             if (i != this.cursor && (this.tokens[i] === undefined || this.tokens[i].is("WHIT") || this.tokens[i].is("COMM"))) {
97                 if (n < 0) i--; else i++;
98                 continue;
99             }
100             
101             if (count == Math.abs(n)) {
102                 return this.tokens[i];
103             }
104             count++;
105             (n < 0)? i-- : i++;
106         }
107
108         return false; // because null isn't an object and caller always expects an object;
109         
110     },
111
112     /**
113         @type JSDOC.Token|JSDOC.Token[]| null!
114     */
115     next : function(/**Number*/howMany) {
116         if (typeof howMany == "undefined") howMany = 1;
117         if (howMany < 1) return null;
118         var got = [];
119
120         for (var i = 1; i <= howMany; i++) {
121             if (this.cursor+i >= this.tokens.length) {
122                 return null;
123             }
124             got.push(this.tokens[this.cursor+i]);
125         }
126         this.cursor += howMany;
127
128         if (howMany == 1) {
129             return got[0];
130         }
131         else return got;
132     },
133     // what about comments after 'function'...
134     // is this used ???
135
136     nextNonSpace : function ()
137     {
138         
139         while (true) {
140             tok = this.next(1);
141             if (!tok) {
142                 return false;
143             }
144             if (tok.is('WHIT') ||  tok.is('COMM')) {
145                 continue;
146             }
147             return tok;
148         }
149     },
150     /**
151         @type JSDOC.Token[]
152     */
153     balance : function(/**String*/start, /**String*/stop) {
154         if (!stop) stop = Lang.matching(start);
155         
156         var depth = 0;
157         var got = [];
158         var started = false;
159         //Seed.print("STOP:" + stop);
160         while ((token = this.look())) {
161             if (token.is(start)) {
162                 depth++;
163                 started = true;
164             }
165             
166             if (started) {
167                 got.push(token);
168             }
169             
170             if (token.is(stop)) {
171                 depth--;
172                 if (depth == 0) return got;
173             }
174             if (!this.next()) break;
175         }
176     },
177
178     getMatchingToken : function(/**String*/start, /**String*/stop) {
179         var depth = 0;
180         var cursor = this.cursor;
181         
182         if (!start) {
183             start = Lang.matching(stop);
184             depth = 1;
185         }
186         if (!stop) stop = Lang.matching(start);
187         
188         while ((token = this.tokens[cursor])) {
189             if (token.is(start)) {
190                 depth++;
191             }
192             
193             if (token.is(stop) && cursor) {
194                 depth--;
195                 if (depth == 0) return this.tokens[cursor];
196             }
197             cursor++;
198         }
199     },
200
201     insertAhead : function(/**JSDOC.Token*/token) {
202         this.tokens.splice(this.cursor+1, 0, token);
203     },
204      
205     remaining : function() {
206         var ret = [];
207         while (true) {
208             var tok = this.look(1,true);
209             if (!tok || !tok.is || tok.is('VOID')) {
210                 return ret;
211             }
212             ret.push(this.next(1));
213         }
214     },
215      
216
217     arrayToString : function(ar) {
218         console.log(typeof(ar));
219         var ret = [];
220         Roo.each(ar, function(e) {
221             ret.push(e.data);
222         })
223         return ret.join('');
224     }
225 });
226