Re: Extract sprite data from old DOS game resource file?
You are completely correct @cumulonimbus (sorry for the long silence). I am a complete beginner when it comes to assembly. But I've played around with the DOS debugging (in DOSBox) and here are my observations: * the executable is DOS MZ 16-bit format * the main executable seems to load **.bin** files and execute them as code, which makes it hard for me to follow what the code is doing * the assumption that these **.sar** files hold all of the resources (sprites, text, sound, ...) was **correct** , as every time a new sprite or text is shown on the screen, the debugger says for example '41891222: FILES:file open command 0 file zelres1.sar' My question is: does anyone know any DOS (MS-DOS) assembly to help me figure out how sprites are loaded from these **.sar** files? Or does anyone know of a website/forum that specializes in these kind of things? Thanks
Re: pegs: match without guessing openarray size
But sadly, it also doesn't work at compile-time.
Re: pegs: match without guessing openarray size
@sky_khan That's it! Perfect, thanks!
Re: pegs: match without guessing openarray size
This code: import pegs static: var matches = newSeq[string](10) let fixedString = "mkdir D:\...\nimgen_test\build\libmodbus" if fixedString.match(peg"cd\s+{\D}\:", matches): # <-- Error in this line echo matches[0] Run throws /playground/nim/lib/pure/pegs.nim(1661, 13) Error: index 11 not in 0 .. 10. Notice the static statement. Is this a bug?
Re: pegs: match without guessing openarray size
Thanks @sky_khan, But how do I get the capture from the result? This now gives @["cd C:"], I need it to return just the captured substring {D} ("C" in this case), like match does.
pegs: match without guessing openarray size
Hi, Example that doesn't work: import pegs var matches = newSeq[string]() # --> Works if using for example: newSeq[string](10) let fixedString = "cd C:\\something\\sometimes\\someone" result = fixedString.match(peg"cd\s+{\D}\:", matches) if fixedString.match(peg"cd\s+{\D}\:", matches): echo matches [0] Run How do I use pegs' " **proc match(s: string; pattern: Peg; matches: var openArray[string]; start = 0): bool** " without guessing the length of **matches**? Or is there another procedure that can be used for this? Thanks
Re: Nim Modbus library
I tried the static build now with **nim c -d:modbusGit -d:modbusStatic modbus.nim**. What version of Nim are you using? **devel** (couple of days old) on Windows 10 x64 Also, how did you install nimterop? Manually cloned nimterop branch **v020** from github and ran **nimble install**. Did you change currentSourcePath()? Tried **currentSourcePath()** and a fixed path, both throw: Hint: paths [Processing] Hint: types [Processing] # Setting up Git repo: https://github.com/stephane/libmodbus # Pulling repository stack trace: (most recent call last) C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(575, 32) C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(497, 11) buildLibrary C:\Nim\lib\system\assertions.nim(27, 20) failedAssertImpl C:\Nim\lib\system\assertions.nim(20, 11) raiseAssert C:\Nim\lib\system\fatal.nim(39, 5) sysFatal D:\VISTA_NAMIZJE\NIM\testing\libmodbus\modbus.nim(12, 10) template/generic instantiation of `getHeader` from here C:\Nim\lib\system\fatal.nim(39, 5) Error: unhandled exception: C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(497, 12) `cmakeDeps or conDeps` # Build configuration failed - No build files found in D:/VISTA_NAMIZJE/NIM/testing/libmodbus/build/libmodbus/ [AssertionError] Run If I manually clone the **libmodbus** into **... /build/libmodbus** I get: Hint: paths [Processing] Hint: types [Processing] # Resetting D:/VISTA_NAMIZJE/NIM/testing/libmodbus/build/libmodbus/ stack trace: (most recent call last) C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(569, 23) C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(383, 10) getGitPath C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(169, 13) gitPull C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(140, 19) gitReset C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(27, 11) execAction C:\Nim\lib\system\assertions.nim(27, 20) failedAssertImpl C:\Nim\lib\system\assertions.nim(20, 11) raiseAssert C:\Nim\lib\system\fatal.nim(39, 5) sysFatal D:\VISTA_NAMIZJE\NIM\testing\libmodbus\modbus.nim(12, 10) template/generic instantiation of `getHeader` from here C:\Nim\lib\system\fatal.nim(39, 5) Error: unhandled exception: C:\Users\matic\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(27, 12) `ret == 0` Command failed: (128, false) ccmd: cmd /c cd D:/VISTA_NAMIZJE/NIM/testing/libmodbus/build/libmodbus/ && git reset --hard result: fatal: not a git repository (or any of the parent directories): .git [AssertionError] Run
Re: Nim Modbus library
@shashlick I just tried it **nim c -d:modbusGit modbus.nim** on Windows and get: Hint: plugin [Processing] Hint: paths [Processing] Hint: types [Processing] # Setting up Git repo: https://github.com/stephane/libmodbus # Pulling repository stack trace: (most recent call last) ...\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(575, 32) ...\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(497, 11) buildLibrary C:\Nim\lib\system\assertions.nim(27, 20) failedAssertImpl C:\Nim\lib\system\assertions.nim(20, 11) raiseAssert C:\Nim\lib\system\fatal.nim(39, 5) sysFatal C:\libmodbus_test\modbus.nim(11, 10) template/generic instantiation of `getHeader` from here C:\Nim\lib\system\fatal.nim(39, 5) Error: unhandled exception: ...\.nimble\pkgs\nimterop-0.1.0\nimterop\build.nim(497, 12) `cmakeDeps or conDeps` # Build configuration failed - No build files found in C:\libmodbus_test\build\libmodbus [AssertionError] Press any key to continue . . . Run Plus, the _libmodbus_ source gets cloned into the _nimterop_ nimble directory.
Re: Nim Modbus library
Never finished it, no. And that was 2 years ago. Your best bet is _c2nim_ and [https://github.com/stephane/libmodbus](https://github.com/stephane/libmodbus)
Re: 'intVal is not accessible' error?
Will do, apologies.
'intVal is not accessible' error?
Hi guys, I get a: fatal.nim(48)sysFatal Error: unhandled exception: intVal is not accessible [FieldError] Run error when trying to update an old project to the newest version of Nim. More details are in this github issue: [https://github.com/nim-lang/Nim/issues/6083](https://github.com/nim-lang/Nim/issues/6083) (my details are at the bottom of the page) Any help would be much appreciated, thanks! Matic
Re: Compiler selects wrong procedure?
@doofenstein Right, I forgot the {.cdecl.}, good catch. The reason why the cast is there, is that the iup library has only one function to set the callbacks, which in `Nim` is: # Callback definition Icallback* = proc (arg: PtrIhandle): cint {.cdecl.} # Function for setting a callback proc setCallback*(ih: PtrIhandle, name: cstring, fn: Icallback): Icallback {.importc: "IupSetCallback", cdecl, discardable.}` Run and in `C` it's: // Callback definition typedef int (*Icallback)(Ihandle*); // Function for setting a callback Icallback IupSetCallback(Ihandle* ih, const char *name, Icallback func); Run Which works great for callbacks that have the exact same signature as Icallback. But some callbacks have additional parameters! And in `C` example code for the library they just cast the different callback signatures with `(Icallback)`. Example from the IUP official docs: // Functions int btn_on_off_cb(Ihandle *self) { // code } int btn_image_button_cb( Ihandle *self,int b, int e ) { // code } // Setting up the callbacks IupSetCallback( btn_on_off, "ACTION", (Icallback) btn_on_off_cb ); IupSetCallback( btn_image, "ACTION", (Icallback) btn_image_button_cb ); Run So I'm just doing the same as these examples in `C`, because I don't know of a way to do this better in `Nim`. Any suggestions would be greatly appreciated?
Compiler selects wrong procedure?
When casting, a procedure is not properly selected when two procedures with different signatures have the same name. The examples below use types from the __iup__ and __nimpy__ libraries. I included all the relevant parts from the libraries and shortened the code a bit: # types imported from the iup library type Ihandle = object PtrIhandle* = ptr Ihandle Icallback* = proc (arg: PtrIhandle): cint {.cdecl.} # types imported from the nimpy library type PPyObject* = distinct pointer PyObject* = ref object rawPyObj: PPyObject Run # mymodule.nim proc turn_on*(bulb: PyObject) = discard Run # main.nim import mymodule proc turn_on(button: PtrIhandle): cint = discard def main() = #[ some code ]# # Setting a callback for a button from the iup library btn_on.setCallback("ACTION", cast[Icallback](turn_on)) # Error line Run The following error is thrown when compiling with nim c main.nim: main.nim(9, 34) Error: expression cannot be cast to Icallback=proc (arg: PtrIhandle): cint{.cdecl.} Run The compiler selects the mymodule.turn_on proc instead of main.turn_on in the line: btn_on.setCallback("ACTION", cast[Icallback](turn_on)) Run First off, I didn't know that you can reference the module you are inside in. Cool. I tried it, and it works: btn_on.setCallback("ACTION", cast[Icallback](main.turn_on)) Run But my feeling is that the compiler should know which is the correct procedure based on the signature or at least say that it doesn't know which one it should pick. Should I report this issue or am I missing something?
Re: Nim development blog
The bullet point system of talking points is excellent Having timestamps of where a point begins would also be great.
Re: Extract sprite data from old DOS game resource file?
> What's also possible, is that multiple pixels are stored in one byte. I don't > know the exact specs, though it might be possible that if a sprite can only > have four colors, each pixel is a palette color index stored in two bits > therefore a byte holds four pixels and the palette selector for each sprite > is stored somewhere else. Yeah, I thought so. I was hoping there were some standard thing one could try to see if data was packed in some slightly standard way. Oh well. > I would recommend just taking a bunch of screen shots and cutting out the > sprites in image editor. In the end, if I don't find anything else, I'll probably go this route. Thanks guys.
Extract sprite data from old DOS game resource file?
Hi guys, I have a couple resource files from an old MS-DOS game called `Zeliard`. The files have a `.sar` extension, if that is of any help. I would like to find out how the sprite information is stored in these files, but I have no knowledge of how it is `packed`. Some data for the game text is stored in plain ascii and there are some references to other files inside it in plain ascii, like KING.GRP, ... The whole file is about 330kB, so I tried storing each byte as a single color value (0..255) and block storing the data in 8x8, 16x16 and 32x32 chunks and then storing the chunks in a single image file, to see if anything would visually stand out as being a sprite, but no luck (well at least I can't see anything useful). Any ideas on where to start? Thanks, Matic
Re: Should we get rid of style insensitivity?
A quick search found that `compiler/idents.nim` proc `cmpIgnoreStyle` and `lib/core/macros.nim` proc `cmpIgnoreStyle` are the only ones that compare the first character via `if a[0] != b[0]: ...`, but commenting that out doesn't seem to do anything. Any other suggestions of how to remove the case sensitivity of the first character?
Re: Should we get rid of style insensitivity?
@mashingan Thanks, will try it today!
Re: Should we get rid of style insensitivity?
Can someone help me: In which places in the source code of Nim do changes have to be made to get rid of case sensitivity of the first character? I have found compiler/idents.nim proc cmpIgnoreStyle, but changing only that procedure does nothing it seems. P.S.: This is only for my personal build on Nim, I do not want to force this behavior on anyone.
Re: iup.getFile fails
Well this one seems the best to me: import iup, strutils discard iup.open(nil,nil) var str : string = "../docs/*.txt\0".alignleft(4096, padding=' ') echo iup.getFile(str) echo str.strip() iup.close() Run
Re: Should we get rid of style insensitivity?
@dom96 * Case insensitivity: `fooBar == foobar` * Style insensitivity: `foo_Bar == foobar` * Nim's style insensitivity: `foo_Bar == foobar`, but `F != f` I will only add my experience regarding the above distinction between the 2nd and 3rd point. There have been at least three occasions where I came back to programming in Nim after a week or so and always get bitten by the same mistake: * Right, I don't have to care about underscores and case, * hack, hack, hack, * compile, * What do you mean: undeclared identifier: 'quitsuccess' !!! * Ohh, right! the first character is case sensitive, it's 'QuitSuccess'!, * But 'Quitsuccess' is even uglier! * Then comes the realization that Nim is not really style insensitive... Sigh. My wish would be that we would pick between either the 1st or 2nd point.
Re: iup.getFile fails
@Stefan_Salewski Excellent, it works with string: import iup discard iup.open(nil,nil) var str : string = newString(1024) i: int = 0 for ch in "../docs/*.txt": str[i] = ch i += 1 echo iup.getFile(str) echo str iup.close() Run But even this works with string like this: import iup discard iup.open(nil,nil) var str : string = "../docs/*.txt" echo iup.getFile(str) echo str iup.close() Run the only thing is it cuts the reply to len("../docs/*.txt")! But why doesn't it work with cstring??? It's weird to see a signature `proc getFile*(arq: cstring): cint`, then when using cstring it doesn't work while it works with string. I know the whole concept is a bad way of passing data around, but still, it's very confusing, it should also work with cstring!
Re: iup.getFile fails
Hey @StefanSalewski The original signature is: proc getFile*(arq: cstring): cint Run and the C prototype is: int IupGetFile(char *arq); Run The problem might be because the function writes the selected file name back into `arq`, but I have no idea. I tried proc getFile*(arq: var cstring): cint Run but nothing changed.
Re: iup.getFile fails
@juanv Right, sorry about that, forgot to check. This works: First change the signature of getFile in iup.nim to proc getFile*(arq: ptr char): cint Run and then try this: import iup discard iup.open(nil,nil) var char_array: array[0..1000, char] char_array[0] = '.' char_array[1] = '.' char_array[2] = '/' char_array[3] = 'd' char_array[4] = 'o' char_array[5] = 'c' char_array[6] = 's' char_array[7] = '/' char_array[8] = '*' char_array[9] = '.' char_array[10] = 't' char_array[11] = 'x' char_array[12] = 't' var ptr_to_char_array = addr(char_array[0]) echo iup.getFile(ptr_to_char_array) var end_char = 0 for i in 0..char_array.len-1: if char_array[i] == '\0': end_char = i - 1 break echo $char_array[0 .. end_char] iup.close() Run I have no idea how to preallocate memory for a cstring, so it would work for cstrings. Maybe someone else can help?
Re: iup.getFile fails
Tried your exact example and it opens a dialog without any problems. I'm on Windows 10, Nim Compiler Version 0.19.1 [Windows: amd64], and the iup.dll I compiled from source.
Re: Elegant way to convert compiletime seq into const array
@LeuGim Excellent, no size bloat! Can you please explain what is happening between my example and yours? Thanks. P.S.: I just copy my code and quickly edited it, so as you noticed with the length, I deleted too much :)
Re: Elegant way to convert compiletime seq into const array
Hey @LeuGim, even if it was copied, each file is only `15kB` in size. That would be `75kB` for the 5 files that are read, but not `2MB`. I have no idea what's going on here.
Re: Elegant way to convert compiletime seq into const array
I just noticed that using this kind of compile-time magic ballons the size of the executable by a factor of about 2. When using a regular array, for example: `const myarray: array[4096, uint8] = [0, 1, 2, ...]`, the size of the executable is about `2.7 MB`. But when using the compile-time magic to read and parse the array from a text file, the executable size jumps to about `4.9 MB`. Anybody got any ideas why? (Win10 x64, Nim-devel, MSVC++)
Re: Elegant way to convert compiletime seq into const array
@Hlaaftana Thanks, it works!
Elegant way to convert compiletime seq into const array
I'm trying @cdome 's example: static: var myseq = @[1,2,3] const myarray = block: var tmp: array[myseq.len, MyType] for i in 0..< tmp.len: tmp[i] = myseq[i] tmp Run and get `Error: cannot evaluate at compile time: myseq`! Should this work or is there another way of converting compile-time seq to const array?
Re: Pure really removed for enums?
@timothee Thanks for pointing that out! So currently if there are enums with members with same names like: type PoliceAlertState = enum Green, Yellow, Red TextMarkColor = enum Green, Yellow, Red, Blue Run it throws a `Redefinition of 'Green'` error. But when the merged implementation is ready, it will allow same named enum members, but give you an error if you use the same named member without a prefix, similarly as how it already works for procs with the same name from different modules? Is my assumption correct?
Re: Pure really removed for enums?
@LeuGim Great macro! Can it somehow be adapted and used with the `Macros as pragmas` magic to make it work exactly like `pure` used to?
Re: Raspberry pi bare metal - Ultibo and Nim
@markprocess It works, AWESOME!!! Tried it on my `RPi1 - model B` and the LED is blinking! This opens up so many possibilities! Need to look at the source and try building it myself next. Thanks, Matic
Re: string change from 0.18.0 on?
Very good, thanks @miran!
Re: string change from 0.18.0 on?
@miran certainly, the rationale is Python: myString = "Some String" print(myString[0 :]) # echos "Some String" print(myString[0 : -1]) # echos "Some Strin" That issue you linked explains it, thanks. I will mark this as solved.
Re: string change from 0.18.0 on?
Sorry, my mistake! I showed the wrong code, it should be: var myString = "Some String" echo "'", myString[0 .. ^0], "'" Sorry guys! Is this a regression?
Re: string change from 0.18.0 on?
Thanks @miran, It may have been introduced in one of the mid 0.18.0 versions, because I tried it again on a friends **Windows 10 x64, Nim 0.18.1 x64** machine and the error is present. @miran, could you perhaps try it with a newer version of Nim? Thanks
Re: string change from 0.18.0 on?
Can someone with Windows please confirm the error, please?
string change from 0.18.0 on?
Pre 0.18.0: var myString = "Some String" echo "'", myString, "'" # --> echos 'Some String' Post 0.18.0: var myString = "Some String" echo "'", myString, "'" # --> echos 'Some String ', notice the space (null character) Is this here to stay or a regression? Specs: * Windows 10 x64 * Nim Version 0.18.1 [Windows: i386], recompiled today from github
Re: UTF8 problem ?
Reproduced on Windows 10. Using **default** encoding shows: ┼Ĺalma while using the **chcp 65001** encoding shows an empty string, while the direct terminal command **echo őalma** displays the string correctly.
Re: Why is my destructor not called?
Oh, seems the **\--newruntime** compiler flag is needed for destructors to work.
Re: Why is my destructor not called?
Hi, Is there a regression in the compiler, because the above example doesn't execute the destructor: {.experimental.} type MyObj = object a: int proc `=destroy`(m: MyObj) = echo "Destruct" proc works() = let x = MyObj(a: 5) works() I am on Windows 10, Nim Compiler Version 0.18.0 [Windows: i386], MinGW GCC.
Re: Is it possible to run Python code from Nim?
Do not forget Yglukhov's great **nimpy** : [https://github.com/yglukhov/nimpy](https://github.com/yglukhov/nimpy) Thanks for the shout-out twetzel59!
Re: Thoughts on imports
This is a great macro you made **@Libman**: macro load*(modulesSeq: varargs[untyped]): untyped = result = newStmtList() for module in modulesSeq: result.add parseStmt("from " & $module & " import nil") # Usage example load os, math dirExists("/")# Error! os.dirExists("/") # OK I find this macro horribly useful! Could we put it in one of the standard library modules? **future** module maybe?
Re: Nim bindings to a DLL?
Thanks for the explanation @yglukhov ! Did the **pragma** pragma maybe work differently two years ago when the wrapper was made? Why else would _{.pragma: stdcall.}_ be used there? **{.push stdcall.}** seems to be invalid, so I used: when defined(windows): ... {pragma: convention, stdcall} else: ... {pragma: convention, cdecl} ... proc wmove*(a2: ptr WINDOW; a3, a4: cint): cint {.convention, importc: "wmove".} As you can see I don't even have much experience with pragmas , let alone calling conventions. I've been looking at the original line _{.pragma: stdcall.}_ in the wrapper for two days now, and always thought to myself: "I guess this pragma sets the calling convention for the entire module, the person who wrote it had to know what he was doing, right?". As far as why all conventions seem to work, I have no idea? _stdcall_, _cdecl_ and _noconv_ seem to work, while _fastcall_ and _nimcall_ don't. Thanks again @yglukhov!
Re: Nim bindings to a DLL?
@yglukhov, THANK YOU for nudging me into trying something! If you look at the [pdcurses](https://github.com/lcrees/pdcurses/blob/master/pdcurses.nim), it has this code: when defined(windows): ... const PDCURSED = "pdcurses.dll" {.pragma: stdcall.} else: ... {.pragma: cdecl.} Doesn't this set the procedure calling convention for the rest of the file? In the above example I gave, I added the _cdecl_ in the **pragma** part of the procedure, but in the wrapper it's just: proc wmove*(a2: ptr WINDOW; a3, a4: cint): cint {.importc: "wmove".} So the abbreviated code looks like this: {.deadCodeElim: on.} ... when defined(windows): ... const PDCURSED = "pdcurses.dll" {.pragma: stdcall.} else: ... {.pragma: cdecl.} # type declarations ... {.push dynlib: PDCURSED.} # procedure declarations ... proc wmove*(a2: ptr WINDOW; a3, a4: cint): cint {.importc: "wmove".} ... {.pop.} Then I tried manually adding the _noconv_ to every procedure declaration: proc wmove*(a2: ptr WINDOW; a3, a4: cint): cint {.noconv, importc: "wmove".} AND IT WORKS! Funnily, it works with either _cdecl_, _stdcall_ or _noconv_? Why?
Re: Nim bindings to a DLL?
_stdcall_ is in the original **pdcurses** wrapper, but it produces the same result, that is why I tried _cdecl_. The enire function signature is: PDCEX int wmove(WINDOW *, int, int); The **PDCEX** macro is this: #ifdef PDC_DLL_BUILD # ifdef CURSES_LIBRARY # define PDCEX __declspec(dllexport) extern # else # define PDCEX __declspec(dllimport) # endif #else # define PDCEX extern #endif And yes, I don't know that much about type signatures, but I used _cdecl_ with the **Python3** wrapper and the **SDL2** wrapper uses it, so I thought I'd try it. Any other ideas?
Nim bindings to a DLL?
I have a dll compiled in C with a function that has the following signature: int wmove(WINDOW *, int, int); In Nim I have the following corresponding procedure: type WINDOW {.pure, final.} = object proc wmove*(a2: ptr WINDOW; a3, a4: cint): cint {.cdecl, importc: "wmove", dynlib: "pdcurses.dll".} When calling the procedure _wmove_ in Nim the **cint** parameters seem not to be passed correctly to the C function. I inserted a _printf("y=%d x=%d", a3, a4)_ call for the _cint_ parameter in the C function and it prints garbage! Does anyone know what the problem is? OS: Windows 10 x64 Nim: Nim Compiler Version 0.17.3 [Windows: i386] Dll: PDCurses 3.4 or 3.5, makes no difference. Compiled as described in the README using mingw-gcc x86. Thanks
PDCurses included DLL's
Hi guys, I'm trying to use the [pdcurses](https://github.com/lcrees/pdcurses) library with the latest [DLL (3.5)](https://github.com/wmcbrine/PDCurses) which I compiled myself, but it doesn't seem to work with it as it produces strange behaviour. I tried compiling with _MSVC_ and _MinGW-W64 gcc_, but there is no difference But it works with the DLL's provided on the Nim website: [https://nim-lang.org/install_windows.html](https://nim-lang.org/install_windows.html) Does anyone know what compiler was used to compile the official DLL's and what flags were used? Specs: * Windows 10 x64 * Nim Compiler Version 0.17.3 [Windows: amd64] * MSVC 2017 and MinGW-W64 x64 Thanks
Re: No 'hasValue' in tables module?
@Stefan_Salewski: Yes, countTable will work with what I need, thanks! @yglukhov: Thanks for reminding me about _contains_! I program so much in Python, I forget these changes when I move to Nim.
No 'hasValue' in tables module?
Hi guys, Is there a reason there is no _hasValue_ procedure in the tables module? I have this code: var uniqueObjects = newSeq[myObject]() objectTable = newTable[int, myObject]() for item in allObjects: if not(item in uniqueObjects): uniqueObjects.add(item) objectTable[] = mySeqToTableProc(uniqueObjects) But is there a way to write it like so: var objectTable = newTable[int, myObject]() counter = 0 for item in allObjects: if not(objectTable.hasValue(item)): objectTable[counter] = item counter += 1 Thanks
Re: Compile time table keys checking?
@Krux02 , I did not know that! Then it's possible to use a combination of **static** and constants to check if all referenced table keys exist at compile time? Very good!
Re: Compile time table keys checking?
**static** and **assert**, right. Unfortunately there are holes in the keys, so arrays are suitable for this purpose. Thanks guys!
Compile time table keys checking?
Hi guys, I have a const table which I want to know if all of the values, referenced in the code exist at compile time. Example: const myTable = { 1: 14.cint, 2: 23.cint 3: 4.cint, }.toTable() echo myTable[33] # <-- Can I get a compile time error here? Is it possible to get an compile-time error in the last line? Or is it better to use a different object for this purpose? Also is there a way to define the table values as **cint** without using **.cint** after every value declaration? Thanks.
Re: manual object cleanup?
Great! Thanks Araq!
manual object cleanup?
This is in context of a Python module written in Nim. I have a Nim procedure that Python will use, that will be compiled using **\--gc:none** and I want it to work like this: proc pythonProc(self, args: ptr PyObject) = var tempString: string tempSeq: seq[string] = newSeq[string]() ... # Some code that does some work ??? # How to clean up tempString and tempSeq manually ? Is there a way to implement manual variable cleanup (the last line) with **\--gc:none** and without resorting to **alloc/dealloc**? Right now I'm compiling **with the GC enabled** and doing this: proc pythonProc(self, args: ptr PyObject) = var tempString: string tempSeq: seq[string] = newSeq[string]() GC_disable() # Needed because some OS'es throw a segfault with the GC enabled ... # Some code that does some work GC_enable() GC_fullcollect()
Re: Thoughts on imports
Could the {.pure.} pragma be made to work with imports the same as it works with enums? Example: import math {.pure.} echo cos(1.0) # Error echo math.cos(1.0) # OK
Re: Nim Robot the Second
Nice! Is the white box the computer? Which one did you use?
Re: Python3 extension help needed
Thanks jlp765! Tried **GC_disableMarkAndSweep()** at the beginning and **GC_enableMarkAndSweep()** at the end of the procedure, still it throws the segmentation fault. Then I tried **GC_disable()** and **GC_enable()** \+ **GC_fullCollect()** and it works!
Re: Python3 extension help needed
Ok, so I managed to write an extension by directly using the **Python.h** header. This works great on Windows x86/x64 and Linux x86/x64, but not on Linux ARM x86 (Raspberry PI 3). By doesn't work I mean it compiles and executes, but **EVERY** call to the Nim compiled module (**.so** shared library) has about a one second delay where the CPU usage of one core jumps to 100%. Is this a known issue on ARM?
Re: Python3 extension help needed
Hey, The conclusion from the python3 IRC discussion: > Debian and Debian based distributions do not load the Python 3 shared library > into memory, so it is necessary to link statically with the **Python.h** > header. Lesson learned.
Re: Python3 extension help needed
@Araq, Fiddled around in the generated C file in the **nimcache** directory by adding code to load the library **libpython3.5m.so.1.0** in C directly and it throws the same error! The added code (added to the generated **PyInit_nim_module** function) is: N_CDECL(..., PyInit_nim_module)(void) { NimMain(); nimln_(171, "nim_module.nim"); void* handle; nimln_(900, "nim_module.nim"); handle = dlopen("libpython3.5m.so.1.0", RTLD_LAZY); nimln_(901, "nim_module.nim"); void (*init)(void) = dlsym(handle, "Py_Initialize"); nimln_(902, "nim_module.nim"); (*init)(); <- ERROR nimln_(903, "nim_module.nim"); dlclose(handle); /* Rest of the code */ } Do you perhaps know why this error occurs when invoking the **dlsym** loaded function? I know this question would probably be better placed in a python forum, but I'm hoping someone knows something about the problem!
Re: Python3 extension help needed
After further testing and help from jasonrbriggs, I found out that the error appears on all Debian Linux distributions. It works on Windows and Arch Linux, but on Ubuntu MATE (ARM), Lubuntu (x86) and Raspbian (ARM) it doesn't. Tried Python versions from 3.4 to 3.6, Nim was at the latest github version. Even this simple example (already shown above) like this throws an error: # The imported Python3 initialization function proc initialize*(){.cdecl, importc: "Py_Initialize" dynlib: "libpython3.YOUR_VERSIONm.so.1.0".} # The module's init function proc PyInit_nim_module() {.cdecl, exportc.} = {.emit: """NimMain();""".} initialize() # <--- ERROR Anyone know how the Python 3 installaion Debian distributions differs from other distributions or other OS'es?
Re: Python3.5 extension help needed
Hey @qqtop, I fixed the first example above, could you try it again? Did you try importing the second compiled module from python3? It compiles on my machine too, but when I import the module from python3 it throws the error. Thanks, Matic
Re: Python3.5 extension help needed
Hey @JohnS, Installed Valgrind and as a test I ran it with: valgrind python3 -c "print('TEST')" but I get an illegal instruction error. Also tried adding the python suppression file but the error still persists. Any ideas?
Re: Python3.5 extension help needed
Ok, I corrected the PyObject object (it has only the obRefcnt and obType fields) but now I'm getting the following error: *** Error in 'python3': free(): invalid pointer: 0x76508050 *** Traceback (most recent call last) nim_module.nim(133)PyInit_nim_module nim_module.nim(106)moduleCreate SIGABRT: Abnormal termination. I checked that the Python3 and C compilers that are used for compiling are the same, which they are. I'm guessing there is either a mistake in one of the object declarations or I'm missing something different between Windows/Linux. I checked the Nim generated C files and they are very similar except for a few naming differences. I have no more good ideas. If anyone finds anything, please let me know! Matic
Re: Python3.5 extension help needed
Hey Araq, Doesn't nim_methods point to the array with only the sentinel, or am I missing something?
Python3.5 extension help needed
I have this code that works on Windows, but not on Ubuntu MATE on the Raspberry Pi 3: # # nim_module.nim # type PySizeT* = clong # typedef int (*traverseproc)(PyObject *, visitproc, void *); TraverseProc* = proc (ob: PyObjectPtr, prc: VisitProc, p: pointer): cint{.cdecl.} # typedef int (*inquiry)(PyObject *); Inquiry* = proc (ob: PyObjectPtr): cint{.cdecl.} # typedef void (*freefunc)(void *); FreeFunc* = proc (p: pointer){.cdecl.} # typedef int (*visitproc)(PyObject *, void *); VisitProc* = proc (ob: PyObjectPtr, p: pointer): cint{.cdecl.} # typedef struct _typeobject PyTypeObject; /* opaque */ PyTypeObjectPtr* = ptr PyTypeObject PyTypeObject* {.final.} = object # Defined in "Include/object.h" # typedef struct _object { # _PyObject_HEAD_EXTRA # Py_ssize_t ob_refcnt; # struct _typeobject *ob_type; # } PyObject; # # #define _PyObject_HEAD_EXTRA\ # struct _object *_ob_next; \ # struct _object *_ob_prev; PyObjectPtr* = ptr PyObject PyObject* {.final.} = object # Defined in "Include/object.h" obNext*: PyObjectPtr obPrev*: PyObjectPtr obRefcnt*: PySizeT obType*: PyTypeObjectPtr # struct PyMethodDef { # const char *ml_name; /* The name of the built-in function/method */ # PyCFunction ml_meth;/* The C function that implements it */ # int ml_flags; /* Combination of METH_xxx flags, which mostly #describe the args expected by the C func */ # const char *ml_doc;/* The __doc__ attribute, or NULL */ # }; # typedef struct PyMethodDef PyMethodDef; PyMethodDefPtr* = ptr PyMethodDef PyMethodDef* {.final.} = object # Defined in "Include/methodobject.h" mlName*: cstring mlMeth*: PyCFunction mlFlags*: cint mlDoc*: cstring # typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); PyCFunction* = proc (self, args: PyObjectPtr): PyObjectPtr{.cdecl.} # typedef struct PyModuleDef{ # PyModuleDef_Base m_base; # const char* m_name; # const char* m_doc; # Py_ssize_t m_size; # PyMethodDef *m_methods; # struct PyModuleDef_Slot* m_slots; # traverseproc m_traverse; # inquiry m_clear; # freefunc m_free; # }PyModuleDef; PyModuleDefPtr* = ptr PyModuleDef PyModuleDef* {.final.} = object m_base*: PyModuleDefBase m_name*: cstring m_doc*: cstring m_size*: PySizeT m_methods*: PyMethodDefPtr m_slots*: PyModuleDefSlotPtr m_traverse*: TraverseProc m_clear*: Inquiry m_free*: FreeFunc # typedef struct PyModuleDef_Base { # PyObject_HEAD # PyObject* (*m_init)(void); # Py_ssize_t m_index; # PyObject* m_copy; # } PyModuleDef_Base; # #define PyObject_HEAD PyObject ob_base; PyModuleDefBasePtr* = ptr PyModuleDefBase PyModuleDefBase* {.final.} = object ob_base*: PyObject m_init*: proc (): PyObjectPtr {.cdecl.} m_index*: PySizeT m_copy*: PyObjectPtr # typedef struct PyModuleDef_Slot{ # int slot; # void *value; # } PyModuleDef_Slot; PyModuleDefSlotPtr* = ptr PyModuleDefSlot PyModuleDefSlot* {.final.} = object slot*: cint value*: pointer # PyObject* PyModule_Create2(struct PyModuleDef* module, int module_api_version) proc moduleCreate2*(module: PyModuleDefPtr; module_api_version: cint): PyObjectPtr {.cdecl, importc: "PyModule_Create2" dynlib: "libpython3.5m.so.1".} proc moduleCreate*(module: PyModuleDefPtr): PyObjectPtr {.cdecl.} = result = moduleCreate2(module, 3) var nim_method_array: array[1, PyMethodDef] = [ PyMethodDef(mlName:nil, mlMeth:nil, mlFlags:0, mlDoc:nil) ] nim_methods* {.exportc.}: PyMethodDefPtr = cast[PyMethodDefPtr]( addr(nim_method_array) ) var nim_lexers* {.exportc.}: PyModuleDef = PyModuleDef( m_base: PyModuleDefBase( ob_base:PyObject( obNext:nil, obPrev:nil, obRefcnt:1, o bType:nil), m_init:nil, m_index:0, m_copy:nil), m_name: "nim_lexers", m_doc: "", m_size: -1, m_methods: nim_methods, ) # Hack needed on windows {.emit: """N_CDECL(void, NimMain)(void);""".} proc PyInit_nim_lexers(): PyObjectPtr {.exportc, cdecl.} = {.emit: """NimMain();""".} result =
Re: Nim Modbus library
LGPL, very good. Thanks @hcorion!
Nim Modbus library
Hi, Anyone know of a Nim Modbus TCP library? Or maybe a good C Modbus TCP library? I'll port it, I just don't know any good ones. Thanks, Matic
Re: nim-chipmunk7 demos
It took some time but here it is: [https://github.com/matkuki/chipmunk7_demos](https://github.com/matkuki/chipmunk7_demos) Also available on nimble: nimble install chipmunk7_demos Have fun! Matic
Simple Python extension in Nim?
Hi guys, I want to make a simple Python3 extension in Nim. I used the **Nim Backend Integration** ([http://nim-lang.org/docs/backends.html#interfacing-backend-code-calling-nim](http://forum.nim-lang.org///nim-lang.org/docs/backends.html#interfacing-backend-code-calling-nim)) example as a starting point. The example crashes when trying to **echo** the arguments passed from the C wrapper to the Nim procedure in the **nim_module.nim** file line 5. When commenting out that line the extension module works! Can anyone tell me why? I'm using Windows Vista x64, Python 3.4.1 x64, Nim 0.14.3 x64. Compiling everything with MSVC 2010. The Nim file **nim_module.nim**: import math proc cos_func*(number: cdouble): cdouble {.exportc.} = echo "You're in Nim!" echo number # <-- This line crashes Python result = math.cos(number) It's compiled with nim c --noMain --noLinking --header:nim_module.h nim_module.nim The Python wrapper file **nim_wrapper.c**: #include #include #include "nim_module.h" /* wrapped cosine function */ static PyObject* first_func(PyObject* self, PyObject* args) { double value; double answer; /* parse the input, from python float to c double */ if (!PyArg_ParseTuple(args, "d", )) return NULL; /* if the above function returns -1, an appropriate Python exception will * have been set, and the function simply returns NULL */ /* call cos in Nim */ answer = cos_func(value); /* construct the output from cos, from c double to python float */ return Py_BuildValue("f", answer); } /* define functions in module */ static PyMethodDef nim_methods[] = { {"first_func", first_func, METH_VARARGS, "evaluate the cosine in Nim"}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef nim_module = { PyModuleDef_HEAD_INIT, "nim_wrapper", /* name of module */ "", /* module documentation, may be NULL */ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ nim_methods }; /* module initialization */ PyMODINIT_FUNC PyInit_nim_wrapper(void) { return PyModule_Create(_module); } and the **setup.py** script: import os from distutils.core import setup, Extension nim_c_files = [] items = os.listdir("nimcache/") for i in items: if i.endswith(".c"): nim_c_files.append("nimcache/" + i) nim_module = Extension( 'nim_wrapper', sources = [ 'nim_wrapper.c', ] + nim_c_files, extra_compile_args = [ "-Ipath\\to\\app\\nimcache", "-IC:\\Nim\\lib", ], ) # run the setup setup(ext_modules=[nim_module]) Building the module with: python3 setup.py build_ext --inplace The test script is: import nim_wrapper print(nim_wrapper.first_func(100))
Re: Windows nim binaries freeze
:
Re: nim-chipmunk7 demos
: