Skip to content

Commit f1e21fd

Browse files
authored
Merge pull request #42 from Clonkk/devel
Devel
2 parents 7a6924c + 18d6521 commit f1e21fd

File tree

5 files changed

+43
-21
lines changed

5 files changed

+43
-21
lines changed

examples/ex06_tensor.nim

+4-8
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ import arraymancer
22
import nimjl
33

44
proc main() =
5-
Julia.init() # Initialize Julia VM. This should be done once in the lifetime of your program.
5+
Julia.init:
6+
Pkg:
7+
add "LinearAlgebra"
8+
# Initialize Julia VM. This should be done once in the lifetime of your program.
69

710
# Just be aware that Nim Seq/Tensor are Row Major.
811
# Julia usually work in Column major.
912
var tensor = randomTensor[float](2, 3, 10.0)
1013

11-
# Uncomment this block if you haven't installed LinearAlgebra on Julia yet
12-
##################################################
13-
# Install LinearAlgebra package
14-
# let evRes = jlEval("""using Pkg; Pkg.add("LinearAlgebra")""")
15-
# doAssert not isNil(evRes)
16-
##################################################
1714
# Use the module
1815
jlUseModule("LinearAlgebra")
1916

@@ -37,6 +34,5 @@ proc main() =
3734
echo tensor
3835
echo res.shape()
3936

40-
4137
when isMainModule:
4238
main()

nimjl.nimble

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Nimjl
22
# Licensed and distributed under MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
3-
version = "0.7.0"
3+
version = "0.7.1"
44
author = "Regis Caillaud"
55
description = "Nim Julia bridge"
66
license = "MIT"

nimjl/config.nim

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ const JuliaBinPath = gorge("julia -E Sys.BINDIR").replace("\"", "")
66
# JuliaPath should be parent folder of Julia-bindir
77
# This is resolved AT COMPILE TIME. Therefore, using the environment of the machine that compile.
88
# 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"
9-
const JuliaPath* {.strdefine.} = if not existsEnv("JULIA_PATH"): JuliaBinPath.parentDir() else: getEnv("JULIA_PATH")
9+
const JuliaPath* {.strdefine.} = if not existsEnv("JULIA_PATH"): JuliaBinPath.parentDir().normalizedPath().absolutePath() else: getEnv("JULIA_PATH")
10+
static:
11+
echo JuliaPath
1012
const JuliaIncludesPath* = JuliaPath / "include" / "julia"
1113
const JuliaHeader* = "julia.h"
1214
const JuliaLibPath* = JuliaPath / "lib"

nimjl/cores.nim

+10-6
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,48 @@ import ./private/jlcores
33
import ./config
44
import std/[strformat, os, macros, tables]
55

6-
# Convert a string to Julia Symbol
76
proc jlSym*(symname: string): JlSym =
7+
## Convert a string to Julia Symbol
88
result = jl_symbol(symname.cstring)
99

1010
proc jlExceptionHandler*() =
1111
let excpt: JlValue = jl_exception_occurred()
12+
## Convert a Julia exception to Nim exception
1213
if not isNil(excpt):
1314
let msg = $(jl_exception_message())
1415
raise newException(JlError, msg)
1516
else:
1617
discard
1718

18-
# Eval function that checkes error
1919
proc jlEval*(code: string): JlValue =
20+
## Eval function that checks JuliaError
2021
result = jl_eval_string(code)
2122
jlExceptionHandler()
2223

23-
# Include file or use module
24-
# Check for nil result
2524
proc jlInclude*(filename: string) =
25+
## Include Julia file
2626
let tmp = jlEval(&"include(\"{filename}\")")
2727
if tmp.isNil:
2828
raise newException(JlError, "&Cannot include file {filename}")
2929

3030
proc jlUseModule*(modname: string) =
31+
## Call using module
3132
let tmp = jlEval(&"using {modname}")
3233
if tmp.isNil:
3334
raise newException(JlError, "&Cannot use module {modname}")
3435

35-
# Just for convenience since Julia funciton is called using
3636
proc jlUsing*(modname: string) =
37+
## Alias for conveniece
3738
jlUseModule(modname)
3839

39-
# Import can be useful
4040
proc jlImport*(modname: string) =
41+
## Import Julia file
4142
let tmp = jlEval(&"import {modname}")
4243
if tmp.isNil:
4344
raise newException(JlError, "&Cannot import module {modname}")
4445

4546
proc jlGetModule*(modname: string): JlModule =
47+
## Get Julia module. Useful to resolve ambiguity
4648
let tmp = jlEval(modname)
4749
if tmp.isNil:
4850
raise newException(JlError, "&Cannot load module {modname}")
@@ -105,6 +107,7 @@ proc private_addKeyVal*(key, value: string) =
105107
staticContents[key] = value
106108

107109
macro jlEmbedDir*(dirname: static[string]): untyped =
110+
## Embed all Julia files from specified directory
108111
result = newStmtList()
109112
let path = getProjectPath() / dirname
110113
# echo path
@@ -122,5 +125,6 @@ macro jlEmbedDir*(dirname: static[string]): untyped =
122125
# echo result.repr
123126

124127
proc jlEmbedFile*(filename: static[string]) =
128+
## Embed specific Julia file
125129
const jlContent = staticRead(getProjectPath() / filename)
126130
staticContents[filename] = jlContent

nimjl/glucose.nim

+25-5
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,26 @@ proc init*(jl: type Julia) =
1313
jlVmInit()
1414

1515
template init*(jl: type Julia, body: untyped) =
16-
# Pkg installation interface
17-
var packages : seq[string]
16+
## Init Julia VM
17+
var packages: seq[string]
1818
template Pkg(innerbody: untyped) =
19+
## Pkg installation API
1920
proc add(pkgname: string) =
2021
packages.add pkgname
2122
innerbody
2223

23-
# Embedding ressources interface
2424
template Embed(innerbody: untyped) =
25+
## Emded Julia file explicitly of from a directory
2526
template file(filename: static[string]) =
27+
## Embed file
2628
jlEmbedFile(filename)
2729

2830
template dir(dirname: static[string]) =
31+
## Embed directory
2932
jlEmbedDir(dirname)
3033

3134
template thisDir() =
35+
## Embed current dir
3236
jlEmbedDir("")
3337

3438
block:
@@ -44,6 +48,7 @@ template init*(jl: type Julia, body: untyped) =
4448
let pkg = Julia.getModule("Pkg")
4549
for pkgname in packages:
4650
discard jlCall(pkg, "add", pkgname)
51+
jlUsing(pkgname)
4752

4853
# Eval Julia code embedded
4954
loadJlRessources()
@@ -52,15 +57,19 @@ template init*(jl: type Julia, body: untyped) =
5257
raise newException(JlError, "Error Julia.init() has already been initialized")
5358

5459
proc exit*(jl: type Julia, exitcode: int = 0) =
60+
## Exit Julia VM
5561
jlVmExit(exitcode.cint)
5662

5763
proc useModule*(jl: type Julia, modname: string) =
64+
## Alias for jlUseModule. "using" is a keyword in Nim and so wasn't available
5865
jlUseModule(modname)
5966

60-
proc getModule*(jl: type Julia, modname: string) : JlModule =
67+
proc getModule*(jl: type Julia, modname: string): JlModule =
68+
## Alias for jlGetModule
6169
jlGetModule(modname)
6270

6371
proc includeFile*(jl: type Julia, fname: string) =
72+
## Alias for jlInclude
6473
jlInclude(fname)
6574

6675
# macro loadModule*(jl: type Julia, modname: untyped) =
@@ -86,21 +95,27 @@ proc `$`*(val: JlSym): string =
8695

8796
# typeof is taken by Nim already
8897
proc jltypeof*(x: JlValue): JlValue =
98+
## Call the Julia function typeof
8999
jlCall("typeof", x)
90100

91101
proc len*(val: JlValue): int =
102+
##Call length
92103
jlCall("length", val).to(int)
93104

94105
proc firstindex*(val: JlValue): int =
106+
## Call firstindex
95107
jlCall("firstindex", val).to(int)
96108

97109
proc lastindex*(val: JlValue): int =
110+
## Call lastindex
98111
jlCall("lastindex", val).to(int)
99112

100113
template getproperty*(val: JlValue, propertyname: string): JlValue =
114+
## Call getproperty
101115
jlCall("getproperty", val, jlSym(propertyname))
102116

103117
template setproperty*(val: JlValue, propertyname: string, newval: untyped) =
118+
## Call setproperty
104119
discard jlCall("setproperty!", val, jlSym(propertyname), newval)
105120

106121
#####################################################
@@ -110,26 +125,31 @@ import std/macros
110125

111126
{.experimental: "dotOperators".}
112127

113-
macro unpackVarargs_first(callee, arg_first: untyped; arg_second: untyped, args: varargs[untyped]):untyped =
128+
macro unpackVarargs_first(callee, arg_first: untyped; arg_second: untyped, args: varargs[untyped]): untyped =
114129
result = newCall(callee)
115130
result.add arg_first
116131
result.add arg_second
117132
for a in args:
118133
result.add a
119134

120135
template `.()`*(jl: type Julia, funcname: untyped, args: varargs[JlValue, toJlVal]): JlValue =
136+
## Alias to call a Julia function
121137
jlCall(astToStr(funcname), args)
122138

123139
template `.()`*(jlmod: JlModule, funcname: untyped, args: varargs[JlValue, toJlVal]): JlValue =
140+
## Alias to call a Julia function
124141
jlCall(jlmod, astToStr(funcname), args)
125142

126143
template `.()`*(jlval: JlValue, funcname: untyped, args: varargs[JlValue, toJlVal]): JlValue =
144+
## Alias to call a Julia function
127145
unpackVarargs_first(jlCall, astToStr(funcname), jlval, args)
128146

129147
template `.`*(jlval: JlValue, propertyname: untyped): JlValue =
148+
## Alias for getproperty
130149
getproperty(jlval, astToStr(propertyname))
131150

132151
template `.=`*(jlval: var JlValue, fieldname: untyped, newval: untyped) =
152+
## Alias for setproperty
133153
setproperty(jlval, astToStr(fieldname), newval)
134154

135155
# Re-export

0 commit comments

Comments
 (0)