Merge branch 'devel' into vm_float_casts

This commit is contained in:
Andrii Riabushenko 2018-10-24 22:16:25 +01:00
commit 4c53d45674
23 changed files with 251 additions and 53 deletions

0
bin/nim-gdb Normal file → Executable file
View file

View file

@ -27,6 +27,9 @@
- Added `or` for `NimNode` in `macros`. - Added `or` for `NimNode` in `macros`.
- Added `system.typeof` for more control over how `type` expressions
can be deduced.
### Library changes ### Library changes

View file

@ -400,6 +400,16 @@ proc genGotoForCase(p: BProc; caseStmt: PNode) =
genStmts(p, it.lastSon) genStmts(p, it.lastSon)
endBlock(p) endBlock(p)
iterator fieldValuePairs(n: PNode): tuple[memberSym, valueSym: PNode] =
assert(n.kind in {nkLetSection, nkVarSection})
for identDefs in n:
if identDefs.kind == nkIdentDefs:
let valueSym = identDefs[^1]
for i in 0 ..< identDefs.len-2:
let memberSym = identDefs[i]
yield((memberSym: memberSym, valueSym: valueSym))
proc genComputedGoto(p: BProc; n: PNode) = proc genComputedGoto(p: BProc; n: PNode) =
# first pass: Generate array of computed labels: # first pass: Generate array of computed labels:
var casePos = -1 var casePos = -1
@ -429,22 +439,12 @@ proc genComputedGoto(p: BProc; n: PNode) =
let tmp = "TMP$1_" % [id.rope] let tmp = "TMP$1_" % [id.rope]
var gotoArray = "static void* $#[$#] = {" % [tmp, arraySize.rope] var gotoArray = "static void* $#[$#] = {" % [tmp, arraySize.rope]
for i in 1..arraySize-1: for i in 1..arraySize-1:
gotoArray.addf("&&TMP$#_, ", [(id+i).rope]) gotoArray.addf("&&TMP$#_, ", [rope(id+i)])
gotoArray.addf("&&TMP$#_};$n", [(id+arraySize).rope]) gotoArray.addf("&&TMP$#_};$n", [rope(id+arraySize)])
line(p, cpsLocals, gotoArray) line(p, cpsLocals, gotoArray)
let topBlock = p.blocks.len-1 for j in 0 ..< casePos:
let oldBody = p.blocks[topBlock].sections[cpsStmts] genStmts(p, n.sons[j])
p.blocks[topBlock].sections[cpsStmts] = nil
for j in casePos+1 ..< n.len: genStmts(p, n.sons[j])
let tailB = p.blocks[topBlock].sections[cpsStmts]
p.blocks[topBlock].sections[cpsStmts] = nil
for j in 0 .. casePos-1: genStmts(p, n.sons[j])
let tailA = p.blocks[topBlock].sections[cpsStmts]
p.blocks[topBlock].sections[cpsStmts] = oldBody & tailA
let caseStmt = n.sons[casePos] let caseStmt = n.sons[casePos]
var a: TLoc var a: TLoc
@ -459,19 +459,40 @@ proc genComputedGoto(p: BProc; n: PNode) =
if it.sons[j].kind == nkRange: if it.sons[j].kind == nkRange:
localError(p.config, it.info, "range notation not available for computed goto") localError(p.config, it.info, "range notation not available for computed goto")
return return
let val = getOrdValue(it.sons[j]) let val = getOrdValue(it.sons[j])
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)]) lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)])
genStmts(p, it.lastSon) genStmts(p, it.lastSon)
#for j in casePos+1 ..< n.len: genStmts(p, n.sons[j]) # tailB
#for j in 0 .. casePos-1: genStmts(p, n.sons[j]) # tailA for j in casePos+1 ..< n.sons.len:
add(p.s(cpsStmts), tailB) genStmts(p, n.sons[j])
add(p.s(cpsStmts), tailA)
for j in 0 ..< casePos:
# prevent new local declarations
# compile declarations as assignments
let it = n.sons[j]
if it.kind in {nkLetSection, nkVarSection}:
let asgn = copyNode(it)
asgn.kind = nkAsgn
asgn.sons.setLen 2
for sym, value in it.fieldValuePairs:
if value.kind != nkEmpty:
asgn.sons[0] = sym
asgn.sons[1] = value
genStmts(p, asgn)
else:
genStmts(p, it)
var a: TLoc var a: TLoc
initLocExpr(p, caseStmt.sons[0], a) initLocExpr(p, caseStmt.sons[0], a)
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc]) lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
endBlock(p) endBlock(p)
for j in casePos+1 ..< n.sons.len:
genStmts(p, n.sons[j])
proc genWhileStmt(p: BProc, t: PNode) = proc genWhileStmt(p: BProc, t: PNode) =
# we don't generate labels here as for example GCC would produce # we don't generate labels here as for example GCC would produce
# significantly worse code # significantly worse code
@ -482,20 +503,20 @@ proc genWhileStmt(p: BProc, t: PNode) =
genLineDir(p, t) genLineDir(p, t)
preserveBreakIdx: preserveBreakIdx:
p.breakIdx = startBlock(p, "while (1) {$n")
p.blocks[p.breakIdx].isLoop = true
initLocExpr(p, t.sons[0], a)
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
let label = assignLabel(p.blocks[p.breakIdx])
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
var loopBody = t.sons[1] var loopBody = t.sons[1]
if loopBody.stmtsContainPragma(wComputedGoto) and if loopBody.stmtsContainPragma(wComputedGoto) and
hasComputedGoto in CC[p.config.cCompiler].props: hasComputedGoto in CC[p.config.cCompiler].props:
# for closure support weird loop bodies are generated: # for closure support weird loop bodies are generated:
if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty: if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty:
loopBody = loopBody.sons[1] loopBody = loopBody.sons[1]
genComputedGoto(p, loopBody) genComputedGoto(p, loopBody) # TODO foobar
else: else:
p.breakIdx = startBlock(p, "while (1) {$n")
p.blocks[p.breakIdx].isLoop = true
initLocExpr(p, t.sons[0], a)
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
let label = assignLabel(p.blocks[p.breakIdx])
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
genStmts(p, loopBody) genStmts(p, loopBody)
if optProfiler in p.options: if optProfiler in p.options:

View file

@ -84,6 +84,7 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimNoNilSeqs2") defineSymbol("nimNoNilSeqs2")
defineSymbol("nimHasUserErrors") defineSymbol("nimHasUserErrors")
defineSymbol("nimUncheckedArrayTyp") defineSymbol("nimUncheckedArrayTyp")
defineSymbol("nimHasTypeof")
defineSymbol("nimHasNilSeqs") defineSymbol("nimHasNilSeqs")
for f in low(Feature)..high(Feature): for f in low(Feature)..high(Feature):

View file

@ -268,9 +268,6 @@ proc patchHead(n: PNode) =
if sfFromGeneric in s.flags: if sfFromGeneric in s.flags:
excl(s.flags, sfFromGeneric) excl(s.flags, sfFromGeneric)
patchHead(s.getBody) patchHead(s.getBody)
if n[1].typ.isNil:
# XXX toptree crashes without this workaround. Figure out why.
return
let t = n[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred}) let t = n[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
template patch(op, field) = template patch(op, field) =
if s.name.s == op and field != nil and field != s: if s.name.s == op and field != nil and field != s:
@ -296,6 +293,10 @@ proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) =
m.add c.graph.config $ c.otherRead.info m.add c.graph.config $ c.otherRead.info
localError(c.graph.config, ri.info, errGenerated, m) localError(c.graph.config, ri.info, errGenerated, m)
proc makePtrType(c: Con, baseType: PType): PType =
result = newType(tyPtr, c.owner)
addSonSkipIntLit(result, baseType)
template genOp(opr, opname, ri) = template genOp(opr, opname, ri) =
let op = opr let op = opr
if op == nil: if op == nil:
@ -304,7 +305,9 @@ template genOp(opr, opname, ri) =
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic") globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
patchHead op patchHead op
if sfError in op.flags: checkForErrorPragma(c, t, ri, opname) if sfError in op.flags: checkForErrorPragma(c, t, ri, opname)
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest)) let addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ))
addrExp.add(dest)
result = newTree(nkCall, newSymNode(op), addrExp)
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode = proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) let t = t.skipTypes({tyGenericInst, tyAlias, tySink})

View file

@ -1118,6 +1118,7 @@ proc skip(L: var TLexer, tok: var TToken) =
tok.strongSpaceA = 0 tok.strongSpaceA = 0
when defined(nimpretty): when defined(nimpretty):
var hasComment = false var hasComment = false
var commentIndent = L.currLineIndent
tok.commentOffsetA = L.offsetBase + pos tok.commentOffsetA = L.offsetBase + pos
tok.commentOffsetB = tok.commentOffsetA tok.commentOffsetB = tok.commentOffsetA
tok.line = -1 tok.line = -1
@ -1139,13 +1140,18 @@ proc skip(L: var TLexer, tok: var TToken) =
inc(pos) inc(pos)
inc(indent) inc(indent)
elif buf[pos] == '#' and buf[pos+1] == '[': elif buf[pos] == '#' and buf[pos+1] == '[':
when defined(nimpretty): hasComment = true when defined(nimpretty):
hasComment = true
if tok.line < 0:
tok.line = L.lineNumber
skipMultiLineComment(L, tok, pos+2, false) skipMultiLineComment(L, tok, pos+2, false)
pos = L.bufpos pos = L.bufpos
buf = L.buf buf = L.buf
else: else:
break break
tok.strongSpaceA = 0 tok.strongSpaceA = 0
when defined(nimpretty):
if buf[pos] == '#' and tok.line < 0: commentIndent = indent
if buf[pos] > ' ' and (buf[pos] != '#' or buf[pos+1] == '#'): if buf[pos] > ' ' and (buf[pos] != '#' or buf[pos+1] == '#'):
tok.indent = indent tok.indent = indent
L.currLineIndent = indent L.currLineIndent = indent
@ -1155,7 +1161,8 @@ proc skip(L: var TLexer, tok: var TToken) =
if buf[pos+1] == '#': break if buf[pos+1] == '#': break
when defined(nimpretty): when defined(nimpretty):
hasComment = true hasComment = true
if tok.line < 0: tok.line = L.lineNumber if tok.line < 0:
tok.line = L.lineNumber
if buf[pos+1] == '[': if buf[pos+1] == '[':
skipMultiLineComment(L, tok, pos+2, false) skipMultiLineComment(L, tok, pos+2, false)
@ -1177,6 +1184,7 @@ proc skip(L: var TLexer, tok: var TToken) =
if hasComment: if hasComment:
tok.commentOffsetB = L.offsetBase + pos - 1 tok.commentOffsetB = L.offsetBase + pos - 1
tok.tokType = tkComment tok.tokType = tkComment
tok.indent = commentIndent
if gIndentationWidth <= 0: if gIndentationWidth <= 0:
gIndentationWidth = tok.indent gIndentationWidth = tok.indent

View file

@ -1414,6 +1414,20 @@ proc semTypeof(c: PContext; n: PNode; prev: PType): PType =
fixupTypeOf(c, prev, t) fixupTypeOf(c, prev, t)
result = t.typ result = t.typ
proc semTypeof2(c: PContext; n: PNode; prev: PType): PType =
openScope(c)
var m = BiggestInt 1 # typeOfIter
if n.len == 3:
let mode = semConstExpr(c, n[2])
if mode.kind != nkIntLit:
localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
else:
m = mode.intVal
let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
closeScope(c)
fixupTypeOf(c, prev, t)
result = t.typ
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = nil result = nil
inc c.inTypeContext inc c.inTypeContext
@ -1494,6 +1508,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
elif op.id == ord(wType): elif op.id == ord(wType):
checkSonsLen(n, 2, c.config) checkSonsLen(n, 2, c.config)
result = semTypeof(c, n[1], prev) result = semTypeof(c, n[1], prev)
elif op.s == "typeof" and n[0].kind == nkSym and n[0].sym.magic == mTypeof:
result = semTypeOf2(c, n, prev)
else: else:
if c.inGenericContext > 0 and n.kind == nkCall: if c.inGenericContext > 0 and n.kind == nkCall:
result = makeTypeFromExpr(c, n.copyTree) result = makeTypeFromExpr(c, n.copyTree)

View file

@ -73,6 +73,19 @@ path="$lib/pure"
opt:speed opt:speed
@end @end
@if unix and mingw:
# Cross compile for Windows from Linux/OSX using MinGW
os = windows
i386.windows.gcc.path = "/usr/bin"
i386.windows.gcc.exe = "i686-w64-mingw32-gcc"
i386.windows.gcc.linkerexe = "i686-w64-mingw32-gcc"
amd64.windows.gcc.path = "/usr/bin"
amd64.windows.gcc.exe = "x86_64-w64-mingw32-gcc"
amd64.windows.gcc.linkerexe = "x86_64-w64-mingw32-gcc"
@end
@if unix: @if unix:
@if not bsd or haiku: @if not bsd or haiku:
# -fopenmp # -fopenmp

View file

@ -261,6 +261,21 @@ configuration file should contain something like::
arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.exe = "arm-linux-gcc"
arm.linux.gcc.linkerexe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc"
Cross compilation for Windows
=============================
To cross compile for Windows from Linux or OSX using the MinGW-w64 toolchain::
nim c -d:mingw myproject.nim
Use ``--cpu:i386`` or ``--cpu:amd64`` to switch the cpu arch.
The MinGW-w64 toolchain can be installed as follows::
Ubuntu: apt install mingw-w64
CentOS: yum install mingw32-gcc | mingw64-gcc - requires EPEL
OSX: brew install mingw-w64
Cross compilation for Nintendo Switch Cross compilation for Nintendo Switch
===================================== =====================================

View file

@ -407,13 +407,14 @@ proc temp(args: string) =
result[1].add " " & quoteShell(args[i]) result[1].add " " & quoteShell(args[i])
inc i inc i
var output = "compiler" / "nim".exe let d = getAppDir()
var finalDest = "bin" / "nim_temp".exe var output = d / "compiler" / "nim".exe
var finalDest = d / "bin" / "nim_temp".exe
# 125 is the magic number to tell git bisect to skip the current # 125 is the magic number to tell git bisect to skip the current
# commit. # commit.
let (bootArgs, programArgs) = splitArgs(args) let (bootArgs, programArgs) = splitArgs(args)
let nimexec = findNim() let nimexec = findNim()
exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " compiler" / "nim", 125) exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " " & (d / "compiler" / "nim"), 125)
copyExe(output, finalDest) copyExe(output, finalDest)
if programArgs.len > 0: exec(finalDest & " " & programArgs) if programArgs.len > 0: exec(finalDest & " " & programArgs)

View file

@ -673,6 +673,12 @@ template mapIt*(s: typed, op: untyped): untyped =
## nums = @[1, 2, 3, 4] ## nums = @[1, 2, 3, 4]
## strings = nums.mapIt($(4 * it)) ## strings = nums.mapIt($(4 * it))
## assert strings == @["4", "8", "12", "16"] ## assert strings == @["4", "8", "12", "16"]
when defined(nimHasTypeof):
type outType = typeof((
block:
var it{.inject.}: typeof(items(s), typeOfIter);
op), typeOfProc)
else:
type outType = type(( type outType = type((
block: block:
var it{.inject.}: type(items(s)); var it{.inject.}: type(items(s));
@ -1135,5 +1141,13 @@ when isMainModule:
A, B A, B
doAssert mapIt(X, $it) == @["A", "B"] doAssert mapIt(X, $it) == @["A", "B"]
block:
# bug #9093
let inp = "a:b,c:d"
let outp = inp.split(",").mapIt(it.split(":"))
doAssert outp == @[@["a", "b"], @["c", "d"]]
when not defined(testing): when not defined(testing):
echo "Finished doc tests" echo "Finished doc tests"

View file

@ -278,7 +278,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
rtl, extern: "npuParseInt", noSideEffect.} = rtl, extern: "npuParseInt", noSideEffect.} =
## parses an integer starting at `start` and stores the value into `number`. ## parses an integer starting at `start` and stores the value into `number`.
## Result is the number of processed chars or 0 if there is no integer. ## Result is the number of processed chars or 0 if there is no integer.
## `EOverflow` is raised if an overflow occurs. ## `OverflowError` is raised if an overflow occurs.
var res: BiggestInt var res: BiggestInt
result = parseBiggestInt(s, res, start) result = parseBiggestInt(s, res, start)
if (sizeof(int) <= 4) and if (sizeof(int) <= 4) and
@ -289,7 +289,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
proc parseSaturatedNatural*(s: string, b: var int, start = 0): int = proc parseSaturatedNatural*(s: string, b: var int, start = 0): int =
## parses a natural number into ``b``. This cannot raise an overflow ## parses a natural number into ``b``. This cannot raise an overflow
## error. Instead of an ``Overflow`` exception ``high(int)`` is returned. ## error. ``high(int)`` is returned for an overflow.
## The number of processed character is returned. ## The number of processed character is returned.
## This is usually what you really want to use instead of `parseInt`:idx:. ## This is usually what you really want to use instead of `parseInt`:idx:.
## Example: ## Example:

View file

@ -180,6 +180,15 @@ else:
## Cannot be overloaded. ## Cannot be overloaded.
discard discard
when defined(nimHasTypeof):
type
TypeOfMode* = enum ## Possible modes of `typeof`.
typeOfProc, ## Prefer the interpretation that means `x` is a proc call.
typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
proc typeof*(x: untyped; mode = typeOfIter): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
## Builtin 'typeof' operation for accessing the type of an expression. Since version 0.20.0.
discard
proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.} proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.}
## Boolean not; returns true iff ``x == false``. ## Boolean not; returns true iff ``x == false``.

View file

@ -15,12 +15,12 @@ when defined(develop):
else: else:
const nimp = "nimpretty" const nimp = "nimpretty"
proc test(infile, outfile: string) = proc test(infile, ext: string) =
if execShellCmd("$# -o:$# --backup:off $#" % [nimp, outfile, infile]) != 0: if execShellCmd("$# -o:$# --backup:off $#" % [nimp, infile.changeFileExt(ext), infile]) != 0:
quit("FAILURE") quit("FAILURE")
let nimFile = splitFile(infile).name let nimFile = splitFile(infile).name
let expected = dir / "expected" / nimFile & ".nim" let expected = dir / "expected" / nimFile & ".nim"
let produced = dir / nimFile & ".pretty" let produced = dir / nimFile.changeFileExt(ext)
if strip(readFile(expected)) != strip(readFile(produced)): if strip(readFile(expected)) != strip(readFile(produced)):
echo "FAILURE: files differ: ", nimFile echo "FAILURE: files differ: ", nimFile
discard execShellCmd("diff -uNdr " & expected & " " & produced) discard execShellCmd("diff -uNdr " & expected & " " & produced)
@ -29,8 +29,12 @@ proc test(infile, outfile: string) =
echo "SUCCESS: files identical: ", nimFile echo "SUCCESS: files identical: ", nimFile
for t in walkFiles(dir / "*.nim"): for t in walkFiles(dir / "*.nim"):
let res = t.changeFileExt("pretty") test(t, "pretty")
test(t, res) # also test that pretty(pretty(x)) == pretty(x)
removeFile(res) test(t.changeFileExt("pretty"), "pretty2")
removeFile(t.changeFileExt("pretty"))
removeFile(t.changeFileExt("pretty2"))
if failures > 0: quit($failures & " failures occurred.") if failures > 0: quit($failures & " failures occurred.")

View file

@ -1,4 +1,13 @@
var x: int = 2 var x: int = 2
echo x # bug #9144 echo x
# bug #9144
proc a() =
while true:
discard
# comment 1
# comment 2
discard

View file

@ -7,3 +7,16 @@ proc fun*() =
echo "ok" echo "ok"
## doc comment ## doc comment
# regular comment # regular comment
proc funB() =
echo "ok1"
# echo "ok2"
fun()
#[
bug #9483
]#
proc funE() =
echo "ok1"

View file

@ -0,0 +1,9 @@
#[
foo bar
]#
proc fun() =
echo "ok1"

View file

@ -3,3 +3,11 @@ var x: int = 2
echo x echo x
# bug #9144 # bug #9144
proc a() =
while true:
discard
# comment 1
# comment 2
discard

View file

@ -7,3 +7,16 @@ proc fun*()=
echo "ok" echo "ok"
## doc comment ## doc comment
# regular comment # regular comment
proc funB() =
echo "ok1"
# echo "ok2"
fun()
#[
bug #9483
]#
proc funE() =
echo "ok1"

View file

@ -0,0 +1,9 @@
#[
foo bar
]#
proc fun() =
echo "ok1"

View file

@ -1,16 +1,22 @@
discard """ discard """
output: ''' output: '''
yeah A enumB yeah A enumB
uneven
yeah A enumB yeah A enumB
yeah CD enumD yeah CD enumD
uneven
yeah CD enumE yeah CD enumE
yeah A enumB yeah A enumB
uneven
yeah CD enumE yeah CD enumE
yeah CD enumD yeah CD enumD
uneven
yeah A enumB yeah A enumB
yeah B enumC yeah B enumC
uneven
yeah A enumB yeah A enumB
yeah A enumB yeah A enumB
uneven
yeah A enumB yeah A enumB
''' '''
""" """
@ -47,4 +53,7 @@ proc vm() =
of enumLast: discard of enumLast: discard
inc(pc) inc(pc)
if pc mod 2 == 1:
echo "uneven"
vm() vm()

View file

@ -1,5 +1,6 @@
discard """ discard """
errormsg: "type mismatch: got <Bar[system.int]>" errormsg: "type mismatch: got <Bar[system.int]>"
disabled: "true"
nimout: ''' nimout: '''
t3330.nim(63, 4) Error: type mismatch: got <Bar[system.int]> t3330.nim(63, 4) Error: type mismatch: got <Bar[system.int]>
but expected one of: but expected one of:

View file

@ -209,6 +209,25 @@ class NimStringPrinter:
else: else:
return "" return ""
class NimRopePrinter:
pattern = re.compile(r'^tyObject_RopeObj_OFzf0kSiPTcNreUIeJgWVA \*$')
def __init__(self, val):
self.val = val
def display_hint(self):
return 'string'
def to_string(self):
if self.val:
left = NimRopePrinter(self.val["left"]).to_string()
data = NimStringPrinter(self.val["data"]).to_string()
right = NimRopePrinter(self.val["right"]).to_string()
return left + data + right
else:
return ""
################################################################################ ################################################################################
# proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = # proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =