ot_kywrd.cpp

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

CPP
1,004
字号
// OT_KYWRD.CPP
//
// Copyright (c) 1997-2001 Symbian Ltd. All rights reserved.

#include "ot_std.h"

// Some useful numbers
const TInt KDefaultQualifier=0;

const TUint KPcPrintSpaceDelta=1;	// e.g. TOplKeyword::ELprintspace=TOplKeyword::ELprint+1
const TUint KPcPrintCrLfDelta=2;	//      TOplKeyword::ELprintspace=TOplKeyword::ELprint+2

//////////////////////////////////////////////////////////////////////////////
//
// COplParserBase
//
/////////////////////////////////////////////////////////////////////////////
void COplParserBase::PCodeCommandL(TOplKeyword::TCode aKeyword)
//
//
//
	{
	PCodeL(TPcode::ECommand);
	iCode<<aKeyword;
	}


//////////////////////////////////////////////////////////////////////////////
//
// COplModuleParser
//
/////////////////////////////////////////////////////////////////////////////
void COplModuleParser::KeywordStatementL()
//
// Have just lexed the start of a keyword statement.
// This just does a massive switch on the Parse Code for the keyword
//
	
	{
	
	TOplKeyword keyword=Lexer().Keyword();
	
	// Take care of TRAP statements as a special case - saves a recursion
	TBool isTrapped=EFalse;
	if (keyword.Code()==TOplKeyword::ETrap)
		{
		MustBeL(TOplToken::EKeywordToken); // Must be followed by a keyword
		keyword=Lexer().Keyword();
		if (!keyword.IsTrappable())
			SyntaxErrorL();
		isTrapped=ETrue;
		}

	// In most cases the switch just deals with arguments etc and then
	// we add the qcode at the end. However, in cases like PRINT we put out
	// the qcode within the switch statement itself in which case addQcode is set to EFalse.
	TBool addQcode=ETrue;
	
	TBool addQualifier=EFalse; // Some codes have a qualifier - usually to indicate 
	TInt32 qualifier=KDefaultQualifier; // how many optional arguments are on the stack
	
	TBool typeModified=EFalse; // Some things are type qualified 
	TOplToken::TType typeModifier=TOplToken::EBadType; // This is set to the type

	switch (keyword.Code())
		{
		// No Arguments
		case TOplKeyword::EAppend:		// APPEND
		case TOplKeyword::EBack:		// BACK
		case TOplKeyword::ECachetidy:	// CACHETIDY
		case TOplKeyword::EClose:		// CLOSE
		case TOplKeyword::ECls:			// CLS
		case TOplKeyword::EErase:		// ERASE
		case TOplKeyword::EFirst:		// FIRST
		case TOplKeyword::EGcls:		// GCLS
		case TOplKeyword::EIosignal:	// IOSIGNAL
		case TOplKeyword::EIoyield:		// IOYIELD
		case TOplKeyword::ELast:		// LAST
		case TOplKeyword::ELclose:		// LCLOSE
		case TOplKeyword::EMinit:		// MINIT
		case TOplKeyword::ENext:		// NEXT
		case TOplKeyword::EStop:		// STOP
		case TOplKeyword::EUpdate:		// UPDATE
		case TOplKeyword::EModify:		// MODIFY
		case TOplKeyword::EInsert:		// INSERT
		case TOplKeyword::ECancel:		// CANCEL
		case TOplKeyword::EPut:			// PUT
		case TOplKeyword::EBeginTrans:	// BEGINTRANS
		case TOplKeyword::ECommitTrans:	// COMMITTRANS
		case TOplKeyword::ERollBack:	// ROLLBACK
		case TOplKeyword::EShowHelp:	// SHOWHELP
			break;
		
		// 1 Word
		case TOplKeyword::ECachehdr:	// CACHEHDR addr(rec%)
		case TOplKeyword::EClosesprite: // CLOSESPRITE id%
		case TOplKeyword::EDefaultwin:	// DEFAULTWIN id%
		case TOplKeyword::EDiampos:		// DIAMPOS pos%
		case TOplKeyword::EGclose:		// GClose id%
		case TOplKeyword::EGgmode:		// GMODE mode%
		case TOplKeyword::EGgrey:		// GGREY mode%
		case TOplKeyword::EGstyle:		// GSTYLE style%
		case TOplKeyword::EGtmode:		// GTMODE mode%
		case TOplKeyword::EGunloadfont: // GUNLOADFONT fontid%
		case TOplKeyword::EGuse:		// GUSE id%
		case TOplKeyword::ELinklib:		// LINKLIB cat%
		case TOplKeyword::EPause:		// PAUSE time%
		case TOplKeyword::EPosition:	// POSITION pos%
		case TOplKeyword::ERaise:		// RAISE err%
		case TOplKeyword::EStyle:		// STYLE style%
		case TOplKeyword::EUsesprite:	// USESPRITE id%
		case TOplKeyword::EGotoMark:    // GOTOBOOKMARK mark%
		case TOplKeyword::EKillMark:	// KILLBOOKMARK mark%
		case TOplKeyword::EgSetPenWidth:// gSetPenWidth width%

			WordExpressionL();
			break;

		// 1 Word and 1 optional word
		case TOplKeyword::EGcircle:		// gCIRCLE radius%[,fill%]
			addQualifier=ETrue;
			WordExpressionL();
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionL();
				}
			break;

		// 2 Words
		case TOplKeyword::EAt:			// AT x%,y%
		case TOplKeyword::EBeep:		// BEEP time%, pitch%
		case TOplKeyword::ECacherec:	// CACHEREC addr(rec%), offset%
		case TOplKeyword::EDposition:	// DPOSITION x%, y%
		case TOplKeyword::EDrawsprite:	// DRAWSPRITE x%, y%
		case TOplKeyword::EGat:			// GAT x%, y%
		case TOplKeyword::EGbox:		// GBOX width%, height%
		case TOplKeyword::EGinvert:		// GINVERT width%, height%
		case TOplKeyword::EGlineby:		// GLINEBY dx%, dy%
		case TOplKeyword::EGlineto:		// GLINETO x%, y%
		case TOplKeyword::EGmove:		// GMOVE dx%, dy%
		case TOplKeyword::EGorder:		// GORDER id%, position%
		case TOplKeyword::EPossprite:	// POSSPRITE x%, y%
		case TOplKeyword::EPointerFilter: // POINTERFILTER filter%,mask%
			WordExpressionsL(2);
			break;

		// 2 Words and 1 optional Word
		case TOplKeyword::EGellipse:	// gELLIPSE radiusx%,radiusy%[,fill%]
			addQualifier=ETrue;
			WordExpressionsL(2);
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionL();
				}
			break;
		
		// 3 Words
		case TOplKeyword::EGcolor:		// GCOLOR red%,green%,blue%
		case TOplKeyword::EGcolorbackground:		// GCOLORBACKGROUND red%,green%,blue%
		case TOplKeyword::EGfill:		// GFILL width%, height%, gMode%
			WordExpressionsL(3);
			break;
		
		// 4 Words
		case TOplKeyword::EGdrawobject: // GDRAWOBJECT type%, flags%, w%, h%
		case TOplKeyword::EGpatt:
			WordExpressionsL(4);
			break;
		
		// 6 Words
		case TOplKeyword::EGcopy:		// GCOPY id%, x%, y%, w%, h%, mode%
			WordExpressionsL(6);
			break;
		
		case TOplKeyword::EFreealloc:	// FREEALLOC pCell& (was FREEALLOC pCell% on Opl1993)
		case TOplKeyword::EGfont:		// GFONT font& (was GFONT font% on Opl1993)
			NativeExpressionL();
			break;

        // 1 Long
		case TOplKeyword::ESetflags:	// SETFLAGS flags&
		case TOplKeyword::EClearflags:	// CLEARFLAGS flags&
			LongExpressionL();
			break;
		
		// 1 Native (word or long), 1 word
		case TOplKeyword::EFont:		// FONT id&, style% (hp: was FONT id%,style% on Opl1993)
			NativeExpressionL();
			CommaL();
			WordExpressionL();
			break;
	
        case TOplKeyword::EGbutton:		// GBUTTON text$, type%, w%, h%, st%[, bitMapId& [,maskId&[,layout%]]]
			StringExpressionL();
			CommaL();
			WordExpressionsL(4);
			if (!TargetIsOpl1993())
				{
				addQualifier=ETrue;
				if (NextIsCommaL())
					{
					LongExpressionL();	// bitMapId& (CFbsBitmap*)
					++qualifier;
					if (NextIsCommaL())
						{
						LongExpressionL();	// maskId&
						++qualifier;
						}
						if (NextIsCommaL())
							{
							WordExpressionL();	// layout%
							++qualifier;
							}
					}
				}
			break;
		
		case TOplKeyword::EChangesprite:// CHANGESPRITE ix%, tenths%, var bitmap$(),[dx%, dy%]
			// ix%
			WordExpressionL();
			CommaL();
		case TOplKeyword::EAppendsprite:// APPENDSPRITE tenths%,var bitmap$()[,dx%,dy%]
			addQualifier=ETrue;
			WordExpressionL(); // tenths%
			CommaL();
			Lexer().Mark(); // var bitmap$	
			MustBeL(TOplToken::EArray);
			if (Lexer().Type()!=TOplToken::EString)
				TypeMismatchL();
			MustBeL(TOplToken::ECloseBracket);
			Lexer().UnGetToMark();
			LeftSideReferenceL(NextL(),ESupplyIndices);			
			if (NextIsCommaL()) // [,dx%,dy%]
				{
				qualifier++;
				WordExpressionsL(2);
				}
			break;

		case TOplKeyword::EBreak:
		case TOplKeyword::EContinue:
			addQcode=EFalse;
			if (!iBranches.InLoop())
				User::Leave(EErrStructure);
			DoBranchL(keyword.Code()==TOplKeyword::EBreak ? TBranches::EBreak : TBranches::EContinue,
				TPcode::EBranchAlways);
			break;
		
		case TOplKeyword::EBusy:		// BUSY OFF|str$[,c%[,delay%]]
			addQualifier=ETrue;
			if (!NextIsOffL())
				{
				StringExpressionL();
				++qualifier;
				while (NextIsCommaL())
					{
					if (++qualifier>3) // too many args
						SyntaxErrorL();
					WordExpressionL();
					}
				}
			break;
		
		case TOplKeyword::ECache:		// CACHE ON | OFF | init%,max%
			addQualifier=ETrue;
			if (!NextIsOffOrOnL(qualifier))
				{
				qualifier++;
				WordExpressionsL(2);
				}
			break;
		
/*		case TOplKeyword::EDCheckBox:		// DCHECKBOX var choice%,p$
			IdentifierRefL(TOplToken::EWord);
			CommaL();
			StringExpressionL();
			break;
*/
		case TOplKeyword::EDeditMulti:		// dEditMulti ptrData&,prompt$,length%,numberOfLines%,maxLength&[,ReadOnly%]
			addQualifier=ETrue;
			LongExpressionL();
			CommaL();
			StringExpressionL();
			CommaL();
			WordExpressionL();
			CommaL();
			WordExpressionL();
			CommaL();
			LongExpressionL();
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionL();
				}
			break;

		case TOplKeyword::EDchoice:			// dCHOICE var choice%,p$,list$[,IncrementalMatching%]
			addQualifier=ETrue;
			IdentifierRefL(TOplToken::EWord);
			CommaL();
			StringExpressionL();
			CommaL();
			StringExpressionL();
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionL();
				}
			break;

		// 2 strings - fall-through is intentional
		case TOplKeyword::ECompress:	// COMPRESS src$, dest$
		case TOplKeyword::ECopy:		// COPY src$, dest$
		case TOplKeyword::ERename:
			StringExpressionL();
			CommaL();
		// 1 String
		case TOplKeyword::ECompact:		// COMPACT name$
		case TOplKeyword::ELoadm:		// LOADM module$
		case TOplKeyword::ELopen:		// LOPEN device$
		case TOplKeyword::EMkdir:		// MKDIR name$
		case TOplKeyword::ERmdir:		// RMDIR name$
		case TOplKeyword::ESetname:		// SETNAME name$
		case TOplKeyword::ESetdoc:		// SETDOC name$
		case TOplKeyword::ESetpath:		// SETPATH name$
		case TOplKeyword::EUnloadm:		// UNLOADM module$
			StringExpressionL();
			break;
		case TOplKeyword::EDelete:		// DELETE filename$[,table$]
			StringExpressionL();
			if (!(iTarget&(KOplTargetOpl1993))) // Not on OPL1993 machines
				{
				if (NextIsCommaL()) // Looks like delete table
					{
					StringExpressionL();
					keyword.SetCode(TOplKeyword::EDeleteTable);
					}
				}
			break;
		
		case TOplKeyword::ECreate:		// CREATE file$,log,f1$,..
		case TOplKeyword::EOpen:		// OPEN file$,log,f1$,..
		case TOplKeyword::EOpenr:		// OPENR file$,log,f1$,..
			{
			addQcode=EFalse;
			StringExpressionL();
			CommaL();
			if (isTrapped)
				PCodeCommandL(TOplKeyword::ETrap);
			PCodeL(TPcode::EQualifiedCommand);
			iCode<<keyword.Code()<<TUint8(LogicalDeviceL());
			CommaL();
			TUint fieldCount=0;
			do
				{
				if (fieldCount==KOplMaxFieldCount)
					User::Leave(EErrBadFieldList);
				if (!NextIsL(TOplToken::ESimple))
					User::Leave(EErrBadFieldName);
				PCodeL(TPcode::EFieldName);
				iCode<<Lexer().Type()<<Lexer().Name();
				fieldCount++;
				} while (NextIsCommaL());
			PCodeL(TPcode::EEndFieldList);
			}		
			break;
		case TOplKeyword::ECursor:		// CURSOR OFF | ON | id%[,asc%,w%,h%[,type%]]
			addQualifier=ETrue;
			if (!NextIsOffOrOnL(qualifier))
				{
				qualifier=CountWordExpressionsL(); // 1 4 or 5 OK
				switch (qualifier)
					{
					default:
						User::Leave(EErrFnArgument);
					case 1:
						qualifier=2; // ON is 1
						break;
					case 4:
						qualifier=3;
						break;
					case 5:
						qualifier=4;
						break;
					}
				}
			break;
		
		case TOplKeyword::EDtext:		// DTEXT p$, body$[, t%]
			StringExpressionL();
			CommaL();
		case TOplKeyword::EGiprint:		// GIPRINT str$[, c%]
			addQualifier=ETrue;	
			StringExpressionL();
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionL();
				}
			break;
		
		case TOplKeyword::EDdate:		// DDATE var dt&,p$,min&,max&
		case TOplKeyword::EDlong:		// DLONG var lg&,p$,min&,max& 
			NumericDialogItemL(TOplToken::ELong);
			break;
		
		case TOplKeyword::EDfloat:		// DFloat var fp,p$,min,max
			NumericDialogItemL(TOplToken::EReal);
			break;
		
		case TOplKeyword::EDtime:		// DTIME vat tim&,p$,t%,min&,max&
			IdentifierRefL(TOplToken::ELong);
			CommaL();
			StringExpressionL();
			CommaL();
			WordExpressionL();
			CommaL();
			LongExpressionL();
			CommaL();
		case TOplKeyword::ERandomize:	// RANDOMIZE seed&
			LongExpressionL();
			break;
		
		case TOplKeyword::EDedit:		// DEDIT var str$, p$[, len%]
			IdentifierRefL(TOplToken::EString);
			CommaL();
			StringExpressionL();
			if (NextIsCommaL())
				{
				keyword.SetCode(TOplKeyword::EDSedit); // for some reason this is a different item type 
				WordExpressionL();
				}
			break;
		
		case TOplKeyword::EDxinput:		// DXINPUT var str$, p$[,SeedTextContents%]
			addQualifier=ETrue;
			IdentifierRefL(TOplToken::EString);
			CommaL();
			StringExpressionL();
			if (NextIsCommaL())
				{
				qualifier++;
				WordExpressionL();
				}
			break;

		case TOplKeyword::EDfile:		// DFILE var str$, p$, f%[,uid1=0,uid2=0,uid3=0]
			IdentifierRefL(TOplToken::EString);
			CommaL();
			StringExpressionL();
			CommaL();
			WordExpressionL();
			if (!TargetIsOpl1993())
				{
				TInt uidCount=0;
				for (;NextIsCommaL();++uidCount)
					{
					if (uidCount==3)
						User::Leave(EErrSyntax);
					LongExpressionL();
					}
				if (uidCount && uidCount!=3)
					User::Leave(EErrMissingComma);
				while (++uidCount<=3)
					{
					PCodeL(TPcode::EConstant);
					iCode<<TOplConstant(TInt32(0));
					}
				}
			break;

		case TOplKeyword::EGxprint:		// GXPRINT string$, flags%
			StringExpressionL();
			CommaL();
			WordExpressionL();
			break;
		
		case TOplKeyword::ESetHelp:		// SETHELP location%, helpId$
			WordExpressionL();
			CommaL();
			StringExpressionL();
			break;

		case TOplKeyword::ESetHelpUid:	// SETHELPUID Uid&
			LongExpressionL();
			break;
		
		case TOplKeyword::EDbuttons:	// DBUTTONS p1$, k1%[, p2$, k2%[, p3$, k3%]]
			addQualifier=ETrue;
			do
				{
				StringExpressionL();
				CommaL();
				WordExpressionL();
				qualifier++;
				} while (qualifier<50 && NextIsCommaL());	// no reason for limit really
			break;
		
		case TOplKeyword::EDiaminit:	// DIAMINIT [pos%[,str1$[,str2$[,...]]]		
			addQualifier=ETrue;

⌨️ 快捷键说明

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