|
| 1 | +import std/assertions |
| 2 | +import "../../compiler/icnif" / [nifencoder, nifdecoder] |
| 3 | +import "../../compiler" / [idents, ast, astalgo, options, pathutils, modulegraphs, modules, msgs, pipelines, syntaxes, sem, llstream, lineinfos] |
| 4 | + |
| 5 | +const TestCodeDir = currentSourcePath().AbsoluteFile.splitFile().dir / RelativeDir"testcode" |
| 6 | + |
| 7 | +proc newConfigRefForTest(): ConfigRef = |
| 8 | + var conf = newConfigRef() |
| 9 | + conf.setDefaultLibpath() |
| 10 | + conf.searchPaths.add(conf.libpath) |
| 11 | + result = conf |
| 12 | + |
| 13 | +proc newModuleGraphForSem(cache: IdentCache; conf: ConfigRef): ModuleGraph = |
| 14 | + var graph = newModuleGraph(cache, conf) |
| 15 | + graph.setPipeLinePass(SemPass) |
| 16 | + graph.compilePipelineSystemModule() |
| 17 | + result = graph |
| 18 | + |
| 19 | +proc sem(graph: ModuleGraph; path: AbsoluteFile): PNode = |
| 20 | + result = nil |
| 21 | + |
| 22 | + let fileIdx = fileInfoIdx(graph.config, path) |
| 23 | + var module = newModule(graph, fileIdx) |
| 24 | + registerModule(graph, module) |
| 25 | + |
| 26 | + var idgen = idGeneratorFromModule(module) |
| 27 | + let ctx = preparePContext(graph, module, idgen) |
| 28 | + |
| 29 | + var stream = llStreamOpen(path, fmRead) |
| 30 | + if stream == nil: |
| 31 | + rawMessage(graph.config, errCannotOpenFile, path.string) |
| 32 | + return nil |
| 33 | + |
| 34 | + var p: Parser = default(Parser) |
| 35 | + syntaxes.openParser(p, fileIdx, stream, graph.cache, graph.config) |
| 36 | + |
| 37 | + checkFirstLineIndentation(p) |
| 38 | + block processCode: |
| 39 | + if graph.stopCompile(): break processCode |
| 40 | + var n = parseTopLevelStmt(p) |
| 41 | + if n.kind == nkEmpty: break processCode |
| 42 | + # read everything, no streaming possible |
| 43 | + var sl = newNodeI(nkStmtList, n.info) |
| 44 | + sl.add n |
| 45 | + while true: |
| 46 | + var n = parseTopLevelStmt(p) |
| 47 | + if n.kind == nkEmpty: break |
| 48 | + sl.add n |
| 49 | + |
| 50 | + var semNode = semWithPContext(ctx, sl) |
| 51 | + |
| 52 | + return semNode |
| 53 | + |
| 54 | +# Compare PSym and PNode but ignores fields nifencoder and nifdecoder doesn't support |
| 55 | +proc eql(x, y: PSym): bool = |
| 56 | + if x == nil and y == nil: |
| 57 | + result = true |
| 58 | + elif x == nil or y == nil: |
| 59 | + result = false |
| 60 | + elif x.itemId.item == y.itemId.item and x.kind == y.kind and x.name.s == y.name.s and x.flags == y.flags and x.disamb == y.disamb: |
| 61 | + if x.owner == nil and y.owner == nil: |
| 62 | + result = true |
| 63 | + elif x.owner == nil or y.owner == nil: |
| 64 | + result = false |
| 65 | + elif x.owner.kind == y.owner.kind and x.owner.name.s == y.owner.name.s: |
| 66 | + if x.kind == skModule: |
| 67 | + result = true |
| 68 | + else: |
| 69 | + result = x.position == y.position |
| 70 | + else: |
| 71 | + result = false |
| 72 | + else: |
| 73 | + result = false |
| 74 | + |
| 75 | +proc eql(x, y: PNode): bool = |
| 76 | + if x == nil and y == nil: |
| 77 | + result = true |
| 78 | + elif x == nil or y == nil: |
| 79 | + result = false |
| 80 | + elif x.kind == y.kind and x.safeLen == y.safeLen: |
| 81 | + case x.kind: |
| 82 | + of nkSym: |
| 83 | + result = eql(x.sym, y.sym) |
| 84 | + if not result: |
| 85 | + echo "Symbol mismatch:" |
| 86 | + #debug(x) |
| 87 | + #debug(y) |
| 88 | + of nkCharLit .. nkTripleStrLit: |
| 89 | + result = sameValue(x, y) |
| 90 | + else: |
| 91 | + result = true |
| 92 | + for i in 0 ..< x.safeLen: |
| 93 | + if not eql(x[i], y[i]): |
| 94 | + result = false |
| 95 | + break |
| 96 | + else: |
| 97 | + result = false |
| 98 | + |
| 99 | +proc testNifEncDec(graph: ModuleGraph; src: string) = |
| 100 | + let fullPath = TestCodeDir / RelativeFile("testmod.nim") |
| 101 | + let n = sem(graph, fullPath) |
| 102 | + let nif = saveNifToBuffer(n, graph.config) |
| 103 | + # Don't reuse the ModuleGraph used for semcheck when load NIF. |
| 104 | + var graphForLoad = newModuleGraph(newIdentCache(), newConfigRefForTest()) |
| 105 | + let n2 = loadNifFromBuffer(nif, fullPath, graphForLoad) |
| 106 | + #debug(n) |
| 107 | + #debug(n2) |
| 108 | + assert eql(n, n2) |
| 109 | + |
| 110 | +var conf = newConfigRefForTest() |
| 111 | +var cache = newIdentCache() |
| 112 | +var graph = newModuleGraphForSem(cache, conf) |
| 113 | +testNifEncDec(graph, "testmod.nim") |
0 commit comments