function statement(context) {
    var i = indent, r, t = state.tokens.next, hasOwnScope = false;

    context |= prodParams.initial;

    if (t.id === ";") {
      advance(";");
      return;
    }

    // Is this a labelled statement?
    var res = isReserved(context, t);

    // We're being more tolerant here: if someone uses
    // a FutureReservedWord (that is not meant to start a statement)
    // as a label, we warn but proceed anyway.

    if (res && t.meta && t.meta.isFutureReservedWord && !t.fud) {
      warning("W024", t, t.id);
      res = false;
    }

    if (t.identifier && !res && peek().id === ":") {
      advance();
      advance(":");

      hasOwnScope = true;
      state.funct["(scope)"].stack();
      state.funct["(scope)"].block.addLabel(t.value, { token: state.tokens.curr });

      if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
        warning("W028", state.tokens.next, t.value, state.tokens.next.value);
      }

      t = state.tokens.next;
    }

    // Is it a lonely block?

    if (t.id === "{") {
      // Is it a switch case block?
      //
      //  switch (foo) {
      //    case bar: { <= here.
      //      ...
      //    }
      //  }
      var iscase = (state.funct["(verb)"] === "case" && state.tokens.curr.value === ":");
      block(context, true, true, false, false, iscase);

      if (hasOwnScope) {
        state.funct["(scope)"].unstack();
      }

      return;
    }

    // Parse the statement.

    r = expression(context, 0);

    if (r && !(r.identifier && r.value === "function") &&
        !(r.type === "(punctuator)" && r.left &&
          r.left.identifier && r.left.value === "function")) {
      if (!state.isStrict() && state.stmtMissingStrict()) {
        warning("E007");
      }
    }

    // Look for the final semicolon.

    if (!t.block) {
      if (!state.option.expr && (!r || !r.exps)) {
        warning("W030", state.tokens.curr);
      } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
        warning("W031", t);
      }

      parseFinalSemicolon(t);
    }


    // Restore the indentation.

    indent = i;
    if (hasOwnScope) {
      state.funct["(scope)"].unstack();
    }
    return r;
  }
Consume a statement.

@param {number} context - the parsing context; see `prod-params.js` for
                          more information

@returns {token} - the token describing the statement