Fix #5732 - change to cmake for build
[roojspacker] / roojspacker / Collapse.vala
1
2 /**
3  * 
4  * base class for parsing segments of token array..
5  * 
6  * 
7  * We want to make parsing the whole thing easy..
8  * 
9  * so we do various tricks:
10  * 
11  * 
12  * a) white space collased
13  *    wsPrefix 
14  * b)  toks
15  *     { } - collapse into first element.
16        ( ) - collapse into first element.
17        [ ] - collapse into first element.
18  * c) items = , seperation within the above..
19  * 
20  * usage: x = new Collapse(token_array)
21  * 
22  * 
23  * 
24  * 
25  */ 
26
27 namespace JSDOC {
28
29         public class  Collapse : TokenStream  {
30
31                 Packer packer;
32                 string filename;
33         
34                 public Collapse(Gee.ArrayList<Token> tokens, Packer pk, string filename) 
35                 {
36                     base(tokens);
37                     
38                     this.packer = pk;
39                     this.filename = filename;
40                     
41                     
42                     
43                     this.spaces();
44                     
45                     var ar = this.collapse(this.tokens);
46                     
47                     this.tokens = ar;
48                     
49                    // console.dump(ar);
50                     
51                 }
52                 
53                 // put spaces into prefix of tokens..
54     
55         void spaces () 
56         {
57             var ar = new Gee.ArrayList<Token>();
58             var pref =  new Gee.ArrayList<Token>();
59             
60                         
61             
62             for (var i = 0; i < this.tokens.size; i ++) {
63                 var tok = this.tokens[i];
64                 if (tok.isType(TokenType.COMM) || tok.isType(TokenType.WHIT)) {
65                     pref.add(tok);
66                     continue;
67                 }
68                 tok.prefix = "";
69                 if (pref.size > 0) {
70                         foreach(var e in pref) {
71                         tok.prefix += e.data;
72                     }
73                     pref =  new Gee.ArrayList<Token>(); // reset pref..
74                 }
75                 
76                 ar.add(tok);
77                 
78
79                 
80             }
81             this.tokens = ar;
82             
83         }
84         
85         
86         
87         Gee.ArrayList<Token>  collapse(Gee.ArrayList<Token>  ar) 
88         {
89             
90             var st = new TokenStream(ar);
91             var ret = new Gee.ArrayList<Token>();
92             var last_is_object_def = false;
93             
94             while (true) {
95                 var  tok = st.look(1,true);
96                 if (tok == null) {
97                   //  Seed.print(TokenStream.toString(ret));
98                     return ret;
99                 }
100                 // console.log(tok.data);
101                 
102                 //print("COL: %s\n", tok.asString());
103                 
104                 switch(tok.type) {
105                     case TokenType.VOID: 
106                         return ret; //EOF
107                         
108                         
109                     case TokenType.KEYW: 
110                     case TokenType.TOKN:
111                     case TokenType.NAME:
112                     case TokenType.STRN:
113                     case TokenType.NUMB:
114                     case TokenType.REGX:
115                                 if (last_is_object_def) {
116                                 
117                                         this.packer.logError(Packer.ResultType.err, this.filename, tok.line, 
118                                                         "Syntax error - found non punctuation after object close brace");
119                                         
120                                         
121                                 
122                                         //GLib.error("Syntax error - found non punctuation after object close brace\n%s", tok.asString());
123                                 }
124                     
125                                 var nn = st.next();
126                                 if (nn != null) { 
127                                 ret.add(nn);
128                         }
129                         last_is_object_def = false;
130                         continue;
131                         
132                     case TokenType.PUNC:
133                         switch (tok.data) {
134                             case "[":
135                             case "{":
136                             case "(":
137                                 last_is_object_def = false;
138                                 var start = st.cursor;
139                                 //st.next(); << no need to shift, balance will start at first character..
140                                 
141                                 var add = st.balance(tok.name);
142                                 
143                                // print("BALANCE returned %d items\n", add.size);
144                                 
145                                 
146                                // if (!add) {
147                                     //console.dump(tok);
148                                     //console.dump(start + '...' + st.cursor);
149                                     //console.dump(st.tokens);
150                                  
151                                 //}
152                                 if (add.size > 0) {
153                                         add.remove_at(0);  // remove the first element... (as it's the 
154                                 }
155                                 //Seed.print("ADD");
156                                 //Seed.print(JSON.stringify(add, null,4));
157                                 
158                                 
159                                 
160                                 var toks = add.size > 0 ? this.collapse(add) : add;
161                                 
162                                 tok.items = new Gee.ArrayList<Gee.ArrayList<Token>>(); //?? needed?
163                                 tok.props = new Gee.HashMap<string,TokenKeyMap>();
164                                  
165                                 
166                                 if (tok.data != "{") {
167                                     // paramters or array elements..
168                                     tok.items = this.toItems(toks, ",");
169                                     if (tok.data == "]") {   // ) can be folowed with lots of things...
170                                             last_is_object_def = true;
171                                     }
172                                 } else {
173                                     // check for types.. it could be a list of statements.. or object
174                                     // format "{" "xXXX" ":" << looks for the ':'.. seems to work.. not sure if it's foolproof...
175                                     
176                                     var ost = new  TokenStream(toks);
177                                     //console.dump(ost.look(2,true) );
178                                     if (ost.look(2,true) != null && ost.look(2,true).data == ":") {
179                                                 // object properties...
180                                                                                 this.toProps(toks,tok);
181                                                                                 last_is_object_def = true;
182                                     } else {
183                                         // list of statemetns..
184                                         tok.items = this.toItems(toks, ";{");;
185                                     }
186                                     
187                                     
188                                 }
189                                  
190                                 
191                                 
192                                 
193                                 
194                                 
195                                 
196                                 //Seed.print(" ADD : " + add.length  +  " ITEMS: " + tok.items.length);
197                                 
198                                 ret.add(tok);
199                                 
200                                 continue;
201                    
202                             default:
203                                     last_is_object_def = false;
204                                 ret.add(st.next());
205                                 continue;
206                         }
207                        print("OOPS");
208                         continue;
209                     default : 
210                        print("OOPS" + tok.type.to_string());
211                         continue;
212                 }
213             }
214                 
215                 
216             
217             
218             
219             
220             
221             
222             
223             
224         }
225         // array of arrays of tokens
226         Gee.ArrayList<Gee.ArrayList<Token>>  toItems(Gee.ArrayList<Token>  ar, string sep)
227         {
228             var ret = new Gee.ArrayList<Gee.ArrayList<Token>>() ;
229             var g =  new Gee.ArrayList<Token>() ;
230               
231             for (var i = 0; i < ar.size; i ++) {
232                 if (sep.index_of(ar.get(i).data) < 0) {
233                     g.add(ar.get(i));
234                     continue;
235                 }
236                 // var a=..., b =...
237                 if ((ar.get(i).data != ";") && g.size> 0  && (g[0].name == TokenName.VAR)) {;
238                     g.add(ar.get(i));
239                     continue;
240                 }
241                 
242                 g.add(ar.get(i));
243                 ret.add(g);
244                 g =  new Gee.ArrayList<Token>() ;
245                 
246             }
247             // last..
248             if (g.size > 0) {
249                 ret.add(g);
250             }
251             return ret;
252             
253         }
254         
255         Gee.HashMap<string,TokenKeyMap> toProps (Gee.ArrayList<Token> ar, Token tok)
256         {
257             
258             var ret = new Gee.HashMap<string,TokenKeyMap>();
259                         
260                         var keyseq = new Gee.ArrayList<string>();
261                
262             var g = new TokenKeyMap();
263                
264             
265             var k = "";
266             var state = 0;
267             for (var i = 0; i < ar.size; i ++) {
268                 
269                 switch(state) {
270                     case 0:
271                         k = ar.get(i).data;
272                         g.key = ar.get(i);
273                         keyseq.add(k);
274                         state = 1;
275                         continue;
276                     case 1:
277                         state =2; // should be ':'
278                         continue;
279                     case 2:
280                         g.vals.add( ar.get(i));
281                         if ( ar.get(i).data != ",") {
282                             continue;
283                         }
284                         ret.set(k, g);
285                         g = new TokenKeyMap();
286                         state = 0;
287                         continue;
288                    
289                 }
290             }
291              // last.. - if g.val.length is 0 then it's a trailing ','...
292              // we should really throw a syntax error in that case..
293             if (k.length > 0 && g.vals.size > 0) {
294                 ret.set(k, g);
295             }
296             tok.props = ret;
297             tok.keyseq = keyseq;
298             return ret;
299             
300             
301         }
302
303         }   
304     
305 }