Created
May 2, 2014 23:13
-
-
Save flaviut/880458a5d7ed23ddbd8e to your computer and use it in GitHub Desktop.
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
## Provides utility methods to make working with bit manipulations | |
## easier and less error prone | |
const | |
validBitfieldType = ["int", "int8", "int16", "int32", "int64", "uint", | |
"uint8", "uint16", "uint32", "uint64", "bool"] | |
macro bitfield(values: varargs[stmt]): stmt = | |
## Creates a bitfield with the given fields | |
# Validate and initial parameter processing | |
if values.len %% 3 != 0: | |
error("Each field requires three values") | |
var fields = newSeq[tuple[typ, name: string, size: int]](values.len div 3) | |
var numSize = 0 | |
for i in 0..(values.len div 3 - 1): | |
let typ = values[i*3] | |
let name = values[i*3 + 1] | |
let size = values[i*3 + 2] | |
if typ.kind != nnkSym or not validBitfieldType.contains($typ): | |
error("Type `" & $typ & "` is either not a type or an invalid one") | |
if not (name.kind in {nnkStrLit, nnkRStrLit, nnkTripleStrLit}) or | |
(not validIdentifier(name.strVal) and name.strVal != ""): | |
error("Name `" & name.strVal & "` either not a literal string or an " & | |
"invalid identifier") | |
if not (size.kind in {nnkIntLit .. nnkUInt64Lit}): | |
error("The size of `" & name.strVal & "` is not an integer") | |
fields[i] = (typ: $typ, name: name.strVal, size: size.intVal.int) | |
numSize += size.intVal.int | |
if not (numSize in {8, 16, 32, 64}): | |
error($numSize & "can only be one of 8, 16, 32, or 64. " & | |
"Adding padding may help") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment