'nimrod pretty' usable

This commit is contained in:
Araq 2013-07-31 20:35:04 +02:00
commit 731c6f9083
5 changed files with 55 additions and 63 deletions

View file

@ -1,7 +1,7 @@
# #
# #
# The Nimrod Compiler # The Nimrod Compiler
# (c) Copyright 2012 Andreas Rumpf # (c) Copyright 2013 Andreas Rumpf
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -10,48 +10,35 @@
# This module handles the conditional symbols. # This module handles the conditional symbols.
import import
ast, astalgo, hashes, platform, strutils, idents strtabs, platform, strutils, idents
var gSymbols*: TStrTable # We need to use a PStringTable here as defined symbols are always guaranteed
# to be style insensitive. Otherwise hell would break lose.
var gSymbols: PStringTable
proc DefineSymbol*(symbol: string) = proc DefineSymbol*(symbol: string) =
var i = getIdent(symbol) gSymbols[symbol] = "true"
var sym = StrTableGet(gSymbols, i)
if sym == nil:
new(sym) # circumvent the ID mechanism
sym.kind = skConditional
sym.name = i
StrTableAdd(gSymbols, sym)
sym.position = 1
proc UndefSymbol*(symbol: string) = proc UndefSymbol*(symbol: string) =
var sym = StrTableGet(gSymbols, getIdent(symbol)) gSymbols[symbol] = "false"
if sym != nil: sym.position = 0
proc isDefined*(symbol: PIdent): bool =
var sym = StrTableGet(gSymbols, symbol)
result = sym != nil and sym.position == 1
proc isDefined*(symbol: string): bool = proc isDefined*(symbol: string): bool =
result = isDefined(getIdent(symbol)) if gSymbols.hasKey(symbol):
result = gSymbols[symbol] == "true"
proc isDefined*(symbol: PIdent): bool = isDefined(symbol.s)
iterator definedSymbolNames*: string = iterator definedSymbolNames*: string =
var it: TTabIter for key, val in pairs(gSymbols):
var s = InitTabIter(it, gSymbols) if val == "true": yield key
while s != nil:
if s.position == 1: yield s.name.s
s = nextIter(it, gSymbols)
proc countDefinedSymbols*(): int = proc countDefinedSymbols*(): int =
var it: TTabIter
var s = InitTabIter(it, gSymbols)
result = 0 result = 0
while s != nil: for key, val in pairs(gSymbols):
if s.position == 1: inc(result) if val == "true": inc(result)
s = nextIter(it, gSymbols)
proc InitDefines*() = proc InitDefines*() =
initStrTable(gSymbols) gSymbols = newStringTable(modeStyleInsensitive)
DefineSymbol("nimrod") # 'nimrod' is always defined DefineSymbol("nimrod") # 'nimrod' is always defined
# for bootstrapping purposes and old code: # for bootstrapping purposes and old code:
DefineSymbol("nimhygiene") DefineSymbol("nimhygiene")
@ -66,7 +53,7 @@ proc InitDefines*() =
of cpuI386: DefineSymbol("x86") of cpuI386: DefineSymbol("x86")
of cpuIa64: DefineSymbol("itanium") of cpuIa64: DefineSymbol("itanium")
of cpuAmd64: DefineSymbol("x8664") of cpuAmd64: DefineSymbol("x8664")
else: nil else: discard
case targetOS case targetOS
of osDOS: of osDOS:
DefineSymbol("msdos") DefineSymbol("msdos")
@ -92,12 +79,10 @@ proc InitDefines*() =
DefineSymbol("macintosh") DefineSymbol("macintosh")
DefineSymbol("unix") DefineSymbol("unix")
DefineSymbol("posix") DefineSymbol("posix")
else: nil else: discard
DefineSymbol("cpu" & $cpu[targetCPU].bit) DefineSymbol("cpu" & $cpu[targetCPU].bit)
DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian])) DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian]))
DefineSymbol(cpu[targetCPU].name) DefineSymbol(cpu[targetCPU].name)
DefineSymbol(platform.os[targetOS].name) DefineSymbol(platform.os[targetOS].name)
if platform.OS[targetOS].props.contains(ospLacksThreadVars): if platform.OS[targetOS].props.contains(ospLacksThreadVars):
DefineSymbol("emulatedthreadvars") DefineSymbol("emulatedthreadvars")

View file

@ -11,8 +11,11 @@
## to convert Nimrod code into a consistent style. ## to convert Nimrod code into a consistent style.
import import
strutils, os, options, ast, astalgo, msgs, ropes, idents, passes, pegs, strutils, os, options, ast, astalgo, msgs, ropes, idents, passes,
intsets, strtabs intsets, strtabs
const
removeTP = false # when true, "nimrod pretty" converts TTyp to Typ.
type type
TGen = object of TPassContext TGen = object of TPassContext
@ -43,10 +46,14 @@ proc loadFile(info: TLineInfo) =
proc overwriteFiles*() = proc overwriteFiles*() =
for i in 0 .. high(gSourceFiles): for i in 0 .. high(gSourceFiles):
if not gSourceFiles[i].dirty: continue if not gSourceFiles[i].dirty: continue
var f = open(gSourceFiles[i].fullpath.changeFileExt(".pretty.nim"), fmWrite) let newFile = gSourceFiles[i].fullpath.changeFileExt(".pretty.nim")
for line in gSourceFiles[i].lines: try:
f.writeln(line) var f = open(newFile, fmWrite)
f.close for line in gSourceFiles[i].lines:
f.writeln(line)
f.close
except EIO:
rawMessage(errCannotOpenFile, newFile)
proc beautifyName(s: string, k: TSymKind): string = proc beautifyName(s: string, k: TSymKind): string =
result = newStringOfCap(s.len) result = newStringOfCap(s.len)
@ -54,8 +61,9 @@ proc beautifyName(s: string, k: TSymKind): string =
case k case k
of skType, skGenericParam: of skType, skGenericParam:
# skip leading 'T' # skip leading 'T'
if s[0] == 'T' and s[1] in {'A'..'Z'}: when removeTP:
i = 1 if s[0] == 'T' and s[1] in {'A'..'Z'}:
i = 1
result.add toUpper(s[i]) result.add toUpper(s[i])
of skConst, skEnumField: of skConst, skEnumField:
# for 'const' we keep how it's spelt; either upper case or lower case: # for 'const' we keep how it's spelt; either upper case or lower case:
@ -138,10 +146,11 @@ proc processSym(c: PPassContext, n: PNode): PNode =
let last = first+identLen(line, first)-1 let last = first+identLen(line, first)-1
if last-first+1 != newName.len or differ(line, first, last, newName): if last-first+1 != newName.len or differ(line, first, last, newName):
var x = line.subStr(0, first-1) & newName & line.substr(last+1) var x = line.subStr(0, first-1) & newName & line.substr(last+1)
# the WinAPI module is full of 'TX = X' which after the substitution when removeTP:
# becomes 'X = X'. We remove those lines: # the WinAPI module is full of 'TX = X' which after the substitution
if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"): # becomes 'X = X'. We remove those lines:
x = "" if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"):
x = ""
system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x) system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x)
gSourceFiles[n.info.fileIndex].dirty = true gSourceFiles[n.info.fileIndex].dirty = true
@ -156,14 +165,16 @@ proc myOpen(module: PSym): PPassContext =
result = g result = g
if rules.isNil: if rules.isNil:
rules = newStringTable(modeStyleInsensitive) rules = newStringTable(modeStyleInsensitive)
let path = joinPath([getPrefixDir(), "config", "rename.rules.cfg"]) when removeTP:
for line in lines(path): # XXX activate when the T/P stuff is deprecated
if line.len > 0: let path = joinPath([getPrefixDir(), "config", "rename.rules.cfg"])
let colon = line.find(':') for line in lines(path):
if colon > 0: if line.len > 0:
rules[line.substr(0, colon-1)] = line.substr(colon+1) let colon = line.find(':')
else: if colon > 0:
rules[line] = line rules[line.substr(0, colon-1)] = line.substr(colon+1)
else:
rules[line] = line
const prettyPass* = makePass(open = myOpen, process = processSym) const prettyPass* = makePass(open = myOpen, process = processSym)

View file

@ -45,14 +45,10 @@ proc addStmt(w: PRodWriter, n: PNode)
proc writeRod(w: PRodWriter) proc writeRod(w: PRodWriter)
proc getDefines(): string = proc getDefines(): string =
var it: TTabIter
var s = InitTabIter(it, gSymbols)
result = "" result = ""
while s != nil: for d in definedSymbolNames():
if s.position == 1: if result.len != 0: add(result, " ")
if result.len != 0: add(result, " ") add(result, d)
add(result, s.name.s)
s = nextIter(it, gSymbols)
proc fileIdx(w: PRodWriter, filename: string): int = proc fileIdx(w: PRodWriter, filename: string): int =
for i in countup(0, high(w.files)): for i in countup(0, high(w.files)):

View file

@ -431,7 +431,7 @@ proc semConst(c: PContext, n: PNode): PNode =
var b = newNodeI(nkConstDef, a.info) var b = newNodeI(nkConstDef, a.info)
if importantComments(): b.comment = a.comment if importantComments(): b.comment = a.comment
addSon(b, newSymNode(v)) addSon(b, newSymNode(v))
addSon(b, ast.emptyNode) # no type description addSon(b, a.sons[1])
addSon(b, copyTree(def)) addSon(b, copyTree(def))
addSon(result, b) addSon(result, b)

View file

@ -601,7 +601,7 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
result.typ = newTypeS(tyExpr, c) result.typ = newTypeS(tyExpr, c)
result.typ.sons = paramType.sons result.typ.sons = paramType.sons
of tyTypeDesc: of tyTypeDesc:
if tfInstantiated notin paramType.flags: if tfInstantiated notin paramType.flags:
result.typ = newTypeS(tyTypeDesc, c) result.typ = newTypeS(tyTypeDesc, c)
result.typ.sons = paramType.sons result.typ.sons = paramType.sons
of tyDistinct: of tyDistinct:
@ -719,8 +719,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
for j in countup(0, length-3): for j in countup(0, length-3):
var arg = newSymG(skParam, a.sons[j], c) var arg = newSymG(skParam, a.sons[j], c)
var finalType = liftParamType(c, kind, genericParams, typ, var finalType = liftParamType(c, kind, genericParams, typ, arg.name.s,
arg.name.s, arg.info).skipIntLit a.sons[length-2].info).skipIntLit
arg.typ = finalType arg.typ = finalType
arg.position = counter arg.position = counter
arg.constraint = constraint arg.constraint = constraint