// 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_pToken(nullptr), m_pErrorInfo(0) {}

int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc,
                           CXFA_FMErrorInfo* pErrorInfo) {
  m_pErrorInfo = pErrorInfo;
  m_lexer.reset(new CXFA_FMLexer(wsFormcalc, m_pErrorInfo));
  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 || m_pToken->m_type == TOKendfunc ||
        m_pToken->m_type == TOKendif || m_pToken->m_type == TOKelseif ||
        m_pToken->m_type == TOKelse || m_pToken->m_type == TOKreserver) {
      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 ||
                       m_pToken->m_type == TOKreserver) {
              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 ||
                           m_pToken->m_type == TOKreserver) {
                  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:
      case TOKreserver:
        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;
}
