Newbie questions about Pliant

Newbie questions about Pliant

variable number of parameters

need to have a Pliant function that can receive variable number of parameters
Message posted by reitman on 2003/07/24 08:20:14
I am working on perl embedding wrapper.  I want to have something like this

  perl_eval {{  sub hello { "i got values:", join ',', @_; } }}

  perl::hello 1 2 "xxx" 4 "yyy"

so that the hello function will be called.
I need to be able to push onto the perl stack a variable number of parameters.
Here is my thinking. In my implementation of the 'perl' meta, I will need to call 
a function of the form,

  call_perl_function "hello" array_of_args

I don't know how to prepare such an array in a meta such that in the end of the day 
I can inline the perl::hello code in the middle of any other pliant code, 
for example with a perl implemented 'add' function, I want to be able to do this: 

  console "sum = " (perl::add 2 3 4 5) eol

This is why I am inclined to send, instead of array_of_args, the actuall variable list of paramters, if I can figure out how to declare such functions in pliant.

Also, embedding syntax suggestions are welcome.
Message posted by hubert.tonneau on 2003/07/24 08:27:58
Pliant will not easily let you mixte two different syntax on a single line.

So you have two solutions:
  perl_eval
    {{  sub hello { "i got values:", join ',', @_; } }}
pr
  perl_eval "{{  sub hello { [dq]i got values:[dq], join ',', @_; } }}"

For the first solution, you have to use 'multiline_keyword' defined
in /pliant/language/parser/multiline.pli
You can see an example as 'listing' .page instruction which is defined
in /pliant/protocol/http/style/default.style

Basically, if you define 'perl_eval' as a multiline keyworkd, you will
receive the bloc under it as a list of strings, one string for each line.


Message posted by reitman on 2003/07/24 14:02:10
Hi, 

In your response you haven't addressed the main question of my posting,
that concerning invocation of a perl function,

  perl::add 1 2 3 4 5 

The 'perl::' prefix just tells Pliant that I am calling function 'add'
function in the perl space. 

Note: the 'add()' function is something that I have defined earlier, 
for example with perl_eval {{ }} block.  ( Concerning the {{ }} 
notation, I have already started working on a filter that
treats anything between {{ and }} as a verbatim string.  Right now 
it works within a line, but I need to figure out how to extend it to multiple lines ).    

To call the perl 'add' function I need to process variable number of arguments,
and for each argument call XPUSHs to push it on the perl stack ( at runtime ). 
If pliant had something like a varagrs syntax, but for native Pliant functions, 
I could see how I could do this. The above line would translate into something like, 

   perl_call "add" 1 2 3 4 5 

by use of a meta rule. I think Pliant, however, doesn't handle variable number of arguments at the moment, for non 'external' functions, but I may be wrong, 
please correct me.  So basically I wonder whats the best plan of attack ?

Thanks,
Boris
Message posted by hubert.tonneau on 2003/07/24 14:13:36
Yes, Pliant does not provide C variable arguments binding because it's a too
dirty feature: C is a typed language, but as soon as you switch to variable
arguments, typing vanishes.
The Pliant meta is the right way to handle it.

Now back to your interface, if you don't want to do dirty tricks, then you need
a C function in the perl library that enables to push one argument, and you will
use a meta on Pliant side.
I don't understand where the problem is.
Message posted by reitman on 2003/07/24 15:13:20
I am just confused how my perl call will be inlined in the surrounding code.
For example, should I do the following: 

In source:  

  console "Result: " (perl::add 1 2 3 4 5) eol

And my meta will rewrite it into something like this: 

  gvar Address my_perl_stack_ptr := perl_get_stack_ptr
  code_to_prepare_perl_stack  my_perl_stack_ptr

  # push arguments
  for i from 1 to e:size
    perl_push_arg my_perl_stack_ptr e:i

  # the original line, modified
  console "Result: " (perl_call_function "add") eol

  code_to_cleanup my_stack_pointer

I have two concerns with this. First, the choice of the my_perl_stack_ptr
identifier name by the meta code.  I need to make sure that my_perl_stack_ptr
is not something currently defined in the current context -- so that I don't override it. 

Second, what happens if I have two perl::add() invocations on one line 

  console  "Result: " (perl::add 1 2 3 4) " result2: " (perl::add 10 11 12) eol
or
  console  "Result: " (perl:add 1 (perl::add 2 3)) eol 

-- I will need to balance the argument passing in the preceeding
and finalizing code in the runtime stack order, which sounds like a lot of work,
and I am not sure how the meta's for different occurences of perl::add will be
communicating to generate the setup and cleanup code in the correct order.

Thanks,
Boris
Message posted by hubert.tonneau on 2003/07/24 20:10:49
> First, the choice of the my_perl_stack_ptr identifier name by the meta code.

You don't need a name for 'my_perl_stack_ptr'.
In a meta, you can create a local variable on the stack with no name, so there
cannot be any conflict.

> Second, what happens if I have two perl::add() invocations on one line 
>   console  "Result: " (perl::add 1 2 3 4) " result2: " (perl::add 10 11 12) eol
> or
>   console  "Result: " (perl:add 1 (perl::add 2 3)) eol 

No problem. You can select through the way you write the meta (the
position of the 'suckup' instructions) if the call will be nested or not.

One more point:
  perl::add 1 2 3 4
is a bad idea. Rather use:
  perl add 1 2 3 4