summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorOscar NihlgÄrd <oscarnihlgard@gmail.com>2019-05-06 21:19:40 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-05-06 21:19:40 +0200
commit4c6fc173b772a4c93d82e9d544a0d5a1fe270eea (patch)
treeeb98ab71d1b450746e695236b40ed5e3241e92f2
parentb1091f85d4d363f4368b65c54b898e83bec459e1 (diff)
downloadNim-4c6fc173b772a4c93d82e9d544a0d5a1fe270eea.tar.gz
low/high for float ranges (#11177)
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semfold.nim10
-rw-r--r--lib/system.nim8
-rw-r--r--tests/misc/tlowhigh.nim14
4 files changed, 27 insertions, 7 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index cb52724b9..2cdc36c52 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -316,7 +316,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
       n.typ = getSysType(c.graph, n.info, tyInt)
     of tyArray:
       n.typ = typ.sons[0] # indextype
-    of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
+    of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32, tyFloat..tyFloat64:
       # do not skip the range!
       n.typ = n.sons[1].typ.skipTypes(abstractVar)
     of tyGenericParam:
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 5fb2fcd65..67ba736f8 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -617,11 +617,17 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
         # If it has no sideEffect, it should be evaluated. But not here.
         return
       of mLow:
-        result = newIntNodeT(firstOrd(g.config, n.sons[1].typ), n, g)
+        if skipTypes(n.sons[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
+          result = newFloatNodeT(firstFloat(n.sons[1].typ), n, g)
+        else:
+          result = newIntNodeT(firstOrd(g.config, n.sons[1].typ), n, g)
       of mHigh:
         if skipTypes(n.sons[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
             {tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
-          result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
+          if skipTypes(n.sons[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
+            result = newFloatNodeT(lastFloat(n.sons[1].typ), n, g)
+          else:
+            result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
         else:
           var a = getArrayConstr(m, n.sons[1], g)
           if a.kind == nkBracket:
diff --git a/lib/system.nim b/lib/system.nim
index b13419eb9..ce6ed4c7f 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -303,7 +303,7 @@ else:
 type sink*{.magic: "BuiltinType".}[T]
 type lent*{.magic: "BuiltinType".}[T]
 
-proc high*[T: Ordinal](x: T): T {.magic: "High", noSideEffect.}
+proc high*[T: Ordinal|enum|range](x: T): T {.magic: "High", noSideEffect.}
   ## Returns the highest possible value of an ordinal value `x`.
   ##
   ## As a special semantic rule, `x` may also be a type identifier.
@@ -314,7 +314,7 @@ proc high*[T: Ordinal](x: T): T {.magic: "High", noSideEffect.}
   ## .. code-block:: Nim
   ##  high(2) # => 9223372036854775807
 
-proc high*[T: Ordinal|enum](x: typeDesc[T]): T {.magic: "High", noSideEffect.}
+proc high*[T: Ordinal|enum|range](x: typeDesc[T]): T {.magic: "High", noSideEffect.}
   ## Returns the highest possible value of an ordinal or enum type.
   ##
   ## ``high(int)`` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:.
@@ -375,7 +375,7 @@ proc high*(x: string): int {.magic: "High", noSideEffect.}
   ##  var str = "Hello world!"
   ##  high(str) # => 11
 
-proc low*[T](x: T): T {.magic: "Low", noSideEffect.}
+proc low*[T: Ordinal|enum|range](x: T): T {.magic: "Low", noSideEffect.}
   ## Returns the lowest possible value of an ordinal value `x`. As a special
   ## semantic rule, `x` may also be a type identifier.
   ##
@@ -385,7 +385,7 @@ proc low*[T](x: T): T {.magic: "Low", noSideEffect.}
   ## .. code-block:: Nim
   ##  low(2) # => -9223372036854775808
 
-proc low*[T: Ordinal|enum](x: typeDesc[T]): T {.magic: "Low", noSideEffect.}
+proc low*[T: Ordinal|enum|range](x: typeDesc[T]): T {.magic: "Low", noSideEffect.}
   ## Returns the lowest possible value of an ordinal or enum type.
   ##
   ## ``low(int)`` is Nim's way of writing `INT_MIN`:idx: or `MIN_INT`:idx:.
diff --git a/tests/misc/tlowhigh.nim b/tests/misc/tlowhigh.nim
new file mode 100644
index 000000000..61a7bfaed
--- /dev/null
+++ b/tests/misc/tlowhigh.nim
@@ -0,0 +1,14 @@
+discard """
+    action: run
+"""
+
+var x: range[-1'f32..1'f32]
+doAssert x.low == -1'f32
+doAssert x.high == 1'f32
+doAssert x.type.low == -1'f32
+doAssert x.type.high == 1'f32
+var y: range[-1'f64..1'f64]
+doAssert y.low == -1'f64
+doAssert y.high == 1'f64
+doAssert y.type.low == -1'f64
+doAssert y.type.high == 1'f64
\ No newline at end of file