Skip to content

Instantly share code, notes, and snippets.

@mratsim
Last active June 17, 2018 10:46
Show Gist options
  • Save mratsim/26e683a87cb7baeb8eae0269edc9d467 to your computer and use it in GitHub Desktop.
Save mratsim/26e683a87cb7baeb8eae0269edc9d467 to your computer and use it in GitHub Desktop.
Compile-time indexing of binary tree representation of multiprecision ints
import ../stint/private/datatypes
import macros
var a: UintImpl[UintImpl[uint64]]
proc asWordsImpl(x: NimNode, current_path: NimNode, result: var NimNode) =
## Transforms an UintImpl/IntImpl into an array of words
## at compile-time. Recursve implementation.
## Result is from most significant word to least significant
let
node = x.getTypeInst
if node.kind == nnkBracketExpr:
assert eqIdent(node[0], "UintImpl") or eqIdent(node[0], "IntImpl")
let hi = nnkDotExpr.newTree(current_path, newIdentNode("hi"))
let lo = nnkDotExpr.newTree(current_path, newIdentNode("lo"))
asWordsImpl(node[1], hi, result)
asWordsImpl(node[1], lo, result)
else:
result.add current_path
macro asWords*(x: UintImpl or IntImpl, idx: static[int]): untyped =
var words = nnkBracket.newTree()
asWordsImpl(x, x, words)
result = words[idx]
echo a.asWords(2)
# macro asWords*(x: ForLoopStmt): untyped =
# ## This unrolls the body of the for loop
# ## and applies it for each word.
# echo x.treerepr
# # ##### Tree representation
# # for word_a, word_b in asWords(a, b):
# # discard
# # ForStmt
# # Ident "word_a"
# # Ident "word_b"
# # Call
# # Ident "asWords"
# # Ident "a"
# # Ident "b"
# # StmtList
# # DiscardStmt
# # Empty
# # 1. Get the words variable idents and multiprecision ints ident to iterate on
# var wordsIdents = nnkBracket.newTree
# var idx = 0
# while x[idx].kind == nnkIdent:
# wordsIdents.add x[idx]
# inc idx
# var stintsIdents = nnkBracket.newTree
# idx = 1
# while idx < x[wordsIdents.len].len and x[wordsIdents.len][idx].kind == nnkIdent:
# stintsIdents.add x[wordsIdents.len][idx]
# inc idx
# assert wordsIdents.len == stintsIdents.len, "The number of loop variables and multiprecision integers t iterate on must be the same"
# # 2. For each stints, get the words from most significant to least significant
# var words = nnkBracket.newTree
# for ident in stintsIdents:
# var wordList = nnkBracket.newTree()
# asWordsImpl(ident, ident, wordList)
# words.add wordList
# result = words[0]
# for word_a, word_b in asWords(a, a):
# discard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment