mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 23:52:02 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom into master
This commit is contained in:
commit
6586877ac5
20 changed files with 297 additions and 223 deletions
|
@ -379,7 +379,7 @@ static void MarkRoot()
|
|||
Mark(PClass::AllClasses[i]);
|
||||
}
|
||||
// Mark global symbols
|
||||
GlobalSymbols.MarkSymbols();
|
||||
Namespaces.MarkSymbols();
|
||||
// Mark bot stuff.
|
||||
Mark(bglobal.firstthing);
|
||||
Mark(bglobal.body1);
|
||||
|
|
129
src/dobjtype.cpp
129
src/dobjtype.cpp
|
@ -65,8 +65,9 @@ EXTERN_CVAR(Bool, strictdecorate);
|
|||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
FNamespaceManager Namespaces;
|
||||
|
||||
FTypeTable TypeTable;
|
||||
PSymbolTable GlobalSymbols;
|
||||
TArray<PClass *> PClass::AllClasses;
|
||||
bool PClass::bShutdown;
|
||||
bool PClass::bVMOperational;
|
||||
|
@ -117,7 +118,7 @@ void DumpTypeTable()
|
|||
Printf("%4zu:", i);
|
||||
for (PType *ty = TypeTable.TypeHash[i]; ty != NULL; ty = ty->HashNext)
|
||||
{
|
||||
Printf(" -> %s", ty->IsKindOf(RUNTIME_CLASS(PNamedType)) ? static_cast<PNamedType*>(ty)->TypeName.GetChars(): ty->GetClass()->TypeName.GetChars());
|
||||
Printf(" -> %s", ty->DescriptiveName());
|
||||
len++;
|
||||
all++;
|
||||
}
|
||||
|
@ -434,7 +435,7 @@ void PType::StaticInit()
|
|||
|
||||
TypeVoidPtr = NewPointer(TypeVoid, false);
|
||||
TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value.
|
||||
TypeStringStruct = NewNativeStruct(NAME_String, nullptr);
|
||||
TypeStringStruct = NewNativeStruct("Stringstruct", nullptr);
|
||||
#ifdef __BIG_ENDIAN__
|
||||
TypeColorStruct->AddField(NAME_a, TypeUInt8);
|
||||
TypeColorStruct->AddField(NAME_r, TypeUInt8);
|
||||
|
@ -472,24 +473,24 @@ void PType::StaticInit()
|
|||
|
||||
|
||||
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_sByte, TypeSInt8));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Byte, TypeUInt8));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Short, TypeSInt16));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_uShort, TypeUInt16));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Int, TypeSInt32));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_uInt, TypeUInt32));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Bool, TypeBool));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Float, TypeFloat64));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Double, TypeFloat64));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Float32, TypeFloat32));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Float64, TypeFloat64));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_String, TypeString));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Name, TypeName));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Sound, TypeSound));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Color, TypeColor));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_State, TypeState));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Vector2, TypeVector2));
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(NAME_Vector3, TypeVector3));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_sByte, TypeSInt8));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Byte, TypeUInt8));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Short, TypeSInt16));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_uShort, TypeUInt16));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Int, TypeSInt32));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_uInt, TypeUInt32));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Bool, TypeBool));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Float, TypeFloat64));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Double, TypeFloat64));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Float32, TypeFloat32));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Float64, TypeFloat64));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_String, TypeString));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Name, TypeName));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Sound, TypeSound));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Color, TypeColor));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_State, TypeState));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Vector2, TypeVector2));
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Vector3, TypeVector3));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1692,7 +1693,7 @@ PClassPointer *NewClassPointer(PClass *restrict)
|
|||
IMPLEMENT_CLASS(PEnum, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(PEnum)
|
||||
IMPLEMENT_POINTER(ValueType)
|
||||
IMPLEMENT_POINTER(Outer)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1702,7 +1703,7 @@ IMPLEMENT_POINTERS_END
|
|||
//==========================================================================
|
||||
|
||||
PEnum::PEnum()
|
||||
: ValueType(NULL)
|
||||
: PInt(4, false)
|
||||
{
|
||||
mDescriptiveName = "Enum";
|
||||
}
|
||||
|
@ -1714,8 +1715,10 @@ PEnum::PEnum()
|
|||
//==========================================================================
|
||||
|
||||
PEnum::PEnum(FName name, PTypeBase *outer)
|
||||
: PNamedType(name, outer), ValueType(NULL)
|
||||
: PInt(4, false)
|
||||
{
|
||||
EnumName = name;
|
||||
Outer = outer;
|
||||
mDescriptiveName.Format("Enum<%s>", name.GetChars());
|
||||
}
|
||||
|
||||
|
@ -1731,6 +1734,7 @@ PEnum::PEnum(FName name, PTypeBase *outer)
|
|||
PEnum *NewEnum(FName name, PTypeBase *outer)
|
||||
{
|
||||
size_t bucket;
|
||||
if (outer == nullptr) outer = Namespaces.GlobalNamespace;
|
||||
PType *etype = TypeTable.FindType(RUNTIME_CLASS(PEnum), (intptr_t)outer, (intptr_t)name, &bucket);
|
||||
if (etype == NULL)
|
||||
{
|
||||
|
@ -2373,6 +2377,7 @@ size_t PStruct::PropagateMark()
|
|||
PStruct *NewStruct(FName name, PTypeBase *outer)
|
||||
{
|
||||
size_t bucket;
|
||||
if (outer == nullptr) outer = Namespaces.GlobalNamespace;
|
||||
PType *stype = TypeTable.FindType(RUNTIME_CLASS(PStruct), (intptr_t)outer, (intptr_t)name, &bucket);
|
||||
if (stype == NULL)
|
||||
{
|
||||
|
@ -2392,8 +2397,8 @@ IMPLEMENT_CLASS(PNativeStruct, false, false)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PNativeStruct::PNativeStruct(FName name)
|
||||
: PStruct(name, nullptr)
|
||||
PNativeStruct::PNativeStruct(FName name, PTypeBase *outer)
|
||||
: PStruct(name, outer)
|
||||
{
|
||||
mDescriptiveName.Format("NativeStruct<%s>", name.GetChars());
|
||||
Size = 0;
|
||||
|
@ -2411,10 +2416,11 @@ PNativeStruct::PNativeStruct(FName name)
|
|||
PNativeStruct *NewNativeStruct(FName name, PTypeBase *outer)
|
||||
{
|
||||
size_t bucket;
|
||||
if (outer == nullptr) outer = Namespaces.GlobalNamespace;
|
||||
PType *stype = TypeTable.FindType(RUNTIME_CLASS(PNativeStruct), (intptr_t)outer, (intptr_t)name, &bucket);
|
||||
if (stype == NULL)
|
||||
{
|
||||
stype = new PNativeStruct(name);
|
||||
stype = new PNativeStruct(name, outer);
|
||||
TypeTable.AddType(stype, RUNTIME_CLASS(PNativeStruct), (intptr_t)outer, (intptr_t)name, bucket);
|
||||
}
|
||||
return static_cast<PNativeStruct *>(stype);
|
||||
|
@ -2796,6 +2802,7 @@ void PClass::StaticInit ()
|
|||
atterm (StaticShutdown);
|
||||
|
||||
StaticBootstrap();
|
||||
Namespaces.GlobalNamespace = Namespaces.NewNamespace(0);
|
||||
|
||||
FAutoSegIterator probe(CRegHead, CRegTail);
|
||||
|
||||
|
@ -2843,7 +2850,7 @@ void PClass::StaticShutdown ()
|
|||
|
||||
// Unless something went wrong, anything left here should be class and type objects only, which do not own any scripts.
|
||||
TypeTable.Clear();
|
||||
GlobalSymbols.ReleaseSymbols();
|
||||
Namespaces.ReleaseSymbols();
|
||||
|
||||
for (i = 0; i < PClass::AllClasses.Size(); ++i)
|
||||
{
|
||||
|
@ -3039,14 +3046,14 @@ void PClass::InsertIntoHash ()
|
|||
size_t bucket;
|
||||
PType *found;
|
||||
|
||||
found = TypeTable.FindType(RUNTIME_CLASS(PClass), (intptr_t)Outer, TypeName, &bucket);
|
||||
found = TypeTable.FindType(RUNTIME_CLASS(PClass), 0, TypeName, &bucket);
|
||||
if (found != NULL)
|
||||
{ // This type has already been inserted
|
||||
I_Error("Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
TypeTable.AddType(this, RUNTIME_CLASS(PClass), (intptr_t)Outer, TypeName, bucket);
|
||||
TypeTable.AddType(this, RUNTIME_CLASS(PClass), 0, TypeName, bucket);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3084,8 +3091,7 @@ PClass *PClass::FindClass (FName zaname)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
return static_cast<PClass *>(TypeTable.FindType(RUNTIME_CLASS(PClass),
|
||||
/*FIXME:Outer*/0, zaname, NULL));
|
||||
return static_cast<PClass *>(TypeTable.FindType(RUNTIME_CLASS(PClass), 0, zaname, NULL));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -3376,7 +3382,7 @@ PClass *PClass::FindClassTentative(FName name)
|
|||
|
||||
Derive(type, name);
|
||||
type->Size = TentativeClass;
|
||||
TypeTable.AddType(type, RUNTIME_CLASS(PClass), (intptr_t)type->Outer, name, bucket);
|
||||
TypeTable.AddType(type, RUNTIME_CLASS(PClass), 0, name, bucket);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -3835,3 +3841,60 @@ PSymbol *PSymbolTable::ReplaceSymbol(PSymbol *newsym)
|
|||
Symbols.Insert(newsym->SymbolName, newsym);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(PNamespace, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(PNamespace)
|
||||
IMPLEMENT_POINTER(Parent)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
PNamespace::PNamespace(int filenum, PNamespace *parent)
|
||||
{
|
||||
Parent = parent;
|
||||
if (parent) Symbols.SetParentTable(&parent->Symbols);
|
||||
FileNum = filenum;
|
||||
}
|
||||
|
||||
size_t PNamespace::PropagateMark()
|
||||
{
|
||||
GC::Mark(Parent);
|
||||
return Symbols.MarkSymbols() + 1;
|
||||
}
|
||||
|
||||
FNamespaceManager::FNamespaceManager()
|
||||
{
|
||||
GlobalNamespace = nullptr;
|
||||
}
|
||||
|
||||
PNamespace *FNamespaceManager::NewNamespace(int filenum)
|
||||
{
|
||||
PNamespace *parent = nullptr;
|
||||
// The parent will be the last namespace with this or a lower filenum.
|
||||
// This ensures that DECORATE won't see the symbols of later files.
|
||||
for (int i = AllNamespaces.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (AllNamespaces[i]->FileNum <= filenum)
|
||||
{
|
||||
parent = AllNamespaces[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto newns = new PNamespace(filenum, parent);
|
||||
AllNamespaces.Push(newns);
|
||||
return newns;
|
||||
}
|
||||
|
||||
size_t FNamespaceManager::MarkSymbols()
|
||||
{
|
||||
for (auto ns : AllNamespaces)
|
||||
{
|
||||
GC::Mark(ns);
|
||||
}
|
||||
return AllNamespaces.Size();
|
||||
}
|
||||
|
||||
void FNamespaceManager::ReleaseSymbols()
|
||||
{
|
||||
GlobalNamespace = nullptr;
|
||||
AllNamespaces.Clear();
|
||||
}
|
||||
|
|
|
@ -171,8 +171,6 @@ public:
|
|||
PSymbolTreeNode() : PSymbol(NAME_None) {}
|
||||
};
|
||||
|
||||
extern PSymbolTable GlobalSymbols;
|
||||
|
||||
// Basic information shared by all types ------------------------------------
|
||||
|
||||
// Only one copy of a type is ever instantiated at one time.
|
||||
|
@ -593,15 +591,15 @@ protected:
|
|||
|
||||
// Compound types -----------------------------------------------------------
|
||||
|
||||
class PEnum : public PNamedType
|
||||
class PEnum : public PInt
|
||||
{
|
||||
DECLARE_CLASS(PEnum, PNamedType);
|
||||
DECLARE_CLASS(PEnum, PInt);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PEnum(FName name, PTypeBase *outer);
|
||||
|
||||
PType *ValueType;
|
||||
TMap<FName, int> Values;
|
||||
PTypeBase *Outer;
|
||||
FName EnumName;
|
||||
protected:
|
||||
PEnum();
|
||||
};
|
||||
|
@ -710,7 +708,7 @@ class PNativeStruct : public PStruct
|
|||
{
|
||||
DECLARE_CLASS(PNativeStruct, PStruct);
|
||||
public:
|
||||
PNativeStruct(FName name = NAME_None);
|
||||
PNativeStruct(FName name = NAME_None, PTypeBase *outer = nullptr);
|
||||
};
|
||||
|
||||
class PPrototype : public PCompoundType
|
||||
|
@ -986,31 +984,39 @@ public:
|
|||
PSymbolConstString() {}
|
||||
};
|
||||
|
||||
// Enumerations for serializing types in an archive -------------------------
|
||||
// Namespaces --------------------------------------------------
|
||||
|
||||
enum ETypeVal : BYTE
|
||||
class PNamespace : public PTypeBase
|
||||
{
|
||||
VAL_Int8,
|
||||
VAL_UInt8,
|
||||
VAL_Int16,
|
||||
VAL_UInt16,
|
||||
VAL_Int32,
|
||||
VAL_UInt32,
|
||||
VAL_Int64,
|
||||
VAL_UInt64,
|
||||
VAL_Zero,
|
||||
VAL_One,
|
||||
VAL_Float32,
|
||||
VAL_Float64,
|
||||
VAL_String,
|
||||
VAL_Name,
|
||||
VAL_Struct,
|
||||
VAL_Array,
|
||||
VAL_Object,
|
||||
VAL_State,
|
||||
VAL_Class,
|
||||
DECLARE_CLASS(PNamespace, PTypeBase)
|
||||
HAS_OBJECT_POINTERS;
|
||||
|
||||
public:
|
||||
PSymbolTable Symbols;
|
||||
PNamespace *Parent;
|
||||
int FileNum; // This is for blocking DECORATE access to later files.
|
||||
|
||||
PNamespace() {}
|
||||
PNamespace(int filenum, PNamespace *parent);
|
||||
size_t PropagateMark();
|
||||
};
|
||||
|
||||
struct FNamespaceManager
|
||||
{
|
||||
PNamespace *GlobalNamespace;
|
||||
TArray<PNamespace *> AllNamespaces;
|
||||
|
||||
FNamespaceManager();
|
||||
PNamespace *NewNamespace(int filenum);
|
||||
size_t MarkSymbols();
|
||||
void ReleaseSymbols();
|
||||
};
|
||||
|
||||
extern FNamespaceManager Namespaces;
|
||||
|
||||
|
||||
// Enumerations for serializing types in an archive -------------------------
|
||||
|
||||
inline bool &DObject::BoolVar(FName field)
|
||||
{
|
||||
return *(bool*)ScriptVar(field, TypeBool);
|
||||
|
|
|
@ -95,14 +95,14 @@ static const FLOP FxFlops[] =
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FCompileContext::FCompileContext(PFunction *fnc, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump)
|
||||
: ReturnProto(ret), Function(fnc), Class(nullptr), FromDecorate(fromdecorate), StateIndex(stateindex), StateCount(statecount), Lump(lump)
|
||||
FCompileContext::FCompileContext(PNamespace *cg, PFunction *fnc, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump)
|
||||
: ReturnProto(ret), Function(fnc), Class(nullptr), FromDecorate(fromdecorate), StateIndex(stateindex), StateCount(statecount), Lump(lump), CurGlobals(cg)
|
||||
{
|
||||
if (fnc != nullptr) Class = fnc->OwningClass;
|
||||
}
|
||||
|
||||
FCompileContext::FCompileContext(PStruct *cls, bool fromdecorate)
|
||||
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1)
|
||||
FCompileContext::FCompileContext(PNamespace *cg, PStruct *cls, bool fromdecorate)
|
||||
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1), CurGlobals(cg)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ PSymbol *FCompileContext::FindInSelfClass(FName identifier, PSymbolTable *&symt)
|
|||
}
|
||||
PSymbol *FCompileContext::FindGlobal(FName identifier)
|
||||
{
|
||||
return GlobalSymbols.FindSymbol(identifier, true);
|
||||
return CurGlobals->Symbols.FindSymbol(identifier, true);
|
||||
}
|
||||
|
||||
void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos)
|
||||
|
@ -185,16 +185,30 @@ FxLocalVariableDeclaration *FCompileContext::FindLocalVariable(FName name)
|
|||
}
|
||||
}
|
||||
|
||||
static PStruct *FindStructType(FName name)
|
||||
static PStruct *FindStructType(FName name, FCompileContext &ctx)
|
||||
{
|
||||
PStruct *ccls = PClass::FindClass(name);
|
||||
if (ccls == nullptr)
|
||||
auto sym = ctx.Class->Symbols.FindSymbol(name, true);
|
||||
if (sym == nullptr) sym = ctx.CurGlobals->Symbols.FindSymbol(name, true);
|
||||
if (sym && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
|
||||
{
|
||||
ccls = dyn_cast<PStruct>(TypeTable.FindType(RUNTIME_CLASS(PStruct), 0, (intptr_t)name, nullptr));
|
||||
if (ccls == nullptr) ccls = dyn_cast<PStruct>(TypeTable.FindType(RUNTIME_CLASS(PNativeStruct), 0, (intptr_t)name, nullptr));
|
||||
auto type = static_cast<PSymbolType*>(sym);
|
||||
return dyn_cast<PStruct>(type->Type);
|
||||
}
|
||||
return ccls;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is for resolving class identifiers which need to be context aware, unlike class names.
|
||||
static PClass *FindClassType(FName name, FCompileContext &ctx)
|
||||
{
|
||||
auto sym = ctx.CurGlobals->Symbols.FindSymbol(name, true);
|
||||
if (sym && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
|
||||
{
|
||||
auto type = static_cast<PSymbolType*>(sym);
|
||||
return dyn_cast<PClass>(type->Type);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExpEmit
|
||||
|
@ -235,7 +249,7 @@ void ExpEmit::Reuse(VMFunctionBuilder *build)
|
|||
|
||||
static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCallType func)
|
||||
{
|
||||
PSymbol *sym = GlobalSymbols.FindSymbol(funcname, false);
|
||||
PSymbol *sym = Namespaces.GlobalNamespace->Symbols.FindSymbol(funcname, false);
|
||||
if (sym == nullptr)
|
||||
{
|
||||
PSymbolVMFunction *symfunc = new PSymbolVMFunction(funcname);
|
||||
|
@ -243,7 +257,7 @@ static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCall
|
|||
calldec->PrintableName = funcname.GetChars();
|
||||
symfunc->Function = calldec;
|
||||
sym = symfunc;
|
||||
GlobalSymbols.AddSymbol(sym);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(sym);
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
@ -5918,7 +5932,7 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
// If the left side is a class name for a static member function call it needs to be resolved manually
|
||||
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
|
||||
ccls = FindStructType(static_cast<FxIdentifier *>(Object)->Identifier);
|
||||
ccls = FindStructType(static_cast<FxIdentifier *>(Object)->Identifier, ctx);
|
||||
if (ccls != nullptr) static_cast<FxIdentifier *>(Object)->noglobal = true;
|
||||
}
|
||||
|
||||
|
@ -7256,7 +7270,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
|||
return x->Resolve(ctx);
|
||||
}
|
||||
|
||||
PClass *cls = PClass::FindClass(MethodName);
|
||||
PClass *cls = FindClassType(MethodName, ctx);
|
||||
if (cls != nullptr && cls->bExported)
|
||||
{
|
||||
if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition))
|
||||
|
@ -7487,9 +7501,11 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
|
||||
if (Self->ExprType == EFX_Identifier)
|
||||
{
|
||||
auto id = static_cast<FxIdentifier *>(Self)->Identifier;
|
||||
// If the left side is a class name for a static member function call it needs to be resolved manually
|
||||
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
|
||||
ccls = FindStructType(static_cast<FxIdentifier *>(Self)->Identifier);
|
||||
if (id == NAME_String) ccls = TypeStringStruct;
|
||||
else ccls = FindStructType(id, ctx);
|
||||
if (ccls != nullptr) static_cast<FxIdentifier *>(Self)->noglobal = true;
|
||||
}
|
||||
|
||||
|
@ -7500,8 +7516,6 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (ccls != nullptr)
|
||||
{
|
||||
// [ZZ] substitute ccls for String internal type.
|
||||
if (ccls->TypeName == NAME_String)
|
||||
ccls = TypeStringStruct;
|
||||
if (!ccls->IsKindOf(RUNTIME_CLASS(PClass)) || static_cast<PClass *>(ccls)->bExported)
|
||||
{
|
||||
cls = ccls;
|
||||
|
@ -9977,7 +9991,7 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
|
|||
|
||||
if (clsname != NAME_None)
|
||||
{
|
||||
cls = PClass::FindClass(clsname);
|
||||
cls = FindClassType(clsname, ctx);
|
||||
if (cls == nullptr)
|
||||
{
|
||||
/* lax */
|
||||
|
|
|
@ -84,9 +84,10 @@ struct FCompileContext
|
|||
int Lump;
|
||||
bool Unsafe = false;
|
||||
TDeletingArray<FxLocalVariableDeclaration *> FunctionArgs;
|
||||
PNamespace *CurGlobals;
|
||||
|
||||
FCompileContext(PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump);
|
||||
FCompileContext(PStruct *cls, bool fromdecorate); // only to be used to resolve constants!
|
||||
FCompileContext(PNamespace *spc, PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump);
|
||||
FCompileContext(PNamespace *spc, PStruct *cls, bool fromdecorate); // only to be used to resolve constants!
|
||||
|
||||
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
|
||||
PSymbol *FindInSelfClass(FName identifier, PSymbolTable *&symt);
|
||||
|
|
|
@ -100,7 +100,7 @@ static const char *RenderStyles[] =
|
|||
//==========================================================================
|
||||
PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FName typeName);
|
||||
|
||||
void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
||||
void ParseOldDecoration(FScanner &sc, EDefinitionType def, PNamespace *ns)
|
||||
{
|
||||
Baggage bag;
|
||||
TArray<FState> StateArray;
|
||||
|
@ -116,6 +116,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
typeName = FName(sc.String);
|
||||
type = DecoDerivedClass(FScriptPosition(sc), parent, typeName);
|
||||
ResetBaggage(&bag, parent);
|
||||
bag.Namespace = ns;
|
||||
bag.Info = type;
|
||||
bag.fromDecorate = true;
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -82,13 +82,13 @@ static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls);
|
|||
static FxExpression *ParseExpressionA (FScanner &sc, PClassActor *cls);
|
||||
static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls);
|
||||
|
||||
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve)
|
||||
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, PNamespace *spc)
|
||||
{
|
||||
FxExpression *data = ParseExpressionM (sc, cls);
|
||||
|
||||
if (mustresolve)
|
||||
if (spc)
|
||||
{
|
||||
FCompileContext ctx(cls, true);
|
||||
FCompileContext ctx(spc, cls, true);
|
||||
data = data->Resolve(ctx);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "v_text.h"
|
||||
#include "m_argv.h"
|
||||
|
||||
void ParseOldDecoration(FScanner &sc, EDefinitionType def);
|
||||
void ParseOldDecoration(FScanner &sc, EDefinitionType def, PNamespace *ns);
|
||||
EXTERN_CVAR(Bool, strictdecorate);
|
||||
|
||||
|
||||
|
@ -101,12 +101,11 @@ PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FN
|
|||
//
|
||||
// ParseParameter
|
||||
//
|
||||
// Parses a parameter - either a default in a function declaration
|
||||
// or an argument in a function call.
|
||||
// Parses an argument in a function call.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant)
|
||||
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type)
|
||||
{
|
||||
FxExpression *x = NULL;
|
||||
int v;
|
||||
|
@ -118,12 +117,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
|
|||
}
|
||||
else if (type == TypeBool || type == TypeSInt32 || type == TypeFloat64)
|
||||
{
|
||||
x = ParseExpression (sc, cls, constant);
|
||||
if (constant && !x->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("Default parameter must be constant.");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
x = ParseExpression (sc, cls, nullptr);
|
||||
// Do automatic coercion between bools, ints and floats.
|
||||
if (type == TypeBool)
|
||||
{
|
||||
|
@ -193,11 +187,10 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
|
|||
x = new FxMultiNameState(sc.String, sc);
|
||||
}
|
||||
}
|
||||
else if (!constant)
|
||||
else
|
||||
{
|
||||
x = new FxRuntimeStateIndex(ParseExpression(sc, cls));
|
||||
}
|
||||
else sc.MustGetToken(TK_StringConst); // This is for the error.
|
||||
}
|
||||
else if (type->GetClass() == RUNTIME_CLASS(PClassPointer))
|
||||
{ // Actor name
|
||||
|
@ -222,7 +215,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
||||
static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls, PNamespace *ns)
|
||||
{
|
||||
// Read the type and make sure it's int or float.
|
||||
if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Float))
|
||||
|
@ -231,7 +224,7 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
sc.MustGetToken(TK_Identifier);
|
||||
FName symname = sc.String;
|
||||
sc.MustGetToken('=');
|
||||
FxExpression *expr = ParseExpression (sc, cls, true);
|
||||
FxExpression *expr = ParseExpression (sc, cls, ns);
|
||||
sc.MustGetToken(';');
|
||||
|
||||
if (expr == nullptr)
|
||||
|
@ -283,7 +276,7 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
||||
static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls, PNamespace *ns)
|
||||
{
|
||||
int currvalue = 0;
|
||||
|
||||
|
@ -294,7 +287,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
FName symname = sc.String;
|
||||
if (sc.CheckToken('='))
|
||||
{
|
||||
FxExpression *expr = ParseExpression (sc, cls, true);
|
||||
FxExpression *expr = ParseExpression (sc, cls, ns);
|
||||
if (expr != nullptr)
|
||||
{
|
||||
if (!expr->isConstant())
|
||||
|
@ -339,7 +332,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
||||
static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cls, PNamespace *ns)
|
||||
{
|
||||
PType *type;
|
||||
int maxelems = 1;
|
||||
|
@ -381,7 +374,7 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
|
|||
|
||||
if (sc.CheckToken('['))
|
||||
{
|
||||
FxExpression *expr = ParseExpression(sc, cls, true);
|
||||
FxExpression *expr = ParseExpression(sc, cls, ns);
|
||||
if (expr == nullptr)
|
||||
{
|
||||
sc.ScriptMessage("Error while resolving array size");
|
||||
|
@ -1112,11 +1105,12 @@ static PClassActor *ParseActorHeader(FScanner &sc, Baggage *bag)
|
|||
// Reads an actor definition
|
||||
//
|
||||
//==========================================================================
|
||||
static void ParseActor(FScanner &sc)
|
||||
static void ParseActor(FScanner &sc, PNamespace *ns)
|
||||
{
|
||||
PClassActor *info = NULL;
|
||||
Baggage bag;
|
||||
|
||||
bag.Namespace = ns;
|
||||
bag.fromDecorate = true;
|
||||
info = ParseActorHeader(sc, &bag);
|
||||
sc.MustGetToken('{');
|
||||
|
@ -1125,15 +1119,15 @@ static void ParseActor(FScanner &sc)
|
|||
switch (sc.TokenType)
|
||||
{
|
||||
case TK_Const:
|
||||
ParseConstant (sc, &info->Symbols, info);
|
||||
ParseConstant (sc, &info->Symbols, info, ns);
|
||||
break;
|
||||
|
||||
case TK_Enum:
|
||||
ParseEnum (sc, &info->Symbols, info);
|
||||
ParseEnum (sc, &info->Symbols, info, ns);
|
||||
break;
|
||||
|
||||
case TK_Var:
|
||||
ParseUserVariable (sc, &info->Symbols, info);
|
||||
ParseUserVariable (sc, &info->Symbols, info, ns);
|
||||
break;
|
||||
|
||||
case TK_Identifier:
|
||||
|
@ -1225,6 +1219,7 @@ static void ParseDamageDefinition(FScanner &sc)
|
|||
|
||||
void ParseDecorate (FScanner &sc)
|
||||
{
|
||||
auto ns = Namespaces.NewNamespace(sc.LumpNum);
|
||||
// Get actor class name.
|
||||
for(;;)
|
||||
{
|
||||
|
@ -1255,11 +1250,11 @@ void ParseDecorate (FScanner &sc)
|
|||
}
|
||||
|
||||
case TK_Const:
|
||||
ParseConstant (sc, &GlobalSymbols, NULL);
|
||||
ParseConstant (sc, &ns->Symbols, NULL, ns);
|
||||
break;
|
||||
|
||||
case TK_Enum:
|
||||
ParseEnum (sc, &GlobalSymbols, NULL);
|
||||
ParseEnum (sc, &ns->Symbols, NULL, ns);
|
||||
break;
|
||||
|
||||
case ';':
|
||||
|
@ -1275,22 +1270,22 @@ void ParseDecorate (FScanner &sc)
|
|||
// so let's do a special case for this.
|
||||
if (sc.Compare("ACTOR"))
|
||||
{
|
||||
ParseActor (sc);
|
||||
ParseActor (sc, ns);
|
||||
break;
|
||||
}
|
||||
else if (sc.Compare("PICKUP"))
|
||||
{
|
||||
ParseOldDecoration (sc, DEF_Pickup);
|
||||
ParseOldDecoration (sc, DEF_Pickup, ns);
|
||||
break;
|
||||
}
|
||||
else if (sc.Compare("BREAKABLE"))
|
||||
{
|
||||
ParseOldDecoration (sc, DEF_BreakableDecoration);
|
||||
ParseOldDecoration (sc, DEF_BreakableDecoration, ns);
|
||||
break;
|
||||
}
|
||||
else if (sc.Compare("PROJECTILE"))
|
||||
{
|
||||
ParseOldDecoration (sc, DEF_Projectile);
|
||||
ParseOldDecoration (sc, DEF_Projectile, ns);
|
||||
break;
|
||||
}
|
||||
else if (sc.Compare("DAMAGETYPE"))
|
||||
|
@ -1300,7 +1295,7 @@ void ParseDecorate (FScanner &sc)
|
|||
}
|
||||
default:
|
||||
sc.RestorePos(pos);
|
||||
ParseOldDecoration(sc, DEF_Decoration);
|
||||
ParseOldDecoration(sc, DEF_Decoration, ns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,7 +343,7 @@ endofstate:
|
|||
if (ScriptCode != nullptr)
|
||||
{
|
||||
auto funcsym = CreateAnonymousFunction(actor, nullptr, state.UseFlags);
|
||||
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, ScriptCode, FStringf("%s.StateFunction.%d", actor->TypeName.GetChars(), bag.statedef.GetStateCount()), true, bag.statedef.GetStateCount(), int(statestring.Len()), sc.LumpNum);
|
||||
state.ActionFunc = FunctionBuildList.AddFunction(bag.Namespace, funcsym, ScriptCode, FStringf("%s.StateFunction.%d", actor->TypeName.GetChars(), bag.statedef.GetStateCount()), true, bag.statedef.GetStateCount(), int(statestring.Len()), sc.LumpNum);
|
||||
}
|
||||
int count = bag.statedef.AddStates(&state, statestring, scp);
|
||||
if (count < 0)
|
||||
|
@ -671,7 +671,7 @@ void ParseFunctionParameters(FScanner &sc, PClassActor *cls, TArray<FxExpression
|
|||
else
|
||||
{
|
||||
// Use the generic parameter parser for everything else
|
||||
x = ParseParameter(sc, cls, params[pnum], false);
|
||||
x = ParseParameter(sc, cls, params[pnum]);
|
||||
}
|
||||
out_params.Push(x);
|
||||
pnum++;
|
||||
|
|
|
@ -216,7 +216,7 @@ PFunction *FindClassMemberFunction(PStruct *selfcls, PStruct *funccls, FName nam
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate, int lumpnum)
|
||||
void CreateDamageFunction(PNamespace *OutNamespace, PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate, int lumpnum)
|
||||
{
|
||||
if (id == nullptr)
|
||||
{
|
||||
|
@ -226,7 +226,7 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
|
|||
{
|
||||
auto dmg = new FxReturnStatement(new FxIntCast(id, true), id->ScriptPosition);
|
||||
auto funcsym = CreateAnonymousFunction(info, TypeSInt32, 0);
|
||||
defaults->DamageFunc = FunctionBuildList.AddFunction(funcsym, dmg, FStringf("%s.DamageFunction", info->TypeName.GetChars()), fromDecorate, -1, 0, lumpnum);
|
||||
defaults->DamageFunc = FunctionBuildList.AddFunction(OutNamespace, funcsym, dmg, FStringf("%s.DamageFunction", info->TypeName.GetChars()), fromDecorate, -1, 0, lumpnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ struct Baggage
|
|||
#ifdef _DEBUG
|
||||
FString ClassName; // This is here so that during debugging the class name can be seen
|
||||
#endif
|
||||
PNamespace *Namespace;
|
||||
PClassActor *Info;
|
||||
bool DropItemSet;
|
||||
bool StateSet;
|
||||
|
@ -132,7 +133,7 @@ struct Baggage
|
|||
|
||||
inline void ResetBaggage (Baggage *bag, PClassActor *stateclass)
|
||||
{
|
||||
bag->DropItemList = NULL;
|
||||
bag->DropItemList = nullptr;
|
||||
bag->DropItemSet = false;
|
||||
bag->CurrentState = 0;
|
||||
bag->fromDecorate = true;
|
||||
|
@ -150,7 +151,7 @@ AFuncDesc *FindFunction(PStruct *cls, const char * string);
|
|||
FieldDesc *FindField(PStruct *cls, const char * string);
|
||||
|
||||
|
||||
FxExpression *ParseExpression(FScanner &sc, PClassActor *cls, bool mustresolve = false);
|
||||
FxExpression *ParseExpression(FScanner &sc, PClassActor *cls, PNamespace *resolvenspc = nullptr);
|
||||
void ParseStates(FScanner &sc, PClassActor *actor, AActor *defaults, Baggage &bag);
|
||||
void ParseFunctionParameters(FScanner &sc, PClassActor *cls, TArray<FxExpression *> &out_params,
|
||||
PFunction *afd, FString statestring, FStateDefinitions *statedef);
|
||||
|
@ -160,7 +161,7 @@ FName CheckCastKludges(FName in);
|
|||
void SetImplicitArgs(TArray<PType *> *args, TArray<DWORD> *argflags, TArray<FName> *argnames, PStruct *cls, DWORD funcflags, int useflags);
|
||||
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags);
|
||||
PFunction *FindClassMemberFunction(PStruct *cls, PStruct *funccls, FName name, FScriptPosition &sc, bool *error);
|
||||
void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate, int lumpnum);
|
||||
void CreateDamageFunction(PNamespace *ns, PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate, int lumpnum);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -169,7 +170,7 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
|
|||
//==========================================================================
|
||||
|
||||
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
|
||||
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant);
|
||||
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type);
|
||||
|
||||
|
||||
enum
|
||||
|
|
|
@ -762,16 +762,16 @@ void InitThingdef()
|
|||
|
||||
// expose the global validcount variable.
|
||||
PField *vcf = new PField("validcount", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&validcount);
|
||||
GlobalSymbols.AddSymbol(vcf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(vcf);
|
||||
|
||||
// expose the global Multiplayer variable.
|
||||
PField *multif = new PField("multiplayer", TypeBool, VARF_Native | VARF_ReadOnly | VARF_Static, (intptr_t)&multiplayer);
|
||||
GlobalSymbols.AddSymbol(multif);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(multif);
|
||||
|
||||
// set up a variable for the global level data structure
|
||||
PStruct *lstruct = NewNativeStruct("LevelLocals", nullptr);
|
||||
PField *levelf = new PField("level", lstruct, VARF_Native | VARF_Static, (intptr_t)&level);
|
||||
GlobalSymbols.AddSymbol(levelf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(levelf);
|
||||
|
||||
// Add the game data arrays to LevelLocals.
|
||||
lstruct->AddNativeField("sectors", NewPointer(NewResizableArray(sectorstruct), false), myoffsetof(FLevelLocals, sectors), VARF_Native);
|
||||
|
@ -783,17 +783,17 @@ void InitThingdef()
|
|||
|
||||
auto aact = NewPointer(NewResizableArray(NewClassPointer(RUNTIME_CLASS(AActor))), true);
|
||||
PField *aacf = new PField("AllActorClasses", aact, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&PClassActor::AllActorClasses);
|
||||
GlobalSymbols.AddSymbol(aacf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(aacf);
|
||||
|
||||
// set up a variable for the DEH data
|
||||
PStruct *dstruct = NewNativeStruct("DehInfo", nullptr);
|
||||
PField *dehf = new PField("deh", dstruct, VARF_Native | VARF_Static, (intptr_t)&deh);
|
||||
GlobalSymbols.AddSymbol(dehf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(dehf);
|
||||
|
||||
// set up a variable for the global gameinfo data
|
||||
PStruct *gistruct = NewNativeStruct("GameInfoStruct", nullptr);
|
||||
PField *gi = new PField("gameinfo", gistruct, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gameinfo);
|
||||
GlobalSymbols.AddSymbol(gi);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(gi);
|
||||
|
||||
// set up a variable for the global players array.
|
||||
PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
|
||||
|
@ -801,33 +801,33 @@ void InitThingdef()
|
|||
pstruct->Align = alignof(player_t);
|
||||
PArray *parray = NewArray(pstruct, MAXPLAYERS);
|
||||
PField *playerf = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
pstruct->AddNativeField("weapons", NewNativeStruct("WeaponSlots", nullptr), myoffsetof(player_t, weapons), VARF_Native);
|
||||
|
||||
|
||||
parray = NewArray(TypeBool, MAXPLAYERS);
|
||||
playerf = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
playerf = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
playerf = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
playerf = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
playerf = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
// Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag.
|
||||
// It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'
|
||||
// is to create a static variable from it and reference that in the script. Yuck!!!
|
||||
static AWeapon *wpnochg = WP_NOCHANGE;
|
||||
playerf = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(playerf);
|
||||
|
||||
// synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them.
|
||||
for (auto &fl : FlagLists)
|
||||
|
@ -936,7 +936,7 @@ DEFINE_ACTION_FUNCTION(FStringTable, Localize)
|
|||
ACTION_RETURN_STRING(GStrings(&label[1]));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FString, Replace)
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Replace)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
PARAM_STRING(s1);
|
||||
|
@ -1103,14 +1103,14 @@ static FString FStringFormat(VM_ARGS)
|
|||
return output;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FString, Format)
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, Format)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
FString s = FStringFormat(param, defaultparam, numparam, ret, numret);
|
||||
ACTION_RETURN_STRING(s);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FString, AppendFormat)
|
||||
DEFINE_ACTION_FUNCTION(FStringStruct, AppendFormat)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||
// first parameter is the self pointer
|
||||
|
|
|
@ -689,7 +689,7 @@ DEFINE_PROPERTY(damage, X, Actor)
|
|||
|
||||
defaults->DamageVal = dmgval;
|
||||
// Only DECORATE can get here with a valid expression.
|
||||
CreateDamageFunction(bag.Info, defaults, id, true, bag.Lumpnum);
|
||||
CreateDamageFunction(bag.Namespace, bag.Info, defaults, id, true, bag.Lumpnum);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -802,7 +802,7 @@ void VMFunctionBuilder::BackpatchListToHere(TArray<size_t> &locs)
|
|||
//==========================================================================
|
||||
FFunctionBuildList FunctionBuildList;
|
||||
|
||||
VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount, int lumpnum)
|
||||
VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount, int lumpnum)
|
||||
{
|
||||
auto func = code->GetDirectFunction();
|
||||
if (func != nullptr)
|
||||
|
@ -814,6 +814,8 @@ VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *c
|
|||
//Printf("Adding %s\n", name.GetChars());
|
||||
|
||||
Item it;
|
||||
assert(gnspc != nullptr);
|
||||
it.CurGlobals = gnspc;
|
||||
it.Func = functype;
|
||||
it.Code = code;
|
||||
it.PrintableName = name;
|
||||
|
@ -853,7 +855,7 @@ void FFunctionBuildList::Build()
|
|||
assert(item.Code != NULL);
|
||||
|
||||
// We don't know the return type in advance for anonymous functions.
|
||||
FCompileContext ctx(item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount, item.Lump);
|
||||
FCompileContext ctx(item.CurGlobals, item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount, item.Lump);
|
||||
|
||||
// Allocate registers for the function's arguments and create local variable nodes before starting to resolve it.
|
||||
VMFunctionBuilder buildit(item.Func->GetImplicitArgs());
|
||||
|
|
|
@ -141,6 +141,7 @@ class FFunctionBuildList
|
|||
FxExpression *Code = nullptr;
|
||||
PPrototype *Proto = nullptr;
|
||||
VMScriptFunction *Function = nullptr;
|
||||
PNamespace *CurGlobals = nullptr;
|
||||
FString PrintableName;
|
||||
int StateIndex;
|
||||
int StateCount;
|
||||
|
@ -151,7 +152,7 @@ class FFunctionBuildList
|
|||
TArray<Item> mItems;
|
||||
|
||||
public:
|
||||
VMFunction *AddFunction(PFunction *func, FxExpression *code, const FString &name, bool fromdecorate, int currentstate, int statecnt, int lumpnum);
|
||||
VMFunction *AddFunction(PNamespace *curglobals, PFunction *func, FxExpression *code, const FString &name, bool fromdecorate, int currentstate, int statecnt, int lumpnum);
|
||||
void Build();
|
||||
};
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ static FString GetStringConst(FxExpression *ex, FCompileContext &ctx)
|
|||
|
||||
int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PStruct *cls)
|
||||
{
|
||||
FCompileContext ctx(cls, false);
|
||||
FCompileContext ctx(OutNamespace, cls, false);
|
||||
FxExpression *ex = new FxIntCast(ConvertNode(node), false);
|
||||
ex = ex->Resolve(ctx);
|
||||
if (ex == nullptr) return 0;
|
||||
|
@ -88,7 +88,7 @@ int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PStruct *cls)
|
|||
|
||||
FString ZCCCompiler::StringConstFromNode(ZCC_TreeNode *node, PStruct *cls)
|
||||
{
|
||||
FCompileContext ctx(cls, false);
|
||||
FCompileContext ctx(OutNamespace, cls, false);
|
||||
FxExpression *ex = new FxStringCast(ConvertNode(node));
|
||||
ex = ex->Resolve(ctx);
|
||||
if (ex == nullptr) return "";
|
||||
|
@ -155,6 +155,11 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
|||
break;
|
||||
|
||||
case AST_Struct:
|
||||
if (static_cast<ZCC_Struct *>(node)->Flags & VARF_Native)
|
||||
{
|
||||
Error(node, "Cannot define native structs inside classes");
|
||||
static_cast<ZCC_Struct *>(node)->Flags &= ~VARF_Native;
|
||||
}
|
||||
ProcessStruct(static_cast<ZCC_Struct *>(node), childnode, cls->cls);
|
||||
break;
|
||||
|
||||
|
@ -271,8 +276,8 @@ void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZC
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, PSymbolTable &_outsymbols, int lumpnum)
|
||||
: Outer(_outer), GlobalTreeNodes(&_symbols), OutputSymbols(&_outsymbols), AST(ast), Lump(lumpnum)
|
||||
ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, PNamespace *_outnamespc, int lumpnum)
|
||||
: Outer(_outer), GlobalTreeNodes(&_symbols), OutNamespace(_outnamespc), AST(ast), Lump(lumpnum)
|
||||
{
|
||||
FScriptPosition::ResetErrorCounter();
|
||||
// Group top-level nodes by type
|
||||
|
@ -303,8 +308,8 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
|
|||
{
|
||||
case AST_Enum:
|
||||
zenumType = static_cast<ZCC_Enum *>(node);
|
||||
enumType = NewEnum(zenumType->NodeName, nullptr);
|
||||
GlobalSymbols.AddSymbol(new PSymbolType(zenumType->NodeName, enumType));
|
||||
enumType = NewEnum(zenumType->NodeName, OutNamespace);
|
||||
OutNamespace->Symbols.AddSymbol(new PSymbolType(zenumType->NodeName, enumType));
|
||||
break;
|
||||
|
||||
case AST_Class:
|
||||
|
@ -468,13 +473,31 @@ void ZCCCompiler::CreateStructTypes()
|
|||
{
|
||||
for(auto s : Structs)
|
||||
{
|
||||
PTypeBase *outer;
|
||||
PSymbolTable *syms;
|
||||
|
||||
s->Outer = s->OuterDef == nullptr? nullptr : s->OuterDef->CType();
|
||||
if (s->strct->Flags & ZCC_Native)
|
||||
s->strct->Type = NewNativeStruct(s->NodeName(), nullptr);
|
||||
if (s->Outer)
|
||||
{
|
||||
outer = s->Outer;
|
||||
syms = &s->Outer->Symbols;
|
||||
}
|
||||
else
|
||||
s->strct->Type = NewStruct(s->NodeName(), s->Outer);
|
||||
{
|
||||
outer = OutNamespace;
|
||||
syms = &OutNamespace->Symbols;
|
||||
}
|
||||
|
||||
if (s->strct->Flags & ZCC_Native)
|
||||
{
|
||||
s->strct->Type = NewNativeStruct(s->NodeName(), outer);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->strct->Type = NewStruct(s->NodeName(), outer);
|
||||
}
|
||||
s->strct->Symbol = new PSymbolType(s->NodeName(), s->Type());
|
||||
GlobalSymbols.AddSymbol(s->strct->Symbol);
|
||||
syms->AddSymbol(s->strct->Symbol);
|
||||
|
||||
for (auto e : s->Enums)
|
||||
{
|
||||
|
@ -577,7 +600,7 @@ void ZCCCompiler::CreateClassTypes()
|
|||
if (c->Type() == nullptr) c->cls->Type = parent->FindClassTentative(c->NodeName());
|
||||
c->Type()->bExported = true; // this class is accessible to script side type casts. (The reason for this flag is that types like PInt need to be skipped.)
|
||||
c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type());
|
||||
GlobalSymbols.AddSymbol(c->cls->Symbol);
|
||||
OutNamespace->Symbols.AddSymbol(c->cls->Symbol);
|
||||
Classes.Push(c);
|
||||
OrigClasses.Delete(i--);
|
||||
donesomething = true;
|
||||
|
@ -601,7 +624,7 @@ void ZCCCompiler::CreateClassTypes()
|
|||
// create a placeholder so that the compiler can continue looking for errors.
|
||||
c->cls->Type = RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName());
|
||||
c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type());
|
||||
GlobalSymbols.AddSymbol(c->cls->Symbol);
|
||||
OutNamespace->Symbols.AddSymbol(c->cls->Symbol);
|
||||
Classes.Push(c);
|
||||
OrigClasses.Delete(i--);
|
||||
donesomething = true;
|
||||
|
@ -617,7 +640,7 @@ void ZCCCompiler::CreateClassTypes()
|
|||
Error(c->cls, "Class %s has circular inheritance", FName(c->NodeName()).GetChars());
|
||||
c->cls->Type = RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName());
|
||||
c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type());
|
||||
GlobalSymbols.AddSymbol(c->cls->Symbol);
|
||||
OutNamespace->Symbols.AddSymbol(c->cls->Symbol);
|
||||
Classes.Push(c);
|
||||
}
|
||||
|
||||
|
@ -678,7 +701,7 @@ void ZCCCompiler::CompileAllConstants()
|
|||
// put all constants in one list to make resolving this easier.
|
||||
TArray<ZCC_ConstantWork> constantwork;
|
||||
|
||||
CopyConstants(constantwork, Constants, nullptr, OutputSymbols);
|
||||
CopyConstants(constantwork, Constants, nullptr, &OutNamespace->Symbols);
|
||||
for (auto c : Classes)
|
||||
{
|
||||
CopyConstants(constantwork, c->Constants, c->Type(), &c->Type()->Symbols);
|
||||
|
@ -810,7 +833,7 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant)
|
|||
|
||||
bool ZCCCompiler::CompileConstant(ZCC_ConstantWork *work)
|
||||
{
|
||||
FCompileContext ctx(work->cls, false);
|
||||
FCompileContext ctx(OutNamespace, work->cls, false);
|
||||
FxExpression *exp = ConvertNode(work->node->Value);
|
||||
try
|
||||
{
|
||||
|
@ -836,49 +859,6 @@ bool ZCCCompiler::CompileConstant(ZCC_ConstantWork *work)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: IdentifyIdentifier
|
||||
//
|
||||
// Returns a node that represents what the identifer stands for.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode, PSymbolTable *symt)
|
||||
{
|
||||
// Check the symbol table for the identifier.
|
||||
PSymbolTable *table;
|
||||
PSymbol *sym = symt->FindSymbolInTable(idnode->Identifier, table);
|
||||
// GlobalSymbols cannot be the parent of a class's symbol table so we have to look for global symbols explicitly.
|
||||
if (sym == nullptr && symt != &GlobalSymbols) sym = GlobalSymbols.FindSymbolInTable(idnode->Identifier, table);
|
||||
if (sym != nullptr)
|
||||
{
|
||||
ZCC_Expression *node = NodeFromSymbol(sym, idnode, table);
|
||||
if (node != NULL)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
else if (SimplifyingConstant) // leave unknown identifiers alone when simplifying non-constants. It is impossible to know what they are here.
|
||||
{
|
||||
// Also handle line specials.
|
||||
// To call this like a function this needs to be done differently, but for resolving constants this is ok.
|
||||
int spec = P_FindLineSpecial(FName(idnode->Identifier).GetChars());
|
||||
if (spec != 0)
|
||||
{
|
||||
ZCC_ExprConstant *val = static_cast<ZCC_ExprConstant *>(AST.InitNode(sizeof(*val), AST_ExprConstant, idnode));
|
||||
val->Operation = PEX_ConstValue;
|
||||
val->Type = TypeSInt32;
|
||||
val->IntVal = spec;
|
||||
return val;
|
||||
}
|
||||
|
||||
Error(idnode, "Unknown identifier '%s'", FName(idnode->Identifier).GetChars());
|
||||
idnode->ToErrorNode();
|
||||
}
|
||||
return idnode;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: NodeFromSymbol
|
||||
|
@ -1056,6 +1036,7 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fiel
|
|||
{
|
||||
auto field = Fields[0];
|
||||
FieldDesc *fd = nullptr;
|
||||
FString str = FName(field->Names[0].Name).GetChars();
|
||||
|
||||
PType *fieldtype = DetermineType(type, field, field->Names->Name, field->Type, true, true);
|
||||
|
||||
|
@ -1394,10 +1375,15 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
}
|
||||
else
|
||||
{
|
||||
// This doesn't check the class list directly but the current symbol table to ensure that
|
||||
// this does not reference a type that got shadowed by a more local definition.
|
||||
// We first look in the current class and its parents, and then in the current namespace and its parents.
|
||||
auto sym = outertype->Symbols.FindSymbol(ctype->Restriction->Id, true);
|
||||
if (sym == nullptr) sym = GlobalSymbols.FindSymbol(ctype->Restriction->Id, false);
|
||||
if (sym == nullptr) sym = OutNamespace->Symbols.FindSymbol(ctype->Restriction->Id, true);
|
||||
if (sym == nullptr)
|
||||
{
|
||||
// A symbol with a given name cannot be reached from this definition point, so
|
||||
// even if a class with the given name exists, it is not accessible.
|
||||
Error(field, "%s: Unknown identifier", FName(ctype->Restriction->Id).GetChars());
|
||||
return TypeError;
|
||||
}
|
||||
|
@ -1434,10 +1420,9 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt)
|
||||
{
|
||||
// Check the symbol table for the identifier.
|
||||
PSymbolTable *table;
|
||||
PSymbol *sym = symt->FindSymbolInTable(type->UserType->Id, table);
|
||||
// GlobalSymbols cannot be the parent of a class's symbol table so we have to look for global symbols explicitly.
|
||||
if (sym == nullptr && symt != &GlobalSymbols) sym = GlobalSymbols.FindSymbolInTable(type->UserType->Id, table);
|
||||
PSymbol *sym = symt->FindSymbol(type->UserType->Id, true);
|
||||
// We first look in the current class and its parents, and then in the current namespace and its parents.
|
||||
if (sym == nullptr) sym = OutNamespace->Symbols.FindSymbol(type->UserType->Id, true);
|
||||
if (sym != nullptr && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
|
||||
{
|
||||
auto ptype = static_cast<PSymbolType *>(sym)->Type;
|
||||
|
@ -1477,7 +1462,7 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
|
|||
} while (node != arraysize);
|
||||
|
||||
|
||||
FCompileContext ctx(cls, false);
|
||||
FCompileContext ctx(OutNamespace, cls, false);
|
||||
for (auto node : indices)
|
||||
{
|
||||
// There is no float->int casting here.
|
||||
|
@ -1526,7 +1511,7 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper
|
|||
const char * p = prop->params;
|
||||
auto exp = property->Values;
|
||||
|
||||
FCompileContext ctx(bag.Info, false);
|
||||
FCompileContext ctx(OutNamespace, bag.Info, false);
|
||||
while (true)
|
||||
{
|
||||
FPropParam conv;
|
||||
|
@ -1693,7 +1678,7 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop
|
|||
}
|
||||
|
||||
auto exp = property->Values;
|
||||
FCompileContext ctx(bag.Info, false);
|
||||
FCompileContext ctx(OutNamespace, bag.Info, false);
|
||||
for (auto f : prop->Variables)
|
||||
{
|
||||
void *addr;
|
||||
|
@ -1775,7 +1760,7 @@ void ZCCCompiler::ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *pro
|
|||
if (namenode->Id == NAME_DamageFunction)
|
||||
{
|
||||
auto x = ConvertNode(prop->Values);
|
||||
CreateDamageFunction(cls, (AActor *)bag.Info->Defaults, x, false, Lump);
|
||||
CreateDamageFunction(OutNamespace, cls, (AActor *)bag.Info->Defaults, x, false, Lump);
|
||||
((AActor *)bag.Info->Defaults)->DamageVal = -1;
|
||||
return;
|
||||
}
|
||||
|
@ -1923,6 +1908,7 @@ void ZCCCompiler::InitDefaults()
|
|||
#ifdef _DEBUG
|
||||
bag.ClassName = c->Type()->TypeName;
|
||||
#endif
|
||||
bag.Namespace = OutNamespace;
|
||||
bag.Info = ti;
|
||||
bag.DropItemSet = false;
|
||||
bag.StateSet = false;
|
||||
|
@ -2150,7 +2136,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
// It will also lose important type info about enums, once these get implemented
|
||||
// The code generator can do this properly for us.
|
||||
FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false);
|
||||
FCompileContext ctx(c->Type(), false);
|
||||
FCompileContext ctx(OutNamespace, c->Type(), false);
|
||||
x = x->Resolve(ctx);
|
||||
|
||||
if (x != nullptr)
|
||||
|
@ -2258,7 +2244,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
auto code = ConvertAST(c->Type(), f->Body);
|
||||
if (code != nullptr)
|
||||
{
|
||||
FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||
FunctionBuildList.AddFunction(OutNamespace, sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2527,7 +2513,7 @@ void ZCCCompiler::CompileStates()
|
|||
{
|
||||
state.sprite = GetSpriteIndex(sl->Sprite->GetChars());
|
||||
}
|
||||
FCompileContext ctx(c->Type(), false);
|
||||
FCompileContext ctx(OutNamespace, c->Type(), false);
|
||||
if (CheckRandom(sl->Duration))
|
||||
{
|
||||
auto func = static_cast<ZCC_ExprFuncCall *>(sl->Duration);
|
||||
|
@ -2581,7 +2567,7 @@ void ZCCCompiler::CompileStates()
|
|||
if (code != nullptr)
|
||||
{
|
||||
auto funcsym = CreateAnonymousFunction(c->Type(), nullptr, state.UseFlags);
|
||||
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, code, FStringf("%s.StateFunction.%d", c->Type()->TypeName.GetChars(), statedef.GetStateCount()), false, statedef.GetStateCount(), (int)sl->Frames->Len(), Lump);
|
||||
state.ActionFunc = FunctionBuildList.AddFunction(OutNamespace, funcsym, code, FStringf("%s.StateFunction.%d", c->Type()->TypeName.GetChars(), statedef.GetStateCount()), false, statedef.GetStateCount(), (int)sl->Frames->Len(), Lump);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,13 +86,13 @@ struct ZCC_ConstantWork
|
|||
class ZCCCompiler
|
||||
{
|
||||
public:
|
||||
ZCCCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols, PSymbolTable &outsymbols, int lumpnum);
|
||||
ZCCCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols, PNamespace *outnamespace, int lumpnum);
|
||||
~ZCCCompiler();
|
||||
int Compile();
|
||||
|
||||
private:
|
||||
int IntConstFromNode(ZCC_TreeNode *node, PStruct *cls);
|
||||
FString ZCCCompiler::StringConstFromNode(ZCC_TreeNode *node, PStruct *cls);
|
||||
FString StringConstFromNode(ZCC_TreeNode *node, PStruct *cls);
|
||||
void ProcessClass(ZCC_Class *node, PSymbolTreeNode *tnode);
|
||||
void ProcessStruct(ZCC_Struct *node, PSymbolTreeNode *tnode, ZCC_Class *outer);
|
||||
void CreateStructTypes();
|
||||
|
@ -130,7 +130,6 @@ private:
|
|||
|
||||
PSymbolTreeNode *AddTreeNode(FName name, ZCC_TreeNode *node, PSymbolTable *treenodes, bool searchparents = false);
|
||||
|
||||
ZCC_Expression *IdentifyIdentifier(ZCC_ExprID *idnode, PSymbolTable *sym);
|
||||
ZCC_Expression *NodeFromSymbol(PSymbol *sym, ZCC_Expression *source, PSymbolTable *table);
|
||||
ZCC_ExprConstant *NodeFromSymbolConst(PSymbolConst *sym, ZCC_Expression *idnode);
|
||||
ZCC_ExprTypeRef *NodeFromSymbolType(PSymbolType *sym, ZCC_Expression *idnode);
|
||||
|
@ -147,7 +146,7 @@ private:
|
|||
DObject *Outer;
|
||||
PStruct *ConvertClass; // class type to be used when resoving symbols while converting an AST
|
||||
PSymbolTable *GlobalTreeNodes;
|
||||
PSymbolTable *OutputSymbols;
|
||||
PNamespace *OutNamespace;
|
||||
ZCC_AST &AST;
|
||||
int Lump;
|
||||
};
|
||||
|
|
|
@ -226,6 +226,8 @@ static void InitTokenMap()
|
|||
#undef TOKENDEF
|
||||
#undef TOKENDEF2
|
||||
|
||||
//**--------------------------------------------------------------------------
|
||||
|
||||
static void ParseSingleFile(const char *filename, int lump, void *parser, ZCCParseState &state)
|
||||
{
|
||||
int tokentype;
|
||||
|
@ -311,6 +313,8 @@ parse_end:
|
|||
state.sc = nullptr;
|
||||
}
|
||||
|
||||
//**--------------------------------------------------------------------------
|
||||
|
||||
static void DoParse(int lumpnum)
|
||||
{
|
||||
FScanner sc;
|
||||
|
@ -395,7 +399,8 @@ static void DoParse(int lumpnum)
|
|||
}
|
||||
|
||||
PSymbolTable symtable;
|
||||
ZCCCompiler cc(state, NULL, symtable, GlobalSymbols, lumpnum);
|
||||
auto newns = Wads.GetLumpFile(lumpnum) == 0 ? Namespaces.GlobalNamespace : Namespaces.NewNamespace(Wads.GetLumpFile(lumpnum));
|
||||
ZCCCompiler cc(state, NULL, symtable, newns, lumpnum);
|
||||
cc.Compile();
|
||||
|
||||
if (FScriptPosition::ErrorCounter > 0)
|
||||
|
|
|
@ -305,7 +305,7 @@ enum EPickStart
|
|||
}
|
||||
|
||||
// Although String is a builtin type, this is a convenient way to attach methods to it.
|
||||
struct String native
|
||||
struct StringStruct native
|
||||
{
|
||||
native void Replace(String pattern, String replacement);
|
||||
native static vararg String Format(String fmt, ...);
|
||||
|
|
|
@ -127,7 +127,7 @@ extend class PlayerPawn
|
|||
{
|
||||
let armoritem = BasicArmorPickup(Spawn("BasicArmorPickup"));
|
||||
armoritem.SaveAmount = 100*deh.BlueAC;
|
||||
armoritem.SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : 0.5;
|
||||
armoritem.SavePercent = gameinfo.Armor2Percent > 0 ? gameinfo.Armor2Percent * 100 : 50;
|
||||
if (!armoritem.CallTryPickup (self))
|
||||
{
|
||||
armoritem.Destroy ();
|
||||
|
|
Loading…
Reference in a new issue