whole_func_string: function() {
      const result = this.node("foreach");
      this.expect(this.tok.T_FOREACH) && this.next();
      let source = null;
      let key = null;
      let value = null;
      let body = null;
      let shortForm = false;
      if (this.expect("(")) this.next();
      source = this.read_expr();
      if (this.expect(this.tok.T_AS)) {
        this.next();
        value = this.read_foreach_variable();
        if (this.token === this.tok.T_DOUBLE_ARROW) {
          key = value;
          value = this.next().read_foreach_variable();
        }
      }
  
      // grammatically correct but not supported by PHP
      if (key && key.kind === "list") {
        this.raiseError("Fatal Error : Cannot use list as key element");
      }
  
      if (this.expect(")")) this.next();
  
      if (this.token === ":") {
        shortForm = true;
        body = this.read_short_form(this.tok.T_ENDFOREACH);
      } else {
        body = this.read_statement();
      }
      return result(source, key, value, body, shortForm);
    }
func_code_string: function() {
      const result = this.node("foreach");
      this.expect(this.tok.T_FOREACH) && this.next();
      let source = null;
      let key = null;
      let value = null;
      let body = null;
      let shortForm = false;
      if (this.expect("(")) this.next();
      source = this.read_expr();
      if (this.expect(this.tok.T_AS)) {
        this.next();
        value = this.read_foreach_variable();
        if (this.token === this.tok.T_DOUBLE_ARROW) {
          key = value;
          value = this.next().read_foreach_variable();
        }
      }
  
      // grammatically correct but not supported by PHP
      if (key && key.kind === "list") {
        this.raiseError("Fatal Error : Cannot use list as key element");
      }
  
      if (this.expect(")")) this.next();
  
      if (this.token === ":") {
        shortForm = true;
        body = this.read_short_form(this.tok.T_ENDFOREACH);
      } else {
        body = this.read_statement();
      }
      return result(source, key, value, body, shortForm);
    }
func_documentation_string: Reads a foreach loop
  ```ebnf
  foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement
  ```
  @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L438
  @return {Foreach}