ot_ident.cpp

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

CPP
201 行
字号
// OT_IDENT.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include "ot_std.h"

/////////////////////////////////////////////////////////////////
//
// COplParserBase
//
/////////////////////////////////////////////////////////////////

void COplParserBase::IdentifierReferenceL(TOplToken aToken, TIndexFlag aFlag, TPcode::TIdentifierSide aSide)
//
//
//
	{

	switch (aToken)
		{
		case TOplToken::EArray:
		case TOplToken::ESimple:
			SimpleOrArrayRefL(aToken,aFlag, aSide);
			break;
		case TOplToken::EField:
			FieldReferenceL(aSide); // Virtual - Eval version just does syntax error
			break;
		case TOplToken::EConstant:
			if (aSide==TPcode::ELeft) // Constants have to be on the right hand side.
				SyntaxErrorL();
			ConstantReferenceL(Lexer().Constant());
			break;
#if defined (_DEBUG)
		default:
			Panic(EOpltUnknownIdentifier);
#endif
		}
	}

void COplParserBase::LeftSideReferenceL(TOplToken anIdent, TIndexFlag aFlag)
//
// Just a syntax error, should perhaps panic
//
	{
	
	IdentifierReferenceL(anIdent,aFlag,TPcode::ELeft);
	}


void COplParserBase::RightSideReferenceL(TOplToken anIdent)
//
// The only base RightSideReferences are constants
//
	{

	
	IdentifierReferenceL(anIdent,EForceIndices,TPcode::ERight);
	}

void COplParserBase::SimpleOrArrayRefL(TOplToken aToken,TIndexFlag aFlag,TPcode::TIdentifierSide aSide)
//
// Reference to a simple or array identifier - have lexed out the identifier
//
// SimpleOrArrayRef := simpleIdent
//					 | arrayIdent [index] ')'
//

	{
	
	// First see if it exists in the symbol table
	COplSymbol *pSym=iSymbols->Find(Lexer().Name(),aToken);
	
	// If it's not in the symbol table, this reference is also the 
	//      declaration of the symbol as an external.
	// Otherwise
	//      check to make sure that it's not already defined as a CONST.
	if (!pSym)
		{
		if (!pSym && iExplicitDefines) // The symbol should have been declared explicitly 
			User::Leave(EErrUndefinedVariable);
		pSym=NewSymbolL(COplSymbol::EExternalDecl);
		}
	else if (pSym->Class()==COplSymbol::EConstant)
		Panic(EOpltConstantSymbol);
	
	// If the symbol we see is an External Declaration then we have to add a reference 
	// to record the fact that it has actually been used in this procedure.
	// This is because it may have been explicity declared outside the
	// procedure scope.
	// In future, the reference will obscure the Declaration and will
	// result in the symbol getting an address in the procedure header.
	if (pSym->Class()==COplSymbol::EExternalDecl)
		pSym=ReferenceL(*pSym);

	// Can't get a left side reference to an argument
	COplSymbol::TClass symbolClass=pSym->Class();
	if (symbolClass==COplSymbol::EArgument && aSide==TPcode::ELeft)
		User::Leave(EErrArgNotReferencedByValue); // Can't assign to arguments

	// Array indices (forced or "au naturale").
	if (aToken==TOplToken::EArray) // arrayIdent [index] ')
		{
		if (NextIsL(TOplToken::ECloseBracket)) // [index] is missing
			{
			if (aFlag==EForceIndices) // Not allowed to miss them out
				User::Leave(EErrSubscript);

			PCodeL(TPcode::EConstant);
			iCode<<TOplConstant(KOplDefaultArrayIndex);
			}
		else
			{
			ExpressionL(TOplToken::EWord);
			if (!NextIsL(TOplToken::ECloseBracket))
				User::Leave(EErrSubscript);
			}
		}
	
	// Finally put out that PCode.
	PCodeL(IdentifierReferencePcode());
	iCode<<pSym<<aSide;
	}

void COplParserBase::ConstantReferenceL(const TOplConstant& aConstant)
//
//
//
	{
	PCodeL(TPcode::EConstant);
	iCode<<aConstant;
	}

////////////////////////////////////////////////////////////////
//
// COplModuleParser
//
/////////////////////////////////////////////////////////////////

void COplModuleParser::IdentifierStatementL(TOplToken aToken)
//
// IdentifierStatement := LeftSideRef '=' Expression
//
	{
	
	
	// So that we can check the sides match.
	TOplToken::TType type=Lexer().Type(); 
	
	// Parse it 
	LeftSideReferenceL(aToken,EForceIndices);	// LeftSideRef
	MustBeL(TOplToken::EEqual);					// =
	ExpressionL(type);							// Expression
	
	// Assignment Pcode.
	PCodeL(TPcode::EAssign);
	iCode<<type;
	}


TPcode::TCode COplModuleParser::IdentifierReferencePcode() const
//
// Pcode for an identifier reference. Different in the evaluator.
//
	{
	
	return TPcode::EIdentifier;
	}

void COplModuleParser::FieldReferenceL(TPcode::TIdentifierSide aSide)
//
// Reference to a field e.g. A.A$
//
	{
	
	PCodeL(TPcode::EField);
	iCode<<Lexer().Field()<<Lexer().Type()<<aSide;
	}


////////////////////////////////////////////////////////////////
//
// COplEvalParser
//
/////////////////////////////////////////////////////////////////
TPcode::TCode COplEvalParser::IdentifierReferencePcode() const
//
// PCode for an external reference during EVAL.
//
	{
	return TPcode::EEvalIdentifier;
	}

void COplEvalParser::FieldReferenceL(TPcode::TIdentifierSide /*aSide*/)
//
// Field references are not allowed in EVAL expressions
//
	{
	SyntaxErrorL();
	}

⌨️ 快捷键说明

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