ot_struc.cpp
来自「在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己」· C++ 代码 · 共 289 行
CPP
289 行
// OT_STRUC.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
// IF, DO, WHILE & VECTOR structures
//
//
#include "ot_std.h"
////////////////////////////////////////////////////////////////////////////
//
// TBranches - Used to keep track of branches used by structural stuff
//
////////////////////////////////////////////////////////////////////////////
TUint TBranches::Branch(TBranch aBranch)
//
//
//
{
return iBranches[aBranch];
}
TUint TBranches::NewBranch(TBranch aBranch)
//
// Gets the next branch number and assigns it to the branch of
// the right type
//
{
return iBranches[aBranch]=iNextBranch++;
}
void TBranches::SaveBranchesL(TUint anArray[EMaxBranches])
//
// Squirrels away the branches before mucking with them and increments the depth
//
{
Mem::Copy(anArray,iBranches,sizeof(TUint)*EMaxBranches);
if (++iDepth>KOplMaxStructureDepth)
User::Leave(EErrTooComplex);
}
void TBranches::RestoreBranches(TUint anArray[EMaxBranches])
//
// Restores saved branches and reduces the depth
//
{
Mem::Copy(iBranches,anArray,sizeof(TUint)*EMaxBranches);
--iDepth;
}
//////////////////////////////////////////////////////////////////////////////////
//
// COplModParser - Module parser for structural stuff
//
//////////////////////////////////////////////////////////////////////////////////
COplSymbol *COplModuleParser::LabelSymbolL(const TDesC& aLabel)
//
// Check to see if aLabel has already been added. If not we add
// it as we assume this is a forward reference.
//
{
COplSymbol *pLabel=iSymbols->Find(aLabel,TOplToken::ELabel);
if (pLabel==NULL) // Not in the table yet
{
pLabel=COplDeclarationSymbol::NewLC(COplSymbol::ELabel,TOplToken::ELabel,TOplToken::EBadType,aLabel);
AddSymbolL(*pLabel);
CleanupStack::Pop();
}
return pLabel;
}
void COplModuleParser::DefineLabelL(const TDesC& aLabel)
//
// Defines a Label & notes the definition in the PCode
//
{
// May already have been added due to forward reference
COplLabelSymbol *pLabel=(COplLabelSymbol *)LabelSymbolL(aLabel);
// Check symbol for duplicate definition & mark definition seen
if (pLabel->IsDefined())
User::Leave(EErrDuplicateName);
pLabel->Define();
// And mark the definition the qcode
PCodeL(TPcode::ELabel);
iCode<<(COplSymbol*)pLabel;
}
void COplModuleParser::LabelReferenceL(TOplToken aToken)
//
// Parses a label reference
//
// label-reference := label || simple-id(real)
//
{
// Check it's OK
if ((aToken!=TOplToken::ELabel) && (aToken!=TOplToken::ESimple || Lexer().Type()!=TOplToken::EReal))
User::Leave(EErrMissingLabel);
// Add it to the PCode
iCode<<LabelSymbolL(Lexer().Name());
}
void COplModuleParser::LabelReferenceL()
//
// gets the next token and checks it out as being a good label reference
// syntacticly - carries no guarantees about the existence of teh label.
//
{
LabelReferenceL(NextL());
}
void COplModuleParser::NeedBranch(TBranches::TBranch aBranch)
//
// Says that we need a new branch of the passed type
//
{
iBranches.NewBranch(aBranch);
}
void COplModuleParser::BranchName(TBranches::TBranch aBranch,TDes& aLabel)
//
// Makes the unique text for an internal label of the form .nnn
// e.g. 0x010a would have text \.\00a\000\001
//
{
aLabel.Zero();
aLabel.Append(TChar('.')); // Illegal in OPL names
for (TUint branchNo=iBranches.Branch(aBranch);branchNo;branchNo>>=2)
aLabel.Append(TChar(branchNo&0xf));
}
void COplModuleParser::SetBranchL(TBranches::TBranch aBranch)
//
// Adds the appropriate label for this branch
//
{
TBuf<KOplMaxIdentifierLength> branchLabel;
BranchName(aBranch,branchLabel);
DefineLabelL(branchLabel);
}
void COplModuleParser::ConditionalExpressionL()
//
// Does the conditional expression and the branch
//
{
TOplToken::TType type=ExpressionL();
if (type==TOplToken::EString)
TypeMismatchL();
if (type!=TOplToken::EWord)
{
PCodeL(TPcode::EConstant);
if (type==TOplToken::ELong)
//iCode<<TOplConstant(TInt32(1));
iCode<<TOplConstant(TInt32(0));
else
//iCode<<TOplConstant(TReal64(1.0));
iCode<<TOplConstant(TReal64(0.0));
PCodeOperatorL(TOplToken::ENotEqual,TPcodeOperator::EBinary,type,TOplToken::EWord);
}
DoBranchL(TBranches::EFalse,TPcode::EBranchFalse);
}
void COplModuleParser::DoBranchL(TBranches::TBranch aBranch, TPcode::TCode aBranchCode)
//
// Adds a branch to an internal label
//
{
PCodeL(aBranchCode);
TBuf<KOplMaxIdentifierLength> branchLabel;
BranchName(aBranch,branchLabel);
iCode<<LabelSymbolL(branchLabel);
}
void COplModuleParser::StructureL(TOplToken aToken)
//
// Deals with IF, DO, WHILE & VECTOR structures.
// Basically LOTS of labels
//
//
// VectorStructure:=
//
{
TUint oldBranches[TBranches::EMaxBranches];
iBranches.SaveBranchesL(oldBranches);
switch (aToken)
{
case TOplToken::EVector: // VECTOR wordExpression Eos [label-lines]+ ENDV
{
// wordExpression EOS
WordExpressionL();
EosL();
PCodeL(TPcode::EVector);
// [label-line]+
TOplToken next=SkipBlankLinesL();
do // label-line := label-ref[,label-ref]* EOS
{
FOREVER
{
PCodeL(TPcode::EVectorLabel);
LabelReferenceL(next);
if (NextIsL(TOplToken::EEos))
break;
CommaL();
next=NextL();
}
next=SkipBlankLinesL();
} while (next!=TOplToken::EEndV);
PCodeL(TPcode::EEndVector);
break;
}
case TOplToken::EDo:
case TOplToken::EWhile:
{
iBranches.EnterLoop();
NeedBranch(TBranches::EContinue);
NeedBranch(TBranches::EBreak);
NeedBranch(TBranches::EFalse);
if (aToken==TOplToken::EDo) // DO statement-list UNTIL conditional-expr
{
SetBranchL(TBranches::EFalse);
if (StatementListL()!=TOplToken::EUntil)
User::Leave(EErrStructure);
SetBranchL(TBranches::EContinue);
ConditionalExpressionL();
SetBranchL(TBranches::EBreak);
}
else // WHILE conditional-expr statement-list ENDWH
{
SetBranchL(TBranches::EContinue);
ConditionalExpressionL();
if (StatementListL()!=TOplToken::EEndWh)
User::Leave(EErrStructure);
DoBranchL(TBranches::EContinue,TPcode::EBranchAlways);
SetBranchL(TBranches::EBreak);
SetBranchL(TBranches::EFalse);
}
iBranches.LeaveLoop();
break;
}
case TOplToken::EIf: // IF if-body [ELSEIF if-body]* [ELSE statement-list] ENDIF
{
TOplToken token;
NeedBranch(TBranches::EExit);
do // if-body := conditional-expr EOS statement-list
{
NeedBranch(TBranches::EFalse);
ConditionalExpressionL();
EosL();
token=StatementListL();
if (token!=TOplToken::EEndIf)
DoBranchL(TBranches::EExit,TPcode::EBranchAlways);
SetBranchL(TBranches::EFalse);
} while (token==TOplToken::EElseIf);
if (token==TOplToken::EElse) // [ELSE statment-list]
token=StatementListL();
if (token!=TOplToken::EEndIf) // ENDIF
User::Leave(EErrStructure);
SetBranchL(TBranches::EExit);
break;
}
default:
Panic(EOpltParserUnknownStructure);
}
iBranches.RestoreBranches(oldBranches);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?