Newbie questions about Pliant

Newbie questions about Pliant

order of evaluation in meta programming

in what order all the parser filters and
meta's are executed ? How can I guarrantee
that my meta and filter code doesn't break something?
Message posted by reitman on 2003/06/10 01:24:35
I am working on a Pliant->Perl interface.  I want something like this

gvar Str str
gvar Int number

str = perl {{ join ",", [1..10]; }} 

number = perl {{ 2
  +2; }}

console str eol 
console number rol

---
should print 
1,2,3,4,5,6,7,8,9,10
4

I understand that I need to write a filter to make {{ perl-code }} to be 
recognized as a mutiline-string.  How do I register my parser filter
so that it will have a chance to look at {{...}} before any other filters ?
( {{...}} is one token)

Similarly, when I implement a meta to convert the assignment 

  str = perl code_in_string 

to a block of code like 

  tmp_sv = lperl_eval_pv code_in_string
  str = lperl_SvPV_nolen tmp_sv

I need to make sure that my meta comes in at the right time. 
If people will become adding metas to pliant, how can we police it
so that we don't step on each other's feet ? Is Pliant a shift-reduce parser ?
Does it build an explicit tree of the program, or is it one pass ? 

Thanks a lot, 
Boris

Message posted by hubert.tonneau on 2003/06/10 08:53:37
> I understand that I need to write a filter to make {{ perl-code }} to be 
> recognized as a mutiline-string.  How do I register my parser filter
> so that it will have a chance to look at {{...}} before any other filters ?

You have to record your parser filter with priority 'pliant parser 2 chars operators'
so that it comes before '{'

> I need to make sure that my meta comes in at the right time. 
> If people will become adding metas to pliant, how can we police it
> so that we don't step on each other's feet ?

If two definitions match for the code, Pliant will return an 'ambigious definition'
error.
Also, you can mark some of the definitions as 'strong_definition' or
'weak_definition' 'always_strong_definition' 'always_weak_definition'

'strong_definition' means if I conflict with another existing definition, then
I am the right one.
'weak_definition' means if I conflict with another existing definition, then
just ignore me.
'always_strong_definition' means if I conflict with any other definition, then
I am the right one.
'always_weak_definition' means if I conflict with any other definition, then
just ignore me.

> Is Pliant a shift-reduce parser ?
> Does it build an explicit tree of the program, or is it one pass ? 

It's in one pass, and it truely builds a tree of the program. The subtree is
what you receive as the only argument when you write a meta.
Message posted by hubert.tonneau on 2003/06/10 08:58:19
Looking at your sample code, I guess that:

. you want to define a parser for {{ }} which is basically the same as " " but
  let you use special characters such as " and [ within, without the need to
  encode these.

. you want to define a 'perl' function that evaluates the string as some perl
  code, then returns the result as a Pliant string.
  I see no meta programming here.
Message posted by reitman on 2003/06/11 04:17:39
The assignment calls for when the l-value is an integer
is different from the call for when the l-value is a string.
I.e, i mean:

original code:

  str = perl {{ some_perl_code }}

becomes:

  tmp_sv = lperl_eval_pv code_in_string
  str = lperl_SvPV_nolen tmp_sv

but, original code:

  number = perl {{ some_perl_code }}

becomes:

  tmp_sv = lperl_eval_pv code_in_string
  number = lperl_SvIv tmp_sv

======================================================
So will I require meta-programming for above case ?
Also, I have tried to code the filter,  and I seem
to not allocate memory correctly, because I get
segmentation fault.  This is the code:

=== test.pli ================
module "/borisreitman/multiline_string.pli"
console {{ hello
to you }}eol

=== multiline_string.pli ====
# filter to recognize a multi-line string: uses {{  }} as delimiters.
# usefull to embed programs in other languages in the middle of
# pliant code.

module "/pliant/language/parser.pli"
module "/pliant/language/compiler.pli"

function multiline_string context line parameter
  arg_rw ParserContext context
  arg Str line
  arg Address parameter
  var Str result

  var uInt value := 0
  if (line:0 <> "{") and (line:1 <> "{")
    return

  var Int i := 2;
  var Pointer:Arrow base nextbase
  var Pointer:Arrow base
  var Pointer:Str cur :> line
  var Int max := cur len
  base :> context:current_line
  nextbase :> context:text next base
  var Char chr
  var Str lookahead
  var Int count := 0;

  while true

    if i = max
      base :> nextbase
      if base = null
        console "Error: Unexpected end of file while looking for closing '}}'" eol
        return

      nextbase :> context:text next base
      cur :> base map Str
      result := result + "[lf][cr]"
      count := count + 2
      i := 0
      max := cur len

    chr  := cur i
    lookahead := (cur i) + (cur i+1)

    #console "Got char: " chr eol
    if lookahead = "}}"
      console "New string token: "  result eol
      var Link:Str token :> new Str result
      context add_token addressof:token
      context forward count+2
      return
    else
      result := result + chr
      i := i + 1
      count := count + 1

gvar ParserFilter my_filter
my_filter function :> the_function multiline_string ParserContext Str Address
constant 'pliant parser 2 chars operators' my_filter
export 'pliant parser 2 chars operators'

==============================================

Is there a better way to do it ?  The program reaches
the line

      console "New string token: "  result eol

and prints correctly as expected. However, the 'console' statement
in the driver program test.pli doesn't get executed -- and I get
segmentation fault.

Thanks a lot for your help,
Boris
~                                    
Message posted by hubert.tonneau on 2003/06/11 08:30:01
Writting a multiline Pliant filter is something quite hard has opposed to
writting one which require all to be provided on the current line, and the
reason is that indentation has meaning to Pliant, so there is a mechanism
to add the missing '{}' that might interfer with any multiline filter.

> context forward count+2

Seems obviously buggy to me because in case of a multi lines match, you will
forward the curset past the end of the line.

You should better start with the existing 'multiline_keyword' instruction
(see /pliant/language/parser/multiline.pli for it's source, and 'listing'
instruction in /pliant/protocol/http/style/default.style for a sample usage)
then try to elaborate step by step.