ot_kywrd.cpp

来自「在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己」· C++ 代码 · 共 1,004 行 · 第 1/2 页

CPP
1,004
字号
			if (!TestEosL())
				{
				qualifier++;
				WordExpressionL();
				while (NextIsCommaL())
					{
					qualifier++;
					StringExpressionL();
					}
				}
			break;
		
		case TOplKeyword::EDinits:		// DINITS [title$] - Only on Opl1994
		case TOplKeyword::EDinit:		// DINIT [title$] or DINIT title$[,flags%]
			addQualifier=ETrue;
			if (!TestEosL())
				{
				qualifier++;
				StringExpressionL();
				if (!TargetIsOpl1993())
					{
					if (NextIsCommaL())
						{
						qualifier++;
						WordExpressionL();
						}
					}
				}		
			break;
		
		case TOplKeyword::EEdit:		// EDIT str$ | str$(index) | a.str$
		case TOplKeyword::EInput:		// INPUT variable | field
			{
			TOplToken next=NextL();
			typeModifier=Lexer().Type();
			if (((next!=TOplToken::ESimple) && (next!=TOplToken::EArray) && (next!=TOplToken::EField))
				 || ((keyword.Code()==TOplKeyword::EEdit) && (typeModifier!=TOplToken::EString)))
				SyntaxErrorL();
			LeftSideReferenceL(next,EForceIndices);
			if (keyword.Code()==TOplKeyword::EInput)
				typeModified=ETrue;
			}
			break;
		
		// OFF | ON
		case TOplKeyword::EGvisible:	// GVISIBLE OFF | ON
		case TOplKeyword::EEscape:		// ESCAPE OFF | ON
		case TOplKeyword::ELock:
			addQualifier=ETrue;
			if (!NextIsOffOrOnL(qualifier))
				SyntaxErrorL();
			break;

		case TOplKeyword::EGborder:		// gBORDER flags%[, widths%, height%]
			addQualifier=ETrue;
			qualifier=CountWordExpressionsL();
			if ((qualifier!=1) && (qualifier !=3))
				SyntaxErrorL();
			break;

		case TOplKeyword::EGclock:		// GCLOCK OFF | ON [,mode%[,offset%[,format$,[font&[,style%]]]]]
			addQualifier=ETrue;
			if (!NextIsOffOrOnL(qualifier))
				SyntaxErrorL();
			if (qualifier!=0) // ON
				{
				if (NextIsCommaL())
					{
					qualifier++;
					WordExpressionL(); // mode%
					if (NextIsCommaL())
						{
						qualifier++;
						NativeExpressionL(); // offset& (was offset% on Opl1993)
						if (NextIsCommaL())
							{
							qualifier++;
							StringExpressionL(); // format$
							if (NextIsCommaL())
								{
								qualifier++;
								NativeExpressionL(); // font& (was font% on Opl1993)
								if (NextIsCommaL())
									{
									qualifier++;
									WordExpressionL(); // style%
									}
								}
							}
						}
					}
				}
			break;
		
		// var a%()
		case TOplKeyword::EGetevent:	// GETEVENT var a%()
		case TOplKeyword::EGinfo:		// GINFO var i%()
		case TOplKeyword::EGpoly:		// GPOLY l%()
		case TOplKeyword::EOdbinfo:		// ODBINFO var info%()
		case TOplKeyword::EScreeninfo:
			WordArrayRefL();
			break;

		// var int%, var a&()
		case TOplKeyword::EGeteventa32:	// GETEVENTA32 var stat%, var a&()
			ArgumentByRefL(TOplToken::EWord);
			CommaL();
			// drop through to var a&()
		// var a&()
		case TOplKeyword::EGetevent32:	// GETEVENT32 var a&()
		case TOplKeyword::EGinfo32:		// GINFO32 var i&()
		case TOplKeyword::EGcolorinfo:	// GCOLORINFO var i&()
			LongArrayRefL();
			break;


		case TOplKeyword::EGoto:		// GOTO label[::]
			addQcode=EFalse;	// BackEnd().BranchL deals with it.
			PCodeL(TPcode::EBranchAlways);
			LabelReferenceL();
			break;

		case TOplKeyword::EGpeekline:   // GPEEKLINE ix%, x%, y%, %(), ln%[,mode%=-1 (for opler1)]
			WordExpressionsL(3);// ix%, x%, y%
			CommaL();               
			WordArrayRefL();
			CommaL();
			WordExpressionL();      // ln%
			if (!TargetIsOpl1993())
				{
				if (NextIsCommaL())
					WordExpressionL();
				else
					{
					PCodeL(TPcode::EConstant);
					iCode<<TOplConstant(TInt16(-1));
					}
				}
			break;


		// These codes are followed immediately by their PrintSpace & PrintCrLf
		// variants & we rely on this.
		// NOTE PcGrint has no PrintCrLf variant 
		case TOplKeyword::EGprint:
		case TOplKeyword::ELprint:
		case TOplKeyword::EPrint: // PRINT  |  { PRINT expr [{;|,} expr]* [;|,]}
			{ 
			addQcode=EFalse;			
			TOplToken punctuator=TOplToken::EEos;
			while (!TestEosL())
				{
				TOplToken::TType type=ExpressionL();
				PCodeTypedCommandL(keyword.Code(),type);
		
				// Check for punctuation
				punctuator=NextL();
				if ((punctuator!=TOplToken::EComma) && (punctuator!=TOplToken::ESemiColon))
					{
					if (!IsEos(punctuator))  // E.g. PRINT x% y% as opposed to PRINT x% Eos
						SyntaxErrorL();
					Lexer().UnLex(); // Put back Eos
					}
				else if (punctuator==TOplToken::EComma)
					PCodeCommandL(TOplKeyword::TCode(keyword.Code()+KPcPrintSpaceDelta)); // PrintSpace variant
				}
			
			// By here punctuator is ;|,|Eos. For Eos add CrLf where allowed
			if (keyword.Code()!=TOplKeyword::EGprint && IsEos(punctuator))
				PCodeCommandL(TOplKeyword::TCode(keyword.Code()+KPcPrintCrLfDelta));
			}
			break;

		case TOplKeyword::EGprintb:		// GPRINTB t$,w%[,a1%[,tp%[,bt%[,m%]]]]
			addQualifier=ETrue;
			StringExpressionL();
			CommaL();
			qualifier=CountWordExpressionsL();
			if (qualifier>5)
				SyntaxErrorL();
			break;

		case TOplKeyword::EGsavebit:	// GSAVEBIT name$[, width%, height%]
			addQualifier=ETrue;
			StringExpressionL();
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionsL(2);
				}
			break;

		case TOplKeyword::EGscroll:		// GSCROLL dx%, dy%[, x%, y%, dx%, dy%]
			addQualifier=ETrue;
			WordExpressionsL(qualifier=2);
			if (NextIsCommaL())
				{
				qualifier=6;
				WordExpressionsL(4);
				}			
			break;

		case TOplKeyword::EGsetwin:		// GSETWIN x%, y%[, width%, height %]
		case TOplKeyword::EGxborder:	// GXBORDER type%, flags%[,w%, h%]
			addQualifier=ETrue;
			WordExpressionsL(qualifier=2);
			if (NextIsCommaL())
				{
				qualifier=4;
				WordExpressionsL(2);
				}
			break;

		case TOplKeyword::EGupdate:		// GUPDATE [OFF | ON]
			addQualifier=ETrue;
			if (!NextIsOffOrOnL(qualifier))
				qualifier=(-1);
			break;

		case TOplKeyword::EIowaitstat:	// IOWAITSTAT var status%
			ArgumentByRefL(TOplToken::EWord);
			break;

		case TOplKeyword::EIowaitstat32:	// IOWAITSTAT32 var status&
			ArgumentByRefL(TOplToken::ELong);
			break;

		case TOplKeyword::EMcard:		// MCARD title$[,n$,k%]+
		case TOplKeyword::EMcasc:		// MCASC cascId$[,n$,k%]+
			addQualifier=ETrue;
			StringExpressionL();
			CommaL();
			FOREVER
				{
				StringExpressionL();
				CommaL();
				WordExpressionL();
				qualifier++;
				if (!NextIsCommaL())
					break;
				}
			break;

		case TOplKeyword::EMcardX:		// MCARDX bitmapId%,maskId%[,n$,k%]+
			addQualifier=ETrue;
			WordExpressionL();
			CommaL();
			WordExpressionL();
			CommaL();
			FOREVER
				{
				StringExpressionL();
				CommaL();
				WordExpressionL();
				qualifier++;
				if (!NextIsCommaL())
					break;
				}
			break;

		case TOplKeyword::EOff:			// OFF [time%]
			if (!TestEosL()) 
				{
				keyword.SetCode(TOplKeyword::EOffTime);
				WordExpressionL();
				}
			break;
		
		case TOplKeyword::EOnerr:
			{
			addQcode=EFalse;
			PCodeL(TPcode::EOnErr);
			if (NextIsOffL())
				iCode<<(COplSymbol *)NULL;
			else
				LabelReferenceL();
			}			
			break;

		// NOTE THIS RELIES ON THE VALUES OF THE TYPES - SET IN OPLTOKEN.H
		case TOplKeyword::EPokes:		// POKE$ addr&, val$  (was addr% on Opl1993)
			qualifier++;
		case TOplKeyword::EPokef:		// POKEF addr&, val
			qualifier++;
		case TOplKeyword::EPokel:		// POKEL addr&, val&
			qualifier++;
		case TOplKeyword::EPokew:		// POKEW addr&, val%
		case TOplKeyword::EPokeb:		// POKEB addr&, val%
			ExpressionL(UnsignedNativeType());
			CommaL();
			ExpressionL(TOplToken::TType(qualifier));
			break;
		
		case TOplKeyword::EReturnValue:
			{
			iLastWasReturn=ETrue; // If this is the last statment then don't need to add default return
			typeModifier=iProcHeader->Type();
			if (TestEosL())
				{
				typeModified=ETrue;
				keyword.SetCode(TOplKeyword::EReturnNull);
				}
			else
				ExpressionL(typeModifier);
			break;
			}
		case TOplKeyword::EScreen:		// SCREEN x%, y%[, width%, height%]
			WordExpressionsL(2);
			if (NextIsCommaL())
				{
				keyword.SetCode(TOplKeyword::EGscreen);
				WordExpressionsL(2);
				}
			break;

		case TOplKeyword::EDaysToDate:		// DAYSTODATE d&[, var v%]3
			LongExpressionL();
			for (qualifier=3;qualifier;qualifier--)
				{
				CommaL();
				ArgumentByRefL(TOplToken::EWord);
				}
			break;

		case TOplKeyword::ESecstodate:		// SECSTODATE s&[, var v%]7
			LongExpressionL();
			for (qualifier=7;qualifier;qualifier--)
				{
				CommaL();
				ArgumentByRefL(TOplToken::EWord);
				}
			break;

		case TOplKeyword::EStatuswin:	// STATUSWIN OFF | ON[,type%]
			addQualifier=ETrue;
			if (!NextIsOffOrOnL(qualifier))
				SyntaxErrorL();
			if (qualifier!=0 && NextIsCommaL()) // [, type%] 
				{
				qualifier++;
				WordExpressionL();
				}
			break;
		case TOplKeyword::EUse:
			addQualifier=ETrue;
			qualifier=LogicalDeviceL();
			break;

		default:
		// None of the following can be obtained from the input token stream
		// They are modified cases of the 'reguler' ParseCodes.
		case TOplKeyword::EDSedit:
		case TOplKeyword::EGprintspace:
		case TOplKeyword::ELprintspace:
		case TOplKeyword::ELprintcrlf:
		case TOplKeyword::EPrintspace: 
		case TOplKeyword::EPrintcrlf:
		case TOplKeyword::EReturnNull:
		case TOplKeyword::EGscreen:
		case TOplKeyword::ETrap:		// This should have been picked out before the switch
			break;
		}
	
	// For vanilla cases we put out the qcode here	
	if (addQcode)
		{
		if (isTrapped)
			PCodeCommandL(TOplKeyword::ETrap);
		
		__ASSERT_ALWAYS(!(addQualifier && typeModified),Panic(EOpltKeywordTypedAndQualified));

		if (addQualifier)
			{
			PCodeL(TPcode::EQualifiedCommand);
			iCode<<keyword.Code()<<TUint8(qualifier);
			}
		else if (typeModified)
			PCodeTypedCommandL(keyword.Code(),typeModifier);
		else
			PCodeCommandL(keyword.Code());
		}
	}


void COplModuleParser::NumericDialogItemL(TOplToken::TType aType)
//
// e.g DLong var lg&, p$, min&, max&
//
	{
	IdentifierRefL(aType);
	CommaL();
	StringExpressionL(); // prompt$
	CommaL();
	ExpressionL(aType); // min
	CommaL();
	ExpressionL(aType); // max
	}

TUint COplModuleParser::CountWordExpressionsL()
//
// Parses comma separated word expressions while it can
//
	{
	
	TUint count=0;
	do
		{
		WordExpressionL();
		count++;
		} while (NextIsCommaL());
	return count;
	}

#pragma warning (disable:4706) // assignment within conditional expression
void COplModuleParser::WordExpressionsL(TInt aCount)
//
// Parses out aCount comma separated word expressions
// (count>=2)
	{
	FOREVER
		{
		WordExpressionL();
		if (!--aCount)
			break;
		CommaL();
		}
	}
#pragma warning (default:4706) 

TOplField::TDevice COplModuleParser::LogicalDeviceL()
//
// A logical device is A-D, i.e. a simple real identifier
// of length 1
//
	{
	MustBeL(TOplToken::ESimple);
	if (Lexer().Type()!=TOplToken::EReal || Lexer().Name().Length()!=1)
		User::Leave(EErrBadLogicalDevice);
	TUint device=Lexer().Name()[0]-'A';
	Lexer().CheckDeviceL(device);
	return TOplField::TDevice(device);
	}

void COplModuleParser::IdentifierRefL(TOplToken::TType aType)
//
// Does a type-safe left side ref
//
	{
	TOplToken next=NextL();
	if (next.Class()!=TOplToken::EIdentifier)
		SyntaxErrorL();
	if (Lexer().Type()!=aType)
		TypeMismatchL();
	LeftSideReferenceL(next,ESupplyIndices);
	}

void COplModuleParser::ArrayRefL(TOplToken::TType aType)
//
// Parses a reference to an array
//
	{

	TOplToken next=NextL();
	if (next!=TOplToken::EHash && (next!=TOplToken::EArray || Lexer().Type()!=aType))
		SyntaxErrorL();
	Lexer().UnLex();
	ArgumentByRefL();
	}

void COplModuleParser::WordArrayRefL()
//
// Parses a reference to a word array
//
	{

	ArrayRefL(TOplToken::EWord);
/*
	TOplToken next=NextL();
	if (next!=TOplToken::EHash && (next!=TOplToken::EArray || Lexer().Type()!=TOplToken::EWord))
		SyntaxErrorL();
	Lexer().UnLex();
	ArgumentByRefL();
*/
	}

void COplModuleParser::LongArrayRefL()
//
// Parses a reference to a long integer array
//
	{
	ArrayRefL(TOplToken::ELong);
	}

void COplModuleParser::PCodeTypedCommandL(TOplKeyword::TCode aKeyword,TOplToken::TType aType)
//
// Puts out PCode for a typed keyword
//
	{
	
	PCodeL(TPcode::ETypedCommand);
	iCode<<aKeyword<<aType;
	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?