#include "stk.h"
#include "amacro.h"

extern STKSYS *stksys;

int STKChgVarNumSub(unchar c,NSTACK *nstk)
// １つの型(c)の数値取り出し
// 変数の時：内容参照、アドレスの時：絶対アドレス化も出来る
/* 切り離し不可 */
{
unchar sc;
int ret;
	/* スタック読みだし */
	if ((ret=PopNStack(nstk))) return(ret);
	if (c!=NANO && c!=NVADR && c!=NVADRN) {
		// 素通し、変数そのもの、未確定変数以外は内容参照に変換する
		if ((ret=STKVarChange(nstk,(c==NOADRS||c==NOSTR1)))) return(ret);
	} // 変換しない時はそのまま
	
	if (c==NOADRS) c=NADRS; // 以下はNADRSと同じ処理
	else
	if (c==NOSTR1) c=NSTR1; // 以下はNSTR1と同じ処理
	
	// 型チェック
	//sc=nstk->atrb&0xff;
	sc=(unchar)nstk->atrb; // スタック中のものの型（下位８ビット）
	#if DEBUG
	printf2("<%c=%c>",c,sc);
	#endif
	if (c!=NANO && c!=NANO2) { // 何でもありの時以外
		if (c!=sc) { /* 一致してない */
		    switch (c) { // 特別判定
			case NSTR1:
			    if (sc==NADRS) break; // NSTR1のときはNADRSもok
			    return(ARGILL);
			
			// 変数はグローバル/ローカルに区別はない
			case NVADR:// 確定変数アドレス
			    if (sc==NVADRN) return(VARNAC); // 未確定変数
			    return(ARGILL);
			
			case NVADRN:// 未確定変数アドレス（変数定義専用）
			    if (sc==NVADR) { // 確定がきた
				// その変数が現在と同じ段なら２重定義エラー
				if (nstk->loc==stksys->loc) return(VARDBL);
				// 違う段の時は現在の段に定義する
				break;
			    }
			    return(ARGILL);
		    }
		}
	} // 型チェックなしのときは素通し
	return(OK);
}

int STKChgVarNum(unchar *list,NSTACK nstk[])
// 必要な数値取り出し＆型チェック
// 変数の時：内容参照、アドレスの時：絶対アドレス化も出来る
/* 引数リストは、左から順に(0)から記述する（見た目と逆なので注意）*/
/* 切り離し不可 */
{
unchar c;
int ret=OK,i=0;
	#if DEBUG
	printf2("%s:",list);
	#endif
	while (ret==OK && (c=*list++)!=0) { // リスト読みだし(0〜)
		ret=STKChgVarNumSub(c,&nstk[i++]);
	}
	#if DEBUG
	printf2("\n");
	#endif
	return(ret);
}
