fixes #2057
This commit is contained in:
parent
61e5f0dc51
commit
b5f1957588
5 changed files with 48 additions and 20 deletions
|
|
@ -2113,7 +2113,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkCurly: result = semSetConstr(c, n)
|
of nkCurly: result = semSetConstr(c, n)
|
||||||
of nkBracket: result = semArrayConstr(c, n, flags)
|
of nkBracket: result = semArrayConstr(c, n, flags)
|
||||||
of nkObjConstr: result = semObjConstr(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 nkDerefExpr: result = semDeref(c, n)
|
||||||
of nkAddr:
|
of nkAddr:
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ proc getEbase(): PType =
|
||||||
|
|
||||||
proc excType(n: PNode): PType =
|
proc excType(n: PNode): PType =
|
||||||
# reraise is like raising E_Base:
|
# 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)
|
result = skipTypes(t, skipPtrs)
|
||||||
|
|
||||||
proc createRaise(n: PNode): PNode =
|
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:
|
# we have a list of implicit type parameters:
|
||||||
n.sons[genericParamsPos] = gp
|
n.sons[genericParamsPos] = gp
|
||||||
else:
|
else:
|
||||||
s.typ = newTypeS(tyProc, c)
|
s.typ = newProcType(c, n.info)
|
||||||
rawAddSon(s.typ, nil)
|
|
||||||
if n.sons[pragmasPos].kind != nkEmpty:
|
if n.sons[pragmasPos].kind != nkEmpty:
|
||||||
pragma(c, s, n.sons[pragmasPos], lambdaPragmas)
|
pragma(c, s, n.sons[pragmasPos], lambdaPragmas)
|
||||||
s.options = gOptions
|
s.options = gOptions
|
||||||
|
|
@ -839,6 +838,13 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
popOwner()
|
popOwner()
|
||||||
result.typ = s.typ
|
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 =
|
proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||||
var n = n
|
var n = n
|
||||||
|
|
||||||
|
|
@ -988,8 +994,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
# check for semantics again:
|
# check for semantics again:
|
||||||
# semParamList(c, n.sons[ParamsPos], nil, s)
|
# semParamList(c, n.sons[ParamsPos], nil, s)
|
||||||
else:
|
else:
|
||||||
s.typ = newTypeS(tyProc, c)
|
s.typ = newProcType(c, n.info)
|
||||||
rawAddSon(s.typ, nil)
|
|
||||||
if n.sons[patternPos].kind != nkEmpty:
|
if n.sons[patternPos].kind != nkEmpty:
|
||||||
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
||||||
if s.kind in skIterators:
|
if s.kind in skIterators:
|
||||||
|
|
|
||||||
|
|
@ -856,25 +856,25 @@ proc semParamType(c: PContext, n: PNode, constraint: var PNode): PType =
|
||||||
else:
|
else:
|
||||||
result = semTypeNode(c, n, nil)
|
result = semTypeNode(c, n, nil)
|
||||||
|
|
||||||
proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType =
|
||||||
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)
|
|
||||||
result = newOrPrevType(tyProc, prev, c)
|
result = newOrPrevType(tyProc, prev, c)
|
||||||
result.callConv = lastOptionEntry(c).defaultCC
|
result.callConv = lastOptionEntry(c).defaultCC
|
||||||
result.n = newNodeI(nkFormalParams, n.info)
|
result.n = newNodeI(nkFormalParams, info)
|
||||||
if genericParams != nil and sonsLen(genericParams) == 0:
|
|
||||||
cl = initIntSet()
|
|
||||||
rawAddSon(result, nil) # return type
|
rawAddSon(result, nil) # return type
|
||||||
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
# 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
|
# the effects are now stored in there too ... this is a bit hacky, but as
|
||||||
# usual we desperately try to save memory:
|
# usual we desperately try to save memory:
|
||||||
res = newNodeI(nkEffectList, n.info)
|
addSon(result.n, newNodeI(nkEffectList, info))
|
||||||
addSon(result.n, res)
|
|
||||||
|
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 check = initIntSet()
|
||||||
var counter = 0
|
var counter = 0
|
||||||
for i in countup(1, n.len - 1):
|
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]
|
# we don't need to change the return type to iter[T]
|
||||||
if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
|
if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
|
||||||
result.sons[0] = r
|
result.sons[0] = r
|
||||||
res.typ = r
|
result.n.typ = r
|
||||||
|
|
||||||
if genericParams != nil:
|
if genericParams != nil:
|
||||||
for n in genericParams:
|
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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue