ExprNode* ReadExpr (FILE* F, ObjData* O) /* Read an expression from the given file */ { ExprNode* Expr; /* Read the node tag and handle NULL nodes */ unsigned char Op = Read8 (F); if (Op == EXPR_NULL) { return 0; } /* Create a new node */ Expr = NewExprNode (O, Op); /* Check the tag and handle the different expression types */ if (EXPR_IS_LEAF (Op)) { switch (Op) { case EXPR_LITERAL: Expr->V.IVal = Read32Signed (F); break; case EXPR_SYMBOL: /* Read the import number */ Expr->V.ImpNum = ReadVar (F); break; case EXPR_SECTION: /* Read the section number */ Expr->V.SecNum = ReadVar (F); break; default: Error ("Invalid expression op: %02X", Op); } } else { /* Not a leaf node */ Expr->Left = ReadExpr (F, O); Expr->Right = ReadExpr (F, O); } /* Return the tree */ return Expr; }
Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; Export* E; /* Read the type */ unsigned char Type = Read8 (F); /* Read the address size */ unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = GET_EXP_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; unsigned I; /* Read the data into temp storage */ ReadData (F, ConDes, ConDesCount); /* Re-order the data. In the file, each decl is encoded into a byte * which contains the type and the priority. In memory, we will use * an array of types which contain the priority. This array was * cleared by the constructor (NewExport), so we must only set the * fields that contain values. */ for (I = 0; I < ConDesCount; ++I) { unsigned ConDesType = CD_GET_TYPE (ConDes[I]); unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]); E->ConDes[ConDesType] = ConDesPrio; } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (IS_EXP_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Last is the file position where the definition was done */ ReadFilePos (F, &E->Pos); /* Return the new export */ return E; }
boost::shared_ptr< AssignExpr > ReadAssignExpr( std::list< std::string > & tokens ) { //Match( tokens, "assign" ); std::string ident = MatchIdentifier( tokens ); Match( tokens, "=" ); boost::shared_ptr< Expr > expr = ReadExpr( tokens ); return boost::shared_ptr< AssignExpr >( new AssignExpr( ident, expr ) ); }
boost::shared_ptr< WhileExpr > ReadWhileExpr( std::list< std::string > & tokens ) { Match( tokens, "while" ); Match( tokens, "(" ); boost::shared_ptr< Expr > expr = ReadExpr( tokens ); Match( tokens, ")" ); Match( tokens, "{" ); ExprList exprlist = ReadExprList( tokens ); Match( tokens, "}" ); return boost::shared_ptr< WhileExpr >( new WhileExpr( expr, exprlist ) ); }
std::list< boost::shared_ptr< Expr > > ReadArgList( std::list< std::string > & tokens ) { boost::shared_ptr< Expr > expr = ReadExpr( tokens ); if( tokens.empty( ) ) { throw SyntaxError( "ReadArgList: unexpected end of token stream" ); } else if( tokens.front( ) == "," ) { Match( tokens, "," ); std::list< boost::shared_ptr< Expr > > arglist = ReadArgList( tokens ); arglist.push_front( expr ); return arglist; } else if( tokens.front( ) == ")" ) { return std::list< boost::shared_ptr< Expr > >( 1, expr ); } else { throw SyntaxError( "ReadArgList: unexpected token " + tokens.front( ) ); } }
void FQueryEvaluator::ReadExpr(FGameplayTagQueryExpression& E) { E.ExprType = (EGameplayTagQueryExprType::Type) GetToken(); if (bReadError) { return; } if (E.UsesTagSet()) { // parse tag set int32 NumTags = GetToken(); if (bReadError) { return; } for (int32 Idx = 0; Idx < NumTags; ++Idx) { int32 const TagIdx = GetToken(); if (bReadError) { return; } FGameplayTag Tag = Query.GetTagFromIndex(TagIdx); E.AddTag(Tag); } } else { // parse expr set int32 NumExprs = GetToken(); if (bReadError) { return; } for (int32 Idx = 0; Idx < NumExprs; ++Idx) { FGameplayTagQueryExpression Exp; ReadExpr(Exp); Exp.AddExpr(Exp); } } }
boost::shared_ptr< IfExpr > ReadIfExpr( std::list< std::string > & tokens ) { Match( tokens, "if" ); Match( tokens, "(" ); boost::shared_ptr< Expr > expr = ReadExpr( tokens ); Match( tokens, ")" ); Match( tokens, "{" ); ExprList trueexpr = ReadExprList( tokens ); Match( tokens, "}" ); Match( tokens, "else" ); Match( tokens, "{" ); ExprList falseexpr = ReadExprList( tokens ); Match( tokens, "}" ); return boost::shared_ptr< IfExpr >( new IfExpr( expr, trueexpr, falseexpr ) ); }
void FQueryEvaluator::Read(FGameplayTagQueryExpression& E) { E = FGameplayTagQueryExpression(); CurStreamIdx = 0; if (Query.QueryTokenStream.Num() > 0) { // start parsing the set Version = GetToken(); if (!bReadError) { uint8 const bHasRootExpression = GetToken(); if (!bReadError && bHasRootExpression) { ReadExpr(E); } } ensure(CurStreamIdx == Query.QueryTokenStream.Num()); } }
Assertion* ReadAssertion (FILE* F, struct ObjData* O) /* Read an assertion from the given file */ { /* Allocate memory */ Assertion* A = xmalloc (sizeof (Assertion)); /* Read the fields from the file */ A->LineInfos = EmptyCollection; A->Expr = ReadExpr (F, O); A->Action = (AssertAction) ReadVar (F); A->Msg = MakeGlobalStringId (O, ReadVar (F)); ReadLineInfoList (F, O, &A->LineInfos); /* Set remaining fields */ A->Obj = O; /* Add the assertion to the global list */ CollAppend (&Assertions, A); /* Return the new struct */ return A; }
ExprList ReadExprList( std::list< std::string > & tokens ) { if( tokens.empty( ) ) { return ExprList( ); } else { if( tokens.front( ) == "}" ) { return ExprList( ); } else { boost::shared_ptr< Expr > expr = ReadExpr( tokens ); if( tokens.empty( ) ) { throw SyntaxError( "ReadExprList: unexpected end of token stream" ); //return ExprList( expr ); } else if( tokens.front( ) == ";" ) { Match( tokens, ";" ); ExprList exprlist = ReadExprList( tokens ); exprlist.push_front( expr ); return exprlist; } else { throw SyntaxError( "ReadExprList: unexpected token " + tokens.front( ) ); } } } }
Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; unsigned I; Export* E; /* Read the type */ unsigned Type = ReadVar (F); /* Read the address size */ unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = SYM_GET_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; /* Read the data into temp storage */ ReadData (F, ConDes, ConDesCount); /* Re-order the data. In the file, each decl is encoded into a byte ** which contains the type and the priority. In memory, we will use ** an array of types which contain the priority. */ for (I = 0; I < ConDesCount; ++I) { E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]); } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (SYM_IS_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Read the size */ if (SYM_HAS_SIZE (Type)) { E->Size = ReadVar (F); } /* Last are the locations */ ReadLineInfoList (F, O, &E->DefLines); ReadLineInfoList (F, O, &E->RefLines); /* If this symbol is exported as a condes, and the condes type declares a ** forced import, add this import to the object module. */ for (I = 0; I < CD_TYPE_COUNT; ++I) { const ConDesImport* CDI; if (E->ConDes[I] != CD_PRIO_NONE && (CDI = ConDesGetImport (I)) != 0) { unsigned J; /* Generate a new import, and add it to the module's import list. */ Import* Imp = GenImport (CDI->Name, CDI->AddrSize); Imp->Obj = O; CollAppend (&O->Imports, Imp); /* Add line info for the export that is actually the condes that ** forces the import. Then, add line info for the config. file. ** The export's info is added first because the import pretends ** that it came from the object module instead of the config. file. */ for (J = 0; J < CollCount (&E->DefLines); ++J) { CollAppend (&Imp->RefLines, DupLineInfo (CollAt (&E->DefLines, J))); } CollAppend (&Imp->RefLines, GenLineInfo (&CDI->Pos)); } } /* Return the new export */ return E; }
Section* ReadSection (FILE* F, ObjData* O) /* Read a section from a file */ { unsigned Name; unsigned Size; unsigned long Alignment; unsigned char Type; unsigned FragCount; Segment* S; Section* Sec; /* Read the segment data */ (void) Read32 (F); /* File size of data */ Name = MakeGlobalStringId (O, ReadVar (F)); /* Segment name */ ReadVar (F); /* Segment flags (currently unused) */ Size = ReadVar (F); /* Size of data */ Alignment = ReadVar (F); /* Alignment */ Type = Read8 (F); /* Segment type */ FragCount = ReadVar (F); /* Number of fragments */ /* Print some data */ Print (stdout, 2, "Module '%s': Found segment '%s', size = %u, alignment = %lu, type = %u\n", GetObjFileName (O), GetString (Name), Size, Alignment, Type); /* Get the segment for this section */ S = GetSegment (Name, Type, GetObjFileName (O)); /* Allocate the section we will return later */ Sec = NewSection (S, Alignment, Type); /* Remember the object file this section was from */ Sec->Obj = O; /* Set up the combined segment alignment */ if (Sec->Alignment > 1) { Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment); if (Alignment > MAX_ALIGNMENT) { Error ("Combined alignment for segment '%s' is %lu which exceeds " "%lu. Last module requiring alignment was '%s'.", GetString (Name), Alignment, MAX_ALIGNMENT, GetObjFileName (O)); } else if (Alignment >= LARGE_ALIGNMENT) { Warning ("Combined alignment for segment '%s' is suspiciously " "large (%lu). Last module requiring alignment was '%s'.", GetString (Name), Alignment, GetObjFileName (O)); } S->Alignment = Alignment; } /* Start reading fragments from the file and insert them into the section . */ while (FragCount--) { Fragment* Frag; /* Read the fragment type */ unsigned char Type = Read8 (F); /* Extract the check mask from the type */ unsigned char Bytes = Type & FRAG_BYTEMASK; Type &= FRAG_TYPEMASK; /* Handle the different fragment types */ switch (Type) { case FRAG_LITERAL: Frag = NewFragment (Type, ReadVar (F), Sec); ReadData (F, Frag->LitBuf, Frag->Size); break; case FRAG_EXPR: case FRAG_SEXPR: Frag = NewFragment (Type, Bytes, Sec); Frag->Expr = ReadExpr (F, O); break; case FRAG_FILL: /* Will allocate memory, but we don't care... */ Frag = NewFragment (Type, ReadVar (F), Sec); break; default: Error ("Unknown fragment type in module '%s', segment '%s': %02X", GetObjFileName (O), GetString (S->Name), Type); /* NOTREACHED */ return 0; } /* Read the line infos into the list of the fragment */ ReadLineInfoList (F, O, &Frag->LineInfos); /* Remember the module we had this fragment from */ Frag->Obj = O; } /* Return the section */ return Sec; }