Re: seq of tuples of procs
I ended-up blending both your answers in the example: proc ptest(pid: int): bool {.procvar.} = echo "foo",$pid return if pid == 100: true else: false type ProcType = proc (pid:int): bool {.gcsafe, locks: 0, nimcall.} var proc_list = newSeq[tuple[id:int; myproc: ProcType]]() proc_list.add((0,ptest)) proc_list.add((0,ptest)) proc_list.add((0,ptest)) echo proc_list[0][1](100), "\n" echo proc_list[1][1](200), "\n" echo proc_list[2][1](300) For my real code, the macro which generates and populates proc_list is now simpler, and works again. Less AST to create. Thanks!
Re: seq of tuples of procs
Thank you Krux02 and LeuGim! Both of your suggestions worked and I understand better! Long live nim. It certainly is making my life easier overall. Code is easy as Python to write, but lightning fast, and much more is possible with meta-programming.
seq of tuples of procs
I've been using meta-programming to create a sequence of tuples of procs at compile time, usable at run-time, but am having difficulty now with 0.16.0 release. This is a minimal example working with 0.14.2; my actual code has a macro to create something like ptest() and proc_list: proc ptest(pid: int): bool {.procvar.} = echo "foo",$pid return if pid == 100: true else: false var proc_list = newSeq[tuple[id:int; myproc:proc (pid:int):bool{.gcsafe, locks: 0.}]]() proc_list.add((0,ptest)) proc_list.add((0,ptest)) proc_list.add((0,ptest)) echo (proc_list[0][1](100),"\n") echo (proc_list[1][1](200),"\n") echo (proc_list[2][1](300)) The error: Error: type mismatch: got (seq[tuple[id: int, myproc: proc (pid: int): bool{.closure, gcsafe, locks: 0.}]], (int, proc (pid: int): bool{.gcsafe, locks: 0.})) but expected one of: proc add[T](x: var seq[T]; y: T) proc add(result: var string; x: float) proc add(x: var string; y: string) proc add(x: var string; y: cstring) proc add(x: var string; y: char) proc add(result: var string; x: int64) proc add[T](x: var seq[T]; y: openArray[T]) Can anybody help me so I don't pull all my hair out? It could be something simple I'm missing. I tried starting the pragma with "{.closure" but that didn't help.
Re: forum route crash with spills error
The sample spills program works with the dev version of nim. I also had to change "z1" to "z" in the spills program: echo z[1234]
forum route crash with spills error
I'm having trouble with the sample program for "spills" (latest stable nim, latest nimble, nimble version of spills) which gives this error: undeclared identifier: 'newSeqOfCap' If I search for that error in the nim forum, then Jester crashes: An error has occured in one of your routes. ... malformed MATCH expression: [undeclared identifier: "newSeqOfCap"]
Re: Nim Podcast
Or something similar to the [PyCoders Weekly](http://pycoders.com/) newsletter, which is very high quality, and easier to curate maybe since it's just a list of all good news for the week, including new packages, jobs, discussion threads, and articles.
Re: sequence of tuples of procs help
Now I'm at a bottleneck.. Inside one of my dynamically-created procedures, I need to access a sequence of tuples, dynamically created earlier in the AST tree. Is this horrible to do? Nim is giving me a warning about being non-GC-safe, but all I'm doing is using the sequence to know which procs to run. For instance, in the below code, asset_def_nau is a sequence of tuples (same structure as _seq_test_ from above post 1) and runs my procs. for i in asset_def_nau: mynaut = i[3](chart) echo "result = ", mynaut So before I just turn-off the warning, is it safe to do so? I'm NOT changing the asset_def_nau sequence, but do need to iterate it. Thanks.. please bear with me as I'm a nim newbie.
Re: sequence of tuples of procs help
My next experiment is to use tables with procs, which gives useful compiler warnings when our procs are not GC-safe. import tables # These three lines give GC-safe warnings when "gprocs[1] = ptest" runs. # var gprocs*: Table[int, proc (test: Test): bool] # gprocs = initTable[int, proc (test: Test): bool](initialSize = 16) # gprocs[1] = ptest # If we use "gcsafe" and "locks" pragmas, and remove the testSeq line # from ptest(), there aren't any GC-safe warnings. var gprocs: Table[int, proc (test: Test): bool{.gcsafe, locks: 0.}] gprocs = initTable[int, proc (test: Test): bool{.gcsafe, locks: 0.}](initialSize = 16) gprocs[1] = ptest echo "CALLING PTEST (GCSAFE): "; discard gprocs[1](testing123) I get good compiler warnings when using tables, but as I'm doing this all within AST meta-programming, I'd like to keep things as simple as possible and keep using seq of tuples-of-procs. I am hoping the compiler warnings improve when using tuples-of-procs. Is there really no way to use meta-programming proc calls with non-GC-safe procs? I just need a way to make procs first-class citizens and pass them around easily, without the requirement that they're GC-safe.
sequence of tuples of procs help
Hi all, I'm needing help with a seq of tuples of procs, used with this example: type Test* = ref TestInternal TestInternal* = object o*: seq[ffloat] var testSeq = @["abc","123"] proc addTest* (): Test = # Test constructor. result = Test(o: newSeq[ffloat]()) result.o.add(0.0); proc ptest(test: Test): bool {.procvar, discardable.} = echo "success from ptest" echo "testSeq = ", testSeq.repr result = true var testing123 = addTest() Now I need a sequence of tuples, with the "myproc" tuple element pointing to the ptest() procedure, but get a type mismatch error: var seq_tuple_test = newSeq[tuple[name:string; procID:int; procBody:string; myproc:proc (test:Test):bool]]() Error: type mismatch: got (seq[tuple[name: string, procID: int, procBody: string, myproc: proc (test: Test): bool{.closure.}]], (string, int, string, proc (test: Test): bool{.gcsafe, locks: 0.})) but expected one of: proc add(x: var string; y: cstring) proc add(x: var string; y: string) proc add[T](x: var seq[T]; y: T) proc add[T](x: var seq[T]; y: openArray[T]) proc add(x: var string; y: char) proc add[A, B](t: var OrderedTable[A, B]; key: A; val: B) proc add[A, B](t: OrderedTableRef[A, B]; key: A; val: B) proc add[A, B](t: TableRef[A, B]; key: A; val: B) proc add[A, B](t: var Table[A, B]; key: A; val: B) proc add(father, child: NimNode): NimNode proc add(father: NimNode; children: varargs[NimNode]): NimNode But this works: # Create seq_test. var seq_test = newSeq[tuple[name:string; procID:int; procBody:string; myproc:proc (test:Test):bool{.gcsafe, locks: 0.}]]() # Populate the seq, and call our procedure referenced in the tuple. seq_test.add(("yo",1,"hey",ptest)) discard seq_test[0][3](testing123) Couple questions: 1) Is there a way for the compiler to not infer 'gcsafe' and 'locks'? I don't want to hang myself later. For instance, ptest() accesses a global seq of strings called **testSeq**, and I don't know if that's safe. 2) Can I set the discardable pragma when defining seq_tuple_test? To avoid an error, I currently must call ptest() like this: **discard seq_test[0][3](testing123)**
Re: dynamically generated variables
Actually, only procs and templates can see the variables my macro created. Do I need to use a special pragma for other macros to see dynamic variables created within earlier macros?
Re: dynamically generated variables
I just fixed the 1st post's error of not being able to reference macro-created variables from a template. I just had to call the macro before the template was defined. How logical. :) I am marking this thread as _solved_.
Re: dynamically generated variables
Thank you, Araq. I generated as many sequences as possible, like these: 7 seq vars like: var system_map_{g,e,x,m,pos,neg,nau} = newSeq[tuple[id:int, sysID:int]](). 7 seq const vars like: const asset_map_{g,e,x,m,pos,neg,nau} = newSeq[int](). 1 seq var like: var system_def = newSeq[tuple[name:string, sysID:int, sysBody:string]](). 7 seq vars like: asset_def_{g|e|x|m|pos|neg|nau} = newSeq[(name:string, procID:int, procBody:string)]. indefinite number of asset procs {g|e|x|m|pos|neg|nau}proc(#): i.e. g1proc(), e8proc(), x4proc(), etc. If I made everything a constant will that mean everything is done in the VM phase and subsequent macros may reference const vars created by earlier macros? I tried accessing my const asset_[map](http://forum.nim-lang.org/postActivity.xml#map).. variables from a later macro and couldn't. I could probably get by with everything being a constant, except the asset_[def](http://forum.nim-lang.org/postActivity.xml#def).. ones. If I understand correctly, a plus of having var sequences is being able to store a lot on the heap, which I need for the asset_[def](http://forum.nim-lang.org/postActivity.xml#def).. sequences. Being able to define these before my program even runs means I can declaratively build-up all the programming building blocks from config files, and my main program can programmatically mix-and-match code blocks, which is incredibly helpful meta-programming capability.
Re: dynamically generated variables
I was able to simplify the _bootSystems()_ macro so that I could create the dynamic procs. The solution was to remove as many variables as possible, and now I don't get the **too many registers required** VM error. Now I don't need a 2nd macro (bootSystem2), but I'm still curious how to make make a macro recognize variables which were created by an earlier-executed macro. I'm wondering if one solution (only solution?) is to solely generate constant variables. Thanks.
dynamically generated variables
Hi all, Can somebody help with this scenario? const cbassets = @["g", "e", "x", "m", "pos", "neg", "nau"] template mybootup*(): expr = bootSystems() for ipos, i in @[system_flats_g, system_flats_e, system_flats_x, system_flats_m, system_flats_pos, system_flats_neg, system_flats_nau]: echo "system_flats_" & cbassets[ipos] & "= ", $i This template runs a macro named _bootSystems()_, which generates the "system_flats" variables, that the above code loops to show they were created. I'd next like to run a 2nd macro, say _bootSystems2()_, which uses the "system_flats" variables, but I get an error that says **"undeclared identifier"**, since those var variables aren't available to the 2nd macro. How do I make dynamically created variables persist "within the entire VM?" phase, just like they do for my normal program? The purpose of bootSystems2() macro will be to create some dynamically created procs, but it needs access to the "system_flats" variables to do that. I would love to keep everything within my _bootSystems()_ macro, but that gives "**Error: VM problem: too many registers required**". Do I need to update nim here? (currently runnning 0.13.0). Thanks.