Merge to XFA: Remove typdefs for pointer types in fx_system.h.
[pdfium.git] / xfa / src / fxfa / src / fm2js / xfa_fmparse.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "xfa_fm2js.h"\r
8 CXFA_FMParse::CXFA_FMParse()\r
9 {\r
10     m_pScript = 0;\r
11     m_uLength = 0;\r
12     m_pErrorInfo = 0;\r
13     m_lexer = 0;\r
14     m_pToken = 0;\r
15 }\r
16 CXFA_FMParse::~CXFA_FMParse()\r
17 {\r
18     if (m_lexer) {\r
19         delete m_lexer;\r
20     }\r
21     m_lexer = 0;\r
22     m_pErrorInfo = 0;\r
23     m_pScript = 0;\r
24     m_pToken = 0;\r
25 }\r
26 int32_t CXFA_FMParse::Init(FX_WSTR wsFormcalc, CXFA_FMErrorInfo *pErrorInfo)\r
27 {\r
28     m_pScript = wsFormcalc.GetPtr();\r
29     m_uLength = wsFormcalc.GetLength();\r
30     m_pErrorInfo = pErrorInfo;\r
31     m_lexer = FX_NEW CXFA_FMLexer(wsFormcalc, m_pErrorInfo);\r
32     if (m_lexer == 0) {\r
33         return -1;\r
34     }\r
35     return 0;\r
36 }\r
37 void CXFA_FMParse::NextToken()\r
38 {\r
39     m_pToken = m_lexer->NextToken();\r
40     while (m_pToken->m_type == TOKreserver) {\r
41         if (m_lexer->HasError()) {\r
42             break;\r
43         }\r
44         m_pToken = m_lexer->NextToken();\r
45     }\r
46 }\r
47 void CXFA_FMParse::Check( XFA_FM_TOKEN op )\r
48 {\r
49     if (m_pToken->m_type != op) {\r
50         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
51         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(op), ws_TempString.c_str());\r
52     }\r
53     NextToken();\r
54 }\r
55 void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...)\r
56 {\r
57     m_pErrorInfo->linenum = lineNum;\r
58     const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);\r
59     va_list ap;\r
60     va_start(ap, msg);\r
61     m_pErrorInfo->message.FormatV(lpMessageInfo, ap);\r
62     va_end(ap);\r
63 }\r
64 CFX_PtrArray * CXFA_FMParse::ParseTopExpression()\r
65 {\r
66     CXFA_FMExpression *e = 0;\r
67     CFX_PtrArray * expression = FX_NEW CFX_PtrArray();\r
68     while (1) {\r
69         if (m_pToken->m_type == TOKeof) {\r
70             return expression;\r
71         }\r
72         if (m_pToken->m_type == TOKendfunc) {\r
73             return expression;\r
74         }\r
75         if (m_pToken->m_type == TOKendif) {\r
76             return expression;\r
77         }\r
78         if (m_pToken->m_type == TOKelseif) {\r
79             return expression;\r
80         }\r
81         if (m_pToken->m_type == TOKelse) {\r
82             return expression;\r
83         }\r
84         if (m_pToken->m_type == TOKfunc) {\r
85             e = ParseFunction();\r
86             if (e) {\r
87                 expression->Add(e);\r
88             } else {\r
89                 break;\r
90             }\r
91         } else {\r
92             e = ParseExpression();\r
93             if (e) {\r
94                 expression->Add(e);\r
95             } else {\r
96                 break;\r
97             }\r
98         }\r
99     }\r
100     return expression;\r
101 }\r
102 CXFA_FMExpression * CXFA_FMParse::ParseFunction()\r
103 {\r
104     CXFA_FMExpression *e = 0;\r
105     CFX_WideStringC ident;\r
106     CFX_WideStringCArray * pArguments = 0;\r
107     CFX_PtrArray * pExpressions = 0;\r
108     FX_DWORD line = m_pToken->m_uLinenum;\r
109     NextToken();\r
110     if (m_pToken->m_type != TOKidentifier) {\r
111         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
112         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, ws_TempString.c_str());\r
113     } else {\r
114         ident = m_pToken->m_wstring;\r
115         NextToken();\r
116     }\r
117     Check(TOKlparen);\r
118     if (m_pToken->m_type == TOKrparen) {\r
119         NextToken();\r
120     } else {\r
121         pArguments = FX_NEW CFX_WideStringCArray();\r
122         CFX_WideStringC p;\r
123         while (1) {\r
124             if (m_pToken->m_type == TOKidentifier) {\r
125                 p = m_pToken->m_wstring;\r
126                 pArguments->Add(p);\r
127                 NextToken();\r
128                 if (m_pToken->m_type == TOKcomma) {\r
129                     NextToken();\r
130                     continue;\r
131                 } else if (m_pToken->m_type == TOKrparen) {\r
132                     NextToken();\r
133                     break;\r
134                 } else {\r
135                     Check(TOKrparen);\r
136                     break;\r
137                 }\r
138             } else {\r
139                 CFX_WideString ws_TempString = m_pToken->m_wstring;\r
140                 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, ws_TempString.c_str());\r
141                 NextToken();\r
142                 break;\r
143             }\r
144         }\r
145     }\r
146     Check(TOKdo);\r
147     if (m_pToken->m_type == TOKendfunc) {\r
148         NextToken();\r
149     } else {\r
150         pExpressions = ParseTopExpression();\r
151         Check(TOKendfunc);\r
152     }\r
153     if (m_pErrorInfo->message.IsEmpty()) {\r
154         e = FX_NEW CXFA_FMFunctionDefinition(line, 0, ident, pArguments, pExpressions);\r
155     } else {\r
156         int32_t size = 0;\r
157         int32_t index = 0;\r
158         if (pArguments) {\r
159             pArguments->RemoveAll();\r
160             delete pArguments;\r
161             pArguments = 0;\r
162         }\r
163         index = 0;\r
164         if (pExpressions) {\r
165             CXFA_FMExpression *e1 = 0;\r
166             size = pExpressions->GetSize();\r
167             while(index < size) {\r
168                 e1 = (CXFA_FMExpression *)pExpressions->GetAt(index);\r
169                 delete e1;\r
170                 index++;\r
171             }\r
172             pExpressions->RemoveAll();\r
173             delete pExpressions;\r
174             pExpressions = 0;\r
175         }\r
176     }\r
177     return e;\r
178 }\r
179 CXFA_FMExpression * CXFA_FMParse::ParseExpression()\r
180 {\r
181     CXFA_FMExpression *e = 0;\r
182     FX_DWORD line = m_pToken->m_uLinenum;\r
183     switch (m_pToken->m_type) {\r
184         case TOKvar:\r
185             e = ParseVarExpression();\r
186             break;\r
187         case TOKnull:\r
188         case TOKnumber:\r
189         case TOKstring:\r
190         case TOKplus:\r
191         case TOKminus:\r
192         case TOKksnot:\r
193         case TOKidentifier:\r
194         case TOKlparen:\r
195             e = ParseExpExpression();\r
196             break;\r
197         case TOKif:\r
198             e = ParseIfExpression();\r
199             break;\r
200         case TOKwhile:\r
201             e = ParseWhileExpression();\r
202             break;\r
203         case TOKfor:\r
204             e = ParseForExpression();\r
205             break;\r
206         case TOKforeach:\r
207             e = ParseForeachExpression();\r
208             break;\r
209         case TOKdo:\r
210             e = ParseDoExpression();\r
211             break;\r
212         case TOKbreak:\r
213             e = FX_NEW CXFA_FMBreakExpression(line);\r
214             NextToken();\r
215             break;\r
216         case TOKcontinue:\r
217             e = FX_NEW CXFA_FMContinueExpression(line);\r
218             NextToken();\r
219             break;\r
220         default:\r
221             CFX_WideString ws_TempString = m_pToken->m_wstring;\r
222             Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, ws_TempString.c_str());\r
223             NextToken();\r
224             break;\r
225     }\r
226     return e;\r
227 }\r
228 CXFA_FMExpression * CXFA_FMParse::ParseVarExpression()\r
229 {\r
230     CXFA_FMExpression * e = 0;\r
231     CFX_WideStringC ident;\r
232     FX_DWORD line = m_pToken->m_uLinenum;\r
233     NextToken();\r
234     if (m_pToken->m_type != TOKidentifier) {\r
235         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
236         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, ws_TempString.c_str());\r
237     } else {\r
238         ident = m_pToken->m_wstring;\r
239         NextToken();\r
240     }\r
241     if( m_pToken->m_type == TOKassign) {\r
242         NextToken();\r
243         e = ParseExpExpression();\r
244     }\r
245     if (m_pErrorInfo->message.IsEmpty()) {\r
246         e = FX_NEW CXFA_FMVarExpression(line, ident, e);\r
247     } else {\r
248         delete e;\r
249         e = 0;\r
250     }\r
251     return e;\r
252 }\r
253 CXFA_FMSimpleExpression * CXFA_FMParse::ParseSimpleExpression()\r
254 {\r
255     FX_DWORD line = m_pToken->m_uLinenum;\r
256     CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;\r
257     pExp1 = ParseLogicalOrExpression();\r
258     while (m_pToken->m_type == TOKassign) {\r
259         NextToken();\r
260         pExp2 = ParseLogicalOrExpression();\r
261         if (m_pErrorInfo->message.IsEmpty()) {\r
262             pExp1 = FX_NEW CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);\r
263         } else {\r
264             delete pExp1;\r
265             pExp1 = 0;\r
266         }\r
267     }\r
268     return pExp1;\r
269 }\r
270 CXFA_FMExpression * CXFA_FMParse::ParseExpExpression()\r
271 {\r
272     CXFA_FMExpression *e = 0;\r
273     FX_DWORD line = m_pToken->m_uLinenum;\r
274     CXFA_FMSimpleExpression *pExp1 = 0 ;\r
275     pExp1 = ParseSimpleExpression();\r
276     if (m_pErrorInfo->message.IsEmpty()) {\r
277         e = FX_NEW CXFA_FMExpExpression(line, pExp1);\r
278     } else {\r
279         delete pExp1;\r
280         e = 0;\r
281     }\r
282     return e;\r
283 }\r
284 CXFA_FMSimpleExpression * CXFA_FMParse::ParseLogicalOrExpression()\r
285 {\r
286     CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;\r
287     FX_DWORD line = m_pToken->m_uLinenum;\r
288     e1 = ParseLogicalAndExpression();\r
289     for (;;) {\r
290         switch (m_pToken->m_type) {\r
291             case TOKor:\r
292             case TOKksor:\r
293                 NextToken();\r
294                 e2 = ParseLogicalAndExpression();\r
295                 if (m_pErrorInfo->message.IsEmpty()) {\r
296                     e1 = FX_NEW CXFA_FMLogicalOrExpression(line, TOKor, e1, e2);\r
297                 } else {\r
298                     delete e1;\r
299                     e1 = 0;\r
300                 }\r
301                 continue;\r
302             default:\r
303                 break;\r
304         }\r
305         break;\r
306     }\r
307     return e1;\r
308 }\r
309 CXFA_FMSimpleExpression * CXFA_FMParse::ParseLogicalAndExpression()\r
310 {\r
311     CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;\r
312     FX_DWORD line = m_pToken->m_uLinenum;\r
313     e1 = ParseEqualityExpression();\r
314     for (;;) {\r
315         switch (m_pToken->m_type) {\r
316             case TOKand:\r
317             case TOKksand:\r
318                 NextToken();\r
319                 e2 = ParseEqualityExpression();\r
320                 if (m_pErrorInfo->message.IsEmpty()) {\r
321                     e1 = FX_NEW CXFA_FMLogicalAndExpression(line, TOKand, e1, e2);\r
322                 } else {\r
323                     delete e1;\r
324                     e1 = 0;\r
325                 }\r
326                 continue;\r
327             default:\r
328                 break;\r
329         }\r
330         break;\r
331     }\r
332     return e1;\r
333 }\r
334 CXFA_FMSimpleExpression * CXFA_FMParse::ParseEqualityExpression()\r
335 {\r
336     CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;\r
337     FX_DWORD line = m_pToken->m_uLinenum;\r
338     e1 = ParseRelationalExpression();\r
339     for (;;) {\r
340         switch (m_pToken->m_type) {\r
341             case TOKeq:\r
342             case TOKkseq:\r
343                 NextToken();\r
344                 e2 = ParseRelationalExpression();\r
345                 if (m_pErrorInfo->message.IsEmpty()) {\r
346                     e1 = FX_NEW CXFA_FMEqualityExpression(line, TOKeq, e1, e2);\r
347                 } else {\r
348                     delete e1;\r
349                     e1 = 0;\r
350                 }\r
351                 continue;\r
352             case TOKne:\r
353             case TOKksne:\r
354                 NextToken();\r
355                 e2 = ParseRelationalExpression();\r
356                 if (m_pErrorInfo->message.IsEmpty()) {\r
357                     e1 = FX_NEW CXFA_FMEqualityExpression(line, TOKne, e1, e2);\r
358                 } else {\r
359                     delete e1;\r
360                     e1 = 0;\r
361                 }\r
362                 continue;\r
363             default:\r
364                 break;\r
365         }\r
366         break;\r
367     }\r
368     return e1;\r
369 }\r
370 CXFA_FMSimpleExpression * CXFA_FMParse::ParseRelationalExpression()\r
371 {\r
372     CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;\r
373     FX_DWORD line = m_pToken->m_uLinenum;\r
374     e1 = ParseAddtiveExpression();\r
375     for (;;) {\r
376         switch (m_pToken->m_type) {\r
377             case TOKlt:\r
378             case TOKkslt:\r
379                 NextToken();\r
380                 e2 = ParseAddtiveExpression();\r
381                 if (m_pErrorInfo->message.IsEmpty()) {\r
382                     e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKlt, e1, e2);\r
383                 } else {\r
384                     delete e1;\r
385                     e1 = 0;\r
386                 }\r
387                 continue;\r
388             case TOKgt:\r
389             case TOKksgt:\r
390                 NextToken();\r
391                 e2 = ParseAddtiveExpression();\r
392                 if (m_pErrorInfo->message.IsEmpty()) {\r
393                     e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKgt, e1, e2);\r
394                 } else {\r
395                     delete e1;\r
396                     e1 = 0;\r
397                 }\r
398                 continue;\r
399             case TOKle:\r
400             case TOKksle:\r
401                 NextToken();\r
402                 e2 = ParseAddtiveExpression();\r
403                 if (m_pErrorInfo->message.IsEmpty()) {\r
404                     e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKle, e1, e2);\r
405                 } else {\r
406                     delete e1;\r
407                     e1 = 0;\r
408                 }\r
409                 continue;\r
410             case TOKge:\r
411             case TOKksge:\r
412                 NextToken();\r
413                 e2 = ParseAddtiveExpression();\r
414                 if (m_pErrorInfo->message.IsEmpty()) {\r
415                     e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKge, e1, e2);\r
416                 } else {\r
417                     delete e1;\r
418                     e1 = 0;\r
419                 }\r
420                 continue;\r
421             default:\r
422                 break;\r
423         }\r
424         break;\r
425     }\r
426     return e1;\r
427 }\r
428 CXFA_FMSimpleExpression * CXFA_FMParse::ParseAddtiveExpression()\r
429 {\r
430     CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;\r
431     FX_DWORD line = m_pToken->m_uLinenum;\r
432     e1 = ParseMultiplicativeExpression();\r
433     for (;;) {\r
434         switch (m_pToken->m_type) {\r
435             case TOKplus:\r
436                 NextToken();\r
437                 e2 = ParseMultiplicativeExpression();\r
438                 if (m_pErrorInfo->message.IsEmpty()) {\r
439                     e1 = FX_NEW CXFA_FMAdditiveExpression(line, TOKplus, e1, e2);\r
440                 } else {\r
441                     delete e1;\r
442                     e1 = 0;\r
443                 }\r
444                 continue;\r
445             case TOKminus:\r
446                 NextToken();\r
447                 e2 = ParseMultiplicativeExpression();\r
448                 if (m_pErrorInfo->message.IsEmpty()) {\r
449                     e1 = FX_NEW CXFA_FMAdditiveExpression(line, TOKminus, e1, e2);\r
450                 } else {\r
451                     delete e1;\r
452                     e1 = 0;\r
453                 }\r
454                 continue;\r
455             default:\r
456                 break;\r
457         }\r
458         break;\r
459     }\r
460     return e1;\r
461 }\r
462 CXFA_FMSimpleExpression * CXFA_FMParse::ParseMultiplicativeExpression()\r
463 {\r
464     CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;\r
465     FX_DWORD line = m_pToken->m_uLinenum;\r
466     e1 = ParseUnaryExpression();\r
467     for (;;) {\r
468         switch (m_pToken->m_type) {\r
469             case TOKmul:\r
470                 NextToken();\r
471                 e2 = ParseUnaryExpression();\r
472                 if (m_pErrorInfo->message.IsEmpty()) {\r
473                     e1 = FX_NEW CXFA_FMMultiplicativeExpression(line, TOKmul, e1, e2);\r
474                 } else {\r
475                     delete e1;\r
476                     e1 = 0;\r
477                 }\r
478                 continue;\r
479             case TOKdiv:\r
480                 NextToken();\r
481                 e2 = ParseUnaryExpression();\r
482                 if (m_pErrorInfo->message.IsEmpty()) {\r
483                     e1 = FX_NEW CXFA_FMMultiplicativeExpression(line, TOKdiv, e1, e2);\r
484                 } else {\r
485                     delete e1;\r
486                     e1 = 0;\r
487                 }\r
488                 continue;\r
489             default:\r
490                 break;\r
491         }\r
492         break;\r
493     }\r
494     return e1;\r
495 }\r
496 CXFA_FMSimpleExpression * CXFA_FMParse::ParseUnaryExpression()\r
497 {\r
498     CXFA_FMSimpleExpression *e = 0;\r
499     FX_DWORD line = m_pToken->m_uLinenum;\r
500     switch (m_pToken->m_type) {\r
501         case TOKplus:\r
502             NextToken();\r
503             e = ParseUnaryExpression();\r
504             if (m_pErrorInfo->message.IsEmpty()) {\r
505                 e = FX_NEW CXFA_FMPosExpression(line, e);\r
506             } else {\r
507                 e = 0;\r
508             }\r
509             break;\r
510         case TOKminus:\r
511             NextToken();\r
512             e = ParseUnaryExpression();\r
513             if (m_pErrorInfo->message.IsEmpty()) {\r
514                 e = FX_NEW CXFA_FMNegExpression(line, e);\r
515             } else {\r
516                 e = 0;\r
517             }\r
518             break;\r
519         case TOKksnot:\r
520             NextToken();\r
521             e = ParseUnaryExpression();\r
522             if (m_pErrorInfo->message.IsEmpty()) {\r
523                 e = FX_NEW CXFA_FMNotExpression(line, e);\r
524             } else {\r
525                 e = 0;\r
526             }\r
527             break;\r
528         default:\r
529             e = ParsePrimaryExpression();\r
530             break;\r
531     }\r
532     return e;\r
533 }\r
534 CXFA_FMSimpleExpression * CXFA_FMParse::ParsePrimaryExpression()\r
535 {\r
536     CXFA_FMSimpleExpression *e = 0;\r
537     FX_DWORD line = m_pToken->m_uLinenum;\r
538     switch (m_pToken->m_type) {\r
539         case TOKnumber:\r
540             e = FX_NEW CXFA_FMNumberExpression(line, m_pToken->m_wstring);\r
541             NextToken();\r
542             break;\r
543         case TOKstring:\r
544             e = FX_NEW CXFA_FMStringExpression(line, m_pToken->m_wstring);\r
545             NextToken();\r
546             break;\r
547         case TOKidentifier: {\r
548                 CFX_WideStringC wsIdentifier(m_pToken->m_wstring);\r
549                 NextToken();\r
550                 if (m_pToken->m_type == TOKlbracket) {\r
551                     CXFA_FMSimpleExpression *s = ParseIndexExpression();\r
552                     if(s) {\r
553                         e = FX_NEW CXFA_FMDotAccessorExpression(line, NULL, TOKdot, wsIdentifier, s);\r
554                     }\r
555                     NextToken();\r
556                 } else {\r
557                     e = FX_NEW CXFA_FMIdentifierExpressionn(line, wsIdentifier);\r
558                 }\r
559             }\r
560             break;\r
561         case TOKif:\r
562             e = FX_NEW CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring);\r
563             NextToken();\r
564             break;\r
565         case TOKnull:\r
566             e = FX_NEW CXFA_FMNullExpression(line);\r
567             NextToken();\r
568             break;\r
569         case TOKlparen:\r
570             e = ParseParenExpression();\r
571             break;\r
572         default:\r
573             CFX_WideString ws_TempString = m_pToken->m_wstring;\r
574             Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, ws_TempString.c_str());\r
575             NextToken();\r
576             break;\r
577     }\r
578     e = ParsePostExpression(e);\r
579     if (!(m_pErrorInfo->message.IsEmpty())) {\r
580         delete e;\r
581         e = 0;\r
582     }\r
583     return e;\r
584 }\r
585 CXFA_FMSimpleExpression *CXFA_FMParse::ParsePostExpression(CXFA_FMSimpleExpression *e)\r
586 {\r
587     FX_DWORD line = m_pToken->m_uLinenum;\r
588     while (1) {\r
589         switch (m_pToken->m_type) {\r
590             case TOKlparen: {\r
591                     NextToken();\r
592                     CFX_PtrArray *pArray = 0;\r
593                     if (m_pToken->m_type != TOKrparen) {\r
594                         pArray = FX_NEW CFX_PtrArray();\r
595                         while (m_pToken->m_type != TOKrparen) {\r
596                             CXFA_FMSimpleExpression *e = ParseSimpleExpression();\r
597                             if (e) {\r
598                                 pArray->Add(e);\r
599                             }\r
600                             if (m_pToken->m_type == TOKcomma) {\r
601                                 NextToken();\r
602                             } else if (m_pToken->m_type == TOKeof) {\r
603                                 break;\r
604                             }\r
605                         }\r
606                         if (m_pToken->m_type != TOKrparen) {\r
607                             CFX_WideString ws_TempString = m_pToken->m_wstring;\r
608                             Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());\r
609                         }\r
610                     }\r
611                     if (m_pErrorInfo->message.IsEmpty()) {\r
612                         e = FX_NEW CXFA_FMCallExpression(line, e, pArray, FALSE);\r
613                         NextToken();\r
614                         if (m_pToken->m_type != TOKlbracket) {\r
615                             continue;\r
616                         }\r
617                         CXFA_FMSimpleExpression *s = ParseIndexExpression();\r
618                         if(s) {\r
619                             e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKcall, FX_WSTRC(L""), s);\r
620                         } else {\r
621                             delete e;\r
622                             e = 0;\r
623                         }\r
624                     } else {\r
625                         int32_t iSize = pArray->GetSize();\r
626                         for (int32_t i = 0; i < iSize; ++i) {\r
627                             CXFA_FMSimpleExpression *pTemp = (CXFA_FMSimpleExpression *)pArray->GetAt(i);\r
628                             delete pTemp;\r
629                         }\r
630                         delete pArray;\r
631                         delete e;\r
632                         e = 0;\r
633                     }\r
634                 }\r
635                 break;\r
636             case TOKdot:\r
637                 NextToken();\r
638                 if (m_pToken->m_type == TOKidentifier) {\r
639                     CFX_WideStringC tempStr = m_pToken->m_wstring;\r
640                     FX_DWORD tempLine = m_pToken->m_uLinenum;\r
641                     NextToken();\r
642                     if (m_pToken->m_type == TOKlparen) {\r
643                         CXFA_FMSimpleExpression *pExpAccessor;\r
644                         CXFA_FMSimpleExpression *pExpCall;\r
645                         pExpAccessor = e;\r
646                         NextToken();\r
647                         CFX_PtrArray *pArray = 0;\r
648                         if (m_pToken->m_type != TOKrparen) {\r
649                             pArray = FX_NEW CFX_PtrArray();\r
650                             while (m_pToken->m_type != TOKrparen) {\r
651                                 CXFA_FMSimpleExpression *exp = ParseSimpleExpression();\r
652                                 pArray->Add(exp);\r
653                                 if (m_pToken->m_type == TOKcomma) {\r
654                                     NextToken();\r
655                                 } else if (m_pToken->m_type == TOKeof) {\r
656                                     break;\r
657                                 }\r
658                             }\r
659                             if (m_pToken->m_type != TOKrparen) {\r
660                                 CFX_WideString ws_TempString = m_pToken->m_wstring;\r
661                                 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());\r
662                             }\r
663                         }\r
664                         if (m_pErrorInfo->message.IsEmpty()) {\r
665                             CXFA_FMSimpleExpression *pIdentifier = FX_NEW CXFA_FMIdentifierExpressionn(tempLine, tempStr);\r
666                             pExpCall = FX_NEW CXFA_FMCallExpression(line, pIdentifier, pArray, TRUE);\r
667                             e = FX_NEW CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall);\r
668                             NextToken();\r
669                             if (m_pToken->m_type != TOKlbracket) {\r
670                                 continue;\r
671                             }\r
672                             CXFA_FMSimpleExpression *s = ParseIndexExpression();\r
673                             if(s) {\r
674                                 e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKcall, FX_WSTRC(L""), s);\r
675                             } else {\r
676                                 delete e;\r
677                                 e = 0;\r
678                             }\r
679                         } else {\r
680                             int32_t iSize = pArray->GetSize();\r
681                             for (int32_t i = 0; i < iSize; ++i) {\r
682                                 CXFA_FMSimpleExpression *pTemp = (CXFA_FMSimpleExpression *)pArray->GetAt(i);\r
683                                 delete pTemp;\r
684                             }\r
685                             delete pArray;\r
686                             delete e;\r
687                             e = 0;\r
688                         }\r
689                     } else if (m_pToken->m_type == TOKlbracket) {\r
690                         CXFA_FMSimpleExpression *s = ParseIndexExpression();\r
691                         if(!(m_pErrorInfo->message.IsEmpty())) {\r
692                             if (s) {\r
693                                 delete s;\r
694                                 s = 0;\r
695                             }\r
696                             if (e) {\r
697                                 delete e;\r
698                                 e = 0;\r
699                             }\r
700                             return e;\r
701                         }\r
702                         e = FX_NEW CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr, s);\r
703                     } else {\r
704                         CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);\r
705                         e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s);\r
706                         continue;\r
707                     }\r
708                 } else {\r
709                     CFX_WideString ws_TempString = m_pToken->m_wstring;\r
710                     Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, ws_TempString.c_str());\r
711                     return e;\r
712                 }\r
713                 break;\r
714             case TOKdotdot:\r
715                 NextToken();\r
716                 if (m_pToken->m_type == TOKidentifier) {\r
717                     CFX_WideStringC tempStr = m_pToken->m_wstring;\r
718                     FX_DWORD tempLine = m_pToken->m_uLinenum;\r
719                     NextToken();\r
720                     if (m_pToken->m_type == TOKlbracket) {\r
721                         CXFA_FMSimpleExpression *s = ParseIndexExpression();\r
722                         if(!(m_pErrorInfo->message.IsEmpty())) {\r
723                             if (s) {\r
724                                 delete s;\r
725                                 s = 0;\r
726                             }\r
727                             if (e) {\r
728                                 delete e;\r
729                                 e = 0;\r
730                             }\r
731                             return e;\r
732                         }\r
733                         e = FX_NEW CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot, tempStr, s);\r
734                     } else {\r
735                         CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);\r
736                         e = FX_NEW CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr, s);\r
737                         continue;\r
738                     }\r
739                 } else {\r
740                     CFX_WideString ws_TempString = m_pToken->m_wstring;\r
741                     Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,  ws_TempString.c_str());\r
742                     return e;\r
743                 }\r
744                 break;\r
745             case TOKdotscream:\r
746                 NextToken();\r
747                 if (m_pToken->m_type == TOKidentifier) {\r
748                     CFX_WideStringC tempStr = m_pToken->m_wstring;\r
749                     FX_DWORD tempLine = m_pToken->m_uLinenum;\r
750                     NextToken();\r
751                     if (m_pToken->m_type == TOKlbracket) {\r
752                         CXFA_FMSimpleExpression *s = ParseIndexExpression();\r
753                         if(!(m_pErrorInfo->message.IsEmpty())) {\r
754                             if (s) {\r
755                                 delete s;\r
756                                 s = 0;\r
757                             }\r
758                             if (e) {\r
759                                 delete e;\r
760                                 e = 0;\r
761                             }\r
762                             return e;\r
763                         }\r
764                         e = FX_NEW CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream, tempStr, s);\r
765                     } else {\r
766                         CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);\r
767                         e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr, s);\r
768                         continue;\r
769                     }\r
770                 } else {\r
771                     CFX_WideString ws_TempString = m_pToken->m_wstring;\r
772                     Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,  ws_TempString.c_str());\r
773                     return e;\r
774                 }\r
775                 break;\r
776             case TOKdotstar: {\r
777                     CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, NULL, FALSE);\r
778                     e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKdotstar, FX_WSTRC(L"*"), s);\r
779                 }\r
780                 break;\r
781             default:\r
782                 return e;\r
783         }\r
784         NextToken();\r
785     }\r
786     return e;\r
787 }\r
788 CXFA_FMSimpleExpression *CXFA_FMParse::ParseIndexExpression()\r
789 {\r
790     CXFA_FMSimpleExpression *pExp = 0;\r
791     FX_DWORD line = m_pToken->m_uLinenum;\r
792     NextToken();\r
793     CXFA_FMSimpleExpression *s = 0;\r
794     XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;\r
795     if (m_pToken->m_type == TOKmul) {\r
796         pExp = FX_NEW CXFA_FMIndexExpression(line, accessorIndex, s, TRUE);\r
797         NextToken();\r
798         if (m_pToken->m_type != TOKrbracket) {\r
799             CFX_WideString ws_TempString = m_pToken->m_wstring;\r
800             Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());\r
801             if (pExp) {\r
802                 delete pExp;\r
803                 pExp = 0;\r
804             }\r
805         }\r
806         return pExp;\r
807     }\r
808     if(m_pToken->m_type == TOKplus) {\r
809         accessorIndex = ACCESSOR_POSITIVE_INDEX;\r
810         NextToken();\r
811     } else if(m_pToken->m_type == TOKminus) {\r
812         accessorIndex = ACCESSOR_NEGATIVE_INDEX;\r
813         NextToken();\r
814     }\r
815     s = ParseSimpleExpression();\r
816     if (m_pToken->m_type != TOKrbracket) {\r
817         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
818         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());\r
819         if (s) {\r
820             delete s;\r
821         }\r
822     } else {\r
823         pExp = FX_NEW CXFA_FMIndexExpression(line, accessorIndex, s, FALSE);\r
824     }\r
825     return pExp;\r
826 }\r
827 CXFA_FMSimpleExpression * CXFA_FMParse::ParseParenExpression()\r
828 {\r
829     CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;\r
830     FX_DWORD line = m_pToken->m_uLinenum;\r
831     Check(TOKlparen);\r
832     if (m_pToken->m_type != TOKrparen) {\r
833         pExp1 = ParseLogicalOrExpression();\r
834         while (m_pToken->m_type == TOKassign) {\r
835             NextToken();\r
836             pExp2 = ParseLogicalOrExpression();\r
837             if (m_pErrorInfo->message.IsEmpty()) {\r
838                 pExp1 = FX_NEW CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);\r
839             } else {\r
840                 delete pExp1;\r
841                 pExp1 = 0;\r
842             }\r
843         }\r
844         Check(TOKrparen);\r
845     } else {\r
846         NextToken();\r
847     }\r
848     return pExp1;\r
849 }\r
850 CXFA_FMExpression * CXFA_FMParse::ParseBlockExpression()\r
851 {\r
852     FX_DWORD line = m_pToken->m_uLinenum;\r
853     CXFA_FMExpression *e = 0;\r
854     CFX_PtrArray * expression = FX_NEW CFX_PtrArray();\r
855     while (1) {\r
856         switch (m_pToken->m_type) {\r
857             case TOKeof:\r
858             case TOKendif:\r
859             case TOKelseif:\r
860             case TOKelse:\r
861             case TOKendwhile:\r
862             case TOKendfor:\r
863             case TOKend:\r
864             case TOKendfunc:\r
865                 break;\r
866             case TOKfunc:\r
867                 e = ParseFunction();\r
868                 if (e) {\r
869                     expression->Add(e);\r
870                 }\r
871                 continue;\r
872             default:\r
873                 e = ParseExpression();\r
874                 if (e) {\r
875                     expression->Add(e);\r
876                 }\r
877                 continue;\r
878         }\r
879         break;\r
880     }\r
881     CXFA_FMBlockExpression *pExp = 0;\r
882     if (m_pErrorInfo->message.IsEmpty()) {\r
883         pExp = FX_NEW CXFA_FMBlockExpression(line, expression);\r
884     } else {\r
885         int32_t size = expression->GetSize();\r
886         int32_t index = 0;\r
887         while(index < size) {\r
888             e = (CXFA_FMExpression *)expression->GetAt(index);\r
889             delete e;\r
890             index++;\r
891         }\r
892         expression->RemoveAll();\r
893         delete expression;\r
894         expression = 0;\r
895     }\r
896     return pExp;\r
897 }\r
898 CXFA_FMExpression * CXFA_FMParse::ParseIfExpression()\r
899 {\r
900     CXFA_FMSimpleExpression *pExpression = 0;\r
901     CXFA_FMExpression   *pIfExpression = 0;\r
902     CXFA_FMExpression  *pElseExpression = 0;\r
903     FX_DWORD line = m_pToken->m_uLinenum;\r
904     const FX_WCHAR* pStartPos = m_lexer->SavePos();\r
905     NextToken();\r
906     Check(TOKlparen);\r
907     while (m_pToken->m_type != TOKrparen) {\r
908         if (pExpression) {\r
909             delete pExpression;\r
910         }\r
911         pExpression = ParseSimpleExpression();\r
912         if (m_pToken->m_type == TOKcomma) {\r
913             NextToken();\r
914         } else {\r
915             break;\r
916         }\r
917     }\r
918     Check(TOKrparen);\r
919     if (m_pToken->m_type != TOKthen) {\r
920         if (pExpression) {\r
921             delete pExpression;\r
922         }\r
923         m_lexer->SetCurrentLine(line);\r
924         m_pToken = FX_NEW CXFA_FMToken(line);\r
925         m_pToken->m_type = TOKidentifier;\r
926         m_pToken->m_wstring = FX_WSTRC(L"if");\r
927         m_lexer->SetToken(m_pToken);\r
928         m_lexer->RestorePos(pStartPos);\r
929         return ParseExpExpression();\r
930     }\r
931     Check(TOKthen);\r
932     pIfExpression = ParseBlockExpression();\r
933     switch (m_pToken->m_type) {\r
934         case TOKeof:\r
935         case TOKendif:\r
936             Check(TOKendif);\r
937             break;\r
938         case TOKif:\r
939             pElseExpression = ParseIfExpression();\r
940             Check(TOKendif);\r
941             break;\r
942         case TOKelseif:\r
943             pElseExpression = ParseIfExpression();\r
944             break;\r
945         case TOKelse:\r
946             NextToken();\r
947             pElseExpression = ParseBlockExpression();\r
948             Check(TOKendif);\r
949             break;\r
950         default:\r
951             CFX_WideString ws_TempString = m_pToken->m_wstring;\r
952             Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IFEND,  ws_TempString.c_str());\r
953             NextToken();\r
954             break;\r
955     }\r
956     CXFA_FMIfExpression *pExp = 0;\r
957     if (m_pErrorInfo->message.IsEmpty()) {\r
958         pExp = FX_NEW CXFA_FMIfExpression(line, pExpression, pIfExpression, pElseExpression);\r
959     } else {\r
960         if (pExpression) {\r
961             delete pExpression;\r
962         }\r
963         if (pIfExpression) {\r
964             delete pIfExpression;\r
965         }\r
966         if (pElseExpression) {\r
967             delete pElseExpression;\r
968         }\r
969     }\r
970     return pExp;\r
971 }\r
972 CXFA_FMExpression * CXFA_FMParse::ParseWhileExpression()\r
973 {\r
974     CXFA_FMExpression *e = 0;\r
975     CXFA_FMSimpleExpression *pCondition = 0;\r
976     CXFA_FMExpression *pExpression = 0;\r
977     FX_DWORD line = m_pToken->m_uLinenum;\r
978     NextToken();\r
979     pCondition = ParseParenExpression();\r
980     Check(TOKdo);\r
981     pExpression = ParseBlockExpression();\r
982     Check(TOKendwhile);\r
983     if (!m_pErrorInfo->message.IsEmpty()) {\r
984         if (pCondition) {\r
985             delete pCondition;\r
986         }\r
987         if (pExpression) {\r
988             delete pExpression;\r
989         }\r
990         delete e;\r
991         e = 0;\r
992     } else {\r
993         e = FX_NEW CXFA_FMWhileExpression(line, pCondition, pExpression);\r
994     }\r
995     return e;\r
996 }\r
997 CXFA_FMSimpleExpression * CXFA_FMParse::ParseSubassignmentInForExpression()\r
998 {\r
999     CXFA_FMSimpleExpression *e = 0;\r
1000     switch (m_pToken->m_type) {\r
1001         case TOKidentifier:\r
1002             e = ParseSimpleExpression();\r
1003             break;\r
1004         default:\r
1005             CFX_WideString ws_TempString = m_pToken->m_wstring;\r
1006             Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, ws_TempString.c_str());\r
1007             NextToken();\r
1008             break;\r
1009     }\r
1010     return e;\r
1011 }\r
1012 CXFA_FMExpression * CXFA_FMParse::ParseForExpression()\r
1013 {\r
1014     CXFA_FMExpression *e = 0;\r
1015     CFX_WideStringC wsVariant;\r
1016     CXFA_FMSimpleExpression *pAssignment = 0;\r
1017     CXFA_FMSimpleExpression *pAccessor = 0;\r
1018     CXFA_FMSimpleExpression *pStep = 0;\r
1019     CXFA_FMExpression *pList = 0;\r
1020     FX_DWORD line = m_pToken->m_uLinenum;\r
1021     NextToken();\r
1022     if (m_pToken->m_type != TOKidentifier) {\r
1023         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
1024         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());\r
1025     }\r
1026     wsVariant = m_pToken->m_wstring;\r
1027     NextToken();\r
1028     if( m_pToken->m_type == TOKassign) {\r
1029         NextToken();\r
1030         pAssignment = ParseSimpleExpression();\r
1031     } else {\r
1032         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
1033         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());\r
1034     }\r
1035     int32_t iDirection = 0;\r
1036     if (m_pToken->m_type == TOKupto) {\r
1037         iDirection = 1;\r
1038     } else if (m_pToken->m_type == TOKdownto) {\r
1039         iDirection = -1;\r
1040     } else {\r
1041         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
1042         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, L"upto or downto", (const FX_WCHAR*)ws_TempString);\r
1043     }\r
1044     NextToken();\r
1045     pAccessor = ParseSimpleExpression();\r
1046     if (m_pToken->m_type == TOKstep) {\r
1047         NextToken();\r
1048         pStep = ParseSimpleExpression();\r
1049     }\r
1050     Check(TOKdo);\r
1051     pList = ParseBlockExpression();\r
1052     Check(TOKendfor);\r
1053     if (m_pErrorInfo->message.IsEmpty()) {\r
1054         e = FX_NEW CXFA_FMForExpression(line, wsVariant, pAssignment, pAccessor, iDirection, pStep, pList);\r
1055     } else {\r
1056         if (pAssignment) {\r
1057             delete pAssignment;\r
1058         }\r
1059         if (pAccessor) {\r
1060             delete pAccessor;\r
1061         }\r
1062         if (pStep) {\r
1063             delete pStep;\r
1064         }\r
1065         if (pList) {\r
1066             delete pList;\r
1067         }\r
1068     }\r
1069     return e;\r
1070 }\r
1071 CXFA_FMExpression * CXFA_FMParse::ParseForeachExpression()\r
1072 {\r
1073     CXFA_FMExpression *e = 0;\r
1074     CFX_WideStringC wsIdentifier;\r
1075     CFX_PtrArray *pAccessors = 0;\r
1076     CXFA_FMExpression *pList = 0;\r
1077     FX_DWORD line = m_pToken->m_uLinenum;\r
1078     NextToken();\r
1079     if (m_pToken->m_type != TOKidentifier) {\r
1080         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
1081         Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());\r
1082     }\r
1083     wsIdentifier = m_pToken->m_wstring;\r
1084     NextToken();\r
1085     Check(TOKin);\r
1086     Check(TOKlparen);\r
1087     if (m_pToken->m_type == TOKrparen) {\r
1088         CFX_WideString ws_TempString = m_pToken->m_wstring;\r
1089         Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, ws_TempString.c_str());\r
1090         NextToken();\r
1091     } else {\r
1092         pAccessors = FX_NEW CFX_PtrArray();\r
1093         while (m_pToken->m_type != TOKrparen) {\r
1094             CXFA_FMSimpleExpression *s = ParseSimpleExpression();\r
1095             if (s) {\r
1096                 pAccessors->Add(s);\r
1097             }\r
1098             if (m_pToken->m_type == TOKcomma) {\r
1099                 NextToken();\r
1100             } else {\r
1101                 break;\r
1102             }\r
1103         }\r
1104         Check(TOKrparen);\r
1105     }\r
1106     Check(TOKdo);\r
1107     pList = ParseBlockExpression();\r
1108     Check(TOKendfor);\r
1109     if (m_pErrorInfo->message.IsEmpty()) {\r
1110         e = FX_NEW CXFA_FMForeachExpression(line, wsIdentifier, pAccessors, pList);\r
1111     } else {\r
1112         if (pAccessors) {\r
1113             CXFA_FMSimpleExpression *s = 0;\r
1114             int32_t size = pAccessors->GetSize();\r
1115             int32_t index = 0;\r
1116             while(index < size) {\r
1117                 s = (CXFA_FMSimpleExpression *)pAccessors->GetAt(index);\r
1118                 delete s;\r
1119                 index++;\r
1120             }\r
1121             pAccessors->RemoveAll();\r
1122             delete pAccessors;\r
1123             pAccessors = 0;\r
1124         }\r
1125         if (pList) {\r
1126             delete pList;\r
1127         }\r
1128     }\r
1129     return e;\r
1130 }\r
1131 CXFA_FMExpression * CXFA_FMParse::ParseDoExpression()\r
1132 {\r
1133     CXFA_FMExpression *e = 0;\r
1134     FX_DWORD line = m_pToken->m_uLinenum;\r
1135     NextToken();\r
1136     e = ParseBlockExpression();\r
1137     Check(TOKend);\r
1138     if (m_pErrorInfo->message.IsEmpty()) {\r
1139         e = FX_NEW CXFA_FMDoExpression(line, e);\r
1140     } else {\r
1141         delete e;\r
1142         e = 0;\r
1143     }\r
1144     return e;\r
1145 }\r