mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-04 01:41:42 +00:00
b1a83bfd26
* everything related to scripting is now placed in a subdirectory 'scripting', which itself is separated into DECORATE, ZSCRIPT, the VM and code generation. * a few items have been moved to different headers so that the DECORATE parser definitions can mostly be kept local. The only exception at the moment is the flags interface on which 3 source files depend.
564 lines
9.5 KiB
C
564 lines
9.5 KiB
C
#ifndef ZCC_PARSER_H
|
|
#define ZCC_PARSER_H
|
|
|
|
#include "memarena.h"
|
|
#include "sc_man.h"
|
|
|
|
struct ZCCToken
|
|
{
|
|
union
|
|
{
|
|
int Int;
|
|
double Float;
|
|
FString *String;
|
|
};
|
|
int SourceLoc;
|
|
|
|
ENamedName Name() { return ENamedName(Int); }
|
|
};
|
|
|
|
// Variable / Function / Class modifiers
|
|
enum
|
|
{
|
|
ZCC_Native = 1 << 0,
|
|
ZCC_Static = 1 << 1,
|
|
ZCC_Private = 1 << 2,
|
|
ZCC_Protected = 1 << 3,
|
|
ZCC_Latent = 1 << 4,
|
|
ZCC_Final = 1 << 5,
|
|
ZCC_Meta = 1 << 6,
|
|
ZCC_Action = 1 << 7,
|
|
ZCC_Deprecated = 1 << 8,
|
|
ZCC_ReadOnly = 1 << 9,
|
|
ZCC_FuncConst = 1 << 10,
|
|
ZCC_Abstract = 1 << 11,
|
|
};
|
|
|
|
// Function parameter modifiers
|
|
enum
|
|
{
|
|
ZCC_In = 1 << 0,
|
|
ZCC_Out = 1 << 1,
|
|
ZCC_Optional = 1 << 2,
|
|
};
|
|
|
|
|
|
|
|
// Syntax tree structures.
|
|
enum EZCCTreeNodeType
|
|
{
|
|
AST_Identifier,
|
|
AST_Class,
|
|
AST_Struct,
|
|
AST_Enum,
|
|
AST_EnumTerminator,
|
|
AST_States,
|
|
AST_StatePart,
|
|
AST_StateLabel,
|
|
AST_StateStop,
|
|
AST_StateWait,
|
|
AST_StateFail,
|
|
AST_StateLoop,
|
|
AST_StateGoto,
|
|
AST_StateLine,
|
|
AST_VarName,
|
|
AST_Type,
|
|
AST_BasicType,
|
|
AST_MapType,
|
|
AST_DynArrayType,
|
|
AST_ClassType,
|
|
AST_Expression,
|
|
AST_ExprID,
|
|
AST_ExprTypeRef,
|
|
AST_ExprConstant,
|
|
AST_ExprFuncCall,
|
|
AST_ExprMemberAccess,
|
|
AST_ExprUnary,
|
|
AST_ExprBinary,
|
|
AST_ExprTrinary,
|
|
AST_FuncParm,
|
|
AST_Statement,
|
|
AST_CompoundStmt,
|
|
AST_ContinueStmt,
|
|
AST_BreakStmt,
|
|
AST_ReturnStmt,
|
|
AST_ExpressionStmt,
|
|
AST_IterationStmt,
|
|
AST_IfStmt,
|
|
AST_SwitchStmt,
|
|
AST_CaseStmt,
|
|
AST_AssignStmt,
|
|
AST_LocalVarStmt,
|
|
AST_FuncParamDecl,
|
|
AST_ConstantDef,
|
|
AST_Declarator,
|
|
AST_VarDeclarator,
|
|
AST_FuncDeclarator,
|
|
AST_Default,
|
|
AST_FlagStmt,
|
|
AST_PropertyStmt,
|
|
|
|
NUM_AST_NODE_TYPES
|
|
};
|
|
|
|
enum EZCCBuiltinType
|
|
{
|
|
ZCC_SInt8,
|
|
ZCC_UInt8,
|
|
ZCC_SInt16,
|
|
ZCC_UInt16,
|
|
ZCC_SInt32,
|
|
ZCC_UInt32,
|
|
ZCC_IntAuto, // for enums, autoselect appropriately sized int
|
|
|
|
ZCC_Bool,
|
|
ZCC_Float32,
|
|
ZCC_Float64,
|
|
ZCC_FloatAuto, // 32-bit in structs/classes, 64-bit everywhere else
|
|
ZCC_String,
|
|
ZCC_Vector2,
|
|
ZCC_Vector3,
|
|
ZCC_Vector4,
|
|
ZCC_Name,
|
|
|
|
ZCC_Color, // special types for ZDoom.
|
|
ZCC_State,
|
|
ZCC_Sound,
|
|
|
|
ZCC_UserType,
|
|
|
|
ZCC_NUM_BUILT_IN_TYPES
|
|
};
|
|
|
|
enum EZCCExprType
|
|
{
|
|
#define xx(a,z) PEX_##a,
|
|
#include "zcc_exprlist.h"
|
|
|
|
PEX_COUNT_OF
|
|
};
|
|
|
|
struct ZCC_TreeNode
|
|
{
|
|
// This tree node's siblings are stored in a circular linked list.
|
|
// When you get back to this node, you know you've been through
|
|
// the whole list.
|
|
ZCC_TreeNode *SiblingNext;
|
|
ZCC_TreeNode *SiblingPrev;
|
|
|
|
// can't use FScriptPosition, because the string wouldn't have a chance to
|
|
// destruct if we did that.
|
|
FString *SourceName;
|
|
int SourceLoc;
|
|
|
|
// Node type is one of the node types above, which corresponds with
|
|
// one of the structures below.
|
|
EZCCTreeNodeType NodeType;
|
|
|
|
// Appends a sibling to this node's sibling list.
|
|
void AppendSibling(ZCC_TreeNode *sibling)
|
|
{
|
|
if (sibling == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Check integrity of our sibling list.
|
|
assert(SiblingPrev->SiblingNext == this);
|
|
assert(SiblingNext->SiblingPrev == this);
|
|
|
|
// Check integrity of new sibling list.
|
|
assert(sibling->SiblingPrev->SiblingNext == sibling);
|
|
assert(sibling->SiblingNext->SiblingPrev == sibling);
|
|
|
|
ZCC_TreeNode *siblingend = sibling->SiblingPrev;
|
|
SiblingPrev->SiblingNext = sibling;
|
|
sibling->SiblingPrev = SiblingPrev;
|
|
SiblingPrev = siblingend;
|
|
siblingend->SiblingNext = this;
|
|
}
|
|
|
|
operator FScriptPosition()
|
|
{
|
|
return FScriptPosition(*SourceName, SourceLoc);
|
|
}
|
|
|
|
};
|
|
|
|
struct ZCC_Identifier : ZCC_TreeNode
|
|
{
|
|
ENamedName Id;
|
|
};
|
|
|
|
struct ZCC_NamedNode : ZCC_TreeNode
|
|
{
|
|
ENamedName NodeName;
|
|
PSymbolType *Symbol;
|
|
};
|
|
|
|
struct ZCC_Class : ZCC_NamedNode
|
|
{
|
|
ZCC_Identifier *ParentName;
|
|
ZCC_Identifier *Replaces;
|
|
VM_UWORD Flags;
|
|
ZCC_TreeNode *Body;
|
|
PClass *Type;
|
|
};
|
|
|
|
struct ZCC_Struct : ZCC_NamedNode
|
|
{
|
|
ZCC_TreeNode *Body;
|
|
PStruct *Type;
|
|
};
|
|
|
|
struct ZCC_Enum : ZCC_NamedNode
|
|
{
|
|
EZCCBuiltinType EnumType;
|
|
struct ZCC_ConstantDef *Elements;
|
|
};
|
|
|
|
struct ZCC_EnumTerminator : ZCC_TreeNode
|
|
{
|
|
};
|
|
|
|
struct ZCC_States : ZCC_TreeNode
|
|
{
|
|
struct ZCC_StatePart *Body;
|
|
};
|
|
|
|
struct ZCC_StatePart : ZCC_TreeNode
|
|
{
|
|
};
|
|
|
|
struct ZCC_StateLabel : ZCC_StatePart
|
|
{
|
|
ENamedName Label;
|
|
};
|
|
|
|
struct ZCC_StateStop : ZCC_StatePart
|
|
{
|
|
};
|
|
|
|
struct ZCC_StateWait : ZCC_StatePart
|
|
{
|
|
};
|
|
|
|
struct ZCC_StateFail : ZCC_StatePart
|
|
{
|
|
};
|
|
|
|
struct ZCC_StateLoop : ZCC_StatePart
|
|
{
|
|
};
|
|
|
|
struct ZCC_Expression : ZCC_TreeNode
|
|
{
|
|
EZCCExprType Operation;
|
|
PType *Type;
|
|
|
|
// Repurposes this node as an error node
|
|
void ToErrorNode()
|
|
{
|
|
Type = TypeError;
|
|
Operation = PEX_Nil;
|
|
NodeType = AST_Expression;
|
|
}
|
|
};
|
|
|
|
struct ZCC_StateGoto : ZCC_StatePart
|
|
{
|
|
ZCC_Identifier *Qualifier;
|
|
ZCC_Identifier *Label;
|
|
ZCC_Expression *Offset;
|
|
};
|
|
|
|
struct ZCC_StateLine : ZCC_StatePart
|
|
{
|
|
FString *Sprite;
|
|
BITFIELD bBright : 1;
|
|
BITFIELD bFast : 1;
|
|
BITFIELD bSlow : 1;
|
|
BITFIELD bNoDelay : 1;
|
|
BITFIELD bCanRaise : 1;
|
|
FString *Frames;
|
|
ZCC_Expression *Duration;
|
|
ZCC_Expression *Offset;
|
|
ZCC_ExprConstant *Lights;
|
|
ZCC_TreeNode *Action;
|
|
};
|
|
|
|
struct ZCC_VarName : ZCC_TreeNode
|
|
{
|
|
ENamedName Name;
|
|
ZCC_Expression *ArraySize; // NULL if not an array
|
|
};
|
|
|
|
struct ZCC_Type : ZCC_TreeNode
|
|
{
|
|
ZCC_Expression *ArraySize; // NULL if not an array
|
|
};
|
|
|
|
struct ZCC_BasicType : ZCC_Type
|
|
{
|
|
EZCCBuiltinType Type;
|
|
ZCC_Identifier *UserType;
|
|
};
|
|
|
|
struct ZCC_MapType : ZCC_Type
|
|
{
|
|
ZCC_Type *KeyType;
|
|
ZCC_Type *ValueType;
|
|
};
|
|
|
|
struct ZCC_DynArrayType : ZCC_Type
|
|
{
|
|
ZCC_Type *ElementType;
|
|
};
|
|
|
|
struct ZCC_ClassType : ZCC_Type
|
|
{
|
|
ZCC_Identifier *Restriction;
|
|
};
|
|
|
|
struct ZCC_ExprID : ZCC_Expression
|
|
{
|
|
ENamedName Identifier;
|
|
};
|
|
|
|
struct ZCC_ExprTypeRef : ZCC_Expression
|
|
{
|
|
PType *RefType;
|
|
};
|
|
|
|
struct ZCC_ExprConstant : ZCC_Expression
|
|
{
|
|
union
|
|
{
|
|
FString *StringVal;
|
|
int IntVal;
|
|
unsigned int UIntVal;
|
|
double DoubleVal;
|
|
};
|
|
};
|
|
|
|
struct ZCC_FuncParm : ZCC_TreeNode
|
|
{
|
|
ZCC_Expression *Value;
|
|
ENamedName Label;
|
|
};
|
|
|
|
struct ZCC_ExprFuncCall : ZCC_Expression
|
|
{
|
|
ZCC_Expression *Function;
|
|
ZCC_FuncParm *Parameters;
|
|
};
|
|
|
|
struct ZCC_ExprMemberAccess : ZCC_Expression
|
|
{
|
|
ZCC_Expression *Left;
|
|
ENamedName Right;
|
|
};
|
|
|
|
struct ZCC_ExprUnary : ZCC_Expression
|
|
{
|
|
ZCC_Expression *Operand;
|
|
};
|
|
|
|
struct ZCC_ExprBinary : ZCC_Expression
|
|
{
|
|
ZCC_Expression *Left;
|
|
ZCC_Expression *Right;
|
|
};
|
|
|
|
struct ZCC_ExprTrinary : ZCC_Expression
|
|
{
|
|
ZCC_Expression *Test;
|
|
ZCC_Expression *Left;
|
|
ZCC_Expression *Right;
|
|
};
|
|
|
|
struct ZCC_Statement : ZCC_TreeNode
|
|
{
|
|
};
|
|
|
|
struct ZCC_CompoundStmt : ZCC_Statement
|
|
{
|
|
ZCC_Statement *Content;
|
|
};
|
|
|
|
struct ZCC_ContinueStmt : ZCC_Statement
|
|
{
|
|
};
|
|
|
|
struct ZCC_BreakStmt : ZCC_Statement
|
|
{
|
|
};
|
|
|
|
struct ZCC_ReturnStmt : ZCC_Statement
|
|
{
|
|
ZCC_Expression *Values;
|
|
};
|
|
|
|
struct ZCC_ExpressionStmt : ZCC_Statement
|
|
{
|
|
ZCC_Expression *Expression;
|
|
};
|
|
|
|
struct ZCC_IterationStmt : ZCC_Statement
|
|
{
|
|
ZCC_Expression *LoopCondition;
|
|
ZCC_Statement *LoopStatement;
|
|
ZCC_Statement *LoopBumper;
|
|
|
|
// Should the loop condition be checked at the
|
|
// start of the loop (before the LoopStatement)
|
|
// or at the end (after the LoopStatement)?
|
|
enum { Start, End } CheckAt;
|
|
};
|
|
|
|
struct ZCC_IfStmt : ZCC_Statement
|
|
{
|
|
ZCC_Expression *Condition;
|
|
ZCC_Statement *TruePath;
|
|
ZCC_Statement *FalsePath;
|
|
};
|
|
|
|
struct ZCC_SwitchStmt : ZCC_Statement
|
|
{
|
|
ZCC_Expression *Condition;
|
|
ZCC_Statement *Content;
|
|
};
|
|
|
|
struct ZCC_CaseStmt : ZCC_Statement
|
|
{
|
|
// A NULL Condition represents the default branch
|
|
ZCC_Expression *Condition;
|
|
};
|
|
|
|
struct ZCC_AssignStmt : ZCC_Statement
|
|
{
|
|
ZCC_Expression *Dests;
|
|
ZCC_Expression *Sources;
|
|
int AssignOp;
|
|
};
|
|
|
|
struct ZCC_LocalVarStmt : ZCC_Statement
|
|
{
|
|
ZCC_Type *Type;
|
|
ZCC_VarName *Vars;
|
|
ZCC_Expression *Inits;
|
|
};
|
|
|
|
struct ZCC_FuncParamDecl : ZCC_TreeNode
|
|
{
|
|
ZCC_Type *Type;
|
|
ZCC_Expression *Default;
|
|
ENamedName Name;
|
|
int Flags;
|
|
};
|
|
|
|
struct ZCC_ConstantDef : ZCC_NamedNode
|
|
{
|
|
ZCC_Expression *Value;
|
|
PSymbolConst *Symbol;
|
|
ZCC_Enum *Type; // gets set when the constant originates from an enum.
|
|
};
|
|
|
|
struct ZCC_Declarator : ZCC_TreeNode
|
|
{
|
|
ZCC_Type *Type;
|
|
int Flags;
|
|
};
|
|
|
|
// A variable in a class or struct.
|
|
struct ZCC_VarDeclarator : ZCC_Declarator
|
|
{
|
|
ZCC_VarName *Names;
|
|
};
|
|
|
|
// A function in a class.
|
|
struct ZCC_FuncDeclarator : ZCC_Declarator
|
|
{
|
|
ZCC_FuncParamDecl *Params;
|
|
ENamedName Name;
|
|
ZCC_Statement *Body;
|
|
};
|
|
|
|
struct ZCC_Default : ZCC_CompoundStmt
|
|
{
|
|
};
|
|
|
|
struct ZCC_PropertyStmt : ZCC_Statement
|
|
{
|
|
ZCC_Identifier *Prop;
|
|
ZCC_Expression *Values;
|
|
};
|
|
|
|
|
|
struct ZCC_FlagStmt : ZCC_Statement
|
|
{
|
|
ZCC_Identifier *name;
|
|
bool set;
|
|
};
|
|
|
|
typedef ZCC_ExprConstant *(*EvalConst1op)(ZCC_ExprConstant *);
|
|
typedef ZCC_ExprConstant *(*EvalConst2op)(ZCC_ExprConstant *, ZCC_ExprConstant *, FSharedStringArena &);
|
|
|
|
struct ZCC_OpProto
|
|
{
|
|
ZCC_OpProto *Next;
|
|
PType *ResType;
|
|
PType *Type1;
|
|
PType *Type2;
|
|
union
|
|
{
|
|
EvalConst1op EvalConst1;
|
|
EvalConst2op EvalConst2;
|
|
};
|
|
|
|
ZCC_OpProto(PType *res, PType *t1, PType *t2)
|
|
: ResType(res), Type1(t1), Type2(t2) {}
|
|
};
|
|
|
|
struct ZCC_OpInfoType
|
|
{
|
|
const char *OpName;
|
|
ZCC_OpProto *Protos;
|
|
|
|
void AddProto(PType *res, PType *optype, EvalConst1op evalconst);
|
|
void AddProto(PType *res, PType *left, PType *right, EvalConst2op evalconst);
|
|
|
|
ZCC_OpProto *FindBestProto(PType *optype, const PType::Conversion **route, int &numslots);
|
|
ZCC_OpProto *FindBestProto(PType *left, const PType::Conversion **route1, int &numslots,
|
|
PType *right, const PType::Conversion **route2, int &numslots2);
|
|
|
|
void FreeAllProtos();
|
|
};
|
|
|
|
#define CONVERSION_ROUTE_SIZE 8
|
|
|
|
FString ZCC_PrintAST(ZCC_TreeNode *root);
|
|
|
|
void ZCC_InitOperators();
|
|
|
|
extern ZCC_OpInfoType ZCC_OpInfo[PEX_COUNT_OF];
|
|
|
|
struct ZCC_AST
|
|
{
|
|
ZCC_AST() : TopNode(NULL) {}
|
|
ZCC_TreeNode *InitNode(size_t size, EZCCTreeNodeType type, ZCC_TreeNode *basis);
|
|
|
|
FSharedStringArena Strings;
|
|
FMemArena SyntaxArena;
|
|
struct ZCC_TreeNode *TopNode;
|
|
};
|
|
|
|
struct ZCCParseState : public ZCC_AST
|
|
{
|
|
ZCCParseState(FScanner *scanner = nullptr) : sc(scanner) {}
|
|
ZCC_TreeNode *InitNode(size_t size, EZCCTreeNodeType type);
|
|
|
|
FScanner *sc;
|
|
};
|
|
|
|
#endif
|