Last active
June 17, 2018 10:46
-
-
Save mratsim/26e683a87cb7baeb8eae0269edc9d467 to your computer and use it in GitHub Desktop.
Compile-time indexing of binary tree representation of multiprecision ints
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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