diff options
-rw-r--r-- | compiler/ccgexprs.nim | 14 | ||||
-rw-r--r-- | compiler/lexer.nim | 10 | ||||
-rw-r--r-- | compiler/magicsys.nim | 13 | ||||
-rw-r--r-- | compiler/renderer.nim | 12 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/semfold.nim | 7 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 10 | ||||
-rw-r--r-- | compiler/types.nim | 3 | ||||
-rw-r--r-- | compiler/vmdef.nim | 3 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 15 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 4 | ||||
-rw-r--r-- | lib/system.nim | 18 | ||||
-rw-r--r-- | lib/system/sysio.nim | 2 | ||||
-rw-r--r-- | tests/compile/tvarious.nim | 3 |
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 |