mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-15 06:51:36 +00:00
- More AST'ing about.
SVN r2359 (scripting)
This commit is contained in:
parent
c043627cc1
commit
85d869315b
2 changed files with 192 additions and 56 deletions
|
@ -1,10 +1,15 @@
|
||||||
%include
|
%include
|
||||||
{
|
{
|
||||||
|
// Allocates a new AST node off the parse state's arena.
|
||||||
#define NEW_AST_NODE(type,name) \
|
#define NEW_AST_NODE(type,name) \
|
||||||
ZCC_##type *name = (ZCC_##type *)stat->SyntaxArena.Alloc(sizeof(ZCC_##type)); \
|
ZCC_##type *name = (ZCC_##type *)stat->SyntaxArena.Alloc(sizeof(ZCC_##type)); \
|
||||||
name->SiblingNext = name; \
|
name->SiblingNext = name; \
|
||||||
name->SiblingPrev = name; \
|
name->SiblingPrev = name; \
|
||||||
name->NodeType = AST_##type
|
name->NodeType = AST_##type
|
||||||
|
|
||||||
|
// If a is non-null, appends b to a. Otherwise, sets a to b.
|
||||||
|
#define SAFE_APPEND(a,b) \
|
||||||
|
if (a == NULL) a = b; else a->AppendSibling(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
%token_prefix ZCC_
|
%token_prefix ZCC_
|
||||||
|
@ -87,23 +92,76 @@ opt_expr(X) ::= expr(A).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A class definition. Can only occur at global scope. */
|
/************ Class Definition ************/
|
||||||
class_definition ::= class_start class_body.
|
/* Can only occur at global scope. */
|
||||||
|
|
||||||
|
%type class_definition{ZCC_Class *}
|
||||||
|
%type class_head{ZCC_Class *}
|
||||||
|
%type class_innards{ZCC_Class *}
|
||||||
|
%type class_body{ZCC_TreeNode *}
|
||||||
|
|
||||||
|
class_definition(X) ::= class_head(A) class_body(B).
|
||||||
{
|
{
|
||||||
/* stat->CurrClass = NULL;*/
|
A->Body = B;
|
||||||
|
X = A;
|
||||||
}
|
}
|
||||||
|
|
||||||
class_start ::= CLASS IDENTIFIER class_ancestry class_flags.
|
class_head(X) ::= CLASS dottable_id(A) class_ancestry(B) class_flags(C).
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(Class,head);
|
||||||
|
head->ClassName = A;
|
||||||
|
head->ParentName = B;
|
||||||
|
head->Flags = C.Flags;
|
||||||
|
head->Replaces = C.Replaces;
|
||||||
|
X = head;
|
||||||
|
}
|
||||||
|
|
||||||
%type class_ancestry {ENamedName}
|
%type class_ancestry{ZCC_Identifier *}
|
||||||
class_ancestry(X) ::= . { X = NAME_Object; }
|
class_ancestry(X) ::= . { X = NULL; }
|
||||||
class_ancestry(X) ::= COLON IDENTIFIER(A). { X = ENamedName(A.Int); }
|
class_ancestry(X) ::= COLON dottable_id(A). { X = A; }
|
||||||
|
|
||||||
class_flags ::= .
|
%type class_flags{ClassFlagsBlock}
|
||||||
class_flags ::= class_flags ABSTRACT.
|
%include{
|
||||||
class_flags ::= class_flags NATIVE.
|
struct ClassFlagsBlock {
|
||||||
class_flags ::= class_flags REPLACES IDENTIFIER.
|
VM_UWORD Flags;
|
||||||
|
ZCC_Identifier *Replaces;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; }
|
||||||
|
class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | 0/*FIXME*/; X.Replaces = A.Replaces; }
|
||||||
|
class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | 0/*FIXME*/; X.Replaces = A.Replaces; }
|
||||||
|
class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; }
|
||||||
|
|
||||||
|
/*----- Dottable Identifier -----*/
|
||||||
|
// This can be either a single identifier or two identifiers connected by a .
|
||||||
|
|
||||||
|
%type dottable_id{ZCC_Identifier *}
|
||||||
|
|
||||||
|
dottable_id(X) ::= IDENTIFIER(A).
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(Identifier,id);
|
||||||
|
id->Id = A.Name();
|
||||||
|
X = id;
|
||||||
|
}
|
||||||
|
dottable_id(X) ::= IDENTIFIER(A) DOT IDENTIFIER(B).
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(Identifier,id1);
|
||||||
|
NEW_AST_NODE(Identifier,id2);
|
||||||
|
id1->Id = A.Name();
|
||||||
|
id2->Id = B.Name();
|
||||||
|
id1->AppendSibling(id2);
|
||||||
|
X = id1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------ Class Body ------*/
|
||||||
|
// Body is a list of:
|
||||||
|
// * variable definitions
|
||||||
|
// * function definitions
|
||||||
|
// * enum definitions
|
||||||
|
// * struct definitions
|
||||||
|
// * state definitions
|
||||||
|
// * constants
|
||||||
|
// * defaults
|
||||||
|
|
||||||
class_body ::= SEMICOLON class_innards EOF.
|
class_body ::= SEMICOLON class_innards EOF.
|
||||||
class_body ::= LBRACE class_innards RBRACE.
|
class_body ::= LBRACE class_innards RBRACE.
|
||||||
|
@ -111,7 +169,10 @@ class_body ::= LBRACE class_innards RBRACE.
|
||||||
class_innards ::= .
|
class_innards ::= .
|
||||||
class_innards ::= class_innards class_member.
|
class_innards ::= class_innards class_member.
|
||||||
|
|
||||||
/* Classes can define variables, functions, enums, structs, states, constants, and defaults. */
|
%type struct_def{ZCC_Struct *}
|
||||||
|
%type enum_def {ZCC_Enum *}
|
||||||
|
%type states_def {ZCC_States *}
|
||||||
|
|
||||||
class_member ::= declarator.
|
class_member ::= declarator.
|
||||||
class_member ::= enum_def.
|
class_member ::= enum_def.
|
||||||
class_member ::= struct_def.
|
class_member ::= struct_def.
|
||||||
|
@ -119,25 +180,79 @@ class_member ::= states_def.
|
||||||
class_member ::= default_def.
|
class_member ::= default_def.
|
||||||
class_member ::= const_def.
|
class_member ::= const_def.
|
||||||
|
|
||||||
/* Structs can define variables, enums, and structs. */
|
/*----- Struct Definition -----*/
|
||||||
struct_def ::= STRUCT IDENTIFIER LBRACE struct_body RBRACE opt_semicolon.
|
/* Structs can define variables, enums<s>, and structs</s>. */
|
||||||
struct_member ::= declarator_no_fun.
|
|
||||||
struct_member ::= enum_def.
|
|
||||||
|
|
||||||
|
%type struct_body{ZCC_TreeNode *}
|
||||||
|
%type struct_member{ZCC_TreeNode *}
|
||||||
|
|
||||||
|
struct_def(X) ::= STRUCT IDENTIFIER(A) LBRACE struct_body(B) RBRACE opt_semicolon.
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(Struct,def);
|
||||||
|
def->StructName = A.Name();
|
||||||
|
def->Body = B;
|
||||||
|
X = def;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_body(X) ::= error. { X = NULL; }
|
||||||
|
struct_body(X) ::= struct_member(A). { X = A; }
|
||||||
|
struct_body(X) ::= struct_member(A) struct_body(B). { X = A; A->AppendSibling(B); }
|
||||||
|
|
||||||
|
struct_member(X) ::= declarator_no_fun(A). { X = A; }
|
||||||
|
struct_member(X) ::= enum_def(A). { X = A; }
|
||||||
|
|
||||||
|
|
||||||
|
/*----- Enum Definition -----*/
|
||||||
/* Enumerators are lists of named integers. */
|
/* Enumerators are lists of named integers. */
|
||||||
enum_def ::= ENUM IDENTIFIER enum_type LBRACE enum_list opt_comma RBRACE opt_semicolon.
|
|
||||||
|
|
||||||
enum_type ::= .
|
%type enum_type {EZCCIntType}
|
||||||
enum_type ::= COLON int_type.
|
%type enum_list {ZCC_EnumNode *}
|
||||||
|
%type enumerator {ZCC_EnumNode *}
|
||||||
|
|
||||||
enum_list ::= enumerator.
|
enum_def(X) ::= ENUM IDENTIFIER(A) enum_type(B) LBRACE enum_list(C) opt_comma RBRACE opt_semicolon.
|
||||||
enum_list ::= enum_list COMMA enumerator.
|
{
|
||||||
|
NEW_AST_NODE(Enum,def);
|
||||||
|
def->EnumName = A.Name();
|
||||||
|
def->EnumType = B;
|
||||||
|
def->Elements = C;
|
||||||
|
X = def;
|
||||||
|
}
|
||||||
|
|
||||||
enumerator ::= IDENTIFIER.
|
enum_type(X) ::= . { X = ZCCINT_Auto; }
|
||||||
enumerator ::= IDENTIFIER EQ expr. /* Expression must be constant. */
|
enum_type(X) ::= COLON int_type(A). { X = A; }
|
||||||
|
|
||||||
/* States */
|
enum_list(X) ::= error. { X = NULL; }
|
||||||
states_def ::= STATES scanner_mode LBRACE states_body RBRACE.
|
enum_list(X) ::= enumerator(A). { X = A; }
|
||||||
|
enum_list(X) ::= enum_list(A) COMMA enumerator(B). { X = A; A->AppendSibling(B); }
|
||||||
|
|
||||||
|
enumerator(X) ::= IDENTIFIER(A).
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(EnumNode,node);
|
||||||
|
node->ElemName = A.Name();
|
||||||
|
node->ElemValue = NULL;
|
||||||
|
X = node;
|
||||||
|
}
|
||||||
|
enumerator(X) ::= IDENTIFIER(A) EQ expr(B). /* Expression must be constant. */
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(EnumNode,node);
|
||||||
|
node->ElemName = A.Name();
|
||||||
|
node->ElemValue = B;
|
||||||
|
X = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ States ************/
|
||||||
|
|
||||||
|
%type states_body {ZCC_StatePart *}
|
||||||
|
%type state_line {ZCC_StatePart *}
|
||||||
|
%type state_label {ZCC_StatePart *}
|
||||||
|
%type state_flow {ZCC_StatePart *}
|
||||||
|
|
||||||
|
states_def(X) ::= STATES scanner_mode LBRACE states_body(A) RBRACE.
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(States,def);
|
||||||
|
def->Body = A;
|
||||||
|
X = def;
|
||||||
|
}
|
||||||
|
|
||||||
/* We use a special scanner mode to allow for sprite names and frame characters
|
/* We use a special scanner mode to allow for sprite names and frame characters
|
||||||
* to not be quoted even if they contain special characters. The scanner_mode
|
* to not be quoted even if they contain special characters. The scanner_mode
|
||||||
|
@ -152,12 +267,11 @@ states_def ::= STATES scanner_mode LBRACE states_body RBRACE.
|
||||||
*/
|
*/
|
||||||
scanner_mode ::= . { stat->sc.SetStateMode(true); }
|
scanner_mode ::= . { stat->sc.SetStateMode(true); }
|
||||||
|
|
||||||
states_body ::= .
|
states_body(X) ::= . { X = NULL; }
|
||||||
states_body ::= error.
|
states_body(X) ::= error. { X = NULL; }
|
||||||
/*states_body ::= states_body LABELID.*/
|
states_body(X) ::= states_body(A) state_line(B). { SAFE_APPEND(A,B); X = A; }
|
||||||
states_body ::= states_body state_line.
|
states_body(X) ::= states_body(A) state_label(B). { SAFE_APPEND(A,B); X = A; }
|
||||||
states_body ::= states_body state_label.
|
states_body(X) ::= states_body(A) state_flow(B). { SAFE_APPEND(A,B); X = A; }
|
||||||
states_body ::= states_body state_flow.
|
|
||||||
|
|
||||||
state_label ::= NWS(A) COLON.
|
state_label ::= NWS(A) COLON.
|
||||||
{ Printf("Label %s\n", FName(ENamedName(A.Int)).GetChars()); }
|
{ Printf("Label %s\n", FName(ENamedName(A.Int)).GetChars()); }
|
||||||
|
@ -201,15 +315,15 @@ dotted_identifier ::= dotted_identifier DOT IDENTIFIER.
|
||||||
default_def ::= DEFAULT compound_statement.
|
default_def ::= DEFAULT compound_statement.
|
||||||
|
|
||||||
/* Type names */
|
/* Type names */
|
||||||
%type int_type {PType *}
|
%type int_type {EZCCIntType}
|
||||||
%type type_name {PType *}
|
%type type_name {PType *}
|
||||||
|
|
||||||
int_type(X) ::= SBYTE. { X = TypeSInt8; }
|
int_type(X) ::= SBYTE. { X = ZCCINT_SInt8; }
|
||||||
int_type(X) ::= BYTE. { X = TypeUInt8; }
|
int_type(X) ::= BYTE. { X = ZCCINT_UInt8; }
|
||||||
int_type(X) ::= SHORT. { X = TypeSInt16; }
|
int_type(X) ::= SHORT. { X = ZCCINT_SInt16; }
|
||||||
int_type(X) ::= USHORT. { X = TypeUInt16; }
|
int_type(X) ::= USHORT. { X = ZCCINT_UInt16; }
|
||||||
int_type(X) ::= INT. { X = TypeSInt32; }
|
int_type(X) ::= INT. { X = ZCCINT_SInt32; }
|
||||||
int_type(X) ::= UINT. { X = TypeUInt32; }
|
int_type(X) ::= UINT. { X = ZCCINT_UInt32; }
|
||||||
|
|
||||||
type_name(X) ::= BOOL. { /*FIXME*/ X = TypeBool; }
|
type_name(X) ::= BOOL. { /*FIXME*/ X = TypeBool; }
|
||||||
type_name(X) ::= int_type(A). { X = A; }
|
type_name(X) ::= int_type(A). { X = A; }
|
||||||
|
@ -358,9 +472,6 @@ func_param_flags ::= func_param_flags IN.
|
||||||
func_param_flags ::= func_param_flags OUT.
|
func_param_flags ::= func_param_flags OUT.
|
||||||
func_param_flags ::= func_param_flags OPTIONAL.
|
func_param_flags ::= func_param_flags OPTIONAL.
|
||||||
|
|
||||||
struct_body ::= struct_member.
|
|
||||||
struct_body ::= struct_member struct_body.
|
|
||||||
|
|
||||||
/* Like UnrealScript, a constant's type is implied by its value's type. */
|
/* Like UnrealScript, a constant's type is implied by its value's type. */
|
||||||
const_def ::= CONST IDENTIFIER EQ expr SEMICOLON.
|
const_def ::= CONST IDENTIFIER EQ expr SEMICOLON.
|
||||||
|
|
||||||
|
|
|
@ -14,16 +14,20 @@ union ZCCToken
|
||||||
int Int;
|
int Int;
|
||||||
double Float;
|
double Float;
|
||||||
FString *String;
|
FString *String;
|
||||||
|
|
||||||
|
ENamedName Name() { return ENamedName(Int); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Syntax tree structures.
|
// Syntax tree structures.
|
||||||
enum EZCCTreeNodeType
|
enum EZCCTreeNodeType
|
||||||
{
|
{
|
||||||
|
AST_Identifier,
|
||||||
AST_Class,
|
AST_Class,
|
||||||
AST_Struct,
|
AST_Struct,
|
||||||
AST_Enum,
|
AST_Enum,
|
||||||
AST_EnumNode,
|
AST_EnumNode,
|
||||||
AST_States,
|
AST_States,
|
||||||
|
AST_StatePart,
|
||||||
AST_StateLabel,
|
AST_StateLabel,
|
||||||
AST_StateGoto,
|
AST_StateGoto,
|
||||||
AST_StateLine,
|
AST_StateLine,
|
||||||
|
@ -58,6 +62,16 @@ enum EZCCTreeNodeType
|
||||||
AST_LocalVarStmt,
|
AST_LocalVarStmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EZCCIntType
|
||||||
|
{
|
||||||
|
ZCCINT_SInt8,
|
||||||
|
ZCCINT_UInt8,
|
||||||
|
ZCCINT_SInt16,
|
||||||
|
ZCCINT_UInt16,
|
||||||
|
ZCCINT_SInt32,
|
||||||
|
ZCCINT_UInt32,
|
||||||
|
ZCCINT_Auto, // for enums, autoselect appropriately sized int
|
||||||
|
};
|
||||||
|
|
||||||
enum EZCCExprType
|
enum EZCCExprType
|
||||||
{
|
{
|
||||||
|
@ -151,49 +165,60 @@ struct ZCC_TreeNode
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ZCC_Identifier : ZCC_TreeNode
|
||||||
|
{
|
||||||
|
ENamedName Id;
|
||||||
|
};
|
||||||
|
|
||||||
struct ZCC_Class : ZCC_TreeNode
|
struct ZCC_Class : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
FName ClassName;
|
ZCC_Identifier *ClassName;
|
||||||
FName ParentName;
|
ZCC_Identifier *ParentName;
|
||||||
|
ZCC_Identifier *Replaces;
|
||||||
VM_UWORD Flags;
|
VM_UWORD Flags;
|
||||||
ZCC_TreeNode *Body;
|
ZCC_TreeNode *Body;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_Struct : ZCC_TreeNode
|
struct ZCC_Struct : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
FName StructName;
|
ENamedName StructName;
|
||||||
ZCC_TreeNode *Body;
|
ZCC_TreeNode *Body;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_Enum : ZCC_TreeNode
|
struct ZCC_Enum : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
FName EnumName;
|
ENamedName EnumName;
|
||||||
|
EZCCIntType EnumType;
|
||||||
struct ZCC_EnumNode *Elements;
|
struct ZCC_EnumNode *Elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_EnumNode : ZCC_TreeNode
|
struct ZCC_EnumNode : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
FName ElemName;
|
ENamedName ElemName;
|
||||||
ZCC_TreeNode *ElemValue;
|
ZCC_TreeNode *ElemValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_States : ZCC_TreeNode
|
struct ZCC_States : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
ZCC_TreeNode *Body;
|
struct ZCC_StatePart *Body;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_StateLabel : ZCC_TreeNode
|
struct ZCC_StatePart : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
FName Label;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_StateGoto : ZCC_TreeNode
|
struct ZCC_StateLabel : ZCC_StatePart
|
||||||
|
{
|
||||||
|
ENamedName Label;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ZCC_StateGoto : ZCC_StatePart
|
||||||
{
|
{
|
||||||
ZCC_TreeNode *Label;
|
ZCC_TreeNode *Label;
|
||||||
ZCC_TreeNode *Offset;
|
ZCC_TreeNode *Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_StateLine : ZCC_TreeNode
|
struct ZCC_StateLine : ZCC_StatePart
|
||||||
{
|
{
|
||||||
char Sprite[4];
|
char Sprite[4];
|
||||||
FString *Frames;
|
FString *Frames;
|
||||||
|
@ -225,7 +250,7 @@ struct ZCC_Type : ZCC_TreeNode
|
||||||
struct ZCC_BasicType : ZCC_Type
|
struct ZCC_BasicType : ZCC_Type
|
||||||
{
|
{
|
||||||
PType *Type;
|
PType *Type;
|
||||||
FName TypeName;
|
ENamedName TypeName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_MapType : ZCC_Type
|
struct ZCC_MapType : ZCC_Type
|
||||||
|
@ -241,12 +266,12 @@ struct ZCC_DynArrayType : ZCC_Type
|
||||||
|
|
||||||
struct ZCC_ClassType : ZCC_Type
|
struct ZCC_ClassType : ZCC_Type
|
||||||
{
|
{
|
||||||
FName Restriction;
|
ENamedName Restriction;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_ExprID : ZCC_Expression
|
struct ZCC_ExprID : ZCC_Expression
|
||||||
{
|
{
|
||||||
FName Identifier;
|
ENamedName Identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_ExprString : ZCC_Expression
|
struct ZCC_ExprString : ZCC_Expression
|
||||||
|
@ -267,7 +292,7 @@ struct ZCC_ExprFloat : ZCC_Expression
|
||||||
struct ZCC_FuncParm : ZCC_TreeNode
|
struct ZCC_FuncParm : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
ZCC_Expression *Value;
|
ZCC_Expression *Value;
|
||||||
FName Label;
|
ENamedName Label;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_ExprFuncCall : ZCC_Expression
|
struct ZCC_ExprFuncCall : ZCC_Expression
|
||||||
|
@ -279,7 +304,7 @@ struct ZCC_ExprFuncCall : ZCC_Expression
|
||||||
struct ZCC_ExprMemberAccess : ZCC_Expression
|
struct ZCC_ExprMemberAccess : ZCC_Expression
|
||||||
{
|
{
|
||||||
ZCC_Expression *Left;
|
ZCC_Expression *Left;
|
||||||
FName Right;
|
ENamedName Right;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_ExprUnary : ZCC_Expression
|
struct ZCC_ExprUnary : ZCC_Expression
|
||||||
|
|
Loading…
Reference in a new issue