Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression: ICE genCheckedRecordField with unsafeAddr and macros #23784

Closed
mratsim opened this issue Jul 1, 2024 · 3 comments · Fixed by #23792
Closed

Regression: ICE genCheckedRecordField with unsafeAddr and macros #23784

mratsim opened this issue Jul 1, 2024 · 3 comments · Fixed by #23792

Comments

@mratsim
Copy link
Collaborator

mratsim commented Jul 1, 2024

This is a followup to #23760 that fixed #23755 to try to get Constantine to compile on devel.

Unfortunately there is yet another regression on devel introduced in #23477 related to this when calling bindSym'ed constants (or so i suppose):

func getOne*(T: type FF): T {.noInit, inline.} =
  cast[ptr T](T.getMontyOne().unsafeAddr)[]

The crash is

[...]/t_debug_ice.nim(20, 5) Error: internal error: genCheckedRecordField
No stack traceback available
To create a stacktrace, rerun compilation with './koch temp c <file>', see https://nim-lang.github.io/Nim/intern.html#debugging-the-compiler for details

Full repro, sorry for the length, the bug tends to be finicky and disappears if nudged a bit too much. Also as mentioned in the code comments, everything is already a pile of workarounds for #14021 and #16774

!nim c

# debug ICE: genCheckedRecordField
# apparently after https://github.com/nim-lang/Nim/pull/23477

import std/bitops, std/macros

# --------------------------------------------------------------

type Algebra = enum
  BN254_Snarks

type SecretWord* = distinct uint64
const WordBitWidth* = sizeof(SecretWord) * 8

func wordsRequired*(bits: int): int {.inline.} =
  const divShiftor = fastLog2(WordBitWidth)
  result = (bits + WordBitWidth - 1) shr divShiftor

type
  BigInt*[bits: static int] = object
    limbs*: array[bits.wordsRequired, SecretWord]  # <--- crash points to here

# --------------------------------------------------------------

const CurveBitWidth = [
  BN254_Snarks: 254
]

const BN254_Snarks_Modulus = BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x2, SecretWord 0x3, SecretWord 0x4])
const BN254_Snarks_Order = BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x1, SecretWord 0x2, SecretWord 0x2])

func montyOne*(M: BigInt[254]): BigInt[254] =
  ## Returns "1 (mod M)" in the Montgomery domain.
  ## This is equivalent to R (mod M) in the natural domain
  BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x1, SecretWord 0x1, SecretWord 0x1])


{.experimental: "dynamicBindSym".}

type
  DerivedConstantMode* = enum
    kModulus
    kOrder

macro genDerivedConstants*(mode: static DerivedConstantMode): untyped =
  ## Generate constants derived from the main constants
  ##
  ## For example
  ## - the Montgomery magic constant "R^2 mod N" in ROM
  ##   For each curve under the private symbol "MyCurve_R2modP"
  ## - the Montgomery magic constant -1/P mod 2^Wordbitwidth
  ##   For each curve under the private symbol "MyCurve_NegInvModWord
  ## - ...

  # Now typedesc are NimNode and there is no way to translate
  # NimNode -> typedesc easily so we can't
  # "for curve in low(Curve) .. high(Curve):"
  # As an ugly workaround, we count
  # The item at position 0 is a pragma
  result = newStmtList()

  template used(name: string): NimNode =
    nnkPragmaExpr.newTree(
      ident(name),
      nnkPragma.newTree(ident"used")
    )

  let ff = if mode == kModulus: "_Fp" else: "_Fr"

  for curveSym in low(Algebra) .. high(Algebra):
    let curve = $curveSym
    let M = if mode == kModulus: bindSym(curve & "_Modulus")
            else: bindSym(curve & "_Order")

    # const MyCurve_montyOne = montyOne(MyCurve_Modulus)
    result.add newConstStmt(
      used(curve & ff & "_MontyOne"), newCall(
        bindSym"montyOne",
        M
      )
    )

# --------------------------------------------------------------

{.experimental: "dynamicBindSym".}

genDerivedConstants(kModulus)
genDerivedConstants(kOrder)

proc bindConstant(ff: NimNode, property: string): NimNode =
  # Need to workaround https://github.com/nim-lang/Nim/issues/14021
  # which prevents checking if a type FF[Name] = Fp[Name] or Fr[Name]
  # was instantiated with Fp or Fr.
  # getTypeInst only returns FF and sameType doesn't work.
  # so quote do + when checks.
  let T = getTypeInst(ff)
  T.expectKind(nnkBracketExpr)
  doAssert T[0].eqIdent("typedesc")

  let curve =
    if T[1].kind == nnkBracketExpr: # typedesc[Fp[BLS12_381]] as used internally
      # doAssert T[1][0].eqIdent"Fp" or T[1][0].eqIdent"Fr", "Found ident: '" & $T[1][0] & "' instead of 'Fp' or 'Fr'"
      T[1][1].expectKind(nnkIntLit) # static enum are ints in the VM
      $Algebra(T[1][1].intVal)
    else: # typedesc[bls12381_fp] alias as used for C exports
      let T1 = getTypeInst(T[1].getImpl()[2])
      if T1.kind != nnkBracketExpr or
         T1[1].kind != nnkIntLit:
        echo T.repr()
        echo T1.repr()
        echo getTypeInst(T1).treerepr()
        error "getTypeInst didn't return the full instantiation." &
          " Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44"
      $Algebra(T1[1].intVal)

  let curve_fp = bindSym(curve & "_Fp_" & property)
  let curve_fr = bindSym(curve & "_Fr_" & property)
  result = quote do:
    when `ff` is Fp:
      `curve_fp`
    elif `ff` is Fr:
      `curve_fr`
    else:
      {.error: "Unreachable, received type: " & $`ff`.}

# --------------------------------------------------------------

template matchingBigInt*(Name: static Algebra): untyped =
  ## BigInt type necessary to store the prime field Fp
  # Workaround: https://github.com/nim-lang/Nim/issues/16774
  # as we cannot do array accesses in type section.
  # Due to generic sandwiches, it must be exported.
  BigInt[CurveBitWidth[Name]]

type
  Fp*[Name: static Algebra] = object
    mres*: matchingBigInt(Name)

macro getMontyOne*(ff: type Fp): untyped =
  ## Get one in Montgomery representation (i.e. R mod P)
  result = bindConstant(ff, "MontyOne")

func getOne*(T: type Fp): T {.noInit, inline.} =
  cast[ptr T](T.getMontyOne().unsafeAddr)[]

# --------------------------------------------------------------

let a = Fp[BN254_Snarks].getOne()
foo(a) # oops this was a leftover that broke the bisect.
Copy link
Contributor

github-actions bot commented Jul 1, 2024

🐧 Linux bisect by @juancarlospaco (collaborator)
devel 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(114, 1) Error: undeclared identifier: 'foo'
assertions.nim(34)       raiseAssert
Error: unhandled exception: errGenerated [AssertionDefect]

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:05
  • Finished 2024-07-01T20:33:06
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
stable 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(114, 1) Error: undeclared identifier: 'foo'
assertions.nim(34)       raiseAssert
Error: unhandled exception: options.nim(682, 5) `false` errGenerated [AssertionDefect]

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:10
  • Finished 2024-07-01T20:33:10
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
2.0.4 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(114, 1) Error: undeclared identifier: 'foo'
assertions.nim(34)       raiseAssert
Error: unhandled exception: options.nim(681, 5) `false` errGenerated [AssertionDefect]

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:13
  • Finished 2024-07-01T20:33:13
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
2.0.0 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(114, 1) Error: undeclared identifier: 'foo'
assertions.nim(34)       raiseAssert
Error: unhandled exception: options.nim(664, 5) `false` errGenerated [AssertionDefect]

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:17
  • Finished 2024-07-01T20:33:17
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
1.6.20 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(114, 1) Error: undeclared identifier: 'foo'
candidates (edit distance, scope distance); see '--spellSuggest': 
 (2, 2): 'bool' [type declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/basic_types.nim(15, 3)]
 (2, 2): 'io' [module declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(3131, 14)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(1595, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(386, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(397, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(408, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(420, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(434, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(445, 6)]
 (2, 2): 'low' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(451, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(216, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(225, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(226, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(227, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(228, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(394, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(397, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(398, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(399, 6)]
 (2, 2): 'mod' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(400, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(123, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(166, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(173, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(174, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(175, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(176, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(323, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(325, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(326, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(327, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(328, 6)]
 (2, 2): 'not' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/basic_types.nim(45, 6)]
 (2, 2): 'of' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(917, 6)]
 (2, 2): 'on' [const declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/basic_types.nim(19, 3)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(117, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(302, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(307, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(308, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(309, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(310, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(351, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(353, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(354, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(355, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(356, 6)]
 (2, 2): 'or' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/basic_types.nim(53, 6)]
 (2, 2): 'or' [template declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/core/macros.nim(197, 10)]
 (2, 2): 'pop' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system.nim(1867, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(312, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(317, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(318, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(319, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(320, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(358, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(360, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(361, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(362, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/arithmetics.nim(363, 6)]
 (2, 2): 'xor' [proc declared in /home/runner/.choosenim/toolchains/nim-1.6.20/lib/system/basic_types.nim(58, 6)]
fatal.nim(54)            sysFatal
Error: unhandled exception: options.nim(662, 14) `false` errGenerated [AssertionDefect]

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:20
  • Finished 2024-07-01T20:33:20
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
1.4.8 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(113, 25) template/generic instantiation of `getOne` from here
/home/runner/work/Nim/Nim/temp.nim(111, 16) template/generic instantiation of `getMontyOne` from here
/home/runner/work/Nim/Nim/temp.nim(93, 18) Error: undeclared identifier: 'Fr'

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:22
  • Finished 2024-07-01T20:33:23
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
1.2.18 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(113, 25) template/generic instantiation of `getOne` from here
/home/runner/work/Nim/Nim/temp.nim(111, 16) template/generic instantiation of `getMontyOne` from here
/home/runner/work/Nim/Nim/temp.nim(93, 18) Error: undeclared identifier: 'Fr'

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:26
  • Finished 2024-07-01T20:33:26
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
1.0.10 👎 FAIL

Output

Error: Command failed: nim c --run  -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(113, 25) template/generic instantiation of `getOne` from here
/home/runner/work/Nim/Nim/temp.nim(111, 16) template/generic instantiation of `getMontyOne` from here
/home/runner/work/Nim/Nim/temp.nim(93, 18) Error: undeclared identifier: 'Fr'

IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:33:29
  • Finished 2024-07-01T20:33:29
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("bitops")
    ),
    nnkInfix.newTree(
      newIdentNode("/"),
      newIdentNode("std"),
      newIdentNode("macros")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      newIdentNode("Algebra"),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("BN254_Snarks")
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("SecretWord")
      ),
      newEmptyNode(),
      nnkDistinctTy.newTree(
        newIdentNode("uint64")
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("WordBitWidth")
      ),
      newEmptyNode(),
      nnkInfix.newTree(
        newIdentNode("*"),
        nnkCall.newTree(
          newIdentNode("sizeof"),
          newIdentNode("SecretWord")
        ),
        newLit(8)
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("wordsRequired")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int"),
      nnkIdentDefs.newTree(
        newIdentNode("bits"),
        newIdentNode("int"),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkConstSection.newTree(
        nnkConstDef.newTree(
          newIdentNode("divShiftor"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("fastLog2"),
            newIdentNode("WordBitWidth")
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkInfix.newTree(
          newIdentNode("shr"),
          nnkPar.newTree(
            nnkInfix.newTree(
              newIdentNode("-"),
              nnkInfix.newTree(
                newIdentNode("+"),
                newIdentNode("bits"),
                newIdentNode("WordBitWidth")
              ),
              newLit(1)
            )
          ),
          newIdentNode("divShiftor")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("BigInt")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("bits"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("int")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("limbs")
            ),
            nnkBracketExpr.newTree(
              newIdentNode("array"),
              nnkDotExpr.newTree(
                newIdentNode("bits"),
                newIdentNode("wordsRequired")
              ),
              newIdentNode("SecretWord")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("CurveBitWidth"),
      newEmptyNode(),
      nnkBracket.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("BN254_Snarks"),
          newLit(254)
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Modulus"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(3)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(4)
            )
          )
        )
      )
    )
  ),
  nnkConstSection.newTree(
    nnkConstDef.newTree(
      newIdentNode("BN254_Snarks_Order"),
      newEmptyNode(),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(2)
            )
          )
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("montyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        newLit(254)
      ),
      nnkIdentDefs.newTree(
        newIdentNode("M"),
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Returns \"1 (mod M)\" in the Montgomery domain.\nThis is equivalent to R (mod M) in the natural domain"),
      nnkObjConstr.newTree(
        nnkBracketExpr.newTree(
          newIdentNode("BigInt"),
          newLit(254)
        ),
        nnkExprColonExpr.newTree(
          newIdentNode("limbs"),
          nnkBracket.newTree(
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            ),
            nnkCommand.newTree(
              newIdentNode("SecretWord"),
              newLit(1)
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("DerivedConstantMode")
      ),
      newEmptyNode(),
      nnkEnumTy.newTree(
        newEmptyNode(),
        newIdentNode("kModulus"),
        newIdentNode("kOrder")
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("genDerivedConstants")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("mode"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("DerivedConstantMode")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Generate constants derived from the main constants\n\nFor example\n- the Montgomery magic constant \"R^2 mod N\" in ROM\n  For each curve under the private symbol \"MyCurve_R2modP\"\n- the Montgomery magic constant -1/P mod 2^Wordbitwidth\n  For each curve under the private symbol \"MyCurve_NegInvModWord\n- ..."),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newStmtList")
        )
      ),
      nnkTemplateDef.newTree(
        newIdentNode("used"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newIdentNode("NimNode"),
          nnkIdentDefs.newTree(
            newIdentNode("name"),
            newIdentNode("string"),
            newEmptyNode()
          )
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkCall.newTree(
            nnkDotExpr.newTree(
              newIdentNode("nnkPragmaExpr"),
              newIdentNode("newTree")
            ),
            nnkCall.newTree(
              newIdentNode("ident"),
              newIdentNode("name")
            ),
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("nnkPragma"),
                newIdentNode("newTree")
              ),
              nnkCallStrLit.newTree(
                newIdentNode("ident"),
                newLit("used")
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("ff"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                newIdentNode("mode"),
                newIdentNode("kModulus")
              ),
              nnkStmtList.newTree(
                newLit("_Fp")
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                newLit("_Fr")
              )
            )
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("curveSym"),
        nnkInfix.newTree(
          newIdentNode(".."),
          nnkCall.newTree(
            newIdentNode("low"),
            newIdentNode("Algebra")
          ),
          nnkCall.newTree(
            newIdentNode("high"),
            newIdentNode("Algebra")
          )
        ),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("curve"),
              newEmptyNode(),
              nnkPrefix.newTree(
                newIdentNode("$"),
                newIdentNode("curveSym")
              )
            )
          ),
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("M"),
              newEmptyNode(),
              nnkIfExpr.newTree(
                nnkElifExpr.newTree(
                  nnkInfix.newTree(
                    newIdentNode("=="),
                    newIdentNode("mode"),
                    newIdentNode("kModulus")
                  ),
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Modulus")
                      )
                    )
                  )
                ),
                nnkElseExpr.newTree(
                  nnkStmtList.newTree(
                    nnkCall.newTree(
                      newIdentNode("bindSym"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newIdentNode("curve"),
                        newLit("_Order")
                      )
                    )
                  )
                )
              )
            )
          ),
          nnkCommand.newTree(
            nnkDotExpr.newTree(
              newIdentNode("result"),
              newIdentNode("add")
            ),
            nnkCall.newTree(
              newIdentNode("newConstStmt"),
              nnkCall.newTree(
                newIdentNode("used"),
                nnkInfix.newTree(
                  newIdentNode("&"),
                  nnkInfix.newTree(
                    newIdentNode("&"),
                    newIdentNode("curve"),
                    newIdentNode("ff")
                  ),
                  newLit("_MontyOne")
                )
              ),
              nnkCall.newTree(
                newIdentNode("newCall"),
                nnkCallStrLit.newTree(
                  newIdentNode("bindSym"),
                  newLit("montyOne")
                ),
                newIdentNode("M")
              )
            )
          )
        )
      )
    )
  ),
  nnkPragma.newTree(
    nnkExprColonExpr.newTree(
      newIdentNode("experimental"),
      newLit("dynamicBindSym")
    )
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kModulus")
  ),
  nnkCall.newTree(
    newIdentNode("genDerivedConstants"),
    newIdentNode("kOrder")
  ),
  nnkProcDef.newTree(
    newIdentNode("bindConstant"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("NimNode"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        newIdentNode("NimNode"),
        newEmptyNode()
      ),
      nnkIdentDefs.newTree(
        newIdentNode("property"),
        newIdentNode("string"),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("T"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("getTypeInst"),
            newIdentNode("ff")
          )
        )
      ),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          newIdentNode("T"),
          newIdentNode("expectKind")
        ),
        newIdentNode("nnkBracketExpr")
      ),
      nnkCommand.newTree(
        newIdentNode("doAssert"),
        nnkCall.newTree(
          nnkDotExpr.newTree(
            nnkBracketExpr.newTree(
              newIdentNode("T"),
              newLit(0)
            ),
            newIdentNode("eqIdent")
          ),
          newLit("typedesc")
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve"),
          newEmptyNode(),
          nnkIfExpr.newTree(
            nnkElifExpr.newTree(
              nnkInfix.newTree(
                newIdentNode("=="),
                nnkDotExpr.newTree(
                  nnkBracketExpr.newTree(
                    newIdentNode("T"),
                    newLit(1)
                  ),
                  newIdentNode("kind")
                ),
                newIdentNode("nnkBracketExpr")
              ),
              nnkStmtList.newTree(
                nnkCall.newTree(
                  nnkDotExpr.newTree(
                    nnkBracketExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T"),
                        newLit(1)
                      ),
                      newLit(1)
                    ),
                    newIdentNode("expectKind")
                  ),
                  newIdentNode("nnkIntLit")
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        nnkBracketExpr.newTree(
                          newIdentNode("T"),
                          newLit(1)
                        ),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            ),
            nnkElseExpr.newTree(
              nnkStmtList.newTree(
                nnkLetSection.newTree(
                  nnkIdentDefs.newTree(
                    newIdentNode("T1"),
                    newEmptyNode(),
                    nnkCall.newTree(
                      newIdentNode("getTypeInst"),
                      nnkBracketExpr.newTree(
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkBracketExpr.newTree(
                              newIdentNode("T"),
                              newLit(1)
                            ),
                            newIdentNode("getImpl")
                          )
                        ),
                        newLit(2)
                      )
                    )
                  )
                ),
                nnkIfStmt.newTree(
                  nnkElifBranch.newTree(
                    nnkInfix.newTree(
                      newIdentNode("or"),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          newIdentNode("T1"),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkBracketExpr")
                      ),
                      nnkInfix.newTree(
                        newIdentNode("!="),
                        nnkDotExpr.newTree(
                          nnkBracketExpr.newTree(
                            newIdentNode("T1"),
                            newLit(1)
                          ),
                          newIdentNode("kind")
                        ),
                        newIdentNode("nnkIntLit")
                      )
                    ),
                    nnkStmtList.newTree(
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            newIdentNode("T1"),
                            newIdentNode("repr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("echo"),
                        nnkCall.newTree(
                          nnkDotExpr.newTree(
                            nnkCall.newTree(
                              newIdentNode("getTypeInst"),
                              newIdentNode("T1")
                            ),
                            newIdentNode("treerepr")
                          )
                        )
                      ),
                      nnkCommand.newTree(
                        newIdentNode("error"),
                        nnkInfix.newTree(
                          newIdentNode("&"),
                          newLit("getTypeInst didn\'t return the full instantiation."),
                          newLit(" Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44")
                        )
                      )
                    )
                  )
                ),
                nnkPrefix.newTree(
                  newIdentNode("$"),
                  nnkCall.newTree(
                    newIdentNode("Algebra"),
                    nnkDotExpr.newTree(
                      nnkBracketExpr.newTree(
                        newIdentNode("T1"),
                        newLit(1)
                      ),
                      newIdentNode("intVal")
                    )
                  )
                )
              )
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fp"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fp_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("curve_fr"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            nnkInfix.newTree(
              newIdentNode("&"),
              nnkInfix.newTree(
                newIdentNode("&"),
                newIdentNode("curve"),
                newLit("_Fr_")
              ),
              newIdentNode("property")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("quote"),
          nnkStmtList.newTree(
            nnkWhenStmt.newTree(
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fp")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fp")
                  )
                )
              ),
              nnkElifBranch.newTree(
                nnkInfix.newTree(
                  newIdentNode("is"),
                  nnkAccQuoted.newTree(
                    newIdentNode("ff")
                  ),
                  newIdentNode("Fr")
                ),
                nnkStmtList.newTree(
                  nnkAccQuoted.newTree(
                    newIdentNode("curve_fr")
                  )
                )
              ),
              nnkElse.newTree(
                nnkStmtList.newTree(
                  nnkPragma.newTree(
                    nnkExprColonExpr.newTree(
                      newIdentNode("error"),
                      nnkInfix.newTree(
                        newIdentNode("&"),
                        newLit("Unreachable, received type: "),
                        nnkPrefix.newTree(
                          newIdentNode("$"),
                          nnkAccQuoted.newTree(
                            newIdentNode("ff")
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ),
  nnkTemplateDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("matchingBigInt")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("Name"),
        nnkCommand.newTree(
          newIdentNode("static"),
          newIdentNode("Algebra")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("BigInt type necessary to store the prime field Fp"),
      nnkBracketExpr.newTree(
        newIdentNode("BigInt"),
        nnkBracketExpr.newTree(
          newIdentNode("CurveBitWidth"),
          newIdentNode("Name")
        )
      )
    )
  ),
  nnkTypeSection.newTree(
    nnkTypeDef.newTree(
      nnkPostfix.newTree(
        newIdentNode("*"),
        newIdentNode("Fp")
      ),
      nnkGenericParams.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("Name"),
          nnkCommand.newTree(
            newIdentNode("static"),
            newIdentNode("Algebra")
          ),
          newEmptyNode()
        )
      ),
      nnkObjectTy.newTree(
        newEmptyNode(),
        newEmptyNode(),
        nnkRecList.newTree(
          nnkIdentDefs.newTree(
            nnkPostfix.newTree(
              newIdentNode("*"),
              newIdentNode("mres")
            ),
            nnkCall.newTree(
              newIdentNode("matchingBigInt"),
              newIdentNode("Name")
            ),
            newEmptyNode()
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getMontyOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("untyped"),
      nnkIdentDefs.newTree(
        newIdentNode("ff"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      newCommentStmtNode("Get one in Montgomery representation (i.e. R mod P)"),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("bindConstant"),
          newIdentNode("ff"),
          newLit("MontyOne")
        )
      )
    )
  ),
  nnkFuncDef.newTree(
    nnkPostfix.newTree(
      newIdentNode("*"),
      newIdentNode("getOne")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("T"),
      nnkIdentDefs.newTree(
        newIdentNode("T"),
        nnkCommand.newTree(
          newIdentNode("type"),
          newIdentNode("Fp")
        ),
        newEmptyNode()
      )
    ),
    nnkPragma.newTree(
      newIdentNode("noInit"),
      newIdentNode("inline")
    ),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkBracketExpr.newTree(
        nnkCast.newTree(
          nnkPtrTy.newTree(
            newIdentNode("T")
          ),
          nnkDotExpr.newTree(
            nnkCall.newTree(
              nnkDotExpr.newTree(
                newIdentNode("T"),
                newIdentNode("getMontyOne")
              )
            ),
            newIdentNode("unsafeAddr")
          )
        )
      )
    )
  ),
  nnkLetSection.newTree(
    nnkIdentDefs.newTree(
      newIdentNode("a"),
      newEmptyNode(),
      nnkCall.newTree(
        nnkDotExpr.newTree(
          nnkBracketExpr.newTree(
            newIdentNode("Fp"),
            newIdentNode("BN254_Snarks")
          ),
          newIdentNode("getOne")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("foo"),
    newIdentNode("a")
  )
)
Stats
  • GCC 11.4.0
  • Clang 14.0.0
  • NodeJS 20.3
  • Created 2024-07-01T20:32:33Z
  • Comments 1
  • Commands nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

🤖 Bug found in 27 minutes bisecting 8 commits at 0 commits per second

@mratsim
Copy link
Collaborator Author

mratsim commented Jul 1, 2024

!nim c

# debug ICE: genCheckedRecordField
# apparently after https://github.com/nim-lang/Nim/pull/23477

import std/bitops, std/macros

# --------------------------------------------------------------

type Algebra = enum
  BN254_Snarks

type SecretWord* = distinct uint64
const WordBitWidth* = sizeof(SecretWord) * 8

func wordsRequired*(bits: int): int {.inline.} =
  const divShiftor = fastLog2(WordBitWidth)
  result = (bits + WordBitWidth - 1) shr divShiftor

type
  BigInt*[bits: static int] = object
    limbs*: array[bits.wordsRequired, SecretWord]  # <--- crash points to here

# --------------------------------------------------------------

const CurveBitWidth = [
  BN254_Snarks: 254
]

const BN254_Snarks_Modulus = BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x2, SecretWord 0x3, SecretWord 0x4])
const BN254_Snarks_Order = BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x1, SecretWord 0x2, SecretWord 0x2])

func montyOne*(M: BigInt[254]): BigInt[254] =
  ## Returns "1 (mod M)" in the Montgomery domain.
  ## This is equivalent to R (mod M) in the natural domain
  BigInt[254](limbs: [SecretWord 0x1, SecretWord 0x1, SecretWord 0x1, SecretWord 0x1])


{.experimental: "dynamicBindSym".}

type
  DerivedConstantMode* = enum
    kModulus
    kOrder

macro genDerivedConstants*(mode: static DerivedConstantMode): untyped =
  ## Generate constants derived from the main constants
  ##
  ## For example
  ## - the Montgomery magic constant "R^2 mod N" in ROM
  ##   For each curve under the private symbol "MyCurve_R2modP"
  ## - the Montgomery magic constant -1/P mod 2^Wordbitwidth
  ##   For each curve under the private symbol "MyCurve_NegInvModWord
  ## - ...

  # Now typedesc are NimNode and there is no way to translate
  # NimNode -> typedesc easily so we can't
  # "for curve in low(Curve) .. high(Curve):"
  # As an ugly workaround, we count
  # The item at position 0 is a pragma
  result = newStmtList()

  template used(name: string): NimNode =
    nnkPragmaExpr.newTree(
      ident(name),
      nnkPragma.newTree(ident"used")
    )

  let ff = if mode == kModulus: "_Fp" else: "_Fr"

  for curveSym in low(Algebra) .. high(Algebra):
    let curve = $curveSym
    let M = if mode == kModulus: bindSym(curve & "_Modulus")
            else: bindSym(curve & "_Order")

    # const MyCurve_montyOne = montyOne(MyCurve_Modulus)
    result.add newConstStmt(
      used(curve & ff & "_MontyOne"), newCall(
        bindSym"montyOne",
        M
      )
    )

# --------------------------------------------------------------

{.experimental: "dynamicBindSym".}

genDerivedConstants(kModulus)
genDerivedConstants(kOrder)

proc bindConstant(ff: NimNode, property: string): NimNode =
  # Need to workaround https://github.com/nim-lang/Nim/issues/14021
  # which prevents checking if a type FF[Name] = Fp[Name] or Fr[Name]
  # was instantiated with Fp or Fr.
  # getTypeInst only returns FF and sameType doesn't work.
  # so quote do + when checks.
  let T = getTypeInst(ff)
  T.expectKind(nnkBracketExpr)
  doAssert T[0].eqIdent("typedesc")

  let curve =
    if T[1].kind == nnkBracketExpr: # typedesc[Fp[BLS12_381]] as used internally
      # doAssert T[1][0].eqIdent"Fp" or T[1][0].eqIdent"Fr", "Found ident: '" & $T[1][0] & "' instead of 'Fp' or 'Fr'"
      T[1][1].expectKind(nnkIntLit) # static enum are ints in the VM
      $Algebra(T[1][1].intVal)
    else: # typedesc[bls12381_fp] alias as used for C exports
      let T1 = getTypeInst(T[1].getImpl()[2])
      if T1.kind != nnkBracketExpr or
         T1[1].kind != nnkIntLit:
        echo T.repr()
        echo T1.repr()
        echo getTypeInst(T1).treerepr()
        error "getTypeInst didn't return the full instantiation." &
          " Dealing with types in macros is hard, complain at https://github.com/nim-lang/RFCs/issues/44"
      $Algebra(T1[1].intVal)

  let curve_fp = bindSym(curve & "_Fp_" & property)
  let curve_fr = bindSym(curve & "_Fr_" & property)
  result = quote do:
    when `ff` is Fp:
      `curve_fp`
    elif `ff` is Fr:
      `curve_fr`
    else:
      {.error: "Unreachable, received type: " & $`ff`.}

# --------------------------------------------------------------

template matchingBigInt*(Name: static Algebra): untyped =
  ## BigInt type necessary to store the prime field Fp
  # Workaround: https://github.com/nim-lang/Nim/issues/16774
  # as we cannot do array accesses in type section.
  # Due to generic sandwiches, it must be exported.
  BigInt[CurveBitWidth[Name]]

type
  Fp*[Name: static Algebra] = object
    mres*: matchingBigInt(Name)

macro getMontyOne*(ff: type Fp): untyped =
  ## Get one in Montgomery representation (i.e. R mod P)
  result = bindConstant(ff, "MontyOne")

func getOne*(T: type Fp): T {.noInit, inline.} =
  cast[ptr T](T.getMontyOne().unsafeAddr)[]

# --------------------------------------------------------------

let a = Fp[BN254_Snarks].getOne()

Copy link
Contributor

github-actions bot commented Jul 1, 2024

🐧 Linux bisect by @mratsim (collaborator)
devel 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:04
  • Finished 2024-07-01T20:58:04
  • Duration now

AST

stable 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:08
  • Finished 2024-07-01T20:58:08
  • Duration now

AST

2.0.4 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:11
  • Finished 2024-07-01T20:58:11
  • Duration now

AST

2.0.0 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:14
  • Finished 2024-07-01T20:58:14
  • Duration now

AST

1.6.20 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:16
  • Finished 2024-07-01T20:58:16
  • Duration now

AST

1.4.8 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:18
  • Finished 2024-07-01T20:58:18
  • Duration now

AST

1.2.18 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:21
  • Finished 2024-07-01T20:58:21
  • Duration

AST

1.0.10 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-07-01T20:58:23
  • Finished 2024-07-01T20:58:23
  • Duration now

AST

Stats
  • GCC 11.4.0
  • Clang 14.0.0
  • NodeJS 20.3
  • Created 2024-07-01T20:57:30Z
  • Comments 2
  • Commands nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

🤖 Bug found in 22 minutes bisecting 8 commits at 0 commits per second

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants