summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-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
10 files changed, 49 insertions, 40 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