From 849cf6788b18d63943c502eeae4e4267a3adf971 Mon Sep 17 00:00:00 2001
From: Clonkk <rf.clonk@linuxmail.org>
Date: Fri, 11 Feb 2022 15:22:24 +0100
Subject: [PATCH 1/4] add some docs

---
 nimjl/cores.nim   | 16 ++++++++++------
 nimjl/glucose.nim | 29 ++++++++++++++++++++++++-----
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/nimjl/cores.nim b/nimjl/cores.nim
index cb450c9..0e271e5 100644
--- a/nimjl/cores.nim
+++ b/nimjl/cores.nim
@@ -3,46 +3,48 @@ import ./private/jlcores
 import ./config
 import std/[strformat, os, macros, tables]
 
-# Convert a string to Julia Symbol
 proc jlSym*(symname: string): JlSym =
+  ## Convert a string to Julia Symbol
   result = jl_symbol(symname.cstring)
 
 proc jlExceptionHandler*() =
   let excpt: JlValue = jl_exception_occurred()
+  ## Convert a Julia exception to Nim exception
   if not isNil(excpt):
     let msg = $(jl_exception_message())
     raise newException(JlError, msg)
   else:
     discard
 
-# Eval function that checkes error
 proc jlEval*(code: string): JlValue =
+  ## Eval function that checks JuliaError
   result = jl_eval_string(code)
   jlExceptionHandler()
 
-# Include file or use module
-# Check for nil result
 proc jlInclude*(filename: string) =
+  ## Include Julia file
   let tmp = jlEval(&"include(\"{filename}\")")
   if tmp.isNil:
     raise newException(JlError, "&Cannot include file {filename}")
 
 proc jlUseModule*(modname: string) =
+  ## Call using module
   let tmp = jlEval(&"using {modname}")
   if tmp.isNil:
     raise newException(JlError, "&Cannot use module {modname}")
 
-# Just for convenience since Julia funciton is called using
 proc jlUsing*(modname: string) =
+  ## Alias for conveniece
   jlUseModule(modname)
 
-# Import can be useful
 proc jlImport*(modname: string) =
+  ## Import Julia file
   let tmp = jlEval(&"import {modname}")
   if tmp.isNil:
     raise newException(JlError, "&Cannot import module {modname}")
 
 proc jlGetModule*(modname: string): JlModule =
+  ## Get Julia module. Useful to resolve ambiguity
   let tmp = jlEval(modname)
   if tmp.isNil:
     raise newException(JlError, "&Cannot load module {modname}")
@@ -105,6 +107,7 @@ proc private_addKeyVal*(key, value: string) =
   staticContents[key] = value
 
 macro jlEmbedDir*(dirname: static[string]): untyped =
+  ## Embed all Julia files from specified directory
   result = newStmtList()
   let path = getProjectPath() / dirname
   # echo path
@@ -122,5 +125,6 @@ macro jlEmbedDir*(dirname: static[string]): untyped =
   # echo result.repr
 
 proc jlEmbedFile*(filename: static[string]) =
+  ## Embed specific Julia file
   const jlContent = staticRead(getProjectPath() / filename)
   staticContents[filename] = jlContent
diff --git a/nimjl/glucose.nim b/nimjl/glucose.nim
index 2803dac..e329324 100644
--- a/nimjl/glucose.nim
+++ b/nimjl/glucose.nim
@@ -13,22 +13,26 @@ proc init*(jl: type Julia) =
   jlVmInit()
 
 template init*(jl: type Julia, body: untyped) =
-  # Pkg installation interface
-  var packages : seq[string]
+  ## Init Julia VM
+  var packages: seq[string]
   template Pkg(innerbody: untyped) =
+    ## Pkg installation API
     proc add(pkgname: string) =
       packages.add pkgname
     innerbody
 
-  # Embedding ressources interface
   template Embed(innerbody: untyped) =
+    ## Emded Julia file explicitly of from a directory
     template file(filename: static[string]) =
+      ## Embed file
       jlEmbedFile(filename)
 
     template dir(dirname: static[string]) =
+      ## Embed directory
       jlEmbedDir(dirname)
 
     template thisDir() =
+      ## Embed current dir
       jlEmbedDir("")
 
     block:
@@ -52,15 +56,19 @@ template init*(jl: type Julia, body: untyped) =
     raise newException(JlError, "Error Julia.init() has already been initialized")
 
 proc exit*(jl: type Julia, exitcode: int = 0) =
+  ## Exit Julia VM
   jlVmExit(exitcode.cint)
 
 proc useModule*(jl: type Julia, modname: string) =
+  ## Alias for jlUseModule. "using" is a keyword in Nim and so wasn't available
   jlUseModule(modname)
 
-proc getModule*(jl: type Julia, modname: string) : JlModule =
+proc getModule*(jl: type Julia, modname: string): JlModule =
+  ## Alias for jlGetModule
   jlGetModule(modname)
 
 proc includeFile*(jl: type Julia, fname: string) =
+  ## Alias for jlInclude
   jlInclude(fname)
 
 # macro loadModule*(jl: type Julia, modname: untyped) =
@@ -86,21 +94,27 @@ proc `$`*(val: JlSym): string =
 
 # typeof is taken by Nim already
 proc jltypeof*(x: JlValue): JlValue =
+  ## Call the Julia function typeof
   jlCall("typeof", x)
 
 proc len*(val: JlValue): int =
+  ##Call length
   jlCall("length", val).to(int)
 
 proc firstindex*(val: JlValue): int =
+  ## Call firstindex
   jlCall("firstindex", val).to(int)
 
 proc lastindex*(val: JlValue): int =
+  ## Call lastindex
   jlCall("lastindex", val).to(int)
 
 template getproperty*(val: JlValue, propertyname: string): JlValue =
+  ## Call getproperty
   jlCall("getproperty", val, jlSym(propertyname))
 
 template setproperty*(val: JlValue, propertyname: string, newval: untyped) =
+  ## Call setproperty
   discard jlCall("setproperty!", val, jlSym(propertyname), newval)
 
 #####################################################
@@ -110,7 +124,7 @@ import std/macros
 
 {.experimental: "dotOperators".}
 
-macro unpackVarargs_first(callee, arg_first: untyped; arg_second: untyped, args: varargs[untyped]):untyped =
+macro unpackVarargs_first(callee, arg_first: untyped; arg_second: untyped, args: varargs[untyped]): untyped =
   result = newCall(callee)
   result.add arg_first
   result.add arg_second
@@ -118,18 +132,23 @@ macro unpackVarargs_first(callee, arg_first: untyped; arg_second: untyped, args:
     result.add a
 
 template `.()`*(jl: type Julia, funcname: untyped, args: varargs[JlValue, toJlVal]): JlValue =
+  ## Alias to call a Julia function
   jlCall(astToStr(funcname), args)
 
 template `.()`*(jlmod: JlModule, funcname: untyped, args: varargs[JlValue, toJlVal]): JlValue =
+  ## Alias to call a Julia function
   jlCall(jlmod, astToStr(funcname), args)
 
 template `.()`*(jlval: JlValue, funcname: untyped, args: varargs[JlValue, toJlVal]): JlValue =
+  ## Alias to call a Julia function
   unpackVarargs_first(jlCall, astToStr(funcname), jlval, args)
 
 template `.`*(jlval: JlValue, propertyname: untyped): JlValue =
+  ## Alias for getproperty
   getproperty(jlval, astToStr(propertyname))
 
 template `.=`*(jlval: var JlValue, fieldname: untyped, newval: untyped) =
+  ## Alias for setproperty
   setproperty(jlval, astToStr(fieldname), newval)
 
 # Re-export

From eef0170bb9d7f51cb2b38a8f2bfa99ab2e36d52a Mon Sep 17 00:00:00 2001
From: Clonkk <sidger@zoho.com>
Date: Wed, 2 Mar 2022 10:11:58 +0100
Subject: [PATCH 2/4] normalize path during compilaiton

---
 examples/ex06_tensor.nim | 12 ++++--------
 nimjl/config.nim         |  4 +++-
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/examples/ex06_tensor.nim b/examples/ex06_tensor.nim
index ae5069c..2397c3e 100644
--- a/examples/ex06_tensor.nim
+++ b/examples/ex06_tensor.nim
@@ -2,18 +2,15 @@ import arraymancer
 import nimjl
 
 proc main() =
-  Julia.init() # Initialize Julia VM. This should be done once in the lifetime of your program.
+  Julia.init:
+    Pkg:
+      add "LinearAlgebra"
+  # Initialize Julia VM. This should be done once in the lifetime of your program.
 
   # Just be aware that Nim Seq/Tensor are Row Major.
   # Julia usually work in Column major.
   var tensor = randomTensor[float](2, 3, 10.0)
 
-  # Uncomment this block if you haven't installed LinearAlgebra on Julia yet
-  ##################################################
-  # Install LinearAlgebra package
-  # let evRes = jlEval("""using Pkg; Pkg.add("LinearAlgebra")""")
-  # doAssert not isNil(evRes)
-  ##################################################
   # Use the module
   jlUseModule("LinearAlgebra")
 
@@ -37,6 +34,5 @@ proc main() =
       echo tensor
       echo res.shape()
 
-
 when isMainModule:
   main()
diff --git a/nimjl/config.nim b/nimjl/config.nim
index 21d90a0..5000741 100644
--- a/nimjl/config.nim
+++ b/nimjl/config.nim
@@ -6,7 +6,9 @@ const JuliaBinPath = gorge("julia -E Sys.BINDIR").replace("\"", "")
 # JuliaPath should be parent folder of Julia-bindir
 # This is resolved AT COMPILE TIME. Therefore, using the environment of the machine that compile.
 # If you want to ship a binary, you need to install in a fixed path and pass this path using -d:JuliaPath="/path/to/Julia"
-const JuliaPath* {.strdefine.} = if not existsEnv("JULIA_PATH"): JuliaBinPath.parentDir() else: getEnv("JULIA_PATH")
+const JuliaPath* {.strdefine.} = if not existsEnv("JULIA_PATH"): JuliaBinPath.parentDir().normalizedPath().absolutePath() else: getEnv("JULIA_PATH")
+static:
+  echo JuliaPath
 const JuliaIncludesPath* = JuliaPath / "include" / "julia"
 const JuliaHeader* = "julia.h"
 const JuliaLibPath* = JuliaPath / "lib"

From e6c725687d85a6fac16d55c579d9550035bf9612 Mon Sep 17 00:00:00 2001
From: Clonkk <sidger@zoho.com>
Date: Mon, 4 Apr 2022 12:03:58 +0200
Subject: [PATCH 3/4] =?UTF-8?q?add=20using=20to=20pkg=20added=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 nimjl/glucose.nim | 1 +
 1 file changed, 1 insertion(+)

diff --git a/nimjl/glucose.nim b/nimjl/glucose.nim
index e329324..ed09239 100644
--- a/nimjl/glucose.nim
+++ b/nimjl/glucose.nim
@@ -48,6 +48,7 @@ template init*(jl: type Julia, body: untyped) =
     let pkg = Julia.getModule("Pkg")
     for pkgname in packages:
       discard jlCall(pkg, "add", pkgname)
+      jlUsing(pkgname)
 
     # Eval Julia code embedded
     loadJlRessources()

From 18d65214e901ab0268a2616135e55ad5ee894b93 Mon Sep 17 00:00:00 2001
From: Clonkk <sidger@zoho.com>
Date: Mon, 4 Apr 2022 12:04:47 +0200
Subject: [PATCH 4/4] bump nimble version

---
 nimjl.nimble | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nimjl.nimble b/nimjl.nimble
index 4f82e30..9b6e3c4 100644
--- a/nimjl.nimble
+++ b/nimjl.nimble
@@ -1,6 +1,6 @@
 # Nimjl
 # Licensed and distributed under MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
-version       = "0.7.0"
+version       = "0.7.1"
 author        = "Regis Caillaud"
 description   = "Nim Julia bridge"
 license       = "MIT"