This commit is contained in:
Araq
2015-02-04 12:40:23 +01:00
parent 61e5f0dc51
commit b5f1957588
5 changed files with 48 additions and 20 deletions

View File

@@ -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

View File

@@ -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 =

View File

@@ -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:

View File

@@ -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
View 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)