Skip to content

Commit da5f633

Browse files
committed
improved init_phase and use ordered table in code eval so the order of the files included matters
1 parent 6ab5e95 commit da5f633

File tree

9 files changed

+202
-150
lines changed

9 files changed

+202
-150
lines changed

changelog.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
Changelog for Nimjl. Date in format YYYY_MM_DD
22

3+
Release v0.8.1 - 2024_03_23
4+
===========================
5+
* Repo moved to SciNim
6+
* Added activate option in init to start-up Julia in a virtual environment
7+
* 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.
8+
* Order of update is now relevant
9+
10+
Release v0.8.0 - 2023_09_30
11+
===========================
12+
* Clean-up some code
13+
* Added more type in evaluation of Dict and Tuples
14+
* Improve loading a Package at init when the Package is already present (speed up init phase)
15+
16+
Release v0.7.6 - 2023_02_22
17+
===========================
18+
* Small CI change
19+
320
Release v0.7.5 - 2022_07_07
421
===========================
522
* Fixed https://github.com/Clonkk/nimjl/issues/18
@@ -34,15 +51,15 @@ Release v0.7.1 - 2022_01_04
3451
Release v0.7.0 - 2022_01_04
3552
===========================
3653
* Add Julia.useModule alias for jlUseModule
37-
* Add Julia.includeFile (include is reserved keyword) alias for jlInclude
54+
* Add Julia.includeFile (include is reserved keyword) alias for jlInclude
3855
* 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
3956
* Add Pkg template to easily install new Julia package during init ; it is also compatible with the embedding stuff :
4057
* See ex09
4158
```nim
42-
Julia.init:
43-
Pkg:
59+
Julia.init:
60+
Pkg:
4461
add("LinearAlgebra")
45-
Embed:
62+
Embed:
4663
file("myfile.jl")
4764
```
4865

@@ -60,7 +77,7 @@ Release v0.6.1 - 2021_10_14
6077

6178
Release v0.6.0 - 2021_10_08
6279
===========================
63-
* Add --gc:orc to CI
80+
* Add --gc:orc to CI
6481

6582
Release v0.5.9 - 2021_10_05
6683
===========================
@@ -157,4 +174,4 @@ Release v0.4.0 - 2021_03_08
157174
* Add ``toJlVal`` / ``to`` proc to make conversion betwen Julia types and Nim types "smooth"
158175
* Added Julia exception handler from Nim
159176
* Examples in the examples folder
160-
* Tess suite and memory leak suite
177+
* Test suite and memory leak suite

examples/ex01_helloworld.nim

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import nimjl
22

3-
Julia.init() # Initialize Julia VM. This should be done once in the lifetime of your program.
3+
proc main() =
4+
Julia.init() # Initialize Julia VM. This should be done once in the lifetime of your program.
45

5-
# Calling Julia function from Nim will always return a JlValue
6-
# This JlValue can be "nothing"
7-
# Therefore, Julia function who do not return a value can be discarded
8-
var res = Julia.println("Hello world")
9-
echo res # nothing
10-
# Check that res is actually nothing
11-
if res == JlNothing:
12-
echo "Julia.println returned nothing"
6+
# Calling Julia function from Nim will always return a JlValue
7+
# This JlValue can be "nothing"
8+
# Therefore, Julia function who do not return a value can be discarded
9+
var res = Julia.println("Hello world")
10+
echo res # nothing
11+
# Check that res is actually nothing
12+
if res == JlNothing:
13+
echo "Julia.println returned nothing"
1314

14-
discard Julia.println("This also works")
15+
discard Julia.println("This also works")
1516

17+
when isMainModule:
18+
main()

examples/ex02_sqrt.nim

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import nimjl
22
import std/math
33

4-
jlVmInit() # Initialize Julia VM. This should be done once in the lifetime of your program.
4+
proc main() =
5+
jlVmInit() # Initialize Julia VM. This should be done once in the lifetime of your program.
56

6-
var myval = 4.0'f64
7-
# Call Julia function "sqrt" and convert the result to a float
8-
# This syntax also works to call a function directly from a Julia modfule
9-
var res = JlBase.sqrt(myval).to(float64)
10-
# Echo on JlValue calls println from Julia
11-
echo res # 2.0
12-
doAssert res == sqrt(myval)
7+
var myval = 4.0'f64
8+
# Call Julia function "sqrt" and convert the result to a float
9+
# This syntax also works to call a function directly from a Julia modfule
10+
var res = JlBase.sqrt(myval).to(float64)
11+
# Echo on JlValue calls println from Julia
12+
echo res # 2.0
13+
doAssert res == sqrt(myval)
1314

15+
when isMainModule:
16+
main()

examples/ex03_sugar.nim

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import nimjl
22
import std/sequtils
33

4-
Julia.init()
5-
# Use Module handle
6-
discard JlMain.println(@[1, 2, 3])
7-
discard Julia.println(toSeq(0..5))
4+
proc main =
5+
Julia.init()
6+
# Use Module handle
7+
discard JlMain.println(@[1, 2, 3])
8+
discard Julia.println(toSeq(0..5))
89

9-
let arr = [1.0, 2.0, 3.0].toJlArray()
10-
# You can now use echo to call println for you on Julia type !
11-
echo jltypeof(arr)
12-
echo arr
10+
let arr = [1.0, 2.0, 3.0].toJlArray()
11+
# You can now use echo to call println for you on Julia type !
12+
echo jltypeof(arr)
13+
echo arr
1314

14-
# You can also call proc from the value directly
15-
echo arr.stride(1)
16-
echo arr.strides()
15+
# You can also call proc from the value directly
16+
echo arr.stride(1)
17+
echo arr.strides()
1718

19+
when isMainModule:
20+
main()

examples/ex04_dict.nim

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,31 @@ proc popMe[U, V](tab: var JlValue, key: U): V =
1212
# Therefore "pop!" function will not modify tab
1313
result = jlCall("pop!", tab, key).to(V)
1414

15-
16-
jlVmInit() # Initialize Julia VM. This should be done once in the lifetime of your program.
17-
18-
var mytab: Table[int64, float64] = {1'i64: 0.90'f64, 2'i64: 0.80'f64, 3'i64: 0.70'f64}.toTable
19-
block:
20-
let key = 1
21-
var poppedValue = popMe(mytab, key)
22-
# mytab has not been changed due to copy when passing value to Julia
23-
doAssert key in mytab
24-
doAssert poppedValue == mytab[key]
25-
26-
block:
27-
var myJlTab = toJlVal(mytab) # Convert myJlTab to JlValue
28-
let key = 1
29-
var poppedValue = popMe[int64, float64](myJlTab, key)
30-
doAssert not myJlTab.to(Table[int64, float64]).contains(key) # Value was removed from myJlTab
31-
doAssert poppedValue == mytab[key]
32-
33-
block:
34-
# You can use [] on Julia dict as well
35-
var jldict = toJlVal({"alpha": 1.1, "beta": 2.2}.toTable)
36-
doAssert jldict["alpha"].to(float) == 1.1
37-
doAssert jldict["beta"].to(float) == 2.2
38-
jldict["alpha"] = 3.3
39-
doAssert jldict["alpha"].to(float) == 3.3
40-
15+
proc main() =
16+
jlVmInit() # Initialize Julia VM. This should be done once in the lifetime of your program.
17+
18+
var mytab: Table[int64, float64] = {1'i64: 0.90'f64, 2'i64: 0.80'f64, 3'i64: 0.70'f64}.toTable
19+
block:
20+
let key = 1
21+
var poppedValue = popMe(mytab, key)
22+
# mytab has not been changed due to copy when passing value to Julia
23+
doAssert key in mytab
24+
doAssert poppedValue == mytab[key]
25+
26+
block:
27+
var myJlTab = toJlVal(mytab) # Convert myJlTab to JlValue
28+
let key = 1
29+
var poppedValue = popMe[int64, float64](myJlTab, key)
30+
doAssert not myJlTab.to(Table[int64, float64]).contains(key) # Value was removed from myJlTab
31+
doAssert poppedValue == mytab[key]
32+
33+
block:
34+
# You can use [] on Julia dict as well
35+
var jldict = toJlVal({"alpha": 1.1, "beta": 2.2}.toTable)
36+
doAssert jldict["alpha"].to(float) == 1.1
37+
doAssert jldict["beta"].to(float) == 2.2
38+
jldict["alpha"] = 3.3
39+
doAssert jldict["alpha"].to(float) == 3.3
40+
41+
when isMainModule:
42+
main()

examples/ex05_module.nim

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,66 @@ type
77
y: float
88
z: string
99

10-
Julia.init() # Initialize Julia VM. This should be done once in the lifetime of your program.
11-
# Include Julia file
12-
jlInclude("localmodule.jl")
13-
# Use the module. If you're confused by the syntax, go and read through Julia's Manual where module usage is explained
14-
jlUseModule(".nimjlExample")
10+
proc main() =
11+
Julia.init() # Initialize Julia VM. This should be done once in the lifetime of your program.
12+
# Include Julia file
13+
jlInclude("localmodule.jl")
14+
# Use the module. If you're confused by the syntax, go and read through Julia's Manual where module usage is explained
15+
jlUseModule(".nimjlExample")
1516

16-
block: # Tuple handling
17-
# Look, you can pass Nim tuple to Julia
18-
var mytup: MyTuple = (nimTupKey1: 1, nimTupKey2: 2)
19-
# Convert Nim tuple to Julia tuple automatically
20-
var res = Julia.customFunction(mytup)
21-
# Convert Julia tuple to Nim tuple
22-
var nimres = res.to(MyTuple)
17+
block: # Tuple handling
18+
# Look, you can pass Nim tuple to Julia
19+
var mytup: MyTuple = (nimTupKey1: 1, nimTupKey2: 2)
20+
# Convert Nim tuple to Julia tuple automatically
21+
var res = Julia.customFunction(mytup)
22+
# Convert Julia tuple to Nim tuple
23+
var nimres = res.to(MyTuple)
2324

24-
echo myTup
25-
echo nimres
25+
echo myTup
26+
echo nimres
2627

27-
doAssert myTup.nimTupKey1+1 == nimres.nimTupKey1
28-
doAssert myTup.nimTupKey2+1 == nimres.nimTupKey2
28+
doAssert myTup.nimTupKey1+1 == nimres.nimTupKey1
29+
doAssert myTup.nimTupKey2+1 == nimres.nimTupKey2
2930

30-
block: # Object manipulation
31-
# Call constructor
32-
var foo = Julia.makeFoo()
33-
# Access fields with dot syntax
34-
# Calls getproperty in Julia side
35-
echo foo.x
36-
echo foo.y
37-
echo foo.z
38-
# Modify fields with .= syntax
39-
# Calls setproperty! on Julia side
40-
foo.x = 2
41-
foo.y = 3.14
42-
foo.z = "General Kenobi !"
43-
# Yay this has been modified
44-
echo foo
31+
block: # Object manipulation
32+
# Call constructor
33+
var foo = Julia.makeFoo()
34+
# Access fields with dot syntax
35+
# Calls getproperty in Julia side
36+
echo foo.x
37+
echo foo.y
38+
echo foo.z
39+
# Modify fields with .= syntax
40+
# Calls setproperty! on Julia side
41+
foo.x = 2
42+
foo.y = 3.14
43+
foo.z = "General Kenobi !"
44+
# Yay this has been modified
45+
echo foo
4546

46-
# You can use dot syntax on Julia value to call proc as well
47-
discard foo.applyToFoo()
48-
echo foo
47+
# You can use dot syntax on Julia value to call proc as well
48+
discard foo.applyToFoo()
49+
echo foo
4950

50-
block:
51-
var foo = Foo(x: 12, y: 15, z: "This string comes from Nim")
52-
# You can convert Nim to Julia object if :
53-
# * fields have the same name and type (fieldName becomdes Julia symbol)
54-
# * The Julia type have an empty constructor -- Nim needs to initialize the Julia variable before calling setproperty! providing a default empty constructor is the easiest way of doing it
55-
var jlfoo = toJlVal(foo)
56-
echo jlfoo
57-
echo jltypeof(jlfoo) # This echo "Foo" -> Julia sees this as a Foo mutable struct type
51+
block:
52+
var foo = Foo(x: 12, y: 15, z: "This string comes from Nim")
53+
# You can convert Nim to Julia object if :
54+
# * fields have the same name and type (fieldName becomdes Julia symbol)
55+
# * The Julia type have an empty constructor -- Nim needs to initialize the Julia variable before calling setproperty! providing a default empty constructor is the easiest way of doing it
56+
var jlfoo = toJlVal(foo)
57+
echo jlfoo
58+
echo jltypeof(jlfoo) # This echo "Foo" -> Julia sees this as a Foo mutable struct type
5859

59-
discard jlfoo.applyToFoo()
60-
# Object are copid during conversions so modifying jlfoo does not modify foo
61-
# There is an exception to this for Array fields -- see ex_arrays for explanation
62-
echo jlfoo
63-
echo foo
60+
discard jlfoo.applyToFoo()
61+
# Object are copid during conversions so modifying jlfoo does not modify foo
62+
# There is an exception to this for Array fields -- see ex_arrays for explanation
63+
echo jlfoo
64+
echo foo
6465

65-
block:
66-
let res = Julia.returnDoubleValue()
67-
echo res.myint
68-
echo res.mystr
66+
block:
67+
let res = Julia.returnDoubleValue()
68+
echo res.myint
69+
echo res.mystr
6970

71+
when isMainModule:
72+
main()

examples/ex11_external_deps.nim

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import nimjl
22

3-
## See https://pkgdocs.julialang.org/dev/api/#Pkg.add for more info
4-
Julia.init(1):
5-
Pkg:
6-
add(name="Polynomials", version="3.0.0")
7-
add(name="LinearAlgebra")
8-
add("DSP")
9-
add(name="Wavelets", version="0.9.4")
3+
proc main() =
4+
## See https://pkgdocs.julialang.org/dev/api/#Pkg.add for more info
5+
Julia.init(1):
6+
Pkg:
7+
add(name="Polynomials", version="3.0.0")
8+
add(name="LinearAlgebra")
9+
add("DSP")
10+
11+
Julia.useModule("Pkg")
12+
let jlpkg = Julia.getModule("Pkg")
13+
discard jlpkg.status()
14+
15+
Julia.exit()
16+
17+
when isMainModule:
18+
main()

nimjl/cores.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,14 @@ proc jlVmExit*(exit_code: cint = 0.cint) =
8282
# discard jlEval(fmt"exit_save_sysimage({fpath})")
8383

8484
#########################################
85-
var staticContents: Table[string, string]
85+
var staticContents: OrderedTable[string, string]
8686

8787
import std/logging
8888

8989
proc loadJlRessources*() =
9090
for key, content in staticContents.pairs():
91-
info("> Nimjl loading Julia ressource: ", key, ".jl")
91+
info("> Nimjl loading Julia ressource: ", key)
92+
# debugEcho("> Nimjl loading Julia ressource: ", key)
9293
JlCode(content)
9394

9495
# Init & Exit function

0 commit comments

Comments
 (0)