vmconv.nim 1.7 KB

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