experimental/sexp

    Dark Mode
Search:
  Source   Edit

Note: Import experimental/sexp to use this module

Symbolic Expressions, S-Expressions, s-expresssions, s-exp, sexp, whatever someone might call them are woefully underspecified. There aren't too many places too screw-up, but edge cases matter.

This modules allows for s-exp handling and is "flavoured" by remaining largely compatible with emacs' EPC specification. As such it's meant for serdes (serializing and deserializing) data and will likely fall short for forgiving/precise parsing that a high quality lisp like language interpreter may require.

Future Direction:

  • Keyword support (:someKeyWord) might be removed or reworked to not require
    a key/value pair approach
  • cons vs list separation and nil handling

Types

SexpNode = ref SexpNodeObj
s-exp node   Source   Edit
SexpNodeKind = enum
  SNil, SInt, SFloat, SString, SSymbol, SKeyword, SList, SCons
possible s-exp node types   Source   Edit
SexpNodeObj {.acyclic.} = object
  case kind*: SexpNodeKind
  of SString:
      str*: string

  of SSymbol:
      symbol*: string

  of SInt:
      num*: BiggestInt

  of SFloat:
      fnum*: float

  of SList:
      elems*: seq[SexpNode]

  of SKeyword:
      key*: string
      value*: SexpNode

  of SCons:
      car*: SexpNode
      cdr*: SexpNode

  of SNil:
      nil

  
  Source   Edit
SexpParsingError = object of ValueError
is raised for a s-exp error   Source   Edit

Procs

proc `$`(node: SexpNode): string {....raises: [], tags: [].}
Converts node to its s-expression representation on one line.   Source   Edit
proc `==`(a, b: SexpNode): bool {.noSideEffect, ...raises: [], tags: [].}
Check two nodes for equality   Source   Edit
proc `[]`(node: SexpNode; index: int): SexpNode {....raises: [], tags: [].}
Gets the node at index in a List. Result is undefined if index is out of bounds   Source   Edit
proc add(father, child: SexpNode) {....raises: [], tags: [].}
Adds child to a SList node father.   Source   Edit
proc addField(node: SexpNode; name: string; value: SexpNode) {....raises: [],
    tags: [].}
Add :name value keyword pair to the node   Source   Edit
proc copy(p: SexpNode): SexpNode {....raises: [], tags: [].}
Performs a deep copy of a.   Source   Edit
proc errorMsg(parser: SexpParser): string {....raises: [ValueError], tags: [].}
returns a helpful error message for the event sexpError   Source   Edit
proc errorMsgExpected(parser: SexpParser; e: string): string {.
    ...raises: [ValueError], tags: [].}
returns an error message "e expected" in the same format as the other error messages   Source   Edit
proc escapeJson(s: string): string {....raises: [], tags: [].}
Converts a string s to its JSON representation.   Source   Edit
proc getCons(n: SexpNode; defaults: Cons = (newSNil(), newSNil())): Cons {.
    ...raises: [], tags: [].}

Retrieves the cons value of a SList SexpNode.

Returns default if n is not a SList.

  Source   Edit
proc getElems(n: SexpNode; default: seq[SexpNode] = @[]): seq[SexpNode] {.
    ...raises: [], tags: [].}

Retrieves the int value of a SList SexpNode.

Returns default if n is not a SList.

  Source   Edit
proc getField(node: SexpNode; name: string; default: SexpNode = nil): SexpNode {.
    ...raises: [], tags: [].}
Iterate over direct subnodes of node, searching for the SKeyword with name set to name. If found return it's .value, otherwise return default   Source   Edit
proc getFNum(n: SexpNode; default: float = 0.0): float {....raises: [], tags: [].}

Retrieves the float value of a SFloat SexpNode.

Returns default if n is not a SFloat.

  Source   Edit
proc getKey(n: SexpNode; default: string = ""): string {....raises: [], tags: [].}

Get key value from the SKeyword node

Return default is n is not a SKeyword

  Source   Edit
proc getNum(n: SexpNode; default: BiggestInt = 0): BiggestInt {....raises: [],
    tags: [].}

Retrieves the int value of a SInt SexpNode.

Returns default if n is not a SInt.

  Source   Edit
proc getStr(n: SexpNode; default: string = ""): string {....raises: [], tags: [].}

Retrieves the string value of a SString SexpNode.

Returns default if n is not a SString.

  Source   Edit
proc getSymbol(n: SexpNode; default: string = ""): string {....raises: [], tags: [].}

Retrieves the int value of a SList SexpNode.

Returns default if n is not a SList.

  Source   Edit
proc hash(n: SexpNode): Hash {....raises: [], tags: [].}
Compute the hash for a SEXP node   Source   Edit
proc len(n: SexpNode): int {....raises: [], tags: [].}
If n is a SList, it returns the number of elements. If n is a JObject, it returns the number of pairs. Else it returns 0.   Source   Edit
proc newSCons(car, cdr: SexpNode): SexpNode {....raises: [], tags: [].}
Creates a new SCons SexpNode NB: this will not evaluate the arguments, eg: 'nil . nil' -> 'nil'   Source   Edit
proc newSFloat(n: float): SexpNode {....raises: [], tags: [].}
Creates a new SFloat SexpNode.   Source   Edit
proc newSInt(n: BiggestInt): SexpNode {....raises: [], tags: [].}
Creates a new SInt SexpNode.   Source   Edit
proc newSKeyword(key: string; value: SexpNode): SexpNode {....raises: [], tags: [].}
Create new SKeyword node with key and value specified   Source   Edit
proc newSList(items: varargs[SexpNode]): SexpNode {....raises: [], tags: [].}
Creates a new SList SexpNode   Source   Edit
proc newSNil(): SexpNode {....raises: [], tags: [].}
Creates a new SNil SexpNode.   Source   Edit
proc newSString(s: string): SexpNode {....raises: [], tags: [].}
Creates a new SString SexpNode.   Source   Edit
proc newSSymbol(s: string): SexpNode {....raises: [], tags: [].}
  Source   Edit
proc parseSexp(buffer: string): SexpNode {.
    ...raises: [IOError, OSError, ValueError, SexpParsingError, Exception],
    tags: [ReadIOEffect, WriteIOEffect].}
Parses an s-expression from buffer.   Source   Edit
proc parseSexp(s: Stream): SexpNode {....raises: [IOError, OSError, ValueError,
    SexpParsingError, Exception], tags: [ReadIOEffect, WriteIOEffect].}
Parses from a buffer s into a SexpNode.   Source   Edit
proc pretty(node: SexpNode; indent = 2): string {....raises: [], tags: [].}
Converts node to its S-Expression representation, with indentation and on multiple lines.   Source   Edit
proc raiseParseErr(p: SexpParser; msg: string) {.noinline, noreturn,
    ...raises: [SexpParsingError, ValueError], tags: [].}
raises an SexpParsingError exception.   Source   Edit
proc sexp(b: bool): SexpNode {....raises: [], tags: [].}

Generic constructor for SEXP data. Creates a new SSymbol SexpNode with value t or SNil SexpNode.

Future Direction: the t/nil behaviour may change unless required by EPC

  Source   Edit
proc sexp(elements: openArray[SexpNode]): SexpNode {....raises: [], tags: [].}
Generic constructor for SEXP data. Creates a new SList SexpNode   Source   Edit
proc sexp(keyword: (string, SexpNode)): SexpNode {....raises: [], tags: [].}
Generic constructor for SEXP data. Creates a new SKeyword SexpNode.   Source   Edit
proc sexp(n: BiggestInt): SexpNode {....raises: [], tags: [].}
Generic constructor for SEXP data. Creates a new SInt SexpNode.   Source   Edit
proc sexp(n: float): SexpNode {....raises: [], tags: [].}
Generic constructor for SEXP data. Creates a new SFloat SexpNode.   Source   Edit
proc sexp(s: SexpNode): SexpNode {....raises: [], tags: [].}
  Source   Edit
proc sexp(s: string): SexpNode {....raises: [], tags: [].}
Generic constructor for SEXP data. Creates a new SString SexpNode.   Source   Edit
proc treeRepr(node: SexpNode): string {....raises: [], tags: [].}
Generate uncolored tree repr string for the S-Expression AST.   Source   Edit

Iterators

iterator items(node: SexpNode): SexpNode {....raises: [], tags: [].}
Iterator for the items of node. node has to be a SList.   Source   Edit
iterator mitems(node: var SexpNode): var SexpNode {....raises: [], tags: [].}
Iterator for the items of node. node has to be a SList. Items can be modified.   Source   Edit
iterator mpairs(node: var SexpNode): (int, var SexpNode) {....raises: [], tags: [].}
Iterator for the pairs of node. node has to be a SList. Items can be modified.   Source   Edit
iterator pairs(node: SexpNode): (int, SexpNode) {....raises: [], tags: [].}
Iterator for the pairs of node. node has to be a SList.   Source   Edit

Macros

macro convertSexp(x: untyped): untyped
Convert an expression to a SexpNode directly, without having to specify % for every element.   Source   Edit