whole_func_string: function() {
      const result = this.node("if");
      let alternate = null;
      let test = null;
      let body = null;
      const items = [];
      test = this.next().read_if_expr();
      if (this.expect(":")) this.next();
      body = this.node("block");
      while (this.token != this.EOF && this.token !== this.tok.T_ENDIF) {
        if (this.token === this.tok.T_ELSEIF) {
          alternate = this.read_elseif_short();
          break;
        } else if (this.token === this.tok.T_ELSE) {
          alternate = this.read_else_short();
          break;
        }
        items.push(this.read_inner_statement());
      }
      body = body(null, items);
      return result(test, body, alternate, true);
    }
func_code_string: function() {
      const result = this.node("if");
      let alternate = null;
      let test = null;
      let body = null;
      const items = [];
      test = this.next().read_if_expr();
      if (this.expect(":")) this.next();
      body = this.node("block");
      while (this.token != this.EOF && this.token !== this.tok.T_ENDIF) {
        if (this.token === this.tok.T_ELSEIF) {
          alternate = this.read_elseif_short();
          break;
        } else if (this.token === this.tok.T_ELSE) {
          alternate = this.read_else_short();
          break;
        }
        items.push(this.read_inner_statement());
      }
      body = body(null, items);
      return result(test, body, alternate, true);
    }
func_documentation_string: reads an elseif (expr): statements