mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 05:23:20 +00:00
fixes #2057
This commit is contained in:
@@ -2113,7 +2113,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
of nkCurly: result = semSetConstr(c, n)
|
||||
of nkBracket: result = semArrayConstr(c, n, flags)
|
||||
of nkObjConstr: result = semObjConstr(c, n, flags)
|
||||
of nkLambdaKinds: result = semLambda(c, n, flags)
|
||||
of nkLambda: result = semLambda(c, n, flags)
|
||||
of nkDo: result = semDo(c, n, flags)
|
||||
of nkDerefExpr: result = semDeref(c, n)
|
||||
of nkAddr:
|
||||
result = n
|
||||
|
||||
@@ -230,7 +230,7 @@ proc getEbase(): PType =
|
||||
|
||||
proc excType(n: PNode): PType =
|
||||
# reraise is like raising E_Base:
|
||||
let t = if n.kind == nkEmpty: getEbase() else: n.typ
|
||||
let t = if n.kind == nkEmpty or n.typ.isNil: getEbase() else: n.typ
|
||||
result = skipTypes(t, skipPtrs)
|
||||
|
||||
proc createRaise(n: PNode): PNode =
|
||||
|
||||
@@ -813,8 +813,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
# we have a list of implicit type parameters:
|
||||
n.sons[genericParamsPos] = gp
|
||||
else:
|
||||
s.typ = newTypeS(tyProc, c)
|
||||
rawAddSon(s.typ, nil)
|
||||
s.typ = newProcType(c, n.info)
|
||||
if n.sons[pragmasPos].kind != nkEmpty:
|
||||
pragma(c, s, n.sons[pragmasPos], lambdaPragmas)
|
||||
s.options = gOptions
|
||||
@@ -839,6 +838,13 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
popOwner()
|
||||
result.typ = s.typ
|
||||
|
||||
proc semDo(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
# 'do' without params produces a stmt:
|
||||
if n[genericParamsPos].kind == nkEmpty and n[paramsPos].kind == nkEmpty:
|
||||
result = semStmt(c, n[bodyPos])
|
||||
else:
|
||||
result = semLambda(c, n, flags)
|
||||
|
||||
proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||
var n = n
|
||||
|
||||
@@ -988,8 +994,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
# check for semantics again:
|
||||
# semParamList(c, n.sons[ParamsPos], nil, s)
|
||||
else:
|
||||
s.typ = newTypeS(tyProc, c)
|
||||
rawAddSon(s.typ, nil)
|
||||
s.typ = newProcType(c, n.info)
|
||||
if n.sons[patternPos].kind != nkEmpty:
|
||||
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
||||
if s.kind in skIterators:
|
||||
|
||||
@@ -856,25 +856,25 @@ proc semParamType(c: PContext, n: PNode, constraint: var PNode): PType =
|
||||
else:
|
||||
result = semTypeNode(c, n, nil)
|
||||
|
||||
proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
prev: PType, kind: TSymKind; isType=false): PType =
|
||||
# for historical reasons (code grows) this is invoked for parameter
|
||||
# lists too and then 'isType' is false.
|
||||
var
|
||||
res: PNode
|
||||
cl: IntSet
|
||||
checkMinSonsLen(n, 1)
|
||||
proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType =
|
||||
result = newOrPrevType(tyProc, prev, c)
|
||||
result.callConv = lastOptionEntry(c).defaultCC
|
||||
result.n = newNodeI(nkFormalParams, n.info)
|
||||
if genericParams != nil and sonsLen(genericParams) == 0:
|
||||
cl = initIntSet()
|
||||
result.n = newNodeI(nkFormalParams, info)
|
||||
rawAddSon(result, nil) # return type
|
||||
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
||||
# the effects are now stored in there too ... this is a bit hacky, but as
|
||||
# usual we desperately try to save memory:
|
||||
res = newNodeI(nkEffectList, n.info)
|
||||
addSon(result.n, res)
|
||||
addSon(result.n, newNodeI(nkEffectList, info))
|
||||
|
||||
proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
prev: PType, kind: TSymKind; isType=false): PType =
|
||||
# for historical reasons (code grows) this is invoked for parameter
|
||||
# lists too and then 'isType' is false.
|
||||
var cl: IntSet
|
||||
checkMinSonsLen(n, 1)
|
||||
result = newProcType(c, n.info, prev)
|
||||
if genericParams != nil and sonsLen(genericParams) == 0:
|
||||
cl = initIntSet()
|
||||
var check = initIntSet()
|
||||
var counter = 0
|
||||
for i in countup(1, n.len - 1):
|
||||
@@ -956,7 +956,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
# we don't need to change the return type to iter[T]
|
||||
if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
|
||||
result.sons[0] = r
|
||||
res.typ = r
|
||||
result.n.typ = r
|
||||
|
||||
if genericParams != nil:
|
||||
for n in genericParams:
|
||||
|
||||
22
tests/template/t2do.nim
Normal file
22
tests/template/t2do.nim
Normal file
@@ -0,0 +1,22 @@
|
||||
discard """
|
||||
output: "8.0"
|
||||
"""
|
||||
|
||||
# bug #2057
|
||||
|
||||
proc mpf_get_d(x: int): float = float(x)
|
||||
proc mpf_cmp_d(a: int; b: float): int = 0
|
||||
|
||||
template toFloatHelper(result: expr; tooSmall, tooLarge: stmt) {.immediate.} =
|
||||
result = mpf_get_d(a)
|
||||
if result == 0.0 and mpf_cmp_d(a,0.0) != 0:
|
||||
tooSmall
|
||||
if result == Inf:
|
||||
tooLarge
|
||||
|
||||
proc toFloat*(a: int): float =
|
||||
toFloatHelper(result)
|
||||
do: raise newException(ValueError, "number too small"):
|
||||
raise newException(ValueError, "number too large")
|
||||
|
||||
echo toFloat(8)
|
||||
Reference in New Issue
Block a user