valid pragma syntax

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

valid pragma syntax

Nicolai Hess-3-2
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>


nicolai


Reply | Threaded
Open this post in threaded view
|

Re: valid pragma syntax

marcel.taeumel
Hi Nicolai,

I thought that pragmas are pretty much like message selectors?

<keyword: arg1 another: arg2 yetAnother: arg3>
<unary>

Arguments can be literals only.

At least, this is my (mental) model of pragmas. :-) I like it. It is simple.

Best,
Marcel
Reply | Threaded
Open this post in threaded view
|

Re: valid pragma syntax

Levente Uzonyi
In reply to this post by Nicolai Hess-3-2

On Sun, 10 Jan 2016, Nicolai Hess wrote:

> pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
>
>
> is this valid pragma syntax:
>
>     <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

This is not a pragma, but the special syntax used by FFI. AFAIK it
predates pragmas.

>
> our (pharo) parser can not parse this (does not recognizes the
> "selector parts" (apicall:module:) right)
>
> Any recommendations how to fix this
> - fix RBParser or
> - change this pragma, for example, like this
>   <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>

There's nothing to fix here. Either you change your parser, compiler and
decompiler to support this syntax, but knowing how things work in Pharo,
this is not an option, or change the methods with these callouts,
introducing another incompatibility between Pharo and the rest, to use
pragmas and create a custom parser, compiler and decompiler to be able to
compile FFI callouts into methods when such pragmas are present.

Levente

>
>
> nicolai
>
>

Reply | Threaded
Open this post in threaded view
|

Re: valid pragma syntax

Nicolai Hess-3-2


2016-01-10 13:14 GMT+01:00 Levente Uzonyi <[hidden email]>:

On Sun, 10 Jan 2016, Nicolai Hess wrote:

pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

This is not a pragma, but the special syntax used by FFI. AFAIK it predates pragmas.

Ah, ok.
 


our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>

There's nothing to fix here. Either you change your parser, compiler and decompiler to support this syntax, but knowing how things work in Pharo, this is not an option

Why is this not an option?

 
, or change the methods with these callouts, introducing another incompatibility between Pharo and the rest, to use pragmas and create a custom parser, compiler and decompiler to be able to compile FFI callouts into methods when such pragmas are present.

As we now included this FFI-Examples, where this is used, I would like to find a way that works in both, pharo and squeak.

@esteban
is this already supported by "our" FFI and just not by the parser used for syntax highlighting or wasn't this package supposed to be in Pharo ?

 

Levente



nicolai







Reply | Threaded
Open this post in threaded view
|

Re: valid pragma syntax

Levente Uzonyi
On Sun, 10 Jan 2016, Nicolai Hess wrote:

>
>
> 2016-01-10 13:14 GMT+01:00 Levente Uzonyi <[hidden email]>:
>
>       On Sun, 10 Jan 2016, Nicolai Hess wrote:
>
>             pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
>
>
>             is this valid pragma syntax:
>
>                 <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>
>
>
>       This is not a pragma, but the special syntax used by FFI. AFAIK it predates pragmas.
>
>
> Ah, ok.
>  
>
>
>             our (pharo) parser can not parse this (does not recognizes the
>             "selector parts" (apicall:module:) right)
>
>             Any recommendations how to fix this
>             - fix RBParser or
>             - change this pragma, for example, like this
>               <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>
>
>
>       There's nothing to fix here. Either you change your parser, compiler and decompiler to support this syntax, but knowing how things work in Pharo, this is not an option
>
>
> Why is this not an option?
It was a goal to get rid of this syntax[1].

Levente

[1] https://lists.gforge.inria.fr/pipermail/pharo-project/2010-February/022534.html

>
>  
>       , or change the methods with these callouts, introducing another incompatibility between Pharo and the rest, to use pragmas and create a custom parser, compiler and decompiler to be able to compile FFI callouts into methods when such pragmas are present.
>
>
> As we now included this FFI-Examples, where this is used, I would like to find a way that works in both, pharo and squeak.
>
> @esteban
> is this already supported by "our" FFI and just not by the parser used for syntax highlighting or wasn't this package supposed to be in Pharo ?
>
>  
>
>       Levente
>
>
>
>             nicolai
>
>
>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: valid pragma syntax

Eliot Miranda-2
In reply to this post by Nicolai Hess-3-2
Hi Nicolai,

On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <[hidden email]> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

As others have said this is not a valid pragma.  A valid pragma is a message expression (a message with no receiver) that has only literal arguments.  There is one exception, to accept a variable name for the error code in a primitive invocation.

And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.

And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference).  So for example, the heapsort declaration from the standard C library:

int
     heapsort(void *base, size_t nel, size_t width,
         int (*compar)(const void *, const void *)) 

could be written as a pragma via e.g.

    <ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>

in which case it is equal to

   <ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>

which, while a massive hack, is pretty neat.  The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.

So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String).  I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.

This would easily allow extensions such as

     <ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>

to guide a marshalling engine in providing automatic checks and conversions.

[Slightly OT]
Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails).  So a Callback for heapsort above looks like

voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #IA32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

or
voidstarvoidstarRetintARM32: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #ARM32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))


Hmmm, if Callback had subclasses for each ABI then the above would become

IA32Callback methods for signature
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

ARM32Callback methods for signatures
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))

Much nicer.  I shall make it so.

our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>


nicolai

_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] Re: [squeak-dev] valid pragma syntax

Nicolai Hess-3-2


2016-01-10 16:57 GMT+01:00 Eliot Miranda <[hidden email]>:
 
Hi Nicolai,

On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <[hidden email]> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

As others have said this is not a valid pragma.  A valid pragma is a message expression (a message with no receiver) that has only literal arguments.  There is one exception, to accept a variable name for the error code in a primitive invocation.

And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.


Thanks Eliot.

I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax



And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference).  So for example, the heapsort declaration from the standard C library:

int
     heapsort(void *base, size_t nel, size_t width,
         int (*compar)(const void *, const void *)) 

could be written as a pragma via e.g.

    <ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>

in which case it is equal to

   <ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>

which, while a massive hack, is pretty neat.  The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.

So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String).  I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.

This would easily allow extensions such as

     <ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>

to guide a marshalling engine in providing automatic checks and conversions.

[Slightly OT]
Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails).  So a Callback for heapsort above looks like

voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #IA32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

or
voidstarvoidstarRetintARM32: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #ARM32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))


Hmmm, if Callback had subclasses for each ABI then the above would become

IA32Callback methods for signature
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

ARM32Callback methods for signatures
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))

Much nicer.  I shall make it so.

our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>


nicolai

_,,,^..^,,,_
best, Eliot




Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] [squeak-dev] valid pragma syntax

EstebanLM
well… UnifiedFFI, UFFI or whatever it will be called already does that… as you know.
Currently we are using “older” NB way: as a method call, then solving it in first call. This is nice because is compatible and easies some stuff. 
But final objective is to provide a pragma and solve it in compilation time. 

Then we can 100% deprecate the invalid pragma old FFI uses today. 

At least, that’s what we have talk :)

Esteban

On 12 Jan 2016, at 20:06, Nicolai Hess <[hidden email]> wrote:



2016-01-10 16:57 GMT+01:00 Eliot Miranda <[hidden email]>:
 
Hi Nicolai,

On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <[hidden email]> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

As others have said this is not a valid pragma.  A valid pragma is a message expression (a message with no receiver) that has only literal arguments.  There is one exception, to accept a variable name for the error code in a primitive invocation.

And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.


Thanks Eliot.

I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax



And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference).  So for example, the heapsort declaration from the standard C library:

int
     heapsort(void *base, size_t nel, size_t width,
         int (*compar)(const void *, const void *)) 

could be written as a pragma via e.g.

    <ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>

in which case it is equal to

   <ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>

which, while a massive hack, is pretty neat.  The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.

So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String).  I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.

This would easily allow extensions such as

     <ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>

to guide a marshalling engine in providing automatic checks and conversions.

[Slightly OT]
Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails).  So a Callback for heapsort above looks like

voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #IA32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

or
voidstarvoidstarRetintARM32: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #ARM32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))


Hmmm, if Callback had subclasses for each ABI then the above would become

IA32Callback methods for signature
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

ARM32Callback methods for signatures
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))

Much nicer.  I shall make it so.

our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>


nicolai

_,,,^..^,,,_
best, Eliot





Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] [squeak-dev] valid pragma syntax

Nicolai Hess-3-2


2016-01-12 20:57 GMT+01:00 Esteban Lorenzano <[hidden email]>:
 
well… UnifiedFFI, UFFI or whatever it will be called already does that… as you know.
Currently we are using “older” NB way: as a method call, then solving it in first call. This is nice because is compatible and easies some stuff. 
But final objective is to provide a pragma and solve it in compilation time. 

Then we can 100% deprecate the invalid pragma old FFI uses today. 

But how do we solve the issue?
 

At least, that’s what we have talk :)

Esteban

On 12 Jan 2016, at 20:06, Nicolai Hess <[hidden email]> wrote:



2016-01-10 16:57 GMT+01:00 Eliot Miranda <[hidden email]>:
 
Hi Nicolai,

On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <[hidden email]> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

As others have said this is not a valid pragma.  A valid pragma is a message expression (a message with no receiver) that has only literal arguments.  There is one exception, to accept a variable name for the error code in a primitive invocation.

And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.


Thanks Eliot.

I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax



And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference).  So for example, the heapsort declaration from the standard C library:

int
     heapsort(void *base, size_t nel, size_t width,
         int (*compar)(const void *, const void *)) 

could be written as a pragma via e.g.

    <ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>

in which case it is equal to

   <ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>

which, while a massive hack, is pretty neat.  The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.

So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String).  I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.

This would easily allow extensions such as

     <ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>

to guide a marshalling engine in providing automatic checks and conversions.

[Slightly OT]
Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails).  So a Callback for heapsort above looks like

voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #IA32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

or
voidstarvoidstarRetintARM32: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #ARM32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))


Hmmm, if Callback had subclasses for each ABI then the above would become

IA32Callback methods for signature
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

ARM32Callback methods for signatures
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))

Much nicer.  I shall make it so.

our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>


nicolai

_,,,^..^,,,_
best, Eliot







Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] [squeak-dev] valid pragma syntax

EstebanLM

On 12 Jan 2016, at 21:12, Nicolai Hess <[hidden email]> wrote:



2016-01-12 20:57 GMT+01:00 Esteban Lorenzano <[hidden email]>:
 
well… UnifiedFFI, UFFI or whatever it will be called already does that… as you know.
Currently we are using “older” NB way: as a method call, then solving it in first call. This is nice because is compatible and easies some stuff. 
But final objective is to provide a pragma and solve it in compilation time. 

Then we can 100% deprecate the invalid pragma old FFI uses today. 

But how do we solve the issue?

Well, we should add an #visitFFIPragmaNode: who can deal with it, in the mean time :)

Esteban

 

At least, that’s what we have talk :)

Esteban

On 12 Jan 2016, at 20:06, Nicolai Hess <[hidden email]> wrote:



2016-01-10 16:57 GMT+01:00 Eliot Miranda <[hidden email]>:
 
Hi Nicolai,

On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <[hidden email]> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil


is this valid pragma syntax:

    <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>

As others have said this is not a valid pragma.  A valid pragma is a message expression (a message with no receiver) that has only literal arguments.  There is one exception, to accept a variable name for the error code in a primitive invocation.

And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.


Thanks Eliot.

I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax



And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference).  So for example, the heapsort declaration from the standard C library:

int
     heapsort(void *base, size_t nel, size_t width,
         int (*compar)(const void *, const void *)) 

could be written as a pragma via e.g.

    <ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>

in which case it is equal to

   <ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>

which, while a massive hack, is pretty neat.  The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.

So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String).  I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.

This would easily allow extensions such as

     <ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>

to guide a marshalling engine in providing automatic checks and conversions.

[Slightly OT]
Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails).  So a Callback for heapsort above looks like

voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #IA32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

or
voidstarvoidstarRetintARM32: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *)) abi: #ARM32>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))


Hmmm, if Callback had subclasses for each ABI then the above would become

IA32Callback methods for signature
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))

ARM32Callback methods for signatures
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien registerAt: 1))
value: (Alien forPointer: (spAlien registerAt: 2)))

Much nicer.  I shall make it so.

our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)

Any recommendations how to fix this
- fix RBParser or
- change this pragma, for example, like this
  <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>


nicolai

_,,,^..^,,,_
best, Eliot