parseStmt method

  1. @override
ASTNode? parseStmt({
  1. required ParseStyle style,
})
override

Implementation

@override
ASTNode? parseStmt({required ParseStyle style}) {
  final precedings = savePrecedings();
  // handle emtpy statement.
  if (curTok.lexeme == lexer.lexicon.endOfStatementMark) {
    advance();
    return null;
  }

  if (curTok.lexeme == Token.endOfFile) {
    return null;
  }

  ASTNode stmt;

  switch (style) {
    case ParseStyle.script:
      if (curTok.lexeme == lexer.lexicon.kImport) {
        stmt = _parseImportDecl();
      } else if (curTok.lexeme == lexer.lexicon.kExport) {
        stmt = _parseExportStmt();
      } else if (curTok.lexeme == lexer.lexicon.kTypeDef) {
        stmt = _parseTypeAliasDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kNamespace) {
        stmt = _parseExplicitNamespaceDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kExtension) {
        stmt = _parseExtensionDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kAssert) {
        stmt = _parseAssertStmt();
      } else if (curTok.lexeme == lexer.lexicon.kExternal) {
        advance();
        if (curTok.lexeme == lexer.lexicon.kAbstract) {
          advance();
          stmt = _parseClassDecl(
              isAbstract: true, isExternal: true, isTopLevel: true);
        } else if (curTok.lexeme == lexer.lexicon.kClass) {
          stmt = _parseClassDecl(isExternal: true, isTopLevel: true);
        } else if (curTok.lexeme == lexer.lexicon.kEnum) {
          stmt = _parseEnumDecl(isExternal: true, isTopLevel: true);
        } else if (lexer.lexicon.variableDeclarationKeywords
            .contains(curTok.lexeme)) {
          final err = HTError.externalVar(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else if (curTok.lexeme == lexer.lexicon.kAsync) {
          advance();
          if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
            final err = HTError.asyncConstructor(
                filename: currrentFileName,
                line: curTok.line,
                column: curTok.column,
                offset: curTok.offset,
                length: curTok.length);
            errors.add(err);
            final errToken = advance();
            stmt = ASTEmptyLine(
                source: currentSource,
                line: errToken.line,
                column: errToken.column,
                offset: errToken.offset);
          } else {
            stmt = _parseFunction(
                isAsync: true, isExternal: true, isTopLevel: true);
          }
        } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
          stmt = _parseFunction(isExternal: true, isTopLevel: true);
        } else {
          final err = HTError.unexpected(lexer.lexicon.kExternal,
              HTLocale.current.declarationStatement, curTok.lexeme,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        }
      } else if (curTok.lexeme == lexer.lexicon.kAbstract) {
        advance();
        stmt = _parseClassDecl(
            isAbstract: true, isTopLevel: true, lateResolve: false);
      } else if (curTok.lexeme == lexer.lexicon.kClass) {
        stmt = _parseClassDecl(isTopLevel: true, lateResolve: false);
      } else if (curTok.lexeme == lexer.lexicon.kEnum) {
        stmt = _parseEnumDecl(isTopLevel: true);
      } else if (lexer.lexicon.kMutables.contains(curTok.lexeme)) {
        if (lexer.lexicon.destructuringDeclarationMarks
            .contains(peek(1).lexeme)) {
          stmt = _parseDestructuringDecl(isTopLevel: true, isMutable: true);
        } else {
          stmt = _parseVarDecl(isMutable: true, isTopLevel: true);
        }
      } else if (curTok.lexeme == lexer.lexicon.kImmutable) {
        if (lexer.lexicon.destructuringDeclarationMarks
            .contains(peek(1).lexeme)) {
          stmt = _parseDestructuringDecl(isTopLevel: true);
        } else {
          stmt = _parseVarDecl(isTopLevel: true);
        }
      } else if (curTok.lexeme == lexer.lexicon.kConst) {
        if (lexer.lexicon.destructuringDeclarationMarks
            .contains(peek(1).lexeme)) {
          stmt = _parseDestructuringDecl(isTopLevel: true);
        } else {
          stmt = _parseVarDecl(
            // isConst: true,
            isTopLevel: true,
          );
        }
      } else if (curTok.lexeme == lexer.lexicon.kLate) {
        stmt = _parseVarDecl(lateFinalize: true, isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kAsync) {
        advance();
        if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
          final err = HTError.asyncConstructor(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(isAsync: true, isTopLevel: true);
        }
      } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
        stmt = _parseFunction(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kStruct) {
        stmt =
            _parseStructDecl(isTopLevel: true); // , lateInitialize: false);
      } else if (curTok.lexeme == lexer.lexicon.kDelete) {
        stmt = _parseDeleteStmt();
      } else if (curTok.lexeme == lexer.lexicon.kIf) {
        stmt = _parseIf();
      } else if (curTok.lexeme == lexer.lexicon.kWhile) {
        stmt = _parseWhileStmt();
      } else if (curTok.lexeme == lexer.lexicon.kDo) {
        stmt = _parseDoStmt();
      } else if (curTok.lexeme == lexer.lexicon.kFor) {
        stmt = _parseForStmt();
      } else if (lexer.lexicon.kSwitchs.contains(curTok.lexeme)) {
        stmt = _parseSwitch();
      } else if (curTok.lexeme == lexer.lexicon.kThrow) {
        stmt = _parseThrowStmt();
      } else {
        stmt = _parseExprStmt();
      }
    case ParseStyle.module:
      if (curTok.lexeme == lexer.lexicon.kImport) {
        stmt = _parseImportDecl();
      } else if (curTok.lexeme == lexer.lexicon.kExport) {
        stmt = _parseExportStmt();
      } else if (curTok.lexeme == lexer.lexicon.kTypeDef) {
        stmt = _parseTypeAliasDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kNamespace) {
        stmt = _parseExplicitNamespaceDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kExtension) {
        stmt = _parseExtensionDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kExternal) {
        advance();
        if (curTok.lexeme == lexer.lexicon.kAbstract) {
          advance();
          if (curTok.lexeme != lexer.lexicon.kClass) {
            final err = HTError.unexpected(lexer.lexicon.kAbstract,
                HTLocale.current.classDeclaration, curTok.lexeme,
                filename: currrentFileName,
                line: curTok.line,
                column: curTok.column,
                offset: curTok.offset,
                length: curTok.length);
            errors.add(err);
            final errToken = advance();
            stmt = ASTEmptyLine(
                source: currentSource,
                line: errToken.line,
                column: errToken.column,
                offset: errToken.offset);
          } else {
            stmt = _parseClassDecl(
                isAbstract: true, isExternal: true, isTopLevel: true);
          }
        } else if (curTok.lexeme == lexer.lexicon.kClass) {
          stmt = _parseClassDecl(isExternal: true, isTopLevel: true);
        } else if (curTok.lexeme == lexer.lexicon.kEnum) {
          stmt = _parseEnumDecl(isExternal: true, isTopLevel: true);
        } else if (curTok.lexeme == lexer.lexicon.kAsync) {
          advance();
          stmt = _parseFunction(
              isAsync: true, isExternal: true, isTopLevel: true);
        } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
          stmt = _parseFunction(isExternal: true, isTopLevel: true);
        } else if (lexer.lexicon.variableDeclarationKeywords
            .contains(curTok.lexeme)) {
          final err = HTError.externalVar(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          final err = HTError.unexpected(lexer.lexicon.kExternal,
              HTLocale.current.declarationStatement, curTok.lexeme,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        }
      } else if (curTok.lexeme == lexer.lexicon.kAbstract) {
        advance();
        stmt = _parseClassDecl(isAbstract: true, isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kClass) {
        stmt = _parseClassDecl(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kEnum) {
        stmt = _parseEnumDecl(isTopLevel: true);
      } else if (lexer.lexicon.kMutables.contains(curTok.lexeme)) {
        stmt = _parseVarDecl(
            isMutable: true, isTopLevel: true, lateInitialize: true);
      } else if (curTok.lexeme == lexer.lexicon.kImmutable) {
        stmt = _parseVarDecl(lateInitialize: true, isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kLate) {
        stmt = _parseVarDecl(lateFinalize: true, isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kConst) {
        stmt = _parseVarDecl(
          lateInitialize: true,
          // isConst: true,
          isTopLevel: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kAsync) {
        advance();
        if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
          final err = HTError.asyncConstructor(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(isAsync: true, isTopLevel: true);
        }
      } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
        stmt = _parseFunction(isTopLevel: true);
      } else if (curTok.lexeme == lexer.lexicon.kStruct) {
        stmt = _parseStructDecl(isTopLevel: true);
      } else {
        final err = HTError.unexpected(HTLocale.current.module,
            HTLocale.current.declarationStatement, curTok.lexeme,
            filename: currrentFileName,
            line: curTok.line,
            column: curTok.column,
            offset: curTok.offset,
            length: curTok.length);
        errors.add(err);
        final errToken = advance();
        stmt = ASTEmptyLine(
            source: currentSource,
            line: errToken.line,
            column: errToken.column,
            offset: errToken.offset);
      }
    case ParseStyle.explicitNamespace:
      if (curTok.lexeme == lexer.lexicon.kTypeDef) {
        stmt = _parseTypeAliasDecl();
      } else if (curTok.lexeme == lexer.lexicon.kNamespace) {
        stmt = _parseExplicitNamespaceDecl();
      } else if (curTok.lexeme == lexer.lexicon.kExtension) {
        stmt = _parseExtensionDecl();
      } else if (curTok.lexeme == lexer.lexicon.kExternal) {
        advance();
        // if (curTok.lexeme == lexer.lexicon.kAbstract) {
        //   advance();
        //   if (curTok.lexeme != lexer.lexicon.kClass) {
        //     final err = HTError.unexpected(lexer.lexicon.kAbstract,
        //         HTLocale.current.classDeclaration, curTok.lexeme,
        //         filename: currrentFileName,
        //         line: curTok.line,
        //         column: curTok.column,
        //         offset: curTok.offset,
        //         length: curTok.length);
        //     errors.add(err);
        //     final errToken = advance();
        //     stmt = ASTEmptyLine(
        //         source: currentSource,
        //         line: errToken.line,
        //         column: errToken.column,
        //         offset: errToken.offset);
        //   } else {
        //     stmt = _parseClassDecl(isAbstract: true, isExternal: true);
        //   }
        // } else if (curTok.lexeme == lexer.lexicon.kClass) {
        //   stmt = _parseClassDecl(isExternal: true);
        // } else if (curTok.lexeme == lexer.lexicon.kEnum) {
        //   stmt = _parseEnumDecl(isExternal: true);
        // } else
        if (curTok.lexeme == lexer.lexicon.kAsync) {
          advance();
          if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
            final err = HTError.asyncConstructor(
                filename: currrentFileName,
                line: curTok.line,
                column: curTok.column,
                offset: curTok.offset,
                length: curTok.length);
            errors.add(err);
            final errToken = advance();
            stmt = ASTEmptyLine(
                source: currentSource,
                line: errToken.line,
                column: errToken.column,
                offset: errToken.offset);
          } else {
            stmt = _parseFunction(isAsync: true, isExternal: true);
          }
        } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
          stmt = _parseFunction(isExternal: true);
        }
        // else if (lexer.lexicon.variableDeclarationKeywords
        //     .contains(curTok.lexeme)) {
        //   final err = HTError.externalVar(
        //       filename: currrentFileName,
        //       line: curTok.line,
        //       column: curTok.column,
        //       offset: curTok.offset,
        //       length: curTok.length);
        //   errors.add(err);
        //   final errToken = advance();
        //   stmt = ASTEmptyLine(
        //       source: currentSource,
        //       line: errToken.line,
        //       column: errToken.column,
        //       offset: errToken.offset);
        // }
        else {
          final err = HTError.unexpected(lexer.lexicon.kExternal,
              HTLocale.current.declarationStatement, curTok.lexeme,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        }
      } else if (curTok.lexeme == lexer.lexicon.kAbstract) {
        advance();
        stmt = _parseClassDecl(
            isAbstract: true, lateResolve: _isWithinModuleNamespace);
      } else if (curTok.lexeme == lexer.lexicon.kClass) {
        stmt = _parseClassDecl(lateResolve: _isWithinModuleNamespace);
      } else if (curTok.lexeme == lexer.lexicon.kEnum) {
        stmt = _parseEnumDecl();
      } else if (lexer.lexicon.kMutables.contains(curTok.lexeme)) {
        stmt = _parseVarDecl(
            isMutable: true, lateInitialize: _isWithinModuleNamespace);
      } else if (curTok.lexeme == lexer.lexicon.kImmutable) {
        stmt = _parseVarDecl(lateInitialize: _isWithinModuleNamespace);
      } else if (curTok.lexeme == lexer.lexicon.kConst) {
        stmt = _parseVarDecl(lateInitialize: _isWithinModuleNamespace
            // isConst: true,
            );
      } else if (curTok.lexeme == lexer.lexicon.kAsync) {
        advance();
        stmt = _parseFunction(isAsync: true);
      } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
        stmt = _parseFunction();
      } else if (curTok.lexeme == lexer.lexicon.kStruct) {
        stmt = _parseStructDecl();
      } else {
        final err = HTError.unexpected(HTLocale.current.namespace,
            HTLocale.current.declarationStatement, curTok.lexeme,
            filename: currrentFileName,
            line: curTok.line,
            column: curTok.column,
            offset: curTok.offset,
            length: curTok.length);
        errors.add(err);
        final errToken = advance();
        stmt = ASTEmptyLine(
            source: currentSource,
            line: errToken.line,
            column: errToken.column,
            offset: errToken.offset);
      }
    case ParseStyle.classDefinition:
      // final isOverrided = expect([lexer.lexicon.kOverride], consume: true);
      // if (isOverrided) {
      //   final err = HTError.unsupported(
      //       lexer.lexicon.kOverride, kHetuVersion.toString(),
      //       filename: currrentFileName,
      //       line: curTok.line,
      //       column: curTok.column,
      //       offset: curTok.offset,
      //       length: curTok.length);
      //   errors.add(err);
      // }
      final isExternal = expect([lexer.lexicon.kExternal], consume: true) ||
          (_currentClassDeclaration?.isExternal ?? false);
      final isStatic = expect([lexer.lexicon.kStatic], consume: true);
      if (curTok.lexeme == lexer.lexicon.kTypeDef) {
        if (isExternal) {
          final err = HTError.external(HTLocale.current.typeAliasDeclaration,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseTypeAliasDecl();
        }
      } else if (lexer.lexicon.kMutables.contains(curTok.lexeme)) {
        stmt = _parseVarDecl(
          classId: _currentClassDeclaration?.id,
          // isOverrided: isOverrided,
          isExternal: isExternal,
          isMutable: true,
          isStatic: isStatic,
          lateInitialize: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kImmutable) {
        stmt = _parseVarDecl(
          classId: _currentClassDeclaration?.id,
          // isOverrided: isOverrided,
          isExternal: isExternal,
          isStatic: isStatic,
          lateInitialize: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kLate) {
        stmt = _parseVarDecl(
          classId: _currentClassDeclaration?.id,
          // isOverrided: isOverrided,
          isExternal: isExternal,
          isStatic: isStatic,
          lateFinalize: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kConst) {
        if (isStatic) {
          stmt = _parseVarDecl(
            // isConst: true,
            classId: _currentClassDeclaration?.id,
          );
        } else {
          final err = HTError.external(
            HTLocale.current.typeAliasDeclaration,
            filename: currrentFileName,
            line: curTok.line,
            column: curTok.column,
            offset: curTok.offset,
            length: curTok.length,
          );
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
            source: currentSource,
            line: errToken.line,
            column: errToken.column,
            offset: errToken.offset,
          );
        }
      } else if (curTok.lexeme == lexer.lexicon.kAsync) {
        advance();
        if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
          final err = HTError.asyncConstructor(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(
            // category: FunctionCategory.method,
            classId: _currentClassDeclaration?.id,
            isAsync: true,
            // isOverrided: isOverrided,
            isExternal: isExternal,
            isStatic: isStatic,
          );
        }
      } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
        stmt = _parseFunction(
            // category: FunctionCategory.method,
            classId: _currentClassDeclaration?.id,
            // isOverrided: isOverrided,
            isExternal: isExternal,
            isStatic: isStatic);
      } else if (curTok.lexeme == lexer.lexicon.kGet) {
        stmt = _parseFunction(
            category: FunctionCategory.getter,
            classId: _currentClassDeclaration?.id,
            // isOverrided: isOverrided,
            isExternal: isExternal,
            isStatic: isStatic);
      } else if (curTok.lexeme == lexer.lexicon.kSet) {
        stmt = _parseFunction(
            category: FunctionCategory.setter,
            classId: _currentClassDeclaration?.id,
            // isOverrided: isOverrided,
            isExternal: isExternal,
            isStatic: isStatic);
      } else if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
        if (isStatic) {
          final err = HTError.unexpected(lexer.lexicon.kStatic,
              HTLocale.current.declarationStatement, curTok.lexeme,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else if (isExternal && !_currentClassDeclaration!.isExternal) {
          final err = HTError.external(HTLocale.current.constructor,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(
            category: FunctionCategory.constructor,
            classId: _currentClassDeclaration?.id,
            isExternal: isExternal,
          );
        }
      } else if (curTok.lexeme == lexer.lexicon.kFactory) {
        if (isStatic) {
          final err = HTError.unexpected(lexer.lexicon.kStatic,
              HTLocale.current.declarationStatement, curTok.lexeme,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else if (isExternal && !_currentClassDeclaration!.isExternal) {
          final err = HTError.external(HTLocale.current.factory,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(
            category: FunctionCategory.factoryConstructor,
            classId: _currentClassDeclaration?.id,
            isExternal: isExternal,
            isStatic: true,
          );
        }
      } else {
        final err = HTError.unexpected(HTLocale.current.classDefinition,
            HTLocale.current.declarationStatement, curTok.lexeme,
            filename: currrentFileName,
            line: curTok.line,
            column: curTok.column,
            offset: curTok.offset,
            length: curTok.length);
        errors.add(err);
        final errToken = advance();
        stmt = ASTEmptyLine(
            source: currentSource,
            line: errToken.line,
            column: errToken.column,
            offset: errToken.offset);
      }
    case ParseStyle.structDefinition:
      final isExternal = expect([lexer.lexicon.kExternal], consume: true);
      final isStatic = expect([lexer.lexicon.kStatic], consume: true);
      if (lexer.lexicon.kMutables.contains(curTok.lexeme)) {
        stmt = _parseVarDecl(
          classId: _currentStructId,
          isExternal: isExternal,
          isMutable: true,
          isStatic: isStatic,
          isField: true,
          lateInitialize: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kImmutable) {
        stmt = _parseVarDecl(
          classId: _currentStructId,
          isExternal: isExternal,
          isStatic: isStatic,
          isField: true,
          lateInitialize: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kAsync) {
        advance();
        if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
          final err = HTError.asyncConstructor(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(
            // category: FunctionCategory.method,
            classId: _currentStructId,
            isAsync: true,
            isExternal: isExternal,
            isStatic: isStatic,
            isField: true,
          );
        }
      } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
        stmt = _parseFunction(
          // category: FunctionCategory.method,
          classId: _currentStructId,
          isExternal: isExternal,
          isStatic: isStatic,
          isField: true,
        );
      }
      // else if (curTok.lexeme == lexer.lexicon.kAsync) {
      //   if (isExternal) {
      //     final err = HTError.external(HTLocale.current.asyncFunction,
      //         filename: currrentFileName,
      //         line: curTok.line,
      //         column: curTok.column,
      //         offset: curTok.offset,
      //         length: curTok.length);
      //     errors.add(err);
      //     final errToken = advance();
      //     stmt = ASTEmptyLine(
      //         source: currentSource,
      //         line: errToken.line,
      //         column: errToken.column,
      //         offset: errToken.offset);
      //   } else {
      //     stmt = _parseFunction(
      //  //       category: FunctionCategory.method,
      //         classId: _currentStructId,
      //         isAsync: true,
      //         isField: true,
      //         isExternal: isExternal,
      //         isStatic: isStatic);
      //   }
      // }
      else if (curTok.lexeme == lexer.lexicon.kGet) {
        stmt = _parseFunction(
          category: FunctionCategory.getter,
          classId: _currentStructId,
          isExternal: isExternal,
          isStatic: isStatic,
          isField: true,
        );
      } else if (curTok.lexeme == lexer.lexicon.kSet) {
        stmt = _parseFunction(
          category: FunctionCategory.setter,
          classId: _currentStructId,
          isExternal: isExternal,
          isStatic: isStatic,
          isField: true,
        );
      } else if (lexer.lexicon.kConstructors.contains(curTok.lexeme)) {
        if (isStatic) {
          final err = HTError.unexpected(lexer.lexicon.kStatic,
              HTLocale.current.declarationStatement, curTok.lexeme,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else if (isExternal) {
          final err = HTError.external(HTLocale.current.constructor,
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
          final errToken = advance();
          stmt = ASTEmptyLine(
              source: currentSource,
              line: errToken.line,
              column: errToken.column,
              offset: errToken.offset);
        } else {
          stmt = _parseFunction(
            category: FunctionCategory.constructor,
            classId: _currentStructId,
            isExternal: isExternal,
            isField: true,
          );
        }
      } else {
        final err = HTError.unexpected(HTLocale.current.structDefinition,
            HTLocale.current.declarationStatement, curTok.lexeme,
            filename: currrentFileName,
            line: curTok.line,
            column: curTok.column,
            offset: curTok.offset,
            length: curTok.length);
        errors.add(err);
        final errToken = advance();
        stmt = ASTEmptyLine(
          source: currentSource,
          line: errToken.line,
          column: errToken.column,
          offset: errToken.offset,
        );
      }
    case ParseStyle.functionDefinition:
      if (curTok.lexeme == lexer.lexicon.kTypeDef) {
        stmt = _parseTypeAliasDecl();
      } else if (curTok.lexeme == lexer.lexicon.kNamespace) {
        stmt = _parseExplicitNamespaceDecl();
      } else if (curTok.lexeme == lexer.lexicon.kExtension) {
        stmt = _parseExtensionDecl();
      } else if (curTok.lexeme == lexer.lexicon.kAssert) {
        stmt = _parseAssertStmt();
      } else if (curTok.lexeme == lexer.lexicon.kAbstract) {
        advance();
        stmt = _parseClassDecl(isAbstract: true, lateResolve: false);
      } else if (curTok.lexeme == lexer.lexicon.kClass) {
        stmt = _parseClassDecl(lateResolve: false);
      } else if (curTok.lexeme == lexer.lexicon.kEnum) {
        stmt = _parseEnumDecl();
      } else if (lexer.lexicon.kMutables.contains(curTok.lexeme)) {
        if (lexer.lexicon.destructuringDeclarationMarks
            .contains(peek(1).lexeme)) {
          stmt = _parseDestructuringDecl(isMutable: true);
        } else {
          stmt = _parseVarDecl(isMutable: true);
        }
      } else if (curTok.lexeme == lexer.lexicon.kImmutable) {
        if (lexer.lexicon.destructuringDeclarationMarks
            .contains(peek(1).lexeme)) {
          stmt = _parseDestructuringDecl();
        } else {
          stmt = _parseVarDecl();
        }
      } else if (curTok.lexeme == lexer.lexicon.kConst) {
        if (lexer.lexicon.destructuringDeclarationMarks
            .contains(peek(1).lexeme)) {
          stmt = _parseDestructuringDecl();
        } else {
          stmt = _parseVarDecl(
              // isConst: true,
              );
        }
      } else if (curTok.lexeme == lexer.lexicon.kLate) {
        stmt = _parseVarDecl(lateFinalize: true);
      } else if (curTok.lexeme == lexer.lexicon.kAsync) {
        advance();
        stmt = _parseFunction(isAsync: true);
      } else if (lexer.lexicon.kFunctions.contains(curTok.lexeme)) {
        stmt = _parseFunction();
      } else if (curTok.lexeme == lexer.lexicon.kStruct) {
        stmt = _parseStructDecl(); // (lateInitialize: false);
      } else if (curTok.lexeme == lexer.lexicon.kDelete) {
        stmt = _parseDeleteStmt();
      } else if (curTok.lexeme == lexer.lexicon.kIf) {
        stmt = _parseIf();
      } else if (curTok.lexeme == lexer.lexicon.kWhile) {
        stmt = _parseWhileStmt();
      } else if (curTok.lexeme == lexer.lexicon.kDo) {
        stmt = _parseDoStmt();
      } else if (curTok.lexeme == lexer.lexicon.kFor) {
        stmt = _parseForStmt();
      } else if (lexer.lexicon.kSwitchs.contains(curTok.lexeme)) {
        stmt = _parseSwitch();
      } else if (curTok.lexeme == lexer.lexicon.kThrow) {
        stmt = _parseThrowStmt();
      } else if (curTok.lexeme == lexer.lexicon.kBreak) {
        if (!_isInLoop) {
          final err = HTError.misplacedBreak(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
        }
        final keyword = advance();
        final hasEndOfStmtMark = parseEndOfStmtMark();
        stmt = BreakStmt(keyword,
            hasEndOfStmtMark: hasEndOfStmtMark,
            source: currentSource,
            line: keyword.line,
            column: keyword.column,
            offset: keyword.offset,
            length: keyword.length);
      } else if (curTok.lexeme == lexer.lexicon.kContinue) {
        if (!_isInLoop) {
          final err = HTError.misplacedContinue(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
        }
        final keyword = advance();
        final hasEndOfStmtMark = parseEndOfStmtMark();
        stmt = ContinueStmt(keyword,
            hasEndOfStmtMark: hasEndOfStmtMark,
            source: currentSource,
            line: keyword.line,
            column: keyword.column,
            offset: keyword.offset,
            length: keyword.length);
      } else if (curTok.lexeme == lexer.lexicon.kReturn) {
        if (_currentFunctionDeclaration?.category ==
            FunctionCategory.constructor) {
          final err = HTError.misplacedReturn(
              filename: currrentFileName,
              line: curTok.line,
              column: curTok.column,
              offset: curTok.offset,
              length: curTok.length);
          errors.add(err);
        }
        stmt = _parseReturnStmt();
      } else {
        stmt = _parseExprStmt();
      }
    case ParseStyle.expression:
      stmt = parseExpr();
  }

  stmt.precedings = precedings;
  // it's possible that there's trailing comment after end of stmt mark (;).
  handleTrailing(stmt);

  return stmt;
}