/*---------------------------------------------------------------------------*/
/* スタック操作（切り放し不可）*/
/*---------------------------------------------------------------------------*/

#include <stdio.h>
#include "defines.h"
#include "stk.h"
#include "amacro.h"

extern STKSYS *stksys;

/*---------------------------------------------------------------------------*/

#ifndef NOTRACE
static void PrintNStack(NSTACK *nstk,unchar *sep)
// 数値スタック内容表示
{
unsint atrb;
	atrb=nstk->atrb;
	printf2("[%d]%s%d/$%x(%x):%c"
		,stksys->ntop
		,sep	   // セパレーター
		,nstk->num // 10進
		,nstk->num // 16進
		,nstk->point
		//,atrb&0xff
		,(unchar)atrb
	);
	// if (atrb&0xff00) printf2("(%d) ",atrb>>8);
	if (atrb>0xff) printf2("(%d) ",atrb>>8);
	else printf2(" ");
}
#endif

int PushNStack(NSTACK *nstk)
// １数値を積む
{
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	if (sys->ntop>=sys->nmax) return(NSTKFULL);
	#ifndef NOTRACE
	if (sys->mode&MDntrace) PrintNStack(nstk,"←");
	#endif
	sys->nstack[sys->ntop++]=*nstk;
	return(OK);
}

int PopNStack(NSTACK *nstk)
// １数値を取り出す
{
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	if (sys->ntop<=0) return(NSTKEMP);
	*nstk=sys->nstack[--sys->ntop];
	#ifndef NOTRACE
	if (sys->mode&MDntrace) PrintNStack(nstk,"→");
	#endif
	return(OK);
}

/*---------------------------------------------------------------------------*/

#ifndef NOTRACE
static void PrintLStack(short ltop,LSTACK *lstk,unchar *mes)
{
	printf2("ﾗﾍﾞﾙ[%d]%s$%x(%c) ",ltop,mes,lstk->adrs,lstk->atrb);
}
#endif

int PushLStack(unchar *adrs,char atrb)
/* ラベルポイントを積む */
{
short ltop;
LSTACK *lstk;
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	ltop=sys->ltop;
	if (ltop>=sys->lmax) return(LSTKFULL);
	lstk=&sys->lstack[ltop];
	lstk->adrs=adrs;
	lstk->atrb=atrb;
	#ifndef NOTRACE
	if (sys->mode&MDltrace) PrintLStack(ltop,lstk,"←");
	#endif
	sys->ltop++;
	return(OK);
}

int PopLStack(unchar *(*adrs),char *atrb,int mode)
/* ラベルポイントを取り出す */
/* mode : 0=取り出して消す , 1=読み出すだけ */
{
short ltop;
LSTACK *lstk;
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	ltop=sys->ltop;
	if (ltop<=0) return(LSTKEMP);
	lstk=&sys->lstack[--ltop];
	*adrs=lstk->adrs;
	*atrb=lstk->atrb;
	#ifndef NOTRACE
	if (sys->mode&MDltrace) PrintLStack(ltop,lstk,(mode? "=":"→"));
	#endif
	if (!mode) sys->ltop=ltop;
	return(OK);
}

/*---------------------------------------------------------------------------*/

#ifndef NOTRACE
static void PrintRStack(short rtop,RSTACK *rstk,unchar *mes)
{
	printf2("ﾙｰﾌﾟ[%d]%s%d,%d ",rtop,mes,rstk->start,rstk->end);
}
#endif

int PushRStack(long start,long end)
/* ループカウンタを積む */
{
short rtop;
RSTACK *rstk;
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	rtop=sys->rtop;
	if (rtop>=sys->rmax) return(RSTKFULL);
	rstk=&sys->rstack[rtop];
	rstk->start=start;
	rstk->end  =end;
	#ifndef NOTRACE
	if (sys->mode&MDrtrace) PrintRStack(rtop,rstk,"←");
	#endif
	sys->rtop++;
	return(OK);
}

int PopRStack(long *start,long *end,int mode)
/* ループカウンタを取り出す */
/* mode : 0=取り出して消す , 1=読み出すだけ */
{
short rtop;
RSTACK *rstk;
STKSYS *sys;
	sys=stksys; // 省メモリーのためローカル変数に置き換える
	rtop=sys->rtop;
	if (rtop<=0) return(RSTKEMP);
	rstk=&sys->rstack[--rtop];
	*start=rstk->start;
	*end  =rstk->end;
	#ifndef NOTRACE
	if (sys->mode&MDrtrace) PrintRStack(rtop,rstk,(mode? "=":"→"));
	#endif
	if (!mode) sys->rtop=rtop;
	return(OK);
}

/*---------------------------------------------------------------------------*/

void SwapStack(NSTACK nstk[],int p0,int p1)
// 数値スタック入れ換え
{
NSTACK nstk0;
	nstk0   =nstk[p0];
	nstk[p0]=nstk[p1];
	nstk[p1]=nstk0;
}

/*---------------------------------------------------------------------------*/
