-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal: use custom rendering for
--expandArc
(#813)
## Summary Report the output for `--expandArc` via manual `msgWrite` calls instead of using `localReport` and use custom render-to-text logic for the `PNode` tree. The rendering logic is kept simple, and while the output of `--expandArc` stays largely the same, it doesn't represent valid NimSkull code anymore. This is a preparation for the introduction of a code-generator IR, as with it, `astgen` is not going to output `PNode` AST anymore, meaning that `renderTree` cannot be used there. ## Details The `rsemExpandArc` report is removed and everything associated with it. While it could be kept, the general direction it to move aways from reports for compiler tracing, and so `msgWrite` is instead used. This also helps with getting around cyclic imports once the new IR is introduced. The rendering logic is a simplified version of `renderTree`, with more complex text-layouting and conditional logic removed. The supported AST shapes are similar to that of the planned initial version of the code-generator IR, and the routines are added to the new `cgirutils` module. In order for changes to the `expandArc`-using tests to stay small, the rendered output is kept compatible with that of `renderTree(n, {renderIr, renderNoComment})`, where reasonable.
- Loading branch information
Showing
11 changed files
with
371 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
## Non-essential code-generator IR related routines. | ||
|
||
import | ||
std/[ | ||
strutils | ||
], | ||
compiler/ast/[ | ||
ast_types, | ||
ast_query, | ||
typesrenderer | ||
], | ||
compiler/utils/[ | ||
idioms | ||
] | ||
|
||
from compiler/ast/renderer import renderTree, TRenderFlag | ||
|
||
type | ||
RenderCtx = object | ||
syms: seq[PSym] | ||
## remembers the already-rendered symbols. Used to provide unique names. | ||
|
||
proc disambiguate(c: var RenderCtx, s: PSym): int = | ||
## Computes and returns a number to append to the symbol name in order to | ||
## make it unique in the output. This way, multiple different symbols sharing | ||
## the same name can be disambiguated. | ||
result = 0 | ||
for it in c.syms.items: | ||
if it == s: | ||
return | ||
elif it.name.id == s.name.id: # same name? | ||
inc result | ||
|
||
c.syms.add s # remember the symbol | ||
|
||
proc render(c: var RenderCtx, ind: int, n: PNode, res: var string) = | ||
template add(s: var string, n: PNode) = | ||
render(c, ind, n, res) | ||
|
||
template indent(extra = 1) = | ||
if res.len > 0 and res[^1] == ' ': | ||
# remove trailing space | ||
res.setLen(res.len - 1) | ||
res.add "\n" | ||
res.add repeat(" ", ind + extra) | ||
|
||
template newLine() = | ||
indent(0) | ||
|
||
template renderList(n: PNode, sep: untyped; start: int = 0; fin: int = 0) = | ||
## Renders the items in the slice ``start..<n.len - fin`` | ||
for i in start..<n.len-fin: | ||
if i > start: | ||
sep | ||
res.add n[i] | ||
|
||
template renderList(n: PNode, sep: string; start: int = 0; fin: int = 0) = | ||
## Renders the items in the slice ``start..<n.len - fin`` | ||
renderList(n, res.add(sep), start, fin) | ||
|
||
case n.kind | ||
of nkIntLit..nkInt64Lit: | ||
res.addInt n.intVal | ||
of nkCharLit, nkUIntLit..nkUInt64Lit: | ||
res.addInt cast[BiggestUInt](n.intVal) | ||
of nkFloatLit..nkFloat128Lit: | ||
res.add $n.floatVal | ||
of nkStrLiterals: | ||
res.add '"' | ||
res.add n.strVal | ||
res.add '"' | ||
of nkNilLit: | ||
res.add "nil" | ||
of nkNimNodeLit: | ||
res.add "<ast>" | ||
of nkSym: | ||
res.add n.sym.name.s | ||
let postfix = disambiguate(c, n.sym) | ||
if postfix > 0 and n.sym.magic == mNone: | ||
res.add "_" & $postfix | ||
|
||
# the rendered code is currently used for the ``--expandArc``, so we also | ||
# highlight cursor locals | ||
if sfCursor in n.sym.flags: | ||
res.add "_cursor" | ||
of nkType: | ||
if n.typ.sym != nil: | ||
res.add $n.typ | ||
else: | ||
res.add "[type node]" | ||
of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref, nkHiddenStdConv, nkChckRange, nkChckRange64, nkChckRangeF: | ||
res.add n[0] | ||
of nkAddr: | ||
res.add "addr " | ||
res.add n[0] | ||
of nkDerefExpr: | ||
res.add n[0] | ||
res.add "[]" | ||
of nkDotExpr: | ||
res.add n[0] | ||
res.add '.' | ||
res.add n[1] | ||
of nkBracketExpr: | ||
res.add n[0] | ||
res.add '[' | ||
res.add n[1] | ||
res.add ']' | ||
of nkRange: | ||
res.add n[0] | ||
res.add ".." | ||
res.add n[1] | ||
of nkCast: | ||
res.add "cast[" | ||
res.add $n[0].typ | ||
res.add "](" | ||
res.add n[1] | ||
res.add ")" | ||
of nkStringToCString: | ||
res.add "cstring(" | ||
res.add n[0] | ||
res.add ')' | ||
of nkCStringToString: | ||
res.add "string(" | ||
res.add n[0] | ||
res.add ')' | ||
of nkConv: | ||
res.add n[0] | ||
res.add '(' | ||
res.add n[1] | ||
res.add ')' | ||
of nkObjUpConv, nkObjDownConv: | ||
res.add $n.typ | ||
res.add "(" | ||
res.add n[0] | ||
res.add ")" | ||
of nkExprColonExpr: | ||
res.add n[0] | ||
res.add ": " | ||
res.add n[1] | ||
of nkCall: | ||
res.add n[0] | ||
res.add '(' | ||
let ind = ind + 1 | ||
renderList(n, ", ", 1) | ||
res.add ')' | ||
|
||
of nkObjConstr: | ||
res.add $n[0].typ | ||
res.add '(' | ||
renderList(n, ", ", 1) | ||
res.add ')' | ||
of nkTupleConstr, nkClosure: | ||
res.add '(' | ||
renderList(n, ", ") | ||
res.add ')' | ||
of nkBracket: | ||
res.add '[' | ||
renderList(n, ", ") | ||
res.add ']' | ||
of nkCurly: | ||
res.add '{' | ||
renderList(n, ", ") | ||
res.add '}' | ||
|
||
of nkAsgn, nkFastAsgn: | ||
res.add n[0] | ||
res.add " = " | ||
let ind = ind + 1 | ||
res.add n[1] | ||
of nkVarSection, nkLetSection: | ||
for i, def in n.pairs: | ||
if i > 0: | ||
newLine() | ||
res.add "var " | ||
res.add def[0] | ||
if def[2].kind != nkEmpty: | ||
res.add " = " | ||
let ind = ind + 1 | ||
res.add def[2] | ||
of nkPragma: | ||
# re-use the ``PNode`` rendering | ||
res.add renderTree(n, {renderIr, renderNoComments}) | ||
of nkReturnStmt: | ||
res.add "return" | ||
of nkDiscardStmt: | ||
res.add "discard " | ||
res.add n[0] | ||
of nkBreakStmt: | ||
if n[0].kind == nkEmpty: | ||
res.add "break" | ||
else: | ||
res.add "break " | ||
res.add n[0] | ||
of nkRaiseStmt: | ||
if n[0].kind == nkEmpty: | ||
res.add "raise" | ||
else: | ||
res.add "raise " | ||
res.add n[0] | ||
of nkAsmStmt: | ||
res.add "asm " | ||
let ind = ind + 1 | ||
renderList(n, ", ") | ||
res.add "" | ||
of nkWhileStmt: | ||
res.add "while true:" | ||
indent() | ||
render(c, ind + 1, n[1], res) | ||
of nkBlockStmt: | ||
if n[0].kind == nkEmpty: | ||
res.add "block:" | ||
else: | ||
res.add "block " | ||
res.add n[0] | ||
res.add ":" | ||
indent() | ||
render(c, ind + 1, n[1], res) | ||
of nkIfStmt: | ||
res.add "if " | ||
res.add n[0][0] | ||
res.add ':' | ||
indent() | ||
render(c, ind + 1, n[0][1], res) | ||
of nkCaseStmt: | ||
res.add "case " | ||
res.add n[0] | ||
for i in 1..<n.len: | ||
newLine() | ||
case n.kind | ||
of nkOfBranch: | ||
res.add "of " | ||
renderList(n[i], ", ", 1, 1) | ||
of nkElse: | ||
res.add "else" | ||
else: | ||
unreachable() | ||
|
||
res.add ":" | ||
indent() | ||
render(c, ind + 1, n[i][^1], res) | ||
of nkTryStmt: | ||
res.add "try:" | ||
indent() | ||
render(c, ind + 1, n[0], res) | ||
for i in 1..<n.len: | ||
case n[i].kind | ||
of nkExceptBranch: | ||
newLine() | ||
res.add "except:" | ||
indent() | ||
render(c, ind + 1, n[i][^1], res) | ||
of nkFinally: | ||
newLine() | ||
res.add "finally:" | ||
indent() | ||
render(c, ind + 1, n[i][0], res) | ||
else: | ||
unreachable() | ||
of nkStmtListExpr: | ||
newLine() | ||
renderList(n, newLine()) | ||
of nkStmtList: | ||
renderList(n, newLine()) | ||
of nkWithSons + nkWithoutSons - codegenExprNodeKinds - | ||
{nkExprColonExpr, nkRange} + {nkEmpty}: | ||
unreachable(n.kind) | ||
|
||
proc render*(n: PNode): string = | ||
## Renders `n` to human-readable code that tries to emulate the shape of the | ||
## high-level language. The output is meant for debugging and tracing and is | ||
## not guaranteed to have a stable format. | ||
var c = RenderCtx() | ||
render(c, 0, n, result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.