2020-04-07 18:14:24 +00:00
# ifndef THINGDEF_EXP_H
# define THINGDEF_EXP_H
/*
* * thingdef_exp . h
* *
* * Expression evaluation
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2008 Christoph Oelckers
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* * 4. When not used as part of ZDoom or a ZDoom derivative , this code will be
* * covered by the terms of the GNU General Public License as published by
* * the Free Software Foundation ; either version 2 of the License , or ( at
* * your option ) any later version .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
# include "m_random.h"
# include "sc_man.h"
# include "s_soundinternal.h"
# include "vmbuilder.h"
# include "scopebarrier.h"
# include "types.h"
# include "vmintern.h"
# include "c_cvars.h"
2020-04-07 20:44:10 +00:00
struct FState ; // needed for FxConstant. Maybe move the state constructor to a subclass later?
2020-04-07 18:14:24 +00:00
# define CHECKRESOLVED() if (isresolved) return this; isresolved=true;
# define SAFE_DELETE(p) if (p!=NULL) { delete p; p=NULL; }
# define RESOLVE(p,c) if (p!=NULL) p = p->Resolve(c)
# define ABORT(p) if (!(p)) { delete this; return NULL; }
# define SAFE_RESOLVE(p,c) RESOLVE(p,c); ABORT(p)
# define SAFE_RESOLVE_OPT(p,c) if (p!=NULL) { SAFE_RESOLVE(p,c) }
class VMFunctionBuilder ;
class FxJumpStatement ;
extern FMemArena FxAlloc ;
//==========================================================================
//
//
//
//==========================================================================
struct FScriptPosition ;
class FxLoopStatement ;
class FxCompoundStatement ;
class FxLocalVariableDeclaration ;
typedef TDeletingArray < FxExpression * > FArgumentList ;
struct FCompileContext
{
FxExpression * ControlStmt = nullptr ;
FxLoopStatement * Loop = nullptr ;
FxCompoundStatement * Block = nullptr ;
PPrototype * ReturnProto ;
PFunction * Function ; // The function that is currently being compiled (or nullptr for constant evaluation.)
PContainerType * Class ; // The type of the owning class.
bool FromDecorate ; // DECORATE must silence some warnings and demote some errors.
int StateIndex ; // index in actor's state table for anonymous functions, otherwise -1 (not used by DECORATE which pre-resolves state indices)
int StateCount ; // amount of states an anoymous function is being used on (must be 1 for state indices to be allowed.)
int Lump ;
bool Unsafe = false ;
TDeletingArray < FxLocalVariableDeclaration * > FunctionArgs ;
PNamespace * CurGlobals ;
VersionInfo Version ;
FString VersionString ;
FCompileContext ( PNamespace * spc , PFunction * func , PPrototype * ret , bool fromdecorate , int stateindex , int statecount , int lump , const VersionInfo & ver ) ;
2022-08-03 12:13:42 +00:00
FCompileContext ( PNamespace * spc , PContainerType * cls , bool fromdecorate , const VersionInfo & ver ) ; // only to be used to resolve constants!
2020-04-07 18:14:24 +00:00
PSymbol * FindInClass ( FName identifier , PSymbolTable * & symt ) ;
PSymbol * FindInSelfClass ( FName identifier , PSymbolTable * & symt ) ;
PSymbol * FindGlobal ( FName identifier ) ;
void HandleJumps ( int token , FxExpression * handler ) ;
void CheckReturn ( PPrototype * proto , FScriptPosition & pos ) ;
2023-02-11 11:06:58 +00:00
bool IsWritable ( int flags , int checkFileNo = 0 ) ;
2020-04-07 18:14:24 +00:00
FxLocalVariableDeclaration * FindLocalVariable ( FName name ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
struct ExpVal
{
PType * Type ;
union
{
int Int ;
double Float ;
void * pointer ;
} ;
ExpVal ( )
{
Type = TypeSInt32 ;
Int = 0 ;
}
~ ExpVal ( )
{
if ( Type = = TypeString )
{
( ( FString * ) & pointer ) - > ~ FString ( ) ;
}
}
ExpVal ( const FString & str )
{
Type = TypeString ;
: : new ( & pointer ) FString ( str ) ;
}
ExpVal ( const ExpVal & o )
{
Type = o . Type ;
if ( o . Type = = TypeString )
{
: : new ( & pointer ) FString ( * ( FString * ) & o . pointer ) ;
}
else
{
memcpy ( & Float , & o . Float , 8 ) ;
}
}
ExpVal & operator = ( const ExpVal & o )
{
if ( Type = = TypeString )
{
( ( FString * ) & pointer ) - > ~ FString ( ) ;
}
Type = o . Type ;
if ( o . Type = = TypeString )
{
: : new ( & pointer ) FString ( * ( FString * ) & o . pointer ) ;
}
else
{
memcpy ( & Float , & o . Float , 8 ) ;
}
return * this ;
}
int GetInt ( ) const
{
int regtype = Type - > GetRegType ( ) ;
return regtype = = REGT_INT ? Int : regtype = = REGT_FLOAT ? int ( Float ) : 0 ;
}
unsigned GetUInt ( ) const
{
int regtype = Type - > GetRegType ( ) ;
return regtype = = REGT_INT ? unsigned ( Int ) : regtype = = REGT_FLOAT ? unsigned ( Float ) : 0 ;
}
double GetFloat ( ) const
{
int regtype = Type - > GetRegType ( ) ;
return regtype = = REGT_INT ? ( Type = = TypeUInt32 ? double ( unsigned ( Int ) ) : double ( Int ) ) : regtype = = REGT_FLOAT ? Float : 0 ;
}
void * GetPointer ( ) const
{
int regtype = Type - > GetRegType ( ) ;
return regtype = = REGT_POINTER ? pointer : nullptr ;
}
const FString GetString ( ) const
{
2020-05-23 13:18:10 +00:00
return Type = = TypeString ? * ( FString * ) & pointer : Type = = TypeName ? FString ( FName ( ENamedName ( Int ) ) . GetChars ( ) ) : FString ( ) ;
2020-04-07 18:14:24 +00:00
}
bool GetBool ( ) const
{
int regtype = Type - > GetRegType ( ) ;
return regtype = = REGT_INT ? ! ! Int : regtype = = REGT_FLOAT ? Float ! = 0. : false ;
}
2021-12-30 09:30:21 +00:00
2020-04-07 18:14:24 +00:00
FName GetName ( ) const
{
if ( Type = = TypeString )
{
if ( ( ( FString * ) & pointer ) - > Len ( ) = = 0 ) return NAME_None ;
return FName ( * ( FString * ) & pointer ) ;
}
return Type = = TypeName ? ENamedName ( Int ) : NAME_None ;
}
} ;
enum EFxType
{
EFX_Expression ,
EFX_Identifier ,
EFX_MemberIdentifier ,
EFX_ClassDefaults ,
EFX_Constant ,
EFX_BoolCast ,
EFX_IntCast ,
EFX_FloatCast ,
EFX_NameCast ,
EFX_StringCast ,
EFX_ColorCast ,
EFX_SoundCast ,
EFX_TypeCast ,
EFX_PlusSign ,
EFX_MinusSign ,
EFX_UnaryNotBitwise ,
EFX_UnaryNotBoolean ,
EFX_SizeAlign ,
EFX_PreIncrDecr ,
EFX_PostIncrDecr ,
EFX_Assign ,
EFX_AssignSelf ,
EFX_Binary , // one token fits all, the operator is enough to distinguish them.
EFX_BinaryLogical ,
EFX_DotCross ,
EFX_Conditional ,
EFX_Abs ,
EFX_ATan2 ,
2022-11-13 07:32:09 +00:00
EFX_ATan2Vec ,
2020-04-07 18:14:24 +00:00
EFX_New ,
EFX_MinMax ,
EFX_Random ,
EFX_RandomPick ,
EFX_FRandom ,
EFX_Random2 ,
EFX_ClassMember ,
EFX_StructMember ,
EFX_LocalVariable ,
EFX_Self ,
EFX_ArrayElement ,
EFX_FunctionCall ,
EFX_MemberFunctionCall ,
EFX_ActionSpecialCall ,
EFX_FlopFunctionCall ,
EFX_VMFunctionCall ,
EFX_Sequence ,
EFX_CompoundStatement ,
EFX_IfStatement ,
EFX_LoopStatement ,
EFX_WhileLoop ,
EFX_DoWhileLoop ,
EFX_ForLoop ,
2022-11-15 20:29:04 +00:00
EFX_ForEachLoop ,
2020-04-07 18:14:24 +00:00
EFX_JumpStatement ,
EFX_ReturnStatement ,
EFX_ClassTypeCast ,
EFX_ClassPtrCast ,
EFX_StateByIndex ,
EFX_RuntimeStateIndex ,
EFX_MultiNameState ,
EFX_DamageValue ,
EFX_Nop ,
EFX_LocalVariableDeclaration ,
EFX_SwitchStatement ,
EFX_CaseStatement ,
EFX_VectorValue ,
2022-11-13 07:32:09 +00:00
EFX_VectorPlusZ ,
2020-04-07 18:14:24 +00:00
EFX_VectorBuiltin ,
EFX_TypeCheck ,
EFX_DynamicCast ,
EFX_GlobalVariable ,
EFX_Super ,
EFX_StackVariable ,
EFX_MultiAssign ,
2023-01-07 18:30:49 +00:00
EFX_MultiAssignDecl ,
2020-04-07 18:14:24 +00:00
EFX_StaticArray ,
EFX_StaticArrayVariable ,
EFX_CVar ,
EFX_NamedNode ,
EFX_GetClass ,
EFX_GetParentClass ,
EFX_GetClassName ,
2021-02-26 18:06:10 +00:00
EFX_IsAbstract ,
2020-04-07 18:14:24 +00:00
EFX_StrLen ,
EFX_ColorLiteral ,
EFX_GetDefaultByType ,
EFX_FontCast ,
EFX_LocalArrayDeclaration ,
EFX_OutVarDereference ,
2022-11-13 07:32:09 +00:00
EFX_ToVector ,
2020-04-07 18:14:24 +00:00
EFX_COUNT
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxExpression
{
protected :
FxExpression ( EFxType type , const FScriptPosition & pos )
: ScriptPosition ( pos ) , ExprType ( type )
{
}
public :
virtual ~ FxExpression ( ) { }
virtual FxExpression * Resolve ( FCompileContext & ctx ) ;
2021-12-30 09:30:21 +00:00
2020-04-07 18:14:24 +00:00
virtual bool isConstant ( ) const ;
virtual bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
virtual PPrototype * ReturnProto ( ) ;
virtual VMFunction * GetDirectFunction ( PFunction * func , const VersionInfo & ver ) ;
virtual bool CheckReturn ( ) { return false ; }
virtual int GetBitValue ( ) { return - 1 ; }
bool IsNumeric ( ) const { return ValueType - > isNumeric ( ) ; }
bool IsFloat ( ) const { return ValueType - > isFloat ( ) ; }
bool IsInteger ( ) const { return ValueType - > isNumeric ( ) & & ValueType - > isIntCompatible ( ) ; }
bool IsPointer ( ) const { return ValueType - > isPointer ( ) ; }
2022-11-12 09:45:39 +00:00
bool IsVector ( ) const { return IsVector2 ( ) | | IsVector3 ( ) | | IsVector4 ( ) ; } ;
2022-06-25 08:39:49 +00:00
bool IsVector2 ( ) const { return ValueType = = TypeVector2 | | ValueType = = TypeFVector2 ; } ;
bool IsVector3 ( ) const { return ValueType = = TypeVector3 | | ValueType = = TypeFVector3 ; } ;
2022-11-12 09:45:39 +00:00
bool IsVector4 ( ) const { return ValueType = = TypeVector4 | | ValueType = = TypeFVector4 ; } ;
2022-11-24 15:56:46 +00:00
bool IsQuaternion ( ) const { return ValueType = = TypeQuaternion | | ValueType = = TypeFQuaternion | | ValueType = = TypeQuaternionStruct ; } ;
2020-04-07 18:14:24 +00:00
bool IsBoolCompat ( ) const { return ValueType - > isScalar ( ) ; }
bool IsObject ( ) const { return ValueType - > isObjectPointer ( ) ; }
2023-07-22 06:59:15 +00:00
bool IsArray ( ) const { return ValueType - > isArray ( ) | | ( ValueType - > isPointer ( ) & & ValueType - > toPointer ( ) - > PointedType & & ValueType - > toPointer ( ) - > PointedType - > isArray ( ) ) ; }
bool isStaticArray ( ) const { return ( ValueType - > isPointer ( ) & & ValueType - > toPointer ( ) - > PointedType & & ValueType - > toPointer ( ) - > PointedType - > isStaticArray ( ) ) ; } // can only exist in pointer form.
2020-04-07 18:14:24 +00:00
bool IsDynamicArray ( ) const { return ( ValueType - > isDynArray ( ) ) ; }
2022-12-04 15:51:44 +00:00
bool IsMap ( ) const { return ValueType - > isMap ( ) ; }
bool IsMapIterator ( ) const { return ValueType - > isMapIterator ( ) ; }
2022-11-15 20:29:04 +00:00
bool IsStruct ( ) const { return ValueType - > isStruct ( ) ; }
2020-04-07 18:14:24 +00:00
bool IsNativeStruct ( ) const { return ( ValueType - > isStruct ( ) & & static_cast < PStruct * > ( ValueType ) - > isNative ) ; }
virtual ExpEmit Emit ( VMFunctionBuilder * build ) ;
void EmitStatement ( VMFunctionBuilder * build ) ;
virtual void EmitCompare ( VMFunctionBuilder * build , bool invert , TArray < size_t > & patchspots_yes , TArray < size_t > & patchspots_no ) ;
FScriptPosition ScriptPosition ;
PType * ValueType = nullptr ;
bool isresolved = false ;
bool NeedResult = true ; // should be set to false if not needed and properly handled by all nodes for their subnodes to eliminate redundant code
EFxType ExprType ;
void * operator new ( size_t size )
{
return FxAlloc . Alloc ( size ) ;
}
void operator delete ( void * block ) { }
void operator delete [ ] ( void * block ) { }
} ;
//==========================================================================
//
// FxIdentifier
//
//==========================================================================
class FxIdentifier : public FxExpression
{
public :
FName Identifier = NAME_None ;
bool noglobal = false ;
FxIdentifier ( FName i , const FScriptPosition & p ) ;
FxExpression * Resolve ( FCompileContext & ) ;
FxExpression * ResolveMember ( FCompileContext & , PContainerType * , FxExpression * & , PContainerType * ) ;
} ;
//==========================================================================
//
// FxMemberIdentifier
//
//==========================================================================
class FxMemberIdentifier : public FxIdentifier
{
FxExpression * Object ;
public :
FxMemberIdentifier ( FxExpression * obj , FName i , const FScriptPosition & p ) ;
~ FxMemberIdentifier ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
} ;
//==========================================================================
//
// FxConstant
//
//==========================================================================
class FxConstant : public FxExpression
{
ExpVal value ;
public :
FxConstant ( bool val , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = value . Type = TypeBool ;
value . Int = val ;
isresolved = true ;
}
FxConstant ( int val , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = value . Type = TypeSInt32 ;
value . Int = val ;
isresolved = true ;
}
FxConstant ( unsigned int val , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = value . Type = TypeUInt32 ;
value . Int = val ;
isresolved = true ;
}
FxConstant ( double val , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = value . Type = TypeFloat64 ;
value . Float = val ;
isresolved = true ;
}
FxConstant ( FSoundID val , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = value . Type = TypeSound ;
2022-11-24 15:56:46 +00:00
value . Int = val . index ( ) ;
2020-04-07 18:14:24 +00:00
isresolved = true ;
}
FxConstant ( FName val , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = value . Type = TypeName ;
value . Int = val . GetIndex ( ) ;
isresolved = true ;
}
FxConstant ( const FString & str , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
ValueType = TypeString ;
value = ExpVal ( str ) ;
isresolved = true ;
}
FxConstant ( ExpVal cv , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
value = cv ;
ValueType = cv . Type ;
isresolved = true ;
}
FxConstant ( PClass * val , PClassPointer * valtype , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
value . pointer = ( void * ) val ;
value . Type = ValueType = valtype ;
isresolved = true ;
}
FxConstant ( FState * state , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
value . pointer = state ;
ValueType = value . Type = TypeState ;
isresolved = true ;
}
FxConstant ( FFont * state , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
value . pointer = state ;
ValueType = value . Type = TypeFont ;
isresolved = true ;
}
FxConstant ( void * state , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
value . pointer = state ;
ValueType = value . Type = TypeVoidPtr ;
isresolved = true ;
}
FxConstant ( const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
value . pointer = nullptr ;
ValueType = value . Type = TypeNullPtr ;
isresolved = true ;
}
FxConstant ( PType * type , TypedVMValue & vmval , const FScriptPosition & pos ) : FxExpression ( EFX_Constant , pos )
{
isresolved = true ;
switch ( vmval . Type )
{
default :
case REGT_INT :
value . Int = vmval . i ;
break ;
case REGT_FLOAT :
value . Float = vmval . f ;
break ;
case REGT_STRING :
new ( & value ) ExpVal ( vmval . s ( ) ) ;
break ;
case REGT_POINTER :
value . pointer = vmval . a ;
break ;
}
ValueType = value . Type = type ;
}
2021-12-30 09:30:21 +00:00
2020-04-07 18:14:24 +00:00
static FxExpression * MakeConstant ( PSymbol * sym , const FScriptPosition & pos ) ;
bool isConstant ( ) const
{
return true ;
}
ExpVal GetValue ( ) const
{
return value ;
}
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxVectorValue : public FxExpression
{
2022-11-12 09:45:39 +00:00
constexpr static int maxVectorDimensions = 4 ;
2020-04-07 18:14:24 +00:00
bool isConst ; // gets set to true if all element are const (used by function defaults parser)
public :
2022-12-18 15:31:50 +00:00
FxExpression * xyzw [ maxVectorDimensions ] ;
2020-04-07 18:14:24 +00:00
friend class ZCCCompiler ;
2022-11-12 09:45:39 +00:00
FxVectorValue ( FxExpression * x , FxExpression * y , FxExpression * z , FxExpression * w , const FScriptPosition & sc ) ;
2020-04-07 18:14:24 +00:00
~ FxVectorValue ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool isConstVector ( int dim )
{
2022-11-12 09:45:39 +00:00
if ( ! isConst )
return false ;
return dim > = 0 & & dim < = maxVectorDimensions & & xyzw [ dim - 1 ] & & ( dim = = maxVectorDimensions | | ! xyzw [ dim ] ) ;
2020-04-07 18:14:24 +00:00
}
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2022-11-14 18:46:25 +00:00
//==========================================================================
//
//
//
//==========================================================================
class FxQuaternionValue : public FxVectorValue
{
public :
FxQuaternionValue ( FxExpression * x , FxExpression * y , FxExpression * z , FxExpression * w , const FScriptPosition & sc ) ;
FxExpression * Resolve ( FCompileContext & ) ;
} ;
2020-04-07 18:14:24 +00:00
//==========================================================================
//
//
//
//==========================================================================
class FxBoolCast : public FxExpression
{
FxExpression * basex ;
bool NeedValue ;
public :
FxBoolCast ( FxExpression * x , bool needvalue = true ) ;
~ FxBoolCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void EmitCompare ( VMFunctionBuilder * build , bool invert , TArray < size_t > & patchspots_yes , TArray < size_t > & patchspots_no ) ;
} ;
class FxIntCast : public FxExpression
{
FxExpression * basex ;
bool NoWarn ;
bool Explicit ;
public :
FxIntCast ( FxExpression * x , bool nowarn , bool explicitly = false , bool isunsigned = false ) ;
~ FxIntCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxFloatCast : public FxExpression
{
FxExpression * basex ;
public :
FxFloatCast ( FxExpression * x ) ;
~ FxFloatCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxNameCast : public FxExpression
{
FxExpression * basex ;
bool mExplicit ;
public :
FxNameCast ( FxExpression * x , bool explicitly = false ) ;
~ FxNameCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxStringCast : public FxExpression
{
FxExpression * basex ;
public :
FxStringCast ( FxExpression * x ) ;
~ FxStringCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxColorCast : public FxExpression
{
FxExpression * basex ;
public :
FxColorCast ( FxExpression * x ) ;
~ FxColorCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxSoundCast : public FxExpression
{
FxExpression * basex ;
public :
FxSoundCast ( FxExpression * x ) ;
~ FxSoundCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxFontCast : public FxExpression
{
FxExpression * basex ;
public :
FxFontCast ( FxExpression * x ) ;
~ FxFontCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
} ;
//==========================================================================
//
// FxTypeCast
//
//==========================================================================
class FxTypeCast : public FxExpression
{
2020-04-07 20:44:10 +00:00
public :
2020-04-07 18:14:24 +00:00
FxExpression * basex ;
bool NoWarn ;
bool Explicit ;
FxTypeCast ( FxExpression * x , PType * type , bool nowarn , bool explicitly = false ) ;
~ FxTypeCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxSign
//
//==========================================================================
class FxPlusSign : public FxExpression
{
FxExpression * Operand ;
public :
FxPlusSign ( FxExpression * ) ;
~ FxPlusSign ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxSign
//
//==========================================================================
class FxMinusSign : public FxExpression
{
FxExpression * Operand ;
public :
FxMinusSign ( FxExpression * ) ;
~ FxMinusSign ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxUnaryNot
//
//==========================================================================
class FxUnaryNotBitwise : public FxExpression
{
FxExpression * Operand ;
public :
FxUnaryNotBitwise ( FxExpression * ) ;
~ FxUnaryNotBitwise ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxUnaryNot
//
//==========================================================================
class FxUnaryNotBoolean : public FxExpression
{
FxExpression * Operand ;
public :
FxUnaryNotBoolean ( FxExpression * ) ;
~ FxUnaryNotBoolean ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void EmitCompare ( VMFunctionBuilder * build , bool invert , TArray < size_t > & patchspots_yes , TArray < size_t > & patchspots_no ) ;
} ;
//==========================================================================
//
// FxSign
//
//==========================================================================
class FxSizeAlign : public FxExpression
{
FxExpression * Operand ;
int Which ;
public :
FxSizeAlign ( FxExpression * , int which ) ;
~ FxSizeAlign ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxPreIncrDecr
//
//==========================================================================
class FxPreIncrDecr : public FxExpression
{
int Token ;
FxExpression * Base ;
bool AddressRequested ;
bool AddressWritable ;
public :
FxPreIncrDecr ( FxExpression * base , int token ) ;
~ FxPreIncrDecr ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxPostIncrDecr
//
//==========================================================================
class FxPostIncrDecr : public FxExpression
{
int Token ;
FxExpression * Base ;
public :
FxPostIncrDecr ( FxExpression * base , int token ) ;
~ FxPostIncrDecr ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxAssign
//
//==========================================================================
class FxAssign : public FxExpression
{
FxExpression * Base ;
FxExpression * Right ;
int IsBitWrite ;
bool AddressRequested ;
bool AddressWritable ;
bool IsModifyAssign ;
friend class FxAssignSelf ;
public :
FxAssign ( FxExpression * base , FxExpression * right , bool ismodify = false ) ;
~ FxAssign ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
//bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit ( VMFunctionBuilder * build ) ;
ExpEmit Address ;
} ;
//==========================================================================
//
// FxAssign
//
//==========================================================================
class FxCompoundStatement ;
class FxMultiAssign : public FxExpression
{
FxCompoundStatement * LocalVarContainer ; // for handling the temporary variables of the results, which may need type casts.
FArgumentList Base ;
FxExpression * Right ;
bool AddressRequested = false ;
bool AddressWritable = false ;
public :
FxMultiAssign ( FArgumentList & base , FxExpression * right , const FScriptPosition & pos ) ;
~ FxMultiAssign ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2023-01-07 18:30:49 +00:00
class FxMultiAssignDecl : public FxExpression
{
FArgumentList Base ;
FxExpression * Right ;
public :
FxMultiAssignDecl ( FArgumentList & base , FxExpression * right , const FScriptPosition & pos ) ;
~ FxMultiAssignDecl ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
//ExpEmit Emit(VMFunctionBuilder *build); This node is transformed into Declarations + FxMultiAssign , so it won't ever be emitted itself
} ;
2020-04-07 18:14:24 +00:00
//==========================================================================
//
// FxAssignSelf
//
//==========================================================================
class FxAssignSelf : public FxExpression
{
public :
FxAssign * Assignment ;
FxAssignSelf ( const FScriptPosition & pos ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxBinary : public FxExpression
{
public :
int Operator ;
FxExpression * left ;
FxExpression * right ;
FxBinary ( int , FxExpression * , FxExpression * ) ;
~ FxBinary ( ) ;
2022-08-03 12:13:42 +00:00
bool Promote ( FCompileContext & ctx , bool forceint = false , bool shiftop = false ) ;
2020-04-07 18:14:24 +00:00
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxAddSub : public FxBinary
{
public :
FxAddSub ( int , FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxMulDiv : public FxBinary
{
public :
FxMulDiv ( int , FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxPow : public FxBinary
{
public :
FxPow ( FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxCompareRel : public FxBinary
{
PType * CompareType ;
public :
FxCompareRel ( int , FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit EmitCommon ( VMFunctionBuilder * build , bool forcompare , bool invert ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void EmitCompare ( VMFunctionBuilder * build , bool invert , TArray < size_t > & patchspots_yes , TArray < size_t > & patchspots_no ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxCompareEq : public FxBinary
{
public :
FxCompareEq ( int , FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit EmitCommon ( VMFunctionBuilder * build , bool forcompare , bool invert ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void EmitCompare ( VMFunctionBuilder * build , bool invert , TArray < size_t > & patchspots_yes , TArray < size_t > & patchspots_no ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxBitOp : public FxBinary
{
public :
FxBitOp ( int , FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinary
//
//==========================================================================
class FxShift : public FxBinary
{
public :
FxShift ( int , FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxLtGtEq : public FxBinary
{
public :
FxLtGtEq ( FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxConcat : public FxBinary
{
public :
FxConcat ( FxExpression * , FxExpression * ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinaryLogical
//
//==========================================================================
class FxBinaryLogical : public FxExpression
{
public :
int Operator ;
FxExpression * left ;
FxExpression * right ;
TDeletingArray < FxExpression * > list ;
FxBinaryLogical ( int , FxExpression * , FxExpression * ) ;
~ FxBinaryLogical ( ) ;
void Flatten ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxBinaryLogical
//
//==========================================================================
class FxDotCross : public FxExpression
{
public :
int Operator ;
FxExpression * left ;
FxExpression * right ;
FxDotCross ( int , FxExpression * , FxExpression * ) ;
~ FxDotCross ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxTypeCheck : public FxExpression
{
public :
FxExpression * left ;
FxExpression * right ;
bool ClassCheck ;
FxTypeCheck ( FxExpression * , FxExpression * ) ;
~ FxTypeCheck ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit EmitCommon ( VMFunctionBuilder * build ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void EmitCompare ( VMFunctionBuilder * build , bool invert , TArray < size_t > & patchspots_yes , TArray < size_t > & patchspots_no ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxDynamicCast : public FxExpression
{
PClass * CastType ;
public :
FxExpression * expr ;
FxDynamicCast ( PClass * , FxExpression * ) ;
~ FxDynamicCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxConditional
//
//==========================================================================
class FxConditional : public FxExpression
{
public :
FxExpression * condition ;
FxExpression * truex ;
FxExpression * falsex ;
FxConditional ( FxExpression * , FxExpression * , FxExpression * ) ;
~ FxConditional ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxAbs : public FxExpression
{
FxExpression * val ;
public :
FxAbs ( FxExpression * v ) ;
~ FxAbs ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxATan2 : public FxExpression
{
FxExpression * yval , * xval ;
public :
FxATan2 ( FxExpression * y , FxExpression * x , const FScriptPosition & pos ) ;
~ FxATan2 ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
private :
ExpEmit ToReg ( VMFunctionBuilder * build , FxExpression * val ) ;
} ;
2022-11-13 07:32:09 +00:00
class FxATan2Vec : public FxExpression
{
FxExpression * vval ;
public :
FxATan2Vec ( FxExpression * y , const FScriptPosition & pos ) ;
~ FxATan2Vec ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2020-04-07 18:14:24 +00:00
//==========================================================================
//
//
//
//==========================================================================
class FxNew : public FxExpression
{
FxExpression * val ;
PFunction * CallingFunction ;
public :
FxNew ( FxExpression * v ) ;
~ FxNew ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxMinMax : public FxExpression
{
TDeletingArray < FxExpression * > choices ;
FName Type ;
public :
FxMinMax ( TArray < FxExpression * > & expr , FName type , const FScriptPosition & pos ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxRandom : public FxExpression
{
protected :
FRandom * rng ;
FxExpression * min , * max ;
FxRandom ( EFxType type , FRandom * r , const FScriptPosition & pos ) ;
public :
FxRandom ( FRandom * , FxExpression * mi , FxExpression * ma , const FScriptPosition & pos , bool nowarn ) ;
~ FxRandom ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxRandomPick : public FxExpression
{
protected :
FRandom * rng ;
TDeletingArray < FxExpression * > choices ;
public :
FxRandomPick ( FRandom * , TArray < FxExpression * > & expr , bool floaty , const FScriptPosition & pos , bool nowarn ) ;
~ FxRandomPick ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxFRandom : public FxRandom
{
public :
FxFRandom ( FRandom * , FxExpression * mi , FxExpression * ma , const FScriptPosition & pos ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxRandom2 : public FxExpression
{
FRandom * rng ;
FxExpression * mask ;
public :
FxRandom2 ( FRandom * , FxExpression * m , const FScriptPosition & pos , bool nowarn ) ;
~ FxRandom2 ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxRandomSeed : public FxExpression
{
protected :
FRandom * rng ;
FxExpression * seed ;
public :
FxRandomSeed ( FRandom * , FxExpression * mi , const FScriptPosition & pos , bool nowarn ) ;
~ FxRandomSeed ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxMemberBase
//
//==========================================================================
class FxMemberBase : public FxExpression
{
public :
PField * membervar ;
bool AddressRequested = false ;
bool AddressWritable = true ;
int BarrierSide = - 1 ; // [ZZ] some magic
FxMemberBase ( EFxType type , PField * f , const FScriptPosition & p ) ;
} ;
//==========================================================================
//
// FxGlobalVariab<61> e
//
//==========================================================================
class FxGlobalVariable : public FxMemberBase
{
public :
FxGlobalVariable ( PField * , const FScriptPosition & ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
virtual int GetBitValue ( ) { return membervar - > BitValue ; }
} ;
class FxCVar : public FxExpression
{
FBaseCVar * CVar ;
public :
FxCVar ( FBaseCVar * , const FScriptPosition & ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxClassMember
//
//==========================================================================
class FxStructMember : public FxMemberBase
{
public :
FxExpression * classx ;
FxStructMember ( FxExpression * , PField * , const FScriptPosition & ) ;
~ FxStructMember ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
virtual int GetBitValue ( ) { return membervar - > BitValue ; }
} ;
//==========================================================================
//
// FxClassMember
//
//==========================================================================
class FxClassMember : public FxStructMember
{
public :
FxClassMember ( FxExpression * , PField * , const FScriptPosition & ) ;
} ;
//==========================================================================
//
// FxLocalVariable
//
//==========================================================================
class FxLocalVariable : public FxExpression
{
public :
FxLocalVariableDeclaration * Variable ;
bool AddressRequested ;
int RegOffset ;
FxLocalVariable ( FxLocalVariableDeclaration * , const FScriptPosition & ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxLocalVariable
//
//==========================================================================
class FxStackVariable : public FxMemberBase
{
public :
FxStackVariable ( PType * type , int offset , const FScriptPosition & ) ;
~ FxStackVariable ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
virtual int GetBitValue ( ) { return membervar - > BitValue ; }
} ;
//==========================================================================
//
// FxLocalVariable
//
//==========================================================================
class FxStaticArray ;
class FxStaticArrayVariable : public FxExpression
{
public :
FxStaticArray * Variable ;
bool AddressRequested ;
FxStaticArrayVariable ( FxLocalVariableDeclaration * , const FScriptPosition & ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxSelf
//
//==========================================================================
class FxSelf : public FxExpression
{
bool check ;
public :
FxSelf ( const FScriptPosition & , bool deccheck = false ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxSuper
//
//==========================================================================
class FxSuper : public FxSelf
{
public :
FxSuper ( const FScriptPosition & pos )
: FxSelf ( pos )
{
ExprType = EFX_Super ;
}
FxExpression * Resolve ( FCompileContext & ) ;
} ;
//==========================================================================
//
// FxArrayElement
//
//==========================================================================
class FxArrayElement : public FxExpression
{
public :
FxExpression * Array ;
FxExpression * index ;
size_t SizeAddr ;
bool AddressRequested ;
bool AddressWritable ;
bool arrayispointer = false ;
2022-11-15 20:29:04 +00:00
bool noboundscheck ;
2020-04-07 18:14:24 +00:00
2022-11-15 20:29:04 +00:00
FxArrayElement ( FxExpression * , FxExpression * , bool = false ) ;
2020-04-07 18:14:24 +00:00
~ FxArrayElement ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxFunctionCall
//
//==========================================================================
class FxFunctionCall : public FxExpression
{
FRandom * RNG ;
public :
2020-04-07 20:44:10 +00:00
FName MethodName ;
FArgumentList ArgList ;
2020-04-07 18:14:24 +00:00
FxFunctionCall ( FName methodname , FName rngname , FArgumentList & args , const FScriptPosition & pos ) ;
~ FxFunctionCall ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
} ;
//==========================================================================
//
// FxFunctionCall
//
//==========================================================================
class FxMemberFunctionCall : public FxExpression
{
FxExpression * Self ;
FName MethodName ;
FArgumentList ArgList ;
public :
FxMemberFunctionCall ( FxExpression * self , FName methodname , FArgumentList & args , const FScriptPosition & pos ) ;
~ FxMemberFunctionCall ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
} ;
//==========================================================================
//
// FxFlopFunctionCall
//
//==========================================================================
class FxFlopFunctionCall : public FxExpression
{
int Index ;
FArgumentList ArgList ;
public :
FxFlopFunctionCall ( size_t index , FArgumentList & args , const FScriptPosition & pos ) ;
~ FxFlopFunctionCall ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxVectorBuiltin
//
//==========================================================================
class FxVectorBuiltin : public FxExpression
{
FName Function ;
FxExpression * Self ;
public :
FxVectorBuiltin ( FxExpression * self , FName name ) ;
~ FxVectorBuiltin ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2022-11-13 07:32:09 +00:00
//==========================================================================
//
// FxPlusZ
//
//==========================================================================
class FxVectorPlusZ : public FxExpression
{
FName Function ;
FxExpression * Self ;
FxExpression * Z ;
public :
FxVectorPlusZ ( FxExpression * self , FName name , FxExpression * ) ;
~ FxVectorPlusZ ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxPlusZ
//
//==========================================================================
class FxToVector : public FxExpression
{
FxExpression * Self ;
public :
FxToVector ( FxExpression * self ) ;
~ FxToVector ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2020-04-07 18:14:24 +00:00
//==========================================================================
//
// FxVectorBuiltin
//
//==========================================================================
class FxStrLen : public FxExpression
{
FxExpression * Self ;
public :
FxStrLen ( FxExpression * self ) ;
~ FxStrLen ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxGetClass
//
//==========================================================================
class FxGetClass : public FxExpression
{
FxExpression * Self ;
public :
FxGetClass ( FxExpression * self ) ;
~ FxGetClass ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxGetClass
//
//==========================================================================
class FxGetParentClass : public FxExpression
{
FxExpression * Self ;
public :
FxGetParentClass ( FxExpression * self ) ;
~ FxGetParentClass ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxGetClass
//
//==========================================================================
class FxGetClassName : public FxExpression
{
FxExpression * Self ;
public :
FxGetClassName ( FxExpression * self ) ;
~ FxGetClassName ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2021-02-26 18:06:10 +00:00
//==========================================================================
//
// FxIsAbstract
//
//==========================================================================
class FxIsAbstract : public FxExpression
{
FxExpression * Self ;
public :
FxIsAbstract ( FxExpression * self ) ;
~ FxIsAbstract ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2020-04-07 18:14:24 +00:00
//==========================================================================
//
// FxColorLiteral
//
//==========================================================================
class FxColorLiteral : public FxExpression
{
FArgumentList ArgList ;
int constval = 0 ;
public :
FxColorLiteral ( FArgumentList & args , FScriptPosition & sc ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxVMFunctionCall
//
//==========================================================================
class FxVMFunctionCall : public FxExpression
{
friend class FxMultiAssign ;
bool NoVirtual ;
bool hasStringArgs = false ;
FxExpression * Self ;
// for multi assignment
int AssignCount = 0 ;
TArray < ExpEmit > ReturnRegs ;
PFunction * CallingFunction ;
bool CheckAccessibility ( const VersionInfo & ver ) ;
public :
2020-04-07 20:44:10 +00:00
FArgumentList ArgList ;
PFunction * Function ;
2020-04-07 18:14:24 +00:00
FxVMFunctionCall ( FxExpression * self , PFunction * func , FArgumentList & args , const FScriptPosition & pos , bool novirtual ) ;
~ FxVMFunctionCall ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
PPrototype * ReturnProto ( ) ;
VMFunction * GetDirectFunction ( PFunction * func , const VersionInfo & ver ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
bool CheckEmitCast ( VMFunctionBuilder * build , bool returnit , ExpEmit & reg ) ;
TArray < PType * > & GetReturnTypes ( ) const
{
return Function - > Variants [ 0 ] . Proto - > ReturnTypes ;
}
} ;
//==========================================================================
//
// FxSequence (a list of statements with no semantics attached - used to return multiple nodes as one)
//
//==========================================================================
class FxLocalVariableDeclaration ;
class FxSequence : public FxExpression
{
TDeletingArray < FxExpression * > Expressions ;
public :
FxSequence ( const FScriptPosition & pos ) : FxExpression ( EFX_Sequence , pos ) { }
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void Add ( FxExpression * expr ) { if ( expr ! = NULL ) Expressions . Push ( expr ) ; expr - > NeedResult = false ; }
VMFunction * GetDirectFunction ( PFunction * func , const VersionInfo & ver ) ;
bool CheckReturn ( ) ;
} ;
//==========================================================================
//
// FxCompoundStatement (like a list but implements maintenance of local variables)
//
//==========================================================================
class FxLocalVariableDeclaration ;
class FxCompoundStatement : public FxSequence
{
TArray < FxLocalVariableDeclaration * > LocalVars ;
FxCompoundStatement * Outer = nullptr ;
friend class FxLocalVariableDeclaration ;
friend class FxStaticArray ;
friend class FxMultiAssign ;
friend class FxLocalArrayDeclaration ;
public :
FxCompoundStatement ( const FScriptPosition & pos ) : FxSequence ( pos ) { }
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
FxLocalVariableDeclaration * FindLocalVariable ( FName name , FCompileContext & ctx ) ;
bool CheckLocalVariable ( FName name ) ;
} ;
//==========================================================================
//
// FxSwitchStatement
//
//==========================================================================
class FxSwitchStatement : public FxExpression
{
FxExpression * Condition ;
FArgumentList Content ;
struct CaseAddr
{
int casevalue ;
size_t jumpaddress ;
} ;
TArray < CaseAddr > CaseAddresses ;
public :
TArray < FxJumpStatement * > Breaks ;
FxSwitchStatement ( FxExpression * cond , FArgumentList & content , const FScriptPosition & pos ) ;
~ FxSwitchStatement ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
bool CheckReturn ( ) ;
} ;
//==========================================================================
//
// FxSwitchStatement
//
//==========================================================================
class FxCaseStatement : public FxExpression
{
FxExpression * Condition ;
int CaseValue ; // copy the value to here for easier access.
friend class FxSwitchStatement ;
public :
FxCaseStatement ( FxExpression * cond , const FScriptPosition & pos ) ;
~ FxCaseStatement ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
} ;
//==========================================================================
//
// FxIfStatement
//
//==========================================================================
class FxIfStatement : public FxExpression
{
FxExpression * Condition ;
FxExpression * WhenTrue ;
FxExpression * WhenFalse ;
public :
FxIfStatement ( FxExpression * cond , FxExpression * true_part , FxExpression * false_part , const FScriptPosition & pos ) ;
~ FxIfStatement ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
bool CheckReturn ( ) ;
} ;
//==========================================================================
//
// Base class for loops
//
//==========================================================================
class FxLoopStatement : public FxExpression
{
protected :
FxLoopStatement ( EFxType etype , const FScriptPosition & pos )
: FxExpression ( etype , pos )
{
}
2021-12-30 09:30:21 +00:00
2020-04-07 18:14:24 +00:00
void Backpatch ( VMFunctionBuilder * build , size_t loopstart , size_t loopend ) ;
FxExpression * Resolve ( FCompileContext & ) final ;
virtual FxExpression * DoResolve ( FCompileContext & ) = 0 ;
public :
TArray < FxJumpStatement * > Jumps ;
} ;
//==========================================================================
//
// FxWhileLoop
//
//==========================================================================
class FxWhileLoop : public FxLoopStatement
{
FxExpression * Condition ;
FxExpression * Code ;
public :
FxWhileLoop ( FxExpression * condition , FxExpression * code , const FScriptPosition & pos ) ;
~ FxWhileLoop ( ) ;
FxExpression * DoResolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxDoWhileLoop
//
//==========================================================================
class FxDoWhileLoop : public FxLoopStatement
{
FxExpression * Condition ;
FxExpression * Code ;
public :
FxDoWhileLoop ( FxExpression * condition , FxExpression * code , const FScriptPosition & pos ) ;
~ FxDoWhileLoop ( ) ;
FxExpression * DoResolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxForLoop
//
//==========================================================================
class FxForLoop : public FxLoopStatement
{
FxExpression * Init ;
FxExpression * Condition ;
FxExpression * Iteration ;
FxExpression * Code ;
public :
FxForLoop ( FxExpression * init , FxExpression * condition , FxExpression * iteration , FxExpression * code , const FScriptPosition & pos ) ;
~ FxForLoop ( ) ;
FxExpression * DoResolve ( FCompileContext & ) ;
2022-11-15 20:29:04 +00:00
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
// FxForLoop
//
//==========================================================================
class FxForEachLoop : public FxLoopStatement
{
FName loopVarName ;
FxExpression * Array ;
FxExpression * Array2 ;
FxExpression * Code ;
public :
FxForEachLoop ( FName vn , FxExpression * arrayvar , FxExpression * arrayvar2 , FxExpression * code , const FScriptPosition & pos ) ;
~ FxForEachLoop ( ) ;
FxExpression * DoResolve ( FCompileContext & ) ;
2020-04-07 18:14:24 +00:00
} ;
//==========================================================================
//
// FxJumpStatement
//
//==========================================================================
class FxJumpStatement : public FxExpression
{
public :
FxJumpStatement ( int token , const FScriptPosition & pos ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
int Token ;
size_t Address ;
} ;
//==========================================================================
//
// FxReturnStatement
//
//==========================================================================
class FxReturnStatement : public FxExpression
{
FArgumentList Args ;
public :
FxReturnStatement ( FxExpression * value , const FScriptPosition & pos ) ;
FxReturnStatement ( FArgumentList & args , const FScriptPosition & pos ) ;
~ FxReturnStatement ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
VMFunction * GetDirectFunction ( PFunction * func , const VersionInfo & ver ) ;
bool CheckReturn ( ) { return true ; }
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxClassTypeCast : public FxExpression
{
PClass * desttype ;
FxExpression * basex ;
bool Explicit ;
public :
FxClassTypeCast ( PClassPointer * dtype , FxExpression * x , bool explicitly ) ;
~ FxClassTypeCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxClassPtrCast : public FxExpression
{
PClass * desttype ;
FxExpression * basex ;
public :
FxClassPtrCast ( PClass * dtype , FxExpression * x ) ;
~ FxClassPtrCast ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxNop : public FxExpression
{
public :
FxNop ( const FScriptPosition & p )
: FxExpression ( EFX_Nop , p )
{
isresolved = true ;
ValueType = TypeVoid ;
}
ExpEmit Emit ( VMFunctionBuilder * build )
{
return ExpEmit ( ) ;
}
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxLocalVariableDeclaration : public FxExpression
{
friend class FxCompoundStatement ;
friend class FxLocalVariable ;
friend class FxStaticArrayVariable ;
friend class FxLocalArrayDeclaration ;
friend class FxStructMember ;
FName Name ;
FxExpression * Init ;
int VarFlags ;
int RegCount ;
protected :
FxExpression * clearExpr ;
void ClearDynamicArray ( VMFunctionBuilder * build ) ;
public :
int StackOffset = - 1 ;
int RegNum = - 1 ;
FxLocalVariableDeclaration ( PType * type , FName name , FxExpression * initval , int varflags , const FScriptPosition & p ) ;
~ FxLocalVariableDeclaration ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
void Release ( VMFunctionBuilder * build ) ;
void SetReg ( ExpEmit reginfo ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxStaticArray : public FxLocalVariableDeclaration
{
friend class FxStaticArrayVariable ;
PType * ElementType ;
FArgumentList values ;
public :
FxStaticArray ( PType * type , FName name , FArgumentList & args , const FScriptPosition & pos ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
class FxNamedNode : public FxExpression
{
public :
FName name ;
FxExpression * value ;
FxNamedNode ( FName n , FxExpression * x , const FScriptPosition & pos )
: FxExpression ( EFX_NamedNode , pos ) , name ( n ) , value ( x )
{
}
FxExpression * Resolve ( FCompileContext & )
{
// This should never reach the backend in a supported context,
// it's just needed to extend argument lists with the skipped parameters and needs to be resolved by the parent node.
ScriptPosition . Message ( MSG_ERROR , " Named arguments not supported here " ) ;
delete this ;
return nullptr ;
}
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxLocalArrayDeclaration : public FxLocalVariableDeclaration
{
PType * ElementType ;
FArgumentList values ;
public :
FxLocalArrayDeclaration ( PType * type , FName name , FArgumentList & args , int varflags , const FScriptPosition & pos ) ;
FxExpression * Resolve ( FCompileContext & ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
//==========================================================================
//
//
//
//==========================================================================
class FxOutVarDereference : public FxExpression
{
FxExpression * Self ;
PType * SelfType ;
bool AddressWritable ;
public :
FxOutVarDereference ( FxExpression * self , const FScriptPosition & p )
: FxExpression ( EFX_OutVarDereference , p ) , Self ( self )
{
}
~ FxOutVarDereference ( ) ;
FxExpression * Resolve ( FCompileContext & ) ;
bool RequestAddress ( FCompileContext & ctx , bool * writable ) ;
ExpEmit Emit ( VMFunctionBuilder * build ) ;
} ;
2020-04-07 20:44:10 +00:00
struct CompileEnvironment
{
FxExpression * ( * SpecialTypeCast ) ( FxTypeCast * func , FCompileContext & ctx ) ;
bool ( * CheckForCustomAddition ) ( FxAddSub * func , FCompileContext & ctx ) ;
FxExpression * ( * CheckSpecialIdentifier ) ( FxIdentifier * func , FCompileContext & ctx ) ;
2020-10-24 15:30:47 +00:00
FxExpression * ( * CheckSpecialGlobalIdentifier ) ( FxIdentifier * func , FCompileContext & ctx ) ;
2020-04-07 20:44:10 +00:00
FxExpression * ( * ResolveSpecialIdentifier ) ( FxIdentifier * func , FxExpression * & object , PContainerType * objtype , FCompileContext & ctx ) ;
FxExpression * ( * CheckSpecialMember ) ( FxStructMember * func , FCompileContext & ctx ) ;
FxExpression * ( * CheckCustomGlobalFunctions ) ( FxFunctionCall * func , FCompileContext & ctx ) ;
bool ( * ResolveSpecialFunction ) ( FxVMFunctionCall * func , FCompileContext & ctx ) ;
FName CustomBuiltinNew ; //override the 'new' function if some classes need special treatment.
} ;
extern CompileEnvironment compileEnvironment ;
2020-04-07 18:14:24 +00:00
# endif