Skip to content

Commit

Permalink
Merge #164
Browse files Browse the repository at this point in the history
164: sexp: Add missing API: items/pairs/treeRepr/getKey r=saem a=haxscramper

- expose `.car` and `.cdr` fields for direct access - everything else can
  already be accesssed, but those were wrapped in weird `getCons()` proc
  that retunred both elements.
- `treeRepr` for S-expression printing
- `getKey` for S-expression keyword pair
- missing `pairs()` and `mpairs()`


Co-authored-by: haxscramper <[email protected]>
  • Loading branch information
bors[bot] and haxscramper authored Jan 17, 2022
2 parents fff9e80 + 371bed4 commit 66a2735
Showing 1 changed file with 69 additions and 2 deletions.
71 changes: 69 additions & 2 deletions nimsuggest/sexp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ type
key*: string
value*: SexpNode
of SCons:
car: SexpNode
cdr: SexpNode
car*: SexpNode
cdr*: SexpNode
of SNil:
discard

Expand Down Expand Up @@ -366,6 +366,12 @@ proc getSymbol*(n: SexpNode, default: string = ""): string =
if n.kind != SSymbol: return default
else: return n.symbol

proc getKey*(n: SexpNode, default: string = ""): string =
## Get key value from the `SKeyword` node
##
## Return `default` is `n` is not a `SKeyword`
if n.kind != SKeyword: default else: n.key

proc getElems*(n: SexpNode, default: seq[SexpNode] = @[]): seq[SexpNode] =
## Retrieves the int value of a `SList SexpNode`.
##
Expand Down Expand Up @@ -620,13 +626,74 @@ iterator items*(node: SexpNode): SexpNode =
for i in items(node.elems):
yield i


iterator pairs*(node: SexpNode): (int, SexpNode) =
## Iterator for the pairs of `node`. `node` has to be a SList.
assert node.kind == SList
for i in pairs(node.elems):
yield i

iterator mitems*(node: var SexpNode): var SexpNode =
## Iterator for the items of `node`. `node` has to be a SList. Items can be
## modified.
assert node.kind == SList
for i in mitems(node.elems):
yield i

iterator mpairs*(node: var SexpNode): (int, var SexpNode) =
## Iterator for the pairs of `node`. `node` has to be a SList. Items can be
## modified.
assert node.kind == SList
for i, node in mpairs(node.elems):
yield (i, node)

proc treeRepr*(node: SexpNode): string =
## Generate uncolored tree repr string for the S-expression AST.
proc aux(node: SexpNode, level: int, res: var string) =
res.add repeat(" ", level)
res.add $node.kind
case node.kind:
of SInt:
res.add " "
res.add $node.getNum()

of SFloat:
res.add " "
res.add $node.getFNum()

of SString:
res.add " \""
res.add node.getStr()
res.add "\""

of SList:
for item in node:
res.add "\n"
aux(item, level + 1, res)

of SKeyword:
res.add " :"
res.add node.key
res.add "\n"
aux(node.value, level + 1, res)

of SNil:
res.add " null"

of SSymbol:
res.add " " & node.symbol

of SCons:
res.add "\n" & repeat(" ", level + 1) & "car"
aux(node.car, level + 2, res)
res.add "\n" & repeat(" ", level + 1) & "cdr"
aux(node.cdr, level + 2, res)


aux(node, 0, result)



proc eat(p: var SexpParser, tok: TTokKind) =
if p.tok == tok: discard getTok(p)
else: raiseParseErr(p, tokToStr[tok])
Expand Down

0 comments on commit 66a2735

Please sign in to comment.