summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim14
-rw-r--r--compiler/lexer.nim10
-rw-r--r--compiler/magicsys.nim13
-rw-r--r--compiler/renderer.nim12
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semfold.nim7
-rw-r--r--compiler/sigmatch.nim10
-rw-r--r--compiler/types.nim3
-rw-r--r--compiler/vmdef.nim3
-rw-r--r--compiler/vmdeps.nim15
-rw-r--r--lib/packages/docutils/rstgen.nim4
-rw-r--r--lib/system.nim18
-rw-r--r--lib/system/sysio.nim2
-rw-r--r--tests/compile/tvarious.nim3
14 files changed, 71 insertions, 45 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 635756220..3475093cb 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -465,10 +465,11 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
 proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   const
     binArithTab: array[mAddF64..mXor, string] = [
-      "($1 + $2)",            # AddF64
-      "($1 - $2)",            # SubF64
-      "($1 * $2)",            # MulF64
-      "($1 / $2)",            # DivF64
+      "(($4)($1) + ($4)($2))", # AddF64
+      "(($4)($1) - ($4)($2))", # SubF64
+      "(($4)($1) * ($4)($2))", # MulF64
+      "(($4)($1) / ($4)($2))", # DivF64
+      
       "($4)((NU$3)($1) >> (NU$3)($2))", # ShrI
       "($4)((NU$3)($1) << (NU$3)($2))", # ShlI
       "($4)($1 & $2)",      # BitandI
@@ -1488,8 +1489,9 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
     assert(e.sons[2].typ != nil)
     InitLocExpr(p, e.sons[1], a)
     InitLocExpr(p, e.sons[2], b)
-    putIntoDest(p, d, e.typ, rfmt(nil, "($2 $1 $3)",
-                                  toRope(opr[m]), rdLoc(a), rdLoc(b)))
+    putIntoDest(p, d, e.typ, rfmt(nil, "(($4)($2) $1 ($4)($3))",
+                                  toRope(opr[m]), rdLoc(a), rdLoc(b),
+                                  getSimpleTypeDesc(p.module, e[1].typ)))
     if optNanCheck in p.options:
       linefmt(p, cpsStmts, "#nanCheck($1);$n", rdLoc(d))
     if optInfCheck in p.options:
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 9e5f4e9d7..6a104d139 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -408,12 +408,12 @@ proc GetNumber(L: var TLexer): TToken =
         (result.tokType == tkFloat64Lit): 
       result.fnumber = parseFloat(result.literal)
       if result.tokType == tkIntLit: result.tokType = tkFloatLit
-    else: 
-      result.iNumber = ParseBiggestInt(result.literal)
-      if (result.iNumber < low(int32)) or (result.iNumber > high(int32)): 
-        if result.tokType == tkIntLit: 
+    else:
+      result.iNumber = parseBiggestInt(result.literal)
+      if (result.iNumber < low(int32)) or (result.iNumber > high(int32)):
+        if result.tokType == tkIntLit:
           result.tokType = tkInt64Lit
-        elif result.tokType != tkInt64Lit: 
+        elif result.tokType in {tkInt8Lit, tkInt16Lit}:
           lexMessage(L, errInvalidNumber, result.literal)
   except EInvalidValue:
     lexMessage(L, errInvalidNumber, result.literal)
diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim
index 1972dec98..88ae2cb12 100644
--- a/compiler/magicsys.nim
+++ b/compiler/magicsys.nim
@@ -115,11 +115,16 @@ proc getIntLitType*(literal: PNode): PType =
     result = copyType(ti, ti.owner, false)
     result.n = literal
 
+proc getFloatLitType*(literal: PNode): PType =
+  # for now we do not cache these:
+  result = newSysType(tyFloat, size=8)
+  result.n = literal
+
 proc skipIntLit*(t: PType): PType {.inline.} =
-  if t.kind == tyInt and t.n != nil:
-    result = getSysType(tyInt)
-  else:
-    result = t
+  if t.n != nil:
+    if t.kind in {tyInt, tyFloat}:
+      return getSysType(t.kind)
+  result = t
 
 proc AddSonSkipIntLit*(father, son: PType) =
   if isNil(father.sons): father.sons = @[]
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 70ce5c27d..efa4ecaba 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -329,7 +329,7 @@ proc atom(n: PNode): string =
     if n.flags * {nfBase2, nfBase8, nfBase16} == {}: 
       result = $n.floatVal & "\'f32"
     else: 
-      f = n.floatVal
+      f = n.floatVal.float32
       result = litAux(n, (cast[PInt32](addr(f)))[], 4) & "\'f32"
   of nkFloat64Lit: 
     if n.flags * {nfBase2, nfBase8, nfBase16} == {}: 
@@ -407,7 +407,8 @@ proc lsub(n: PNode): int =
     result = result + lcomma(n, 1)
   of nkExprColonExpr: result = lsons(n) + 2
   of nkInfix: result = lsons(n) + 2
-  of nkPrefix: result = lsons(n) + 1
+  of nkPrefix:
+    result = lsons(n)+1+(if n.len > 0 and n.sons[1].kind == nkInfix: 2 else: 0)
   of nkPostfix: result = lsons(n)
   of nkCallStrLit: result = lsons(n)
   of nkPragmaExpr: result = lsub(n.sons[0]) + lcomma(n, 1)
@@ -939,7 +940,12 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
     gsub(g, n.sons[0])
     if n.len > 1:
       put(g, tkSpaces, space)
-      gsub(g, n.sons[1])
+      if n.sons[1].kind == nkInfix:
+        put(g, tkParLe, "(")
+        gsub(g, n.sons[1])
+        put(g, tkParRi, ")")
+      else:
+        gsub(g, n.sons[1])
   of nkPostfix: 
     gsub(g, n.sons[1])
     gsub(g, n.sons[0])
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index ebda31501..4d7ceffa9 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1808,7 +1808,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
   of nkUInt64Lit: 
     if result.typ == nil: result.typ = getSysType(tyUInt64)
   of nkFloatLit: 
-    if result.typ == nil: result.typ = getSysType(tyFloat)
+    if result.typ == nil: result.typ = getFloatLitType(result)
   of nkFloat32Lit: 
     if result.typ == nil: result.typ = getSysType(tyFloat32)
   of nkFloat64Lit: 
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index ed7b14684..ca06ea1b6 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -21,7 +21,7 @@ proc getConstExpr*(m: PSym, n: PNode): PNode
 proc evalOp*(m: TMagic, n, a, b, c: PNode): PNode
 proc leValueConv*(a, b: PNode): bool
 proc newIntNodeT*(intVal: BiggestInt, n: PNode): PNode
-proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode): PNode
+proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode
 proc newStrNodeT*(strVal: string, n: PNode): PNode
 
 # implementation
@@ -43,7 +43,10 @@ proc newIntNodeT(intVal: BiggestInt, n: PNode): PNode =
 
 proc newFloatNodeT(floatVal: BiggestFloat, n: PNode): PNode = 
   result = newFloatNode(nkFloatLit, floatVal)
-  result.typ = n.typ
+  if skipTypes(n.typ, abstractVarRange).kind == tyFloat:
+    result.typ = getFloatLitType(result)
+  else:
+    result.typ = n.typ
   result.info = n.info
 
 proc newStrNodeT(strVal: string, n: PNode): PNode = 
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 5766aa164..a37b47366 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -283,14 +283,18 @@ proc isConvertibleToRange(f, a: PType): bool =
        a.kind in {tyFloat..tyFloat128}:
     result = true
 
-proc handleFloatRange(f, a: PType): TTypeRelation = 
-  if a.kind == f.kind: 
+proc handleFloatRange(f, a: PType): TTypeRelation =
+  if a.kind == f.kind:
     result = isEqual
-  else: 
+  else:
     let ab = skipTypes(a, {tyRange})
     var k = ab.kind
     if k == f.kind: result = isSubrange
+    elif isFloatLit(ab): result = isFromIntLit
     elif isIntLit(ab): result = isConvertible
+    elif f.kind == tyFloat32:
+      # no conversion to "float32" as that might lose precision
+      result = isNone
     elif k >= tyFloat and k <= tyFloat128: result = isConvertible
     else: result = isNone
   
diff --git a/compiler/types.nim b/compiler/types.nim
index 2564741d8..084091630 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -109,6 +109,9 @@ proc getOrdValue(n: PNode): biggestInt =
 proc isIntLit*(t: PType): bool {.inline.} =
   result = t.kind == tyInt and t.n != nil and t.n.kind == nkIntLit
 
+proc isFloatLit*(t: PType): bool {.inline.} =
+  result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
+
 proc isCompatibleToCString(a: PType): bool = 
   if a.kind == tyArray: 
     if (firstOrd(a.sons[0]) == 0) and
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 050caa65c..515f2975b 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -122,7 +122,8 @@ type
     opcLdImmInt,  # dest = immediate value
     opcWrGlobal,
     opcWrGlobalRef,
-    opcSetType    # dest.typ = types[Bx]
+    opcSetType,   # dest.typ = types[Bx]
+    opcTypeTrait
 
   TBlock* = object
     label*: PSym
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index 0e90a9b14..2a40276d1 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -35,21 +35,6 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
     result = ""
     LocalError(info, errCannotOpenFile, file)
 
-proc opTypeTrait*(n: PNode, context: PSym): PNode =
-  ## XXX: This should be pretty much guaranteed to be true
-  # by the type traits procs' signatures, but until the
-  # code is more mature it doesn't hurt to be extra safe
-  internalAssert n.len >= 2 and n.sons[1].kind == nkSym
-
-  let typ = n.sons[1].sym.typ.skipTypes({tyTypeDesc})
-  case n.sons[0].sym.name.s.normalize
-  of "name":
-    result = newStrNode(nkStrLit, typ.typeToString(preferExported))
-    result.typ = newType(tyString, context)
-    result.info = n.info
-  else:
-    internalAssert false
-
 when false:
   proc opExpandToAst*(c: PEvalContext, original: PNode): PNode =
     var
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index a393943fb..364f847cc 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -265,12 +265,12 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
     d.tocPart[length].header = tmp
     
     dispA(d.target, result,
-        "<h$1><a class=\"toc-backref\" id=\"$2\" href=\"#$2_toc\">$3</a></h$1>", 
+        "\n<h$1><a class=\"toc-backref\" id=\"$2\" href=\"#$2_toc\">$3</a></h$1>", 
         "\\rsth$4{$3}\\label{$2}\n", [$n.level, 
         d.tocPart[length].refname, tmp, 
         $chr(n.level - 1 + ord('A'))])
   else:
-    dispA(d.target, result, "<h$1 id=\"$2\">$3</h$1>", 
+    dispA(d.target, result, "\n<h$1 id=\"$2\">$3</h$1>", 
                             "\\rsth$4{$3}\\label{$2}\n", [
         $n.level, refname, tmp, 
         $chr(n.level - 1 + ord('A'))])
diff --git a/lib/system.nim b/lib/system.nim
index 749124ac9..40a9be2d4 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -28,7 +28,9 @@ type
   uint64* {.magic: UInt64.} ## unsigned 64 bit integer type
   float* {.magic: Float.} ## default floating point type
   float32* {.magic: Float32.} ## 32 bit floating point type
-  float64* {.magic: Float64.} ## 64 bit floating point type
+  float64* {.magic: Float.} ## 64 bit floating point type
+
+# 'float64' is now an alias to 'float'; this solves many problems
 
 type # we need to start a new type section here, so that ``0`` can have a type
   bool* {.magic: Bool.} = enum ## built-in boolean type
@@ -638,6 +640,14 @@ proc `<%` *(x, y: Int64): bool {.magic: "LtU64", noSideEffect.}
 
 
 # floating point operations:
+
+proc `+` *(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect.}
+proc `-` *(x: float32): float32 {.magic: "UnaryMinusF64", noSideEffect.}
+proc `+` *(x, y: float32): float32 {.magic: "AddF64", noSideEffect.}
+proc `-` *(x, y: float32): float32 {.magic: "SubF64", noSideEffect.}
+proc `*` *(x, y: float32): float32 {.magic: "MulF64", noSideEffect.}
+proc `/` *(x, y: float32): float32 {.magic: "DivF64", noSideEffect.}
+
 proc `+` *(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}
 proc `-` *(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}
 proc `+` *(x, y: float): float {.magic: "AddF64", noSideEffect.}
@@ -646,6 +656,10 @@ proc `*` *(x, y: float): float {.magic: "MulF64", noSideEffect.}
 proc `/` *(x, y: float): float {.magic: "DivF64", noSideEffect.}
   ## computes the floating point division
 
+proc `==` *(x, y: float32): bool {.magic: "EqF64", noSideEffect.}
+proc `<=` *(x, y: float32): bool {.magic: "LeF64", noSideEffect.}
+proc `<`  *(x, y: float32): bool {.magic: "LtF64", noSideEffect.}
+
 proc `==` *(x, y: float): bool {.magic: "EqF64", noSideEffect.}
 proc `<=` *(x, y: float): bool {.magic: "LeF64", noSideEffect.}
 proc `<`  *(x, y: float): bool {.magic: "LtF64", noSideEffect.}
@@ -1996,7 +2010,7 @@ when not defined(JS): #and not defined(NimrodVM):
       ## `content` completely to the file and closes the file afterwards.
       ## Raises an IO exception in case of an error.
 
-    proc write*(f: TFile, r: float) {.tags: [FWriteIO].}
+    proc write*(f: TFile, r: float32) {.tags: [FWriteIO].}
     proc write*(f: TFile, i: int) {.tags: [FWriteIO].}
     proc write*(f: TFile, i: biggestInt) {.tags: [FWriteIO].}
     proc write*(f: TFile, r: biggestFloat) {.tags: [FWriteIO].}
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 5407e0618..a877f8b28 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -91,7 +91,7 @@ proc write(f: TFile, i: biggestInt) =
 proc write(f: TFile, b: bool) =
   if b: write(f, "true")
   else: write(f, "false")
-proc write(f: TFile, r: float) = fprintf(f, "%g", r)
+proc write(f: TFile, r: float32) = fprintf(f, "%g", r)
 proc write(f: TFile, r: biggestFloat) = fprintf(f, "%g", r)
 
 proc write(f: TFile, c: Char) = putc(c, f)
diff --git a/tests/compile/tvarious.nim b/tests/compile/tvarious.nim
index e91de9245..25f48bb30 100644
--- a/tests/compile/tvarious.nim
+++ b/tests/compile/tvarious.nim
@@ -1,4 +1,7 @@
 # Test various aspects

+
+# bug #572
+var a=12345678901'u64
 

 var x = (x: 42, y: (a: 8, z: 10))
 echo x.y