... with the least friction?
Incremental adoption was in my mind one of Nim's strong points, but I don't
actually know what that workflow looks like. Ignoring a build system at the
moment, below is one approach. I'd love to hear more ideas. Incremental
adoption is where the intended design of theoretical languages like Carbon and
CPPFront may eventually be great, but I wonder if Nim can already do this well
and I'm just being obtuse not seeing it.
This example begins wrapping the entry point C source. It also demonstrated
overriding a `void say()` in the C source with a Nim version, and wraps `int
main()` to replace in the future with a full Nim version, passing CLI args and
calling it for now. I imagine a similar nim module for each C file, but I'm
unsure the C includes and Nim includes will work like I want... I'll have to
try it later. But this is enough to ask my general question.
import strutils
proc say() {.exportc.}
{.emit:"""
/*VARSECTION*/ // inject as far down in the header section as possible
""" & staticRead("main.c").
multiReplace(@[
("int main","int cmain"),
("void say","void csay")])
# (override more here as the project progresses...)
# yes, textual replacement is kind of gross and possibly
# results in conflicting symbols. Is there a better way?
.}
proc say() {.exportc.} =
echo "nim version of say() called by main() in original C source"
proc cmain(argc: int, argv: cstringArray):int {.importc: "cmain", nodecl.}
import os
proc main =
echo "nim main(), gathering parameters and forwarding to original C
main()"
var argv = allocCStringArray([])
argv[0] = getAppFilename()
for i in 1..paramCount():
argv[i] = paramStr(i)
# call the original c source that we haven't replaced yet
discard cmain(paramCount()+1,argv)
when isMainModule:
main()
Run