後ろで定義されている関数を呼び出せるようにするパッチ


改良しました -> 後ろで定義されている関数を呼び出せるようにするパッチ その2 - fujidigの雑記

だいたい以下のような仕組みです。

  • プリプロセス時のラベル情報を使って関数の名前を type = TYPE_MODCMD, opt = -1 で登録
  • opt = -1 の関数の呼び出しがあったら FINFO にダミー登録。 opt をその FINFO ID に更新
  • ダミー登録済みの関数の #deffunc があったらダミー登録に上書き

ただこれだけだと以下のようなのは動くんですが、

	f
	stop
#module
#deffunc f
	return
#global

以下のようにモジュール内で呼び出すと動きません。

#module
#deffunc f
	g
	return
#deffunc g
	return
#global
	f

なぜかというとプリプロセス後に「g」が「g@m0」になっちゃうからです。「g@」と書けば動くんですが、それでは駄目ですよね。そこでちょっと小細工を入れて動くようにしています。 ExpandToken の変更や SearchSymbolOrRegisterVar のあたりです。
以下のような小細工を入れています:

  • プリプロセス時にモジュール内で@をつけていない識別子は終端に@をつけるようにします。たとえば "foo" は "foo@modname@" になります。
  • コンパイル時に "foo@modname@" という形式になっている識別子は、まず "foo" という名前の関数を探し、それがなければ "foo@modname" という名前の識別子を使うようにしています。
Index: token.cpp
===================================================================
--- token.cpp	(revision 241)
+++ token.cpp	(working copy)
@@ -1348,6 +1348,11 @@ char *CToken::ExpandToken( char *str, in
 	if (wrtbuf!=NULL) {
 //		AddModuleName( (char *)s2 );
 		wrtbuf->PutStr( fixname );
+		if ( strcmp( (char *)s2, fixname ) ) {
+			//		後ろで定義されている関数の呼び出しのために
+			//		モジュール内の foo はプリプロセス済みソースで foo@modname@ とする
+			wrtbuf->Put( '@' );
+		}
 //		wrtbuf->Put( '?' );
 	}
 	*type = TK_OBJ;
Index: codegen.cpp
===================================================================
--- codegen.cpp	(revision 241)
+++ codegen.cpp	(working copy)
@@ -160,17 +160,9 @@ void CToken::CalcCG_factor( CGVAR &v )
 		CalcCG_token();
 		return;
 	case TK_OBJ:
-		id = lb->Search( cg_str );
-		if ( id < 0 ) {
-			//Mesf( "[%s][%d]",cg_str, cg_valcnt );
-			id = lb->Regist( cg_str, TYPE_VAR, cg_valcnt );
-			v.curtype = TYPE_VAR;
-			v.ival = cg_valcnt;
-			cg_valcnt++;
-		} else {
-			v.curtype = lb->GetType( id );
-			v.ival = lb->GetOpt(id);
-		}
+		id = SearchSymbolOrRegisterVar( cg_str );
+		v.curtype = lb->GetType( id );
+		v.ival = lb->GetOpt(id);
 		if ( v.minflag ) {
 			if ( v.cnt > 0 ) {
 				ttype=TK_CALCERROR; return;
@@ -339,6 +331,63 @@ void CToken::CalcCG( int ex )
 //-----------------------------------------------------------------------------
 
 
+int CToken::SymbolEndsWithAtMark( char *name, int *len )
+{
+	//		シンボルが foo@modname@ という形式になっているか
+	//
+	unsigned char *p = (unsigned char *)name;
+	int state = 0;
+	while ( *p != '\0' ) {
+		unsigned char c = *p;
+		if ( c == '@' ) {
+			if ( state % 2 == 0 ) return 0;
+			if ( state == 1 ) {
+				state = 2;
+				*len = (int)((char *)p - name);
+			}
+			if ( state == 3 ) {
+				return *(p+1) == '\0';
+			}
+		} else if ( state % 2 == 0 ) {
+			state ++;
+		}
+		if ( issjisleadbyte(c) ) {
+			p += 2;
+		} else {
+			p ++;
+		}
+	}
+	return 0;
+}
+
+
+int CToken::SearchSymbolOrRegisterVar( char *name )
+{
+	int id = lb->Search( name );
+	int len;
+	char new_name[256];
+	if ( SymbolEndsWithAtMark( name, &len ) ) {
+		//		"foo@modname@" というシンボルに対して、
+		//		まず "foo" という関数がないか探し、次に "foo@modname" というシンボルを探す
+		strcpy2( new_name, name, sizeof new_name );
+		new_name[len] = '\0';
+		id = lb->Search( new_name );
+		if ( id >= 0 && lb->GetType(id) == TYPE_MODCMD ) {
+			return id;
+		}
+		new_name[len] = '@';
+		new_name[strlen(new_name)-1] = '\0';
+		id = lb->Search( new_name );
+		name = new_name;
+	}
+	if ( id < 0 ) {
+		id = lb->Regist( name, TYPE_VAR, cg_valcnt );
+		cg_valcnt++;
+	}
+	return id;
+}
+
+
 char *CToken::PickLongStringCG( char *str )
 {
 	//		指定文字列をmembufへ展開する
@@ -924,15 +973,11 @@ void CToken::GenerateCodePRMF2( void )
 			GetTokenCG( GETTOKEN_NOFLOAT );
 			break;
 		case TK_OBJ:
-			id = lb->Search( cg_str );
-			if ( id < 0 ) {
-				id = lb->Regist( cg_str, TYPE_VAR, cg_valcnt );
-				cg_valcnt++;
-			}
+			id = SearchSymbolOrRegisterVar( cg_str );
 
 			t = lb->GetType(id);
 			if (( t == TYPE_XLABEL )||( t == TYPE_LABEL )) throw CGERROR_LABELNAME;
-			PutCS( t, lb->GetOpt(id), ex );
+			PutCSSymbol( id, ex );
 			GetTokenCG( GETTOKEN_DEFAULT );
 
 			if ( ttype == TK_NONE ) {
@@ -971,11 +1016,7 @@ void CToken::GenerateCodePRMF3( void )
 	GetTokenCG( GETTOKEN_DEFAULT );
 	if ( ttype != TK_OBJ ) throw CGERROR_PP_BAD_STRUCT_SOURCE;
 
-	id = lb->Search( cg_str );
-	if ( id < 0 ) {
-		id = lb->Regist( cg_str, TYPE_VAR, cg_valcnt );
-		cg_valcnt++;
-	}
+	id = SearchSymbolOrRegisterVar( cg_str );
 	GenerateCodeVAR( id, ex );
 
 	if ( ttype != TK_NONE ) throw CGERROR_PP_BAD_STRUCT_SOURCE;
@@ -1052,11 +1093,7 @@ void CToken::GenerateCodeMethod( void )
 		GetTokenCG( GETTOKEN_DEFAULT );
 		break;
 	case TK_OBJ:
-		id = lb->Search( cg_str );
-		if ( id < 0 ) {
-			id = lb->Regist( cg_str, TYPE_VAR, cg_valcnt );
-			cg_valcnt++;
-		}
+		id = SearchSymbolOrRegisterVar( cg_str );
 		GenerateCodeVAR( id, ex );
 		break;
 	default:
@@ -1130,16 +1167,10 @@ void CToken::GenerateCodePRMN( void )
 			ex = 0;
 			break;
 		case TK_OBJ:
-			i = lb->Search( cg_str );
-			if ( i < 0 ) {
-				lb->Regist( cg_str, TYPE_VAR, cg_valcnt );
-				PutCS( TYPE_VAR, cg_valcnt, ex );
-				cg_valcnt++;
-			} else {
-				t = lb->GetType( i );
-				if ( t == TYPE_XLABEL ) t = TYPE_LABEL;
-				PutCS( t, lb->GetOpt(i), ex );
-			}
+			i = SearchSymbolOrRegisterVar( cg_str );
+			t = lb->GetType( i );
+			if ( t == TYPE_XLABEL ) t = TYPE_LABEL;
+			PutCS( t, lb->GetOpt(i), ex );
 			ex = 0;
 			break;
 		case TK_LABEL:
@@ -1200,7 +1231,7 @@ void CToken::GenerateCodeVAR( int id, in
 	t = lb->GetType(id);
 	if (( t == TYPE_XLABEL )||( t == TYPE_LABEL )) throw CGERROR_LABELNAME;
 	//
-	PutCS( t, lb->GetOpt(id), ex );
+	PutCSSymbol( id, ex );
 	GetTokenCG( GETTOKEN_DEFAULT );
 
 	if ( t == TYPE_SYSVAR ) return;
@@ -1365,7 +1396,7 @@ void CToken::GenerateCodeCMD( int id )
 	t = lb->GetType(id);
 	opt = lb->GetOpt(id);
 	orgcs = GetCS();
-	PutCS( t, opt & 0xffff, EXFLG_1 );
+	PutCSSymbol( id, EXFLG_1 );
 	if ( t == TYPE_PROGCMD ) CheckInternalProgCMD( opt, orgcs );
 	if ( t == TYPE_CMPCMD ) CheckInternalIF( opt );
 	GetTokenCG( GETTOKEN_DEFAULT );
@@ -1827,12 +1858,18 @@ int CToken::GetParameterResTypeCG( char 
 }
 
 
-void CToken::GenerateCodePP_deffunc( void )
+#define GET_FI_SIZE() ((int)(fi_buf->GetSize() / sizeof(STRUCTDAT)))
+#define GET_FI(n) (((STRUCTDAT *)fi_buf->GetBuffer()) + (n))
+#define STRUCTDAT_INDEX_DUMMY ((short)0x8000)
+
+
+void CToken::GenerateCodePP_deffunc0( int is_command )
 {
-	//		HSP3Codeを展開する(deffunc)
+	//		HSP3Codeを展開する(deffunc / defcfunc)
 	//
 	int i,t,ot,prmid,subid;
-	int clean;
+	int index;
+	int funcflag;
 	int regflag;
 	int prep;
 	char funcname[1024];
@@ -1843,7 +1880,7 @@ void CToken::GenerateCodePP_deffunc( voi
 	GetTokenCG( GETTOKEN_DEFAULT );
 	if ( ttype != TK_OBJ ) throw CGERROR_PP_NAMEREQUIRED;
 
-	if ( !strcmp( cg_str,"prep" ) ) {				// プロトタイプ宣言
+	if ( is_command && !strcmp( cg_str,"prep" ) ) {				// プロトタイプ宣言
 		prep = 1;
 		GetTokenCG( GETTOKEN_DEFAULT );
 		if ( ttype != TK_OBJ ) throw CGERROR_PP_NAMEREQUIRED;
@@ -1855,12 +1892,17 @@ void CToken::GenerateCodePP_deffunc( voi
 		lb->SetFlag( cg_localstruct[i], -1 );		// 以前に指定されたパラメーター名を削除する
 	}
 	cg_localcur = 0;
-	clean = 0;
+	funcflag = 0;
 	regflag = 1;
 
-	i = lb->Search( funcname );
-	if ( i >= 0 ) {
-		throw CGERROR_PP_ALREADY_USE_FUNC;
+	index = -1;
+	int label_id = lb->Search( funcname );
+	if ( label_id >= 0 ) {
+		if ( lb->GetType(label_id) != TYPE_MODCMD ) throw CGERROR_PP_ALREADY_USE_FUNC;
+		index = lb->GetOpt(label_id);
+		if ( index >= 0 && GET_FI(index)->index != STRUCTDAT_INDEX_DUMMY ) {
+			throw CGERROR_PP_ALREADY_USE_FUNC;
+		}
 	}
 
 	PutStructStart();
@@ -1869,8 +1911,8 @@ void CToken::GenerateCodePP_deffunc( voi
 		if ( ttype >= TK_EOL ) break;
 		if ( ttype != TK_OBJ ) throw CGERROR_PP_WRONG_PARAM_NAME;
 
-		if ( !strcmp( cg_str,"onexit" ) ) {
-			clean |= STRUCTDAT_FUNCFLAG_CLEANUP;
+		if ( is_command && !strcmp( cg_str,"onexit" ) ) {
+			funcflag |= STRUCTDAT_FUNCFLAG_CLEANUP;
 			break;
 		}
 
@@ -1888,13 +1930,13 @@ void CToken::GenerateCodePP_deffunc( voi
 			//Mesf( "%s:struct%d",cg_str,subid );
 			if ( t == MPTYPE_IMODULEVAR ) {
 				if ( prm[ lb->GetOpt(i) ].offset != -1 ) throw CGERROR_PP_MODINIT_USED;
-				prm[ lb->GetOpt(i) ].offset = fi_buf->GetSize() / sizeof(STRUCTDAT);
+				prm[ lb->GetOpt(i) ].offset = GET_FI_SIZE();
 				regflag = 0;
 			}
 			if ( t == MPTYPE_TMODULEVAR ) {
 				st = (STRUCTDAT *)fi_buf->GetBuffer();
 				if ( st[ subid ].otindex != 0 ) throw CGERROR_PP_MODTERM_USED;
-				st[ subid ].otindex = fi_buf->GetSize() / sizeof(STRUCTDAT);
+				st[ subid ].otindex = GET_FI_SIZE();
 				regflag = 0;
 			}
 			prmid = PutStructParam( t, subid );
@@ -1923,91 +1965,30 @@ void CToken::GenerateCodePP_deffunc( voi
 	}
 
 	ot = PutOT( GetCS() );
-	i = PutStructEnd( funcname, STRUCTDAT_INDEX_FUNC, ot, clean );
-	if ( regflag ) {
-		lb->Regist( funcname, TYPE_MODCMD, i );
+	if ( index == -1 ) {
+		index = GET_FI_SIZE();
+		fi_buf->PreparePtr( sizeof(STRUCTDAT) );
+		if ( regflag ) {
+			lb->Regist( funcname, TYPE_MODCMD, index );
+		}
+	}
+	if ( label_id >= 0 ) {
+		lb->SetOpt( label_id, index );
 	}
+	int dat_index = is_command ? STRUCTDAT_INDEX_FUNC : STRUCTDAT_INDEX_CFUNC;
+	PutStructEnd( index, funcname, dat_index, ot, funcflag );
 }
 
 
-void CToken::GenerateCodePP_defcfunc( void )
+void CToken::GenerateCodePP_deffunc( void )
 {
-	//		HSP3Codeを展開する(defcfunc)
-	//
-	int i,t,ot,prmid,subid;
-	int funcflag;
-	char funcname[1024];
-	STRUCTPRM *prm;
-
-	/*
-	GetTokenCG( GETTOKEN_DEFAULT );
-	t = GetParameterResTypeCG( cg_str );
-	if ( t <= MPTYPE_NONE ) {
-		throw CGERROR_PP_WRONG_PARAM_NAME;
-	}
-	funcflag = t;
-	*/
-	funcflag = 0;
-
-	GetTokenCG( GETTOKEN_DEFAULT );
-	if ( ttype != TK_OBJ ) throw CGERROR_PP_NAMEREQUIRED;
-	strncpy( funcname, cg_str, 1023 );
-
-	for(i=0;i<cg_localcur;i++) {
-		lb->SetFlag( cg_localstruct[i], -1 );		// 以前に指定されたパラメーター名を削除する
-	}
-	cg_localcur = 0;
-
-
-	PutStructStart();
-	while(1) {
-		GetTokenCG( GETTOKEN_DEFAULT );
-		if ( ttype >= TK_EOL ) break;
-		if ( ttype != TK_OBJ ) throw CGERROR_PP_WRONG_PARAM_NAME;
-		t = GetParameterTypeCG( cg_str );
-		if ( t == MPTYPE_NONE ) throw CGERROR_PP_WRONG_PARAM_NAME;
-		if ( t == MPTYPE_MODULEVAR ) {
-			//	モジュール名指定
-			GetTokenCG( GETTOKEN_DEFAULT );
-			if ( ttype != TK_OBJ ) throw CGERROR_PP_WRONG_PARAM_NAME;
-			i = lb->Search( cg_str );
-			if ( i < 0 ) throw CGERROR_PP_BAD_STRUCT;
-			if ( lb->GetType(i) != TYPE_STRUCT ) throw CGERROR_PP_BAD_STRUCT;
-			prm = (STRUCTPRM *)mi_buf->GetBuffer();
-			subid = prm[ lb->GetOpt(i) ].subid;
-			//Mesf( "%s:struct%d",cg_str,subid );
-			prmid = PutStructParam( t, subid );
-			GetTokenCG( GETTOKEN_DEFAULT );
-
-		} else {
-			prmid = PutStructParam( t, STRUCTPRM_SUBID_STACK );
-			//Mesf( "%d:type%d",prmid,t );
-
-			GetTokenCG( GETTOKEN_DEFAULT );
-			if ( ttype == TK_OBJ ) {
-				//	引数のエイリアス
-				i = lb->Search( cg_str );
-				if ( i >= 0 ) {
-					throw CGERROR_PP_ALREADY_USE_PARAM;
-				}
-				i = lb->Regist( cg_str, TYPE_STRUCT, prmid );
-				cg_localstruct[ cg_localcur++ ] = i;
-				GetTokenCG( GETTOKEN_DEFAULT );
-			}
-		}
+	GenerateCodePP_deffunc0( 1 );
+}
 
-		if ( ttype >= TK_EOL ) break;
-		if ( ttype != TK_NONE ) throw CGERROR_PP_WRONG_PARAM_NAME;
-		if ( val != ',' ) throw CGERROR_PP_WRONG_PARAM_NAME;
-	}
 
-	i = lb->Search( funcname );
-	if ( i >= 0 ) {
-		throw CGERROR_PP_ALREADY_USE_FUNC;
-	}
-	ot = PutOT( GetCS() );
-	i = PutStructEnd( funcname, STRUCTDAT_INDEX_CFUNC, ot, funcflag );
-	lb->Regist( funcname, TYPE_MODCMD, i );
+void CToken::GenerateCodePP_defcfunc( void )
+{
+	GenerateCodePP_deffunc0( 0 );
 }
 
 
@@ -2177,27 +2158,20 @@ int CToken::GenerateCodeSub( void )
 //			break;
 		case TK_OBJ:
 			cg_lastcmd = CG_LASTCMD_LET;
-			i = lb->Search( cg_str );
-			if ( i < 0 ) {
-				//Mesf( "[%s][%d]",cg_str, cg_valcnt );
-				i = lb->Regist( cg_str, TYPE_VAR, cg_valcnt );
-				cg_valcnt++;
+			i = SearchSymbolOrRegisterVar( cg_str );
+			t = lb->GetType( i );
+			switch( t ) {
+			case TYPE_VAR:
+			case TYPE_STRUCT:
 				GenerateCodeLET( i );
-			} else {
-				t = lb->GetType( i );
-				switch( t ) {
-				case TYPE_VAR:
-				case TYPE_STRUCT:
-					GenerateCodeLET( i );
-					break;
-				case TYPE_LABEL:
-				case TYPE_XLABEL:
-					throw CGERROR_LABELNAME;
-					break;
-				default:
-					GenerateCodeCMD( i );
-					break;
-				}
+				break;
+			case TYPE_LABEL:
+			case TYPE_XLABEL:
+				throw CGERROR_LABELNAME;
+				break;
+			default:
+				GenerateCodeCMD( i );
+				break;
 			}
 //			sprintf( tmp,"#obj:%s (%d)",cg_str,i );
 //			Mes( tmp );
@@ -2326,6 +2300,25 @@ int CToken::GenerateCodeBlock( void )
 }
 
 
+void CToken::RegisterFuncLabels( void )
+{
+	//		プリプロセス時のラベル情報から関数を定義
+	//
+	if ( tmp_lb == NULL ) return;
+	int len = tmp_lb->GetCount();
+	for( int i = 0; i < len; i ++ ) {
+		if ( tmp_lb->GetType(i) == LAB_TYPE_PPMODFUNC && tmp_lb->GetFlag(i) >= 0 ) {
+			char *name = tmp_lb->GetName(i);
+			if ( lb->Search(name) >= 0 ) {
+				throw CGERROR_PP_ALREADY_USE_FUNC;
+			}
+			int id = lb->Regist( name, TYPE_MODCMD, -1 );
+			lb->SetData2( id, (char *)&i, sizeof i ); // tmp_lbのidをdata2内に保存
+		}
+	}
+}
+
+
 int CToken::GenerateCodeMain( CMemBuf *buf )
 {
 	//		ソースをHSP3Codeに展開する
@@ -2354,6 +2347,8 @@ int CToken::GenerateCodeMain( CMemBuf *b
 	for( a=0; a<CG_REPLEV_MAX; a++) { repend[a] = -1; }
 
 	try {
+		RegisterFuncLabels();
+
 		while(1) {
 			if ( GenerateCodeBlock() == TK_EOF ) break;
 		}
@@ -2372,6 +2367,15 @@ int CToken::GenerateCodeMain( CMemBuf *b
 				errend++;
 			}
 		}
+		
+		//		関数未処理チェック
+		for( a=0; a<GET_FI_SIZE(); a++ ) {
+			if ( GET_FI(a)->index == STRUCTDAT_INDEX_DUMMY ) {
+				Mesf( "#関数が存在しません [%s]", lb->GetName(GET_FI(a)->otindex) );
+				errend++;
+			}
+		}
+		
 		if ( errend ) throw CGERROR_FATAL;
 	}
 	catch ( CGERROR code ) {
@@ -2416,6 +2420,26 @@ void CToken::PutCS( int type, double val
 }
 
 
+void CToken::PutCSSymbol( int label_id, int exflag )
+{
+	//		まだ定義されていない関数の呼び出しがあったら仮登録する
+	//
+	int type = lb->GetType(label_id);
+	int value = lb->GetOpt(label_id);
+	if ( type == TYPE_MODCMD && value == -1 ) {
+		int id = *(int *)lb->GetData2(label_id);
+		tmp_lb->AddReference( id );
+		
+		STRUCTDAT st = { STRUCTDAT_INDEX_DUMMY };
+		st.otindex = label_id;
+		value = GET_FI_SIZE();
+		fi_buf->PutData( &st, sizeof(STRUCTDAT) );
+		lb->SetOpt( label_id, value );
+	}
+	if ( exflag & EXFLG_1 && type != TYPE_VAR && type != TYPE_STRUCT ) {
+		value &= 0xffff;
+	}
+	PutCS( type, value, exflag );
+}
+
+
 int CToken::GetCS( void )
 {
 	//		Get current CS index
@@ -2609,7 +2633,7 @@ int CToken::PutStructParam( short mptype
 
 	prm.mptype = mptype;
 	if ( extype == STRUCTPRM_SUBID_STID ) {
-		prm.subid  = fi_buf->GetSize() / sizeof(STRUCTDAT);
+		prm.subid  = GET_FI_SIZE();
 	} else {
 		prm.subid = extype;
 	}
@@ -2673,7 +2697,7 @@ int CToken::PutStructParamTag( void )
 	i = mi_buf->GetSize() / sizeof(STRUCTPRM);
 
 	prm.mptype = MPTYPE_STRUCTTAG;
-	prm.subid  = fi_buf->GetSize() / sizeof(STRUCTDAT);
+	prm.subid  = GET_FI_SIZE();
 	prm.offset = -1;
 
 	cg_stnum++;
@@ -2690,13 +2714,11 @@ void CToken::PutStructStart( void )
 }
 
 
-int CToken::PutStructEnd( char *name, int libindex, int otindex, int funcflag )
+int CToken::PutStructEnd( int i, char *name, int libindex, int otindex, int funcflag )
 {
 	//		STRUCTDATを登録する(モジュール用)
 	//
-	int i;
 	STRUCTDAT st;
-	i = fi_buf->GetSize() / sizeof(STRUCTDAT);
 	st.index = libindex;
 	st.nameidx = PutDS( name );
 	st.subid = i;
@@ -2710,19 +2732,27 @@ int CToken::PutStructEnd( char *name, in
 	} else {
 		st.otindex = otindex;
 	}
-	fi_buf->PutData( &st, sizeof(STRUCTDAT) );
+	*GET_FI(i) = st;
 	//Mesf( "#%d : %s(LIB%d) prm%d size%d ot%d", i, name, libindex, cg_stnum, cg_stsize, otindex );
 	return i;
 }
 
 
+int CToken::PutStructEnd( char *name, int libindex, int otindex, int funcflag )
+{
+	int i = GET_FI_SIZE();
+	fi_buf->PreparePtr( sizeof(STRUCTDAT) );
+	return PutStructEnd( i, name, libindex, otindex, funcflag );
+}
+
+
 int CToken::PutStructEndDll( char *name, int libindex, int subid, int otindex )
 {
 	//		STRUCTDATを登録する(DLL用)
 	//
 	int i;
 	STRUCTDAT st;
-	i = fi_buf->GetSize() / sizeof(STRUCTDAT);
+	i = GET_FI_SIZE();
 	st.index = libindex;
 	if ( name[0] == '*' ) {
 		st.nameidx = -1;
Index: token.h
===================================================================
--- token.h	(revision 241)
+++ token.h	(working copy)
@@ -169,6 +169,7 @@ public:
 	int GenerateCode( CMemBuf *srcbuf, char *oname, int mode );
 
 	void PutCS( int type, int value, int exflg );
+	void PutCSSymbol( int label_id, int exflag );
 	int GetCS( void );
 	void PutCS( int type, double value, int exflg );
 	int PutOT( int value );
@@ -186,6 +187,7 @@ public:
 	int PutStructParamTag( void );
 	void PutStructStart( void );
 	int PutStructEnd( char *name, int libindex, int otindex, int funcflag );
+	int PutStructEnd( int i, char *name, int libindex, int otindex, int funcflag );
 	int PutStructEndDll( char *name, int libindex, int subid, int otindex );
 
 	void CalcCG( int ex );
@@ -257,6 +259,7 @@ private:
 	//		For Code Generate
 	//
 	int GenerateCodeMain( CMemBuf *src );
+	void RegisterFuncLabels( void );
 	int GenerateCodeBlock( void );
 	int GenerateCodeSub( void );
 	void GenerateCodePP( char *buf );
@@ -271,9 +274,12 @@ private:
 	int GenerateCodePRMF4( int t );
 	void GenerateCodeMethod( void );
 	void GenerateCodeLabel( char *name, int ex );
+	int SearchSymbolOrRegisterVar( char *name );
+	int SymbolEndsWithAtMark( char *name, int *len );
 
 	void GenerateCodePP_regcmd( void );
 	void GenerateCodePP_cmd( void );
+	void GenerateCodePP_deffunc0( int is_command );
 	void GenerateCodePP_deffunc( void );
 	void GenerateCodePP_defcfunc( void );
 	void GenerateCodePP_uselib( void );

追記 (2009-06-12T21:44:20+09:00)

PutCSSymbol を修正しました。 常に value & 0xffff とすると thismod が -1 から 0xffff になってしまうので ex1 フラグのときのみマスクをかけるように。

追記 (2009-06-19T19:21:24+09:00)

TYPE_VAR や TYPE_STRUCT のときはマスクをかけないように修正...