/* Copyright (c) 1997-2004			 -*- C -*-
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

#ident "$Project: polymake $$Id: Object.xs,v 1.2 2004/10/29 15:29:01 gawrilow Exp $"

#include "Ext.h"

MODULE = Poly::Object			PACKAGE = Poly::Object

PROTOTYPES: DISABLE

void
assigned_to(...)
CODE:
{
   PERL_CONTEXT *cx_bottom=cxstack, *cx_top=cx_bottom+cxstack_ix, *cx=cx_top;
   OP *o;
   while (cx >= cx_bottom) {
      if (CxTYPE(cx) == CXt_SUB) {
	 o=PL_retstack[cx->blk_oldretsp-1];
	 if (o->op_type != OP_LEAVESUBLV) {
	    if (o->op_type == OP_SASSIGN && !(o->op_private & OPpASSIGN_BACKWARDS)) {
	       SV *rhs=*(PL_stack_base+cx->blk_oldsp);		/* value to be assigned ... */
	       AV *args=GvAV(PL_defgv);
	       U8 save_flags=AvREIFY(args);
	       AvREIFY_off(args);
	       av_push(GvAV(PL_defgv), rhs);			/* pushed into the current @_ */
	       AvFLAGS(args) |= save_flags;
	       PL_retstack[cx->blk_oldretsp-1]=o->op_next;	/* skip pp_sassign */
	       while (cx <= cx_top) {
		  if (CxTYPE(cx) == CXt_SUB)
		     cx->blk_sub.lval=0;
		  ++cx;
	       }
	       XSRETURN_YES;
	    }
	    break;
	 }
      }
      --cx;
   }
   XSRETURN_NO;
}
items=0;

void
get_alternatives(...)
PPCODE:
{
   PERL_CONTEXT *cx_bottom=cxstack, *cx=cx_bottom+cxstack_ix;
   while (cx >= cx_bottom) {
      if (CxTYPE(cx) == CXt_SUB) {
	 OP *o=PL_retstack[cx->blk_oldretsp-1];
	 if (o->op_type != OP_LEAVESUBLV) {
	    I32 skip=FALSE, push=GIMME_V==G_ARRAY;
#ifdef USE_ITHREADS
	    SV **saved_curpad=0;
#endif
	    while (o->op_type == OP_CONST && o->op_next->op_type == OP_BIT_OR) {
	       if (push) {
#ifdef USE_ITHREADS
		  if (!skip) {
		     saved_curpad=PL_curpad;
		     PL_curpad=get_cx_curpad(aTHX_ cx, cx_bottom);
		  }
#endif
		  XPUSHs(cSVOPo_sv);
	       }
	       skip=TRUE;
	       o=o->op_next->op_next;
	    }
	    if (skip) {
	       PL_retstack[cx->blk_oldretsp-1]=o;
#ifdef USE_ITHREADS
	       if (push) PL_curpad=saved_curpad;
#endif
	    }
	    break;
	 }
      }
      --cx;
   }
}
items=0;

BOOT:
if (PL_DBgv) {
   CvNODEBUG_on(get_cv("Poly::Object::assigned_to", FALSE));
   CvNODEBUG_on(get_cv("Poly::Object::get_alternatives", FALSE));
}
