2016-06-25 3 views
1

Предположим, что я типа определяется следующим образом:Nim отражают на типах полей типа в во время компиляции

type TMyStruct = object 
    foo: int32 
    bar: int16 

Моя цель состоит в том, чтобы построить макрос (или иначе), которые, учитывая «простой» тип объекта, как выше, способна вычислять сумму размеров каждого поля в типе на основе sizeof. В этом случае int32 имеет размер 4 и int16 имеет размер 2, так что идея заключается в том, что

myMacro(TMyStruct) # or, in the worst case, myMacro(x) where x is a TMyStruct 

следует оценивать до 6 в качестве постоянного выражения. Я хочу расширить его на вложенные объекты позже, но это должно быть легко через рекурсию, как только базовая версия работает.

Я пробовал много вещей и провалился ужасно; самое большее, что мне удалось получить, - это получить имена полей «foo» и «bar» в AST как nnkSymNodes, но мне не удалось получить какую-либо информацию об их типах. Значимая документация (на моем уровне экспертизы Nim) является редкой для несуществующей.

Является ли то, что я прошу, и какую функциональность Nim мне нужно использовать для его достижения?

Благодаря

ответ

1
import macros 

type TMyStruct = object 
    foo: int32 
    bar: int16 

macro sumSizes(t: typedesc): expr = 
    result = nil 
    let tDesc = getType(getType(t)[1]) 
    for field in tDesc[2].children: 
    let sizeOfThis = newCall("sizeof", field) 
    if isNil(result): 
     result = sizeOfThis 
    else: 
     result = infix(result, "+", sizeOfThis) 

echo sumSizes(TMyStruct) 

Это немного странно, что вы должны приковать getType вызовы в начале. Это происходит потому, что getType(t) возвращает следующее:

BracketExpr 
    Sym "typeDesc" 
    Sym "TMyStruct" 

Если вы хотите сделать это с экземплярами типа, просто изменить эти строки:

macro sumSizes(e: typed): expr = 
    result = nil 
    let tDesc = getType(e) 

Обратите внимание, что typed важно здесь иметь напечатанный символ внутри макроса.

+0

Очень приятно! Благодарю. Я думаю, что нужно просто ознакомиться с деталями АСТ, чтобы хорошо писать макросы :) – Thomas

Смежные вопросы