123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- #
- #
- # The Nim Compiler
- # (c) Copyright 2023 Andreas Rumpf
- #
- # See the file "copying.txt", included in this
- # distribution, for details about the copyright.
- #
- ## Nim Intermediate Representation, designed to capture all of Nim's semantics without losing too much
- ## precious information. Can easily be translated into C. And to JavaScript, hopefully.
- from std/os import addFileExt, `/`, createDir
- import std / assertions
- import ".." / [ast, modulegraphs, renderer, transf, options, msgs, lineinfos]
- import nirtypes, nirinsts, ast2ir, nirlineinfos, nirfiles, nirvm
- import ".." / ic / [rodfiles, bitabs]
- type
- PCtx* = ref object of TPassContext
- m: ModuleCon
- c: ProcCon
- oldErrorCount: int
- bytecode: Bytecode
- proc newCtx*(module: PSym; g: ModuleGraph; idgen: IdGenerator): PCtx =
- var lit = Literals()
- var nirm = (ref NirModule)(types: initTypeGraph(lit), lit: lit)
- var m = initModuleCon(g, g.config, idgen, module, nirm)
- m.noModularity = true
- PCtx(m: m, c: initProcCon(m, nil, g.config), idgen: idgen, bytecode: initBytecode(nirm))
- proc refresh*(c: PCtx; module: PSym; idgen: IdGenerator) =
- #c.m = initModuleCon(c.m.graph, c.m.graph.config, idgen, module, c.m.nirm)
- #c.m.noModularity = true
- c.c = initProcCon(c.m, nil, c.m.graph.config)
- c.idgen = idgen
- proc setupGlobalCtx*(module: PSym; graph: ModuleGraph; idgen: IdGenerator) =
- if graph.repl.isNil:
- graph.repl = newCtx(module, graph, idgen)
- #registerAdditionalOps(PCtx graph.repl)
- else:
- refresh(PCtx graph.repl, module, idgen)
- proc setupNirReplGen*(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext =
- setupGlobalCtx(module, graph, idgen)
- result = PCtx graph.repl
- proc evalStmt(c: PCtx; n: PNode) =
- let n = transformExpr(c.m.graph, c.idgen, c.m.module, n)
- let pc = genStmt(c.c, n)
- #var res = ""
- #toString c.m.nirm.code, NodePos(pc), c.m.nirm.lit.strings, c.m.nirm.lit.numbers, c.m.symnames, res
- #res.add "\n--------------------------\n"
- #toString res, c.m.types.g
- if pc.int < c.m.nirm.code.len:
- c.bytecode.interactive = c.m.graph.interactive
- execCode c.bytecode, c.m.nirm.code, pc
- #echo res
- proc runCode*(c: PPassContext; n: PNode): PNode =
- let c = PCtx(c)
- # don't eval errornous code:
- if c.oldErrorCount == c.m.graph.config.errorCounter:
- evalStmt(c, n)
- result = newNodeI(nkEmpty, n.info)
- else:
- result = n
- c.oldErrorCount = c.m.graph.config.errorCounter
- type
- NirPassContext* = ref object of TPassContext
- m: ModuleCon
- c: ProcCon
- proc openNirBackend*(g: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext =
- var lit = Literals()
- var nirm = (ref NirModule)(types: initTypeGraph(lit), lit: lit)
- let m = initModuleCon(g, g.config, idgen, module, nirm)
- NirPassContext(m: m, c: initProcCon(m, nil, g.config), idgen: idgen)
- proc gen(c: NirPassContext; n: PNode) =
- let n = transformExpr(c.m.graph, c.idgen, c.m.module, n)
- let pc = genStmt(c.c, n)
- proc nirBackend*(c: PPassContext; n: PNode): PNode =
- gen(NirPassContext(c), n)
- result = n
- proc closeNirBackend*(c: PPassContext; finalNode: PNode) =
- discard nirBackend(c, finalNode)
- let c = NirPassContext(c)
- let nimcache = getNimcacheDir(c.c.config).string
- createDir nimcache
- let outp = nimcache / c.m.module.name.s.addFileExt("nir")
- #c.m.nirm.code = move c.c.code
- try:
- store c.m.nirm[], outp
- echo "created: ", outp
- except IOError:
- rawMessage(c.c.config, errFatal, "serialization failed: " & outp)
|