summary refs log blame commit diff stats
path: root/compiler/main.nim
blob: f662ded1ba9731d487e6e126c60f196bcd726cc1 (plain) (tree)
"p">: if rfLongMode in c.flags: indentNL(g) gsub(g, n) gcoms(g) optNL(g) if rfLongMode in c.flags: dedent(g) proc gif(g: var TSrcGen, n: PNode) = var c: TContext gsub(g, n.sons[0].sons[0]) initContext(c) putWithSpace(g, tkColon, ":") if longMode(n) or (lsub(n.sons[0].sons[1]) + g.lineLen > maxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0].sons[1], c) var length = sonsLen(n) for i in countup(1, length - 1): optNL(g) gsub(g, n.sons[i], c) proc gwhile(g: var TSrcGen, n: PNode) = var c: TContext putWithSpace(g, tkWhile, "while") gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") initContext(c) if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[1], c) proc gpragmaBlock(g: var TSrcGen, n: PNode) = var c: TContext gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") initContext(c) if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[1], c) proc gtry(g: var TSrcGen, n: PNode) = var c: TContext put(g, tkTry, "try") putWithSpace(g, tkColon, ":") initContext(c) if longMode(n) or (lsub(n.sons[0]) + g.lineLen > maxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0], c) gsons(g, n, c, 1) proc gfor(g: var TSrcGen, n: PNode) = var c: TContext var length = sonsLen(n) putWithSpace(g, tkFor, "for") initContext(c) if longMode(n) or (lsub(n.sons[length - 1]) + lsub(n.sons[length - 2]) + 6 + g.lineLen > maxLineLen): incl(c.flags, rfLongMode) gcomma(g, n, c, 0, - 3) put(g, tkSpaces, Space) putWithSpace(g, tkIn, "in") gsub(g, n.sons[length - 2], c) putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, n.sons[length - 1], c) proc gmacro(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): incl(c.flags, rfLongMode) gcoms(g) gsons(g, n, c, 1) proc gcase(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) var length = sonsLen(n) var last = if n.sons[length-1].kind == nkElse: -2 else: -1 if longMode(n, 0, last): incl(c.flags, rfLongMode) putWithSpace(g, tkCase, "case") gsub(g, n.sons[0]) gcoms(g) optNL(g) gsons(g, n, c, 1, last) if last == - 2: initContext(c) if longMode(n.sons[length - 1]): incl(c.flags, rfLongMode) gsub(g, n.sons[length - 1], c) proc gproc(g: var TSrcGen, n: PNode) = var c: TContext gsub(g, n.sons[0]) gsub(g, n.sons[1]) gsub(g, n.sons[2]) gsub(g, n.sons[3]) if not (renderNoBody in g.flags): if n.sons[4].kind != nkEmpty: put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") indentNL(g) gcoms(g) dedent(g) initContext(c) gstmts(g, n.sons[4], c) putNL(g) else: indentNL(g) gcoms(g) dedent(g) proc gblock(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) if n.sons[0].kind != nkEmpty: putWithSpace(g, tkBlock, "block") gsub(g, n.sons[0]) else: put(g, tkBlock, "block") putWithSpace(g, tkColon, ":") if longMode(n) or (lsub(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 gasm(g: var TSrcGen, n: PNode) = putWithSpace(g, tkAsm, "asm") gsub(g, n.sons[0]) gcoms(g) gsub(g, n.sons[1]) proc gident(g: var TSrcGen, n: PNode) = var t: TTokType var s = atom(n) if (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 else: t = TTokType(n.ident.id + ord(tkSymbol)) else: t = tkSymbol else: t = tkOpr put(g, t, s) if n.kind == nkSym and renderIds in g.flags: put(g, tkIntLit, $n.sym.id) proc gsub(g: var TSrcGen, n: PNode, c: TContext) = if isNil(n): return var L: int a: TContext if n.comment != nil: pushCom(g, n) case n.kind # atoms: of nkTripleStrLit: putRawStr(g, tkTripleStrLit, n.strVal) of nkEmpty: nil of nkType: put(g, tkInvalid, atom(n)) of nkSym, nkIdent: gident(g, n) of nkIntLit: put(g, tkIntLit, atom(n)) of nkInt8Lit: put(g, tkInt8Lit, atom(n)) of nkInt16Lit: put(g, tkInt16Lit, atom(n)) of nkInt32Lit: put(g, tkInt32Lit, atom(n)) of nkInt64Lit: put(g, tkInt64Lit, atom(n)) of nkFloatLit: put(g, tkFloatLit, atom(n)) of nkFloat32Lit: put(g, tkFloat32Lit, atom(n)) of nkFloat64Lit: put(g, tkFloat64Lit, atom(n)) of nkStrLit: put(g, tkStrLit, atom(n)) of nkRStrLit: put(g, tkRStrLit, atom(n)) of nkCharLit: put(g, tkCharLit, atom(n)) of nkNilLit: put(g, tkNil, atom(n)) # complex expressions of nkCall, nkConv, nkDotCall: if sonsLen(n) >= 1: gsub(g, n.sons[0]) put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") of nkCallStrLit: gsub(g, n.sons[0]) if n.sons[1].kind == nkRStrLit: put(g, tkRStrLit, '\"' & replace(n[1].strVal, "\"", "\"\"") & '\"') else: gsub(g, n.sons[1]) of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv: gsub(g, n.sons[0]) of nkCast: put(g, tkCast, "cast") put(g, tkBracketLe, "[") gsub(g, n.sons[0]) put(g, tkBracketRi, "]") put(g, tkParLe, "(") gsub(g, n.sons[1]) put(g, tkParRi, ")") of nkAddr: put(g, tkAddr, "addr") put(g, tkParLe, "(") gsub(g, n.sons[0]) put(g, tkParRi, ")") of nkBracketExpr: gsub(g, n.sons[0]) put(g, tkBracketLe, "[") gcomma(g, n, 1) put(g, tkBracketRi, "]") of nkCurlyExpr: gsub(g, n.sons[0]) put(g, tkCurlyLe, "{") gcomma(g, n, 1) put(g, tkCurlyRi, "}") of nkPragmaExpr: gsub(g, n.sons[0]) gcomma(g, n, 1) of nkCommand: gsub(g, n.sons[0]) put(g, tkSpaces, space) gcomma(g, n, 1) of nkExprEqExpr, nkAsgn, nkFastAsgn: gsub(g, n.sons[0]) put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[1]) of nkChckRangeF: put(g, tkSymbol, "chckRangeF") put(g, tkParLe, "(") gcomma(g, n) put(g, tkParRi, ")") of nkChckRange64: put(g, tkSymbol, "chckRange64") put(g, tkParLe, "(") gcomma(g, n) put(g, tkParRi, ")") of nkChckRange: put(g, tkSymbol, "chckRange") put(g, tkParLe, "(") gcomma(g, n) put(g, tkParRi, ")") of nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString: if sonsLen(n) >= 1: gsub(g, n.sons[0]) put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") of nkSymChoice: put(g, tkParLe, "(") for i in countup(0, sonsLen(n) - 1): if i > 0: put(g, tkOpr, "|") gsub(g, n.sons[i], c) put(g, tkParRi, ")") of nkPar: put(g, tkParLe, "(") gcomma(g, n, c) put(g, tkParRi, ")") of nkCurly: put(g, tkCurlyLe, "{") gcomma(g, n, c) put(g, tkCurlyRi, "}") of nkTableConstr: put(g, tkCurlyLe, "{") if n.len > 0: gcomma(g, n, c) else: put(g, tkColon, ":") put(g, tkCurlyRi, "}") of nkBracket: put(g, tkBracketLe, "[") gcomma(g, n, c) put(g, tkBracketRi, "]") of nkDotExpr: gsub(g, n.sons[0]) put(g, tkDot, ".") gsub(g, n.sons[1]) of nkBind: putWithSpace(g, tkBind, "bind") gsub(g, n.sons[0]) of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref: gsub(g, n.sons[0]) of nkLambda: assert(n.sons[genericParamsPos].kind == nkEmpty) putWithSpace(g, tkLambda, "lambda") gsub(g, n.sons[paramsPos]) gsub(g, n.sons[pragmasPos]) put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[bodyPos]) of nkConstDef, nkIdentDefs: gcomma(g, n, 0, - 3) var L = sonsLen(n) if n.sons[L - 2].kind != nkEmpty: putWithSpace(g, tkColon, ":") gsub(g, n.sons[L - 2]) if n.sons[L - 1].kind != nkEmpty: put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[L - 1], c) of nkVarTuple: put(g, tkParLe, "(") gcomma(g, n, 0, - 3) put(g, tkParRi, ")") put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, lastSon(n), c) of nkExprColonExpr: gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") gsub(g, n.sons[1]) of nkInfix: gsub(g, n.sons[1]) put(g, tkSpaces, Space) gsub(g, n.sons[0]) # binary operator if not fits(g, lsub(n.sons[2]) + lsub(n.sons[0]) + 1): optNL(g, g.indent + longIndentWid) else: put(g, tkSpaces, Space) gsub(g, n.sons[2]) of nkPrefix: gsub(g, n.sons[0]) put(g, tkSpaces, space) gsub(g, n.sons[1]) of nkPostfix: gsub(g, n.sons[1]) gsub(g, n.sons[0]) of nkRange: gsub(g, n.sons[0]) put(g, tkDotDot, "..") gsub(g, n.sons[1]) of nkDerefExpr: gsub(g, n.sons[0]) putWithSpace(g, tkOpr, "^") # unfortunately this requires a space, because ^. would be only one opr of nkAccQuoted: put(g, tkAccent, "`") if n.len > 0: gsub(g, n.sons[0]) for i in 1 .. <n.len: put(g, tkSpaces, Space) gsub(g, n.sons[i]) put(g, tkAccent, "`") of nkIfExpr: putWithSpace(g, tkIf, "if") gsub(g, n.sons[0].sons[0]) putWithSpace(g, tkColon, ":") gsub(g, n.sons[0].sons[1]) gsons(g, n, emptyContext, 1) of nkElifExpr: putWithSpace(g, tkElif, " elif") gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") gsub(g, n.sons[1]) of nkElseExpr: put(g, tkElse, " else") putWithSpace(g, tkColon, ":") gsub(g, n.sons[0]) of nkTypeOfExpr: putWithSpace(g, tkType, "type") gsub(g, n.sons[0]) of nkRefTy: if sonsLen(n) > 0: putWithSpace(g, tkRef, "ref") gsub(g, n.sons[0]) else: put(g, tkRef, "ref") of nkPtrTy: if sonsLen(n) > 0: putWithSpace(g, tkPtr, "ptr") gsub(g, n.sons[0]) else: put(g, tkPtr, "ptr") of nkVarTy: if sonsLen(n) > 0: putWithSpace(g, tkVar, "var") gsub(g, n.sons[0]) else: put(g, tkVar, "var") of nkDistinctTy: if sonsLen(n) > 0: putWithSpace(g, tkDistinct, "distinct") gsub(g, n.sons[0]) else: put(g, tkDistinct, "distinct") of nkTypeDef: gsub(g, n.sons[0]) gsub(g, n.sons[1]) put(g, tkSpaces, Space) if n.sons[2].kind != nkEmpty: putWithSpace(g, tkEquals, "=") gsub(g, n.sons[2]) of nkObjectTy: if sonsLen(n) > 0: putWithSpace(g, tkObject, "object") gsub(g, n.sons[0]) gsub(g, n.sons[1]) gcoms(g) gsub(g, n.sons[2]) else: put(g, tkObject, "object") of nkRecList: indentNL(g) for i in countup(0, sonsLen(n) - 1): optNL(g) gsub(g, n.sons[i], c) gcoms(g) dedent(g) putNL(g) of nkOfInherit: putWithSpace(g, tkOf, "of") gsub(g, n.sons[0]) of nkProcTy: if sonsLen(n) > 0: putWithSpace(g, tkProc, "proc") gsub(g, n.sons[0]) gsub(g, n.sons[1]) else: put(g, tkProc, "proc") of nkEnumTy: if sonsLen(n) > 0: putWithSpace(g, tkEnum, "enum") gsub(g, n.sons[0]) gcoms(g) indentNL(g) gcommaAux(g, n, g.indent, 1) gcoms(g) # BUGFIX: comment for the last enum field dedent(g) else: put(g, tkEnum, "enum") of nkEnumFieldDef: gsub(g, n.sons[0]) put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[1]) of nkStmtList, nkStmtListExpr: gstmts(g, n, emptyContext) of nkIfStmt: putWithSpace(g, tkIf, "if") gif(g, n) of nkWhenStmt, nkRecWhen: putWithSpace(g, tkWhen, "when") gif(g, n) of nkWhileStmt: gwhile(g, n) of nkPragmaBlock: gpragmaBlock(g, n) of nkCaseStmt, nkRecCase: gcase(g, n) of nkMacroStmt: gmacro(g, n) of nkTryStmt: gtry(g, n) of nkForStmt: gfor(g, n) of nkBlockStmt, nkBlockExpr: gblock(g, n) of nkAsmStmt: gasm(g, n) of nkProcDef: putWithSpace(g, tkProc, "proc") gproc(g, n) of nkMethodDef: putWithSpace(g, tkMethod, "method") gproc(g, n) of nkIteratorDef: putWithSpace(g, tkIterator, "iterator") gproc(g, n) of nkMacroDef: putWithSpace(g, tkMacro, "macro") gproc(g, n) of nkTemplateDef: putWithSpace(g, tkTemplate, "template") gproc(g, n) of nkTypeSection: gsection(g, n, emptyContext, tkType, "type") of nkConstSection: initContext(a) incl(a.flags, rfInConstExpr) gsection(g, n, a, tkConst, "const") of nkVarSection, nkLetSection: L = sonsLen(n) if L == 0: return if n.kind == nkVarSection: putWithSpace(g, tkVar, "var") else: putWithSpace(g, tkLet, "let") if L > 1: gcoms(g) indentNL(g) for i in countup(0, L - 1): optNL(g) gsub(g, n.sons[i]) gcoms(g) dedent(g) else: gsub(g, n.sons[0]) of nkReturnStmt: putWithSpace(g, tkReturn, "return") gsub(g, n.sons[0]) of nkRaiseStmt: putWithSpace(g, tkRaise, "raise") gsub(g, n.sons[0]) of nkYieldStmt: putWithSpace(g, tkYield, "yield") gsub(g, n.sons[0]) of nkDiscardStmt: putWithSpace(g, tkDiscard, "discard") gsub(g, n.sons[0]) of nkBreakStmt: putWithSpace(g, tkBreak, "break") gsub(g, n.sons[0]) of nkContinueStmt: putWithSpace(g, tkContinue, "continue") gsub(g, n.sons[0]) of nkPragma: if not (renderNoPragmas in g.flags): put(g, tkCurlyDotLe, "{.") gcomma(g, n, emptyContext) put(g, tkCurlyDotRi, ".}") of nkImportStmt: putWithSpace(g, tkImport, "import") gcoms(g) indentNL(g) gcommaAux(g, n, g.indent) dedent(g) putNL(g) of nkFromStmt: putWithSpace(g, tkFrom, "from") gsub(g, n.sons[0]) put(g, tkSpaces, Space) putWithSpace(g, tkImport, "import") gcomma(g, n, emptyContext, 1) putNL(g) of nkIncludeStmt: putWithSpace(g, tkInclude, "include") gcoms(g) indentNL(g) gcommaAux(g, n, g.indent) dedent(g) putNL(g) of nkCommentStmt: gcoms(g) optNL(g) of nkOfBranch: optNL(g) putWithSpace(g, tkOf, "of") gcomma(g, n, c, 0, - 2) putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, lastSon(n), c) of nkBindStmt: putWithSpace(g, tkBind, "bind") gcomma(g, n, c) of nkElifBranch: optNL(g) putWithSpace(g, tkElif, "elif") gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, n.sons[1], c) of nkElse: optNL(g) put(g, tkElse, "else") putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, n.sons[0], c) of nkFinally: optNL(g) put(g, tkFinally, "finally") putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, n.sons[0], c) of nkExceptBranch: optNL(g) putWithSpace(g, tkExcept, "except") gcomma(g, n, 0, - 2) putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, lastSon(n), c) of nkGenericParams: put(g, tkBracketLe, "[") gcomma(g, n) put(g, tkBracketRi, "]") of nkFormalParams: put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") if n.sons[0].kind != nkEmpty: putWithSpace(g, tkColon, ":") gsub(g, n.sons[0]) of nkTupleTy: put(g, tkTuple, "tuple") if sonsLen(n) > 0: put(g, tkBracketLe, "[") gcomma(g, n) put(g, tkBracketRi, "]") else: #nkNone, nkMetaNode, nkExplicitTypeListCall: InternalError(n.info, "rnimsyn.gsub(" & $n.kind & ')') proc renderTree(n: PNode, renderFlags: TRenderFlags = {}): string = var g: TSrcGen initSrcGen(g, renderFlags) gsub(g, n) result = g.buf proc renderModule(n: PNode, filename: string, renderFlags: TRenderFlags = {}) = var f: tfile g: TSrcGen initSrcGen(g, renderFlags) for i in countup(0, sonsLen(n) - 1): gsub(g, n.sons[i]) optNL(g) case n.sons[i].kind of nkTypeSection, nkConstSection, nkVarSection, nkLetSection, nkCommentStmt: putNL(g) else: nil gcoms(g) if optStdout in gGlobalOptions: write(stdout, g.buf) elif open(f, filename, fmWrite): write(f, g.buf) close(f) else: rawMessage(errCannotOpenFile, filename) proc initTokRender(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) = initSrcGen(r, renderFlags) gsub(r, n) proc getNextTok(r: var TSrcGen, kind: var TTokType, literal: var string) = if r.idx < len(r.tokens): kind = r.tokens[r.idx].kind var length = r.tokens[r.idx].length literal = substr(r.buf, r.pos + 0, r.pos + 0 + length - 1) inc(r.pos, length) inc(r.idx) else: kind = tkEof