Re: Editor support for Nim 1.0

2019-12-12 Thread jangko
"editor support" can have a very wide meaning. I personally too lazy to 
maintain it(npp) seriously. If it does not break with new compiler or still 
able to run in new editor, I prefer to spend my productivity in other areas. 
Perhaps other plugins authors agree with me. :)


Re: thiscall calling convention?

2019-05-22 Thread jangko
This is a perfect job for Nim macros. You can use macros API to construct 
generated code or generate string of Nim code then parsed by parseStmt, or a 
mix of both.

With macros, you can generate not only type declaration, but also convenience 
wrapper at the same time.

Here is an incomplete example, you can study real life implementation from 
reference section


import macros

proc comImpl64(n: NimNode, methods: NimNode): NimNode {.used.} =
  # put your 64 bit implementation here
  result = newEmptyNode() # replace this with implementation result

proc comImpl32(n: NimNode, methods: NimNode): NimNode {.used.} =
  # put your 32 bit implementation here
  result = newEmptyNode() # replace this with implementation result

macro comMacro(n: untyped, methods: untyped): untyped =
  when defined(cpu64):
result = comImpl64(n, methods)
  else:
result = comImpl32(n, methods)

comMacro(ITextHost):
  proc TxGetDC(): HDC
  proc TxReleaseDC(hdc: HDC): INT


Run

References:

  * [Nim and CPP 
VTABLE](https://github.com/nim-lang/Nim/wiki/Playing-with-CPP--VTABLE-from-Nim)
  * [route.nim in nim-json-rpc](https://github.com/status-im/nim-json-rpc)
  * [nimLUA](https://github.com/jangko/nimLUA)
  * [util\nc_util.nim in nimCEF](https://github.com/jangko/nimCEF)




Re: Defined Symbol Value Error

2018-09-28 Thread jangko
you can use 


when defined(CTS): # if the CTS value is "true" or "false"
   ...


Run

or


const CTS {.strdefine.} = "default_value"
when CTS=="yes":
   ...


Run

currently there is nothing like `when getValue(CTS) == "xxx"` and conditional 
symbols are not 'normal symbols'


Re: calculated import argument

2018-09-27 Thread jangko
shorter version


const apple {.strdefine.} = "default_value"
template toImport(x: static[string]): untyped = import x

toImport(apple & "tools")


Run


Re: calculated import argument

2018-09-27 Thread jangko

import macros

const apple {.strdefine.} = "default_value"
macro toImport(x: static[string]): untyped = quote do: import `x`

toImport(apple & "tools")


Run


nim c -d:apple=new_value myproject


Run


Re: Interop with Delphi Interfaces

2018-09-27 Thread jangko
result = cast[ptr ITestIntf](intf) probably what you want is result = cast[ptr 
ITestIntf](intf.addr).

use addr operator to get the address of a variable.

returning something on the stack is very dangerous, the time you exit/returned 
from the proc, the object on the stack may be already replaced by something 
else or already gone.

maybe you should put in on global space


Re: 0.19.0 pegs regression?

2018-09-27 Thread jangko
yeah, this is a regression. this bug already reported on github


Re: Nim source equivalent to C #define

2018-09-26 Thread jangko
Actually Nim has {.define: identifier.} pragma, but then it was deprecated. I'm 
curious to know what was the reason. Doesn't it behave similarly with '-d:' or 
'\--define:'? 


Re: Error converting json to types

2018-08-06 Thread jangko
This is a bug in **json.to** macro. It cannot handle type aliases properly


Re: Generated assembly for imported modules on MSP430

2018-05-04 Thread jangko
> The functions that are being called are referenced by the call so the linker 
> can't remove them

see issue [#6134](https://github.com/nim-lang/Nim/issues/6134)


Re: volatileStore ptr T question

2018-05-04 Thread jangko
while it tedious, the compiler expect you to know what you are doing when you 
mix different size of datatype, or when you use different datatype in an 
operation.

consider this C code: 


int a = 10;
int b = 3;
float c = a / b;  /* compiler will allow this but beware that c = 3 and not 
3. */
float d = (float) a / b; /* this time c = 3. while perform hidden 
conversion on b */


now in Nim: 


var a = 10, b = 3
var c = a.float / b.float  # no hidden conversion, you should know what you 
are doing
# equals to c = `/`(a.float, b.float) because an operator is alias to 
function call


I found this explicit conversion annoying when I write the code, but at the 
same time, it force me to rethink the code I write, can I use less conversion 
an thus make the code run faster?

Hidden conversion _could_ potentially hide bugs and cost performance too.

When reviewing other people's code or maintaining my own code, explicit 
conversion help me to think more clearly.

btw, you could rewrite your template like this:


template volatileStore[T](dest: ptr T; val: SomeInteger) =
  var dest[] = T(val) # do the conversion here, and get the convenience 
when using this template



Re: What is the typedesc inside the compiler?

2018-04-24 Thread jangko
sorry, I misunderstood your question.

> Why the t1, t2 cannot be treated as correct typedesc, they all Sym "User" 
> just like nT.


echo repr nT.getType() # typeDesc[User]
echo repr t1.getType() # object
echo repr t2.getType() # object


I don't know if this just some inconsistencies or qualified as a bug


Re: What is the typedesc inside the compiler?

2018-04-24 Thread jangko
when you cross macro boundary, not only typedesc transformed into NimNode, 
practically all args passed to macros will be transformed into NimNode, no 
matter it is an int, string, int literal, string literal, or a block of 
code/statements, all will be transformed into NimNode with specific kind.


macro mymacro(x: int): untyped =
  echo x # perhaps failed to compile, x is not an int anymore, it is a 
NimNode of int literal


the same is also happened with T: typedesc, inside a macro, T is not a typedesc 
anymore, it is a NimNode of symbol. When you call template create(x: int, T: 
typedesc): untyped = T(age: x), it will not works because the template create 
expecting a T and constrained the type to typedesc not NimNode. while template 
create(x: int, T: untyped): untyped = T(age: x) will accept T wihout any 
specific type.

when you have more than one macro with the same name, and they don't have 
varargs or untyped parameters, they can participate in macro overloading


macro mymacro(T: typedesc): untyped
macro mymacro(T: int): untyped
macro mymacro(T: string): untyped
etc



Re: How to get string representation of int inside of the macros?

2018-04-02 Thread jangko
or you can use intVal, strVal, etc on literal nodes


import macros

macro initNui(a:int): typed =
  result = parseStmt("const b=" & $a.intVal)

initNui(1)



Re: a proc returning void creates 1 arg, not 0: breaking generic code

2018-03-29 Thread jangko
> Maybe I'm missing some valid use case I haven't thought about?

Nim macros cannot be directly compared to D templates/generics. You can use Nim 
macros to implement DSL, such as assembler, JIT engine, shader language, etc:


macro my_asm_engine(n: varargs[untyped]): typed =
  bla bla bla


my_asm_engine:
  mov eax, ebx
  xor eax, eax
  whatever


if Nim macros choose to ignore void returning function call, it would be 
unusable to implement DSL at all. 


Re: How to return Unicode in shared library

2018-03-29 Thread jangko
if your unicode string is encoded in UTF8 and your C shared library also accept 
UTF8 encoded, then it is safe to export nim string to cstring. the Nim compiler 
will automatically handle the conversion. actually, no conversion take place, 
only pointer passing.

if it is not UTF8 encoded, or the C library cannot accept UTF8, you can do some 
conversion and pass the pointer of your unicode string to C.


#assume both of this function deals with UTF8 encoded string
proc get_c_unicode(): cstring {.importc: bla bla bla.}
proc put_c_unicode(x: cstring): cint {.importc: bla bla bla.}


var nim_unicode_string = $get_c_unicode()

#do something with unicode module

if put_c_unicode(nim_unicode_string) != 0.cint:
  echo "ok"



as simple as that, if both party agree to use UTF8

unicode codepoints it self it not too hard to program, but rendering and 
formatting the unicode font/typeface, that is the real nightmare.


Re: How to return Unicode in shared library

2018-03-28 Thread jangko
the easiest one is using $ operator to convert cstring to Nim string, assuming 
it is null terminated. then the resulted string can be iterated using Nim 
unicode module, assuming it is encoded in UTF8.

if it is not encoded in UTF8, you need to find another suitable library, or 
write it yourself, it's not that too hard if only dealing with UTF16 - UTF8 - 
UTF32 conversion.


Re: C's char* -> ptr char or cstring ?

2018-01-19 Thread jangko
as the name implies, alloc0 zeroed the chunk of memory requested, while alloc 
return raw memory block. when you free the memory, Nim internal allocator might 
reuse it at the next alloc call, if it thinks the previous block allocated 
could be reuse, hence the garbage.

if you think there is no need to do new allocation, you can keep the pointer 
around and reuse it, and call zeroMem if needed.

isn't this scenario a common practice when using C language?(I really have no 
idea about your C skills)

if you think alloc0 is slow because of the zeroMem overhead, you can put the 
zero terminator manually if you know the incoming packet length. (again, this 
is so common in C, no offense  )

also I noticed that in line 67: if nread == 0: return, you don't free the 
buffer, doesn't it will leak? 


Re: C's char* -> ptr char or cstring ?

2018-01-19 Thread jangko
if you use C backend, ptr char basically equals to cstring

> I call alloc () and then cast it to ptr char, is this wrong?

it's ok, as long as you don't forget to call free()

or you can do something like this:


var x = newString(someLen)
call_some_c_func(x.cstring)
# and the gc will free the x for you



Re: Having trouble wrapping foo->bar

2018-01-08 Thread jangko
the complete struct of GPU_Image is this:


typedef struct GPU_Image
{
struct GPU_Renderer* renderer;
GPU_Target* context_target;
GPU_Target* target;
Uint16 w, h;
GPU_bool using_virtual_resolution;
GPU_FormatEnum format;
int num_layers;
int bytes_per_pixel;
Uint16 base_w, base_h;
Uint16 texture_w, texture_h;
GPU_bool has_mipmaps;

float anchor_x;
float anchor_y;

SDL_Color color;
GPU_bool use_blending;
GPU_BlendMode blend_mode;
GPU_FilterEnum filter_mode;
GPU_SnapEnum snap_mode;
GPU_WrapEnum wrap_mode_x;
GPU_WrapEnum wrap_mode_y;

void* data;
int refcount;
GPU_bool is_alias;
} GPU_Image;


it is true you don't have to write all of them in Nim if you only need to 
access the width and height, but you also cannot ignore fields that came before 
width and height.

this is minimal fields you need to write in Nim if you only need to access the 
width and height:


type
  image* = object
renderer: pointer
context_target: pointer
target: pointer
w*, h*: uint16
  ptrImage* = ptr image


Nim's object has strong relationship with C struct, so it works like C struct, 
not like javascript or python object


Re: Understanding staticRead's weird behaviour

2017-12-20 Thread jangko
Dom96's answer no.1 is correct

> 1\. Maybe --force flag will affect this?

How can this be?, if Nim compiler detect that your .nim(on disk) not modified, 
and there is already .c/.o for the .nim in /nimcache, Nim compiler will skip 
codegen for the .c/.o file(if the dependencies/imports also not changed). Using 
staticRead(x) indeed change .nim file(in memory) if you change/update the 'x', 
but the compiler will not know about this(the compiler hash the file on disk, 
not the AST in memory).

That's why, it looks cached somehow. Perhaps you can request a new feature for 
Nim compiler to hash the 'x' too as a dependency.

No.3 Compile time FFI

if I am not mistaken, araq has a branch of Nim implementing compile time FFI, 
but then abandoned/postponed because it would be a nightmare for maintainer to 
deal with upcoming issues related to compile time FFI while the Nim compiler 
itself already had many issues. But I believe, in the future we can revive this 
idea. It will be cool although a bit nasty.


Re: bad code generated when trying to access static: var at run time

2017-11-14 Thread jangko
currently there is no simple way to make compile-time var to exist at run-time.

some attempt has been taken place to enhance the compiler capability by 
enabling _all_ compile-time var exist at run-time. But that solution is not 
optimal, because not everyone want _all_ compile-time var also exist at 
run-time.

The idea to introduce new pragma to annotate compile-time var was rejected by 
araq. He said, the compiler must be smart enough to identify which compile-time 
var need to exist at run-time without introducing new pragma.

therefore, we need to make the compiler smarter. the compiler should be able to 
know which compile-time var accessed at both compile-time and run-time, and 
which one is accessed only at compile-time. the compiler then generate run-time 
code for the former and generate nothing for the latter.


Re: Confusion with Generics and nim typesystem.

2017-11-10 Thread jangko
this is another generics typerel bug that should be reported.


Re: templates with generics question

2017-10-31 Thread jangko
you can always inspect the generated C code to see what are the differences 
between them.

One thing I spotted which could be a potential hidden bug is data.unsafeAddr. 
When the data is an ordinary array, it would be ok. But when it is a seq, crash 
is almost guaranteed.

safer way to write it would be data[0].unsafeAddr, safe for array and seq


Re: possible compiler bug with generics?

2017-10-28 Thread jangko
@wizzardx is correct, this is normal Nim behaviour.

Nim generic proc is instantiated at _callsite_. The above example, Bar is 
instantiated at bug.nim not at lib.nim, and at that time, the scope where the 
Bar is instantiated have no information about Foo symbol.


Re: Convert tuple into a Object

2017-09-06 Thread jangko
@Udiknedormin: you can use bleeding edge devel branch(0.17.1) on github to test 
this newly fixed object contruction syntax. or wait until next version released 


Re: Allocation on heap somehow unstable - Why does this crash?

2017-07-19 Thread jangko
that is a [known bug](https://github.com/nim-lang/Nim/issues/5143)


Re: Allocation on heap somehow unstable - Why does this crash?

2017-07-19 Thread jangko
>From [Nim Compiler user 
>guide](https://nim-lang.org/docs/nimc.html#dll-generation):


Nim supports the generation of DLLs. However, there must be only one 
instance of the GC per process/address
space. This instance is contained in nimrtl.dll. This means that every 
generated Nim DLL depends on
nimrtl.dll.


To generate the "nimrtl.dll" file, goto Nim/lib directory and use the command: 


nim c -d:release nimrtl.nim


then compile your project with: 


nim --app:lib -d:useNimRtl c lib
nim c -d:useNimRtl main


nimRtl not used if there is only single instance of GC, such as C app + Nim 
DLL, or Nim app + C dll. nimRtl used in situation like Nim app + Nim DLL, or C 
app + multiple Nim DLL


Re: Converting Nim string to c void*

2017-07-14 Thread jangko
variations to convert C pointer to Nim string, and perhaps faster too:


proc fromCString(p: pointer, len: int): string =
  result = newString(len)
  for i in 0.. 

Re: Converting Nim string to c void*

2017-07-13 Thread jangko
say you have a C function: 


void store(void* data);


then you can using Nim ffi like this:


proc store(data: pointer) {.importc, dynlib: "shared lib name".}


or pretend that the argument is a cstring


proc store(data: cstring) {.importc, dynlib: "shared lib name".}


how to use the first one? 


var mydata = "something"
store(mydata[0].addr) #get the underlying char* address

#or
store(mydata.cstring) # implicit cast from char* to void*

#or
store(cast[pointer](mydata.cstring)) #unnecessary, but ok too


how to use the second one? 


var mydata = "something"
store(mydata) #use Nim's automatic conversion from string to cstring

#or
store(mydata.cstring) #unnecessary, but it's ok too.



Re: Concepts

2017-06-20 Thread jangko
imagine we have an ordinary generic proc:


proc genericProc[T](a: T): T =
  discard


and this generic proc might be instantiated with different types.

If we want to get the proc's address, we need to tell the compiler which one of 
those proc instances using generic specialization:


var s = [genericProc[int]]  #get the genericProc's address with `int` 
instance and put it into array


proc definition contains concept is another form of generic proc. If we want to 
get the proc's address, there should be a mechanism to disambiguate which 
instance that we need. But unfortunately, looks like there is nothing like 
concept specialization.

the first issue: 


var x = [proc_with_concept_address]


need some addition in the language specification describing concept 
specialization.

the second issue: 


var y = [some_concept]


perhaps this can be realized if the compiler put some restriction or constraint 
on the types involved.

both issues need to be reported to nim's bugs tracker, perhaps someone 
interested to fix it in the future. 


Re: Nim's Easy Serialization Macro - new version available

2017-05-22 Thread jangko
@cdunn2001, looks like you already know the difference between msgpack and 
NESM. But I will give add some information.

msgpack is a well defined protocol, the spec dictates you how to serialize 
number, the endianess, how many bytes should be used, etc, etc. An msgpack 
library author need to make sure, the output of the library is following the 
standard, therefore other(s) msgpack can also read the output.

msgpack4nim do allow little freedom, as long as the output conform to the 
standard.

In other hand, NESM not bounded by any standard, it offers greater freedom.


Re: Nim's Easy Serialization Macro - new version available

2017-05-10 Thread jangko
> (for example, doesn't have a field of type Socket/File/stream/callbacks)

in this case, user intervention is needed, but using non-intrusive serializer, 
the intervention is minimal.

And the code to manage this special case can be put among the other serializer 
routines, no need to modify the serialized library.


Re: Nim's Easy Serialization Macro - new version available

2017-05-09 Thread jangko
looks like this is a kind of intrusive serializer. I usually avoid using 
intrusive serializer and prefer non-intrusive one. But I believe your library 
can be modified to support non-intrusive mode too, because you already using 
macros, and Nim macros can easily handle non-intrusive serializer.

why I prefer non-intrusive serializer?

Imagine I already using a huge library with tons of objects. Then one day I 
decide that I need to serialize those objects, it would be painful if the 
serializer only in intrusive mode because I have to annotate each of the 
objects. But if the serializer also support non-intrusive mode, I don't need to 
modify my huge library. I just need to serialize it and done.

anyway, what you have done is awesome. 


Re: Problem with the generic of sequence.

2017-03-26 Thread jangko
This is a known compiler bug. Let's hope it will be fixed soon


Re: 2 question about DLL with Mingw

2017-01-23 Thread jangko
  1. proc double(x: cint): cint {.cdecl, dynlib: "foo.dll", importc:"_double".}
  2. use compiler switch --nomain




Re: Strange compiler bug when import critibits and nre

2016-11-16 Thread jangko
see [#4996](https://github.com/nim-lang/Nim/issues/4996)


Re: c2nim: typdef

2016-10-10 Thread jangko
Please be patient with me. This may sound crazy, but this little experiment 
will tell us some --perhaps inconsistencies in C language.


typedef int xxx(int yyy);

xxx abc;

int main() {
  abc(0);
  return 0;
}


altough abc looks like a variable declaration, both gcc and vcc says it is a 
function declaration. here is the output of gcc and vcc:


gcc:
C:\Users\Jangko\AppData\Local\Temp\ccJu7Cm2.o:abc.c:(.text+0x13): undefined 
reference to `abc'
collect2.exe: error: ld returned 1 exit status

vcc:
abc.obj : error LNK2019: unresolved external symbol _abc referenced in 
function _main
abc.exe : fatal error LNK1120: 1 unresolved externals


if we change the C code a little bit with additional *:


typedef int xxx(int yyy);

xxx* abc;

int main() {
  abc(0);
  return 0;
}


both gcc and vcc will silent, because they accept abc as a variable 
declaration. of course, if you run the produced executables, it will crash.

now xxx will be used as argument type.


#include 

typedef int xxx(int yyy);

int pineapple(int yyy) {
  return yyy + 13;
}

void apple(xxx n) {
  printf("%d\n", n(1));
}

void banana(xxx* n) {
  printf("%d\n", n(2));
}

int main() {
  apple(pineapple);
  banana(pineapple);
  return 0;
}


again both vcc and gcc agree that n with type xxx or xxx* is equivalent, but 
looks inconsistent with the first abc.

from this little experiment, I think altough c2nim translation looks correct, 
but gcc and vcc don't agree that xxx abc; is a variable declaration.

In case of banana argument syntax, c2nim will produce proc banana*(n: ptr xxx). 
But how this proc can be usable? something like banana(pineapple), 
banana(pineapple.addr), or banana(pineapple.unsafeaddr) will be rejected by Nim 
compiler.

if we use something like: 


var f: xxx = pineapple
banana(xxx.addr)


this is accepted by the compiler, but totally wrong if banana is imported from 
C.

Personally, i never encountered C library written like this, perhaps it is safe 
to assume very little chance for c2nim to encounter such code, but at least 
c2nim should warn the user if it does see code like this or we should document 
this peculiar C behaviour in c2nim documentation.


Re: c2nim: typdef

2016-10-07 Thread jangko
The c2nim translation posted by jlp765 is correct. But i found something wrong 
when c2nim try to translate the _usage_ of the typedefed type. Sorry not to 
mention them earlier.


typedef int xxx(int yyy);

xxx abc;

void zzz(xxx* f);
void www(xxx f);


zzz and www should produce the same result because they are equivalent. abc 
should be function declaration, but see how c2nim translate them:


type
  xxx* = proc (yyy: cint): cint

var abc*: xxx  #wrong, should be proc abc(yyy: int): cint

proc zzz*(f: ptr xxx) #wrong
proc www*(f: xxx)


imagine if this is used to importc something, crash will it be


Re: c2nim: typdef

2016-10-06 Thread jangko
no, the c2nim translation is correct for pfv2 and pxfv2.


Re: What does "direct hardware access" in Nim mean?

2016-09-17 Thread jangko
I don't think modern OSes will allow any user space application to access any 
hardware directly. Any hardware access must be performed through system 
calls(low level e.g. asm), which often encapsulated into function calls(higher 
level).

But beside normal user space application, Nim can produce kernel space program 
or device driver that can access hardware directly.

Nim also can produce a program that will be put in an embedded system. In such 
environment, usually there is no OS or only primitive OS, and Nim produced 
program have higher chances to access hardware direcly.


Re: Libraries

2016-09-15 Thread jangko
> Nim could be used to build static/shared libraries?

yes. You can use compiler switch \--app:lib (shared lib) or \--app:staticLib

> I'm supposed that the GC should be turned off

yes/no. You can keep Nim's GC around in a static lib but don't forget to call 
NimMain() to initialize the GC. 


Re: C invocation example does not work in 32bit

2016-09-07 Thread jangko
depends on your C compiler configuration, most of the times you need to specify 
the calling convention explicitly, for example: stdcall for msvc or cdecl for 
gcc

in your case, try add cdecl:


proc addTwoIntegers(a, b: cint): cint {.importc,cdecl.}



Re: Can i use 64bit nim compile 32bit program?

2016-09-06 Thread jangko
use compiler switch \--cpu:i386

for example: 


nim c --cpu:i386 test.nim



Re: Debugging the compiler

2016-08-23 Thread jangko
very good job indeed, we need more tools like this to speed up development not 
only for nim compiler, any other projects could also benefits.

I will try it soon.

I imagine tools like this can be extended to generate/mapping function calls 
into program flow(visual flowchart, mindmap, graph or something like that) -- 
that can be very useful to analyze a piece of code from many different angles.


Re: Cross-import error or am I doing it wrong?

2016-08-08 Thread jangko
currently Nim does not support circular import


Re: How to obtain parameters and their types of akProc?

2016-08-08 Thread jangko
try this:


import macros

... # your code here

macro test(n: typed): untyped =
  let x = getImpl(n.symbol)
  echo x.treeRepr
  ... # do whatever you like with the x

test(testProc)



Re: Go-lang like interface

2016-07-30 Thread jangko
surprisingly, this Go like interface is very similar with what I have 
implemented when creating high level wrapper for Chromium Embedded Framework in 
[nimCEF](https://github.com/jangko/nimCEF).

in my experience, Nim macro not only capable simulate Go like interface, but 
also interface + simulated inheritance. Indeed Nim's macro can make Nim a very 
powerful language.


Re: Calling Nim compiled to dll from Java programs?

2016-07-21 Thread jangko
Now I can reproduce the error too. Very interesting, this code below works, 
maybe someone else can explain this phenomenon


cap.add("test")
var tmp = cap
env[].ReleaseStringUTFChars(env, input, str)
result = env[].NewStringUTF(env, tmp)



Re: Why Nim language unlike rust and go language, the same direct compiler

2016-07-21 Thread jangko
**gcc** actually produces assembly code and assembles it using the **as** 
assembler. And nobody complains gcc borrow an assembler. and the assembler also 
produce object file which is linked by linker to produce executable. I don't 
see the point why Nim need to become something like rust and go. And don't 
forget there exist gccgo, gcc front end for go-lang.


Re: Calling Nim compiled to dll from Java programs?

2016-07-21 Thread jangko
I didn't encounter the problem you've mentioned. I also increase the upper 
limit of for loop to 100.000 and everything still fine. I manipulate the cap 
variable here and there and still ok. What exactly you've done?


Re: Calling Nim compiled to dll from Java programs?

2016-07-20 Thread jangko
You can get the source code 
[here](https://gist.github.com/jangko/48ba0b76716d0631560e5f2ff470256d). There 
are 5 files.

how to build sample code:


javac Sample1.java

javah -classpath . Sample1

nim c --app:lib --passL:"-static-libgcc" --passL:"-Wl,--kill-at" Sample1


You can omit -static-libgcc part, but you must use "-Wl,--kill-at" to remove 
'@' from exported symbol name.

don't forget to include jni_export in all your project files that uses 
jni.nim(don't import it, use include)

and finally, run the java vm:


java Sample1


beware: if there exist more than one dll plugin written in Nim, please use 
compiler switch "-d:useNimRtl", (I never tested it before, but the 
documentation says like that)