Skip to content

Commit

Permalink
improved init_phase
Browse files Browse the repository at this point in the history
  • Loading branch information
Clonkk committed Mar 22, 2024
1 parent 6ab5e95 commit f34cddb
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 32 deletions.
28 changes: 22 additions & 6 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
Changelog for Nimjl. Date in format YYYY_MM_DD

Release v0.8.1 - 2024_03_23
===========================
* Repo moved to SciNim
* Added activate option in init to start-up Julia in a virtual environment
* Added Hook function at init to execute code : BEFORE jl_init() is called; AFTER jl_init() and Pkg.activate() is called but BEFORE Pkg.add calls and BEFORE the embedded code is passed through ``eval`` function.

Release v0.8.0 - 2023_09_30
===========================
* Clean-up some code
* Added more type in evaluation of Dict and Tuples
* Improve loading a Package at init when the Package is already present (speed up init phase)

Release v0.7.6 - 2023_02_22
===========================
* Small CI change

Release v0.7.5 - 2022_07_07
===========================
* Fixed https://github.com/Clonkk/nimjl/issues/18
Expand Down Expand Up @@ -34,15 +50,15 @@ Release v0.7.1 - 2022_01_04
Release v0.7.0 - 2022_01_04
===========================
* Add Julia.useModule alias for jlUseModule
* Add Julia.includeFile (include is reserved keyword) alias for jlInclude
* Add Julia.includeFile (include is reserved keyword) alias for jlInclude
* Add mechanism to embed julia files at compile-time and run the code at init for an easy way to distribute binary with Julia code contained
* Add Pkg template to easily install new Julia package during init ; it is also compatible with the embedding stuff :
* See ex09
```nim
Julia.init:
Pkg:
Julia.init:
Pkg:
add("LinearAlgebra")
Embed:
Embed:
file("myfile.jl")
```

Expand All @@ -60,7 +76,7 @@ Release v0.6.1 - 2021_10_14

Release v0.6.0 - 2021_10_08
===========================
* Add --gc:orc to CI
* Add --gc:orc to CI

Release v0.5.9 - 2021_10_05
===========================
Expand Down Expand Up @@ -157,4 +173,4 @@ Release v0.4.0 - 2021_03_08
* Add ``toJlVal`` / ``to`` proc to make conversion betwen Julia types and Nim types "smooth"
* Added Julia exception handler from Nim
* Examples in the examples folder
* Tess suite and memory leak suite
* Test suite and memory leak suite
62 changes: 36 additions & 26 deletions nimjl/glucose.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is named glucose because it gives you sugar ;)
# It contains most syntactic sugar to ease using Julia inside Nim
import std/[os, strutils, strformat, tables]
import std/[os, strutils, strformat, tables, paths]
import ./types
import ./cores
import ./functions
Expand Down Expand Up @@ -122,7 +122,9 @@ template add*(name: static string, url: static string = "", path: static string

template init*(jl: type Julia, nthreads: int, body: untyped) =
## Init Julia VM
var packages :JlPkgs
var packages: JlPkgs
var pkgEnv {.inject.} : string = ""

template Pkg(innerbody: untyped) {.used.} =
block:
# Technically accessible but since the type are not exported, what are you going to do with it ?
Expand All @@ -131,6 +133,9 @@ template init*(jl: type Julia, nthreads: int, body: untyped) =
innerbody
packages = jl_pkg_private_scope

template activate(env: string) {.used.} =
pkgEnv = string(expandTilde(Path(env)))

template Embed(innerbody: untyped) {.used.} =
## Emded Julia file explicitly of from a directory
template file(filename: static[string]) =
Expand All @@ -156,35 +161,40 @@ template init*(jl: type Julia, nthreads: int, body: untyped) =
jl_init()
# Module installation
Julia.useModule("Pkg")
else:
raise newException(JlError, "Error Julia.init() has already been initialized")

let
jlExistingPkgStr = "Dict(x[2].name => string(x[2].version) for x in Pkg.dependencies())"
jlPkgsExisting = jlEval(jlExistingPkgStr)
installed = jlPkgsExisting.to(Table[string, string])
debugEcho(&"\"Pkg.activate(\"{pkgEnv}\")\"")
discard jlEval(&"Pkg.activate(\"{pkgEnv}\")")

for pkgspec in packages:
if not checkJlPkgSpec(installed, pkgspec):
var exprs: seq[string] = @[jlExpr(":.", ":Pkg", "QuoteNode(:add)")]
for key, field in pkgspec.fieldPairs():
let fname = ":" & key
if not isEmptyOrWhitespace(field):
exprs.add jlExpr(":kw", fname, field)
when compiles(postJlInit()):
postJlInit()

let strexpr = jlExpr(":call", exprs)
var jlexpr = jlEval(strexpr)
# Will crash if version are invalid
discard jlTopLevelEval(jlexpr)
let
jlExistingPkgStr = "Dict(x[2].name => string(x[2].version) for x in Pkg.dependencies())"
jlPkgsExisting = jlEval(jlExistingPkgStr)
installed = jlPkgsExisting.to(Table[string, string])

for pkgspec in packages:
# TODO : handle precompilation ?
# Julia.precompile()
jlUsing(pkgspec.name)
for pkgspec in packages:
if not checkJlPkgSpec(installed, pkgspec):
var exprs: seq[string] = @[jlExpr(":.", ":Pkg", "QuoteNode(:add)")]
for key, field in pkgspec.fieldPairs():
let fname = ":" & key
if not isEmptyOrWhitespace(field):
exprs.add jlExpr(":kw", fname, field)

# Eval Julia code embedded
loadJlRessources()
let strexpr = jlExpr(":call", exprs)
var jlexpr = jlEval(strexpr)
# Will crash if version are invalid
discard jlTopLevelEval(jlexpr)

else:
raise newException(JlError, "Error Julia.init() has already been initialized")
for pkgspec in packages:
# TODO : handle precompilation ?
# Julia.precompile()
jlUsing(pkgspec.name)

# Eval Julia code embedded
loadJlRessources()

proc exit*(jl: type Julia, exitcode: int = 0) =
## Exit Julia VM
Expand Down Expand Up @@ -247,4 +257,4 @@ import ./sugar/operators
export operators

import ./sugar/valindexing
export valindexing
export valindexing

0 comments on commit f34cddb

Please sign in to comment.