diff options
Diffstat (limited to 'compiler/sem.nim')
-rw-r--r-- | compiler/sem.nim | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index cd0df0de0..bc994201d 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -12,7 +12,7 @@ import ast, strutils, hashes, options, lexer, astalgo, trees, treetab, wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math, - magicsys, parser, nversion, nimsets, semfold, importer, + magicsys, parser, nversion, nimsets, semfold, modulepaths, importer, procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity, @@ -122,7 +122,7 @@ proc commonType*(x, y: PType): PType = if a.sons[idx].kind == tyEmpty: return y elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: var nt: PType - for i in 0.. <a.len: + for i in 0..<a.len: let aEmpty = isEmptyContainer(a.sons[i]) let bEmpty = isEmptyContainer(b.sons[i]) if aEmpty != bEmpty: @@ -423,7 +423,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, result = evalMacroCall(c.module, c.cache, n, nOrig, sym) if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, sym, flags) - result = wrapInComesFrom(nOrig.info, result) + result = wrapInComesFrom(nOrig.info, sym, result) popInfoContext() proc forceBool(c: PContext, n: PNode): PNode = @@ -449,7 +449,7 @@ include semtypes, semtempl, semgnrc, semstmts, semexprs proc addCodeForGenerics(c: PContext, n: PNode) = for i in countup(c.lastGenericIdx, c.generics.len - 1): var prc = c.generics[i].inst.sym - if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone: + if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone: if prc.ast == nil or prc.ast.sons[bodyPos] == nil: internalError(prc.info, "no code for " & prc.name.s) else: @@ -495,13 +495,15 @@ proc isImportSystemStmt(n: PNode): bool = case n.kind of nkImportStmt: for x in n: - let f = checkModuleName(x, false) + if x.kind == nkIdent: + let f = checkModuleName(x, false) + if f == magicsys.systemModule.info.fileIndex: + return true + of nkImportExceptStmt, nkFromStmt: + if n[0].kind == nkIdent: + let f = checkModuleName(n[0], false) if f == magicsys.systemModule.info.fileIndex: return true - of nkImportExceptStmt, nkFromStmt: - let f = checkModuleName(n[0], false) - if f == magicsys.systemModule.info.fileIndex: - return true else: discard proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = @@ -520,14 +522,18 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = else: result = n result = semStmt(c, result) - # BUGFIX: process newly generated generics here, not at the end! - if c.lastGenericIdx < c.generics.len: - var a = newNodeI(nkStmtList, n.info) - addCodeForGenerics(c, a) - if sonsLen(a) > 0: - # a generic has been added to `a`: - if result.kind != nkEmpty: addSon(a, result) - result = a + when false: + # Code generators are lazy now and can deal with undeclared procs, so these + # steps are not required anymore and actually harmful for the upcoming + # destructor support. + # BUGFIX: process newly generated generics here, not at the end! + if c.lastGenericIdx < c.generics.len: + var a = newNodeI(nkStmtList, n.info) + addCodeForGenerics(c, a) + if sonsLen(a) > 0: + # a generic has been added to `a`: + if result.kind != nkEmpty: addSon(a, result) + result = a result = hloStmt(c, result) if gCmd == cmdInteractive and not isEmptyType(result.typ): result = buildEchoStmt(c, result) @@ -564,6 +570,18 @@ proc myProcess(context: PPassContext, n: PNode): PNode = result = ast.emptyNode #if gCmd == cmdIdeTools: findSuggest(c, n) +proc testExamples(c: PContext) = + let inp = toFullPath(c.module.info) + let outp = inp.changeFileExt"" & "_examples.nim" + renderModule(c.runnableExamples, inp, outp) + let backend = if isDefined("js"): "js" + elif isDefined("cpp"): "cpp" + elif isDefined("objc"): "objc" + else: "c" + if os.execShellCmd("nim " & backend & " -r " & outp) != 0: + quit "[Examples] failed" + removeFile(outp) + proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = var c = PContext(context) if gCmd == cmdIdeTools and not c.suggestionsMade: @@ -578,5 +596,6 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = result.add(c.module.ast) popOwner(c) popProcCon(c) + if c.runnableExamples != nil: testExamples(c) const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose) |