Newbie questions about Pliant

Newbie questions about Pliant

assignment operator

Is there an equivalent of operator=(TypeA, TypeB) as in C++ ?
Message posted by maybe Boris on 2003/10/12 05:53:49
(The work on embedding perl in pliant continues, and I'm now wrapping perl arrays. Here's the problem I'm facing.)

I know that there are two methods: casting and copy constructor: 

  function copy src dst

where src and dst are of the same type.

I have, 

gvar TypeA a; gvar TypeB b;
a := b

If I try to solve this with defining how to cast b to a, what happens is 
that a temporary object of type A is constructed and is initialized from b,
and then the copy function copies this temporary object into a. 

I need direct copy, without the temporary object. How would I go about this problem ?

Thanks,
Boris



Message posted by hubert.tonneau on 2003/10/12 20:07:39
> If I try to solve this with defining how to cast b to a, what happens is 
> that a temporary object of type A is constructed and is initialized from b,
> and then the copy function copies this temporary object into a. 

Pliant code optimiser should be smart enough to cast directly to 'a' instead
of creating a temporary object.

If you find a case where it's not, then I'll investigate.
Message posted by reitman on 2003/10/17 07:55:14
Here is a sample.  What happens is that the copy routine is executed 
after the cast.  This is pliant version 86. What I want is
to execute only one routine that assigns a into b (this is what cast does now), 
and thats it. 


boris@einstein:/pliant/borisreitman$ cat copy.pli
type TypeA
  field Int x

type TypeB
  field Int y

function copy src dst
  arg TypeB src
  arg_w TypeB dst
  console "in copy b b" eol
  dst y := src y

function 'cast TypeB' a -> b
  arg TypeA a
  arg TypeB b
  implicit
  console "In cast a->b" eol
  b y := a x


gvar TypeA a
gvar TypeB b
a x := 5
b := a
console "b = " b:y eol

boris@einstein:/pliant/borisreitman$ pliant copy.pli
In cast a->b
in copy b b
b = 5

Message posted by hubert.tonneau on 2003/10/17 08:48:30
Here is my test code.

Please notice two things:
. calling the function you study 'sample function' will automatically turn on
  verbose Pliant code generator, so that you can know how it translates from
  the initial set of instructions to the final binary code
. in my sample, no copy append, and I bet it is because I don't access the
  'y' field on B directly anymore

type TypeA
  field Int x

type TypeB
  field Int y

function copy src dst
  arg TypeB src ; arg_w TypeB dst
  has_no_side_effect
  console "in copy b b" eol
  dst y := src y

function 'cast TypeB' a -> b
  arg TypeA a
  arg TypeB b
  implicit
  has_no_side_effect
  console "In cast a->b" eol
  b y := a x

function verify a
  arg TypeA a
  console "a value is " a:x eol

function verify b
  arg TypeB b
  console "b value is " b:y eol

function 'sample function'
  var TypeA a
  var TypeB b
  a x := 5
  verify a
  b := a
  verify b

'sample function'


You may want to try the following, and then you get the copy back:

function verify i
  arg Int i
  console "i value is " i eol

function 'sample function'
  var TypeA a
  var TypeB b
  a x := 5
  verify a
  b := a
  verify b:y

'sample function'
Message posted by maybe Boris Reitman on 2003/11/24 23:38:28
Ok, I see -- so as long as I don't look inside 'b' withint the same block of code,
I'm ok. Do you not think that this behaviour is wrong ?  Why would a temporary
object be created in the case that I look inside 'b' within the same block ? 
Message posted by hubert.tonneau on 2003/11/24 23:52:46
I bet the problem is that Pliant optimizer is suboptimal in this case.

It's probably the 'optimize_drop' function in /pliant/language/optimizer/extra.pli
that should recognize that 'a2' (see listing in the output of the program) can
be mixed with 'b'.
Also finding why it fails in this case is quite some work because code optimizing
is something very very complex (and probably not well done from the design point
of view in Pliant).
Message posted by maybe Boris Reitman on 2003/11/24 23:54:48
Here is another instance of the problem, now with subelements not 
accessed explicitely. What follows is a short program, and a test run. 
between 'HERE' and 'THERE' is where it happens.

### array.pli

module "/pliant/language/compiler.pli"
module "/pliantx/language/perl.pli"
module "/pliantx/syntax/multiline_string.pli"

lperl_prepare

gvar PerlArray array;
gvar PerlScalar scalar;

scalar := 5;
gvar PerlArray_element tmp := array:0;
console "HERE" eol
tmp := scalar;
console "THERE" eol


console "Almost done" eol

# must cleanup refcounts before lperl_cleanup
destroy array
lperl_cleanup

console "DONE" eol


#################

boris@einstein:/pliant/borisreitman/t/perl$ pliant array.pli 
IN build ae
IN build ae
DEBUG_C: AV = 134661020
Now in copy PerlArray_element
HERE
IN build ae
In cast scalar->ae
Now in copy PerlArray_element
THERE
Almost done
DONE

################

as you see, what happens is that in assignment,

tmp := scalar

where tmp is of type PerlArray_element and scalar is of type PerlScalar,
a cast from scalar->ae  (from perl scalar inro PerlArray_element)
occurs, where the target is not 'tmp' variable, but a temporary object.  Then
a copy constructor kicks in, and copied the temporary object it into 'tmp'.

Nowhere in the main scope I'm accessing the members of tmp object.
Message posted by maybe Boris Reitman on 2003/12/02 23:09:27
Hi,

Could you give a tip on how to write a meta that will turn

  a:i := s

to compile as,

  set_perlarray_element(a,i,s)

where a is of type PerlArray,  i is of type Int, s is of type 
PerlScalar, Int or String, and each can be an arbitrary expression, eg

  a:(random_integer 0 10) := get_some_value

Thanks,
Boris


Message posted by hubert.tonneau on 2003/12/02 23:40:42
One possibility is to write a ':=' meta

meta ':='
  if e:size=2 and e:0=2 and (e:0:0 cast ...) and (e:0:1 cast Int) and (e:1 cast ...)
    ...

I bet this would work without any problem, but I would not bet that it's the
simplest solution.
Message posted by maybe Boris Reitman on 2003/12/03 07:23:00
Thanks!  I started writing it, and this is where I got stuck.

===============
module "/pliant/language/unsafe.pli"
module "/pliant/language/compiler.pli"

type PerlArray
  field Int a

function set_perlarray_element a index value
  arg PerlArray a
  arg Int index
  arg Int value
  console "Got index = " index " value = " value eol

meta ':=' e
  if e:size <> 2
    return
  if e:0:size <> 1
    return
  console "e:size =" e:size       eol
  console "e:0    =" e:0:ident    eol
  console "e:0:0  =" e:0:0:ident  eol
  console "e:1    =" e:1:ident    eol
  var Link:Expression array_expr :> expression ident e:0:ident near e

  if (array_expr cast PerlArray) and (e:0:0 cast Int) and (e:1 cast Int)
    console "match" eol
    e suckup e:0:0
    e suckup e:1
    e suckup array_expr
    e add (instruction (the_function set_perlarray_element PerlArray Int Int) array_expr:result e:0:0:result e:1:result)

gvar PerlArray a
gvar Int x y
x := 2
y := 3
a x := y

===============
The output:
===============

e:size =2
e:0    =a
e:0:0  =x
e:1    =y
match
----------------------------------------------------------------
Failed to compile a   (Int rw)
  compile file:x.pli (internals) 35 1
compile file:x.pli (internals) 35 5
compile file:x.pli (internals) 35 5
compile file:x.pli (internals) 35 1
compile file:x.pli (internals) 35 1
parse file:x.pli (internals) 36 1
module file:x.pli
----------------------------------------------------------------
actions stack is:
parse file:x.pli (internals) 36 1
module file:x.pli
----------------------------------------------------------------
processor stack content is:
error_notify_fatal (ErrorID Str) +14
error_report +61
error_renotify (ErrorID Address Str) +41
. compile (Expression) +125
  file:x.pli (internals) 35 1
parser_tag_record  /pliant/language/type/misc/tag.pli (internals) 182 1
. execute (ParserContext) +39
parser_filter_execute +240
pliant internal parse_one_token function (ParserContext) +391
compile_text (List Module) +230
pliant_load_module (Str Module Int Module) +920
??? at 134599668
----------------------------------------------------------------
Message posted by hubert.tonneau on 2003/12/03 10:00:15
If your meta succeded, it must end with 'e set_void_result' or something like that.