Compiling Aporia for GTK3 with Nim 0.10.2
In aporia.nim from github we have
proc CommentLines_Activate(menuitem: PMenuItem, user_data: pointer) =
template cb(): expr = win.tabs[currentPage].buffer
var currentPage = win.sourceViewTabs.getCurrentPage()
var start, theEnd: TTextIter
proc toggleSingle() =
#cb.beginUserAction()
win.tabs[currentPage].buffer.beginUserAction()
# start and end are the same line no.
# get the whole
var line = cb.getText(addr(start), addr(theEnd),
false)
if not (addr theEnd).ends_line:
aporia.nim(1066, 15) Error: type mismatch: got (seq[Tab], proc (Notebook): gint{.cdecl.} | proc (Assistant): gint{.cdecl.} | proc (PrintUnixDialog): gint{.cdecl.}) but expected one of: system.[](a: array[Idx, T], x: Slice[int]): seq[T] system.[](s: seq[T], x: Slice[int]): seq[T] system.[](s: string, x: Slice[int]): string system.[](a: array[Idx, T], x: Slice[Idx]): seq[T] tables.[](t: TableRef[A, B], key: A): B tables.[](t: Table[A, B], key: A): B tables.[](t: CountTableRef[A], key: A): int tables.[](t: CountTable[A], key: A): int tables.[](t: OrderedTable[A, B], key: A): B tables.[](t: OrderedTableRef[A, B], key: A): B
So the compiler does not like the cb() template, but its works when I replace the template by the verbatin code. Do I need latest 0.10.3 compiler?
This seems to be indeed a strange bug -- maybe I should install 0.10.3
My impression is, that the compiler inserts in the template for symbol "currentPage" not a plain int value, what would be correct, but something like a proc? Providing a minimal example for bug tracker would be some effort, so I will wait until I tested with 0.10.3.
[Edit]
And an easy fix is to put the template after "var currentPage ="
proc CommentLines_Activate(menuitem: PMenuItem, user_data: pointer) =
#template cb(): expr = win.tabs[currentPage].buffer
var currentPage = win.sourceViewTabs.getCurrentPage()
template cb(): expr = win.tabs[currentPage].buffer
var start, theEnd: TTextIter
proc toggleSingle() =
cb.beginUserAction()
Hello Araq,
finally I have found the reason for this bug: In gtk3.nim there exists procs named currentPage -- same name as the used var. Below is an example without direct relation to my wrappers but with a very similar problem. I guess it will be not easy for me to avoid such conflicts and to find the reason fast...
type
Buffer* = ptr BufferObj
BufferObj*{.final.} = object
type
Boffer* = ptr BofferObj
BofferObj*{.final.} = object
proc currentPage(b: Boffer):int =
0
proc getCurrentPage(b: Boffer):int =
0
proc bginUserAction(b: Buffer)=
echo ""
type
Tab* = ref object
buffer*: Buffer # salewski
MainWin* = object
sourceViewTabs*: Boffer
tabs*: seq[Tab]
var win: MainWin
proc CommentLines_Activate() =
template cb(): expr = win.tabs[currentPage].buffer
var currentPage = win.sourceViewTabs.getCurrentPage()
#template cb(): expr = win.tabs[currentPage].buffer
proc toggleSingle() =
cb.bginUserAction()
test.nim(34, 4) Error: type mismatch: got (seq[Tab], proc (Boffer): int{.gcsafe, locks: 0.})
but expected one of:
system.[](a: array[Idx, T], x: Slice[[].Idx]): seq[T]
system.[](a: array[Idx, T], x: Slice[system.int]): seq[T]
system.[](s: string, x: Slice[system.int]): string
system.[](s: seq[T], x: Slice[system.int]): seq[T]
And some more problems...
Last week I got aporia to compile with my gtk3 after some strange hacks in gtk3.nim. Now I was cleaning up that, but the cleaned code does not compile. It took me two hours to find that order of three templates made the difference:
template gtk_type_file_chooser*(): expr =
(file_chooser_get_type())
template gtk_file_chooser*(obj: expr): expr =
(g_type_check_instance_cast(obj, gtk_type_file_chooser, FileChooserObj))
template gtk_is_file_chooser*(obj: expr): expr =
(g_type_check_instance_type(obj, gtk_type_file_chooser))
For this order I get
dialogs.nim(107, 32) Error: type mismatch: got (GTypeInstance, proc (): expr)
but expected one of:
gobject.g_type_check_instance_cast(instance: expr, g_type: expr, c_type: expr): expr
gobject.g_type_check_instance_cast(instance: GTypeInstance, iface_type: GType): GTypeInstance
But when I put the first template to the bottom, I do not get this error.
proc file_chooser_get_type*(): GType {.
importc: "gtk_file_chooser_get_type", libgtk.}
So the order decides if I get a proc type or the result of the proc call? (I need the result of the proc call, the GType, to make the c2nim generated wrapper code to work. Of course I may insert () manually to get the proc result.) Can I fix that with the dirty pragma also? Already tried, but was not sure about notation. And of course dirty sounds not really nice.
This is how hygenic templates work.
I still hope that someone can give some more explanations. I read the chapter about hygenic templates in the manual, but it seems that I have not really understood. And I already tried some simple examples, but they showed not the behaviour of the code above.
Of course I am trying to find good solutions for all the GTK casting macros. It is related to
http://forum.nim-lang.org/t/812
output of c2nim which does not compile, still with latest c2nim. To make the GTK macros work all together fine, I have at least three solutions: Dirty pragma, reorder templates, or append empty brackets () to template or proc call to get the GType value instead of proc value. Have no idea which is the best solution. Dirty pragma seems to be the easiest one, will try it next.
[EDIT]
I think I will use proc consts again, as I had some weeks ago already. I have only to make a script which appends () everywhere where the proc const appears in other templates, so that it is a value, not a proc type...
proc a(i: int): int =
0
proc b(i: int): int =
1
template B(): expr =
b(A)
template A(x: expr): expr =
a(0)
echo 1 + B
Indeed. When I exchange the order of templates A and B, I get two different error messages
t.nim(14, 9) Error: wrong number of arguments or t.nim(13, 10) Error: type mismatch: got (proc (expr): expr) but expected one of: t.b(i: int): int
There is a fine explanation of hygeinic_macros at Wikipedia http://en.wikipedia.org/wiki/Hygeinic_macro
Will continue thinking about that later...
And something different...
Seems that for unsigned ints there is no hash proc defined, so that tables.nim works not out of the box for unsigned. No problem. So I looked at hashes.nim to see how one may define one. Scrolling down
proc hash*(x: float): THash {.inline.} =
var y = x + 1.0
result = cast[ptr THash](addr(y))[]
No idea what that is. For me addr(y) should be independent from the value of x.
Stefan_Salewski: No idea what that is.
It adds 1.0 to x, then takes the first word of the float representation as an integer (which is the entire float for single precision floats, and sign + exponent + the beginning of the mantissa for double precision floats). Note the [] at the end, which dereferences the pointer.
Note the [] at the end, which dereferences the pointer.
Oh, I missed that. Thanks.
type
B = set[0..7]
var i: B
i = {}
incl(i, 1)
echo 0 in i
i = {1}
i = {0..3, 7}
I have no idea what is wrong with the last two assignments -- guess in Modula and Oberon that was OK?
Stefan_Salewski: I have no idea what is wrong with the last two assignments
The constants inside set literals need to be of the proper ordinal type (it's sufficient for the first literal in the set to be of that type, the rest will be inferred).
E.g.:
type
R = 0..7
B = set[R]
var i: B
i = {}
incl(i, 1)
echo 0 in i
i = {R(1)}
i = {R(0)..3, 7}
Thanks.
What is also strange is, that this compiles file:
type
B = set['a'..'d']
var i: B
i = {}
i = {'a', 'd'..'f'}