... 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

Reply via email to