Rename PNimrodNode to NimNode
This commit is contained in:
parent
8e651fa0d4
commit
fd4e629905
30 changed files with 508 additions and 518 deletions
|
|
@ -85,11 +85,11 @@ type
|
||||||
ntyInt8, ntyInt16, ntyInt32, ntyInt64,
|
ntyInt8, ntyInt16, ntyInt32, ntyInt64,
|
||||||
ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128,
|
ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128,
|
||||||
ntyUInt, ntyUInt8, ntyUInt16, ntyUInt32, ntyUInt64,
|
ntyUInt, ntyUInt8, ntyUInt16, ntyUInt32, ntyUInt64,
|
||||||
ntyBigNum,
|
ntyBigNum,
|
||||||
ntyConst, ntyMutable, ntyVarargs,
|
ntyConst, ntyMutable, ntyVarargs,
|
||||||
ntyIter,
|
ntyIter,
|
||||||
ntyError
|
ntyError
|
||||||
|
|
||||||
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
||||||
NimSymKind* = enum
|
NimSymKind* = enum
|
||||||
nskUnknown, nskConditional, nskDynLib, nskParam,
|
nskUnknown, nskConditional, nskDynLib, nskParam,
|
||||||
|
|
@ -120,12 +120,10 @@ const
|
||||||
nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
||||||
nnkCallStrLit}
|
nnkCallStrLit}
|
||||||
|
|
||||||
{.push warning[deprecated]: off.}
|
proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.}
|
||||||
|
|
||||||
proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild", noSideEffect.}
|
|
||||||
## get `n`'s `i`'th child.
|
## get `n`'s `i`'th child.
|
||||||
|
|
||||||
proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild",
|
proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild",
|
||||||
noSideEffect.}
|
noSideEffect.}
|
||||||
## set `n`'s `i`'th child to `child`.
|
## set `n`'s `i`'th child to `child`.
|
||||||
|
|
||||||
|
|
@ -141,34 +139,34 @@ proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
|
||||||
proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
|
proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
|
||||||
## compares two Nim identifiers
|
## compares two Nim identifiers
|
||||||
|
|
||||||
proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
|
proc `==`*(a, b: NimNode): bool {.magic: "EqNimrodNode", noSideEffect.}
|
||||||
## compares two Nim nodes
|
## compares two Nim nodes
|
||||||
|
|
||||||
proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.}
|
proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.}
|
||||||
## returns the number of children of `n`.
|
## returns the number of children of `n`.
|
||||||
|
|
||||||
proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable,
|
proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable,
|
||||||
noSideEffect, locks: 0.}
|
noSideEffect, locks: 0.}
|
||||||
## Adds the `child` to the `father` node. Returns the
|
## Adds the `child` to the `father` node. Returns the
|
||||||
## father node so that calls can be nested.
|
## father node so that calls can be nested.
|
||||||
|
|
||||||
proc add*(father: PNimrodNode, children: varargs[PNimrodNode]): PNimrodNode {.
|
proc add*(father: NimNode, children: varargs[NimNode]): NimNode {.
|
||||||
magic: "NAddMultiple", discardable, noSideEffect, locks: 0.}
|
magic: "NAddMultiple", discardable, noSideEffect, locks: 0.}
|
||||||
## Adds each child of `children` to the `father` node.
|
## Adds each child of `children` to the `father` node.
|
||||||
## Returns the `father` node so that calls can be nested.
|
## Returns the `father` node so that calls can be nested.
|
||||||
|
|
||||||
proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel", noSideEffect.}
|
proc del*(father: NimNode, idx = 0, n = 1) {.magic: "NDel", noSideEffect.}
|
||||||
## deletes `n` children of `father` starting at index `idx`.
|
## deletes `n` children of `father` starting at index `idx`.
|
||||||
|
|
||||||
proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind", noSideEffect.}
|
proc kind*(n: NimNode): NimNodeKind {.magic: "NKind", noSideEffect.}
|
||||||
## returns the `kind` of the node `n`.
|
## returns the `kind` of the node `n`.
|
||||||
|
|
||||||
proc intVal*(n: PNimrodNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
|
proc intVal*(n: NimNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
|
||||||
proc floatVal*(n: PNimrodNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
|
proc floatVal*(n: NimNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
|
||||||
proc symbol*(n: PNimrodNode): NimSym {.magic: "NSymbol", noSideEffect.}
|
proc symbol*(n: NimNode): NimSym {.magic: "NSymbol", noSideEffect.}
|
||||||
proc ident*(n: PNimrodNode): NimIdent {.magic: "NIdent", noSideEffect.}
|
proc ident*(n: NimNode): NimIdent {.magic: "NIdent", noSideEffect.}
|
||||||
|
|
||||||
proc getType*(n: PNimrodNode): PNimrodNode {.magic: "NGetType", noSideEffect.}
|
proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||||
## with 'getType' you can access the node's `type`:idx:. A Nim type is
|
## with 'getType' you can access the node's `type`:idx:. A Nim type is
|
||||||
## mapped to a Nim AST too, so it's slightly confusing but it means the same
|
## mapped to a Nim AST too, so it's slightly confusing but it means the same
|
||||||
## API can be used to traverse types. Recursive types are flattened for you
|
## API can be used to traverse types. Recursive types are flattened for you
|
||||||
|
|
@ -176,30 +174,30 @@ proc getType*(n: PNimrodNode): PNimrodNode {.magic: "NGetType", noSideEffect.}
|
||||||
## resolve recursive types, you have to call 'getType' again. To see what
|
## resolve recursive types, you have to call 'getType' again. To see what
|
||||||
## kind of type it is, call `typeKind` on getType's result.
|
## kind of type it is, call `typeKind` on getType's result.
|
||||||
|
|
||||||
proc typeKind*(n: PNimrodNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
|
proc typeKind*(n: NimNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
|
||||||
## Returns the type kind of the node 'n' that should represent a type, that
|
## Returns the type kind of the node 'n' that should represent a type, that
|
||||||
## means the node should have been obtained via `getType`.
|
## means the node should have been obtained via `getType`.
|
||||||
|
|
||||||
proc strVal*(n: PNimrodNode): string {.magic: "NStrVal", noSideEffect.}
|
proc strVal*(n: NimNode): string {.magic: "NStrVal", noSideEffect.}
|
||||||
|
|
||||||
proc `intVal=`*(n: PNimrodNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}
|
proc `intVal=`*(n: NimNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}
|
||||||
proc `floatVal=`*(n: PNimrodNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.}
|
proc `floatVal=`*(n: NimNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.}
|
||||||
proc `symbol=`*(n: PNimrodNode, val: NimSym) {.magic: "NSetSymbol", noSideEffect.}
|
proc `symbol=`*(n: NimNode, val: NimSym) {.magic: "NSetSymbol", noSideEffect.}
|
||||||
proc `ident=`*(n: PNimrodNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.}
|
proc `ident=`*(n: NimNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.}
|
||||||
#proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
|
#proc `typ=`*(n: NimNode, typ: typedesc) {.magic: "NSetType".}
|
||||||
# this is not sound! Unfortunately forbidding 'typ=' is not enough, as you
|
# this is not sound! Unfortunately forbidding 'typ=' is not enough, as you
|
||||||
# can easily do:
|
# can easily do:
|
||||||
# let bracket = semCheck([1, 2])
|
# let bracket = semCheck([1, 2])
|
||||||
# let fake = semCheck(2.0)
|
# let fake = semCheck(2.0)
|
||||||
# bracket[0] = fake # constructs a mixed array with ints and floats!
|
# bracket[0] = fake # constructs a mixed array with ints and floats!
|
||||||
|
|
||||||
proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal", noSideEffect.}
|
proc `strVal=`*(n: NimNode, val: string) {.magic: "NSetStrVal", noSideEffect.}
|
||||||
|
|
||||||
proc newNimNode*(kind: TNimrodNodeKind,
|
proc newNimNode*(kind: NimNodeKind,
|
||||||
n: PNimrodNode=nil): PNimrodNode {.magic: "NNewNimNode", noSideEffect.}
|
n: NimNode=nil): NimNode {.magic: "NNewNimNode", noSideEffect.}
|
||||||
|
|
||||||
proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode", noSideEffect.}
|
proc copyNimNode*(n: NimNode): NimNode {.magic: "NCopyNimNode", noSideEffect.}
|
||||||
proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree", noSideEffect.}
|
proc copyNimTree*(n: NimNode): NimNode {.magic: "NCopyNimTree", noSideEffect.}
|
||||||
|
|
||||||
proc error*(msg: string) {.magic: "NError", benign.}
|
proc error*(msg: string) {.magic: "NError", benign.}
|
||||||
## writes an error message at compile time
|
## writes an error message at compile time
|
||||||
|
|
@ -210,27 +208,27 @@ proc warning*(msg: string) {.magic: "NWarning", benign.}
|
||||||
proc hint*(msg: string) {.magic: "NHint", benign.}
|
proc hint*(msg: string) {.magic: "NHint", benign.}
|
||||||
## writes a hint message at compile time
|
## writes a hint message at compile time
|
||||||
|
|
||||||
proc newStrLitNode*(s: string): PNimrodNode {.compileTime, noSideEffect.} =
|
proc newStrLitNode*(s: string): NimNode {.compileTime, noSideEffect.} =
|
||||||
## creates a string literal node from `s`
|
## creates a string literal node from `s`
|
||||||
result = newNimNode(nnkStrLit)
|
result = newNimNode(nnkStrLit)
|
||||||
result.strVal = s
|
result.strVal = s
|
||||||
|
|
||||||
proc newIntLitNode*(i: BiggestInt): PNimrodNode {.compileTime.} =
|
proc newIntLitNode*(i: BiggestInt): NimNode {.compileTime.} =
|
||||||
## creates a int literal node from `i`
|
## creates a int literal node from `i`
|
||||||
result = newNimNode(nnkIntLit)
|
result = newNimNode(nnkIntLit)
|
||||||
result.intVal = i
|
result.intVal = i
|
||||||
|
|
||||||
proc newFloatLitNode*(f: BiggestFloat): PNimrodNode {.compileTime.} =
|
proc newFloatLitNode*(f: BiggestFloat): NimNode {.compileTime.} =
|
||||||
## creates a float literal node from `f`
|
## creates a float literal node from `f`
|
||||||
result = newNimNode(nnkFloatLit)
|
result = newNimNode(nnkFloatLit)
|
||||||
result.floatVal = f
|
result.floatVal = f
|
||||||
|
|
||||||
proc newIdentNode*(i: NimIdent): PNimrodNode {.compileTime.} =
|
proc newIdentNode*(i: NimIdent): NimNode {.compileTime.} =
|
||||||
## creates an identifier node from `i`
|
## creates an identifier node from `i`
|
||||||
result = newNimNode(nnkIdent)
|
result = newNimNode(nnkIdent)
|
||||||
result.ident = i
|
result.ident = i
|
||||||
|
|
||||||
proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
|
proc newIdentNode*(i: string): NimNode {.compileTime.} =
|
||||||
## creates an identifier node from `i`
|
## creates an identifier node from `i`
|
||||||
result = newNimNode(nnkIdent)
|
result = newNimNode(nnkIdent)
|
||||||
result.ident = !i
|
result.ident = !i
|
||||||
|
|
@ -247,7 +245,7 @@ type
|
||||||
|
|
||||||
{.deprecated: [TBindSymRule: BindSymRule].}
|
{.deprecated: [TBindSymRule: BindSymRule].}
|
||||||
|
|
||||||
proc bindSym*(ident: string, rule: BindSymRule = brClosed): PNimrodNode {.
|
proc bindSym*(ident: string, rule: BindSymRule = brClosed): NimNode {.
|
||||||
magic: "NBindSym", noSideEffect.}
|
magic: "NBindSym", noSideEffect.}
|
||||||
## creates a node that binds `ident` to a symbol node. The bound symbol
|
## creates a node that binds `ident` to a symbol node. The bound symbol
|
||||||
## may be an overloaded symbol.
|
## may be an overloaded symbol.
|
||||||
|
|
@ -258,48 +256,48 @@ proc bindSym*(ident: string, rule: BindSymRule = brClosed): PNimrodNode {.
|
||||||
## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
|
## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
|
||||||
## returned even if the symbol is not ambiguous.
|
## returned even if the symbol is not ambiguous.
|
||||||
|
|
||||||
proc genSym*(kind: NimSymKind = nskLet; ident = ""): PNimrodNode {.
|
proc genSym*(kind: NimSymKind = nskLet; ident = ""): NimNode {.
|
||||||
magic: "NGenSym", noSideEffect.}
|
magic: "NGenSym", noSideEffect.}
|
||||||
## generates a fresh symbol that is guaranteed to be unique. The symbol
|
## generates a fresh symbol that is guaranteed to be unique. The symbol
|
||||||
## needs to occur in a declaration context.
|
## needs to occur in a declaration context.
|
||||||
|
|
||||||
proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.}
|
proc callsite*(): NimNode {.magic: "NCallSite", benign.}
|
||||||
## returns the AST of the invocation expression that invoked this macro.
|
## returns the AST of the invocation expression that invoked this macro.
|
||||||
|
|
||||||
proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc toStrLit*(n: NimNode): NimNode {.compileTime.} =
|
||||||
## converts the AST `n` to the concrete Nim code and wraps that
|
## converts the AST `n` to the concrete Nim code and wraps that
|
||||||
## in a string literal node
|
## in a string literal node
|
||||||
return newStrLitNode(repr(n))
|
return newStrLitNode(repr(n))
|
||||||
|
|
||||||
proc lineinfo*(n: PNimrodNode): string {.magic: "NLineInfo", noSideEffect.}
|
proc lineinfo*(n: NimNode): string {.magic: "NLineInfo", noSideEffect.}
|
||||||
## returns the position the node appears in the original source file
|
## returns the position the node appears in the original source file
|
||||||
## in the form filename(line, col)
|
## in the form filename(line, col)
|
||||||
|
|
||||||
proc internalParseExpr(s: string): PNimrodNode {.
|
proc internalParseExpr(s: string): NimNode {.
|
||||||
magic: "ParseExprToAst", noSideEffect.}
|
magic: "ParseExprToAst", noSideEffect.}
|
||||||
|
|
||||||
proc internalParseStmt(s: string): PNimrodNode {.
|
proc internalParseStmt(s: string): NimNode {.
|
||||||
magic: "ParseStmtToAst", noSideEffect.}
|
magic: "ParseStmtToAst", noSideEffect.}
|
||||||
|
|
||||||
proc internalErrorFlag*(): string {.magic: "NError", noSideEffect.}
|
proc internalErrorFlag*(): string {.magic: "NError", noSideEffect.}
|
||||||
## Some builtins set an error flag. This is then turned into a proper
|
## Some builtins set an error flag. This is then turned into a proper
|
||||||
## exception. **Note**: Ordinary application code should not call this.
|
## exception. **Note**: Ordinary application code should not call this.
|
||||||
|
|
||||||
proc parseExpr*(s: string): PNimrodNode {.noSideEffect, compileTime.} =
|
proc parseExpr*(s: string): NimNode {.noSideEffect, compileTime.} =
|
||||||
## Compiles the passed string to its AST representation.
|
## Compiles the passed string to its AST representation.
|
||||||
## Expects a single expression. Raises ``ValueError`` for parsing errors.
|
## Expects a single expression. Raises ``ValueError`` for parsing errors.
|
||||||
result = internalParseExpr(s)
|
result = internalParseExpr(s)
|
||||||
let x = internalErrorFlag()
|
let x = internalErrorFlag()
|
||||||
if x.len > 0: raise newException(ValueError, x)
|
if x.len > 0: raise newException(ValueError, x)
|
||||||
|
|
||||||
proc parseStmt*(s: string): PNimrodNode {.noSideEffect, compileTime.} =
|
proc parseStmt*(s: string): NimNode {.noSideEffect, compileTime.} =
|
||||||
## Compiles the passed string to its AST representation.
|
## Compiles the passed string to its AST representation.
|
||||||
## Expects one or more statements. Raises ``ValueError`` for parsing errors.
|
## Expects one or more statements. Raises ``ValueError`` for parsing errors.
|
||||||
result = internalParseStmt(s)
|
result = internalParseStmt(s)
|
||||||
let x = internalErrorFlag()
|
let x = internalErrorFlag()
|
||||||
if x.len > 0: raise newException(ValueError, x)
|
if x.len > 0: raise newException(ValueError, x)
|
||||||
|
|
||||||
proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideEffect.}
|
proc getAst*(macroOrTemplate: expr): NimNode {.magic: "ExpandToAst", noSideEffect.}
|
||||||
## Obtains the AST nodes returned from a macro or template invocation.
|
## Obtains the AST nodes returned from a macro or template invocation.
|
||||||
## Example:
|
## Example:
|
||||||
##
|
##
|
||||||
|
|
@ -308,10 +306,10 @@ proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideE
|
||||||
## macro FooMacro() =
|
## macro FooMacro() =
|
||||||
## var ast = getAst(BarTemplate())
|
## var ast = getAst(BarTemplate())
|
||||||
|
|
||||||
proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst", noSideEffect.}
|
proc quote*(bl: stmt, op = "``"): NimNode {.magic: "QuoteAst", noSideEffect.}
|
||||||
## Quasi-quoting operator.
|
## Quasi-quoting operator.
|
||||||
## Accepts an expression or a block and returns the AST that represents it.
|
## Accepts an expression or a block and returns the AST that represents it.
|
||||||
## Within the quoted AST, you are able to interpolate PNimrodNode expressions
|
## Within the quoted AST, you are able to interpolate NimNode expressions
|
||||||
## from the surrounding scope. If no operator is given, quoting is done using
|
## from the surrounding scope. If no operator is given, quoting is done using
|
||||||
## backticks. Otherwise, the given operator must be used as a prefix operator
|
## backticks. Otherwise, the given operator must be used as a prefix operator
|
||||||
## for any interpolated expression. The original meaning of the interpolation
|
## for any interpolated expression. The original meaning of the interpolation
|
||||||
|
|
@ -339,26 +337,26 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst", noSideEffect.
|
||||||
## if not `ex`:
|
## if not `ex`:
|
||||||
## echo `info` & ": Check failed: " & `expString`
|
## echo `info` & ": Check failed: " & `expString`
|
||||||
|
|
||||||
proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
|
proc expectKind*(n: NimNode, k: NimNodeKind) {.compileTime.} =
|
||||||
## checks that `n` is of kind `k`. If this is not the case,
|
## checks that `n` is of kind `k`. If this is not the case,
|
||||||
## compilation aborts with an error message. This is useful for writing
|
## compilation aborts with an error message. This is useful for writing
|
||||||
## macros that check the AST that is passed to them.
|
## macros that check the AST that is passed to them.
|
||||||
if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind)
|
if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind)
|
||||||
|
|
||||||
proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
|
proc expectMinLen*(n: NimNode, min: int) {.compileTime.} =
|
||||||
## checks that `n` has at least `min` children. If this is not the case,
|
## checks that `n` has at least `min` children. If this is not the case,
|
||||||
## compilation aborts with an error message. This is useful for writing
|
## compilation aborts with an error message. This is useful for writing
|
||||||
## macros that check its number of arguments.
|
## macros that check its number of arguments.
|
||||||
if n.len < min: error("macro expects a node with " & $min & " children")
|
if n.len < min: error("macro expects a node with " & $min & " children")
|
||||||
|
|
||||||
proc expectLen*(n: PNimrodNode, len: int) {.compileTime.} =
|
proc expectLen*(n: NimNode, len: int) {.compileTime.} =
|
||||||
## checks that `n` has exactly `len` children. If this is not the case,
|
## checks that `n` has exactly `len` children. If this is not the case,
|
||||||
## compilation aborts with an error message. This is useful for writing
|
## compilation aborts with an error message. This is useful for writing
|
||||||
## macros that check its number of arguments.
|
## macros that check its number of arguments.
|
||||||
if n.len != len: error("macro expects a node with " & $len & " children")
|
if n.len != len: error("macro expects a node with " & $len & " children")
|
||||||
|
|
||||||
proc newCall*(theProc: PNimrodNode,
|
proc newCall*(theProc: NimNode,
|
||||||
args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
|
args: varargs[NimNode]): NimNode {.compileTime.} =
|
||||||
## produces a new call node. `theProc` is the proc that is called with
|
## produces a new call node. `theProc` is the proc that is called with
|
||||||
## the arguments ``args[0..]``.
|
## the arguments ``args[0..]``.
|
||||||
result = newNimNode(nnkCall)
|
result = newNimNode(nnkCall)
|
||||||
|
|
@ -366,7 +364,7 @@ proc newCall*(theProc: PNimrodNode,
|
||||||
result.add(args)
|
result.add(args)
|
||||||
|
|
||||||
proc newCall*(theProc: NimIdent,
|
proc newCall*(theProc: NimIdent,
|
||||||
args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
|
args: varargs[NimNode]): NimNode {.compileTime.} =
|
||||||
## produces a new call node. `theProc` is the proc that is called with
|
## produces a new call node. `theProc` is the proc that is called with
|
||||||
## the arguments ``args[0..]``.
|
## the arguments ``args[0..]``.
|
||||||
result = newNimNode(nnkCall)
|
result = newNimNode(nnkCall)
|
||||||
|
|
@ -374,35 +372,35 @@ proc newCall*(theProc: NimIdent,
|
||||||
result.add(args)
|
result.add(args)
|
||||||
|
|
||||||
proc newCall*(theProc: string,
|
proc newCall*(theProc: string,
|
||||||
args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
|
args: varargs[NimNode]): NimNode {.compileTime.} =
|
||||||
## produces a new call node. `theProc` is the proc that is called with
|
## produces a new call node. `theProc` is the proc that is called with
|
||||||
## the arguments ``args[0..]``.
|
## the arguments ``args[0..]``.
|
||||||
result = newNimNode(nnkCall)
|
result = newNimNode(nnkCall)
|
||||||
result.add(newIdentNode(theProc))
|
result.add(newIdentNode(theProc))
|
||||||
result.add(args)
|
result.add(args)
|
||||||
|
|
||||||
proc newLit*(c: char): PNimrodNode {.compileTime.} =
|
proc newLit*(c: char): NimNode {.compileTime.} =
|
||||||
## produces a new character literal node.
|
## produces a new character literal node.
|
||||||
result = newNimNode(nnkCharLit)
|
result = newNimNode(nnkCharLit)
|
||||||
result.intVal = ord(c)
|
result.intVal = ord(c)
|
||||||
|
|
||||||
proc newLit*(i: BiggestInt): PNimrodNode {.compileTime.} =
|
proc newLit*(i: BiggestInt): NimNode {.compileTime.} =
|
||||||
## produces a new integer literal node.
|
## produces a new integer literal node.
|
||||||
result = newNimNode(nnkIntLit)
|
result = newNimNode(nnkIntLit)
|
||||||
result.intVal = i
|
result.intVal = i
|
||||||
|
|
||||||
proc newLit*(f: BiggestFloat): PNimrodNode {.compileTime.} =
|
proc newLit*(f: BiggestFloat): NimNode {.compileTime.} =
|
||||||
## produces a new float literal node.
|
## produces a new float literal node.
|
||||||
result = newNimNode(nnkFloatLit)
|
result = newNimNode(nnkFloatLit)
|
||||||
result.floatVal = f
|
result.floatVal = f
|
||||||
|
|
||||||
proc newLit*(s: string): PNimrodNode {.compileTime.} =
|
proc newLit*(s: string): NimNode {.compileTime.} =
|
||||||
## produces a new string literal node.
|
## produces a new string literal node.
|
||||||
result = newNimNode(nnkStrLit)
|
result = newNimNode(nnkStrLit)
|
||||||
result.strVal = s
|
result.strVal = s
|
||||||
|
|
||||||
proc nestList*(theProc: NimIdent,
|
proc nestList*(theProc: NimIdent,
|
||||||
x: PNimrodNode): PNimrodNode {.compileTime.} =
|
x: NimNode): NimNode {.compileTime.} =
|
||||||
## nests the list `x` into a tree of call expressions:
|
## nests the list `x` into a tree of call expressions:
|
||||||
## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))``.
|
## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))``.
|
||||||
var L = x.len
|
var L = x.len
|
||||||
|
|
@ -413,11 +411,11 @@ proc nestList*(theProc: NimIdent,
|
||||||
# This could easily user code and so should be fixed in evals.nim somehow.
|
# This could easily user code and so should be fixed in evals.nim somehow.
|
||||||
result = newCall(theProc, x[i], copyNimTree(result))
|
result = newCall(theProc, x[i], copyNimTree(result))
|
||||||
|
|
||||||
proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} =
|
proc treeRepr*(n: NimNode): string {.compileTime, benign.} =
|
||||||
## Convert the AST `n` to a human-readable tree-like string.
|
## Convert the AST `n` to a human-readable tree-like string.
|
||||||
##
|
##
|
||||||
## See also `repr` and `lispRepr`.
|
## See also `repr` and `lispRepr`.
|
||||||
proc traverse(res: var string, level: int, n: PNimrodNode) {.benign.} =
|
proc traverse(res: var string, level: int, n: NimNode) {.benign.} =
|
||||||
for i in 0..level-1: res.add " "
|
for i in 0..level-1: res.add " "
|
||||||
res.add(($n.kind).substr(3))
|
res.add(($n.kind).substr(3))
|
||||||
|
|
||||||
|
|
@ -438,7 +436,7 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} =
|
||||||
result = ""
|
result = ""
|
||||||
traverse(result, 0, n)
|
traverse(result, 0, n)
|
||||||
|
|
||||||
proc lispRepr*(n: PNimrodNode): string {.compileTime, benign.} =
|
proc lispRepr*(n: NimNode): string {.compileTime, benign.} =
|
||||||
## Convert the AST `n` to a human-readable lisp-like string,
|
## Convert the AST `n` to a human-readable lisp-like string,
|
||||||
##
|
##
|
||||||
## See also `repr` and `treeRepr`.
|
## See also `repr` and `treeRepr`.
|
||||||
|
|
@ -485,56 +483,56 @@ macro dumpLispImm*(s: stmt): stmt {.immediate, deprecated.} = echo s.lispRepr
|
||||||
## The ``immediate`` version of `dumpLisp`.
|
## The ``immediate`` version of `dumpLisp`.
|
||||||
|
|
||||||
|
|
||||||
proc newEmptyNode*(): PNimrodNode {.compileTime, noSideEffect.} =
|
proc newEmptyNode*(): NimNode {.compileTime, noSideEffect.} =
|
||||||
## Create a new empty node
|
## Create a new empty node
|
||||||
result = newNimNode(nnkEmpty)
|
result = newNimNode(nnkEmpty)
|
||||||
|
|
||||||
proc newStmtList*(stmts: varargs[PNimrodNode]): PNimrodNode {.compileTime.}=
|
proc newStmtList*(stmts: varargs[NimNode]): NimNode {.compileTime.}=
|
||||||
## Create a new statement list
|
## Create a new statement list
|
||||||
result = newNimNode(nnkStmtList).add(stmts)
|
result = newNimNode(nnkStmtList).add(stmts)
|
||||||
|
|
||||||
proc newPar*(exprs: varargs[PNimrodNode]): PNimrodNode {.compileTime.}=
|
proc newPar*(exprs: varargs[NimNode]): NimNode {.compileTime.}=
|
||||||
## Create a new parentheses-enclosed expression
|
## Create a new parentheses-enclosed expression
|
||||||
newNimNode(nnkPar).add(exprs)
|
newNimNode(nnkPar).add(exprs)
|
||||||
|
|
||||||
proc newBlockStmt*(label, body: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newBlockStmt*(label, body: NimNode): NimNode {.compileTime.} =
|
||||||
## Create a new block statement with label
|
## Create a new block statement with label
|
||||||
return newNimNode(nnkBlockStmt).add(label, body)
|
return newNimNode(nnkBlockStmt).add(label, body)
|
||||||
|
|
||||||
proc newBlockStmt*(body: PNimrodNode): PNimrodNode {.compiletime.} =
|
proc newBlockStmt*(body: NimNode): NimNode {.compiletime.} =
|
||||||
## Create a new block: stmt
|
## Create a new block: stmt
|
||||||
return newNimNode(nnkBlockStmt).add(newEmptyNode(), body)
|
return newNimNode(nnkBlockStmt).add(newEmptyNode(), body)
|
||||||
|
|
||||||
proc newVarStmt*(name, value: PNimrodNode): PNimrodNode {.compiletime.} =
|
proc newVarStmt*(name, value: NimNode): NimNode {.compiletime.} =
|
||||||
## Create a new var stmt
|
## Create a new var stmt
|
||||||
return newNimNode(nnkVarSection).add(
|
return newNimNode(nnkVarSection).add(
|
||||||
newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
|
newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
|
||||||
|
|
||||||
proc newLetStmt*(name, value: PNimrodNode): PNimrodNode {.compiletime.} =
|
proc newLetStmt*(name, value: NimNode): NimNode {.compiletime.} =
|
||||||
## Create a new let stmt
|
## Create a new let stmt
|
||||||
return newNimNode(nnkLetSection).add(
|
return newNimNode(nnkLetSection).add(
|
||||||
newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
|
newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
|
||||||
|
|
||||||
proc newConstStmt*(name, value: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newConstStmt*(name, value: NimNode): NimNode {.compileTime.} =
|
||||||
## Create a new const stmt
|
## Create a new const stmt
|
||||||
newNimNode(nnkConstSection).add(
|
newNimNode(nnkConstSection).add(
|
||||||
newNimNode(nnkConstDef).add(name, newNimNode(nnkEmpty), value))
|
newNimNode(nnkConstDef).add(name, newNimNode(nnkEmpty), value))
|
||||||
|
|
||||||
proc newAssignment*(lhs, rhs: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newAssignment*(lhs, rhs: NimNode): NimNode {.compileTime.} =
|
||||||
return newNimNode(nnkAsgn).add(lhs, rhs)
|
return newNimNode(nnkAsgn).add(lhs, rhs)
|
||||||
|
|
||||||
proc newDotExpr*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newDotExpr*(a, b: NimNode): NimNode {.compileTime.} =
|
||||||
## Create new dot expression
|
## Create new dot expression
|
||||||
## a.dot(b) -> `a.b`
|
## a.dot(b) -> `a.b`
|
||||||
return newNimNode(nnkDotExpr).add(a, b)
|
return newNimNode(nnkDotExpr).add(a, b)
|
||||||
|
|
||||||
proc newColonExpr*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newColonExpr*(a, b: NimNode): NimNode {.compileTime.} =
|
||||||
## Create new colon expression
|
## Create new colon expression
|
||||||
## newColonExpr(a, b) -> `a: b`
|
## newColonExpr(a, b) -> `a: b`
|
||||||
newNimNode(nnkExprColonExpr).add(a, b)
|
newNimNode(nnkExprColonExpr).add(a, b)
|
||||||
|
|
||||||
proc newIdentDefs*(name, kind: PNimrodNode;
|
proc newIdentDefs*(name, kind: NimNode;
|
||||||
default = newEmptyNode()): PNimrodNode {.compileTime.} =
|
default = newEmptyNode()): NimNode {.compileTime.} =
|
||||||
## Creates a new ``nnkIdentDefs`` node of a specific kind and value.
|
## Creates a new ``nnkIdentDefs`` node of a specific kind and value.
|
||||||
##
|
##
|
||||||
## ``nnkIdentDefs`` need to have at least three children, but they can have
|
## ``nnkIdentDefs`` need to have at least three children, but they can have
|
||||||
|
|
@ -565,13 +563,13 @@ proc newIdentDefs*(name, kind: PNimrodNode;
|
||||||
## newStrLitNode("Hello"))
|
## newStrLitNode("Hello"))
|
||||||
newNimNode(nnkIdentDefs).add(name, kind, default)
|
newNimNode(nnkIdentDefs).add(name, kind, default)
|
||||||
|
|
||||||
proc newNilLit*(): PNimrodNode {.compileTime.} =
|
proc newNilLit*(): NimNode {.compileTime.} =
|
||||||
## New nil literal shortcut
|
## New nil literal shortcut
|
||||||
result = newNimNode(nnkNilLit)
|
result = newNimNode(nnkNilLit)
|
||||||
|
|
||||||
proc high*(node: PNimrodNode): int {.compileTime.} = len(node) - 1
|
proc high*(node: NimNode): int {.compileTime.} = len(node) - 1
|
||||||
## Return the highest index available for a node
|
## Return the highest index available for a node
|
||||||
proc last*(node: PNimrodNode): PNimrodNode {.compileTime.} = node[node.high]
|
proc last*(node: NimNode): NimNode {.compileTime.} = node[node.high]
|
||||||
## Return the last item in nodes children. Same as `node[node.high()]`
|
## Return the last item in nodes children. Same as `node[node.high()]`
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -581,11 +579,11 @@ const
|
||||||
CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
||||||
nnkCallStrLit, nnkHiddenCallConv}
|
nnkCallStrLit, nnkHiddenCallConv}
|
||||||
|
|
||||||
proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
|
proc expectKind*(n: NimNode; k: set[NimNodeKind]) {.compileTime.} =
|
||||||
assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind
|
assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind
|
||||||
|
|
||||||
proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyNode()];
|
proc newProc*(name = newEmptyNode(); params: openArray[NimNode] = [newEmptyNode()];
|
||||||
body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} =
|
body: NimNode = newStmtList(), procType = nnkProcDef): NimNode {.compileTime.} =
|
||||||
## shortcut for creating a new proc
|
## shortcut for creating a new proc
|
||||||
##
|
##
|
||||||
## The ``params`` array must start with the return type of the proc,
|
## The ``params`` array must start with the return type of the proc,
|
||||||
|
|
@ -600,8 +598,8 @@ proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyN
|
||||||
newEmptyNode(),
|
newEmptyNode(),
|
||||||
body)
|
body)
|
||||||
|
|
||||||
proc newIfStmt*(branches: varargs[tuple[cond, body: PNimrodNode]]):
|
proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]):
|
||||||
PNimrodNode {.compiletime.} =
|
NimNode {.compiletime.} =
|
||||||
## Constructor for ``if`` statements.
|
## Constructor for ``if`` statements.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
|
|
@ -616,35 +614,35 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: PNimrodNode]]):
|
||||||
result.add(newNimNode(nnkElifBranch).add(i.cond, i.body))
|
result.add(newNimNode(nnkElifBranch).add(i.cond, i.body))
|
||||||
|
|
||||||
|
|
||||||
proc copyChildrenTo*(src, dest: PNimrodNode) {.compileTime.}=
|
proc copyChildrenTo*(src, dest: NimNode) {.compileTime.}=
|
||||||
## Copy all children from `src` to `dest`
|
## Copy all children from `src` to `dest`
|
||||||
for i in 0 .. < src.len:
|
for i in 0 .. < src.len:
|
||||||
dest.add src[i].copyNimTree
|
dest.add src[i].copyNimTree
|
||||||
|
|
||||||
template expectRoutine(node: PNimrodNode): stmt =
|
template expectRoutine(node: NimNode): stmt =
|
||||||
expectKind(node, RoutineNodes)
|
expectKind(node, RoutineNodes)
|
||||||
|
|
||||||
proc name*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc name*(someProc: NimNode): NimNode {.compileTime.} =
|
||||||
someProc.expectRoutine
|
someProc.expectRoutine
|
||||||
result = someProc[0]
|
result = someProc[0]
|
||||||
proc `name=`*(someProc: PNimrodNode; val: PNimrodNode) {.compileTime.} =
|
proc `name=`*(someProc: NimNode; val: NimNode) {.compileTime.} =
|
||||||
someProc.expectRoutine
|
someProc.expectRoutine
|
||||||
someProc[0] = val
|
someProc[0] = val
|
||||||
|
|
||||||
proc params*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc params*(someProc: NimNode): NimNode {.compileTime.} =
|
||||||
someProc.expectRoutine
|
someProc.expectRoutine
|
||||||
result = someProc[3]
|
result = someProc[3]
|
||||||
proc `params=`* (someProc: PNimrodNode; params: PNimrodNode) {.compileTime.}=
|
proc `params=`* (someProc: NimNode; params: NimNode) {.compileTime.}=
|
||||||
someProc.expectRoutine
|
someProc.expectRoutine
|
||||||
assert params.kind == nnkFormalParams
|
assert params.kind == nnkFormalParams
|
||||||
someProc[3] = params
|
someProc[3] = params
|
||||||
|
|
||||||
proc pragma*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc pragma*(someProc: NimNode): NimNode {.compileTime.} =
|
||||||
## Get the pragma of a proc type
|
## Get the pragma of a proc type
|
||||||
## These will be expanded
|
## These will be expanded
|
||||||
someProc.expectRoutine
|
someProc.expectRoutine
|
||||||
result = someProc[4]
|
result = someProc[4]
|
||||||
proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
|
proc `pragma=`*(someProc: NimNode; val: NimNode){.compileTime.}=
|
||||||
## Set the pragma of a proc type
|
## Set the pragma of a proc type
|
||||||
someProc.expectRoutine
|
someProc.expectRoutine
|
||||||
assert val.kind in {nnkEmpty, nnkPragma}
|
assert val.kind in {nnkEmpty, nnkPragma}
|
||||||
|
|
@ -654,7 +652,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
|
||||||
template badNodeKind(k; f): stmt{.immediate.} =
|
template badNodeKind(k; f): stmt{.immediate.} =
|
||||||
assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
|
assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
|
||||||
|
|
||||||
proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc body*(someProc: NimNode): NimNode {.compileTime.} =
|
||||||
case someProc.kind:
|
case someProc.kind:
|
||||||
of RoutineNodes:
|
of RoutineNodes:
|
||||||
return someProc[6]
|
return someProc[6]
|
||||||
|
|
@ -665,7 +663,7 @@ proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
else:
|
else:
|
||||||
badNodeKind someProc.kind, "body"
|
badNodeKind someProc.kind, "body"
|
||||||
|
|
||||||
proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
|
proc `body=`*(someProc: NimNode, val: NimNode) {.compileTime.} =
|
||||||
case someProc.kind
|
case someProc.kind
|
||||||
of RoutineNodes:
|
of RoutineNodes:
|
||||||
someProc[6] = val
|
someProc[6] = val
|
||||||
|
|
@ -676,10 +674,10 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
|
||||||
else:
|
else:
|
||||||
badNodeKind someProc.kind, "body="
|
badNodeKind someProc.kind, "body="
|
||||||
|
|
||||||
proc basename*(a: PNimrodNode): PNimrodNode {.compiletime, benign.}
|
proc basename*(a: NimNode): NimNode {.compiletime, benign.}
|
||||||
|
|
||||||
|
|
||||||
proc `$`*(node: PNimrodNode): string {.compileTime.} =
|
proc `$`*(node: NimNode): string {.compileTime.} =
|
||||||
## Get the string of an identifier node
|
## Get the string of an identifier node
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkIdent:
|
of nnkIdent:
|
||||||
|
|
@ -693,14 +691,14 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} =
|
||||||
else:
|
else:
|
||||||
badNodeKind node.kind, "$"
|
badNodeKind node.kind, "$"
|
||||||
|
|
||||||
proc ident*(name: string): PNimrodNode {.compileTime,inline.} = newIdentNode(name)
|
proc ident*(name: string): NimNode {.compileTime,inline.} = newIdentNode(name)
|
||||||
## Create a new ident node from a string
|
## Create a new ident node from a string
|
||||||
|
|
||||||
iterator children*(n: PNimrodNode): PNimrodNode {.inline.}=
|
iterator children*(n: NimNode): NimNode {.inline.}=
|
||||||
for i in 0 .. high(n):
|
for i in 0 .. high(n):
|
||||||
yield n[i]
|
yield n[i]
|
||||||
|
|
||||||
template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.
|
template findChild*(n: NimNode; cond: expr): NimNode {.
|
||||||
immediate, dirty.} =
|
immediate, dirty.} =
|
||||||
## Find the first child node matching condition (or nil).
|
## Find the first child node matching condition (or nil).
|
||||||
##
|
##
|
||||||
|
|
@ -708,14 +706,14 @@ template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.
|
||||||
## var res = findChild(n, it.kind == nnkPostfix and
|
## var res = findChild(n, it.kind == nnkPostfix and
|
||||||
## it.basename.ident == !"foo")
|
## it.basename.ident == !"foo")
|
||||||
block:
|
block:
|
||||||
var result: PNimrodNode
|
var result: NimNode
|
||||||
for it in n.children:
|
for it in n.children:
|
||||||
if cond:
|
if cond:
|
||||||
result = it
|
result = it
|
||||||
break
|
break
|
||||||
result
|
result
|
||||||
|
|
||||||
proc insert*(a: PNimrodNode; pos: int; b: PNimrodNode) {.compileTime.} =
|
proc insert*(a: NimNode; pos: int; b: NimNode) {.compileTime.} =
|
||||||
## Insert node B into A at pos
|
## Insert node B into A at pos
|
||||||
if high(a) < pos:
|
if high(a) < pos:
|
||||||
## add some empty nodes first
|
## add some empty nodes first
|
||||||
|
|
@ -730,7 +728,7 @@ proc insert*(a: PNimrodNode; pos: int; b: PNimrodNode) {.compileTime.} =
|
||||||
a[i + 1] = a[i]
|
a[i + 1] = a[i]
|
||||||
a[pos] = b
|
a[pos] = b
|
||||||
|
|
||||||
proc basename*(a: PNimrodNode): PNimrodNode =
|
proc basename*(a: NimNode): NimNode =
|
||||||
## Pull an identifier from prefix/postfix expressions
|
## Pull an identifier from prefix/postfix expressions
|
||||||
case a.kind
|
case a.kind
|
||||||
of nnkIdent: return a
|
of nnkIdent: return a
|
||||||
|
|
@ -738,39 +736,39 @@ proc basename*(a: PNimrodNode): PNimrodNode =
|
||||||
else:
|
else:
|
||||||
quit "Do not know how to get basename of ("& treeRepr(a) &")\n"& repr(a)
|
quit "Do not know how to get basename of ("& treeRepr(a) &")\n"& repr(a)
|
||||||
|
|
||||||
proc `basename=`*(a: PNimrodNode; val: string) {.compileTime.}=
|
proc `basename=`*(a: NimNode; val: string) {.compileTime.}=
|
||||||
case a.kind
|
case a.kind
|
||||||
of nnkIdent: macros.`ident=`(a, !val)
|
of nnkIdent: macros.`ident=`(a, !val)
|
||||||
of nnkPostfix, nnkPrefix: a[1] = ident(val)
|
of nnkPostfix, nnkPrefix: a[1] = ident(val)
|
||||||
else:
|
else:
|
||||||
quit "Do not know how to get basename of ("& treeRepr(a)& ")\n"& repr(a)
|
quit "Do not know how to get basename of ("& treeRepr(a)& ")\n"& repr(a)
|
||||||
|
|
||||||
proc postfix*(node: PNimrodNode; op: string): PNimrodNode {.compileTime.} =
|
proc postfix*(node: NimNode; op: string): NimNode {.compileTime.} =
|
||||||
newNimNode(nnkPostfix).add(ident(op), node)
|
newNimNode(nnkPostfix).add(ident(op), node)
|
||||||
|
|
||||||
proc prefix*(node: PNimrodNode; op: string): PNimrodNode {.compileTime.} =
|
proc prefix*(node: NimNode; op: string): NimNode {.compileTime.} =
|
||||||
newNimNode(nnkPrefix).add(ident(op), node)
|
newNimNode(nnkPrefix).add(ident(op), node)
|
||||||
|
|
||||||
proc infix*(a: PNimrodNode; op: string;
|
proc infix*(a: NimNode; op: string;
|
||||||
b: PNimrodNode): PNimrodNode {.compileTime.} =
|
b: NimNode): NimNode {.compileTime.} =
|
||||||
newNimNode(nnkInfix).add(ident(op), a, b)
|
newNimNode(nnkInfix).add(ident(op), a, b)
|
||||||
|
|
||||||
proc unpackPostfix*(node: PNimrodNode): tuple[node: PNimrodNode; op: string] {.
|
proc unpackPostfix*(node: NimNode): tuple[node: NimNode; op: string] {.
|
||||||
compileTime.} =
|
compileTime.} =
|
||||||
node.expectKind nnkPostfix
|
node.expectKind nnkPostfix
|
||||||
result = (node[0], $node[1])
|
result = (node[0], $node[1])
|
||||||
|
|
||||||
proc unpackPrefix*(node: PNimrodNode): tuple[node: PNimrodNode; op: string] {.
|
proc unpackPrefix*(node: NimNode): tuple[node: NimNode; op: string] {.
|
||||||
compileTime.} =
|
compileTime.} =
|
||||||
node.expectKind nnkPrefix
|
node.expectKind nnkPrefix
|
||||||
result = (node[0], $node[1])
|
result = (node[0], $node[1])
|
||||||
|
|
||||||
proc unpackInfix*(node: PNimrodNode): tuple[left: PNimrodNode; op: string;
|
proc unpackInfix*(node: NimNode): tuple[left: NimNode; op: string;
|
||||||
right: PNimrodNode] {.compileTime.} =
|
right: NimNode] {.compileTime.} =
|
||||||
assert node.kind == nnkInfix
|
assert node.kind == nnkInfix
|
||||||
result = (node[0], $node[1], node[2])
|
result = (node[0], $node[1], node[2])
|
||||||
|
|
||||||
proc copy*(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc copy*(node: NimNode): NimNode {.compileTime.} =
|
||||||
## An alias for copyNimTree().
|
## An alias for copyNimTree().
|
||||||
return node.copyNimTree()
|
return node.copyNimTree()
|
||||||
|
|
||||||
|
|
@ -793,7 +791,7 @@ proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} =
|
||||||
proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0
|
proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0
|
||||||
## Check if two idents are identical.
|
## Check if two idents are identical.
|
||||||
|
|
||||||
proc hasArgOfName* (params: PNimrodNode; name: string): bool {.compiletime.}=
|
proc hasArgOfName* (params: NimNode; name: string): bool {.compiletime.}=
|
||||||
## Search nnkFormalParams for an argument.
|
## Search nnkFormalParams for an argument.
|
||||||
assert params.kind == nnkFormalParams
|
assert params.kind == nnkFormalParams
|
||||||
for i in 1 .. <params.len:
|
for i in 1 .. <params.len:
|
||||||
|
|
@ -801,7 +799,7 @@ proc hasArgOfName* (params: PNimrodNode; name: string): bool {.compiletime.}=
|
||||||
if name.eqIdent( $ node[0]):
|
if name.eqIdent( $ node[0]):
|
||||||
return true
|
return true
|
||||||
|
|
||||||
proc addIdentIfAbsent*(dest: PNimrodNode, ident: string) {.compiletime.} =
|
proc addIdentIfAbsent*(dest: NimNode, ident: string) {.compiletime.} =
|
||||||
## Add ident to dest if it is not present. This is intended for use
|
## Add ident to dest if it is not present. This is intended for use
|
||||||
## with pragmas.
|
## with pragmas.
|
||||||
for node in dest.children:
|
for node in dest.children:
|
||||||
|
|
@ -825,5 +823,3 @@ when not defined(booting):
|
||||||
macro payload: stmt {.gensym.} =
|
macro payload: stmt {.gensym.} =
|
||||||
result = parseStmt(e)
|
result = parseStmt(e)
|
||||||
payload()
|
payload()
|
||||||
|
|
||||||
{.pop.}
|
|
||||||
|
|
|
||||||
|
|
@ -1064,13 +1064,13 @@ proc accept*(socket: TAsyncFD,
|
||||||
|
|
||||||
# -- Await Macro
|
# -- Await Macro
|
||||||
|
|
||||||
proc skipUntilStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc skipUntilStmtList(node: NimNode): NimNode {.compileTime.} =
|
||||||
# Skips a nest of StmtList's.
|
# Skips a nest of StmtList's.
|
||||||
result = node
|
result = node
|
||||||
if node[0].kind == nnkStmtList:
|
if node[0].kind == nnkStmtList:
|
||||||
result = skipUntilStmtList(node[0])
|
result = skipUntilStmtList(node[0])
|
||||||
|
|
||||||
proc skipStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc skipStmtList(node: NimNode): NimNode {.compileTime.} =
|
||||||
result = node
|
result = node
|
||||||
if node[0].kind == nnkStmtList:
|
if node[0].kind == nnkStmtList:
|
||||||
result = node[0]
|
result = node[0]
|
||||||
|
|
@ -1098,11 +1098,11 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
cb()
|
cb()
|
||||||
#{.pop.}
|
#{.pop.}
|
||||||
proc generateExceptionCheck(futSym,
|
proc generateExceptionCheck(futSym,
|
||||||
tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} =
|
tryStmt, rootReceiver, fromNode: NimNode): NimNode {.compileTime.} =
|
||||||
if tryStmt.kind == nnkNilLit:
|
if tryStmt.kind == nnkNilLit:
|
||||||
result = rootReceiver
|
result = rootReceiver
|
||||||
else:
|
else:
|
||||||
var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[]
|
var exceptionChecks: seq[tuple[cond, body: NimNode]] = @[]
|
||||||
let errorNode = newDotExpr(futSym, newIdentNode("error"))
|
let errorNode = newDotExpr(futSym, newIdentNode("error"))
|
||||||
for i in 1 .. <tryStmt.len:
|
for i in 1 .. <tryStmt.len:
|
||||||
let exceptBranch = tryStmt[i]
|
let exceptBranch = tryStmt[i]
|
||||||
|
|
@ -1110,7 +1110,7 @@ proc generateExceptionCheck(futSym,
|
||||||
exceptionChecks.add((newIdentNode("true"), exceptBranch[0]))
|
exceptionChecks.add((newIdentNode("true"), exceptBranch[0]))
|
||||||
else:
|
else:
|
||||||
var exceptIdentCount = 0
|
var exceptIdentCount = 0
|
||||||
var ifCond: PNimrodNode
|
var ifCond: NimNode
|
||||||
for i in 0 .. <exceptBranch.len:
|
for i in 0 .. <exceptBranch.len:
|
||||||
let child = exceptBranch[i]
|
let child = exceptBranch[i]
|
||||||
if child.kind == nnkIdent:
|
if child.kind == nnkIdent:
|
||||||
|
|
@ -1144,10 +1144,10 @@ proc generateExceptionCheck(futSym,
|
||||||
)
|
)
|
||||||
result.add elseNode
|
result.add elseNode
|
||||||
|
|
||||||
template createVar(result: var PNimrodNode, futSymName: string,
|
template createVar(result: var NimNode, futSymName: string,
|
||||||
asyncProc: PNimrodNode,
|
asyncProc: NimNode,
|
||||||
valueReceiver, rootReceiver: expr,
|
valueReceiver, rootReceiver: expr,
|
||||||
fromNode: PNimrodNode) =
|
fromNode: NimNode) =
|
||||||
result = newNimNode(nnkStmtList, fromNode)
|
result = newNimNode(nnkStmtList, fromNode)
|
||||||
var futSym = genSym(nskVar, "future")
|
var futSym = genSym(nskVar, "future")
|
||||||
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
||||||
|
|
@ -1155,9 +1155,9 @@ template createVar(result: var PNimrodNode, futSymName: string,
|
||||||
valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
|
valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
|
||||||
result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode)
|
result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode)
|
||||||
|
|
||||||
proc processBody(node, retFutureSym: PNimrodNode,
|
proc processBody(node, retFutureSym: NimNode,
|
||||||
subTypeIsVoid: bool,
|
subTypeIsVoid: bool,
|
||||||
tryStmt: PNimrodNode): PNimrodNode {.compileTime.} =
|
tryStmt: NimNode): NimNode {.compileTime.} =
|
||||||
#echo(node.treeRepr)
|
#echo(node.treeRepr)
|
||||||
result = node
|
result = node
|
||||||
case node.kind
|
case node.kind
|
||||||
|
|
@ -1183,7 +1183,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
||||||
result = newNimNode(nnkYieldStmt, node).add(node[1]) # -> yield x
|
result = newNimNode(nnkYieldStmt, node).add(node[1]) # -> yield x
|
||||||
of nnkCall, nnkCommand:
|
of nnkCall, nnkCommand:
|
||||||
# await foo(p, x)
|
# await foo(p, x)
|
||||||
var futureValue: PNimrodNode
|
var futureValue: NimNode
|
||||||
result.createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
|
result.createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
|
||||||
futureValue, node)
|
futureValue, node)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1232,8 +1232,8 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
||||||
# working in ``except``?
|
# working in ``except``?
|
||||||
tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil)
|
tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil)
|
||||||
|
|
||||||
proc processForTry(n: PNimrodNode, i: var int,
|
proc processForTry(n: NimNode, i: var int,
|
||||||
res: PNimrodNode): bool {.compileTime.} =
|
res: NimNode): bool {.compileTime.} =
|
||||||
## Transforms the body of the tryStmt. Does not transform the
|
## Transforms the body of the tryStmt. Does not transform the
|
||||||
## body in ``except``.
|
## body in ``except``.
|
||||||
## Returns true if the tryStmt node was transformed into an ifStmt.
|
## Returns true if the tryStmt node was transformed into an ifStmt.
|
||||||
|
|
@ -1275,7 +1275,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
||||||
for i in 0 .. <result.len:
|
for i in 0 .. <result.len:
|
||||||
result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, tryStmt)
|
result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, tryStmt)
|
||||||
|
|
||||||
proc getName(node: PNimrodNode): string {.compileTime.} =
|
proc getName(node: NimNode): string {.compileTime.} =
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkPostfix:
|
of nnkPostfix:
|
||||||
return $node[1].ident
|
return $node[1].ident
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
||||||
#echo treeRepr(p)
|
#echo treeRepr(p)
|
||||||
#echo treeRepr(b)
|
#echo treeRepr(b)
|
||||||
result = newNimNode(nnkProcTy)
|
result = newNimNode(nnkProcTy)
|
||||||
|
|
@ -44,7 +44,7 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
formalParams.add identDefs
|
formalParams.add identDefs
|
||||||
else:
|
else:
|
||||||
error("Incorrect type list in proc type declaration.")
|
error("Incorrect type list in proc type declaration.")
|
||||||
|
|
||||||
result.add formalParams
|
result.add formalParams
|
||||||
result.add newEmptyNode()
|
result.add newEmptyNode()
|
||||||
#echo(treeRepr(result))
|
#echo(treeRepr(result))
|
||||||
|
|
@ -59,10 +59,10 @@ macro `=>`*(p, b: expr): expr {.immediate.} =
|
||||||
## f(2, 2)
|
## f(2, 2)
|
||||||
##
|
##
|
||||||
## passTwoAndTwo((x, y) => x + y) # 4
|
## passTwoAndTwo((x, y) => x + y) # 4
|
||||||
|
|
||||||
#echo treeRepr(p)
|
#echo treeRepr(p)
|
||||||
#echo(treeRepr(b))
|
#echo(treeRepr(b))
|
||||||
var params: seq[PNimrodNode] = @[newIdentNode("auto")]
|
var params: seq[NimNode] = @[newIdentNode("auto")]
|
||||||
|
|
||||||
case p.kind
|
case p.kind
|
||||||
of nnkPar:
|
of nnkPar:
|
||||||
|
|
@ -118,7 +118,7 @@ macro `->`*(p, b: expr): expr {.immediate.} =
|
||||||
##
|
##
|
||||||
## proc pass2(f: (float, float) -> float): float =
|
## proc pass2(f: (float, float) -> float): float =
|
||||||
## f(2, 2)
|
## f(2, 2)
|
||||||
##
|
##
|
||||||
## # is the same as:
|
## # is the same as:
|
||||||
##
|
##
|
||||||
## proc pass2(f: proc (x, y: float): float): float =
|
## proc pass2(f: proc (x, y: float): float): float =
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
## as ``from htmlgen import nil`` and then fully qualify the macros.
|
## as ``from htmlgen import nil`` and then fully qualify the macros.
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## This module implements a simple `XML`:idx: and `HTML`:idx: code
|
## This module implements a simple `XML`:idx: and `HTML`:idx: code
|
||||||
## generator. Each commonly used HTML tag has a corresponding macro
|
## generator. Each commonly used HTML tag has a corresponding macro
|
||||||
## that generates a string with its HTML representation.
|
## that generates a string with its HTML representation.
|
||||||
##
|
##
|
||||||
|
|
@ -21,9 +21,9 @@
|
||||||
## .. code-block:: Nim
|
## .. code-block:: Nim
|
||||||
## var nim = "Nim"
|
## var nim = "Nim"
|
||||||
## echo h1(a(href="http://nim-lang.org", nim))
|
## echo h1(a(href="http://nim-lang.org", nim))
|
||||||
##
|
##
|
||||||
## Writes the string::
|
## Writes the string::
|
||||||
##
|
##
|
||||||
## <h1><a href="http://nim-lang.org">Nim</a></h1>
|
## <h1><a href="http://nim-lang.org">Nim</a></h1>
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
@ -36,16 +36,16 @@ const
|
||||||
"onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup "
|
"onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup "
|
||||||
commonAttr* = coreAttr & eventAttr
|
commonAttr* = coreAttr & eventAttr
|
||||||
|
|
||||||
proc getIdent(e: PNimrodNode): string {.compileTime.} =
|
proc getIdent(e: NimNode): string {.compileTime.} =
|
||||||
case e.kind
|
case e.kind
|
||||||
of nnkIdent: result = normalize($e.ident)
|
of nnkIdent: result = normalize($e.ident)
|
||||||
of nnkAccQuoted:
|
of nnkAccQuoted:
|
||||||
result = getIdent(e[0])
|
result = getIdent(e[0])
|
||||||
for i in 1 .. e.len-1:
|
for i in 1 .. e.len-1:
|
||||||
result.add getIdent(e[i])
|
result.add getIdent(e[i])
|
||||||
else: error("cannot extract identifier from node: " & toStrLit(e).strVal)
|
else: error("cannot extract identifier from node: " & toStrLit(e).strVal)
|
||||||
|
|
||||||
proc delete[T](s: var seq[T], attr: T): bool =
|
proc delete[T](s: var seq[T], attr: T): bool =
|
||||||
var idx = find(s, attr)
|
var idx = find(s, attr)
|
||||||
if idx >= 0:
|
if idx >= 0:
|
||||||
var L = s.len
|
var L = s.len
|
||||||
|
|
@ -53,10 +53,10 @@ proc delete[T](s: var seq[T], attr: T): bool =
|
||||||
setLen(s, L-1)
|
setLen(s, L-1)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
proc xmlCheckedTag*(e: NimNode, tag: string, optAttr = "", reqAttr = "",
|
||||||
isLeaf = false): PNimrodNode {.compileTime.} =
|
isLeaf = false): NimNode {.compileTime.} =
|
||||||
## use this procedure to define a new XML tag
|
## use this procedure to define a new XML tag
|
||||||
|
|
||||||
# copy the attributes; when iterating over them these lists
|
# copy the attributes; when iterating over them these lists
|
||||||
# will be modified, so that each attribute is only given one value
|
# will be modified, so that each attribute is only given one value
|
||||||
var req = split(reqAttr)
|
var req = split(reqAttr)
|
||||||
|
|
@ -66,7 +66,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
||||||
result.add(newStrLitNode(tag))
|
result.add(newStrLitNode(tag))
|
||||||
# first pass over attributes:
|
# first pass over attributes:
|
||||||
for i in 1..e.len-1:
|
for i in 1..e.len-1:
|
||||||
if e[i].kind == nnkExprEqExpr:
|
if e[i].kind == nnkExprEqExpr:
|
||||||
var name = getIdent(e[i][0])
|
var name = getIdent(e[i][0])
|
||||||
if delete(req, name) or delete(opt, name):
|
if delete(req, name) or delete(opt, name):
|
||||||
result.add(newStrLitNode(" "))
|
result.add(newStrLitNode(" "))
|
||||||
|
|
@ -81,7 +81,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
||||||
error(req[0] & " attribute for '" & tag & "' element expected")
|
error(req[0] & " attribute for '" & tag & "' element expected")
|
||||||
if isLeaf:
|
if isLeaf:
|
||||||
for i in 1..e.len-1:
|
for i in 1..e.len-1:
|
||||||
if e[i].kind != nnkExprEqExpr:
|
if e[i].kind != nnkExprEqExpr:
|
||||||
error("element " & tag & " cannot be nested")
|
error("element " & tag & " cannot be nested")
|
||||||
result.add(newStrLitNode(" />"))
|
result.add(newStrLitNode(" />"))
|
||||||
else:
|
else:
|
||||||
|
|
@ -95,389 +95,389 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
||||||
result = nestList(!"&", result)
|
result = nestList(!"&", result)
|
||||||
|
|
||||||
|
|
||||||
macro a*(e: expr): expr {.immediate.} =
|
macro a*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``a`` element.
|
## generates the HTML ``a`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "a", "href charset type hreflang rel rev " &
|
result = xmlCheckedTag(e, "a", "href charset type hreflang rel rev " &
|
||||||
"accesskey tabindex" & commonAttr)
|
"accesskey tabindex" & commonAttr)
|
||||||
|
|
||||||
macro acronym*(e: expr): expr {.immediate.} =
|
macro acronym*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``acronym`` element.
|
## generates the HTML ``acronym`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "acronym", commonAttr)
|
result = xmlCheckedTag(e, "acronym", commonAttr)
|
||||||
|
|
||||||
macro address*(e: expr): expr {.immediate.} =
|
macro address*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``address`` element.
|
## generates the HTML ``address`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "address", commonAttr)
|
result = xmlCheckedTag(e, "address", commonAttr)
|
||||||
|
|
||||||
macro area*(e: expr): expr {.immediate.} =
|
macro area*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``area`` element.
|
## generates the HTML ``area`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "area", "shape coords href nohref" &
|
result = xmlCheckedTag(e, "area", "shape coords href nohref" &
|
||||||
" accesskey tabindex" & commonAttr, "alt", true)
|
" accesskey tabindex" & commonAttr, "alt", true)
|
||||||
|
|
||||||
macro b*(e: expr): expr {.immediate.} =
|
macro b*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``b`` element.
|
## generates the HTML ``b`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "b", commonAttr)
|
result = xmlCheckedTag(e, "b", commonAttr)
|
||||||
|
|
||||||
macro base*(e: expr): expr {.immediate.} =
|
macro base*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``base`` element.
|
## generates the HTML ``base`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "base", "", "href", true)
|
result = xmlCheckedTag(e, "base", "", "href", true)
|
||||||
|
|
||||||
macro big*(e: expr): expr {.immediate.} =
|
macro big*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``big`` element.
|
## generates the HTML ``big`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "big", commonAttr)
|
result = xmlCheckedTag(e, "big", commonAttr)
|
||||||
|
|
||||||
macro blockquote*(e: expr): expr {.immediate.} =
|
macro blockquote*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``blockquote`` element.
|
## generates the HTML ``blockquote`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "blockquote", " cite" & commonAttr)
|
result = xmlCheckedTag(e, "blockquote", " cite" & commonAttr)
|
||||||
|
|
||||||
macro body*(e: expr): expr {.immediate.} =
|
macro body*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``body`` element.
|
## generates the HTML ``body`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "body", commonAttr)
|
result = xmlCheckedTag(e, "body", commonAttr)
|
||||||
|
|
||||||
macro br*(e: expr): expr {.immediate.} =
|
macro br*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``br`` element.
|
## generates the HTML ``br`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "br", "", "", true)
|
result = xmlCheckedTag(e, "br", "", "", true)
|
||||||
|
|
||||||
macro button*(e: expr): expr {.immediate.} =
|
macro button*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``button`` element.
|
## generates the HTML ``button`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "button", "accesskey tabindex " &
|
result = xmlCheckedTag(e, "button", "accesskey tabindex " &
|
||||||
"disabled name type value" & commonAttr)
|
"disabled name type value" & commonAttr)
|
||||||
|
|
||||||
macro caption*(e: expr): expr {.immediate.} =
|
macro caption*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``caption`` element.
|
## generates the HTML ``caption`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "caption", commonAttr)
|
result = xmlCheckedTag(e, "caption", commonAttr)
|
||||||
|
|
||||||
macro cite*(e: expr): expr {.immediate.} =
|
macro cite*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``cite`` element.
|
## generates the HTML ``cite`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "cite", commonAttr)
|
result = xmlCheckedTag(e, "cite", commonAttr)
|
||||||
|
|
||||||
macro code*(e: expr): expr {.immediate.} =
|
macro code*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``code`` element.
|
## generates the HTML ``code`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "code", commonAttr)
|
result = xmlCheckedTag(e, "code", commonAttr)
|
||||||
|
|
||||||
macro col*(e: expr): expr {.immediate.} =
|
macro col*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``col`` element.
|
## generates the HTML ``col`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "col", "span align valign" & commonAttr, "", true)
|
result = xmlCheckedTag(e, "col", "span align valign" & commonAttr, "", true)
|
||||||
|
|
||||||
macro colgroup*(e: expr): expr {.immediate.} =
|
macro colgroup*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``colgroup`` element.
|
## generates the HTML ``colgroup`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "colgroup", "span align valign" & commonAttr)
|
result = xmlCheckedTag(e, "colgroup", "span align valign" & commonAttr)
|
||||||
|
|
||||||
macro dd*(e: expr): expr {.immediate.} =
|
macro dd*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``dd`` element.
|
## generates the HTML ``dd`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "dd", commonAttr)
|
result = xmlCheckedTag(e, "dd", commonAttr)
|
||||||
|
|
||||||
macro del*(e: expr): expr {.immediate.} =
|
macro del*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``del`` element.
|
## generates the HTML ``del`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "del", "cite datetime" & commonAttr)
|
result = xmlCheckedTag(e, "del", "cite datetime" & commonAttr)
|
||||||
|
|
||||||
macro dfn*(e: expr): expr {.immediate.} =
|
macro dfn*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``dfn`` element.
|
## generates the HTML ``dfn`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "dfn", commonAttr)
|
result = xmlCheckedTag(e, "dfn", commonAttr)
|
||||||
|
|
||||||
macro `div`*(e: expr): expr {.immediate.} =
|
macro `div`*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``div`` element.
|
## generates the HTML ``div`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "div", commonAttr)
|
result = xmlCheckedTag(e, "div", commonAttr)
|
||||||
|
|
||||||
macro dl*(e: expr): expr {.immediate.} =
|
macro dl*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``dl`` element.
|
## generates the HTML ``dl`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "dl", commonAttr)
|
result = xmlCheckedTag(e, "dl", commonAttr)
|
||||||
|
|
||||||
macro dt*(e: expr): expr {.immediate.} =
|
macro dt*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``dt`` element.
|
## generates the HTML ``dt`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "dt", commonAttr)
|
result = xmlCheckedTag(e, "dt", commonAttr)
|
||||||
|
|
||||||
macro em*(e: expr): expr {.immediate.} =
|
macro em*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``em`` element.
|
## generates the HTML ``em`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "em", commonAttr)
|
result = xmlCheckedTag(e, "em", commonAttr)
|
||||||
|
|
||||||
macro fieldset*(e: expr): expr {.immediate.} =
|
macro fieldset*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``fieldset`` element.
|
## generates the HTML ``fieldset`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "fieldset", commonAttr)
|
result = xmlCheckedTag(e, "fieldset", commonAttr)
|
||||||
|
|
||||||
macro form*(e: expr): expr {.immediate.} =
|
macro form*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``form`` element.
|
## generates the HTML ``form`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "form", "method encype accept accept-charset" &
|
result = xmlCheckedTag(e, "form", "method encype accept accept-charset" &
|
||||||
commonAttr, "action")
|
commonAttr, "action")
|
||||||
|
|
||||||
macro h1*(e: expr): expr {.immediate.} =
|
macro h1*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``h1`` element.
|
## generates the HTML ``h1`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "h1", commonAttr)
|
result = xmlCheckedTag(e, "h1", commonAttr)
|
||||||
|
|
||||||
macro h2*(e: expr): expr {.immediate.} =
|
macro h2*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``h2`` element.
|
## generates the HTML ``h2`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "h2", commonAttr)
|
result = xmlCheckedTag(e, "h2", commonAttr)
|
||||||
|
|
||||||
macro h3*(e: expr): expr {.immediate.} =
|
macro h3*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``h3`` element.
|
## generates the HTML ``h3`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "h3", commonAttr)
|
result = xmlCheckedTag(e, "h3", commonAttr)
|
||||||
|
|
||||||
macro h4*(e: expr): expr {.immediate.} =
|
macro h4*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``h4`` element.
|
## generates the HTML ``h4`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "h4", commonAttr)
|
result = xmlCheckedTag(e, "h4", commonAttr)
|
||||||
|
|
||||||
macro h5*(e: expr): expr {.immediate.} =
|
macro h5*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``h5`` element.
|
## generates the HTML ``h5`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "h5", commonAttr)
|
result = xmlCheckedTag(e, "h5", commonAttr)
|
||||||
|
|
||||||
macro h6*(e: expr): expr {.immediate.} =
|
macro h6*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``h6`` element.
|
## generates the HTML ``h6`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "h6", commonAttr)
|
result = xmlCheckedTag(e, "h6", commonAttr)
|
||||||
|
|
||||||
macro head*(e: expr): expr {.immediate.} =
|
macro head*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``head`` element.
|
## generates the HTML ``head`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "head", "profile")
|
result = xmlCheckedTag(e, "head", "profile")
|
||||||
|
|
||||||
macro html*(e: expr): expr {.immediate.} =
|
macro html*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``html`` element.
|
## generates the HTML ``html`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "html", "xmlns", "")
|
result = xmlCheckedTag(e, "html", "xmlns", "")
|
||||||
|
|
||||||
macro hr*(): expr {.immediate.} =
|
macro hr*(): expr {.immediate.} =
|
||||||
## generates the HTML ``hr`` element.
|
## generates the HTML ``hr`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "hr", commonAttr, "", true)
|
result = xmlCheckedTag(e, "hr", commonAttr, "", true)
|
||||||
|
|
||||||
macro i*(e: expr): expr {.immediate.} =
|
macro i*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``i`` element.
|
## generates the HTML ``i`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "i", commonAttr)
|
result = xmlCheckedTag(e, "i", commonAttr)
|
||||||
|
|
||||||
macro img*(e: expr): expr {.immediate.} =
|
macro img*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``img`` element.
|
## generates the HTML ``img`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "img", "longdesc height width", "src alt", true)
|
result = xmlCheckedTag(e, "img", "longdesc height width", "src alt", true)
|
||||||
|
|
||||||
macro input*(e: expr): expr {.immediate.} =
|
macro input*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``input`` element.
|
## generates the HTML ``input`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "input", "name type value checked maxlength src" &
|
result = xmlCheckedTag(e, "input", "name type value checked maxlength src" &
|
||||||
" alt accept disabled readonly accesskey tabindex" & commonAttr, "", true)
|
" alt accept disabled readonly accesskey tabindex" & commonAttr, "", true)
|
||||||
|
|
||||||
macro ins*(e: expr): expr {.immediate.} =
|
macro ins*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``ins`` element.
|
## generates the HTML ``ins`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "ins", "cite datetime" & commonAttr)
|
result = xmlCheckedTag(e, "ins", "cite datetime" & commonAttr)
|
||||||
|
|
||||||
macro kbd*(e: expr): expr {.immediate.} =
|
macro kbd*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``kbd`` element.
|
## generates the HTML ``kbd`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "kbd", commonAttr)
|
result = xmlCheckedTag(e, "kbd", commonAttr)
|
||||||
|
|
||||||
macro label*(e: expr): expr {.immediate.} =
|
macro label*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``label`` element.
|
## generates the HTML ``label`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "label", "for accesskey" & commonAttr)
|
result = xmlCheckedTag(e, "label", "for accesskey" & commonAttr)
|
||||||
|
|
||||||
macro legend*(e: expr): expr {.immediate.} =
|
macro legend*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``legend`` element.
|
## generates the HTML ``legend`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "legend", "accesskey" & commonAttr)
|
result = xmlCheckedTag(e, "legend", "accesskey" & commonAttr)
|
||||||
|
|
||||||
macro li*(e: expr): expr {.immediate.} =
|
macro li*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``li`` element.
|
## generates the HTML ``li`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "li", commonAttr)
|
result = xmlCheckedTag(e, "li", commonAttr)
|
||||||
|
|
||||||
macro link*(e: expr): expr {.immediate.} =
|
macro link*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``link`` element.
|
## generates the HTML ``link`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "link", "href charset hreflang type rel rev media" &
|
result = xmlCheckedTag(e, "link", "href charset hreflang type rel rev media" &
|
||||||
commonAttr, "", true)
|
commonAttr, "", true)
|
||||||
|
|
||||||
macro map*(e: expr): expr {.immediate.} =
|
macro map*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``map`` element.
|
## generates the HTML ``map`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "map", "class title" & eventAttr, "id", false)
|
result = xmlCheckedTag(e, "map", "class title" & eventAttr, "id", false)
|
||||||
|
|
||||||
macro meta*(e: expr): expr {.immediate.} =
|
macro meta*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``meta`` element.
|
## generates the HTML ``meta`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "meta", "name http-equiv scheme", "content", true)
|
result = xmlCheckedTag(e, "meta", "name http-equiv scheme", "content", true)
|
||||||
|
|
||||||
macro noscript*(e: expr): expr {.immediate.} =
|
macro noscript*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``noscript`` element.
|
## generates the HTML ``noscript`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "noscript", commonAttr)
|
result = xmlCheckedTag(e, "noscript", commonAttr)
|
||||||
|
|
||||||
macro `object`*(e: expr): expr {.immediate.} =
|
macro `object`*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``object`` element.
|
## generates the HTML ``object`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "object", "classid data codebase declare type " &
|
result = xmlCheckedTag(e, "object", "classid data codebase declare type " &
|
||||||
"codetype archive standby width height name tabindex" & commonAttr)
|
"codetype archive standby width height name tabindex" & commonAttr)
|
||||||
|
|
||||||
macro ol*(e: expr): expr {.immediate.} =
|
macro ol*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``ol`` element.
|
## generates the HTML ``ol`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "ol", commonAttr)
|
result = xmlCheckedTag(e, "ol", commonAttr)
|
||||||
|
|
||||||
macro optgroup*(e: expr): expr {.immediate.} =
|
macro optgroup*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``optgroup`` element.
|
## generates the HTML ``optgroup`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "optgroup", "disabled" & commonAttr, "label", false)
|
result = xmlCheckedTag(e, "optgroup", "disabled" & commonAttr, "label", false)
|
||||||
|
|
||||||
macro option*(e: expr): expr {.immediate.} =
|
macro option*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``option`` element.
|
## generates the HTML ``option`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "option", "selected value" & commonAttr)
|
result = xmlCheckedTag(e, "option", "selected value" & commonAttr)
|
||||||
|
|
||||||
macro p*(e: expr): expr {.immediate.} =
|
macro p*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``p`` element.
|
## generates the HTML ``p`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "p", commonAttr)
|
result = xmlCheckedTag(e, "p", commonAttr)
|
||||||
|
|
||||||
macro param*(e: expr): expr {.immediate.} =
|
macro param*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``param`` element.
|
## generates the HTML ``param`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "param", "value id type valuetype", "name", true)
|
result = xmlCheckedTag(e, "param", "value id type valuetype", "name", true)
|
||||||
|
|
||||||
macro pre*(e: expr): expr {.immediate.} =
|
macro pre*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``pre`` element.
|
## generates the HTML ``pre`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "pre", commonAttr)
|
result = xmlCheckedTag(e, "pre", commonAttr)
|
||||||
|
|
||||||
macro q*(e: expr): expr {.immediate.} =
|
macro q*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``q`` element.
|
## generates the HTML ``q`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "q", "cite" & commonAttr)
|
result = xmlCheckedTag(e, "q", "cite" & commonAttr)
|
||||||
|
|
||||||
macro samp*(e: expr): expr {.immediate.} =
|
macro samp*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``samp`` element.
|
## generates the HTML ``samp`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "samp", commonAttr)
|
result = xmlCheckedTag(e, "samp", commonAttr)
|
||||||
|
|
||||||
macro script*(e: expr): expr {.immediate.} =
|
macro script*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``script`` element.
|
## generates the HTML ``script`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "script", "src charset defer", "type", false)
|
result = xmlCheckedTag(e, "script", "src charset defer", "type", false)
|
||||||
|
|
||||||
macro select*(e: expr): expr {.immediate.} =
|
macro select*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``select`` element.
|
## generates the HTML ``select`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "select", "name size multiple disabled tabindex" &
|
result = xmlCheckedTag(e, "select", "name size multiple disabled tabindex" &
|
||||||
commonAttr)
|
commonAttr)
|
||||||
|
|
||||||
macro small*(e: expr): expr {.immediate.} =
|
macro small*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``small`` element.
|
## generates the HTML ``small`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "small", commonAttr)
|
result = xmlCheckedTag(e, "small", commonAttr)
|
||||||
|
|
||||||
macro span*(e: expr): expr {.immediate.} =
|
macro span*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``span`` element.
|
## generates the HTML ``span`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "span", commonAttr)
|
result = xmlCheckedTag(e, "span", commonAttr)
|
||||||
|
|
||||||
macro strong*(e: expr): expr {.immediate.} =
|
macro strong*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``strong`` element.
|
## generates the HTML ``strong`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "strong", commonAttr)
|
result = xmlCheckedTag(e, "strong", commonAttr)
|
||||||
|
|
||||||
macro style*(e: expr): expr {.immediate.} =
|
macro style*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``style`` element.
|
## generates the HTML ``style`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "style", "media title", "type")
|
result = xmlCheckedTag(e, "style", "media title", "type")
|
||||||
|
|
||||||
macro sub*(e: expr): expr {.immediate.} =
|
macro sub*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``sub`` element.
|
## generates the HTML ``sub`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "sub", commonAttr)
|
result = xmlCheckedTag(e, "sub", commonAttr)
|
||||||
|
|
||||||
macro sup*(e: expr): expr {.immediate.} =
|
macro sup*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``sup`` element.
|
## generates the HTML ``sup`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "sup", commonAttr)
|
result = xmlCheckedTag(e, "sup", commonAttr)
|
||||||
|
|
||||||
macro table*(e: expr): expr {.immediate.} =
|
macro table*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``table`` element.
|
## generates the HTML ``table`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "table", "summary border cellpadding cellspacing" &
|
result = xmlCheckedTag(e, "table", "summary border cellpadding cellspacing" &
|
||||||
" frame rules width" & commonAttr)
|
" frame rules width" & commonAttr)
|
||||||
|
|
||||||
macro tbody*(e: expr): expr {.immediate.} =
|
macro tbody*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``tbody`` element.
|
## generates the HTML ``tbody`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "tbody", "align valign" & commonAttr)
|
result = xmlCheckedTag(e, "tbody", "align valign" & commonAttr)
|
||||||
|
|
||||||
macro td*(e: expr): expr {.immediate.} =
|
macro td*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``td`` element.
|
## generates the HTML ``td`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "td", "colspan rowspan abbr axis headers scope" &
|
result = xmlCheckedTag(e, "td", "colspan rowspan abbr axis headers scope" &
|
||||||
" align valign" & commonAttr)
|
" align valign" & commonAttr)
|
||||||
|
|
||||||
macro textarea*(e: expr): expr {.immediate.} =
|
macro textarea*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``textarea`` element.
|
## generates the HTML ``textarea`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "textarea", " name disabled readonly accesskey" &
|
result = xmlCheckedTag(e, "textarea", " name disabled readonly accesskey" &
|
||||||
" tabindex" & commonAttr, "rows cols", false)
|
" tabindex" & commonAttr, "rows cols", false)
|
||||||
|
|
||||||
macro tfoot*(e: expr): expr {.immediate.} =
|
macro tfoot*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``tfoot`` element.
|
## generates the HTML ``tfoot`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "tfoot", "align valign" & commonAttr)
|
result = xmlCheckedTag(e, "tfoot", "align valign" & commonAttr)
|
||||||
|
|
||||||
macro th*(e: expr): expr {.immediate.} =
|
macro th*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``th`` element.
|
## generates the HTML ``th`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "th", "colspan rowspan abbr axis headers scope" &
|
result = xmlCheckedTag(e, "th", "colspan rowspan abbr axis headers scope" &
|
||||||
" align valign" & commonAttr)
|
" align valign" & commonAttr)
|
||||||
|
|
||||||
macro thead*(e: expr): expr {.immediate.} =
|
macro thead*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``thead`` element.
|
## generates the HTML ``thead`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "thead", "align valign" & commonAttr)
|
result = xmlCheckedTag(e, "thead", "align valign" & commonAttr)
|
||||||
|
|
||||||
macro title*(e: expr): expr {.immediate.} =
|
macro title*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``title`` element.
|
## generates the HTML ``title`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "title")
|
result = xmlCheckedTag(e, "title")
|
||||||
|
|
||||||
macro tr*(e: expr): expr {.immediate.} =
|
macro tr*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``tr`` element.
|
## generates the HTML ``tr`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "tr", "align valign" & commonAttr)
|
result = xmlCheckedTag(e, "tr", "align valign" & commonAttr)
|
||||||
|
|
||||||
macro tt*(e: expr): expr {.immediate.} =
|
macro tt*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``tt`` element.
|
## generates the HTML ``tt`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "tt", commonAttr)
|
result = xmlCheckedTag(e, "tt", commonAttr)
|
||||||
|
|
||||||
macro ul*(e: expr): expr {.immediate.} =
|
macro ul*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``ul`` element.
|
## generates the HTML ``ul`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "ul", commonAttr)
|
result = xmlCheckedTag(e, "ul", commonAttr)
|
||||||
|
|
||||||
macro `var`*(e: expr): expr {.immediate.} =
|
macro `var`*(e: expr): expr {.immediate.} =
|
||||||
## generates the HTML ``var`` element.
|
## generates the HTML ``var`` element.
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
result = xmlCheckedTag(e, "var", commonAttr)
|
result = xmlCheckedTag(e, "var", commonAttr)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module implements a simple high performance `JSON`:idx:
|
## This module implements a simple high performance `JSON`:idx:
|
||||||
## parser. JSON (JavaScript Object Notation) is a lightweight
|
## parser. JSON (JavaScript Object Notation) is a lightweight
|
||||||
## data-interchange format that is easy for humans to read and write
|
## data-interchange format that is easy for humans to read and write
|
||||||
## (unlike XML). It is easy for machines to parse and generate.
|
## (unlike XML). It is easy for machines to parse and generate.
|
||||||
## JSON is based on a subset of the JavaScript Programming Language,
|
## JSON is based on a subset of the JavaScript Programming Language,
|
||||||
## Standard ECMA-262 3rd Edition - December 1999.
|
## Standard ECMA-262 3rd Edition - December 1999.
|
||||||
|
|
@ -50,10 +50,10 @@
|
||||||
## }
|
## }
|
||||||
## ]
|
## ]
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, strutils, lexbase, streams, unicode, macros
|
hashes, strutils, lexbase, streams, unicode, macros
|
||||||
|
|
||||||
type
|
type
|
||||||
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
||||||
jsonError, ## an error occurred during parsing
|
jsonError, ## an error occurred during parsing
|
||||||
jsonEof, ## end of file reached
|
jsonEof, ## end of file reached
|
||||||
|
|
@ -67,7 +67,7 @@ type
|
||||||
jsonObjectEnd, ## end of an object: the ``}`` token
|
jsonObjectEnd, ## end of an object: the ``}`` token
|
||||||
jsonArrayStart, ## start of an array: the ``[`` token
|
jsonArrayStart, ## start of an array: the ``[`` token
|
||||||
jsonArrayEnd ## start of an array: the ``]`` token
|
jsonArrayEnd ## start of an array: the ``]`` token
|
||||||
|
|
||||||
TTokKind = enum # must be synchronized with TJsonEventKind!
|
TTokKind = enum # must be synchronized with TJsonEventKind!
|
||||||
tkError,
|
tkError,
|
||||||
tkEof,
|
tkEof,
|
||||||
|
|
@ -83,7 +83,7 @@ type
|
||||||
tkBracketRi,
|
tkBracketRi,
|
||||||
tkColon,
|
tkColon,
|
||||||
tkComma
|
tkComma
|
||||||
|
|
||||||
JsonError* = enum ## enumeration that lists all errors that can occur
|
JsonError* = enum ## enumeration that lists all errors that can occur
|
||||||
errNone, ## no error
|
errNone, ## no error
|
||||||
errInvalidToken, ## invalid token
|
errInvalidToken, ## invalid token
|
||||||
|
|
@ -96,8 +96,8 @@ type
|
||||||
errEOC_Expected, ## ``*/`` expected
|
errEOC_Expected, ## ``*/`` expected
|
||||||
errEofExpected, ## EOF expected
|
errEofExpected, ## EOF expected
|
||||||
errExprExpected ## expr expected
|
errExprExpected ## expr expected
|
||||||
|
|
||||||
ParserState = enum
|
ParserState = enum
|
||||||
stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
|
stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
|
||||||
stateExpectObjectComma, stateExpectColon, stateExpectValue
|
stateExpectObjectComma, stateExpectColon, stateExpectValue
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ type
|
||||||
|
|
||||||
{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError,
|
{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError,
|
||||||
TJsonParser: JsonParser].}
|
TJsonParser: JsonParser].}
|
||||||
|
|
||||||
const
|
const
|
||||||
errorMessages: array [JsonError, string] = [
|
errorMessages: array [JsonError, string] = [
|
||||||
"no error",
|
"no error",
|
||||||
|
|
@ -146,56 +146,56 @@ proc open*(my: var JsonParser, input: Stream, filename: string) =
|
||||||
my.state = @[stateStart]
|
my.state = @[stateStart]
|
||||||
my.kind = jsonError
|
my.kind = jsonError
|
||||||
my.a = ""
|
my.a = ""
|
||||||
|
|
||||||
proc close*(my: var JsonParser) {.inline.} =
|
proc close*(my: var JsonParser) {.inline.} =
|
||||||
## closes the parser `my` and its associated input stream.
|
## closes the parser `my` and its associated input stream.
|
||||||
lexbase.close(my)
|
lexbase.close(my)
|
||||||
|
|
||||||
proc str*(my: JsonParser): string {.inline.} =
|
proc str*(my: JsonParser): string {.inline.} =
|
||||||
## returns the character data for the events: ``jsonInt``, ``jsonFloat``,
|
## returns the character data for the events: ``jsonInt``, ``jsonFloat``,
|
||||||
## ``jsonString``
|
## ``jsonString``
|
||||||
assert(my.kind in {jsonInt, jsonFloat, jsonString})
|
assert(my.kind in {jsonInt, jsonFloat, jsonString})
|
||||||
return my.a
|
return my.a
|
||||||
|
|
||||||
proc getInt*(my: JsonParser): BiggestInt {.inline.} =
|
proc getInt*(my: JsonParser): BiggestInt {.inline.} =
|
||||||
## returns the number for the event: ``jsonInt``
|
## returns the number for the event: ``jsonInt``
|
||||||
assert(my.kind == jsonInt)
|
assert(my.kind == jsonInt)
|
||||||
return parseBiggestInt(my.a)
|
return parseBiggestInt(my.a)
|
||||||
|
|
||||||
proc getFloat*(my: JsonParser): float {.inline.} =
|
proc getFloat*(my: JsonParser): float {.inline.} =
|
||||||
## returns the number for the event: ``jsonFloat``
|
## returns the number for the event: ``jsonFloat``
|
||||||
assert(my.kind == jsonFloat)
|
assert(my.kind == jsonFloat)
|
||||||
return parseFloat(my.a)
|
return parseFloat(my.a)
|
||||||
|
|
||||||
proc kind*(my: JsonParser): JsonEventKind {.inline.} =
|
proc kind*(my: JsonParser): JsonEventKind {.inline.} =
|
||||||
## returns the current event type for the JSON parser
|
## returns the current event type for the JSON parser
|
||||||
return my.kind
|
return my.kind
|
||||||
|
|
||||||
proc getColumn*(my: JsonParser): int {.inline.} =
|
proc getColumn*(my: JsonParser): int {.inline.} =
|
||||||
## get the current column the parser has arrived at.
|
## get the current column the parser has arrived at.
|
||||||
result = getColNumber(my, my.bufpos)
|
result = getColNumber(my, my.bufpos)
|
||||||
|
|
||||||
proc getLine*(my: JsonParser): int {.inline.} =
|
proc getLine*(my: JsonParser): int {.inline.} =
|
||||||
## get the current line the parser has arrived at.
|
## get the current line the parser has arrived at.
|
||||||
result = my.lineNumber
|
result = my.lineNumber
|
||||||
|
|
||||||
proc getFilename*(my: JsonParser): string {.inline.} =
|
proc getFilename*(my: JsonParser): string {.inline.} =
|
||||||
## get the filename of the file that the parser processes.
|
## get the filename of the file that the parser processes.
|
||||||
result = my.filename
|
result = my.filename
|
||||||
|
|
||||||
proc errorMsg*(my: JsonParser): string =
|
proc errorMsg*(my: JsonParser): string =
|
||||||
## returns a helpful error message for the event ``jsonError``
|
## returns a helpful error message for the event ``jsonError``
|
||||||
assert(my.kind == jsonError)
|
assert(my.kind == jsonError)
|
||||||
result = "$1($2, $3) Error: $4" % [
|
result = "$1($2, $3) Error: $4" % [
|
||||||
my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]]
|
my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]]
|
||||||
|
|
||||||
proc errorMsgExpected*(my: JsonParser, e: string): string =
|
proc errorMsgExpected*(my: JsonParser, e: string): string =
|
||||||
## returns an error message "`e` expected" in the same format as the
|
## returns an error message "`e` expected" in the same format as the
|
||||||
## other error messages
|
## other error messages
|
||||||
result = "$1($2, $3) Error: $4" % [
|
result = "$1($2, $3) Error: $4" % [
|
||||||
my.filename, $getLine(my), $getColumn(my), e & " expected"]
|
my.filename, $getLine(my), $getColumn(my), e & " expected"]
|
||||||
|
|
||||||
proc handleHexChar(c: char, x: var int): bool =
|
proc handleHexChar(c: char, x: var int): bool =
|
||||||
result = true # Success
|
result = true # Success
|
||||||
case c
|
case c
|
||||||
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
||||||
|
|
@ -208,8 +208,8 @@ proc parseString(my: var JsonParser): TTokKind =
|
||||||
var pos = my.bufpos + 1
|
var pos = my.bufpos + 1
|
||||||
var buf = my.buf
|
var buf = my.buf
|
||||||
while true:
|
while true:
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of '\0':
|
of '\0':
|
||||||
my.err = errQuoteExpected
|
my.err = errQuoteExpected
|
||||||
result = tkError
|
result = tkError
|
||||||
break
|
break
|
||||||
|
|
@ -218,21 +218,21 @@ proc parseString(my: var JsonParser): TTokKind =
|
||||||
break
|
break
|
||||||
of '\\':
|
of '\\':
|
||||||
case buf[pos+1]
|
case buf[pos+1]
|
||||||
of '\\', '"', '\'', '/':
|
of '\\', '"', '\'', '/':
|
||||||
add(my.a, buf[pos+1])
|
add(my.a, buf[pos+1])
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
of 'b':
|
of 'b':
|
||||||
add(my.a, '\b')
|
add(my.a, '\b')
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
of 'f':
|
of 'f':
|
||||||
add(my.a, '\f')
|
add(my.a, '\f')
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
of 'n':
|
of 'n':
|
||||||
add(my.a, '\L')
|
add(my.a, '\L')
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
of 'r':
|
of 'r':
|
||||||
add(my.a, '\C')
|
add(my.a, '\C')
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
of 't':
|
of 't':
|
||||||
add(my.a, '\t')
|
add(my.a, '\t')
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
|
|
@ -244,15 +244,15 @@ proc parseString(my: var JsonParser): TTokKind =
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
if handleHexChar(buf[pos], r): inc(pos)
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
if handleHexChar(buf[pos], r): inc(pos)
|
||||||
add(my.a, toUTF8(Rune(r)))
|
add(my.a, toUTF8(Rune(r)))
|
||||||
else:
|
else:
|
||||||
# don't bother with the error
|
# don't bother with the error
|
||||||
add(my.a, buf[pos])
|
add(my.a, buf[pos])
|
||||||
inc(pos)
|
inc(pos)
|
||||||
of '\c':
|
of '\c':
|
||||||
pos = lexbase.handleCR(my, pos)
|
pos = lexbase.handleCR(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
add(my.a, '\c')
|
add(my.a, '\c')
|
||||||
of '\L':
|
of '\L':
|
||||||
pos = lexbase.handleLF(my, pos)
|
pos = lexbase.handleLF(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
add(my.a, '\L')
|
add(my.a, '\L')
|
||||||
|
|
@ -260,25 +260,25 @@ proc parseString(my: var JsonParser): TTokKind =
|
||||||
add(my.a, buf[pos])
|
add(my.a, buf[pos])
|
||||||
inc(pos)
|
inc(pos)
|
||||||
my.bufpos = pos # store back
|
my.bufpos = pos # store back
|
||||||
|
|
||||||
proc skip(my: var JsonParser) =
|
proc skip(my: var JsonParser) =
|
||||||
var pos = my.bufpos
|
var pos = my.bufpos
|
||||||
var buf = my.buf
|
var buf = my.buf
|
||||||
while true:
|
while true:
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of '/':
|
of '/':
|
||||||
if buf[pos+1] == '/':
|
if buf[pos+1] == '/':
|
||||||
# skip line comment:
|
# skip line comment:
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
while true:
|
while true:
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of '\0':
|
of '\0':
|
||||||
break
|
break
|
||||||
of '\c':
|
of '\c':
|
||||||
pos = lexbase.handleCR(my, pos)
|
pos = lexbase.handleCR(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
break
|
break
|
||||||
of '\L':
|
of '\L':
|
||||||
pos = lexbase.handleLF(my, pos)
|
pos = lexbase.handleLF(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
break
|
break
|
||||||
|
|
@ -288,44 +288,44 @@ proc skip(my: var JsonParser) =
|
||||||
# skip long comment:
|
# skip long comment:
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
while true:
|
while true:
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of '\0':
|
of '\0':
|
||||||
my.err = errEOC_Expected
|
my.err = errEOC_Expected
|
||||||
break
|
break
|
||||||
of '\c':
|
of '\c':
|
||||||
pos = lexbase.handleCR(my, pos)
|
pos = lexbase.handleCR(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
of '\L':
|
of '\L':
|
||||||
pos = lexbase.handleLF(my, pos)
|
pos = lexbase.handleLF(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
of '*':
|
of '*':
|
||||||
inc(pos)
|
inc(pos)
|
||||||
if buf[pos] == '/':
|
if buf[pos] == '/':
|
||||||
inc(pos)
|
inc(pos)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
inc(pos)
|
inc(pos)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
of ' ', '\t':
|
of ' ', '\t':
|
||||||
inc(pos)
|
inc(pos)
|
||||||
of '\c':
|
of '\c':
|
||||||
pos = lexbase.handleCR(my, pos)
|
pos = lexbase.handleCR(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
of '\L':
|
of '\L':
|
||||||
pos = lexbase.handleLF(my, pos)
|
pos = lexbase.handleLF(my, pos)
|
||||||
buf = my.buf
|
buf = my.buf
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
my.bufpos = pos
|
my.bufpos = pos
|
||||||
|
|
||||||
proc parseNumber(my: var JsonParser) =
|
proc parseNumber(my: var JsonParser) =
|
||||||
var pos = my.bufpos
|
var pos = my.bufpos
|
||||||
var buf = my.buf
|
var buf = my.buf
|
||||||
if buf[pos] == '-':
|
if buf[pos] == '-':
|
||||||
add(my.a, '-')
|
add(my.a, '-')
|
||||||
inc(pos)
|
inc(pos)
|
||||||
if buf[pos] == '.':
|
if buf[pos] == '.':
|
||||||
add(my.a, "0.")
|
add(my.a, "0.")
|
||||||
inc(pos)
|
inc(pos)
|
||||||
else:
|
else:
|
||||||
|
|
@ -350,7 +350,7 @@ proc parseNumber(my: var JsonParser) =
|
||||||
inc(pos)
|
inc(pos)
|
||||||
my.bufpos = pos
|
my.bufpos = pos
|
||||||
|
|
||||||
proc parseName(my: var JsonParser) =
|
proc parseName(my: var JsonParser) =
|
||||||
var pos = my.bufpos
|
var pos = my.bufpos
|
||||||
var buf = my.buf
|
var buf = my.buf
|
||||||
if buf[pos] in IdentStartChars:
|
if buf[pos] in IdentStartChars:
|
||||||
|
|
@ -359,11 +359,11 @@ proc parseName(my: var JsonParser) =
|
||||||
inc(pos)
|
inc(pos)
|
||||||
my.bufpos = pos
|
my.bufpos = pos
|
||||||
|
|
||||||
proc getTok(my: var JsonParser): TTokKind =
|
proc getTok(my: var JsonParser): TTokKind =
|
||||||
setLen(my.a, 0)
|
setLen(my.a, 0)
|
||||||
skip(my) # skip whitespace, comments
|
skip(my) # skip whitespace, comments
|
||||||
case my.buf[my.bufpos]
|
case my.buf[my.bufpos]
|
||||||
of '-', '.', '0'..'9':
|
of '-', '.', '0'..'9':
|
||||||
parseNumber(my)
|
parseNumber(my)
|
||||||
if {'.', 'e', 'E'} in my.a:
|
if {'.', 'e', 'E'} in my.a:
|
||||||
result = tkFloat
|
result = tkFloat
|
||||||
|
|
@ -393,17 +393,17 @@ proc getTok(my: var JsonParser): TTokKind =
|
||||||
result = tkEof
|
result = tkEof
|
||||||
of 'a'..'z', 'A'..'Z', '_':
|
of 'a'..'z', 'A'..'Z', '_':
|
||||||
parseName(my)
|
parseName(my)
|
||||||
case my.a
|
case my.a
|
||||||
of "null": result = tkNull
|
of "null": result = tkNull
|
||||||
of "true": result = tkTrue
|
of "true": result = tkTrue
|
||||||
of "false": result = tkFalse
|
of "false": result = tkFalse
|
||||||
else: result = tkError
|
else: result = tkError
|
||||||
else:
|
else:
|
||||||
inc(my.bufpos)
|
inc(my.bufpos)
|
||||||
result = tkError
|
result = tkError
|
||||||
my.tok = result
|
my.tok = result
|
||||||
|
|
||||||
proc next*(my: var JsonParser) =
|
proc next*(my: var JsonParser) =
|
||||||
## retrieves the first/next event. This controls the parser.
|
## retrieves the first/next event. This controls the parser.
|
||||||
var tk = getTok(my)
|
var tk = getTok(my)
|
||||||
var i = my.state.len-1
|
var i = my.state.len-1
|
||||||
|
|
@ -416,13 +416,13 @@ proc next*(my: var JsonParser) =
|
||||||
else:
|
else:
|
||||||
my.kind = jsonError
|
my.kind = jsonError
|
||||||
my.err = errEofExpected
|
my.err = errEofExpected
|
||||||
of stateStart:
|
of stateStart:
|
||||||
# tokens allowed?
|
# tokens allowed?
|
||||||
case tk
|
case tk
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state[i] = stateEof # expect EOF next!
|
my.state[i] = stateEof # expect EOF next!
|
||||||
my.kind = JsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state.add(stateArray) # we expect any
|
my.state.add(stateArray) # we expect any
|
||||||
my.kind = jsonArrayStart
|
my.kind = jsonArrayStart
|
||||||
of tkCurlyLe:
|
of tkCurlyLe:
|
||||||
|
|
@ -433,12 +433,12 @@ proc next*(my: var JsonParser) =
|
||||||
else:
|
else:
|
||||||
my.kind = jsonError
|
my.kind = jsonError
|
||||||
my.err = errEofExpected
|
my.err = errEofExpected
|
||||||
of stateObject:
|
of stateObject:
|
||||||
case tk
|
case tk
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state.add(stateExpectColon)
|
my.state.add(stateExpectColon)
|
||||||
my.kind = JsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state.add(stateExpectColon)
|
my.state.add(stateExpectColon)
|
||||||
my.state.add(stateArray)
|
my.state.add(stateArray)
|
||||||
my.kind = jsonArrayStart
|
my.kind = jsonArrayStart
|
||||||
|
|
@ -457,7 +457,7 @@ proc next*(my: var JsonParser) =
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state.add(stateExpectArrayComma) # expect value next!
|
my.state.add(stateExpectArrayComma) # expect value next!
|
||||||
my.kind = JsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state.add(stateExpectArrayComma)
|
my.state.add(stateExpectArrayComma)
|
||||||
my.state.add(stateArray)
|
my.state.add(stateArray)
|
||||||
my.kind = jsonArrayStart
|
my.kind = jsonArrayStart
|
||||||
|
|
@ -472,8 +472,8 @@ proc next*(my: var JsonParser) =
|
||||||
my.kind = jsonError
|
my.kind = jsonError
|
||||||
my.err = errBracketRiExpected
|
my.err = errBracketRiExpected
|
||||||
of stateExpectArrayComma:
|
of stateExpectArrayComma:
|
||||||
case tk
|
case tk
|
||||||
of tkComma:
|
of tkComma:
|
||||||
discard my.state.pop()
|
discard my.state.pop()
|
||||||
next(my)
|
next(my)
|
||||||
of tkBracketRi:
|
of tkBracketRi:
|
||||||
|
|
@ -484,8 +484,8 @@ proc next*(my: var JsonParser) =
|
||||||
my.kind = jsonError
|
my.kind = jsonError
|
||||||
my.err = errBracketRiExpected
|
my.err = errBracketRiExpected
|
||||||
of stateExpectObjectComma:
|
of stateExpectObjectComma:
|
||||||
case tk
|
case tk
|
||||||
of tkComma:
|
of tkComma:
|
||||||
discard my.state.pop()
|
discard my.state.pop()
|
||||||
next(my)
|
next(my)
|
||||||
of tkCurlyRi:
|
of tkCurlyRi:
|
||||||
|
|
@ -495,9 +495,9 @@ proc next*(my: var JsonParser) =
|
||||||
else:
|
else:
|
||||||
my.kind = jsonError
|
my.kind = jsonError
|
||||||
my.err = errCurlyRiExpected
|
my.err = errCurlyRiExpected
|
||||||
of stateExpectColon:
|
of stateExpectColon:
|
||||||
case tk
|
case tk
|
||||||
of tkColon:
|
of tkColon:
|
||||||
my.state[i] = stateExpectValue
|
my.state[i] = stateExpectValue
|
||||||
next(my)
|
next(my)
|
||||||
else:
|
else:
|
||||||
|
|
@ -508,7 +508,7 @@ proc next*(my: var JsonParser) =
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state[i] = stateExpectObjectComma
|
my.state[i] = stateExpectObjectComma
|
||||||
my.kind = JsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state[i] = stateExpectObjectComma
|
my.state[i] = stateExpectObjectComma
|
||||||
my.state.add(stateArray)
|
my.state.add(stateArray)
|
||||||
my.kind = jsonArrayStart
|
my.kind = jsonArrayStart
|
||||||
|
|
@ -532,8 +532,8 @@ type
|
||||||
JString,
|
JString,
|
||||||
JObject,
|
JObject,
|
||||||
JArray
|
JArray
|
||||||
|
|
||||||
JsonNode* = ref JsonNodeObj ## JSON node
|
JsonNode* = ref JsonNodeObj ## JSON node
|
||||||
JsonNodeObj* {.acyclic.} = object
|
JsonNodeObj* {.acyclic.} = object
|
||||||
case kind*: JsonNodeKind
|
case kind*: JsonNodeKind
|
||||||
of JString:
|
of JString:
|
||||||
|
|
@ -644,7 +644,7 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
|
||||||
newSeq(result.elems, elements.len)
|
newSeq(result.elems, elements.len)
|
||||||
for i, p in pairs(elements): result.elems[i] = p
|
for i, p in pairs(elements): result.elems[i] = p
|
||||||
|
|
||||||
proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
|
proc toJson(x: NimNode): NimNode {.compiletime.} =
|
||||||
case x.kind
|
case x.kind
|
||||||
of nnkBracket:
|
of nnkBracket:
|
||||||
result = newNimNode(nnkBracket)
|
result = newNimNode(nnkBracket)
|
||||||
|
|
@ -672,7 +672,7 @@ proc `==`* (a,b: JsonNode): bool =
|
||||||
if a.isNil:
|
if a.isNil:
|
||||||
if b.isNil: return true
|
if b.isNil: return true
|
||||||
return false
|
return false
|
||||||
elif b.isNil or a.kind != b.kind:
|
elif b.isNil or a.kind != b.kind:
|
||||||
return false
|
return false
|
||||||
else:
|
else:
|
||||||
return case a.kind
|
return case a.kind
|
||||||
|
|
@ -709,7 +709,7 @@ proc hash* (n:JsonNode): THash =
|
||||||
of JNull:
|
of JNull:
|
||||||
result = hash(0)
|
result = hash(0)
|
||||||
|
|
||||||
proc len*(n: JsonNode): int =
|
proc len*(n: JsonNode): int =
|
||||||
## If `n` is a `JArray`, it returns the number of elements.
|
## If `n` is a `JArray`, it returns the number of elements.
|
||||||
## If `n` is a `JObject`, it returns the number of pairs.
|
## If `n` is a `JObject`, it returns the number of pairs.
|
||||||
## Else it returns 0.
|
## Else it returns 0.
|
||||||
|
|
@ -727,7 +727,7 @@ proc `[]`*(node: JsonNode, name: string): JsonNode =
|
||||||
if key == name:
|
if key == name:
|
||||||
return item
|
return item
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc `[]`*(node: JsonNode, index: int): JsonNode =
|
proc `[]`*(node: JsonNode, index: int): JsonNode =
|
||||||
## Gets the node at `index` in an Array. Result is undefined if `index`
|
## Gets the node at `index` in an Array. Result is undefined if `index`
|
||||||
## is out of bounds
|
## is out of bounds
|
||||||
|
|
@ -744,12 +744,12 @@ proc hasKey*(node: JsonNode, key: string): bool =
|
||||||
proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
||||||
## Deprecated for `hasKey`
|
## Deprecated for `hasKey`
|
||||||
|
|
||||||
proc add*(father, child: JsonNode) =
|
proc add*(father, child: JsonNode) =
|
||||||
## Adds `child` to a JArray node `father`.
|
## Adds `child` to a JArray node `father`.
|
||||||
assert father.kind == JArray
|
assert father.kind == JArray
|
||||||
father.elems.add(child)
|
father.elems.add(child)
|
||||||
|
|
||||||
proc add*(obj: JsonNode, key: string, val: JsonNode) =
|
proc add*(obj: JsonNode, key: string, val: JsonNode) =
|
||||||
## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
|
## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
|
||||||
## reasons no check for duplicate keys is performed!
|
## reasons no check for duplicate keys is performed!
|
||||||
## But ``[]=`` performs the check.
|
## But ``[]=`` performs the check.
|
||||||
|
|
@ -760,7 +760,7 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) =
|
||||||
## Sets a field from a `JObject`. Performs a check for duplicate keys.
|
## Sets a field from a `JObject`. Performs a check for duplicate keys.
|
||||||
assert(obj.kind == JObject)
|
assert(obj.kind == JObject)
|
||||||
for i in 0..obj.fields.len-1:
|
for i in 0..obj.fields.len-1:
|
||||||
if obj.fields[i].key == key:
|
if obj.fields[i].key == key:
|
||||||
obj.fields[i].val = val
|
obj.fields[i].val = val
|
||||||
return
|
return
|
||||||
obj.fields.add((key, val))
|
obj.fields.add((key, val))
|
||||||
|
|
@ -815,17 +815,17 @@ proc copy*(p: JsonNode): JsonNode =
|
||||||
|
|
||||||
# ------------- pretty printing ----------------------------------------------
|
# ------------- pretty printing ----------------------------------------------
|
||||||
|
|
||||||
proc indent(s: var string, i: int) =
|
proc indent(s: var string, i: int) =
|
||||||
s.add(spaces(i))
|
s.add(spaces(i))
|
||||||
|
|
||||||
proc newIndent(curr, indent: int, ml: bool): int =
|
proc newIndent(curr, indent: int, ml: bool): int =
|
||||||
if ml: return curr + indent
|
if ml: return curr + indent
|
||||||
else: return indent
|
else: return indent
|
||||||
|
|
||||||
proc nl(s: var string, ml: bool) =
|
proc nl(s: var string, ml: bool) =
|
||||||
if ml: s.add("\n")
|
if ml: s.add("\n")
|
||||||
|
|
||||||
proc escapeJson*(s: string): string =
|
proc escapeJson*(s: string): string =
|
||||||
## Converts a string `s` to its JSON representation.
|
## Converts a string `s` to its JSON representation.
|
||||||
result = newStringOfCap(s.len + s.len shr 3)
|
result = newStringOfCap(s.len + s.len shr 3)
|
||||||
result.add("\"")
|
result.add("\"")
|
||||||
|
|
@ -842,13 +842,13 @@ proc escapeJson*(s: string): string =
|
||||||
result.add(toHex(r, 4))
|
result.add(toHex(r, 4))
|
||||||
result.add("\"")
|
result.add("\"")
|
||||||
|
|
||||||
proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||||
lstArr = false, currIndent = 0) =
|
lstArr = false, currIndent = 0) =
|
||||||
case node.kind
|
case node.kind
|
||||||
of JObject:
|
of JObject:
|
||||||
if currIndent != 0 and not lstArr: result.nl(ml)
|
if currIndent != 0 and not lstArr: result.nl(ml)
|
||||||
result.indent(currIndent) # Indentation
|
result.indent(currIndent) # Indentation
|
||||||
if node.fields.len > 0:
|
if node.fields.len > 0:
|
||||||
result.add("{")
|
result.add("{")
|
||||||
result.nl(ml) # New line
|
result.nl(ml) # New line
|
||||||
for i in 0..len(node.fields)-1:
|
for i in 0..len(node.fields)-1:
|
||||||
|
|
@ -856,17 +856,17 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||||
result.add(", ")
|
result.add(", ")
|
||||||
result.nl(ml) # New Line
|
result.nl(ml) # New Line
|
||||||
# Need to indent more than {
|
# Need to indent more than {
|
||||||
result.indent(newIndent(currIndent, indent, ml))
|
result.indent(newIndent(currIndent, indent, ml))
|
||||||
result.add(escapeJson(node.fields[i].key))
|
result.add(escapeJson(node.fields[i].key))
|
||||||
result.add(": ")
|
result.add(": ")
|
||||||
toPretty(result, node.fields[i].val, indent, ml, false,
|
toPretty(result, node.fields[i].val, indent, ml, false,
|
||||||
newIndent(currIndent, indent, ml))
|
newIndent(currIndent, indent, ml))
|
||||||
result.nl(ml)
|
result.nl(ml)
|
||||||
result.indent(currIndent) # indent the same as {
|
result.indent(currIndent) # indent the same as {
|
||||||
result.add("}")
|
result.add("}")
|
||||||
else:
|
else:
|
||||||
result.add("{}")
|
result.add("{}")
|
||||||
of JString:
|
of JString:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add(escapeJson(node.str))
|
result.add(escapeJson(node.str))
|
||||||
of JInt:
|
of JInt:
|
||||||
|
|
@ -934,11 +934,11 @@ iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] =
|
||||||
for keyVal in mitems(node.fields):
|
for keyVal in mitems(node.fields):
|
||||||
yield keyVal
|
yield keyVal
|
||||||
|
|
||||||
proc eat(p: var JsonParser, tok: TTokKind) =
|
proc eat(p: var JsonParser, tok: TTokKind) =
|
||||||
if p.tok == tok: discard getTok(p)
|
if p.tok == tok: discard getTok(p)
|
||||||
else: raiseParseErr(p, tokToStr[tok])
|
else: raiseParseErr(p, tokToStr[tok])
|
||||||
|
|
||||||
proc parseJson(p: var JsonParser): JsonNode =
|
proc parseJson(p: var JsonParser): JsonNode =
|
||||||
## Parses JSON from a JSON Parser `p`.
|
## Parses JSON from a JSON Parser `p`.
|
||||||
case p.tok
|
case p.tok
|
||||||
of tkString:
|
of tkString:
|
||||||
|
|
@ -955,17 +955,17 @@ proc parseJson(p: var JsonParser): JsonNode =
|
||||||
of tkTrue:
|
of tkTrue:
|
||||||
result = newJBool(true)
|
result = newJBool(true)
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
of tkFalse:
|
of tkFalse:
|
||||||
result = newJBool(false)
|
result = newJBool(false)
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
of tkNull:
|
of tkNull:
|
||||||
result = newJNull()
|
result = newJNull()
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
of tkCurlyLe:
|
of tkCurlyLe:
|
||||||
result = newJObject()
|
result = newJObject()
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
while p.tok != tkCurlyRi:
|
while p.tok != tkCurlyRi:
|
||||||
if p.tok != tkString:
|
if p.tok != tkString:
|
||||||
raiseParseErr(p, "string literal as key expected")
|
raiseParseErr(p, "string literal as key expected")
|
||||||
var key = p.a
|
var key = p.a
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
|
|
@ -978,7 +978,7 @@ proc parseJson(p: var JsonParser): JsonNode =
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
result = newJArray()
|
result = newJArray()
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
while p.tok != tkBracketRi:
|
while p.tok != tkBracketRi:
|
||||||
result.add(parseJson(p))
|
result.add(parseJson(p))
|
||||||
if p.tok != tkComma: break
|
if p.tok != tkComma: break
|
||||||
discard getTok(p)
|
discard getTok(p)
|
||||||
|
|
@ -1098,10 +1098,10 @@ when false:
|
||||||
of jsonObjectEnd: echo("}")
|
of jsonObjectEnd: echo("}")
|
||||||
of jsonArrayStart: echo("[")
|
of jsonArrayStart: echo("[")
|
||||||
of jsonArrayEnd: echo("]")
|
of jsonArrayEnd: echo("]")
|
||||||
|
|
||||||
close(x)
|
close(x)
|
||||||
|
|
||||||
# { "json": 5 }
|
# { "json": 5 }
|
||||||
# To get that we shall use, obj["json"]
|
# To get that we shall use, obj["json"]
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ type
|
||||||
|
|
||||||
{.deprecated: [TTestStatus: TestStatus, TOutputLevel: OutputLevel]}
|
{.deprecated: [TTestStatus: TestStatus, TOutputLevel: OutputLevel]}
|
||||||
|
|
||||||
var
|
var
|
||||||
abortOnError* {.threadvar.}: bool
|
abortOnError* {.threadvar.}: bool
|
||||||
outputLevel* {.threadvar.}: OutputLevel
|
outputLevel* {.threadvar.}: OutputLevel
|
||||||
colorOutput* {.threadvar.}: bool
|
colorOutput* {.threadvar.}: bool
|
||||||
|
|
@ -144,7 +144,7 @@ macro check*(conditions: stmt): stmt {.immediate.} =
|
||||||
when compiles(string($value)):
|
when compiles(string($value)):
|
||||||
checkpoint(name & " was " & $value)
|
checkpoint(name & " was " & $value)
|
||||||
|
|
||||||
proc inspectArgs(exp: PNimrodNode) =
|
proc inspectArgs(exp: NimNode) =
|
||||||
for i in 1 .. <exp.len:
|
for i in 1 .. <exp.len:
|
||||||
if exp[i].kind notin nnkLiterals:
|
if exp[i].kind notin nnkLiterals:
|
||||||
inc counter
|
inc counter
|
||||||
|
|
@ -202,7 +202,7 @@ template require*(conditions: stmt): stmt {.immediate, dirty.} =
|
||||||
macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
|
macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
|
||||||
let exp = callsite()
|
let exp = callsite()
|
||||||
template expectBody(errorTypes, lineInfoLit: expr,
|
template expectBody(errorTypes, lineInfoLit: expr,
|
||||||
body: stmt): PNimrodNode {.dirty.} =
|
body: stmt): NimNode {.dirty.} =
|
||||||
try:
|
try:
|
||||||
body
|
body
|
||||||
checkpoint(lineInfoLit & ": Expect Failed, no exception was thrown.")
|
checkpoint(lineInfoLit & ": Expect Failed, no exception was thrown.")
|
||||||
|
|
|
||||||
|
|
@ -12,20 +12,20 @@
|
||||||
import macros, strtabs
|
import macros, strtabs
|
||||||
|
|
||||||
type
|
type
|
||||||
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s.
|
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s.
|
||||||
|
|
||||||
XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s
|
XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s
|
||||||
xnText, ## a text element
|
xnText, ## a text element
|
||||||
xnElement, ## an element with 0 or more children
|
xnElement, ## an element with 0 or more children
|
||||||
xnCData, ## a CDATA node
|
xnCData, ## a CDATA node
|
||||||
xnEntity, ## an entity (like ``&thing;``)
|
xnEntity, ## an entity (like ``&thing;``)
|
||||||
xnComment ## an XML comment
|
xnComment ## an XML comment
|
||||||
|
|
||||||
XmlAttributes* = StringTableRef ## an alias for a string to string mapping
|
XmlAttributes* = StringTableRef ## an alias for a string to string mapping
|
||||||
|
|
||||||
XmlNodeObj {.acyclic.} = object
|
XmlNodeObj {.acyclic.} = object
|
||||||
case k: XmlNodeKind # private, use the kind() proc to read this field.
|
case k: XmlNodeKind # private, use the kind() proc to read this field.
|
||||||
of xnText, xnComment, xnCData, xnEntity:
|
of xnText, xnComment, xnCData, xnEntity:
|
||||||
fText: string
|
fText: string
|
||||||
of xnElement:
|
of xnElement:
|
||||||
fTag: string
|
fTag: string
|
||||||
|
|
@ -41,34 +41,34 @@ proc newXmlNode(kind: XmlNodeKind): XmlNode =
|
||||||
new(result)
|
new(result)
|
||||||
result.k = kind
|
result.k = kind
|
||||||
|
|
||||||
proc newElement*(tag: string): XmlNode =
|
proc newElement*(tag: string): XmlNode =
|
||||||
## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`.
|
## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`.
|
||||||
result = newXmlNode(xnElement)
|
result = newXmlNode(xnElement)
|
||||||
result.fTag = tag
|
result.fTag = tag
|
||||||
result.s = @[]
|
result.s = @[]
|
||||||
# init attributes lazily to safe memory
|
# init attributes lazily to safe memory
|
||||||
|
|
||||||
proc newText*(text: string): XmlNode =
|
proc newText*(text: string): XmlNode =
|
||||||
## creates a new ``PXmlNode`` of kind ``xnText`` with the text `text`.
|
## creates a new ``PXmlNode`` of kind ``xnText`` with the text `text`.
|
||||||
result = newXmlNode(xnText)
|
result = newXmlNode(xnText)
|
||||||
result.fText = text
|
result.fText = text
|
||||||
|
|
||||||
proc newComment*(comment: string): XmlNode =
|
proc newComment*(comment: string): XmlNode =
|
||||||
## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `comment`.
|
## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `comment`.
|
||||||
result = newXmlNode(xnComment)
|
result = newXmlNode(xnComment)
|
||||||
result.fText = comment
|
result.fText = comment
|
||||||
|
|
||||||
proc newCData*(cdata: string): XmlNode =
|
proc newCData*(cdata: string): XmlNode =
|
||||||
## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `cdata`.
|
## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `cdata`.
|
||||||
result = newXmlNode(xnCData)
|
result = newXmlNode(xnCData)
|
||||||
result.fText = cdata
|
result.fText = cdata
|
||||||
|
|
||||||
proc newEntity*(entity: string): XmlNode =
|
proc newEntity*(entity: string): XmlNode =
|
||||||
## creates a new ``PXmlNode`` of kind ``xnEntity`` with the text `entity`.
|
## creates a new ``PXmlNode`` of kind ``xnEntity`` with the text `entity`.
|
||||||
result = newXmlNode(xnCData)
|
result = newXmlNode(xnCData)
|
||||||
result.fText = entity
|
result.fText = entity
|
||||||
|
|
||||||
proc text*(n: XmlNode): string {.inline.} =
|
proc text*(n: XmlNode): string {.inline.} =
|
||||||
## gets the associated text with the node `n`. `n` can be a CDATA, Text,
|
## gets the associated text with the node `n`. `n` can be a CDATA, Text,
|
||||||
## comment, or entity node.
|
## comment, or entity node.
|
||||||
assert n.k in {xnText, xnComment, xnCData, xnEntity}
|
assert n.k in {xnText, xnComment, xnCData, xnEntity}
|
||||||
|
|
@ -93,16 +93,16 @@ proc innerText*(n: XmlNode): string =
|
||||||
for i in 0 .. n.s.len-1:
|
for i in 0 .. n.s.len-1:
|
||||||
if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText)
|
if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText)
|
||||||
|
|
||||||
proc tag*(n: XmlNode): string {.inline.} =
|
proc tag*(n: XmlNode): string {.inline.} =
|
||||||
## gets the tag name of `n`. `n` has to be an ``xnElement`` node.
|
## gets the tag name of `n`. `n` has to be an ``xnElement`` node.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
result = n.fTag
|
result = n.fTag
|
||||||
|
|
||||||
proc add*(father, son: XmlNode) {.inline.} =
|
proc add*(father, son: XmlNode) {.inline.} =
|
||||||
## adds the child `son` to `father`.
|
## adds the child `son` to `father`.
|
||||||
add(father.s, son)
|
add(father.s, son)
|
||||||
|
|
||||||
proc len*(n: XmlNode): int {.inline.} =
|
proc len*(n: XmlNode): int {.inline.} =
|
||||||
## returns the number `n`'s children.
|
## returns the number `n`'s children.
|
||||||
if n.k == xnElement: result = len(n.s)
|
if n.k == xnElement: result = len(n.s)
|
||||||
|
|
||||||
|
|
@ -110,38 +110,38 @@ proc kind*(n: XmlNode): XmlNodeKind {.inline.} =
|
||||||
## returns `n`'s kind.
|
## returns `n`'s kind.
|
||||||
result = n.k
|
result = n.k
|
||||||
|
|
||||||
proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} =
|
proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} =
|
||||||
## returns the `i`'th child of `n`.
|
## returns the `i`'th child of `n`.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
result = n.s[i]
|
result = n.s[i]
|
||||||
|
|
||||||
proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} =
|
proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} =
|
||||||
## returns the `i`'th child of `n` so that it can be modified
|
## returns the `i`'th child of `n` so that it can be modified
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
result = n.s[i]
|
result = n.s[i]
|
||||||
|
|
||||||
iterator items*(n: XmlNode): XmlNode {.inline.} =
|
iterator items*(n: XmlNode): XmlNode {.inline.} =
|
||||||
## iterates over any child of `n`.
|
## iterates over any child of `n`.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
for i in 0 .. n.len-1: yield n[i]
|
for i in 0 .. n.len-1: yield n[i]
|
||||||
|
|
||||||
iterator mitems*(n: var XmlNode): var XmlNode {.inline.} =
|
iterator mitems*(n: var XmlNode): var XmlNode {.inline.} =
|
||||||
## iterates over any child of `n`.
|
## iterates over any child of `n`.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
for i in 0 .. n.len-1: yield mget(n, i)
|
for i in 0 .. n.len-1: yield mget(n, i)
|
||||||
|
|
||||||
proc attrs*(n: XmlNode): XmlAttributes {.inline.} =
|
proc attrs*(n: XmlNode): XmlAttributes {.inline.} =
|
||||||
## gets the attributes belonging to `n`.
|
## gets the attributes belonging to `n`.
|
||||||
## Returns `nil` if attributes have not been initialised for this node.
|
## Returns `nil` if attributes have not been initialised for this node.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
result = n.fAttr
|
result = n.fAttr
|
||||||
|
|
||||||
proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} =
|
proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} =
|
||||||
## sets the attributes belonging to `n`.
|
## sets the attributes belonging to `n`.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
n.fAttr = attr
|
n.fAttr = attr
|
||||||
|
|
||||||
proc attrsLen*(n: XmlNode): int {.inline.} =
|
proc attrsLen*(n: XmlNode): int {.inline.} =
|
||||||
## returns the number of `n`'s attributes.
|
## returns the number of `n`'s attributes.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
if not isNil(n.fAttr): result = len(n.fAttr)
|
if not isNil(n.fAttr): result = len(n.fAttr)
|
||||||
|
|
@ -151,12 +151,12 @@ proc clientData*(n: XmlNode): int {.inline.} =
|
||||||
## parser and generator.
|
## parser and generator.
|
||||||
result = n.fClientData
|
result = n.fClientData
|
||||||
|
|
||||||
proc `clientData=`*(n: XmlNode, data: int) {.inline.} =
|
proc `clientData=`*(n: XmlNode, data: int) {.inline.} =
|
||||||
## sets the client data of `n`. The client data field is used by the HTML
|
## sets the client data of `n`. The client data field is used by the HTML
|
||||||
## parser and generator.
|
## parser and generator.
|
||||||
n.fClientData = data
|
n.fClientData = data
|
||||||
|
|
||||||
proc addEscaped*(result: var string, s: string) =
|
proc addEscaped*(result: var string, s: string) =
|
||||||
## same as ``result.add(escape(s))``, but more efficient.
|
## same as ``result.add(escape(s))``, but more efficient.
|
||||||
for c in items(s):
|
for c in items(s):
|
||||||
case c
|
case c
|
||||||
|
|
@ -168,8 +168,8 @@ proc addEscaped*(result: var string, s: string) =
|
||||||
of '/': result.add("/")
|
of '/': result.add("/")
|
||||||
else: result.add(c)
|
else: result.add(c)
|
||||||
|
|
||||||
proc escape*(s: string): string =
|
proc escape*(s: string): string =
|
||||||
## escapes `s` for inclusion into an XML document.
|
## escapes `s` for inclusion into an XML document.
|
||||||
## Escapes these characters:
|
## Escapes these characters:
|
||||||
##
|
##
|
||||||
## ------------ -------------------
|
## ------------ -------------------
|
||||||
|
|
@ -184,26 +184,26 @@ proc escape*(s: string): string =
|
||||||
## ------------ -------------------
|
## ------------ -------------------
|
||||||
result = newStringOfCap(s.len)
|
result = newStringOfCap(s.len)
|
||||||
addEscaped(result, s)
|
addEscaped(result, s)
|
||||||
|
|
||||||
proc addIndent(result: var string, indent: int) =
|
proc addIndent(result: var string, indent: int) =
|
||||||
result.add("\n")
|
result.add("\n")
|
||||||
for i in 1..indent: result.add(' ')
|
for i in 1..indent: result.add(' ')
|
||||||
|
|
||||||
proc noWhitespace(n: XmlNode): bool =
|
proc noWhitespace(n: XmlNode): bool =
|
||||||
#for i in 1..n.len-1:
|
#for i in 1..n.len-1:
|
||||||
# if n[i].kind != n[0].kind: return true
|
# if n[i].kind != n[0].kind: return true
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
if n[i].kind in {xnText, xnEntity}: return true
|
if n[i].kind in {xnText, xnEntity}: return true
|
||||||
|
|
||||||
proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||||
## adds the textual representation of `n` to `result`.
|
## adds the textual representation of `n` to `result`.
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
case n.k
|
case n.k
|
||||||
of xnElement:
|
of xnElement:
|
||||||
result.add('<')
|
result.add('<')
|
||||||
result.add(n.fTag)
|
result.add(n.fTag)
|
||||||
if not isNil(n.fAttr):
|
if not isNil(n.fAttr):
|
||||||
for key, val in pairs(n.fAttr):
|
for key, val in pairs(n.fAttr):
|
||||||
result.add(' ')
|
result.add(' ')
|
||||||
result.add(key)
|
result.add(key)
|
||||||
result.add("=\"")
|
result.add("=\"")
|
||||||
|
|
@ -217,7 +217,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||||
# because this would be wrong. For example: ``a<b>b</b>`` is
|
# because this would be wrong. For example: ``a<b>b</b>`` is
|
||||||
# different from ``a <b>b</b>``.
|
# different from ``a <b>b</b>``.
|
||||||
for i in 0..n.len-1: result.add(n[i], indent+indWidth, indWidth)
|
for i in 0..n.len-1: result.add(n[i], indent+indWidth, indWidth)
|
||||||
else:
|
else:
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
result.addIndent(indent+indWidth)
|
result.addIndent(indent+indWidth)
|
||||||
result.add(n[i], indent+indWidth, indWidth)
|
result.add(n[i], indent+indWidth, indWidth)
|
||||||
|
|
@ -227,7 +227,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||||
result.add("</")
|
result.add("</")
|
||||||
result.add(n.fTag)
|
result.add(n.fTag)
|
||||||
result.add(">")
|
result.add(">")
|
||||||
else:
|
else:
|
||||||
result.add(" />")
|
result.add(" />")
|
||||||
of xnText:
|
of xnText:
|
||||||
result.addEscaped(n.fText)
|
result.addEscaped(n.fText)
|
||||||
|
|
@ -245,7 +245,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||||
result.add(';')
|
result.add(';')
|
||||||
|
|
||||||
const
|
const
|
||||||
xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||||
## header to use for complete XML output
|
## header to use for complete XML output
|
||||||
|
|
||||||
proc `$`*(n: XmlNode): string =
|
proc `$`*(n: XmlNode): string =
|
||||||
|
|
@ -255,21 +255,21 @@ proc `$`*(n: XmlNode): string =
|
||||||
result.add(n)
|
result.add(n)
|
||||||
|
|
||||||
proc newXmlTree*(tag: string, children: openArray[XmlNode],
|
proc newXmlTree*(tag: string, children: openArray[XmlNode],
|
||||||
attributes: XmlAttributes = nil): XmlNode =
|
attributes: XmlAttributes = nil): XmlNode =
|
||||||
## creates a new XML tree with `tag`, `children` and `attributes`
|
## creates a new XML tree with `tag`, `children` and `attributes`
|
||||||
result = newXmlNode(xnElement)
|
result = newXmlNode(xnElement)
|
||||||
result.fTag = tag
|
result.fTag = tag
|
||||||
newSeq(result.s, children.len)
|
newSeq(result.s, children.len)
|
||||||
for i in 0..children.len-1: result.s[i] = children[i]
|
for i in 0..children.len-1: result.s[i] = children[i]
|
||||||
result.fAttr = attributes
|
result.fAttr = attributes
|
||||||
|
|
||||||
proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc xmlConstructor(e: NimNode): NimNode {.compileTime.} =
|
||||||
expectLen(e, 2)
|
expectLen(e, 2)
|
||||||
var a = e[1]
|
var a = e[1]
|
||||||
if a.kind == nnkCall:
|
if a.kind == nnkCall:
|
||||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||||
var attrs = newNimNode(nnkBracket, a)
|
var attrs = newNimNode(nnkBracket, a)
|
||||||
var newStringTabCall = newCall("newStringTable", attrs,
|
var newStringTabCall = newCall("newStringTable", attrs,
|
||||||
newIdentNode("modeCaseSensitive"))
|
newIdentNode("modeCaseSensitive"))
|
||||||
var elements = newNimNode(nnkBracket, a)
|
var elements = newNimNode(nnkBracket, a)
|
||||||
for i in 1..a.len-1:
|
for i in 1..a.len-1:
|
||||||
|
|
@ -280,13 +280,13 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
else:
|
else:
|
||||||
elements.add(a[i])
|
elements.add(a[i])
|
||||||
result.add(elements)
|
result.add(elements)
|
||||||
if attrs.len > 1:
|
if attrs.len > 1:
|
||||||
#echo repr(newStringTabCall)
|
#echo repr(newStringTabCall)
|
||||||
result.add(newStringTabCall)
|
result.add(newStringTabCall)
|
||||||
else:
|
else:
|
||||||
result = newCall("newXmlTree", toStrLit(a))
|
result = newCall("newXmlTree", toStrLit(a))
|
||||||
|
|
||||||
macro `<>`*(x: expr): expr {.immediate.} =
|
macro `<>`*(x: expr): expr {.immediate.} =
|
||||||
## Constructor macro for XML. Example usage:
|
## Constructor macro for XML. Example usage:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
|
|
|
||||||
|
|
@ -3149,15 +3149,9 @@ proc shallow*(s: var string) {.noSideEffect, inline.} =
|
||||||
type
|
type
|
||||||
NimNodeObj = object
|
NimNodeObj = object
|
||||||
|
|
||||||
when defined(nimnode):
|
NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
|
||||||
type
|
## represents a Nim AST node. Macros operate on this type.
|
||||||
NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
|
{.deprecated: [PNimrodNode: NimNode].}
|
||||||
## represents a Nim AST node. Macros operate on this type.
|
|
||||||
{.deprecated: [PNimrodNode: NimNode].}
|
|
||||||
else:
|
|
||||||
type
|
|
||||||
PNimrodNode* {.magic: "PNimrodNode".} = ref NimNodeObj
|
|
||||||
## represents a Nim AST node. Macros operate on this type.
|
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
template eval*(blk: stmt): stmt =
|
template eval*(blk: stmt): stmt =
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
|
||||||
## Expect docstrings
|
## Expect docstrings
|
||||||
let exp = callsite()
|
let exp = callsite()
|
||||||
template expectBody(errorTypes, lineInfoLit: expr,
|
template expectBody(errorTypes, lineInfoLit: expr,
|
||||||
body: stmt): PNimrodNode {.dirty.} =
|
body: stmt): NimNode {.dirty.} =
|
||||||
try:
|
try:
|
||||||
body
|
body
|
||||||
assert false
|
assert false
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ import strutils
|
||||||
# This serves the same purpose as D's `alias` parameters for types, used heavily
|
# This serves the same purpose as D's `alias` parameters for types, used heavily
|
||||||
# in its popular `ranges` and `algorithm` modules.
|
# in its popular `ranges` and `algorithm` modules.
|
||||||
|
|
||||||
var exprNodes {.compileTime.} = newSeq[PNimrodNode]()
|
var exprNodes {.compileTime.} = newSeq[NimNode]()
|
||||||
|
|
||||||
proc refExpr(exprNode: PNimrodNode): string {.compileTime.} =
|
proc refExpr(exprNode: NimNode): string {.compileTime.} =
|
||||||
exprNodes.add exprNode.copy
|
exprNodes.add exprNode.copy
|
||||||
"expr" & $(exprNodes.len - 1)
|
"expr" & $(exprNodes.len - 1)
|
||||||
|
|
||||||
proc derefExpr(exprRef: string): PNimrodNode {.compileTime.} =
|
proc derefExpr(exprRef: string): NimNode {.compileTime.} =
|
||||||
exprNodes[parseInt(exprRef[4 .. -1])]
|
exprNodes[parseInt(exprRef[4 .. -1])]
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,13 @@ echotest()
|
||||||
|
|
||||||
# bug #1103
|
# bug #1103
|
||||||
|
|
||||||
type
|
type
|
||||||
Td = tuple
|
Td = tuple
|
||||||
a:string
|
a:string
|
||||||
b:int
|
b:int
|
||||||
|
|
||||||
proc get_data(d: Td) : string {.compileTime.} =
|
proc get_data(d: Td) : string {.compileTime.} =
|
||||||
result = d.a # Works if a literal string is used here.
|
result = d.a # Works if a literal string is used here.
|
||||||
# Bugs if line A or B is active. Works with C
|
# Bugs if line A or B is active. Works with C
|
||||||
result &= "aa" # A
|
result &= "aa" # A
|
||||||
#result.add("aa") # B
|
#result.add("aa") # B
|
||||||
|
|
@ -69,7 +69,7 @@ m(s)
|
||||||
|
|
||||||
# bug #933
|
# bug #933
|
||||||
|
|
||||||
proc nilcheck(): PNimrodNode {.compileTime.} =
|
proc nilcheck(): NimNode {.compileTime.} =
|
||||||
echo(result == nil) # true
|
echo(result == nil) # true
|
||||||
echo(result.isNil) # true
|
echo(result.isNil) # true
|
||||||
echo(repr(result)) # nil
|
echo(repr(result)) # nil
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Dump the contents of a PNimrodNode
|
# Dump the contents of a NimNode
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
|
|
@ -7,7 +7,7 @@ template plus(a, b: expr): expr {.dirty} =
|
||||||
|
|
||||||
macro call(e: expr): expr =
|
macro call(e: expr): expr =
|
||||||
result = newCall("foo", newStrLitNode("bar"))
|
result = newCall("foo", newStrLitNode("bar"))
|
||||||
|
|
||||||
macro dumpAST(n: stmt): stmt {.immediate.} =
|
macro dumpAST(n: stmt): stmt {.immediate.} =
|
||||||
# dump AST as a side-effect and return the inner node
|
# dump AST as a side-effect and return the inner node
|
||||||
let n = callsite()
|
let n = callsite()
|
||||||
|
|
@ -24,10 +24,10 @@ macro dumpAST(n: stmt): stmt {.immediate.} =
|
||||||
echo e.lispRepr
|
echo e.lispRepr
|
||||||
|
|
||||||
result = n[1]
|
result = n[1]
|
||||||
|
|
||||||
dumpAST:
|
dumpAST:
|
||||||
proc add(x, y: int): int =
|
proc add(x, y: int): int =
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
proc sub(x, y: int): int = return x - y
|
proc sub(x, y: int): int = return x - y
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
# Dump the contents of a PNimrodNode
|
# Dump the contents of a NimNode
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
proc dumpit(n: PNimrodNode): string {.compileTime.} =
|
proc dumpit(n: NimNode): string {.compileTime.} =
|
||||||
if n == nil: return "nil"
|
if n == nil: return "nil"
|
||||||
result = $n.kind
|
result = $n.kind
|
||||||
add(result, "(")
|
add(result, "(")
|
||||||
case n.kind
|
case n.kind
|
||||||
of nnkEmpty: discard # same as nil node in this representation
|
of nnkEmpty: discard # same as nil node in this representation
|
||||||
of nnkNilLit: add(result, "nil")
|
of nnkNilLit: add(result, "nil")
|
||||||
of nnkCharLit..nnkInt64Lit: add(result, $n.intVal)
|
of nnkCharLit..nnkInt64Lit: add(result, $n.intVal)
|
||||||
of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal)
|
of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal)
|
||||||
|
|
@ -20,17 +20,17 @@ proc dumpit(n: PNimrodNode): string {.compileTime.} =
|
||||||
add(result, ", ")
|
add(result, ", ")
|
||||||
add(result, dumpit(n[j]))
|
add(result, dumpit(n[j]))
|
||||||
add(result, ")")
|
add(result, ")")
|
||||||
|
|
||||||
macro dumpAST(n: stmt): stmt {.immediate.} =
|
macro dumpAST(n: stmt): stmt {.immediate.} =
|
||||||
# dump AST as a side-effect and return the inner node
|
# dump AST as a side-effect and return the inner node
|
||||||
let n = callsite()
|
let n = callsite()
|
||||||
echo dumpit(n)
|
echo dumpit(n)
|
||||||
result = n[1]
|
result = n[1]
|
||||||
|
|
||||||
dumpAST:
|
dumpAST:
|
||||||
proc add(x, y: int): int =
|
proc add(x, y: int): int =
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
proc sub(x, y: int): int = return x - y
|
proc sub(x, y: int): int = return x - y
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import rawsockets, asyncdispatch, macros
|
||||||
var p = newDispatcher()
|
var p = newDispatcher()
|
||||||
var sock = newAsyncRawSocket()
|
var sock = newAsyncRawSocket()
|
||||||
|
|
||||||
proc convertReturns(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkReturnStmt:
|
of nnkReturnStmt:
|
||||||
result = newCall(newIdentNode("complete"), retFutureSym, node[0])
|
result = newCall(newIdentNode("complete"), retFutureSym, node[0])
|
||||||
|
|
@ -19,19 +19,19 @@ macro async2(prc: stmt): stmt {.immediate.} =
|
||||||
# -> var retFuture = newFuture[T]()
|
# -> var retFuture = newFuture[T]()
|
||||||
var retFutureSym = newIdentNode("retFuture") #genSym(nskVar, "retFuture")
|
var retFutureSym = newIdentNode("retFuture") #genSym(nskVar, "retFuture")
|
||||||
outerProcBody.add(
|
outerProcBody.add(
|
||||||
newVarStmt(retFutureSym,
|
newVarStmt(retFutureSym,
|
||||||
newCall(
|
newCall(
|
||||||
newNimNode(nnkBracketExpr).add(
|
newNimNode(nnkBracketExpr).add(
|
||||||
newIdentNode("newFuture"),
|
newIdentNode("newFuture"),
|
||||||
prc[3][0][1])))) # Get type from return type of this proc.
|
prc[3][0][1])))) # Get type from return type of this proc.
|
||||||
|
|
||||||
# -> iterator nameIter(): PFutureBase {.closure.} = <proc_body>
|
# -> iterator nameIter(): FutureBase {.closure.} = <proc_body>
|
||||||
# Changing this line to: newIdentNode($prc[0].ident & "Iter") # will make it work.
|
# Changing this line to: newIdentNode($prc[0].ident & "Iter") # will make it work.
|
||||||
var iteratorNameSym = genSym(nskIterator, $prc[0].ident & "Iter")
|
var iteratorNameSym = genSym(nskIterator, $prc[0].ident & "Iter")
|
||||||
#var iteratorNameSym = newIdentNode($prc[0].ident & "Iter")
|
#var iteratorNameSym = newIdentNode($prc[0].ident & "Iter")
|
||||||
var procBody = prc[6].convertReturns(retFutureSym)
|
var procBody = prc[6].convertReturns(retFutureSym)
|
||||||
|
|
||||||
var closureIterator = newProc(iteratorNameSym, [newIdentNode("PFutureBase")],
|
var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")],
|
||||||
procBody, nnkIteratorDef)
|
procBody, nnkIteratorDef)
|
||||||
closureIterator[4] = newNimNode(nnkPragma).add(newIdentNode("closure"))
|
closureIterator[4] = newNimNode(nnkPragma).add(newIdentNode("closure"))
|
||||||
outerProcBody.add(closureIterator)
|
outerProcBody.add(closureIterator)
|
||||||
|
|
@ -55,8 +55,8 @@ macro async2(prc: stmt): stmt {.immediate.} =
|
||||||
|
|
||||||
result[6] = outerProcBody
|
result[6] = outerProcBody
|
||||||
|
|
||||||
proc readStuff(): PFuture[string] {.async2.} =
|
proc readStuff(): Future[string] {.async2.} =
|
||||||
var fut = connect(sock, "irc.freenode.org", TPort(6667))
|
var fut = connect(sock, "irc.freenode.org", Port(6667))
|
||||||
yield fut
|
yield fut
|
||||||
var fut2 = recv(sock, 50)
|
var fut2 = recv(sock, 50)
|
||||||
yield fut2
|
yield fut2
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import parseutils, macros
|
import parseutils, macros
|
||||||
|
|
||||||
proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool {.compiletime.} =
|
proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} =
|
||||||
var splitValue: string
|
var splitValue: string
|
||||||
var read = value.parseUntil(splitValue, '$', index)
|
var read = value.parseUntil(splitValue, '$', index)
|
||||||
|
|
||||||
|
|
@ -15,7 +15,7 @@ proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool
|
||||||
if splitValue.len > 0:
|
if splitValue.len > 0:
|
||||||
node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue))
|
node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue))
|
||||||
|
|
||||||
proc parse_template(node: PNimrodNode, value: string) {.compiletime.} =
|
proc parse_template(node: NimNode, value: string) {.compiletime.} =
|
||||||
var index = 0
|
var index = 0
|
||||||
while index < value.len and
|
while index < value.len and
|
||||||
parse_until_symbol(node, value, index): discard
|
parse_until_symbol(node, value, index): discard
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,17 @@ import macros
|
||||||
from uri import `/`
|
from uri import `/`
|
||||||
|
|
||||||
macro test*(a: stmt): stmt {.immediate.} =
|
macro test*(a: stmt): stmt {.immediate.} =
|
||||||
var nodes: tuple[a, b: int]
|
var nodes: tuple[a, b: int]
|
||||||
nodes.a = 4
|
nodes.a = 4
|
||||||
nodes[1] = 45
|
nodes[1] = 45
|
||||||
|
|
||||||
type
|
type
|
||||||
TTypeEx = object
|
TTypeEx = object
|
||||||
x, y: int
|
x, y: int
|
||||||
case b: bool
|
case b: bool
|
||||||
of false: nil
|
of false: nil
|
||||||
of true: z: float
|
of true: z: float
|
||||||
|
|
||||||
var t: TTypeEx
|
var t: TTypeEx
|
||||||
t.b = true
|
t.b = true
|
||||||
t.z = 4.5
|
t.z = 4.5
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ discard """
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
type
|
type
|
||||||
TA = tuple[a: int]
|
TA = tuple[a: int]
|
||||||
PA = ref TA
|
PA = ref TA
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ test:
|
||||||
macro test2*(a: stmt): stmt {.immediate.} =
|
macro test2*(a: stmt): stmt {.immediate.} =
|
||||||
proc testproc(recurse: int) =
|
proc testproc(recurse: int) =
|
||||||
echo "Thats weird"
|
echo "Thats weird"
|
||||||
var o : PNimrodNode = nil
|
var o : NimNode = nil
|
||||||
echo " no its not!"
|
echo " no its not!"
|
||||||
o = newNimNode(nnkNone)
|
o = newNimNode(nnkNone)
|
||||||
if recurse > 0:
|
if recurse > 0:
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import
|
||||||
|
|
||||||
macro test_macro*(n: stmt): stmt {.immediate.} =
|
macro test_macro*(n: stmt): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
var ass : PNimrodNode = newNimNode(nnkAsgn)
|
var ass : NimNode = newNimNode(nnkAsgn)
|
||||||
add(ass, newIdentNode("str"))
|
add(ass, newIdentNode("str"))
|
||||||
add(ass, newStrLitNode("after"))
|
add(ass, newStrLitNode("after"))
|
||||||
add(result, ass)
|
add(result, ass)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import macros,json
|
import macros,json
|
||||||
|
|
||||||
var decls{.compileTime.}: seq[PNimrodNode] = @[]
|
var decls{.compileTime.}: seq[NimNode] = @[]
|
||||||
var impls{.compileTime.}: seq[PNimrodNode] = @[]
|
var impls{.compileTime.}: seq[NimNode] = @[]
|
||||||
|
|
||||||
macro importImpl_forward(name, returns): stmt {.immediate.} =
|
macro importImpl_forward(name, returns): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkEmpty)
|
result = newNimNode(nnkEmpty)
|
||||||
|
|
@ -38,7 +38,7 @@ macro importImpl_forward(name, returns): stmt {.immediate.} =
|
||||||
decls.add res
|
decls.add res
|
||||||
echo(repr(res))
|
echo(repr(res))
|
||||||
|
|
||||||
macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} =
|
macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} =
|
||||||
#var res = getAST(importImpl_forward(name, returns))
|
#var res = getAST(importImpl_forward(name, returns))
|
||||||
discard getAST(importImpl_forward(name, returns))
|
discard getAST(importImpl_forward(name, returns))
|
||||||
var res = copyNimTree(decls[decls.high])
|
var res = copyNimTree(decls[decls.high])
|
||||||
|
|
@ -56,4 +56,4 @@ importImpl(Item, int):
|
||||||
importImpl(Foo, int16):
|
importImpl(Foo, int16):
|
||||||
echo 77
|
echo 77
|
||||||
|
|
||||||
okayy
|
okayy
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ macro outterMacro*(n: stmt): stmt {.immediate.} =
|
||||||
expectKind(n, TNimrodNodeKind.nnkCall)
|
expectKind(n, TNimrodNodeKind.nnkCall)
|
||||||
if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent:
|
if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent:
|
||||||
error("Macro " & callNode.repr &
|
error("Macro " & callNode.repr &
|
||||||
" requires the ident passed as parameter (eg: " & callNode.repr &
|
" requires the ident passed as parameter (eg: " & callNode.repr &
|
||||||
"(the_name_you_want)): statements.")
|
"(the_name_you_want)): statements.")
|
||||||
result = newNimNode(TNimrodNodeKind.nnkStmtList)
|
result = newNimNode(TNimrodNodeKind.nnkStmtList)
|
||||||
var ass : PNimrodNode = newNimNode(nnkAsgn)
|
var ass : NimNode = newNimNode(nnkAsgn)
|
||||||
ass.add(newIdentNode(n[1].ident))
|
ass.add(newIdentNode(n[1].ident))
|
||||||
ass.add(newStrLitNode(innerProc(4)))
|
ass.add(newStrLitNode(innerProc(4)))
|
||||||
result.add(ass)
|
result.add(ass)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ discard """
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
proc makeMacro: PNimrodNode =
|
proc makeMacro: NimNode =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
var p = makeMacro()
|
var p = makeMacro()
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ template processInterpolations(e: expr) =
|
||||||
|
|
||||||
macro formatStyleInterpolation(e: expr): expr =
|
macro formatStyleInterpolation(e: expr): expr =
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
var
|
var
|
||||||
formatString = ""
|
formatString = ""
|
||||||
arrayNode = newNimNode(nnkBracket)
|
arrayNode = newNimNode(nnkBracket)
|
||||||
idx = 1
|
idx = 1
|
||||||
|
|
@ -27,14 +27,14 @@ macro formatStyleInterpolation(e: expr): expr =
|
||||||
proc addString(s: string) =
|
proc addString(s: string) =
|
||||||
formatString.add(s)
|
formatString.add(s)
|
||||||
|
|
||||||
proc addExpr(e: PNimrodNode) =
|
proc addExpr(e: NimNode) =
|
||||||
arrayNode.add(e)
|
arrayNode.add(e)
|
||||||
formatString.add("$" & $(idx))
|
formatString.add("$" & $(idx))
|
||||||
inc idx
|
inc idx
|
||||||
|
|
||||||
proc addDollar() =
|
proc addDollar() =
|
||||||
formatString.add("$$")
|
formatString.add("$$")
|
||||||
|
|
||||||
processInterpolations(e)
|
processInterpolations(e)
|
||||||
|
|
||||||
result = parseExpr("\"x\" % [y]")
|
result = parseExpr("\"x\" % [y]")
|
||||||
|
|
@ -43,11 +43,11 @@ macro formatStyleInterpolation(e: expr): expr =
|
||||||
|
|
||||||
macro concatStyleInterpolation(e: expr): expr =
|
macro concatStyleInterpolation(e: expr): expr =
|
||||||
let e = callsite()
|
let e = callsite()
|
||||||
var args: seq[PNimrodNode]
|
var args: seq[NimNode]
|
||||||
newSeq(args, 0)
|
newSeq(args, 0)
|
||||||
|
|
||||||
proc addString(s: string) = args.add(newStrLitNode(s))
|
proc addString(s: string) = args.add(newStrLitNode(s))
|
||||||
proc addExpr(e: PNimrodNode) = args.add(e)
|
proc addExpr(e: NimNode) = args.add(e)
|
||||||
proc addDollar() = args.add(newStrLitNode"$")
|
proc addDollar() = args.add(newStrLitNode"$")
|
||||||
|
|
||||||
processInterpolations(e)
|
processInterpolations(e)
|
||||||
|
|
@ -59,7 +59,7 @@ macro concatStyleInterpolation(e: expr): expr =
|
||||||
proc sum(a, b, c: int): int =
|
proc sum(a, b, c: int): int =
|
||||||
return (a + b + c)
|
return (a + b + c)
|
||||||
|
|
||||||
var
|
var
|
||||||
alice = "Alice"
|
alice = "Alice"
|
||||||
bob = "Bob"
|
bob = "Bob"
|
||||||
a = 10
|
a = 10
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ discard """
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
proc test(f: var PNimrodNode) {.compileTime.} =
|
proc test(f: var NimNode) {.compileTime.} =
|
||||||
f = newNimNode(nnkStmtList)
|
f = newNimNode(nnkStmtList)
|
||||||
f.add newCall(newIdentNode("echo"), newLit(10))
|
f.add newCall(newIdentNode("echo"), newLit(10))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ proc `$`*[T](x: seq[T]): string =
|
||||||
result.add($x[i])
|
result.add($x[i])
|
||||||
result.add ']'
|
result.add ']'
|
||||||
|
|
||||||
macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
let
|
let
|
||||||
typeName = quoted2ident(typeNameN)
|
typeName = quoted2ident(typeNameN)
|
||||||
packetID = ^"p"
|
packetID = ^"p"
|
||||||
streamID = ^"s"
|
streamID = ^"s"
|
||||||
|
|
@ -66,7 +66,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
readBody = newNimNode(nnkStmtList)
|
readBody = newNimNode(nnkStmtList)
|
||||||
lenNames = 0
|
lenNames = 0
|
||||||
for i in 0.. typeFields.len - 1:
|
for i in 0.. typeFields.len - 1:
|
||||||
let
|
let
|
||||||
name = typeFields[i][0]
|
name = typeFields[i][0]
|
||||||
dotName = packetID.dot(name)
|
dotName = packetID.dot(name)
|
||||||
resName = newIdentNode(!"result").dot(name)
|
resName = newIdentNode(!"result").dot(name)
|
||||||
|
|
@ -91,11 +91,11 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
newNimNode(nnkDiscardStmt).und(
|
newNimNode(nnkDiscardStmt).und(
|
||||||
newCall("readData", streamID, newNimNode(nnkAddr).und(resName), newCall("sizeof", resName))))
|
newCall("readData", streamID, newNimNode(nnkAddr).und(resName), newCall("sizeof", resName))))
|
||||||
packBody.add(
|
packBody.add(
|
||||||
newCall("writeData", streamID, newNimNode(nnkAddr).und(dotName), newCall("sizeof", dotName)))
|
newCall("writeData", streamID, newNimNode(nnkAddr).und(dotName), newCall("sizeof", dotName)))
|
||||||
of "seq":
|
of "seq":
|
||||||
## let lenX = readInt16(s)
|
## let lenX = readInt16(s)
|
||||||
newLenName()
|
newLenName()
|
||||||
let
|
let
|
||||||
item = ^"item" ## item name in our iterators
|
item = ^"item" ## item name in our iterators
|
||||||
seqType = typeFields[i][1][1] ## type of seq
|
seqType = typeFields[i][1][1] ## type of seq
|
||||||
readName = newIdentNode("read"& $seqType.ident)
|
readName = newIdentNode("read"& $seqType.ident)
|
||||||
|
|
@ -107,7 +107,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
readBody.add( ## result.name = @[]
|
readBody.add( ## result.name = @[]
|
||||||
resName := ("@".prefix(newNimNode(nnkBracket))),
|
resName := ("@".prefix(newNimNode(nnkBracket))),
|
||||||
newNimNode(nnkForStmt).und( ## for item in 1..len:
|
newNimNode(nnkForStmt).und( ## for item in 1..len:
|
||||||
item,
|
item,
|
||||||
infix(1.lit, "..", lenName),
|
infix(1.lit, "..", lenName),
|
||||||
newNimNode(nnkStmtList).und(
|
newNimNode(nnkStmtList).und(
|
||||||
newCall( ## add(result.name, unpack[seqType](stream))
|
newCall( ## add(result.name, unpack[seqType](stream))
|
||||||
|
|
@ -117,7 +117,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
|
newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
|
||||||
lenName, ## var lenName = int16(len(p.name))
|
lenName, ## var lenName = int16(len(p.name))
|
||||||
newIdentNode("int16"),
|
newIdentNode("int16"),
|
||||||
newCall("int16", newCall("len", dotName)))),
|
newCall("int16", newCall("len", dotName)))),
|
||||||
newCall("writeData", streamID, newNimNode(nnkAddr).und(lenName), 2.lit),
|
newCall("writeData", streamID, newNimNode(nnkAddr).und(lenName), 2.lit),
|
||||||
newNimNode(nnkForStmt).und( ## for item in 0..length - 1: pack(p.name[item], stream)
|
newNimNode(nnkForStmt).und( ## for item in 0..length - 1: pack(p.name[item], stream)
|
||||||
item,
|
item,
|
||||||
|
|
@ -143,8 +143,8 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
|
readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
|
||||||
else:
|
else:
|
||||||
error("I dont know what to do with: "& treerepr(typeFields[i]))
|
error("I dont know what to do with: "& treerepr(typeFields[i]))
|
||||||
|
|
||||||
var
|
var
|
||||||
toStringFunc = newNimNode(nnkProcDef).und(
|
toStringFunc = newNimNode(nnkProcDef).und(
|
||||||
newNimNode(nnkPostfix).und(
|
newNimNode(nnkPostfix).und(
|
||||||
^"*",
|
^"*",
|
||||||
|
|
@ -161,12 +161,12 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
emptyNode(),
|
emptyNode(),
|
||||||
newNimNode(nnkStmtList).und(#[6]
|
newNimNode(nnkStmtList).und(#[6]
|
||||||
newNimNode(nnkAsgn).und(
|
newNimNode(nnkAsgn).und(
|
||||||
^"result", ## result =
|
^"result", ## result =
|
||||||
newNimNode(nnkCall).und(#[6][0][1]
|
newNimNode(nnkCall).und(#[6][0][1]
|
||||||
^"format", ## format
|
^"format", ## format
|
||||||
emptyNode())))) ## "[TypeName $1 $2]"
|
emptyNode())))) ## "[TypeName $1 $2]"
|
||||||
formatStr = "["& $typeName.ident
|
formatStr = "["& $typeName.ident
|
||||||
|
|
||||||
const emptyFields = {nnkEmpty, nnkNilLit}
|
const emptyFields = {nnkEmpty, nnkNilLit}
|
||||||
var objFields = newNimNode(nnkRecList)
|
var objFields = newNimNode(nnkRecList)
|
||||||
for i in 0.. < len(typeFields):
|
for i in 0.. < len(typeFields):
|
||||||
|
|
@ -186,10 +186,10 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
prefix("$", packetID.dot(fname)))
|
prefix("$", packetID.dot(fname)))
|
||||||
formatStr.add " $"
|
formatStr.add " $"
|
||||||
formatStr.add($(i + 1))
|
formatStr.add($(i + 1))
|
||||||
|
|
||||||
formatStr.add ']'
|
formatStr.add ']'
|
||||||
toStringFunc[6][0][1][1] = formatStr.lit()
|
toStringFunc[6][0][1][1] = formatStr.lit()
|
||||||
|
|
||||||
result.add(
|
result.add(
|
||||||
newNimNode(nnkTypeSection).und(
|
newNimNode(nnkTypeSection).und(
|
||||||
newNimNode(nnkTypeDef).und(
|
newNimNode(nnkTypeDef).und(
|
||||||
|
|
@ -206,15 +206,15 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
when defined(GenPacketShowOutput):
|
when defined(GenPacketShowOutput):
|
||||||
echo(repr(result))
|
echo(repr(result))
|
||||||
|
|
||||||
proc `->`(a: string, b: string): PNimrodNode {.compileTime.} =
|
proc `->`(a: string, b: string): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkIdentDefs).und(^a, ^b, newNimNode(nnkEmpty))
|
result = newNimNode(nnkIdentDefs).und(^a, ^b, newNimNode(nnkEmpty))
|
||||||
proc `->`(a: string, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc `->`(a: string, b: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkIdentDefs).und(^a, b, newNimNode(nnkEmpty))
|
result = newNimNode(nnkIdentDefs).und(^a, b, newNimNode(nnkEmpty))
|
||||||
proc `->`(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc `->`(a, b: NimNode): NimNode {.compileTime.} =
|
||||||
a[2] = b
|
a[2] = b
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
proc newProc*(name: string, params: varargs[PNimrodNode], resultType: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newProc*(name: string, params: varargs[NimNode], resultType: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkProcDef).und(
|
result = newNimNode(nnkProcDef).und(
|
||||||
^name,
|
^name,
|
||||||
emptyNode(),
|
emptyNode(),
|
||||||
|
|
@ -227,7 +227,7 @@ proc newProc*(name: string, params: varargs[PNimrodNode], resultType: PNimrodNod
|
||||||
macro forwardPacket*(typeName: expr, underlyingType: typedesc): stmt {.immediate.} =
|
macro forwardPacket*(typeName: expr, underlyingType: typedesc): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkStmtList).und(
|
result = newNimNode(nnkStmtList).und(
|
||||||
newProc(
|
newProc(
|
||||||
"read"& $typeName.ident,
|
"read"& $typeName.ident,
|
||||||
["s" -> "PStream" -> newNimNode(nnkNilLit)],
|
["s" -> "PStream" -> newNimNode(nnkNilLit)],
|
||||||
typeName),
|
typeName),
|
||||||
newProc(
|
newProc(
|
||||||
|
|
@ -258,21 +258,21 @@ when isMainModule:
|
||||||
A = 0'i8,
|
A = 0'i8,
|
||||||
B, C
|
B, C
|
||||||
forwardPacket(SomeEnum, int8)
|
forwardPacket(SomeEnum, int8)
|
||||||
|
|
||||||
|
|
||||||
defPacket(Foo, tuple[x: array[0..4, int8]])
|
defPacket(Foo, tuple[x: array[0..4, int8]])
|
||||||
var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
|
var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
|
||||||
var s2 = newStringStream("")
|
var s2 = newStringStream("")
|
||||||
f.pack(s2)
|
f.pack(s2)
|
||||||
assert s2.data == "\4\3\2\1\0"
|
assert s2.data == "\4\3\2\1\0"
|
||||||
|
|
||||||
var s = newStringStream()
|
var s = newStringStream()
|
||||||
s.flushImpl = proc(s: PStream) =
|
s.flushImpl = proc(s: PStream) =
|
||||||
var z = PStringStream(s)
|
var z = PStringStream(s)
|
||||||
z.setPosition(0)
|
z.setPosition(0)
|
||||||
z.data.setLen(0)
|
z.data.setLen(0)
|
||||||
|
|
||||||
|
|
||||||
s.setPosition(0)
|
s.setPosition(0)
|
||||||
s.data.setLen(0)
|
s.data.setLen(0)
|
||||||
var o = B
|
var o = B
|
||||||
|
|
@ -283,7 +283,7 @@ when isMainModule:
|
||||||
o.pack(s)
|
o.pack(s)
|
||||||
assert s.data == "\1\0\2"
|
assert s.data == "\1\0\2"
|
||||||
s.flush
|
s.flush
|
||||||
|
|
||||||
defPacket(Y, tuple[z: int8])
|
defPacket(Y, tuple[z: int8])
|
||||||
proc `$`(z: Y): string = result = "Y("& $z.z &")"
|
proc `$`(z: Y): string = result = "Y("& $z.z &")"
|
||||||
defPacket(TestPkt, tuple[x: seq[Y]])
|
defPacket(TestPkt, tuple[x: seq[Y]])
|
||||||
|
|
@ -292,4 +292,4 @@ when isMainModule:
|
||||||
for itm in test.x:
|
for itm in test.x:
|
||||||
echo(itm)
|
echo(itm)
|
||||||
test.pack(s)
|
test.pack(s)
|
||||||
echo(repr(s.data))
|
echo(repr(s.data))
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ template defPacketImports*(): stmt {.immediate, dirty.} =
|
||||||
import macros, macro_dsl, estreams
|
import macros, macro_dsl, estreams
|
||||||
from strutils import format
|
from strutils import format
|
||||||
|
|
||||||
macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
let
|
let
|
||||||
typeName = quoted2ident(typeNameN)
|
typeName = quoted2ident(typeNameN)
|
||||||
packetID = ^"p"
|
packetID = ^"p"
|
||||||
streamID = ^"s"
|
streamID = ^"s"
|
||||||
|
|
@ -57,7 +57,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
readBody = newNimNode(nnkStmtList)
|
readBody = newNimNode(nnkStmtList)
|
||||||
lenNames = 0
|
lenNames = 0
|
||||||
for i in 0.. typeFields.len - 1:
|
for i in 0.. typeFields.len - 1:
|
||||||
let
|
let
|
||||||
name = typeFields[i][0]
|
name = typeFields[i][0]
|
||||||
dotName = packetID.dot(name)
|
dotName = packetID.dot(name)
|
||||||
resName = newIdentNode(!"result").dot(name)
|
resName = newIdentNode(!"result").dot(name)
|
||||||
|
|
@ -67,7 +67,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
of "seq":
|
of "seq":
|
||||||
## let lenX = readInt16(s)
|
## let lenX = readInt16(s)
|
||||||
newLenName()
|
newLenName()
|
||||||
let
|
let
|
||||||
item = ^"item" ## item name in our iterators
|
item = ^"item" ## item name in our iterators
|
||||||
seqType = typeFields[i][1][1] ## type of seq
|
seqType = typeFields[i][1][1] ## type of seq
|
||||||
readName = newIdentNode("read"& $seqType.ident)
|
readName = newIdentNode("read"& $seqType.ident)
|
||||||
|
|
@ -79,7 +79,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
readBody.add( ## result.name = @[]
|
readBody.add( ## result.name = @[]
|
||||||
resName := ("@".prefix(newNimNode(nnkBracket))),
|
resName := ("@".prefix(newNimNode(nnkBracket))),
|
||||||
newNimNode(nnkForStmt).und( ## for item in 1..len:
|
newNimNode(nnkForStmt).und( ## for item in 1..len:
|
||||||
item,
|
item,
|
||||||
infix(1.lit, "..", lenName),
|
infix(1.lit, "..", lenName),
|
||||||
newNimNode(nnkStmtList).und(
|
newNimNode(nnkStmtList).und(
|
||||||
newCall( ## add(result.name, unpack[seqType](stream))
|
newCall( ## add(result.name, unpack[seqType](stream))
|
||||||
|
|
@ -89,7 +89,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
|
newNimNode(nnkVarSection).und(newNimNode(nnkIdentDefs).und(
|
||||||
lenName, ## var lenName = int16(len(p.name))
|
lenName, ## var lenName = int16(len(p.name))
|
||||||
newIdentNode("int16"),
|
newIdentNode("int16"),
|
||||||
newCall("int16", newCall("len", dotName)))),
|
newCall("int16", newCall("len", dotName)))),
|
||||||
newCall("writeBE", streamID, lenName),
|
newCall("writeBE", streamID, lenName),
|
||||||
newNimNode(nnkForStmt).und( ## for item in 0..length - 1: pack(p.name[item], stream)
|
newNimNode(nnkForStmt).und( ## for item in 0..length - 1: pack(p.name[item], stream)
|
||||||
item,
|
item,
|
||||||
|
|
@ -115,8 +115,8 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
|
readBody.add(resName := newCall("read"& $typeFields[i][1].ident, streamID))
|
||||||
else:
|
else:
|
||||||
error("I dont know what to do with: "& treerepr(typeFields[i]))
|
error("I dont know what to do with: "& treerepr(typeFields[i]))
|
||||||
|
|
||||||
var
|
var
|
||||||
toStringFunc = newNimNode(nnkProcDef).und(
|
toStringFunc = newNimNode(nnkProcDef).und(
|
||||||
newNimNode(nnkPostfix).und(
|
newNimNode(nnkPostfix).und(
|
||||||
^"*",
|
^"*",
|
||||||
|
|
@ -133,12 +133,12 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
emptyNode(),
|
emptyNode(),
|
||||||
newNimNode(nnkStmtList).und(#[6]
|
newNimNode(nnkStmtList).und(#[6]
|
||||||
newNimNode(nnkAsgn).und(
|
newNimNode(nnkAsgn).und(
|
||||||
^"result", ## result =
|
^"result", ## result =
|
||||||
newNimNode(nnkCall).und(#[6][0][1]
|
newNimNode(nnkCall).und(#[6][0][1]
|
||||||
^"format", ## format
|
^"format", ## format
|
||||||
emptyNode())))) ## "[TypeName $1 $2]"
|
emptyNode())))) ## "[TypeName $1 $2]"
|
||||||
formatStr = "["& $typeName.ident
|
formatStr = "["& $typeName.ident
|
||||||
|
|
||||||
const emptyFields = {nnkEmpty, nnkNilLit}
|
const emptyFields = {nnkEmpty, nnkNilLit}
|
||||||
var objFields = newNimNode(nnkRecList)
|
var objFields = newNimNode(nnkRecList)
|
||||||
for i in 0.. < len(typeFields):
|
for i in 0.. < len(typeFields):
|
||||||
|
|
@ -158,10 +158,10 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
prefix("$", packetID.dot(fname)))
|
prefix("$", packetID.dot(fname)))
|
||||||
formatStr.add " $"
|
formatStr.add " $"
|
||||||
formatStr.add($(i + 1))
|
formatStr.add($(i + 1))
|
||||||
|
|
||||||
formatStr.add ']'
|
formatStr.add ']'
|
||||||
toStringFunc[6][0][1][1] = formatStr.lit()
|
toStringFunc[6][0][1][1] = formatStr.lit()
|
||||||
|
|
||||||
result.add(
|
result.add(
|
||||||
newNimNode(nnkTypeSection).und(
|
newNimNode(nnkTypeSection).und(
|
||||||
newNimNode(nnkTypeDef).und(
|
newNimNode(nnkTypeDef).und(
|
||||||
|
|
@ -178,7 +178,7 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
when defined(GenPacketShowOutput):
|
when defined(GenPacketShowOutput):
|
||||||
echo(repr(result))
|
echo(repr(result))
|
||||||
|
|
||||||
proc newProc*(name: PNimrodNode; params: varargs[PNimrodNode]; resultType: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc newProc*(name: NimNode; params: varargs[NimNode]; resultType: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkProcDef).und(
|
result = newNimNode(nnkProcDef).und(
|
||||||
name,
|
name,
|
||||||
emptyNode(),
|
emptyNode(),
|
||||||
|
|
@ -189,15 +189,15 @@ proc newProc*(name: PNimrodNode; params: varargs[PNimrodNode]; resultType: PNimr
|
||||||
newNimNode(nnkStmtList))
|
newNimNode(nnkStmtList))
|
||||||
result[3].add(params)
|
result[3].add(params)
|
||||||
|
|
||||||
proc body*(procNode: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc body*(procNode: NimNode): NimNode {.compileTime.} =
|
||||||
assert procNode.kind == nnkProcDef and procNode[6].kind == nnkStmtList
|
assert procNode.kind == nnkProcDef and procNode[6].kind == nnkStmtList
|
||||||
result = procNode[6]
|
result = procNode[6]
|
||||||
|
|
||||||
proc iddefs*(a, b: string; c: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc iddefs*(a, b: string; c: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkIdentDefs).und(^a, ^b, c)
|
result = newNimNode(nnkIdentDefs).und(^a, ^b, c)
|
||||||
proc iddefs*(a: string; b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc iddefs*(a: string; b: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkIdentDefs).und(^a, b, emptyNode())
|
result = newNimNode(nnkIdentDefs).und(^a, b, emptyNode())
|
||||||
proc varTy*(a: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc varTy*(a: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkVarTy).und(a)
|
result = newNimNode(nnkVarTy).und(a)
|
||||||
|
|
||||||
macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
|
macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
|
||||||
|
|
@ -206,7 +206,7 @@ macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
|
||||||
streamID = ^"s"
|
streamID = ^"s"
|
||||||
result = newNimNode(nnkStmtList).und(
|
result = newNimNode(nnkStmtList).und(
|
||||||
newProc(
|
newProc(
|
||||||
(^("read"& $typeName.ident)).postfix("*"),
|
(^("read"& $typeName.ident)).postfix("*"),
|
||||||
[ iddefs("s", "PBuffer", newNimNode(nnkNilLit)) ],
|
[ iddefs("s", "PBuffer", newNimNode(nnkNilLit)) ],
|
||||||
typeName),
|
typeName),
|
||||||
newProc(
|
newProc(
|
||||||
|
|
@ -218,7 +218,7 @@ macro forwardPacket*(typeName: expr, underlyingType: expr): stmt {.immediate.} =
|
||||||
readBody = result[0][6]
|
readBody = result[0][6]
|
||||||
packBody = result[1][6]
|
packBody = result[1][6]
|
||||||
resName = ^"result"
|
resName = ^"result"
|
||||||
|
|
||||||
case underlyingType.kind
|
case underlyingType.kind
|
||||||
of nnkBracketExpr:
|
of nnkBracketExpr:
|
||||||
case $underlyingType[0].ident
|
case $underlyingType[0].ident
|
||||||
|
|
@ -250,21 +250,21 @@ when isMainModule:
|
||||||
A = 0'i8,
|
A = 0'i8,
|
||||||
B, C
|
B, C
|
||||||
forwardPacket(SomeEnum, int8)
|
forwardPacket(SomeEnum, int8)
|
||||||
|
|
||||||
|
|
||||||
defPacket(Foo, tuple[x: array[0..4, int8]])
|
defPacket(Foo, tuple[x: array[0..4, int8]])
|
||||||
var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
|
var f = newFoo([4'i8, 3'i8, 2'i8, 1'i8, 0'i8])
|
||||||
var s2 = newStringStream("")
|
var s2 = newStringStream("")
|
||||||
f.pack(s2)
|
f.pack(s2)
|
||||||
assert s2.data == "\4\3\2\1\0"
|
assert s2.data == "\4\3\2\1\0"
|
||||||
|
|
||||||
var s = newStringStream()
|
var s = newStringStream()
|
||||||
s.flushImpl = proc(s: PStream) =
|
s.flushImpl = proc(s: PStream) =
|
||||||
var z = PStringStream(s)
|
var z = PStringStream(s)
|
||||||
z.setPosition(0)
|
z.setPosition(0)
|
||||||
z.data.setLen(0)
|
z.data.setLen(0)
|
||||||
|
|
||||||
|
|
||||||
s.setPosition(0)
|
s.setPosition(0)
|
||||||
s.data.setLen(0)
|
s.data.setLen(0)
|
||||||
var o = B
|
var o = B
|
||||||
|
|
@ -275,7 +275,7 @@ when isMainModule:
|
||||||
o.pack(s)
|
o.pack(s)
|
||||||
assert s.data == "\1\0\2"
|
assert s.data == "\1\0\2"
|
||||||
s.flush
|
s.flush
|
||||||
|
|
||||||
defPacket(Y, tuple[z: int8])
|
defPacket(Y, tuple[z: int8])
|
||||||
proc `$`(z: Y): string = result = "Y("& $z.z &")"
|
proc `$`(z: Y): string = result = "Y("& $z.z &")"
|
||||||
defPacket(TestPkt, tuple[x: seq[Y]])
|
defPacket(TestPkt, tuple[x: seq[Y]])
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,42 @@
|
||||||
import macros
|
import macros
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.}
|
||||||
#Inline macro.add() to allow for easier nesting
|
#Inline macro.add() to allow for easier nesting
|
||||||
proc und*(a: PNimrodNode; b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc und*(a: NimNode; b: NimNode): NimNode {.compileTime.} =
|
||||||
a.add(b)
|
a.add(b)
|
||||||
result = a
|
result = a
|
||||||
proc und*(a: PNimrodNode; b: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
|
proc und*(a: NimNode; b: varargs[NimNode]): NimNode {.compileTime.} =
|
||||||
a.add(b)
|
a.add(b)
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
proc `^`*(a: string): PNimrodNode {.compileTime.} =
|
proc `^`*(a: string): NimNode {.compileTime.} =
|
||||||
## new ident node
|
## new ident node
|
||||||
result = newIdentNode(!a)
|
result = newIdentNode(!a)
|
||||||
proc `[]`*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc `[]`*(a, b: NimNode): NimNode {.compileTime.} =
|
||||||
## new bracket expression: node[node] not to be confused with node[indx]
|
## new bracket expression: node[node] not to be confused with node[indx]
|
||||||
result = newNimNode(nnkBracketExpr).und(a, b)
|
result = newNimNode(nnkBracketExpr).und(a, b)
|
||||||
proc `:=`*(left, right: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc `:=`*(left, right: NimNode): NimNode {.compileTime.} =
|
||||||
## new Asgn node: left = right
|
## new Asgn node: left = right
|
||||||
result = newNimNode(nnkAsgn).und(left, right)
|
result = newNimNode(nnkAsgn).und(left, right)
|
||||||
|
|
||||||
proc lit*(a: string): PNimrodNode {.compileTime.} =
|
proc lit*(a: string): NimNode {.compileTime.} =
|
||||||
result = newStrLitNode(a)
|
result = newStrLitNode(a)
|
||||||
proc lit*(a: int): PNimrodNode {.compileTime.} =
|
proc lit*(a: int): NimNode {.compileTime.} =
|
||||||
result = newIntLitNode(a)
|
result = newIntLitNode(a)
|
||||||
proc lit*(a: float): PNimrodNode {.compileTime.} =
|
proc lit*(a: float): NimNode {.compileTime.} =
|
||||||
result = newFloatLitNode(a)
|
result = newFloatLitNode(a)
|
||||||
proc lit*(a: char): PNimrodNode {.compileTime.} =
|
proc lit*(a: char): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkCharLit)
|
result = newNimNode(nnkCharLit)
|
||||||
result.intval = a.ord
|
result.intval = a.ord
|
||||||
|
|
||||||
proc emptyNode*(): PNimrodNode {.compileTime.} =
|
proc emptyNode*(): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkEmpty)
|
result = newNimNode(nnkEmpty)
|
||||||
|
|
||||||
proc dot*(left, right: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc dot*(left, right: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkDotExpr).und(left, right)
|
result = newNimNode(nnkDotExpr).und(left, right)
|
||||||
proc prefix*(a: string, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc prefix*(a: string, b: NimNode): NimNode {.compileTime.} =
|
||||||
result = newNimNode(nnkPrefix).und(newIdentNode(!a), b)
|
result = newNimNode(nnkPrefix).und(newIdentNode(!a), b)
|
||||||
|
|
||||||
proc quoted2ident*(a: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc quoted2ident*(a: NimNode): NimNode {.compileTime.} =
|
||||||
if a.kind != nnkAccQuoted:
|
if a.kind != nnkAccQuoted:
|
||||||
return a
|
return a
|
||||||
var pname = ""
|
var pname = ""
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ var g = 70
|
||||||
++g
|
++g
|
||||||
g ++ 7
|
g ++ 7
|
||||||
g.`++`(10, 20)
|
g.`++`(10, 20)
|
||||||
echo g
|
echo g
|
||||||
|
|
||||||
|
|
||||||
#let lv = stdin.readline
|
#let lv = stdin.readline
|
||||||
|
|
@ -56,7 +56,7 @@ type
|
||||||
fkLit, ## element is a literal like 0.1
|
fkLit, ## element is a literal like 0.1
|
||||||
fkAdd, ## element is an addition operation
|
fkAdd, ## element is an addition operation
|
||||||
fkMul, ## element is a multiplication operation
|
fkMul, ## element is a multiplication operation
|
||||||
fkExp ## element is an exponentiation operation
|
fkExp ## element is an exponentiation operation
|
||||||
|
|
||||||
type
|
type
|
||||||
Formula = ref object
|
Formula = ref object
|
||||||
|
|
@ -78,16 +78,16 @@ proc evaluate(n: Formula, varToVal: proc (name: string): float): float =
|
||||||
echo evaluate(Formula(kind: fkLit, value: 0.4), nil)
|
echo evaluate(Formula(kind: fkLit, value: 0.4), nil)
|
||||||
|
|
||||||
proc isPolyTerm(n: Formula): bool =
|
proc isPolyTerm(n: Formula): bool =
|
||||||
n.kind == fkMul and n.left.kind == fkLit and (let e = n.right;
|
n.kind == fkMul and n.left.kind == fkLit and (let e = n.right;
|
||||||
e.kind == fkExp and e.left.kind == fkVar and e.right.kind == fkLit)
|
e.kind == fkExp and e.left.kind == fkVar and e.right.kind == fkLit)
|
||||||
|
|
||||||
proc isPolynomial(n: Formula): bool =
|
proc isPolynomial(n: Formula): bool =
|
||||||
isPolyTerm(n) or
|
isPolyTerm(n) or
|
||||||
(n.kind == fkAdd and isPolynomial(n.left) and isPolynomial(n.right))
|
(n.kind == fkAdd and isPolynomial(n.left) and isPolynomial(n.right))
|
||||||
|
|
||||||
let myFormula = Formula(kind: fkMul,
|
let myFormula = Formula(kind: fkMul,
|
||||||
left: Formula(kind: fkLit, value: 2.0),
|
left: Formula(kind: fkLit, value: 2.0),
|
||||||
right: Formula(kind: fkExp,
|
right: Formula(kind: fkExp,
|
||||||
left: Formula(kind: fkVar, name: "x"),
|
left: Formula(kind: fkVar, name: "x"),
|
||||||
right: Formula(kind: fkLit, value: 5.0)))
|
right: Formula(kind: fkLit, value: 5.0)))
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ proc pat2kind(pattern: string): FormulaKind =
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
proc matchAgainst(n, pattern: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc matchAgainst(n, pattern: NimNode): NimNode {.compileTime.} =
|
||||||
template `@`(current, field: expr): expr =
|
template `@`(current, field: expr): expr =
|
||||||
newDotExpr(current, newIdentNode(astToStr(field)))
|
newDotExpr(current, newIdentNode(astToStr(field)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const identChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
|
||||||
|
|
||||||
|
|
||||||
# Procedure Declarations
|
# Procedure Declarations
|
||||||
proc parse_template(node: PNimrodNode, value: string) {.compiletime.}
|
proc parse_template(node: NimNode, value: string) {.compiletime.}
|
||||||
|
|
||||||
|
|
||||||
# Procedure Definitions
|
# Procedure Definitions
|
||||||
|
|
@ -166,7 +166,7 @@ iterator parse_compound_statements(value, identifier: string, index: int): strin
|
||||||
get_next_ident(["try", "$except", "$finally"])
|
get_next_ident(["try", "$except", "$finally"])
|
||||||
|
|
||||||
|
|
||||||
proc parse_complex_stmt(value, identifier: string, index: var int): PNimrodNode {.compiletime.} =
|
proc parse_complex_stmt(value, identifier: string, index: var int): NimNode {.compiletime.} =
|
||||||
## Parses if/when/try /elif /else /except /finally statements
|
## Parses if/when/try /elif /else /except /finally statements
|
||||||
|
|
||||||
# Build up complex statement string
|
# Build up complex statement string
|
||||||
|
|
@ -218,7 +218,7 @@ proc parse_complex_stmt(value, identifier: string, index: var int): PNimrodNode
|
||||||
inc(resultIndex)
|
inc(resultIndex)
|
||||||
|
|
||||||
|
|
||||||
proc parse_simple_statement(value: string, index: var int): PNimrodNode {.compiletime.} =
|
proc parse_simple_statement(value: string, index: var int): NimNode {.compiletime.} =
|
||||||
## Parses for/while
|
## Parses for/while
|
||||||
|
|
||||||
# Detect indentation
|
# Detect indentation
|
||||||
|
|
@ -252,7 +252,7 @@ proc parse_simple_statement(value: string, index: var int): PNimrodNode {.compil
|
||||||
inc(index, value.parse_thru_eol(index))
|
inc(index, value.parse_thru_eol(index))
|
||||||
|
|
||||||
|
|
||||||
proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool {.compiletime.} =
|
proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} =
|
||||||
## Parses a string until a $ symbol is encountered, if
|
## Parses a string until a $ symbol is encountered, if
|
||||||
## two $$'s are encountered in a row, a split will happen
|
## two $$'s are encountered in a row, a split will happen
|
||||||
## removing one of the $'s from the resulting output
|
## removing one of the $'s from the resulting output
|
||||||
|
|
@ -311,7 +311,7 @@ proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool
|
||||||
node.insert insertionPoint, newCall("add", ident("result"), newStrLitNode(splitValue))
|
node.insert insertionPoint, newCall("add", ident("result"), newStrLitNode(splitValue))
|
||||||
|
|
||||||
|
|
||||||
proc parse_template(node: PNimrodNode, value: string) =
|
proc parse_template(node: NimNode, value: string) =
|
||||||
## Parses through entire template, outputing valid
|
## Parses through entire template, outputing valid
|
||||||
## Nim code into the input `node` AST.
|
## Nim code into the input `node` AST.
|
||||||
var index = 0
|
var index = 0
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ discard """
|
||||||
output: "Using test.Closing test."
|
output: "Using test.Closing test."
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import
|
import
|
||||||
macros
|
macros
|
||||||
|
|
||||||
# This macro mimics the using statement from C#
|
# This macro mimics the using statement from C#
|
||||||
#
|
#
|
||||||
# It's kept only as a test for the macro system
|
# It's kept only as a test for the macro system
|
||||||
# Nim's destructors offer a mechanism for automatic
|
# Nim's destructors offer a mechanism for automatic
|
||||||
# disposal of resources.
|
# disposal of resources.
|
||||||
#
|
#
|
||||||
macro autoClose(e: expr): stmt {.immediate.} =
|
macro autoClose(e: expr): stmt {.immediate.} =
|
||||||
|
|
@ -20,19 +20,19 @@ macro autoClose(e: expr): stmt {.immediate.} =
|
||||||
|
|
||||||
var args = e
|
var args = e
|
||||||
var body = e[2]
|
var body = e[2]
|
||||||
|
|
||||||
var
|
var
|
||||||
variables : seq[PNimrodNode]
|
variables : seq[NimNode]
|
||||||
closingCalls : seq[PNimrodNode]
|
closingCalls : seq[NimNode]
|
||||||
|
|
||||||
newSeq(variables, 0)
|
newSeq(variables, 0)
|
||||||
newSeq(closingCalls, 0)
|
newSeq(closingCalls, 0)
|
||||||
|
|
||||||
for i in countup(1, args.len-2):
|
for i in countup(1, args.len-2):
|
||||||
if args[i].kind == nnkExprEqExpr:
|
if args[i].kind == nnkExprEqExpr:
|
||||||
var varName = args[i][0]
|
var varName = args[i][0]
|
||||||
var varValue = args[i][1]
|
var varValue = args[i][1]
|
||||||
|
|
||||||
var varAssignment = newNimNode(nnkIdentDefs)
|
var varAssignment = newNimNode(nnkIdentDefs)
|
||||||
varAssignment.add(varName)
|
varAssignment.add(varName)
|
||||||
varAssignment.add(newNimNode(nnkEmpty)) # empty means no type
|
varAssignment.add(newNimNode(nnkEmpty)) # empty means no type
|
||||||
|
|
@ -43,7 +43,7 @@ macro autoClose(e: expr): stmt {.immediate.} =
|
||||||
else:
|
else:
|
||||||
error "Using statement: Unexpected expression. Got " &
|
error "Using statement: Unexpected expression. Got " &
|
||||||
$args[i].kind & " instead of assignment."
|
$args[i].kind & " instead of assignment."
|
||||||
|
|
||||||
var varSection = newNimNode(nnkVarSection)
|
var varSection = newNimNode(nnkVarSection)
|
||||||
varSection.add(variables)
|
varSection.add(variables)
|
||||||
|
|
||||||
|
|
@ -67,10 +67,10 @@ macro autoClose(e: expr): stmt {.immediate.} =
|
||||||
targetAst[0][1][0] = varSection
|
targetAst[0][1][0] = varSection
|
||||||
targetAst[0][1][1][0] = body
|
targetAst[0][1][1][0] = body
|
||||||
targetAst[0][1][1][1][0] = finallyBlock
|
targetAst[0][1][1][1][0] = finallyBlock
|
||||||
|
|
||||||
result = targetAst
|
result = targetAst
|
||||||
|
|
||||||
type
|
type
|
||||||
TResource* = object
|
TResource* = object
|
||||||
field*: string
|
field*: string
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ type
|
||||||
suiteDesc: string
|
suiteDesc: string
|
||||||
testName: string
|
testName: string
|
||||||
testDesc: string
|
testDesc: string
|
||||||
testBlock: PNimrodNode
|
testBlock: NimNode
|
||||||
|
|
||||||
proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tests: seq[SuiteTest]] {.compileTime.} =
|
proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: NimNode): tuple[tests: seq[SuiteTest]] {.compileTime.} =
|
||||||
var
|
var
|
||||||
tests:seq[SuiteTest] = @[]
|
tests:seq[SuiteTest] = @[]
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tes
|
||||||
discard
|
discard
|
||||||
|
|
||||||
return (tests: tests)
|
return (tests: tests)
|
||||||
|
|
||||||
macro suite(suiteName, suiteDesc: expr, suiteBloc: stmt): stmt {.immediate.} =
|
macro suite(suiteName, suiteDesc: expr, suiteBloc: stmt): stmt {.immediate.} =
|
||||||
let contents = buildSuiteContents(suiteName, suiteDesc, suiteBloc)
|
let contents = buildSuiteContents(suiteName, suiteDesc, suiteBloc)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue