Advertisement
Guest User

Untitled

a guest
Aug 24th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.62 KB | None | 0 0
  1. import re, macros, os, strutils
  2.  
  3. macro multiMatch*(inp: string; sections: varargs[untyped]): untyped =
  4. ## "Multi regex match". Usage:
  5. ## multiMatch inp:
  6. ## of pattern1:
  7. ## x = matches[0]
  8. ## of pattern2:
  9. ## ...
  10. template branch(inp, p, action) =
  11. var mmlen = matchLen(inp, mmpatterns[p], matches, mmpos)
  12. if mmlen > 0:
  13. action
  14. inc(mmpos, mmlen)
  15. break searchSubs
  16.  
  17. template searchLoop(inp, actions) {.dirty} =
  18. var mmpos = 0
  19. while mmpos < inp.len:
  20. block searchSubs:
  21. actions
  22. inc(mmpos)
  23.  
  24. result = newTree(nnkStmtList)
  25. # first pass: extract regexes:
  26. var regexes: seq[string] = @[]
  27. for sec in sections:
  28. if sec.kind == nnkElse:
  29. discard
  30. else:
  31. expectKind sec, nnkOfBranch
  32. expectLen sec, 2
  33. if sec[0].kind in nnkStrLit..nnkTripleStrLit:
  34. regexes.add sec[0].strVal
  35. else:
  36. error("Expected a node of kind nnkStrLit, got " & $sec[0].kind)
  37. # now generate re-construction and cache regexes for efficiency:
  38. template declPatterns(size) =
  39. var mmpatterns{.inject.}: array[size, Regex]
  40. var matches{.inject.}: array[MaxSubpatterns, string]
  41.  
  42. template createPattern(i, p) {.dirty.} =
  43. bind re
  44. mmpatterns[i] = re(p)
  45.  
  46. result.add getAst(declPatterns(regexes.len))
  47. for i, r in regexes:
  48. result.add getAst(createPattern(i, r))
  49.  
  50. # last pass: generate code:
  51. let actions = newTree(nnkStmtList)
  52. var i = 0
  53. for sec in sections.children:
  54. if sec.kind == nnkElse:
  55. actions.add sec[0]
  56. else:
  57. actions.add getAst branch(inp, i, sec[1])
  58. inc i
  59. result.add getAst searchLoop(inp, actions)
  60.  
  61.  
  62. import sets
  63.  
  64. proc py2nim(inp: string): string =
  65. var locals = initSet[string]()
  66. var globals = initSet[string]()
  67. result = newStringOfCap(inp.len + 1000)
  68. result &= "import pylib\n"
  69. template sink(x) =
  70. result &= x
  71. multiMatch inp:
  72. of r"\b def \s+ (\w+) \(([a-zA-Z0-9_, \t]+)\):":
  73. sink "proc " & matches[0] & "(" & matches[1] & ": auto): auto ="
  74. # reset locals:
  75. locals = initSet[string]()
  76. globals = initSet[string]()
  77. of r"(\w+) \s* = \s+":
  78. if not globals.contains(matches[0]) and not locals.containsOrIncl(matches[0]):
  79. sink "var "
  80. sink matches[0] & " = "
  81. of r"\[\:\]":
  82. discard
  83. of r"'(.+)'":
  84. # Replace ' by "
  85. sink "\"" & matches[0].replace("\"", "\\\"") & "\""
  86. of r"\[(.+?):(.+?)\]":
  87. sink "[" & matches[0] & ".." & matches[0] & "+" & matches[1] & "]"
  88. #of r"\b print \b":
  89. # sink "echo"
  90. of r"\s*\b global \s+ (\w+);?":
  91. globals.incl matches[0]
  92. else:
  93. sink inp[mmpos]
  94.  
  95. if paramCount() != 0:
  96. echo py2nim readFile(paramStr(1))
  97. else:
  98. echo py2nim stdin.readAll()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement