mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Add function pointer Properties
This commit is contained in:
parent
0e9135132d
commit
c935a95cb0
4 changed files with 88 additions and 0 deletions
|
@ -2883,6 +2883,12 @@ static FString MakeFunctionPointerDescriptiveName(PPrototype * proto,const TArra
|
||||||
return mDescriptiveName;
|
return mDescriptiveName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FString PFunctionPointer::GenerateNameForError(const PFunction * from)
|
||||||
|
{
|
||||||
|
return MakeFunctionPointerDescriptiveName(from->Variants[0].Proto, from->Variants[0].ArgFlags, FScopeBarrier::SideFromFlags(from->Variants[0].Flags));
|
||||||
|
}
|
||||||
|
|
||||||
PFunctionPointer::PFunctionPointer(PPrototype * proto, TArray<uint32_t> && argflags, int scope)
|
PFunctionPointer::PFunctionPointer(PPrototype * proto, TArray<uint32_t> && argflags, int scope)
|
||||||
: PPointer(proto ? (PType*) proto : TypeVoid, false), ArgFlags(std::move(argflags)), Scope(scope)
|
: PPointer(proto ? (PType*) proto : TypeVoid, false), ArgFlags(std::move(argflags)), Scope(scope)
|
||||||
{
|
{
|
||||||
|
|
|
@ -605,6 +605,8 @@ public:
|
||||||
//PointedType = PPrototype or TypeVoid
|
//PointedType = PPrototype or TypeVoid
|
||||||
PFunctionPointer(PPrototype * proto, TArray<uint32_t> &&argflags, int scope);
|
PFunctionPointer(PPrototype * proto, TArray<uint32_t> &&argflags, int scope);
|
||||||
|
|
||||||
|
static FString GenerateNameForError(const PFunction * from);
|
||||||
|
|
||||||
TArray<uint32_t> ArgFlags;
|
TArray<uint32_t> ArgFlags;
|
||||||
int Scope;
|
int Scope;
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ int ZCCDoomCompiler::Compile()
|
||||||
InitDefaults();
|
InitDefaults();
|
||||||
InitFunctions();
|
InitFunctions();
|
||||||
CompileStates();
|
CompileStates();
|
||||||
|
InitDefaultFunctionPointers();
|
||||||
return FScriptPosition::ErrorCounter;
|
return FScriptPosition::ErrorCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +396,46 @@ void ZCCDoomCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *pr
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
PFunction * FindFunctionPointer(PClass * cls, int fn_name);
|
||||||
|
PFunction *NativeFunctionPointerCast(PFunction *from, const PFunctionPointer *to);
|
||||||
|
|
||||||
|
struct FunctionPointerProperties
|
||||||
|
{
|
||||||
|
ZCC_PropertyStmt *prop;
|
||||||
|
PClass * cls;
|
||||||
|
FName name;
|
||||||
|
const PFunctionPointer * type;
|
||||||
|
PFunction ** addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
TArray<FunctionPointerProperties> DefaultFunctionPointers;
|
||||||
|
|
||||||
|
void ZCCDoomCompiler::InitDefaultFunctionPointers()
|
||||||
|
{
|
||||||
|
for(auto &d : DefaultFunctionPointers)
|
||||||
|
{
|
||||||
|
PFunction * fn = FindFunctionPointer(d.cls, d.name.GetIndex());
|
||||||
|
if(!fn)
|
||||||
|
{
|
||||||
|
Error(d.prop, "Could not find function '%s' in class '%s'",d.name.GetChars(), d.cls->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PFunction * casted = NativeFunctionPointerCast(fn,d.type);
|
||||||
|
if(!casted)
|
||||||
|
{
|
||||||
|
FString fn_proto_name = PFunctionPointer::GenerateNameForError(fn);
|
||||||
|
Error(d.prop, "Function has incompatible types, cannot convert from '%s' to '%s'",fn_proto_name.GetChars(), d.type->DescriptiveName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*d.addr) = casted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunctionPointers.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *property, AActor *defaults, Baggage &bag)
|
void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *property, AActor *defaults, Baggage &bag)
|
||||||
{
|
{
|
||||||
ZCC_ExprConstant one;
|
ZCC_ExprConstant one;
|
||||||
|
@ -608,6 +649,44 @@ void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *
|
||||||
*(PClass**)addr = cls;
|
*(PClass**)addr = cls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (f->Type->isFunctionPointer())
|
||||||
|
{
|
||||||
|
const char * fn_str = GetStringConst(ex, ctx);
|
||||||
|
if (*fn_str == 0 || !stricmp(fn_str, "none"))
|
||||||
|
{
|
||||||
|
*(PFunction**)addr = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TArray<FString> fn_info(FString(fn_str).Split("::", FString::TOK_SKIPEMPTY));
|
||||||
|
if(fn_info.Size() != 2)
|
||||||
|
{
|
||||||
|
Error(property, "Malformed function pointer property \"%s\", must be \"Class::Function\"",fn_str);
|
||||||
|
}
|
||||||
|
PClass * cls = PClass::FindClass(fn_info[0]);
|
||||||
|
if(!cls)
|
||||||
|
{
|
||||||
|
Error(property, "Could not find class '%s'",fn_info[0].GetChars());
|
||||||
|
*(PFunction**)addr = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FName fn_name(fn_info[1], true);
|
||||||
|
if(fn_name.GetIndex() == 0)
|
||||||
|
{
|
||||||
|
Error(property, "Could not find function '%s' in class '%s'",fn_info[1].GetChars(),fn_info[0].GetChars());
|
||||||
|
*(PFunction**)addr = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultFunctionPointers.Push({property, cls, fn_name, static_cast<const PFunctionPointer *>(f->Type), (PFunction**)addr});
|
||||||
|
*(PFunction**)addr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error(property, "unhandled property type %s", f->Type->DescriptiveName());
|
Error(property, "unhandled property type %s", f->Type->DescriptiveName());
|
||||||
|
|
|
@ -25,6 +25,7 @@ private:
|
||||||
void ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *prop, Baggage &bag);
|
void ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *prop, Baggage &bag);
|
||||||
void ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg);
|
void ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg);
|
||||||
void InitDefaults() override final;
|
void InitDefaults() override final;
|
||||||
|
void InitDefaultFunctionPointers();
|
||||||
FxExpression *SetupActionFunction(PClass *cls, ZCC_TreeNode *af, int StateFlags);
|
FxExpression *SetupActionFunction(PClass *cls, ZCC_TreeNode *af, int StateFlags);
|
||||||
void CompileStates();
|
void CompileStates();
|
||||||
int CheckActionKeyword(ZCC_FuncDeclarator *f, uint32_t &varflags, int useflags, ZCC_StructWork *c);
|
int CheckActionKeyword(ZCC_FuncDeclarator *f, uint32_t &varflags, int useflags, ZCC_StructWork *c);
|
||||||
|
|
Loading…
Reference in a new issue