vmconv.nim 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import ast, idents, lineinfos, astalgo
  2. import vmdef
  3. import std/times
  4. template elementType*(T: typedesc): typedesc =
  5. typeof(block:
  6. var a: T
  7. for ai in a: ai)
  8. proc fromLit*(a: PNode, T: typedesc): auto =
  9. ## generic PNode => type
  10. ## see also reverse operation `toLit`
  11. when T is set:
  12. result = default(T)
  13. type Ti = elementType(T)
  14. for ai in a:
  15. result.incl Ti(ai.intVal)
  16. else:
  17. static: raiseAssert "not yet supported: " & $T # add as needed
  18. proc toLit*[T](a: T): PNode =
  19. ## generic type => PNode
  20. ## see also reverse operation `fromLit`
  21. when T is string: newStrNode(nkStrLit, a)
  22. elif T is Ordinal: newIntNode(nkIntLit, a.ord)
  23. elif T is (proc): newNode(nkNilLit)
  24. elif T is ref:
  25. if a == nil: newNode(nkNilLit)
  26. else: toLit(a[])
  27. elif T is tuple:
  28. result = newTree(nkTupleConstr)
  29. for ai in fields(a): result.add toLit(ai)
  30. elif T is seq:
  31. result = newNode(nkBracket)
  32. for ai in a:
  33. result.add toLit(ai)
  34. elif T is object:
  35. result = newTree(nkObjConstr)
  36. result.add(newNode(nkEmpty))
  37. for k, ai in fieldPairs(a):
  38. let reti = newNode(nkExprColonExpr)
  39. reti.add k.toLit
  40. reti.add ai.toLit
  41. result.add reti
  42. else:
  43. static: raiseAssert "not yet supported: " & $T # add as needed
  44. proc toTimeLit*(a: Time, c: PCtx, obj: PNode, info: TLineInfo): PNode =
  45. # probably refactor it into `toLit` in the future
  46. result = newTree(nkObjConstr)
  47. result.add(newNode(nkEmpty)) # can be changed to a symbol according to PType
  48. for k, ai in fieldPairs(a):
  49. let reti = newNode(nkExprColonExpr)
  50. reti.add newSymNode(lookupInRecord(obj, getIdent(c.cache, k)), info)
  51. reti.add ai.toLit
  52. result.add reti