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