Skip to content

Commit

Permalink
sexp: Add missing API: items/pairs/treeRepr/getKey
Browse files Browse the repository at this point in the history
- 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()`
  • Loading branch information
haxscramper committed Jan 17, 2022
1 parent fff9e80 commit 7976136
Showing 1 changed file with 68 additions and 2 deletions.
70 changes: 68 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,73 @@ 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 =
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 7976136

Please sign in to comment.