<commit_before>#
# Declarative programming
#

proc getForLoopElems(code: NimNode): (NimNode, NimNode) =
  ## Get ``for`` statement's container and element
  if code.kind != nnkInfix or code[0] != ident("in") or code.len != 3:
    error("`X in Y` notation expected, found: $1".format(code.repr))
  result = (code[1], code[2])

macro forsome* (what, cond: untyped): untyped =
  ## For-like existential quantifier with natural syntax.
  ## It works similar to
  ## `sequtils.any <http://nim-lang.org/docs/sequtils.html#any>`_
  ## but is more generic.
  ##
  ## .. code-block:: nim
  ##  require:
  ##    forsome x in arr: x == key
  let (first, second) = getForLoopElems(what)
  template forImpl(fi, sec, cond) =
    block:
      var flag = false
      for fi in sec:
        if cond:
          flag = true
          break
      flag
  result = getAst(forImpl(first, second, cond))

macro forall* (what, cond: untyped): untyped =
  ## For-like universal quantifier with natural syntax.
  ## It works similar to
  ## `sequtils.all <http://nim-lang.org/docs/sequtils.html#all>`_
  ## but is more generic.
  ##
  ## .. code-block:: nim
  ##  require:
  ##    forall x in arr: x > 0
  let (first, second) = getForLoopElems(what)
  template forImpl(fi, sec, cond) =
    block:
      var flag = true
      for fi in sec:
        if not cond:
          flag = false
          break
      flag
  result = getAst(forImpl(first, second, cond))<commit_msg>better docs for forall and forsome<commit_after>#
# Declarative programming
#

proc getForLoopElems(code: NimNode): (NimNode, NimNode) =
  ## Get ``for`` statement's container and element
  if code.kind != nnkInfix or code[0] != ident("in") or code.len != 3:
    error("`X in Y` notation expected, found: $1".format(code.repr))
  result = (code[1], code[2])

proc flattenCondList(cond: NimNode): NimNode =
  if cond.kind == nnkStmtList or cond.kind == nnkStmtListExpr:
    var newCond = cond[0]
    for child in cond[1 ..^ cond.len]:
      newCond = infix(newCond, "and", child)
    newCond
  else:
    cond

macro forsome* (what, cond: untyped): untyped =
  ## For-like existential quantifier with natural syntax.
  ## It works similar to
  ## `sequtils.anyIt <http://nim-lang.org/docs/sequtils.html#any>`_.
  ##
  ## .. code-block:: nim
  ##  require:
  ##    forsome x in arr: x == key
  let (first, second) = getForLoopElems(what)
  let newCond = flattenCondList(cond)
  template forImpl(fi, sec, cond) =
    block:
      var flag = false
      for fi in sec:
        if cond:
          flag = true
          break
      flag
  result = getAst(forImpl(first, second, newCond))

macro forall* (what, cond: untyped): untyped =
  ## For-like universal quantifier with natural syntax.
  ## It works similar to
  ## `sequtils.allIt <http://nim-lang.org/docs/sequtils.html#all>`_.
  ##
  ## .. code-block:: nim
  ##  require:
  ##    forall x in arr: x > 0
  let (first, second) = getForLoopElems(what)
  let newCond = flattenCondList(cond)
  template forImpl(fi, sec, cond) =
    block:
      var flag = true
      for fi in sec:
        if not cond:
          flag = false
          break
      flag
  result = getAst(forImpl(first, second, newCond))
{'fraction_non_alphanumeric': 0.13529595991230817, 'fraction_numerical': 0.004384591293454432, 'mean_word_length': 2.825149700598802, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3378629', 'n_tokens_mistral': 1121, 'n_tokens_neox': 1086, 'n_words': 323}