summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgstmts.nim21
-rw-r--r--compiler/layouter.nim41
-rw-r--r--compiler/semfold.nim11
3 files changed, 44 insertions, 29 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 71d212282..f9654bb1f 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -978,16 +978,17 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
   if isAsmStmt and hasGnuAsm in CC[p.config.cCompiler].props:
     for x in splitLines(res):
       var j = 0
-      while x[j] in {' ', '\t'}: inc(j)
-      if x[j] in {'"', ':'}:
-        # don't modify the line if already in quotes or
-        # some clobber register list:
-        add(result, x); add(result, "\L")
-      elif x[j] != '\0':
-        # ignore empty lines
-        add(result, "\"")
-        add(result, x)
-        add(result, "\\n\"\n")
+      while j < x.len and x[j] in {' ', '\t'}: inc(j)
+      if j < x.len:
+        if x[j] in {'"', ':'}:
+          # don't modify the line if already in quotes or
+          # some clobber register list:
+          add(result, x); add(result, "\L")
+        else:
+          # ignore empty lines
+          add(result, "\"")
+          add(result, x)
+          add(result, "\\n\"\n")
   else:
     res.add("\L")
     result = res.rope
diff --git a/compiler/layouter.nim b/compiler/layouter.nim
index e07bde786..62844db4b 100644
--- a/compiler/layouter.nim
+++ b/compiler/layouter.nim
@@ -21,7 +21,6 @@ type
     splitComma, splitParLe, splitAnd, splitOr, splitIn, splitBinary
 
   Emitter* = object
-    f: PLLStream
     config: ConfigRef
     fid: FileIndex
     lastTok: TTokType
@@ -40,8 +39,6 @@ proc openEmitter*(em: var Emitter, cache: IdentCache;
   em.indWidth = getIndentWidth(fileIdx, llStreamOpen(fullPath, fmRead),
                                cache, config)
   if em.indWidth == 0: em.indWidth = 2
-  let outfile = changeFileExt(fullPath, ".pretty.nim")
-  em.f = llStreamOpen(outfile, fmWrite)
   em.config = config
   em.fid = fileIdx
   em.lastTok = tkInvalid
@@ -50,12 +47,13 @@ proc openEmitter*(em: var Emitter, cache: IdentCache;
   em.content = newStringOfCap(16_000)
   em.indentStack = newSeqOfCap[int](30)
   em.indentStack.add 0
-  if em.f == nil:
-    rawMessage(config, errGenerated, "cannot open file: " & outfile)
 
 proc closeEmitter*(em: var Emitter) =
-  em.f.llStreamWrite em.content
-  llStreamClose(em.f)
+  var f = llStreamOpen(em.config.outFile, fmWrite)
+  if f == nil:
+    rawMessage(em.config, errGenerated, "cannot open file: " & em.config.outFile)
+  f.llStreamWrite em.content
+  llStreamClose(f)
 
 proc countNewlines(s: string): int =
   result = 0
@@ -76,9 +74,10 @@ template wr(x) =
 template goodCol(col): bool = col in 40..MaxLineLen
 
 const
-  splitters = {tkComma, tkSemicolon, tkParLe, tkParDotLe,
-               tkBracketLe, tkBracketLeColon, tkCurlyDotLe,
-               tkCurlyLe}
+  openPars = {tkParLe, tkParDotLe,
+              tkBracketLe, tkBracketLeColon, tkCurlyDotLe,
+              tkCurlyLe}
+  splitters = openPars + {tkComma, tkSemicolon}
   oprSet = {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs,
             tkIsnot, tkNot, tkOf, tkAs, tkDotDot, tkAnd, tkOr, tkXor}
 
@@ -95,6 +94,8 @@ proc softLinebreak(em: var Emitter, lit: string) =
   # +2 because we blindly assume a comma or ' &' might follow
   if not em.inquote and em.col+lit.len+2 >= MaxLineLen:
     if em.lastTok in splitters:
+      while em.content.len > 0 and em.content[em.content.high] == ' ':
+        setLen(em.content, em.content.len-1)
       wr("\L")
       em.col = 0
       for i in 1..em.indentLevel+moreIndent(em): wr(" ")
@@ -102,8 +103,11 @@ proc softLinebreak(em: var Emitter, lit: string) =
       # search backwards for a good split position:
       for a in em.altSplitPos:
         if a > em.fixedUntil:
-          let ws = "\L" & repeat(' ',em.indentLevel+moreIndent(em) -
-              ord(em.content[a] == ' '))
+          var spaces = 0
+          while a+spaces < em.content.len and em.content[a+spaces] == ' ':
+            inc spaces
+          if spaces > 0: delete(em.content, a, a+spaces-1)
+          let ws = "\L" & repeat(' ',em.indentLevel+moreIndent(em))
           em.col = em.content.len - a
           em.content.insert(ws, a)
           break
@@ -166,7 +170,9 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
   of tokKeywordLow..tokKeywordHigh:
     if endsInAlpha(em):
       wr(" ")
-    elif not em.inquote and not endsInWhite(em):
+    elif not em.inquote and not endsInWhite(em) and
+        em.lastTok notin openPars:
+      #and tok.tokType in oprSet
       wr(" ")
 
     if not em.inquote:
@@ -188,8 +194,8 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
     wr(" ")
   of tkSemicolon, tkComma:
     wr(TokTypeToStr[tok.tokType])
-    wr(" ")
     rememberSplit(splitComma)
+    wr(" ")
   of tkParDotLe, tkParLe, tkBracketDotLe, tkBracketLe,
      tkCurlyLe, tkCurlyDotLe, tkBracketLeColon:
     if tok.strongSpaceA > 0 and not em.endsInWhite:
@@ -204,9 +210,9 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
      tkColonColon, tkDot:
     wr(TokTypeToStr[tok.tokType])
   of tkEquals:
-    if not em.endsInWhite: wr(" ")
+    if not em.inquote and not em.endsInWhite: wr(" ")
     wr(TokTypeToStr[tok.tokType])
-    wr(" ")
+    if not em.inquote: wr(" ")
   of tkOpr, tkDotDot:
     if tok.strongSpaceA == 0 and tok.strongSpaceB == 0:
       # if not surrounded by whitespace, don't produce any whitespace either:
@@ -217,10 +223,11 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
       template isUnary(tok): bool =
         tok.strongSpaceB == 0 and tok.strongSpaceA > 0
 
-      if not isUnary(tok) or em.lastTok in {tkOpr, tkDotDot}:
+      if not isUnary(tok):
         wr(" ")
         rememberSplit(splitBinary)
   of tkAccent:
+    if not em.inquote and endsInAlpha(em): wr(" ")
     wr(TokTypeToStr[tok.tokType])
     em.inquote = not em.inquote
   of tkComment:
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 10a223ea2..eceb10470 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -211,7 +211,12 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
   of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g)
   of mNot: result = newIntNodeT(1 - getInt(a), n, g)
   of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g)
-  of mBitnotI: result = newIntNodeT(not getInt(a), n, g)
+  of mBitnotI:
+    case skipTypes(n.typ, abstractRange).kind
+    of tyUInt..tyUInt64:
+      result = newIntNodeT((not getInt(a)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g)
+    else:
+      result = newIntNodeT(not getInt(a), n, g)
   of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g)
   of mLengthSeq, mLengthOpenArray, mXLenSeq, mLengthStr, mXLenStr:
     if a.kind == nkNilLit:
@@ -250,8 +255,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
     of tyInt8: result = newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n, g)
     of tyInt16: result = newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n, g)
     of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n, g)
-    of tyInt64, tyInt, tyUInt..tyUInt64:
+    of tyInt64, tyInt:
       result = newIntNodeT(`shl`(getInt(a), getInt(b)), n, g)
+    of tyUInt..tyUInt64:
+      result = newIntNodeT(`shl`(getInt(a), getInt(b)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g)
     else: internalError(g.config, n.info, "constant folding for shl")
   of mShrI:
     case skipTypes(n.typ, abstractRange).kind