/* ラベル確定（中間コード作成：切り放し不可）*/

#include "stk.h"

extern STKSYS *stksys;

int STKSetLabelAdrs(unchar *ctext,VARSYS2 *label)
/* 中間コード化後に中間コードを読んでラベルと変数を識別し、
	ラベルを確定＋絶対アドレス化する */
{
unchar c,len,*ctext0,*name;
long num;
short p;
	ctext0=ctext;
	while ((c=*ctext++)!=SCEND) {
	  len=*ctext++;
	  if (c>SCCMD) { // コマンド以外
	    switch (c) {
		default:
		    return(STKCodeErr(c,"label"));
		
		// 以下のものは飛ばすだけ(defaultにしないため)
		case SCSTR1: // 固定文字列
		    len=EvenLen(len); // 偶数バイト化
		case SCNUM:  // 数値
		case SCCOMT: // コメント
		    break;
		
		case SCCAL0: // 未定義callﾗﾍﾞﾙ
		case SCVAR:  // 変数
		    // 変数かラベルかを判定する
		    name=stksys->Gvar.vwork[*(long *)ctext].adrs;
		    if (VarRead(name,&num,NULL,&p,label)) {
			    // ラベルでない＝変数である
			    // 未確定ラベルはすべて変数扱いになる
			    //	 （ラベル名の書き間違いに注意、ということ）
			    if (c==SCCAL0) { // callﾗﾍﾞﾙが変数になることはない
				SetErrToken(name);
				return(LBLNONE);
			    }
			    // 変数の場合は何もしない
			    break;
		    }
		    // 実はラベルであった:中間コード変更(lenは不変)
		    // SC??? $04 アドレス
		    // -2    -1  ↑=ctext=ltext
		    *(ctext-2)=(c==SCCAL0? SCCALL:SCLBL);
		    *(long *)ctext=(long)&ctext0[num]; // 絶対アドレスで
		    break;
		
		case SCCALL:/* callラベルアドレス */
		case SCLBL: /* ラベルアドレス */
		    // オフセットアドレス -> 絶対アドレス
		    *(long *)ctext=(long)&ctext0[*(long *)ctext];
		    break;
		
	    }
	  } // コマンドは飛ばすだけ
	  ctext+=len;
	}
	return(OK);
}
