diff options
Diffstat (limited to 'compiler/renderer.nim')
-rw-r--r-- | compiler/renderer.nim | 268 |
1 files changed, 161 insertions, 107 deletions
diff --git a/compiler/renderer.nim b/compiler/renderer.nim index fa93c968a..aa666290c 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -10,7 +10,7 @@ # This module implements the renderer of the standard Nim representation. import - lexer, options, idents, strutils, ast, msgs + lexer, options, idents, strutils, ast, msgs, lineinfos type TRenderFlag* = enum @@ -39,8 +39,8 @@ type inPragma: int when defined(nimpretty): pendingNewlineCount: int - origContent: string - + fid*: FileIndex + config*: ConfigRef # We render the source code in a two phases: The first # determines how long the subtree will likely be, the second @@ -91,7 +91,7 @@ const MaxLineLen = 80 LineCommentColumn = 30 -proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) = +proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags; config: ConfigRef) = g.comStack = @[] g.tokens = @[] g.indent = 0 @@ -103,6 +103,7 @@ proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) = g.pendingNL = -1 g.pendingWhitespace = -1 g.inGenericParams = false + g.config = config proc addTok(g: var TSrcGen, kind: TTokType, s: string) = var length = len(g.tokens) @@ -173,34 +174,14 @@ proc put(g: var TSrcGen, kind: TTokType, s: string) = else: g.pendingWhitespace = s.len -proc toNimChar(c: char): string = - case c - of '\0': result = "\\x00" # not "\\0" to avoid ambiguous cases like "\\012". - of '\a': result = "\\a" # \x07 - of '\b': result = "\\b" # \x08 - of '\t': result = "\\t" # \x09 - of '\L': result = "\\L" # \x0A - of '\v': result = "\\v" # \x0B - of '\f': result = "\\f" # \x0C - of '\c': result = "\\c" # \x0D - of '\e': result = "\\e" # \x1B - of '\x01'..'\x06', '\x0E'..'\x1A', '\x1C'..'\x1F', '\x80'..'\xFF': - result = "\\x" & strutils.toHex(ord(c), 2) - of '\'', '\"', '\\': result = '\\' & c - else: result = c & "" - -proc makeNimString(s: string): string = - result = "\"" - for i in countup(0, len(s)-1): add(result, toNimChar(s[i])) - add(result, '\"') - proc putComment(g: var TSrcGen, s: string) = - if s.isNil: return + if s.len == 0: return var i = 0 + let hi = len(s) - 1 var isCode = (len(s) >= 2) and (s[1] != ' ') var ind = g.lineLen var com = "## " - while true: + while i <= hi: case s[i] of '\0': break @@ -208,7 +189,7 @@ proc putComment(g: var TSrcGen, s: string) = put(g, tkComment, com) com = "## " inc(i) - if s[i] == '\x0A': inc(i) + if i <= hi and s[i] == '\x0A': inc(i) optNL(g, ind) of '\x0A': put(g, tkComment, com) @@ -223,28 +204,29 @@ proc putComment(g: var TSrcGen, s: string) = # gets too long: # compute length of the following word: var j = i - while s[j] > ' ': inc(j) + while j <= hi and s[j] > ' ': inc(j) if not isCode and (g.lineLen + (j - i) > MaxLineLen): put(g, tkComment, com) optNL(g, ind) com = "## " - while s[i] > ' ': + while i <= hi and s[i] > ' ': add(com, s[i]) inc(i) put(g, tkComment, com) optNL(g) proc maxLineLength(s: string): int = - if s.isNil: return 0 + if s.len == 0: return 0 var i = 0 + let hi = len(s) - 1 var lineLen = 0 - while true: + while i <= hi: case s[i] of '\0': break of '\x0D': inc(i) - if s[i] == '\x0A': inc(i) + if i <= hi and s[i] == '\x0A': inc(i) result = max(result, lineLen) lineLen = 0 of '\x0A': @@ -257,7 +239,7 @@ proc maxLineLength(s: string): int = proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) = var i = 0 - var hi = len(s) - 1 + let hi = len(s) - 1 var str = "" while i <= hi: case s[i] @@ -265,7 +247,7 @@ proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) = put(g, kind, str) str = "" inc(i) - if (i <= hi) and (s[i] == '\x0A'): inc(i) + if i <= hi and s[i] == '\x0A': inc(i) optNL(g, 0) of '\x0A': put(g, kind, str) @@ -299,7 +281,7 @@ const proc shouldRenderComment(g: var TSrcGen, n: PNode): bool = result = false - if n.comment != nil: + if n.comment.len > 0: result = (renderNoComments notin g.flags) or (renderDocComments in g.flags) @@ -325,14 +307,19 @@ proc lsub(g: TSrcGen; n: PNode): int proc litAux(g: TSrcGen; n: PNode, x: BiggestInt, size: int): string = proc skip(t: PType): PType = result = t - while result.kind in {tyGenericInst, tyRange, tyVar, tyLent, tyDistinct, + while result != nil and result.kind in {tyGenericInst, tyRange, tyVar, tyLent, tyDistinct, tyOrdinal, tyAlias, tySink}: result = lastSon(result) - if n.typ != nil and n.typ.skip.kind in {tyBool, tyEnum}: - let enumfields = n.typ.skip.n + let typ = n.typ.skip + if typ != nil and typ.kind in {tyBool, tyEnum}: + if sfPure in typ.sym.flags: + result = typ.sym.name.s & '.' + let enumfields = typ.n # we need a slow linear search because of enums with holes: for e in items(enumfields): - if e.sym.position == x: return e.sym.name.s + if e.sym.position == x: + result &= e.sym.name.s + return if nfBase2 in n.flags: result = "0b" & toBin(x, size * 8) elif nfBase8 in n.flags: result = "0o" & toOct(x, size * 3) @@ -348,23 +335,27 @@ proc ulitAux(g: TSrcGen; n: PNode, x: BiggestInt, size: int): string = proc atom(g: TSrcGen; n: PNode): string = when defined(nimpretty): + doAssert g.config != nil, "g.config not initialized!" let comment = if n.info.commentOffsetA < n.info.commentOffsetB: - " " & substr(g.origContent, n.info.commentOffsetA, n.info.commentOffsetB) + " " & fileSection(g.config, g.fid, n.info.commentOffsetA, n.info.commentOffsetB) else: "" if n.info.offsetA <= n.info.offsetB: # for some constructed tokens this can not be the case and we're better # off to not mess with the offset then. - return substr(g.origContent, n.info.offsetA, n.info.offsetB) & comment + return fileSection(g.config, g.fid, n.info.offsetA, n.info.offsetB) & comment var f: float32 case n.kind of nkEmpty: result = "" of nkIdent: result = n.ident.s of nkSym: result = n.sym.name.s - of nkStrLit: result = makeNimString(n.strVal) - of nkRStrLit: result = "r\"" & replace(n.strVal, "\"", "\"\"") & '\"' + of nkStrLit: result = ""; result.addQuoted(n.strVal) + of nkRStrLit: result = "r\"" & replace(n.strVal, "\"", "\"\"") & '\"' of nkTripleStrLit: result = "\"\"\"" & n.strVal & "\"\"\"" - of nkCharLit: result = '\'' & toNimChar(chr(int(n.intVal))) & '\'' + of nkCharLit: + result = "\'" + result.addEscapedChar(chr(int(n.intVal))); + result.add '\'' of nkIntLit: result = litAux(g, n, n.intVal, 4) of nkInt8Lit: result = litAux(g, n, n.intVal, 1) & "\'i8" of nkInt16Lit: result = litAux(g, n, n.intVal, 2) & "\'i16" @@ -394,15 +385,17 @@ proc atom(g: TSrcGen; n: PNode): string = if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s else: result = "[type node]" else: - internalError("rnimsyn.atom " & $n.kind) + internalError(g.config, "rnimsyn.atom " & $n.kind) result = "" proc lcomma(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int = assert(theEnd < 0) result = 0 for i in countup(start, sonsLen(n) + theEnd): - inc(result, lsub(g, n.sons[i])) - inc(result, 2) # for ``, `` + let param = n.sons[i] + if nfDefaultParam notin param.flags: + inc(result, lsub(g, param)) + inc(result, 2) # for ``, `` if result > 0: dec(result, 2) # last does not get a comma! @@ -414,7 +407,7 @@ proc lsons(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int = proc lsub(g: TSrcGen; n: PNode): int = # computes the length of a tree if isNil(n): return 0 - if n.comment != nil: return MaxLineLen + 1 + if n.comment.len > 0: return MaxLineLen + 1 case n.kind of nkEmpty: result = 0 of nkTripleStrLit: @@ -428,10 +421,13 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkCast: result = lsub(g, n.sons[0]) + lsub(g, n.sons[1]) + len("cast[]()") of nkAddr: result = (if n.len>0: lsub(g, n.sons[0]) + len("addr()") else: 4) of nkStaticExpr: result = lsub(g, n.sons[0]) + len("static_") - of nkHiddenAddr, nkHiddenDeref: result = lsub(g, n.sons[0]) + of nkHiddenAddr, nkHiddenDeref, nkStringToCString, nkCStringToString: result = lsub(g, n.sons[0]) of nkCommand: result = lsub(g, n.sons[0]) + lcomma(g, n, 1) + 1 of nkExprEqExpr, nkAsgn, nkFastAsgn: result = lsons(g, n) + 3 of nkPar, nkCurly, nkBracket, nkClosure: result = lcomma(g, n) + 2 + of nkTupleConstr: + # assume the trailing comma: + result = lcomma(g, n) + 3 of nkArgList: result = lcomma(g, n) of nkTableConstr: result = if n.len > 0: lcomma(g, n) + 2 else: len("{:}") @@ -455,7 +451,7 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkChckRangeF: result = len("chckRangeF") + 2 + lcomma(g, n) of nkChckRange64: result = len("chckRange64") + 2 + lcomma(g, n) of nkChckRange: result = len("chckRange") + 2 + lcomma(g, n) - of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString: + of nkObjDownConv, nkObjUpConv: result = 2 if sonsLen(n) >= 1: result = result + lsub(g, n.sons[0]) result = result + lcomma(g, n, 1) @@ -509,7 +505,7 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkBreakStmt: result = lsub(g, n.sons[0]) + len("break_") of nkContinueStmt: result = lsub(g, n.sons[0]) + len("continue_") of nkPragma: result = lcomma(g, n) + 4 - of nkCommentStmt: result = if n.comment.isNil: 0 else: len(n.comment) + of nkCommentStmt: result = len(n.comment) of nkOfBranch: result = lcomma(g, n, 0, - 2) + lsub(g, lastSon(n)) + len("of_:_") of nkImportAs: result = lsub(g, n.sons[0]) + len("_as_") + lsub(g, n.sons[1]) of nkElifBranch: result = lsons(g, n) + len("elif_:_") @@ -548,7 +544,7 @@ proc gsub(g: var TSrcGen, n: PNode) = proc hasCom(n: PNode): bool = result = false if n.isNil: return false - if n.comment != nil: return true + if n.comment.len > 0: return true case n.kind of nkEmpty..nkNilLit: discard else: @@ -611,7 +607,7 @@ proc gsection(g: var TSrcGen, n: PNode, c: TContext, kind: TTokType, dedent(g) proc longMode(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): bool = - result = n.comment != nil + result = n.comment.len > 0 if not result: # check further for i in countup(start, sonsLen(n) + theEnd): @@ -636,15 +632,23 @@ proc gstmts(g: var TSrcGen, n: PNode, c: TContext, doIndent=true) = gcoms(g) if doIndent: dedent(g) else: - if rfLongMode in c.flags: indentNL(g) + indentNL(g) gsub(g, n) gcoms(g) + dedent(g) optNL(g) - if rfLongMode in c.flags: dedent(g) + + +proc gcond(g: var TSrcGen, n: PNode) = + if n.kind == nkStmtListExpr: + put(g, tkParLe, "(") + gsub(g, n) + if n.kind == nkStmtListExpr: + put(g, tkParRi, ")") proc gif(g: var TSrcGen, n: PNode) = var c: TContext - gsub(g, n.sons[0].sons[0]) + gcond(g, n.sons[0].sons[0]) initContext(c) putWithSpace(g, tkColon, ":") if longMode(g, n) or (lsub(g, n.sons[0].sons[1]) + g.lineLen > MaxLineLen): @@ -659,7 +663,7 @@ proc gif(g: var TSrcGen, n: PNode) = proc gwhile(g: var TSrcGen, n: PNode) = var c: TContext putWithSpace(g, tkWhile, "while") - gsub(g, n.sons[0]) + gcond(g, n.sons[0]) putWithSpace(g, tkColon, ":") initContext(c) if longMode(g, n) or (lsub(g, n.sons[1]) + g.lineLen > MaxLineLen): @@ -723,7 +727,7 @@ proc gcase(g: var TSrcGen, n: PNode) = var last = if n.sons[length-1].kind == nkElse: -2 else: -1 if longMode(g, n, 0, last): incl(c.flags, rfLongMode) putWithSpace(g, tkCase, "case") - gsub(g, n.sons[0]) + gcond(g, n.sons[0]) gcoms(g) optNL(g) gsons(g, n, c, 1, last) @@ -753,7 +757,8 @@ proc gproc(g: var TSrcGen, n: PNode) = gsub(g, n.sons[genericParamsPos]) g.inGenericParams = oldInGenericParams gsub(g, n.sons[paramsPos]) - gsub(g, n.sons[pragmasPos]) + if renderNoPragmas notin g.flags: + gsub(g, n.sons[pragmasPos]) if renderNoBody notin g.flags: if n.sons[bodyPos].kind != nkEmpty: put(g, tkSpaces, Space) @@ -794,10 +799,7 @@ proc gblock(g: var TSrcGen, n: PNode) = if longMode(g, n) or (lsub(g, n.sons[1]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) - # XXX I don't get why this is needed here! gstmts should already handle this! - indentNL(g) gstmts(g, n.sons[1], c) - dedent(g) proc gstaticStmt(g: var TSrcGen, n: PNode) = var c: TContext @@ -823,8 +825,8 @@ proc gident(g: var TSrcGen, n: PNode) = var t: TTokType var s = atom(g, n) - if (s[0] in lexer.SymChars): - if (n.kind == nkIdent): + if s.len > 0 and s[0] in lexer.SymChars: + if n.kind == nkIdent: if (n.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or (n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)): t = tkSymbol @@ -864,11 +866,52 @@ proc isBracket*(n: PNode): bool = of nkSym: result = n.sym.name.s == "[]" else: result = false +proc skipHiddenNodes(n: PNode): PNode = + result = n + while result != nil: + if result.kind in {nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv} and result.len > 1: + result = result[1] + elif result.kind in {nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref, nkStringToCString, nkCStringToString} and + result.len > 0: + result = result[0] + else: break + +proc accentedName(g: var TSrcGen, n: PNode) = + if n == nil: return + let isOperator = + if n.kind == nkIdent and n.ident.s.len > 0 and n.ident.s[0] in OpChars: true + elif n.kind == nkSym and n.sym.name.s.len > 0 and n.sym.name.s[0] in OpChars: true + else: false + + if isOperator: + put(g, tkAccent, "`") + gident(g, n) + put(g, tkAccent, "`") + else: + gsub(g, n) + +proc infixArgument(g: var TSrcGen, n: PNode, i: int) = + if i >= n.len: return + + var needsParenthesis = false + let n_next = n[i].skipHiddenNodes + if n_next.kind == nkInfix: + if n_next[0].kind in {nkSym, nkIdent} and n[0].kind in {nkSym, nkIdent}: + let nextId = if n_next[0].kind == nkSym: n_next[0].sym.name else: n_next[0].ident + let nnId = if n[0].kind == nkSym: n[0].sym.name else: n[0].ident + if getPrecedence(nextId) < getPrecedence(nnId): + needsParenthesis = true + if needsParenthesis: + put(g, tkParLe, "(") + gsub(g, n, i) + if needsParenthesis: + put(g, tkParRi, ")") + proc gsub(g: var TSrcGen, n: PNode, c: TContext) = if isNil(n): return var a: TContext - if n.comment != nil: pushCom(g, n) + if n.comment.len > 0: pushCom(g, n) case n.kind # atoms: of nkTripleStrLit: put(g, tkTripleStrLit, atom(g, n)) of nkEmpty: discard @@ -899,7 +942,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gcomma(g, n, 2) put(g, tkBracketRi, "]") elif n.len > 1 and n.lastSon.kind == nkStmtList: - gsub(g, n[0]) + accentedName(g, n[0]) if n.len > 2: put(g, tkParLe, "(") gcomma(g, n, 1, -2) @@ -907,16 +950,16 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkColon, ":") gsub(g, n, n.len-1) else: - if sonsLen(n) >= 1: gsub(g, n.sons[0]) + if sonsLen(n) >= 1: accentedName(g, n[0]) put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") of nkCallStrLit: - gsub(g, n, 0) + if n.len > 0: accentedName(g, n[0]) if n.len > 1 and n.sons[1].kind == nkRStrLit: put(g, tkRStrLit, '\"' & replace(n[1].strVal, "\"", "\"\"") & '\"') else: - gsub(g, n.sons[1]) + gsub(g, n, 1) of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv: if n.len >= 2: gsub(g, n.sons[1]) @@ -954,7 +997,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gsub(g, n, 0) gcomma(g, n, 1) of nkCommand: - gsub(g, n, 0) + accentedName(g, n[0]) put(g, tkSpaces, Space) gcomma(g, n, 1) of nkExprEqExpr, nkAsgn, nkFastAsgn: @@ -977,7 +1020,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkParLe, "(") gcomma(g, n) put(g, tkParRi, ")") - of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString: + of nkObjDownConv, nkObjUpConv: if sonsLen(n) >= 1: gsub(g, n.sons[0]) put(g, tkParLe, "(") gcomma(g, n, 1) @@ -1002,6 +1045,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkParLe, "(") gcomma(g, n, c) put(g, tkParRi, ")") + of nkTupleConstr: + put(g, tkParLe, "(") + gcomma(g, n, c) + if n.len == 1: put(g, tkComma, ",") + put(g, tkParRi, ")") of nkCurly: put(g, tkCurlyLe, "{") gcomma(g, n, c) @@ -1024,7 +1072,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkBind: putWithSpace(g, tkBind, "bind") gsub(g, n, 0) - of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref: + of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref, nkStringToCString, nkCStringToString: gsub(g, n, 0) of nkLambda: putWithSpace(g, tkProc, "proc") @@ -1062,23 +1110,25 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = putWithSpace(g, tkColon, ":") gsub(g, n, 1) of nkInfix: - gsub(g, n, 1) + infixArgument(g, n, 1) put(g, tkSpaces, Space) gsub(g, n, 0) # binary operator if not fits(g, lsub(g, n.sons[2]) + lsub(g, n.sons[0]) + 1): optNL(g, g.indent + longIndentWid) else: put(g, tkSpaces, Space) - gsub(g, n, 2) + infixArgument(g, n, 2) of nkPrefix: gsub(g, n, 0) if n.len > 1: let opr = if n[0].kind == nkIdent: n[0].ident elif n[0].kind == nkSym: n[0].sym.name + elif n[0].kind in {nkOpenSymChoice, nkClosedSymChoice}: n[0][0].sym.name else: nil - if n[1].kind == nkPrefix or (opr != nil and renderer.isKeyword(opr)): + let n_next = skipHiddenNodes(n[1]) + if n_next.kind == nkPrefix or (opr != nil and renderer.isKeyword(opr)): put(g, tkSpaces, Space) - if n.sons[1].kind == nkInfix: + if n_next.kind == nkInfix: put(g, tkParLe, "(") gsub(g, n.sons[1]) put(g, tkParRi, ")") @@ -1103,13 +1153,13 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkAccent, "`") of nkIfExpr: putWithSpace(g, tkIf, "if") - if n.len > 0: gsub(g, n.sons[0], 0) + if n.len > 0: gcond(g, n.sons[0].sons[0]) putWithSpace(g, tkColon, ":") if n.len > 0: gsub(g, n.sons[0], 1) gsons(g, n, emptyContext, 1) of nkElifExpr: putWithSpace(g, tkElif, " elif") - gsub(g, n, 0) + gcond(g, n[0]) putWithSpace(g, tkColon, ":") gsub(g, n, 1) of nkElseExpr: @@ -1291,17 +1341,16 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = putWithSpace(g, tkContinue, "continue") gsub(g, n, 0) of nkPragma: - if renderNoPragmas notin g.flags: - if g.inPragma <= 0: - inc g.inPragma - #if not previousNL(g): - put(g, tkSpaces, Space) - put(g, tkCurlyDotLe, "{.") - gcomma(g, n, emptyContext) - put(g, tkCurlyDotRi, ".}") - dec g.inPragma - else: - gcomma(g, n, emptyContext) + if g.inPragma <= 0: + inc g.inPragma + #if not previousNL(g): + put(g, tkSpaces, Space) + put(g, tkCurlyDotLe, "{.") + gcomma(g, n, emptyContext) + put(g, tkCurlyDotRi, ".}") + dec g.inPragma + else: + gcomma(g, n, emptyContext) of nkImportStmt, nkExportStmt: if n.kind == nkImportStmt: putWithSpace(g, tkImport, "import") @@ -1419,22 +1468,32 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkParLe, "(ComesFrom|") gsub(g, n, 0) put(g, tkParRi, ")") - of nkGotoState, nkState: + of nkGotoState: var c: TContext initContext c - putWithSpace g, tkSymbol, if n.kind == nkState: "state" else: "goto" + putWithSpace g, tkSymbol, "goto" gsons(g, n, c) + of nkState: + var c: TContext + initContext c + putWithSpace g, tkSymbol, "state" + gsub(g, n[0], c) + putWithSpace(g, tkColon, ":") + indentNL(g) + gsons(g, n, c, 1) + dedent(g) + of nkBreakState: put(g, tkTuple, "breakstate") of nkTypeClassTy: gTypeClassTy(g, n) else: #nkNone, nkExplicitTypeListCall: - internalError(n.info, "rnimsyn.gsub(" & $n.kind & ')') + internalError(g.config, n.info, "rnimsyn.gsub(" & $n.kind & ')') proc renderTree*(n: PNode, renderFlags: TRenderFlags = {}): string = var g: TSrcGen - initSrcGen(g, renderFlags) + initSrcGen(g, renderFlags, newPartialConfigRef()) # do not indent the initial statement list so that # writeFile("file.nim", repr n) # produces working Nim code: @@ -1447,17 +1506,14 @@ proc renderTree*(n: PNode, renderFlags: TRenderFlags = {}): string = proc `$`*(n: PNode): string = n.renderTree proc renderModule*(n: PNode, infile, outfile: string, - renderFlags: TRenderFlags = {}) = + renderFlags: TRenderFlags = {}; + fid = FileIndex(-1); + conf: ConfigRef = nil) = var f: File g: TSrcGen - initSrcGen(g, renderFlags) - when defined(nimpretty): - try: - g.origContent = readFile(infile) - except IOError: - rawMessage(errCannotOpenFile, infile) - + initSrcGen(g, renderFlags, conf) + g.fid = fid for i in countup(0, sonsLen(n) - 1): gsub(g, n.sons[i]) optNL(g) @@ -1466,16 +1522,14 @@ proc renderModule*(n: PNode, infile, outfile: string, nkCommentStmt: putNL(g) else: discard gcoms(g) - if optStdout in gGlobalOptions: - write(stdout, g.buf) - elif open(f, outfile, fmWrite): + if open(f, outfile, fmWrite): write(f, g.buf) close(f) else: - rawMessage(errCannotOpenFile, outfile) + rawMessage(g.config, errGenerated, "cannot open file: " & outfile) proc initTokRender*(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) = - initSrcGen(r, renderFlags) + initSrcGen(r, renderFlags, newPartialConfigRef()) gsub(r, n) proc getNextTok*(r: var TSrcGen, kind: var TTokType, literal: var string) = |