Skip to content

Commit 54d5535

Browse files
committed
progress
1 parent 8b99ee9 commit 54d5535

File tree

2 files changed

+109
-112
lines changed

2 files changed

+109
-112
lines changed

compiler/main.nim

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ import ic / [cbackend, integrity, navigator, ic]
3030

3131
import ../dist/checksums/src/checksums/sha1
3232

33-
import pipelines, nifbackend
33+
import pipelines
34+
35+
when not defined(nimKochBootstrap):
36+
import nifbackend
3437

3538
when not defined(leanCompiler):
3639
import docgen
@@ -137,14 +140,17 @@ proc commandNifC(graph: ModuleGraph) =
137140
## Generate C code from precompiled NIF files.
138141
## This is the new IC approach: compile modules to NIF first with `nim m`,
139142
## then generate C code from the entry.nif file with whole-program DCE.
140-
let conf = graph.config
141-
extccomp.initVars(conf)
143+
when not defined(nimKochBootstrap):
144+
let conf = graph.config
145+
extccomp.initVars(conf)
142146

143-
if not extccomp.ccHasSaneOverflow(conf):
144-
conf.symbols.defineSymbol("nimEmulateOverflowChecks")
147+
if not extccomp.ccHasSaneOverflow(conf):
148+
conf.symbols.defineSymbol("nimEmulateOverflowChecks")
145149

146-
# Use the NIF backend to generate C code
147-
nifbackend.generateCode(graph, conf.projectMainIdx)
150+
# Use the NIF backend to generate C code
151+
nifbackend.generateCode(graph, conf.projectMainIdx)
152+
else:
153+
rawMessage(graph.config, errGenerated, "NIF backend not available during bootstrap build")
148154

149155
proc commandCompileToC(graph: ModuleGraph) =
150156
let conf = graph.config

compiler/nifbackend.nim

Lines changed: 96 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -17,110 +17,101 @@
1717
## 1. Compile modules to NIF: nim m mymodule.nim
1818
## 2. Generate C from NIF: nim nifc myproject.nim
1919

20-
when defined(nimKochBootstrap):
21-
# During bootstrap, NIF functionality is not available
22-
import ".." / [ast, options, lineinfos, modulegraphs, pathutils, msgs]
20+
import std/[intsets, tables, sets, os]
2321

24-
proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
22+
when defined(nimPreviewSlimSystem):
23+
import std/assertions
24+
25+
import ast, options, lineinfos, modulegraphs, cgendata, cgen,
26+
pathutils, extccomp, msgs, modulepaths, idents, types, ast2nif
27+
28+
proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[PSym] =
29+
## Traverse the module dependency graph using a stack.
30+
## Returns all modules that need code generation, in dependency order.
31+
var visited = initIntSet()
32+
var stack: seq[FileIndex] = @[mainFileIdx]
33+
var modules: seq[PSym] = @[]
34+
var cachedModules: seq[FileIndex] = @[]
35+
36+
while stack.len > 0:
37+
let fileIdx = stack.pop()
38+
39+
if visited.containsOrIncl(int(fileIdx)):
40+
continue
41+
42+
# Load module from NIF
43+
let module = moduleFromNifFile(g, fileIdx, cachedModules)
44+
if module == nil:
45+
continue
46+
47+
modules.add module
48+
49+
# Add dependencies to stack (they come from cachedModules)
50+
for dep in cachedModules:
51+
if not visited.contains(int(dep)):
52+
stack.add dep
53+
cachedModules.setLen(0)
54+
55+
result = modules
56+
57+
proc setupNifBackendModule(g: ModuleGraph; module: PSym): BModule =
58+
## Set up a BModule for code generation from a NIF module.
59+
if g.backend == nil:
60+
g.backend = cgendata.newModuleList(g)
61+
result = cgen.newModule(BModuleList(g.backend), module, g.config)
62+
63+
proc generateCodeForModule(g: ModuleGraph; module: PSym) =
64+
## Generate C code for a single module.
65+
let moduleId = module.position
66+
var bmod = BModuleList(g.backend).modules[moduleId]
67+
if bmod == nil:
68+
bmod = setupNifBackendModule(g, module)
69+
70+
# Generate code for the module's top-level statements
71+
if module.ast != nil:
72+
cgen.genTopLevelStmt(bmod, module.ast)
73+
74+
# Finalize the module
75+
finalCodegenActions(g, bmod, newNodeI(nkStmtList, module.info))
76+
77+
# Generate dispatcher methods
78+
for disp in getDispatchers(g):
79+
genProcAux(bmod, disp)
80+
81+
proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
82+
## Main entry point for NIF-based C code generation.
83+
## Traverses the module dependency graph and generates C code.
84+
85+
# Reset backend state
86+
resetForBackend(g)
87+
88+
# Load all modules in dependency order using stack traversal
89+
let modules = loadModuleDependencies(g, mainFileIdx)
90+
if modules.len == 0:
2591
rawMessage(g.config, errGenerated,
26-
"NIF backend not available during bootstrap build")
27-
28-
else:
29-
import std/[intsets, tables, sets, os]
30-
31-
when defined(nimPreviewSlimSystem):
32-
import std/assertions
33-
34-
import ast, options, lineinfos, modulegraphs, cgendata, cgen,
35-
pathutils, extccomp, msgs, modulepaths, idents, types, ast2nif
36-
37-
proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[PSym] =
38-
## Traverse the module dependency graph using a stack.
39-
## Returns all modules that need code generation, in dependency order.
40-
var visited = initIntSet()
41-
var stack: seq[FileIndex] = @[mainFileIdx]
42-
var modules: seq[PSym] = @[]
43-
var cachedModules: seq[FileIndex] = @[]
44-
45-
while stack.len > 0:
46-
let fileIdx = stack.pop()
47-
48-
if visited.containsOrIncl(int(fileIdx)):
49-
continue
50-
51-
# Load module from NIF
52-
let module = moduleFromNifFile(g, fileIdx, cachedModules)
53-
if module == nil:
54-
continue
55-
56-
modules.add module
57-
58-
# Add dependencies to stack (they come from cachedModules)
59-
for dep in cachedModules:
60-
if not visited.contains(int(dep)):
61-
stack.add dep
62-
cachedModules.setLen(0)
63-
64-
result = modules
65-
66-
proc setupNifBackendModule(g: ModuleGraph; module: PSym): BModule =
67-
## Set up a BModule for code generation from a NIF module.
68-
if g.backend == nil:
69-
g.backend = cgendata.newModuleList(g)
70-
result = cgen.newModule(BModuleList(g.backend), module, g.config)
71-
72-
proc generateCodeForModule(g: ModuleGraph; module: PSym) =
73-
## Generate C code for a single module.
74-
let moduleId = module.position
75-
var bmod = BModuleList(g.backend).modules[moduleId]
76-
if bmod == nil:
77-
bmod = setupNifBackendModule(g, module)
78-
79-
# Generate code for the module's top-level statements
80-
if module.ast != nil:
81-
cgen.genTopLevelStmt(bmod, module.ast)
82-
83-
# Finalize the module
84-
finalCodegenActions(g, bmod, newNodeI(nkStmtList, module.info))
85-
86-
# Generate dispatcher methods
87-
for disp in getDispatchers(g):
88-
genProcAux(bmod, disp)
89-
90-
proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
91-
## Main entry point for NIF-based C code generation.
92-
## Traverses the module dependency graph and generates C code.
93-
94-
# Reset backend state
95-
resetForBackend(g)
96-
97-
# Load all modules in dependency order using stack traversal
98-
let modules = loadModuleDependencies(g, mainFileIdx)
99-
if modules.len == 0:
100-
rawMessage(g.config, errGenerated,
101-
"Cannot load NIF file for main module: " & toFullPath(g.config, mainFileIdx))
102-
return
103-
104-
# Set up backend modules
105-
for module in modules:
106-
discard setupNifBackendModule(g, module)
107-
108-
# Generate code for all modules except main (main goes last)
109-
let mainModule = g.getModule(mainFileIdx)
110-
for module in modules:
111-
if module != mainModule:
112-
generateCodeForModule(g, module)
113-
114-
# Generate main module last (so all init procs are registered)
115-
if mainModule != nil:
116-
generateCodeForModule(g, mainModule)
117-
118-
# Write C files
119-
if g.backend != nil:
120-
cgenWriteModules(g.backend, g.config)
121-
122-
# Run C compiler
123-
if g.config.cmd != cmdTcc:
124-
extccomp.callCCompiler(g.config)
125-
if not g.config.hcrOn:
126-
extccomp.writeJsonBuildInstructions(g.config, g.cachedFiles)
92+
"Cannot load NIF file for main module: " & toFullPath(g.config, mainFileIdx))
93+
return
94+
95+
# Set up backend modules
96+
for module in modules:
97+
discard setupNifBackendModule(g, module)
98+
99+
# Generate code for all modules except main (main goes last)
100+
let mainModule = g.getModule(mainFileIdx)
101+
for module in modules:
102+
if module != mainModule:
103+
generateCodeForModule(g, module)
104+
105+
# Generate main module last (so all init procs are registered)
106+
if mainModule != nil:
107+
generateCodeForModule(g, mainModule)
108+
109+
# Write C files
110+
if g.backend != nil:
111+
cgenWriteModules(g.backend, g.config)
112+
113+
# Run C compiler
114+
if g.config.cmd != cmdTcc:
115+
extccomp.callCCompiler(g.config)
116+
if not g.config.hcrOn:
117+
extccomp.writeJsonBuildInstructions(g.config, g.cachedFiles)

0 commit comments

Comments
 (0)