1
1
# This file is named glucose because it gives you sugar ;)
2
2
# It contains most syntactic sugar to ease using Julia inside Nim
3
- import std/ [os, strutils, strformat]
3
+ import std/ [os, strutils, strformat, tables ]
4
4
import ./ types
5
5
import ./ cores
6
6
import ./ functions
@@ -10,6 +10,50 @@ import ./private/jlcores
10
10
11
11
type Julia* = object
12
12
13
+ # ####################################################
14
+ # Interop and utility
15
+ # ####################################################
16
+ proc `$` * (val: JlValue): string =
17
+ jlCall(" string" , val).to(string )
18
+
19
+ proc `$` * (val: JlModule): string =
20
+ jlCall(" string" , val).to(string )
21
+
22
+ proc `$` * [T](val: JlArray[T]) : string =
23
+ jlCall(" string" , val).to(string )
24
+
25
+ proc `$` * (val: JlFunc): string =
26
+ jlCall(" string" , val).to(string )
27
+
28
+ proc `$` * (val: JlSym): string =
29
+ jlCall(" string" , val).to(string )
30
+
31
+ # typeof is taken by Nim already
32
+ proc jltypeof* (x: JlValue): JlValue =
33
+ # # Call the Julia function typeof
34
+ jlCall(" typeof" , x)
35
+
36
+ proc len* (val: JlValue): int =
37
+ # #Call length
38
+ jlCall(" length" , val).to(int )
39
+
40
+ proc firstindex* (val: JlValue): int =
41
+ # # Call firstindex
42
+ jlCall(" firstindex" , val).to(int )
43
+
44
+ proc lastindex* (val: JlValue): int =
45
+ # # Call lastindex
46
+ jlCall(" lastindex" , val).to(int )
47
+
48
+ template getproperty* (val: JlValue, propertyname: string ): JlValue =
49
+ # # Call getproperty
50
+ jlCall(" getproperty" , val, jlSym(propertyname))
51
+
52
+ template setproperty* (val: JlValue, propertyname: string , newval: untyped ) =
53
+ # # Call setproperty
54
+ discard jlCall(" setproperty!" , val, jlSym(propertyname), newval)
55
+
56
+
13
57
proc init* (jl: type Julia, nthreads: int = 1 ) =
14
58
jlVmInit(nthreads)
15
59
36
80
name, url, path, subdir, rev, version, mode, level: string
37
81
JlPkgs = seq [JlPkgSpec]
38
82
83
+ proc checkJlPkgSpec(installed: Table[string , string ], package: JlPkgSpec) : bool =
84
+ # Check if package is installed with the correct version
85
+
86
+ result = false
87
+ if installed.contains(package.name):
88
+ let installedVer = installed[package.name]
89
+ var verCheck = " "
90
+ if installedVer != " nothing" :
91
+ # Split + symbol for some reason Julia.Pkg sometimes use it even if it's outside of semver
92
+ verCheck = installedVer.split('+' )[0 ]
93
+
94
+ if package.version.isEmptyOrWhitespace():
95
+ # If no Pkg version is specified, package presence is enough
96
+ result = true
97
+ else :
98
+ # Else result is true if semver matches
99
+ result = (verCheck == package.version)
100
+
39
101
# Workaround because named parameters do not work inside closure for proc defined in template
40
102
# TODO : Should string be static ?
41
103
proc addImpl(pkgs: var JlPkgs, name: static string , url: static string = " " , path: static string = " " , subdir: static string = " " , rev: static string = " " , version: static string = " " , mode: static string = " " , level: static string = " " ) =
@@ -94,16 +156,26 @@ template init*(jl: type Julia, nthreads: int, body: untyped) =
94
156
jl_init()
95
157
# Module installation
96
158
Julia.useModule(" Pkg" )
159
+
160
+ let
161
+ jlExistingPkgStr = " Dict(x[2].name => string(x[2].version) for x in Pkg.dependencies())"
162
+ jlPkgsExisting = jlEval(jlExistingPkgStr)
163
+ installed = jlPkgsExisting.to(Table[string , string ])
164
+
165
+ for pkgspec in packages:
166
+ if not checkJlPkgSpec(installed, pkgspec):
167
+ var exprs: seq [string ] = @ [jlExpr(" :." , " :Pkg" , " QuoteNode(:add)" )]
168
+ for key, field in pkgspec.fieldPairs():
169
+ let fname = " :" & key
170
+ if not isEmptyOrWhitespace(field):
171
+ exprs.add jlExpr(" :kw" , fname, field)
172
+
173
+ let strexpr = jlExpr(" :call" , exprs)
174
+ var jlexpr = jlEval(strexpr)
175
+ # Will crash if version are invalid
176
+ discard jlTopLevelEval(jlexpr)
177
+
97
178
for pkgspec in packages:
98
- var exprs: seq [string ] = @ [jlExpr(" :." , " :Pkg" , " QuoteNode(:add)" )]
99
- for key, field in pkgspec.fieldPairs():
100
- let fname = " :" & key
101
- if not isEmptyOrWhitespace(field):
102
- exprs.add jlExpr(" :kw" , fname, field)
103
- let strexpr = jlExpr(" :call" , exprs)
104
- var jlexpr = jlEval(strexpr)
105
- # Will crash if version are invalid
106
- discard jlTopLevelEval(jlexpr)
107
179
# TODO : handle precompilation ?
108
180
# Julia.precompile()
109
181
jlUsing(pkgspec.name)
@@ -133,49 +205,6 @@ proc includeFile*(jl: type Julia, fname: string) =
133
205
# macro loadModule*(jl: type Julia, modname: untyped) =
134
206
# TODO generate a proc ``modname`` that returns module
135
207
136
- # ####################################################
137
- # Interop and utility
138
- # ####################################################
139
- proc `$` * (val: JlValue): string =
140
- jlCall(" string" , val).to(string )
141
-
142
- proc `$` * (val: JlModule): string =
143
- jlCall(" string" , val).to(string )
144
-
145
- proc `$` * [T](val: JlArray[T]) : string =
146
- jlCall(" string" , val).to(string )
147
-
148
- proc `$` * (val: JlFunc): string =
149
- jlCall(" string" , val).to(string )
150
-
151
- proc `$` * (val: JlSym): string =
152
- jlCall(" string" , val).to(string )
153
-
154
- # typeof is taken by Nim already
155
- proc jltypeof* (x: JlValue): JlValue =
156
- # # Call the Julia function typeof
157
- jlCall(" typeof" , x)
158
-
159
- proc len* (val: JlValue): int =
160
- # #Call length
161
- jlCall(" length" , val).to(int )
162
-
163
- proc firstindex* (val: JlValue): int =
164
- # # Call firstindex
165
- jlCall(" firstindex" , val).to(int )
166
-
167
- proc lastindex* (val: JlValue): int =
168
- # # Call lastindex
169
- jlCall(" lastindex" , val).to(int )
170
-
171
- template getproperty* (val: JlValue, propertyname: string ): JlValue =
172
- # # Call getproperty
173
- jlCall(" getproperty" , val, jlSym(propertyname))
174
-
175
- template setproperty* (val: JlValue, propertyname: string , newval: untyped ) =
176
- # # Call setproperty
177
- discard jlCall(" setproperty!" , val, jlSym(propertyname), newval)
178
-
179
208
# ####################################################
180
209
# Syntactic sugar
181
210
# ####################################################
0 commit comments