Skip to content

Commit

Permalink
Add function pointer Properties
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoLuis0 committed Oct 11, 2023
1 parent 4a2b3bb commit f98d68b
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/common/scripting/core/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2883,6 +2883,12 @@ static FString MakeFunctionPointerDescriptiveName(PPrototype * proto,const TArra
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)
: PPointer(proto ? (PType*) proto : TypeVoid, false), ArgFlags(std::move(argflags)), Scope(scope)
{
Expand Down
2 changes: 2 additions & 0 deletions src/common/scripting/core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,8 @@ class PFunctionPointer : public PPointer
//PointedType = PPrototype or TypeVoid
PFunctionPointer(PPrototype * proto, TArray<uint32_t> &&argflags, int scope);

static FString GenerateNameForError(const PFunction * from);

TArray<uint32_t> ArgFlags;
int Scope;

Expand Down
79 changes: 79 additions & 0 deletions src/scripting/zscript/zcc_compile_doom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ int ZCCDoomCompiler::Compile()
InitDefaults();
InitFunctions();
CompileStates();
InitDefaultFunctionPointers();
return FScriptPosition::ErrorCounter;
}

Expand Down Expand Up @@ -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)
{
ZCC_ExprConstant one;
Expand Down Expand Up @@ -608,6 +649,44 @@ void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *
*(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_info);
}
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
{
Error(property, "unhandled property type %s", f->Type->DescriptiveName());
Expand Down
1 change: 1 addition & 0 deletions src/scripting/zscript/zcc_compile_doom.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ZCCDoomCompiler : public ZCCCompiler
void ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *prop, Baggage &bag);
void ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg);
void InitDefaults() override final;
void InitDefaultFunctionPointers();
FxExpression *SetupActionFunction(PClass *cls, ZCC_TreeNode *af, int StateFlags);
void CompileStates();
int CheckActionKeyword(ZCC_FuncDeclarator *f, uint32_t &varflags, int useflags, ZCC_StructWork *c);
Expand Down

0 comments on commit f98d68b

Please sign in to comment.