Engine
Class Sequencer

source: c:\runehov\Engine\Classes\Sequencer.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.SequencerBase
         |
         +--Engine.Sequencer
Direct Known Subclasses:None

class Sequencer
extends Engine.SequencerBase

//============================================================================= // Sequencer. //=============================================================================
Variables
 DSPtr, CSPtr
           Control stack
 int CStack[8]
           Control stack
 string CodeString
 int CommunityLocus
 ESeqToken CurrentToken
 byte DStackType[32]
           0..25:var, 26..51:gvar,
 float DStack[32]
           Data stack
 EIAction NextInterpAction
           Control stack
 LOp, ROp
           Control stack
 float SVar[26]
 SequencerAdministrator SeqAdmin
           Duration to wait after IA_Sleep
 float SleepDuration
           Duration to wait after IA_Sleep
 int TokLabel
 float TokNumber
 string TokString
 int TokVariable
 int TokWord
 string XCode
 int XCodePtr
 int XCodeSize
 bool bAutoStart

States
Interpret, CheckAutoStart

Function Summary
 void ExecuteWord()
     
//-----------------------------------------------------------------------------
// ExecuteWord.
//-----------------------------------------------------------------------------
 void InitCodeString(string cStr)
     
//-----------------------------------------------------------------------------
// InitCodeString.
//-----------------------------------------------------------------------------
 void JumpAhead(int cSearch, int cMatch)
     
//-----------------------------------------------------------------------------
// JumpAhead.
//-----------------------------------------------------------------------------
 void JumpBack(int cSearch, int cMatch)
     
//-----------------------------------------------------------------------------
// JumpBack.
//-----------------------------------------------------------------------------
 void MainParse()
     
//-----------------------------------------------------------------------------
// MainParse.
//-----------------------------------------------------------------------------
 ESeqToken NextToken()
     
//-----------------------------------------------------------------------------
// NextToken.
//-----------------------------------------------------------------------------
 void ParseError()
     
//-----------------------------------------------------------------------------
// ParseError.
//-----------------------------------------------------------------------------
 float ParseNumber(int c)
     
//-----------------------------------------------------------------------------
// ParseNumber.
//-----------------------------------------------------------------------------
 string ParseString(int sPtr)
     
//-----------------------------------------------------------------------------
// ParseString.
//-----------------------------------------------------------------------------
 int PopAddr()
 float PopNum()
 int PopVar()
 void PrepBOperator()
 void PrepSingleDS()
 int PrepSpecStore()
 void PushAddr(int a)
 void PushGlobalVar(int v)
 void PushNum(float n)
     
//-----------------------------------------------------------------------------
// Stack Functions.
//-----------------------------------------------------------------------------
 void PushVar(int v)
 void WordEvent()


State Interpret Function Summary


State CheckAutoStart Function Summary



Source Code


00001	//=============================================================================
00002	// Sequencer.
00003	//=============================================================================
00004	class Sequencer expands SequencerBase;
00005	
00006	const SEQ_VAR_COUNT = 26;
00007	
00008	enum EIAction
00009	{
00010		IA_Continue,	// Continue interpretation
00011		IA_Halt,		// Halt and wait for trigger
00012		IA_Stop,		// Stop
00013		IA_Sleep		// Sleep for a specified duration
00014	};
00015	
00016	// EDITABLE INSTANCE VARIABLES ////////////////////////////////////////////////
00017	
00018	var() bool		bAutoStart;
00019	var() string	CodeString;
00020	var() int		CommunityLocus;
00021	
00022	// INSTANCE VARIABLES /////////////////////////////////////////////////////////
00023	
00024	var float				SVar[26];
00025	var string				XCode;
00026	var int					XCodeSize;
00027	var int					XCodePtr;
00028	var float				TokNumber;
00029	var string				TokString;
00030	var int					TokLabel;
00031	var int					TokVariable;
00032	var int					TokWord;
00033	var ESeqToken			CurrentToken;
00034	var float				DStack[32];			// Data stack
00035	var byte				DStackType[32];		// 0..25:var, 26..51:gvar,
00036												// 255:float
00037	var int					CStack[8];			// Control stack
00038	var int					DSPtr, CSPtr;
00039	var float				LOp, ROp;
00040	var EIAction			NextInterpAction;
00041	var float				SleepDuration;		// Duration to wait after IA_Sleep
00042	
00043	var SequencerAdministrator SeqAdmin;
00044	
00045	// FUNCTIONS //////////////////////////////////////////////////////////////////
00046	
00047	//-----------------------------------------------------------------------------
00048	// BeginPlay.
00049	//-----------------------------------------------------------------------------
00050	event BeginPlay()
00051	{
00052		local SequencerAdministrator sAdmin;
00053	
00054		super.BeginPlay();
00055		foreach AllActors(class'SequencerAdministrator', sAdmin)
00056			return;
00057	
00058		sAdmin = spawn(class'SequencerAdministrator');
00059		sAdmin.Inception();
00060	}
00061	
00062	//-----------------------------------------------------------------------------
00063	// InitCodeString.
00064	//-----------------------------------------------------------------------------
00065	function InitCodeString(string cStr)
00066	{
00067		local int i, c;
00068	
00069		for(i = 0; i < 26; i++)
00070			SVar[i] = 0.0;
00071	
00072		i = 0;
00073		XCodeSize = Len(cStr);
00074		while(i < XCodeSize-2)
00075			if(Mid(cStr, i++, 1) == "_")
00076			{
00077				c = Asc(Mid(cStr, i++));
00078				if(c > 96 && c < 123)
00079					SVar[c-97] = i;
00080			}
00081		XCode = cStr;
00082		XCodePtr = 0;
00083		DSPtr = 32;
00084		CSPtr = 8;
00085	}
00086	
00087	//-----------------------------------------------------------------------------
00088	// NextToken.
00089	//-----------------------------------------------------------------------------
00090	function ESeqToken NextToken()
00091	{
00092		local int c, c2;
00093		local ESeqToken t;
00094	
00095		while(XCodePtr < XCodeSize)
00096		{
00097			c = Asc(Mid(XCode, XCodePtr++, 1));
00098			if(c < 33)
00099				continue;
00100			t = SeqAdmin.AscToToken[c-32];
00101			if(t == TK_Variable)
00102			{
00103				TokVariable = c-97;
00104				return TK_Variable;
00105			}
00106			if(t == TK_GlobalVariable)
00107			{
00108				if(XCodePtr < XCodeSize)
00109				{
00110					c2 = Asc(Mid(XCode, XCodePtr++, 1));
00111					t = SeqAdmin.AscToToken[c2-32];
00112					if(t == TK_Variable)
00113					{
00114						TokVariable = c2-97;
00115						return TK_GlobalVariable;
00116					}
00117					else return TK_None;
00118				}
00119				else return TK_End;
00120			}
00121			if(t == TK_Number)
00122			{
00123				TokNumber = ParseNumber(c);
00124				return TK_Number;
00125			}
00126			if(t == TK_Word)
00127			{
00128				if(XCodePtr >= XCodeSize)
00129					return TK_End;
00130				TokWord = c*100 + Asc(Mid(XCode, XCodePtr++))-32;
00131				return TK_Word;
00132			}
00133			if(t == TK_String)
00134			{ // Strings -> numbers
00135				TokNumber = XCodePtr;
00136				c2 = -1;
00137				while(XCodePtr < XCodeSize)
00138				{
00139					c = Asc(Mid(XCode, XCodePtr++));
00140					if(c == 34 && c2 != 92)
00141						break;
00142					c2 = c;
00143				}
00144				return TK_Number;
00145			}
00146	
00147			c2 = Asc(Mid(XCode, XCodePtr++));
00148			if(t == TK_Add)
00149			{
00150				if(c2 == 43) // ++
00151					return TK_Inc;
00152				if(c2 == 35) // +#
00153					return TK_AddStore;
00154			}
00155			if(t == TK_Sub)
00156			{
00157				if(c2 == 45) // --
00158					return TK_Dec;
00159				if(c2 == 35) // +#
00160					return TK_SubStore;
00161				if(SeqAdmin.AscToToken[c2-32] == TK_Number)
00162				{
00163					XCodePtr--;
00164					TokNumber = ParseNumber(c);
00165					return TK_Number;
00166				}
00167			}
00168			if(t == TK_Mul && c2 == 35) // *#
00169				return TK_MulStore;
00170			if(t == TK_Div && c2 == 35) // /#
00171				return TK_DivStore;
00172			XCodePtr--;
00173	
00174			if(t != TK_None)
00175				return t;
00176		}
00177		return TK_End;
00178	}
00179	
00180	//-----------------------------------------------------------------------------
00181	// ParseNumber.
00182	//-----------------------------------------------------------------------------
00183	function float ParseNumber(int c)
00184	{
00185		local float v, v2, d;
00186		local bool neg;
00187	
00188		v = 0;
00189		neg = false;
00190		if(c == 46)
00191			XCodePtr--;
00192		else
00193		{
00194			if(c == 45)
00195				neg = true;
00196			v = FClamp(c-48, 0, 9);
00197			while(XCodePtr < XCodeSize)
00198			{
00199				c = Asc(Mid(XCode, XCodePtr));
00200				if(SeqAdmin.AscToToken[c-32] != TK_Number || c == 46)
00201					break;
00202				v = v*10 + c-48;
00203				XCodePtr++;
00204			}
00205		}
00206		if(c == 46)
00207		{
00208			v2 = 0;
00209			d = 1;
00210			XCodePtr++;
00211			while(XCodePtr < XCodeSize)
00212			{
00213				c = Asc(Mid(XCode, XCodePtr));
00214				if(SeqAdmin.AscToToken[c-32] != TK_Number || c == 46)
00215					break;
00216				v2 = v2*10 + c-48;
00217				d *= 10;
00218				XCodePtr++;
00219			}
00220			v += v2/d;
00221		}
00222		if(neg)
00223			return -v;
00224		return v;
00225	}
00226	
00227	//-----------------------------------------------------------------------------
00228	// ParseString.
00229	//-----------------------------------------------------------------------------
00230	function string ParseString(int sPtr)
00231	{
00232		local int c;
00233		local string tStr;
00234		local bool escapeSequence;
00235	
00236		escapeSequence = false;
00237		while(sPtr >= 0 && sPtr < XCodeSize)
00238		{
00239			c = Asc(Mid(XCode, sPtr++));
00240			if(escapeSequence)
00241			{
00242				switch(c)
00243				{
00244				case  97: c =  7; break; // a: Audible alert
00245				case  98: c =  8; break; // b: Backspace
00246				case 116: c =  9; break; // t: Horizontal tab
00247				case 110: c = 10; break; // n: Newline
00248				case 118: c = 11; break; // v: Verticle tab
00249				case 102: c = 12; break; // f: Formfeed
00250				case 114: c = 13; break; // r: Carraige return
00251				case 120: // x:
00252					break;
00253				}
00254				escapeSequence = false;
00255			}
00256			else
00257			{
00258				if(c == 92)
00259				{
00260					escapeSequence = true;
00261					continue;
00262				}
00263				if(c == 34)
00264					break;
00265			}
00266			tStr = tStr $ Chr(c);
00267		}
00268		return tStr;
00269	}
00270	
00271	//-----------------------------------------------------------------------------
00272	// MainParse.
00273	//-----------------------------------------------------------------------------
00274	function MainParse()
00275	{
00276		local float n;
00277		local int i, v;
00278		local ESeqToken t;
00279	
00280		NextInterpAction = IA_Continue;
00281		do
00282		{
00283			switch(NextToken())
00284			{
00285			case TK_Number: PushNum(TokNumber); break;
00286			case TK_Variable: PushVar(TokVariable); break;
00287			case TK_GlobalVariable: PushGlobalVar(TokVariable); break;
00288			case TK_Call: PushAddr(XCodePtr); XCodePtr = PopNum(); break;
00289			case TK_Return: XCodePtr = PopAddr(); break;
00290			case TK_Word: ExecuteWord(); break;
00291			case TK_Mul: PrepBOperator(); DStack[DSPtr] *= ROp; break;
00292			case TK_Div: PrepBOperator(); DStack[DSPtr] /= ROp; break;
00293			case TK_Mod: PrepBOperator(); DStack[DSPtr] = DStack[DSPtr] % ROp; break;
00294			case TK_Add: PrepBOperator(); DStack[DSPtr] += ROp; break;
00295			case TK_Sub: PrepBOperator(); DStack[DSPtr] -= ROp; break;
00296			case TK_MulStore:
00297				v = PrepSpecStore();
00298				if(v < SEQ_VAR_COUNT)
00299					SVar[v] *= LOp;
00300				else
00301					SeqAdmin.GVar[v-SEQ_VAR_COUNT] *= LOp;
00302				break;
00303			case TK_DivStore:
00304				v = PrepSpecStore();
00305				if(v < SEQ_VAR_COUNT)
00306					SVar[v] /= LOp;
00307				else
00308					SeqAdmin.GVar[v-SEQ_VAR_COUNT] /= LOp;
00309				break;
00310			case TK_ModStore:
00311				v = PrepSpecStore();
00312				if(v < SEQ_VAR_COUNT)
00313					SVar[v] = SVar[v] % Lop;
00314				else
00315					SeqAdmin.GVar[v-SEQ_VAR_COUNT] = SeqAdmin.GVar[v-SEQ_VAR_COUNT] % LOp;
00316				break;
00317			case TK_AddStore:
00318				v = PrepSpecStore();
00319				if(v < SEQ_VAR_COUNT)
00320					SVar[v] += LOp;
00321				else
00322					SeqAdmin.GVar[v-SEQ_VAR_COUNT] += LOp;
00323				break;
00324			case TK_SubStore:
00325				v = PrepSpecStore();
00326				if(v < SEQ_VAR_COUNT)
00327					SVar[v] -= LOp;
00328				else
00329					SeqAdmin.GVar[v-SEQ_VAR_COUNT] -= LOp;
00330				break;
00331			case TK_Eq:
00332				PrepBOperator(); DStack[DSPtr] = float(DStack[DSPtr] == ROp); break;
00333			case TK_Lt:
00334				PrepBOperator(); DStack[DSPtr] = float(DStack[DSPtr] < ROp); break;
00335			case TK_Gt:
00336				PrepBOperator(); DStack[DSPtr] = float(DStack[DSPtr] > ROp); break;
00337			case TK_And:
00338				PrepBOperator();
00339				DStack[DSPtr] = float(bool(DStack[DSPtr]) && bool(ROp)); break;
00340			case TK_Or:
00341				PrepBOperator();
00342				DStack[DSPtr] = float(bool(DStack[DSPtr]) || bool(ROp)); break;
00343			case TK_Not:
00344				PrepSingleDS(); DStack[DSPtr] = float(!bool(DStack[DSPtr])); break;
00345			case TK_Inc: v = PopVar(); SVar[v] += 1.0; break;
00346			case TK_Dec: v = PopVar(); SVar[v] -= 1.0; break;
00347			case TK_Store:
00348				v = PopVar();
00349				if(v < SEQ_VAR_COUNT)
00350					SVar[v] = PopNum();
00351				else
00352					SeqAdmin.GVar[v-SEQ_VAR_COUNT] = PopNum();
00353				break;
00354			case TK_If:
00355				if(!bool(PopNum()))
00356				{
00357					i = 0;
00358					do
00359					{
00360						t = NextToken();
00361						if(t == TK_If)
00362							i++;
00363						else if(t == TK_EndIf)
00364						{
00365							if(i == 0)
00366								break;
00367							else
00368								i--;
00369						}
00370						else if(t == TK_Else && i == 0)
00371							break;
00372					} until(t == TK_End);
00373				}
00374				break;
00375			case TK_Else:
00376				i = 0;
00377				do
00378				{
00379					t = NextToken();
00380					if(t == TK_If)
00381						i++;
00382					else if(t == TK_EndIf)
00383						if(i == 0)
00384							break;
00385						else
00386							i--;
00387				} until(t == TK_End);
00388				break;
00389			case TK_Endif:
00390			case TK_Loop:
00391			case TK_Do:
00392			case TK_Repeat:
00393				break;
00394			case TK_EndLoop:
00395				JumpBack(40, 41);
00396				break;
00397			case TK_Until:
00398				if(bool(PopNum()) == false)
00399					JumpBack(123, 125);
00400				break;
00401			case TK_EndRepeat:
00402				PrepSingleDS();
00403				DStack[DSPtr] -= 1;
00404				if(DStack[DSPtr] != 0)
00405					JumpBack(91, 93);
00406				else
00407					PopNum();
00408				break;
00409			case TK_End:
00410				NextInterpAction = IA_Stop;
00411				break;
00412			}
00413		} until(NextInterpAction != IA_Continue);
00414	}
00415	
00416	//-----------------------------------------------------------------------------
00417	// JumpBack.
00418	//-----------------------------------------------------------------------------
00419	function JumpBack(int cSearch, int cMatch)
00420	{
00421		local int i, c, c2, failPtr;
00422	
00423		i = 1;
00424		failPtr = XCodePtr;
00425		XCodePtr--;
00426		while(XCodePtr-- > 0)
00427		{
00428			c = Asc(Mid(XCode, XCodePtr));
00429			if(c == cSearch)
00430			{
00431				i--;
00432				if(i == 0)
00433				{
00434					XCodePtr++;
00435					return;
00436				}
00437			}
00438			else if(c == cMatch)
00439				i++;
00440			else if(c == 34)
00441			{
00442				c2 = -1;
00443				//while(XCodePtr-- > 0)
00444				//{
00445				//	c = Asc(Mid(XCode, XCodePtr));
00446				//	if(c == 34 && c2 != 92)
00447				//		break;
00448				//	c2 = c;
00449				//}
00450			}
00451		}
00452		log("SEQ,ScanBack: no match");
00453		XCodePtr = failPtr;
00454	}
00455	
00456	//-----------------------------------------------------------------------------
00457	// JumpAhead.
00458	//-----------------------------------------------------------------------------
00459	function JumpAhead(int cSearch, int cMatch)
00460	{
00461	}
00462	
00463	function PrepBOperator()
00464	{
00465		ROp = PopNum();
00466		if(DSPtr == 32)
00467			ParseError();
00468		DStackType[DSPtr] = 255; // A result is never a variable
00469	}
00470	
00471	function int PrepSpecStore()
00472	{
00473		local int v;
00474	
00475		v = PopVar();
00476		LOp = PopNum();
00477		return v;
00478	}
00479	
00480	function PrepSingleDS()
00481	{
00482		if(DSPtr == 32)
00483			ParseError();
00484		DStackType[DSPtr] = 255;
00485	}
00486	
00487	//-----------------------------------------------------------------------------
00488	// Stack Functions.
00489	//-----------------------------------------------------------------------------
00490	function PushNum(float n)
00491	{
00492		if(DSPtr == 0)
00493			ParseError();
00494		DStackType[--DSPtr] = 255;
00495		DStack[DSPtr] = n;
00496	}
00497	
00498	function float PopNum()
00499	{
00500		if(DSPtr == 32)
00501			ParseError();
00502		return DStack[DSPtr++];
00503	}
00504	
00505	function PushVar(int v)
00506	{
00507		if(DSPtr == 0)
00508			ParseError();
00509		DStackType[--DSPtr] = v;
00510		DStack[DSPtr] = SVar[v];
00511	}
00512	
00513	function int PopVar()
00514	{
00515		if(DSPtr == 32)
00516			ParseError();
00517		if(DStackType[DSPtr] == 255) ParseError();
00518		return DStackType[DSPtr++];
00519	}
00520	
00521	function PushGlobalVar(int v)
00522	{
00523	 	if(DSPtr == 0)
00524	 		ParseError();
00525		DStackType[--DSPtr] = v + SEQ_VAR_COUNT;
00526		DStack[DSPtr] = SeqAdmin.GVar[v];
00527	}
00528	
00529	function PushAddr(int a)
00530	{
00531		if(CSPtr == 0)
00532			ParseError();
00533		CStack[--CSPtr] = a;
00534	}
00535	
00536	function int PopAddr()
00537	{
00538		if(CSPtr == 8)
00539			ParseError();
00540		return CStack[CSPtr++];
00541	}
00542	
00543	//-----------------------------------------------------------------------------
00544	// ParseError.
00545	//-----------------------------------------------------------------------------
00546	function ParseError()
00547	{
00548		log("Sequence interpret error");
00549		NextInterpAction = IA_Stop;
00550	}
00551	
00552	//-----------------------------------------------------------------------------
00553	// ExecuteWord.
00554	//-----------------------------------------------------------------------------
00555	function ExecuteWord()
00556	{
00557		local int i;
00558		local float f, f2;
00559	
00560		switch(TokWord)
00561		{
00562		case 6885: // Du : Dup ( n1 ... n1 n1 )
00563			if(DSPtr == 32 || DSPtr == 0)
00564				ParseError();
00565			DSPtr--;
00566			DStackType[DSPtr] = DStackType[DSPtr+1];
00567			DStack[DSPtr] = DStack[DSPtr+1];
00568			break;
00569		case 8387: // Sw : Swap ( n1 n2 ... n2 n1 )
00570			if(DSPtr > 30)
00571				ParseError();
00572			f = DStack[DSPtr+1];
00573			i = DStackType[DSPtr+1];
00574			DStack[DSPtr+1] = DStack[DSPtr];
00575			DStackType[DSPtr+1] = DStackType[DSPtr];
00576			DStack[DSPtr] = f;
00577			DStackType[DSPtr] = i;
00578			break;
00579		case 6882: // Dr : Drop ( n ... )
00580			PopNum();
00581			break;
00582		case 6566: // Ab : Abs ( n1 ... n2 )
00583			PrepSingleDS();
00584			DStack[DSPtr] = Abs(DStack[DSPtr]);
00585			break;
00586		case 7778: // Mn : Min ( n1 n2 ... n3 )
00587			PushNum(FMin(PopNum(), PopNum()));
00588			break;
00589		case 7788: // Mx : Max ( n1 n2 ... n3 )
00590			PushNum(FMax(PopNum(), PopNum()));
00591			break;
00592		case 8373: // Si : Sin ( n1 ... n2 )
00593			PrepSingleDS();
00594			DStack[DSPtr] = Sin(DStack[DSPtr]);
00595			break;
00596		case 6779: // Co : Cos ( n1 ... n2 )
00597			PrepSingleDS();
00598			DStack[DSPtr] = Cos(DStack[DSPtr]);
00599			break;
00600		case 8465: // Ta : Tan ( n1 ... n2 )
00601			PrepSingleDS();
00602			DStack[DSPtr] = Tan(DStack[DSPtr]);
00603			break;
00604		case 7871: // Ng : Neg ( n1 ... n2 )
00605			PrepSingleDS();
00606			DStack[DSPtr] = -DStack[DSPtr];
00607			break;
00608		case 6986: // Ev : Event ( s ... )
00609			WordEvent();
00610			break;
00611		case 8376: // Sl : Sleep ( n ... )
00612			SleepDuration = PopNum();
00613			NextInterpAction = IA_Sleep;
00614			break;
00615		case 8384: // St : Stop ( ... )
00616			NextInterpAction = IA_Stop;
00617			break;
00618		case 8073: // Pi : Pi ( ... n )
00619			PushNum(Pi);
00620			break;
00621		case 8265: // Ra : Rand ( ... n )
00622			PushNum(FRand());
00623			break;
00624		case 8282: // Rr : RandRange ( n1 n2 ... n3 )
00625			f2 = PopNum();
00626			f = PopNum();
00627			PushNum(f + (f2-f)*FRand());
00628			break;
00629		case 8078: // Pn : PrintNum ( n ... )
00630			slog(PopNum());
00631			break;
00632		case 8083: // Ps : PrintString ( s ... )
00633			slog(ParseString(PopNum()));
00634			break;
00635		default:
00636			log("Bad TokWord case");
00637		}
00638	}
00639	
00640	function WordEvent()
00641	{
00642		local name evName;
00643	
00644		evName = name(ParseString(PopNum()));
00645		if(evName != '')
00646			foreach AllActors(class 'Actor', Target, evName)
00647				Target.Trigger(self, none);
00648	}
00649	
00650	// STATES /////////////////////////////////////////////////////////////////////
00651	
00652	//-----------------------------------------------------------------------------
00653	// CheckAutoStart.
00654	//-----------------------------------------------------------------------------
00655	auto state CheckAutoStart
00656	{
00657	begin:
00658		if(bAutoStart)
00659		{
00660			InitCodeString(CodeString);
00661			GotoState('Interpret');
00662		}
00663		else
00664			GotoState('');
00665	}
00666	
00667	//-----------------------------------------------------------------------------
00668	// Interpret.
00669	//-----------------------------------------------------------------------------
00670	state Interpret
00671	{
00672	
00673	begin:
00674		MainParse();
00675		switch(NextInterpAction)
00676		{
00677		case IA_Sleep:
00678			Sleep(SleepDuration);
00679			goto 'begin';
00680		case IA_Stop:
00681			GotoState('');
00682		}
00683		goto 'begin';
00684	}
00685	
00686	defaultproperties
00687	{
00688	}

End Source Code