diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ccgstmts.nim | 4 | ||||
-rwxr-xr-x | compiler/cgen.nim | 2 | ||||
-rwxr-xr-x | compiler/msgs.nim | 2 | ||||
-rwxr-xr-x | compiler/sem.nim | 5 | ||||
-rwxr-xr-x | compiler/semcall.nim | 40 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 1 | ||||
-rwxr-xr-x | compiler/seminst.nim | 6 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 15 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 34 |
9 files changed, 64 insertions, 45 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 089f7fb83..9d5659f5e 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -124,6 +124,7 @@ proc genBreakState(p: BProc, n: PNode) = lineF(p, cpsStmts, "if ((((NI*) $1.ClEnv)[0]) < 0) break;$n", [rdLoc(a)]) # lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)]) +proc genVarPrototypeAux(m: BModule, sym: PSym) proc genSingleVar(p: BProc, a: PNode) = var v = a.sons[0].sym if sfCompileTime in v.flags: return @@ -142,6 +143,9 @@ proc genSingleVar(p: BProc, a: PNode) = genObjectInit(p.module.preInitProc, cpsInit, v.typ, v.loc, true) # Alternative construction using default constructor (which may zeromem): # if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc) + if sfExportc in v.flags and generatedHeader != nil: + genVarPrototypeAux(generatedHeader, v) + else: assignLocalVar(p, v) initLocalVar(p, v, immediateAsgn) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 5bdbefde1..d024f3479 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -799,8 +799,6 @@ proc genVarPrototypeAux(m: BModule, sym: PSym) = proc genVarPrototype(m: BModule, sym: PSym) = genVarPrototypeAux(m, sym) - if sfExportc in sym.flags and generatedHeader != nil: - genVarPrototypeAux(generatedHeader, sym) proc addIntTypes(result: var PRope) {.inline.} = appf(result, "#define NIM_INTBITS $1", [ diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 0f795c07d..240115817 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -132,7 +132,7 @@ const errNumberOutOfRange: "number $1 out of valid range", errNnotAllowedInCharacter: "\\n not allowed in character literal", errClosingBracketExpected: "closing ']' expected, but end of file reached", - errMissingFinalQuote: "missing final \'", + errMissingFinalQuote: "missing final \' for character literal", errIdentifierExpected: "identifier expected, but found \'$1\'", errNewlineExpected: "newline expected, but found \'$1\'", errInvalidModuleName: "invalid module name: '$1'", diff --git a/compiler/sem.nim b/compiler/sem.nim index 911eafb08..c70cbf61e 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -39,14 +39,15 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType proc semStmt(c: PContext, n: PNode): PNode proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) proc addParams(c: PContext, n: PNode, kind: TSymKind) -proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) -proc addResultNode(c: PContext, n: PNode) +proc maybeAddResult(c: PContext, s: PSym, n: PNode) proc instGenericContainer(c: PContext, n: PNode, header: PType): PType proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc fixImmediateParams(n: PNode): PNode proc activate(c: PContext, n: 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) = if formal.kind != tyError and actual.kind != tyError: LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) & diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 962e4d3cc..0a5f19822 100755 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -84,15 +84,34 @@ proc resolveOverloads(c: PContext, n, orig: PNode, getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym), args]) -proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {. - noinline.}= - for i in 1 .. <n.len: - var a = n.sons[i] - if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and - isGenericRoutine(a.sons[0].sym): - let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, n.info) - a.sons[0].sym = finalCallee - a.sons[0].typ = finalCallee.typ + +proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) = + if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and + isGenericRoutine(a.sons[0].sym): + let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, a.info) + a.sons[0].sym = finalCallee + 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 = 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) return result = x.call - if x.genericConverter: - instantiateGenericConverters(c, result, x) + instGenericConvertersSons(c, result, x) result.sons[0] = newSymNode(finalCallee, result.sons[0].info) result.typ = finalCallee.typ.sons[0] diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 7b37987ee..d0fbcab6f 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -664,6 +664,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = nil else: result = m.call + instGenericConvertersSons(c, result, m) # we assume that a procedure that calls something indirectly # has side-effects: if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 8e164531a..0a1a17f72 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -93,9 +93,7 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) = # add it here, so that recursive generic procs are possible: addDecl(c, result) pushProcCon(c, result) - if result.kind in {skProc, skMethod, skConverter, skMacro}: - addResult(c, result.typ.sons[0], n.info, result.kind) - addResultNode(c, n) + maybeAddResult(c, result, n) var b = n.sons[bodyPos] var symMap: TIdTable InitIdTable symMap @@ -168,6 +166,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.typ = newTypeS(tyProc, c) rawAddSon(result.typ, nil) result.typ.callConv = fn.typ.callConv + if result.kind == skIterator: result.typ.flags.incl(tfIterator) + var oldPrc = GenericCacheGet(c, entry) if oldPrc == nil: c.generics.generics.add(entry) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 68d485f48..abd064a62 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -713,6 +713,12 @@ proc doDestructorStuff(c: PContext, s: PSym, n: PNode) = useSym(t.sons[i].destructor), n.sons[paramsPos][1][0]])) +proc maybeAddResult(c: PContext, s: PSym, n: PNode) = + if s.typ.sons[0] != nil and + (s.kind != skIterator or s.typ.callConv == ccClosure): + addResult(c, s.typ.sons[0], n.info, s.kind) + addResultNode(c, n) + proc semProcAux(c: PContext, n: PNode, kind: TSymKind, validPragmas: TSpecialWords): PNode = result = semProcAnnotation(c, n) @@ -794,17 +800,13 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if n.sons[genericParamsPos].kind == nkEmpty: ParamsTypeCheck(c, s.typ) pushProcCon(c, s) - if s.typ.sons[0] != nil and - (kind != skIterator or s.typ.callConv == ccClosure): - addResult(c, s.typ.sons[0], n.info, kind) - addResultNode(c, n) + maybeAddResult(c, s, n) if sfImportc notin s.flags: # no semantic checking for importc: let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) # unfortunately we cannot skip this step when in 'system.compiles' # context as it may even be evaluated in 'system.compiles': n.sons[bodyPos] = transformBody(c.module, semBody, s) - #if s.typ.sons[0] != nil and kind != skIterator: addResultNode(c, n) popProcCon(c) else: if s.typ.sons[0] != nil and kind != skIterator: @@ -1076,7 +1078,8 @@ proc insertDestructors(c: PContext, varSection: PNode): varTyp = varId.sym.typ info = varId.info - if varTyp != nil and instantiateDestructor(c, varTyp): + if varTyp != nil and instantiateDestructor(c, varTyp) and + sfGlobal notin varId.sym.flags: var tryStmt = newNodeI(nkTryStmt, info) if j < totalVars - 1: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1f2511694..2fecda427 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -594,7 +594,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, addSon(result, copyTree(arg)) inc(m.convMatches) m.genericConverter = srca == isGeneric or destIsGeneric - return + return result proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, arg: PNode): PNode = @@ -705,8 +705,8 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, else: result = userConvMatch(c, m, base(f), a, arg) -proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, - arg, argOrig: PNode): PNode = +proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, + arg, argOrig: PNode): PNode = if arg == nil or arg.kind notin nkSymChoices: result = ParamTypesMatchAux(c, m, f, a, arg, argOrig) else: @@ -752,27 +752,12 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best], 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) = if sonsLen(father) <= at: setlen(father.sons, at + 1) father.sons[at] = son -proc matchesAux*(c: PContext, n, nOrig: PNode, - m: var TCandidate, marker: var TIntSet) = +proc matchesAux(c: PContext, n, nOrig: PNode, + m: var TCandidate, marker: var TIntSet) = template checkConstraint(n: expr) {.immediate, dirty.} = if not formal.constraint.isNil: if matchNodeKinds(formal.constraint, n): @@ -904,4 +889,13 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = setSon(m.call, formal.position + 1, copyTree(formal.ast)) 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 |