Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- proc parseVars(node: NimNode): (seq[string], NimNode) =
- ## Traverses the AST to find any identifiers
- ## and either replaces them with a constraint
- ## vararg access, or treats them as a Nim
- ## identifier if prefixed `u` or not alphanumeric.
- ##
- ## Return: The Variable names in AST First Occurence Order
- var queue = @[node] # TODO: Change to list, ensure FIFO
- var variables = newTable[string, int]()
- result[1] = queue[0]
- while queue.len > 0:
- let current = queue.pop
- for i, child in current.pairs:
- ## Find any Identifiers on the current Node
- if child.kind == nnkIdent:
- if child.strVal[0] == 'u':
- ## If tagged as a literal, keep it, but drop tag
- current[i] = ident(child.strVal.substr(1))
- elif child.strVal.isAlphaNumeric:
- ## Any untagged identifier is assumed a Variable
- ## Track its order in the AST
- if not variables.hasKeyOrPut(child.strVal, variables.len):
- result[0].add(child.strVal)
- ## Then replace the Identifier with an Array Access
- ## corresponding to its location in the constraint
- current[i] = newNimNode(nnkBracketExpr).add(
- ident("x"),
- newIntLitNode(variables[child.strVal])
- )
- else:
- queue.add(child)
- macro constrain*[T](problem: Problem[T], input: untyped): untyped =
- result = newStmtList()
- for child in input:
- let (vars, ast) = parseVars(child)
- result.add ast
- echo result.treeRepr ## No changes occurred
Advertisement
Add Comment
Please, Sign In to add comment