Backend update from GZDoom.

This commit is contained in:
Christoph Oelckers 2023-11-07 18:35:11 +01:00
parent a9dc57e99f
commit 6c702847ff
31 changed files with 1239 additions and 63 deletions

View file

@ -521,6 +521,26 @@ static void PrintDynArrayType(FLispString &out, const ZCC_TreeNode *node)
out.Close();
}
static void PrintFuncPtrParamDecl(FLispString &out, const ZCC_TreeNode *node)
{
ZCC_FuncPtrParamDecl *dnode = (ZCC_FuncPtrParamDecl *)node;
out.Break();
out.Open("func-ptr-param-decl");
PrintNodes(out, dnode->Type);
out.AddHex(dnode->Flags);
out.Close();
}
static void PrintFuncPtrType(FLispString &out, const ZCC_TreeNode *node){
ZCC_FuncPtrType *dnode = (ZCC_FuncPtrType *)node;
out.Break();
out.Open("func-ptr-type");
PrintNodes(out, dnode->RetType);
PrintNodes(out, dnode->Params);
out.AddHex(dnode->Scope);
out.Close();
}
static void PrintClassType(FLispString &out, const ZCC_TreeNode *node)
{
ZCC_ClassType *tnode = (ZCC_ClassType *)node;
@ -628,6 +648,16 @@ static void PrintExprClassCast(FLispString &out, const ZCC_TreeNode *node)
out.Close();
}
static void PrintExprFunctionPtrCast(FLispString &out, const ZCC_TreeNode *node)
{
ZCC_FunctionPtrCast *enode = (ZCC_FunctionPtrCast *)node;
assert(enode->Operation == PEX_FunctionPtrCast);
out.Open("expr-func-ptr-cast");
PrintNodes(out, enode->PtrType, false);
PrintNodes(out, enode->Expr, false);
out.Close();
}
static void PrintStaticArray(FLispString &out, const ZCC_TreeNode *node)
{
ZCC_StaticArrayStatement *enode = (ZCC_StaticArrayStatement *)node;
@ -976,6 +1006,8 @@ static const NodePrinterFunc TreeNodePrinter[] =
PrintMapType,
PrintMapIteratorType,
PrintDynArrayType,
PrintFuncPtrParamDecl,
PrintFuncPtrType,
PrintClassType,
PrintExpression,
PrintExprID,
@ -1011,6 +1043,7 @@ static const NodePrinterFunc TreeNodePrinter[] =
PrintVectorInitializer,
PrintDeclFlags,
PrintExprClassCast,
PrintExprFunctionPtrCast,
PrintStaticArrayState,
PrintProperty,
PrintFlagDef,

View file

@ -978,6 +978,71 @@ aggregate_type(X) ::= ARRAY(T) LT type_or_array(A) GT. /* TArray<type> */
X = arr;
}
aggregate_type(X) ::= func_ptr_type(A). { X = A; /*X-overwrites-A*/ }
%type func_ptr_type {ZCC_FuncPtrType *}
%type func_ptr_params {ZCC_FuncPtrParamDecl *}
%type func_ptr_param_list {ZCC_FuncPtrParamDecl *}
%type func_ptr_param {ZCC_FuncPtrParamDecl *}
//fn_ptr_flag(X) ::= . { X.Int = 0; } //implicit scope not allowed
fn_ptr_flag(X) ::= UI. { X.Int = ZCC_UIFlag; }
fn_ptr_flag(X) ::= PLAY. { X.Int = ZCC_Play; }
fn_ptr_flag(X) ::= CLEARSCOPE. { X.Int = ZCC_ClearScope; }
//fn_ptr_flag(X) ::= VIRTUALSCOPE. { X.Int = ZCC_VirtualScope; } //virtual scope not allowed
func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN func_ptr_params(B) RPAREN GT. /* Function<...(...)> */
{
NEW_AST_NODE(FuncPtrType,fn_ptr,T);
fn_ptr->RetType = A;
fn_ptr->Params = B;
fn_ptr->Scope = F.Int;
X = fn_ptr;
}
func_ptr_type(X) ::= FNTYPE(T) LT VOID GT. /* Function<void> */
{
NEW_AST_NODE(FuncPtrType,fn_ptr,T);
fn_ptr->RetType = nullptr;
fn_ptr->Params = nullptr;
fn_ptr->Scope = -1;
X = fn_ptr;
}
func_ptr_params(X) ::= . /* empty */ { X = NULL; }
func_ptr_params(X) ::= VOID. { X = NULL; }
func_ptr_params(X) ::= func_ptr_param_list(X).
// varargs function pointers not currently supported
//func_ptr_params(X) ::= func_ptr_param_list(A) COMMA ELLIPSIS.
//{
// NEW_AST_NODE(FuncPtrParamDecl,parm,stat->sc->GetMessageLine());
// parm->Type = nullptr;
// parm->Flags = 0;
// X = A; /*X-overwrites-A*/
// AppendTreeNodeSibling(X, parm);
//}
func_ptr_param_list(X) ::= func_ptr_param(X).
func_ptr_param_list(X) ::= func_ptr_param_list(A) COMMA func_ptr_param(B). { X = A; /*X-overwrites-A*/ AppendTreeNodeSibling(X, B); }
func_ptr_param(X) ::= func_param_flags(A) type(B).
{
NEW_AST_NODE(FuncPtrParamDecl,parm,A.SourceLoc ? A.SourceLoc : B->SourceLoc);
parm->Type = B;
parm->Flags = A.Int;
X = parm;
}
func_ptr_param(X) ::= func_param_flags(A) type(B) AND.
{
NEW_AST_NODE(FuncPtrParamDecl,parm,A.SourceLoc ? A.SourceLoc : B->SourceLoc);
parm->Type = B;
parm->Flags = A.Int | ZCC_Out;
X = parm;
}
aggregate_type(X) ::= CLASS(T) class_restrictor(A). /* class<type> */
{
NEW_AST_NODE(ClassType,cls,T);
@ -1398,6 +1463,17 @@ primary(X) ::= LPAREN CLASS LT IDENTIFIER(A) GT RPAREN LPAREN func_expr_list(B)
expr->Parameters = B;
X = expr;
}
primary(X) ::= LPAREN func_ptr_type(A) RPAREN LPAREN expr(B) RPAREN. [DOT] // function pointer type cast
{
NEW_AST_NODE(FunctionPtrCast, expr, A);
expr->Operation = PEX_FunctionPtrCast;
A->ArraySize = NULL;
expr->PtrType = A;
expr->Expr = B;
X = expr;
}
primary(X) ::= primary(A) LBRACKET expr(B) RBRACKET. [DOT] // Array access
{
NEW_AST_NODE(ExprBinary, expr, B);
@ -1407,6 +1483,7 @@ primary(X) ::= primary(A) LBRACKET expr(B) RBRACKET. [DOT] // Array access
expr->Right = B;
X = expr;
}
primary(X) ::= primary(A) DOT IDENTIFIER(B). // Member access
{
NEW_AST_NODE(ExprMemberAccess, expr, B);

View file

@ -2012,6 +2012,52 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
}
break;
}
case AST_FuncPtrType:
{
auto fn = static_cast<ZCC_FuncPtrType*>(ztype);
if(fn->Scope == -1)
{ // Function<void>
retval = NewFunctionPointer(nullptr, {}, -1);
}
else
{
TArray<PType*> returns;
TArray<PType*> args;
TArray<uint32_t> argflags;
if(auto *t = fn->RetType; t != nullptr) do {
returns.Push(DetermineType(outertype, field, name, t, false, false));
} while( (t = (ZCC_Type *)t->SiblingNext) != fn->RetType);
if(auto *t = fn->Params; t != nullptr) do {
args.Push(DetermineType(outertype, field, name, t->Type, false, false));
argflags.Push(t->Flags == ZCC_Out ? VARF_Out : 0);
} while( (t = (ZCC_FuncPtrParamDecl *) t->SiblingNext) != fn->Params);
auto proto = NewPrototype(returns,args);
switch(fn->Scope)
{ // only play/ui/clearscope functions are allowed, no data or virtual scope functions
case ZCC_Play:
fn->Scope = FScopeBarrier::Side_Play;
break;
case ZCC_UIFlag:
fn->Scope = FScopeBarrier::Side_UI;
break;
case ZCC_ClearScope:
fn->Scope = FScopeBarrier::Side_PlainData;
break;
case 0:
fn->Scope = -1;
break;
default:
Error(field, "Invalid Scope for Function Pointer");
break;
}
retval = NewFunctionPointer(proto, std::move(argflags), fn->Scope);
}
break;
}
case AST_ClassType:
{
auto ctype = static_cast<ZCC_ClassType *>(ztype);
@ -2980,6 +3026,17 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
return new FxClassPtrCast(cls, ConvertNode(cc->Parameters));
}
case AST_FunctionPtrCast:
{
auto cast = static_cast<ZCC_FunctionPtrCast *>(ast);
auto type = DetermineType(ConvertClass, cast, NAME_None, cast->PtrType, false, false);
assert(type->isFunctionPointer());
auto ptrType = static_cast<PFunctionPointer*>(type);
return new FxFunctionPtrCast(ptrType, ConvertNode(cast->Expr));
}
case AST_StaticArrayStatement:
{
auto sas = static_cast<ZCC_StaticArrayStatement *>(ast);

View file

@ -9,6 +9,7 @@ xx(FuncCall, '(')
xx(ArrayAccess, TK_Array)
xx(MemberAccess, '.')
xx(ClassCast, TK_Class)
xx(FunctionPtrCast, TK_FunctionType)
xx(TypeRef, TK_Class)
xx(Vector, TK_Vector2)

View file

@ -222,6 +222,7 @@ static void InitTokenMap()
TOKENDEF2(TK_Map, ZCC_MAP, NAME_Map);
TOKENDEF2(TK_MapIterator, ZCC_MAPITERATOR,NAME_MapIterator);
TOKENDEF2(TK_Array, ZCC_ARRAY, NAME_Array);
TOKENDEF2(TK_FunctionType, ZCC_FNTYPE, NAME_Function);
TOKENDEF2(TK_Include, ZCC_INCLUDE, NAME_Include);
TOKENDEF (TK_Void, ZCC_VOID);
TOKENDEF (TK_True, ZCC_TRUE);
@ -925,6 +926,29 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c
break;
}
case AST_FuncPtrParamDecl:
{
TreeNodeDeepCopy_Start(FuncPtrParamDecl);
// ZCC_FuncPtrParamDecl
copy->Type = static_cast<ZCC_Type *>(TreeNodeDeepCopy_Internal(ast, origCasted->Type, true, copiedNodesList));
copy->Flags = origCasted->Flags;
break;
}
case AST_FuncPtrType:
{
TreeNodeDeepCopy_Start(FuncPtrType);
// ZCC_FuncPtrType
copy->RetType = static_cast<ZCC_Type *>(TreeNodeDeepCopy_Internal(ast, origCasted->RetType, true, copiedNodesList));
copy->Params = static_cast<ZCC_FuncPtrParamDecl *>(TreeNodeDeepCopy_Internal(ast, origCasted->Params, true, copiedNodesList));
copy->Scope = origCasted->Scope;
break;
}
case AST_ClassType:
{
TreeNodeDeepCopy_Start(ClassType);
@ -1371,7 +1395,21 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c
break;
}
case AST_FunctionPtrCast:
{
TreeNodeDeepCopy_Start(FunctionPtrCast);
// ZCC_Expression
copy->Operation = origCasted->Operation;
copy->Type = origCasted->Type;
// ZCC_FunctionPtrCast
copy->PtrType = static_cast<ZCC_FuncPtrType *>(TreeNodeDeepCopy_Internal(ast, origCasted->PtrType, true, copiedNodesList));
copy->Expr = static_cast<ZCC_Expression *>(TreeNodeDeepCopy_Internal(ast, origCasted->Expr, true, copiedNodesList));
break;
}
case AST_StaticArrayStatement:
{
TreeNodeDeepCopy_Start(StaticArrayStatement);

View file

@ -101,6 +101,8 @@ enum EZCCTreeNodeType
AST_MapType,
AST_MapIteratorType,
AST_DynArrayType,
AST_FuncPtrParamDecl,
AST_FuncPtrType,
AST_ClassType,
AST_Expression,
AST_ExprID,
@ -136,6 +138,7 @@ enum EZCCTreeNodeType
AST_VectorValue,
AST_DeclFlags,
AST_ClassCast,
AST_FunctionPtrCast,
AST_StaticArrayStatement,
AST_Property,
AST_FlagDef,
@ -382,6 +385,19 @@ struct ZCC_DynArrayType : ZCC_Type
ZCC_Type *ElementType;
};
struct ZCC_FuncPtrParamDecl : ZCC_TreeNode
{
ZCC_Type *Type;
int Flags;
};
struct ZCC_FuncPtrType : ZCC_Type
{
ZCC_Type *RetType;
ZCC_FuncPtrParamDecl *Params;
int Scope;
};
struct ZCC_ClassType : ZCC_Type
{
ZCC_Identifier *Restriction;
@ -428,6 +444,12 @@ struct ZCC_ClassCast : ZCC_Expression
ZCC_FuncParm *Parameters;
};
struct ZCC_FunctionPtrCast : ZCC_Expression
{
ZCC_FuncPtrType *PtrType;
ZCC_Expression *Expr;
};
struct ZCC_ExprMemberAccess : ZCC_Expression
{
ZCC_Expression *Left;