This commit is contained in:
Araq 2012-12-15 22:35:16 +01:00
commit a22c1f444f
9 changed files with 54 additions and 38 deletions

View file

@ -132,7 +132,7 @@ const
errNumberOutOfRange: "number $1 out of valid range", errNumberOutOfRange: "number $1 out of valid range",
errNnotAllowedInCharacter: "\\n not allowed in character literal", errNnotAllowedInCharacter: "\\n not allowed in character literal",
errClosingBracketExpected: "closing ']' expected, but end of file reached", errClosingBracketExpected: "closing ']' expected, but end of file reached",
errMissingFinalQuote: "missing final \'", errMissingFinalQuote: "missing final \' for character literal",
errIdentifierExpected: "identifier expected, but found \'$1\'", errIdentifierExpected: "identifier expected, but found \'$1\'",
errNewlineExpected: "newline expected, but found \'$1\'", errNewlineExpected: "newline expected, but found \'$1\'",
errInvalidModuleName: "invalid module name: '$1'", errInvalidModuleName: "invalid module name: '$1'",

View file

@ -47,6 +47,8 @@ proc fixImmediateParams(n: PNode): PNode
proc activate(c: PContext, n: PNode) proc activate(c: PContext, n: PNode)
proc semQuoteAst(c: PContext, n: PNode): PNode proc semQuoteAst(c: PContext, n: PNode): PNode
proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
proc typeMismatch(n: PNode, formal, actual: PType) = proc typeMismatch(n: PNode, formal, actual: PType) =
if formal.kind != tyError and actual.kind != tyError: if formal.kind != tyError and actual.kind != tyError:
LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) & LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &

View file

@ -84,15 +84,34 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym), getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
args]) args])
proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {.
noinline.}= proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
for i in 1 .. <n.len:
var a = n.sons[i]
if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
isGenericRoutine(a.sons[0].sym): isGenericRoutine(a.sons[0].sym):
let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, n.info) let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, a.info)
a.sons[0].sym = finalCallee a.sons[0].sym = finalCallee
a.sons[0].typ = finalCallee.typ a.sons[0].typ = finalCallee.typ
#a.typ = finalCallee.typ.sons[0]
proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
assert n.kind in nkCallKinds
if x.genericConverter:
for i in 1 .. <n.len:
instGenericConvertersArg(c, n.sons[i], x)
proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, arg, nil)
if m.genericConverter and result != nil:
instGenericConvertersArg(c, result, m)
proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, n.typ, n, nil)
if m.genericConverter and result != nil:
instGenericConvertersArg(c, result, m)
proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
assert x.state == csMatch assert x.state == csMatch
@ -111,8 +130,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
if ContainsGenericType(result.typ): result.typ = errorType(c) if ContainsGenericType(result.typ): result.typ = errorType(c)
return return
result = x.call result = x.call
if x.genericConverter: instGenericConvertersSons(c, result, x)
instantiateGenericConverters(c, result, x)
result.sons[0] = newSymNode(finalCallee, result.sons[0].info) result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
result.typ = finalCallee.typ.sons[0] result.typ = finalCallee.typ.sons[0]

View file

@ -664,6 +664,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
result = nil result = nil
else: else:
result = m.call result = m.call
instGenericConvertersSons(c, result, m)
# we assume that a procedure that calls something indirectly # we assume that a procedure that calls something indirectly
# has side-effects: # has side-effects:
if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect)

View file

@ -594,7 +594,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
addSon(result, copyTree(arg)) addSon(result, copyTree(arg))
inc(m.convMatches) inc(m.convMatches)
m.genericConverter = srca == isGeneric or destIsGeneric m.genericConverter = srca == isGeneric or destIsGeneric
return return result
proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
arg: PNode): PNode = arg: PNode): PNode =
@ -705,7 +705,7 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
else: else:
result = userConvMatch(c, m, base(f), a, arg) result = userConvMatch(c, m, base(f), a, arg)
proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType,
arg, argOrig: PNode): PNode = arg, argOrig: PNode): PNode =
if arg == nil or arg.kind notin nkSymChoices: if arg == nil or arg.kind notin nkSymChoices:
result = ParamTypesMatchAux(c, m, f, a, arg, argOrig) result = ParamTypesMatchAux(c, m, f, a, arg, argOrig)
@ -752,26 +752,11 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best], result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best],
argOrig) argOrig)
proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, arg, nil)
proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, n.typ, n, nil)
proc argtypeMatches*(c: PContext, f, a: PType): bool =
var m: TCandidate
initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, ast.emptyNode, nil) != nil
proc setSon(father: PNode, at: int, son: PNode) = proc setSon(father: PNode, at: int, son: PNode) =
if sonsLen(father) <= at: setlen(father.sons, at + 1) if sonsLen(father) <= at: setlen(father.sons, at + 1)
father.sons[at] = son father.sons[at] = son
proc matchesAux*(c: PContext, n, nOrig: PNode, proc matchesAux(c: PContext, n, nOrig: PNode,
m: var TCandidate, marker: var TIntSet) = m: var TCandidate, marker: var TIntSet) =
template checkConstraint(n: expr) {.immediate, dirty.} = template checkConstraint(n: expr) {.immediate, dirty.} =
if not formal.constraint.isNil: if not formal.constraint.isNil:
@ -904,4 +889,13 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
setSon(m.call, formal.position + 1, copyTree(formal.ast)) setSon(m.call, formal.position + 1, copyTree(formal.ast))
inc(f) inc(f)
proc argtypeMatches*(c: PContext, f, a: PType): bool =
var m: TCandidate
initCandidate(m, f)
let res = paramTypesMatch(c, m, f, a, ast.emptyNode, nil)
#instantiateGenericConverters(c, res, m)
# XXX this is used by patterns.nim too; I think it's better to not
# instantiate generic converters for that
result = res != nil
include suggest include suggest

View file

@ -33,7 +33,7 @@ path="$lib/ecmas"
path="$lib/pure/unidecode" path="$lib/pure/unidecode"
@if nimbabel: @if nimbabel:
babelpath="$home/babeltest/" babelpath="$home/.babel/libs/"
@end @end
@if release or quick: @if release or quick:

View file

@ -38,11 +38,11 @@ Core
* `threads <threads.html>`_ * `threads <threads.html>`_
Nimrod thread support. **Note**: This is part of the system module. Do not Nimrod thread support. **Note**: This is part of the system module. Do not
import it explicitely. import it explicitly.
* `channels <channels.html>`_ * `channels <channels.html>`_
Nimrod message passing support for threads. **Note**: This is part of the Nimrod message passing support for threads. **Note**: This is part of the
system module. Do not import it explicitely. system module. Do not import it explicitly.
* `locks <locks.html>`_ * `locks <locks.html>`_
Locks and condition variables for Nimrod. Locks and condition variables for Nimrod.

View file

@ -4,17 +4,17 @@ discard """
0''' 0'''
""" """
iterator count(x: int, skip: bool): int {.closure.} = iterator count[T](x: T, skip: bool): int {.closure.} =
if skip: return x+10 if skip: return x+10
else: yield x+1 else: yield x+1
if skip: return x+10 if skip: return x+10
else: yield x+2 else: yield x+2
proc takeProc(x: iterator (x: int, skip: bool): int) = proc takeProc[T](x: iterator (x: T, skip: bool): int) =
echo x(4, false) echo x(4, false)
echo x(4, true) echo x(4, true)
echo x(4, false) echo x(4, false)
takeProc(count) takeProc(count[int])

View file

@ -87,6 +87,7 @@ GC
Optimizations Optimizations
============= =============
- optimize 'if' with a constant condition
- escape analysis for string/seq seems to be easy to do too; - escape analysis for string/seq seems to be easy to do too;
even further write barrier specialization even further write barrier specialization
- inlining of first class functions - inlining of first class functions