// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa_fm2js.h"
CXFA_FMParse::CXFA_FMParse() {
  m_pScript = 0;
  m_uLength = 0;
  m_pErrorInfo = 0;
  m_lexer = 0;
  m_pToken = 0;
}
CXFA_FMParse::~CXFA_FMParse() {
  if (m_lexer) {
    delete m_lexer;
  }
  m_lexer = 0;
  m_pErrorInfo = 0;
  m_pScript = 0;
  m_pToken = 0;
}
int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc,
                           CXFA_FMErrorInfo* pErrorInfo) {
  m_pScript = wsFormcalc.GetPtr();
  m_uLength = wsFormcalc.GetLength();
  m_pErrorInfo = pErrorInfo;
  m_lexer = new CXFA_FMLexer(wsFormcalc, m_pErrorInfo);
  if (m_lexer == 0) {
    return -1;
  }
  return 0;
}
void CXFA_FMParse::NextToken() {
  m_pToken = m_lexer->NextToken();
  while (m_pToken->m_type == TOKreserver) {
    if (m_lexer->HasError()) {
      break;
    }
    m_pToken = m_lexer->NextToken();
  }
}
void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
  if (m_pToken->m_type != op) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
          XFA_FM_KeywordToString(op), ws_TempString.c_str());
  }
  NextToken();
}
void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...) {
  m_pErrorInfo->linenum = lineNum;
  const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
  va_list ap;
  va_start(ap, msg);
  m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
  va_end(ap);
}
CFX_PtrArray* CXFA_FMParse::ParseTopExpression() {
  CXFA_FMExpression* e = 0;
  CFX_PtrArray* expression = new CFX_PtrArray();
  while (1) {
    if (m_pToken->m_type == TOKeof) {
      return expression;
    }
    if (m_pToken->m_type == TOKendfunc) {
      return expression;
    }
    if (m_pToken->m_type == TOKendif) {
      return expression;
    }
    if (m_pToken->m_type == TOKelseif) {
      return expression;
    }
    if (m_pToken->m_type == TOKelse) {
      return expression;
    }
    if (m_pToken->m_type == TOKfunc) {
      e = ParseFunction();
      if (e) {
        expression->Add(e);
      } else {
        break;
      }
    } else {
      e = ParseExpression();
      if (e) {
        expression->Add(e);
      } else {
        break;
      }
    }
  }
  return expression;
}
CXFA_FMExpression* CXFA_FMParse::ParseFunction() {
  CXFA_FMExpression* e = 0;
  CFX_WideStringC ident;
  CFX_WideStringCArray* pArguments = 0;
  CFX_PtrArray* pExpressions = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
          ws_TempString.c_str());
  } else {
    ident = m_pToken->m_wstring;
    NextToken();
  }
  Check(TOKlparen);
  if (m_pToken->m_type == TOKrparen) {
    NextToken();
  } else {
    pArguments = new CFX_WideStringCArray();
    CFX_WideStringC p;
    while (1) {
      if (m_pToken->m_type == TOKidentifier) {
        p = m_pToken->m_wstring;
        pArguments->Add(p);
        NextToken();
        if (m_pToken->m_type == TOKcomma) {
          NextToken();
          continue;
        } else if (m_pToken->m_type == TOKrparen) {
          NextToken();
          break;
        } else {
          Check(TOKrparen);
          break;
        }
      } else {
        CFX_WideString ws_TempString = m_pToken->m_wstring;
        Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
              ws_TempString.c_str());
        NextToken();
        break;
      }
    }
  }
  Check(TOKdo);
  if (m_pToken->m_type == TOKendfunc) {
    NextToken();
  } else {
    pExpressions = ParseTopExpression();
    Check(TOKendfunc);
  }
  if (m_pErrorInfo->message.IsEmpty()) {
    e = new CXFA_FMFunctionDefinition(line, 0, ident, pArguments, pExpressions);
  } else {
    int32_t size = 0;
    int32_t index = 0;
    if (pArguments) {
      pArguments->RemoveAll();
      delete pArguments;
      pArguments = 0;
    }
    index = 0;
    if (pExpressions) {
      CXFA_FMExpression* e1 = 0;
      size = pExpressions->GetSize();
      while (index < size) {
        e1 = (CXFA_FMExpression*)pExpressions->GetAt(index);
        delete e1;
        index++;
      }
      pExpressions->RemoveAll();
      delete pExpressions;
      pExpressions = 0;
    }
  }
  return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseExpression() {
  CXFA_FMExpression* e = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKvar:
      e = ParseVarExpression();
      break;
    case TOKnull:
    case TOKnumber:
    case TOKstring:
    case TOKplus:
    case TOKminus:
    case TOKksnot:
    case TOKidentifier:
    case TOKlparen:
      e = ParseExpExpression();
      break;
    case TOKif:
      e = ParseIfExpression();
      break;
    case TOKwhile:
      e = ParseWhileExpression();
      break;
    case TOKfor:
      e = ParseForExpression();
      break;
    case TOKforeach:
      e = ParseForeachExpression();
      break;
    case TOKdo:
      e = ParseDoExpression();
      break;
    case TOKbreak:
      e = new CXFA_FMBreakExpression(line);
      NextToken();
      break;
    case TOKcontinue:
      e = new CXFA_FMContinueExpression(line);
      NextToken();
      break;
    default:
      CFX_WideString ws_TempString = m_pToken->m_wstring;
      Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
            ws_TempString.c_str());
      NextToken();
      break;
  }
  return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() {
  CXFA_FMExpression* e = 0;
  CFX_WideStringC ident;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
          ws_TempString.c_str());
  } else {
    ident = m_pToken->m_wstring;
    NextToken();
  }
  if (m_pToken->m_type == TOKassign) {
    NextToken();
    e = ParseExpExpression();
  }
  if (m_pErrorInfo->message.IsEmpty()) {
    e = new CXFA_FMVarExpression(line, ident, e);
  } else {
    delete e;
    e = 0;
  }
  return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() {
  FX_DWORD line = m_pToken->m_uLinenum;
  CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
  pExp1 = ParseLogicalOrExpression();
  while (m_pToken->m_type == TOKassign) {
    NextToken();
    pExp2 = ParseLogicalOrExpression();
    if (m_pErrorInfo->message.IsEmpty()) {
      pExp1 = new CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);
    } else {
      delete pExp1;
      pExp1 = 0;
    }
  }
  return pExp1;
}
CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() {
  CXFA_FMExpression* e = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  CXFA_FMSimpleExpression* pExp1 = 0;
  pExp1 = ParseSimpleExpression();
  if (m_pErrorInfo->message.IsEmpty()) {
    e = new CXFA_FMExpExpression(line, pExp1);
  } else {
    delete pExp1;
    e = 0;
  }
  return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() {
  CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  e1 = ParseLogicalAndExpression();
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKor:
      case TOKksor:
        NextToken();
        e2 = ParseLogicalAndExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMLogicalOrExpression(line, TOKor, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() {
  CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  e1 = ParseEqualityExpression();
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKand:
      case TOKksand:
        NextToken();
        e2 = ParseEqualityExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMLogicalAndExpression(line, TOKand, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() {
  CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  e1 = ParseRelationalExpression();
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKeq:
      case TOKkseq:
        NextToken();
        e2 = ParseRelationalExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMEqualityExpression(line, TOKeq, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      case TOKne:
      case TOKksne:
        NextToken();
        e2 = ParseRelationalExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMEqualityExpression(line, TOKne, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() {
  CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  e1 = ParseAddtiveExpression();
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKlt:
      case TOKkslt:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMRelationalExpression(line, TOKlt, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      case TOKgt:
      case TOKksgt:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMRelationalExpression(line, TOKgt, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      case TOKle:
      case TOKksle:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMRelationalExpression(line, TOKle, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      case TOKge:
      case TOKksge:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMRelationalExpression(line, TOKge, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() {
  CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  e1 = ParseMultiplicativeExpression();
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKplus:
        NextToken();
        e2 = ParseMultiplicativeExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMAdditiveExpression(line, TOKplus, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      case TOKminus:
        NextToken();
        e2 = ParseMultiplicativeExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMAdditiveExpression(line, TOKminus, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() {
  CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  e1 = ParseUnaryExpression();
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKmul:
        NextToken();
        e2 = ParseUnaryExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMMultiplicativeExpression(line, TOKmul, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      case TOKdiv:
        NextToken();
        e2 = ParseUnaryExpression();
        if (m_pErrorInfo->message.IsEmpty()) {
          e1 = new CXFA_FMMultiplicativeExpression(line, TOKdiv, e1, e2);
        } else {
          delete e1;
          e1 = 0;
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() {
  CXFA_FMSimpleExpression* e = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKplus:
      NextToken();
      e = ParseUnaryExpression();
      if (m_pErrorInfo->message.IsEmpty()) {
        e = new CXFA_FMPosExpression(line, e);
      } else {
        e = 0;
      }
      break;
    case TOKminus:
      NextToken();
      e = ParseUnaryExpression();
      if (m_pErrorInfo->message.IsEmpty()) {
        e = new CXFA_FMNegExpression(line, e);
      } else {
        e = 0;
      }
      break;
    case TOKksnot:
      NextToken();
      e = ParseUnaryExpression();
      if (m_pErrorInfo->message.IsEmpty()) {
        e = new CXFA_FMNotExpression(line, e);
      } else {
        e = 0;
      }
      break;
    default:
      e = ParsePrimaryExpression();
      break;
  }
  return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() {
  CXFA_FMSimpleExpression* e = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKnumber:
      e = new CXFA_FMNumberExpression(line, m_pToken->m_wstring);
      NextToken();
      break;
    case TOKstring:
      e = new CXFA_FMStringExpression(line, m_pToken->m_wstring);
      NextToken();
      break;
    case TOKidentifier: {
      CFX_WideStringC wsIdentifier(m_pToken->m_wstring);
      NextToken();
      if (m_pToken->m_type == TOKlbracket) {
        CXFA_FMSimpleExpression* s = ParseIndexExpression();
        if (s) {
          e = new CXFA_FMDotAccessorExpression(line, NULL, TOKdot, wsIdentifier,
                                               s);
        }
        NextToken();
      } else {
        e = new CXFA_FMIdentifierExpressionn(line, wsIdentifier);
      }
    } break;
    case TOKif:
      e = new CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring);
      NextToken();
      break;
    case TOKnull:
      e = new CXFA_FMNullExpression(line);
      NextToken();
      break;
    case TOKlparen:
      e = ParseParenExpression();
      break;
    default:
      CFX_WideString ws_TempString = m_pToken->m_wstring;
      Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
            ws_TempString.c_str());
      NextToken();
      break;
  }
  e = ParsePostExpression(e);
  if (!(m_pErrorInfo->message.IsEmpty())) {
    delete e;
    e = 0;
  }
  return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParsePostExpression(
    CXFA_FMSimpleExpression* e) {
  FX_DWORD line = m_pToken->m_uLinenum;
  while (1) {
    switch (m_pToken->m_type) {
      case TOKlparen: {
        NextToken();
        CFX_PtrArray* pArray = 0;
        if (m_pToken->m_type != TOKrparen) {
          pArray = new CFX_PtrArray();
          while (m_pToken->m_type != TOKrparen) {
            CXFA_FMSimpleExpression* e = ParseSimpleExpression();
            if (e) {
              pArray->Add(e);
            }
            if (m_pToken->m_type == TOKcomma) {
              NextToken();
            } else if (m_pToken->m_type == TOKeof) {
              break;
            }
          }
          if (m_pToken->m_type != TOKrparen) {
            CFX_WideString ws_TempString = m_pToken->m_wstring;
            Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
                  XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
          }
        }
        if (m_pErrorInfo->message.IsEmpty()) {
          e = new CXFA_FMCallExpression(line, e, pArray, FALSE);
          NextToken();
          if (m_pToken->m_type != TOKlbracket) {
            continue;
          }
          CXFA_FMSimpleExpression* s = ParseIndexExpression();
          if (s) {
            e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
                                                 FX_WSTRC(L""), s);
          } else {
            delete e;
            e = 0;
          }
        } else {
          int32_t iSize = pArray->GetSize();
          for (int32_t i = 0; i < iSize; ++i) {
            CXFA_FMSimpleExpression* pTemp =
                (CXFA_FMSimpleExpression*)pArray->GetAt(i);
            delete pTemp;
          }
          delete pArray;
          delete e;
          e = 0;
        }
      } break;
      case TOKdot:
        NextToken();
        if (m_pToken->m_type == TOKidentifier) {
          CFX_WideStringC tempStr = m_pToken->m_wstring;
          FX_DWORD tempLine = m_pToken->m_uLinenum;
          NextToken();
          if (m_pToken->m_type == TOKlparen) {
            CXFA_FMSimpleExpression* pExpAccessor;
            CXFA_FMSimpleExpression* pExpCall;
            pExpAccessor = e;
            NextToken();
            CFX_PtrArray* pArray = 0;
            if (m_pToken->m_type != TOKrparen) {
              pArray = new CFX_PtrArray();
              while (m_pToken->m_type != TOKrparen) {
                CXFA_FMSimpleExpression* exp = ParseSimpleExpression();
                pArray->Add(exp);
                if (m_pToken->m_type == TOKcomma) {
                  NextToken();
                } else if (m_pToken->m_type == TOKeof) {
                  break;
                }
              }
              if (m_pToken->m_type != TOKrparen) {
                CFX_WideString ws_TempString = m_pToken->m_wstring;
                Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
                      XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
              }
            }
            if (m_pErrorInfo->message.IsEmpty()) {
              CXFA_FMSimpleExpression* pIdentifier =
                  new CXFA_FMIdentifierExpressionn(tempLine, tempStr);
              pExpCall =
                  new CXFA_FMCallExpression(line, pIdentifier, pArray, TRUE);
              e = new CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall);
              NextToken();
              if (m_pToken->m_type != TOKlbracket) {
                continue;
              }
              CXFA_FMSimpleExpression* s = ParseIndexExpression();
              if (s) {
                e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
                                                     FX_WSTRC(L""), s);
              } else {
                delete e;
                e = 0;
              }
            } else {
              int32_t iSize = pArray->GetSize();
              for (int32_t i = 0; i < iSize; ++i) {
                CXFA_FMSimpleExpression* pTemp =
                    (CXFA_FMSimpleExpression*)pArray->GetAt(i);
                delete pTemp;
              }
              delete pArray;
              delete e;
              e = 0;
            }
          } else if (m_pToken->m_type == TOKlbracket) {
            CXFA_FMSimpleExpression* s = ParseIndexExpression();
            if (!(m_pErrorInfo->message.IsEmpty())) {
              if (s) {
                delete s;
                s = 0;
              }
              if (e) {
                delete e;
                e = 0;
              }
              return e;
            }
            e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr,
                                                 s);
          } else {
            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
                tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
            e = new CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s);
            continue;
          }
        } else {
          CFX_WideString ws_TempString = m_pToken->m_wstring;
          Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
                ws_TempString.c_str());
          return e;
        }
        break;
      case TOKdotdot:
        NextToken();
        if (m_pToken->m_type == TOKidentifier) {
          CFX_WideStringC tempStr = m_pToken->m_wstring;
          FX_DWORD tempLine = m_pToken->m_uLinenum;
          NextToken();
          if (m_pToken->m_type == TOKlbracket) {
            CXFA_FMSimpleExpression* s = ParseIndexExpression();
            if (!(m_pErrorInfo->message.IsEmpty())) {
              if (s) {
                delete s;
                s = 0;
              }
              if (e) {
                delete e;
                e = 0;
              }
              return e;
            }
            e = new CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot,
                                                    tempStr, s);
          } else {
            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
                tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
            e = new CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr,
                                                    s);
            continue;
          }
        } else {
          CFX_WideString ws_TempString = m_pToken->m_wstring;
          Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
                ws_TempString.c_str());
          return e;
        }
        break;
      case TOKdotscream:
        NextToken();
        if (m_pToken->m_type == TOKidentifier) {
          CFX_WideStringC tempStr = m_pToken->m_wstring;
          FX_DWORD tempLine = m_pToken->m_uLinenum;
          NextToken();
          if (m_pToken->m_type == TOKlbracket) {
            CXFA_FMSimpleExpression* s = ParseIndexExpression();
            if (!(m_pErrorInfo->message.IsEmpty())) {
              if (s) {
                delete s;
                s = 0;
              }
              if (e) {
                delete e;
                e = 0;
              }
              return e;
            }
            e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream,
                                                 tempStr, s);
          } else {
            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
                tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
            e = new CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr,
                                                 s);
            continue;
          }
        } else {
          CFX_WideString ws_TempString = m_pToken->m_wstring;
          Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
                ws_TempString.c_str());
          return e;
        }
        break;
      case TOKdotstar: {
        CXFA_FMSimpleExpression* s =
            new CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, NULL, FALSE);
        e = new CXFA_FMDotAccessorExpression(line, e, TOKdotstar,
                                             FX_WSTRC(L"*"), s);
      } break;
      default:
        return e;
    }
    NextToken();
  }
  return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseIndexExpression() {
  CXFA_FMSimpleExpression* pExp = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  CXFA_FMSimpleExpression* s = 0;
  XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
  if (m_pToken->m_type == TOKmul) {
    pExp = new CXFA_FMIndexExpression(line, accessorIndex, s, TRUE);
    NextToken();
    if (m_pToken->m_type != TOKrbracket) {
      CFX_WideString ws_TempString = m_pToken->m_wstring;
      Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
            XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
      if (pExp) {
        delete pExp;
        pExp = 0;
      }
    }
    return pExp;
  }
  if (m_pToken->m_type == TOKplus) {
    accessorIndex = ACCESSOR_POSITIVE_INDEX;
    NextToken();
  } else if (m_pToken->m_type == TOKminus) {
    accessorIndex = ACCESSOR_NEGATIVE_INDEX;
    NextToken();
  }
  s = ParseSimpleExpression();
  if (m_pToken->m_type != TOKrbracket) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
          XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
    if (s) {
      delete s;
    }
  } else {
    pExp = new CXFA_FMIndexExpression(line, accessorIndex, s, FALSE);
  }
  return pExp;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() {
  CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  Check(TOKlparen);
  if (m_pToken->m_type != TOKrparen) {
    pExp1 = ParseLogicalOrExpression();
    while (m_pToken->m_type == TOKassign) {
      NextToken();
      pExp2 = ParseLogicalOrExpression();
      if (m_pErrorInfo->message.IsEmpty()) {
        pExp1 = new CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);
      } else {
        delete pExp1;
        pExp1 = 0;
      }
    }
    Check(TOKrparen);
  } else {
    NextToken();
  }
  return pExp1;
}
CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() {
  FX_DWORD line = m_pToken->m_uLinenum;
  CXFA_FMExpression* e = 0;
  CFX_PtrArray* expression = new CFX_PtrArray();
  while (1) {
    switch (m_pToken->m_type) {
      case TOKeof:
      case TOKendif:
      case TOKelseif:
      case TOKelse:
      case TOKendwhile:
      case TOKendfor:
      case TOKend:
      case TOKendfunc:
        break;
      case TOKfunc:
        e = ParseFunction();
        if (e) {
          expression->Add(e);
        }
        continue;
      default:
        e = ParseExpression();
        if (e) {
          expression->Add(e);
        }
        continue;
    }
    break;
  }
  CXFA_FMBlockExpression* pExp = 0;
  if (m_pErrorInfo->message.IsEmpty()) {
    pExp = new CXFA_FMBlockExpression(line, expression);
  } else {
    int32_t size = expression->GetSize();
    int32_t index = 0;
    while (index < size) {
      e = (CXFA_FMExpression*)expression->GetAt(index);
      delete e;
      index++;
    }
    expression->RemoveAll();
    delete expression;
    expression = 0;
  }
  return pExp;
}
CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() {
  CXFA_FMSimpleExpression* pExpression = 0;
  CXFA_FMExpression* pIfExpression = 0;
  CXFA_FMExpression* pElseExpression = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  const FX_WCHAR* pStartPos = m_lexer->SavePos();
  NextToken();
  Check(TOKlparen);
  while (m_pToken->m_type != TOKrparen) {
    if (pExpression) {
      delete pExpression;
    }
    pExpression = ParseSimpleExpression();
    if (m_pToken->m_type == TOKcomma) {
      NextToken();
    } else {
      break;
    }
  }
  Check(TOKrparen);
  if (m_pToken->m_type != TOKthen) {
    if (pExpression) {
      delete pExpression;
    }
    m_lexer->SetCurrentLine(line);
    m_pToken = new CXFA_FMToken(line);
    m_pToken->m_type = TOKidentifier;
    m_pToken->m_wstring = FX_WSTRC(L"if");
    m_lexer->SetToken(m_pToken);
    m_lexer->RestorePos(pStartPos);
    return ParseExpExpression();
  }
  Check(TOKthen);
  pIfExpression = ParseBlockExpression();
  switch (m_pToken->m_type) {
    case TOKeof:
    case TOKendif:
      Check(TOKendif);
      break;
    case TOKif:
      pElseExpression = ParseIfExpression();
      Check(TOKendif);
      break;
    case TOKelseif:
      pElseExpression = ParseIfExpression();
      break;
    case TOKelse:
      NextToken();
      pElseExpression = ParseBlockExpression();
      Check(TOKendif);
      break;
    default:
      CFX_WideString ws_TempString = m_pToken->m_wstring;
      Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IFEND, ws_TempString.c_str());
      NextToken();
      break;
  }
  CXFA_FMIfExpression* pExp = 0;
  if (m_pErrorInfo->message.IsEmpty()) {
    pExp = new CXFA_FMIfExpression(line, pExpression, pIfExpression,
                                   pElseExpression);
  } else {
    if (pExpression) {
      delete pExpression;
    }
    if (pIfExpression) {
      delete pIfExpression;
    }
    if (pElseExpression) {
      delete pElseExpression;
    }
  }
  return pExp;
}
CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() {
  CXFA_FMExpression* e = 0;
  CXFA_FMSimpleExpression* pCondition = 0;
  CXFA_FMExpression* pExpression = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  pCondition = ParseParenExpression();
  Check(TOKdo);
  pExpression = ParseBlockExpression();
  Check(TOKendwhile);
  if (!m_pErrorInfo->message.IsEmpty()) {
    if (pCondition) {
      delete pCondition;
    }
    if (pExpression) {
      delete pExpression;
    }
    delete e;
    e = 0;
  } else {
    e = new CXFA_FMWhileExpression(line, pCondition, pExpression);
  }
  return e;
}
CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() {
  CXFA_FMSimpleExpression* e = 0;
  switch (m_pToken->m_type) {
    case TOKidentifier:
      e = ParseSimpleExpression();
      break;
    default:
      CFX_WideString ws_TempString = m_pToken->m_wstring;
      Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
            ws_TempString.c_str());
      NextToken();
      break;
  }
  return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseForExpression() {
  CXFA_FMExpression* e = 0;
  CFX_WideStringC wsVariant;
  CXFA_FMSimpleExpression* pAssignment = 0;
  CXFA_FMSimpleExpression* pAccessor = 0;
  CXFA_FMSimpleExpression* pStep = 0;
  CXFA_FMExpression* pList = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
  }
  wsVariant = m_pToken->m_wstring;
  NextToken();
  if (m_pToken->m_type == TOKassign) {
    NextToken();
    pAssignment = ParseSimpleExpression();
  } else {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
  }
  int32_t iDirection = 0;
  if (m_pToken->m_type == TOKupto) {
    iDirection = 1;
  } else if (m_pToken->m_type == TOKdownto) {
    iDirection = -1;
  } else {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, L"upto or downto",
          (const FX_WCHAR*)ws_TempString);
  }
  NextToken();
  pAccessor = ParseSimpleExpression();
  if (m_pToken->m_type == TOKstep) {
    NextToken();
    pStep = ParseSimpleExpression();
  }
  Check(TOKdo);
  pList = ParseBlockExpression();
  Check(TOKendfor);
  if (m_pErrorInfo->message.IsEmpty()) {
    e = new CXFA_FMForExpression(line, wsVariant, pAssignment, pAccessor,
                                 iDirection, pStep, pList);
  } else {
    if (pAssignment) {
      delete pAssignment;
    }
    if (pAccessor) {
      delete pAccessor;
    }
    if (pStep) {
      delete pStep;
    }
    if (pList) {
      delete pList;
    }
  }
  return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() {
  CXFA_FMExpression* e = 0;
  CFX_WideStringC wsIdentifier;
  CFX_PtrArray* pAccessors = 0;
  CXFA_FMExpression* pList = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
  }
  wsIdentifier = m_pToken->m_wstring;
  NextToken();
  Check(TOKin);
  Check(TOKlparen);
  if (m_pToken->m_type == TOKrparen) {
    CFX_WideString ws_TempString = m_pToken->m_wstring;
    Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
          ws_TempString.c_str());
    NextToken();
  } else {
    pAccessors = new CFX_PtrArray();
    while (m_pToken->m_type != TOKrparen) {
      CXFA_FMSimpleExpression* s = ParseSimpleExpression();
      if (s) {
        pAccessors->Add(s);
      }
      if (m_pToken->m_type == TOKcomma) {
        NextToken();
      } else {
        break;
      }
    }
    Check(TOKrparen);
  }
  Check(TOKdo);
  pList = ParseBlockExpression();
  Check(TOKendfor);
  if (m_pErrorInfo->message.IsEmpty()) {
    e = new CXFA_FMForeachExpression(line, wsIdentifier, pAccessors, pList);
  } else {
    if (pAccessors) {
      CXFA_FMSimpleExpression* s = 0;
      int32_t size = pAccessors->GetSize();
      int32_t index = 0;
      while (index < size) {
        s = (CXFA_FMSimpleExpression*)pAccessors->GetAt(index);
        delete s;
        index++;
      }
      pAccessors->RemoveAll();
      delete pAccessors;
      pAccessors = 0;
    }
    if (pList) {
      delete pList;
    }
  }
  return e;
}
CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() {
  CXFA_FMExpression* e = 0;
  FX_DWORD line = m_pToken->m_uLinenum;
  NextToken();
  e = ParseBlockExpression();
  Check(TOKend);
  if (m_pErrorInfo->message.IsEmpty()) {
    e = new CXFA_FMDoExpression(line, e);
  } else {
    delete e;
    e = 0;
  }
  return e;
}
