Guest User

Constraint Macro

a guest
Dec 21st, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 1.75 KB | None | 0 0
  1. proc parseVars(node: NimNode): (seq[string], NimNode) =
  2.     ## Traverses the AST to find any identifiers
  3.     ## and either replaces them with a constraint
  4.     ## vararg access, or treats them as a Nim
  5.     ## identifier if prefixed `u` or not alphanumeric.
  6.     ##
  7.     ## Return: The Variable names in AST First Occurence Order
  8.     var queue = @[node] # TODO: Change to list, ensure FIFO
  9.     var variables = newTable[string, int]()
  10.     result[1] = queue[0]
  11.  
  12.     while queue.len > 0:
  13.         let current = queue.pop
  14.  
  15.         for i, child in current.pairs:
  16.             ## Find any Identifiers on the current Node
  17.             if child.kind == nnkIdent:
  18.                 if child.strVal[0] == 'u':
  19.                     ## If tagged as a literal, keep it, but drop tag
  20.                     current[i] = ident(child.strVal.substr(1))
  21.                 elif child.strVal.isAlphaNumeric:
  22.                     ## Any untagged identifier is assumed a Variable
  23.                     ## Track its order in the AST
  24.                     if not variables.hasKeyOrPut(child.strVal, variables.len):
  25.                         result[0].add(child.strVal)
  26.  
  27.                     ## Then replace the Identifier with an Array Access
  28.                     ## corresponding to its location in the constraint
  29.                     current[i] = newNimNode(nnkBracketExpr).add(
  30.                         ident("x"),
  31.                         newIntLitNode(variables[child.strVal])
  32.                     )
  33.             else:
  34.                 queue.add(child)
  35.  
  36.  
  37. macro constrain*[T](problem: Problem[T], input: untyped): untyped =
  38.     result = newStmtList()
  39.  
  40.     for child in input:
  41.         let (vars, ast) = parseVars(child)
  42.         result.add ast
  43.    
  44.     echo result.treeRepr ## No changes occurred
Advertisement
Add Comment
Please, Sign In to add comment