diff --git a/src/dobject.cpp b/src/dobject.cpp index 8e209e640..4ca08a79d 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -425,11 +425,22 @@ void DObject::SerializeUserVars(FArchive &arc) while (it.NextPair(pair)) { - PSymbolVariable *var = dyn_cast(pair->Value); - if (var != NULL && var->bUserVar) + PField *var = dyn_cast(pair->Value); + if (var != NULL && !(var->Flags & VARF_Native)) { - count = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1; - varloc = (int *)(reinterpret_cast(this) + var->offset); + PType *type = var->Type; + PArray *arraytype = dyn_cast(type); + if (arraytype == NULL) + { + count = 1; + } + else + { + count = arraytype->ElementCount; + type = arraytype->ElementType; + } + assert(type == TypeSInt32); + varloc = (int *)(reinterpret_cast(this) + var->Offset); arc << var->SymbolName; arc.WriteCount(count); @@ -450,13 +461,24 @@ void DObject::SerializeUserVars(FArchive &arc) arc << varname; while (varname != NAME_None) { - PSymbolVariable *var = dyn_cast(symt->FindSymbol(varname, true)); + PField *var = dyn_cast(symt->FindSymbol(varname, true)); DWORD wanted = 0; - if (var != NULL && var->bUserVar) + if (var != NULL && !(var->Flags & VARF_Native)) { - wanted = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1; - varloc = (int *)(reinterpret_cast(this) + var->offset); + PType *type = var->Type; + PArray *arraytype = dyn_cast(type); + if (arraytype != NULL) + { + wanted = arraytype->ElementCount; + type = arraytype->ElementType; + } + else + { + wanted = 1; + } + assert(type == TypeSInt32); + varloc = (int *)(reinterpret_cast(this) + var->Offset); } count = arc.ReadCount(); for (j = 0; j < MIN(wanted, count); ++j) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index fdb85a892..f10a07ad1 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2287,7 +2287,6 @@ CCMD(typetable) IMPLEMENT_ABSTRACT_CLASS(PSymbol); IMPLEMENT_CLASS(PSymbolConst); -IMPLEMENT_CLASS(PSymbolVariable); IMPLEMENT_POINTY_CLASS(PSymbolVMFunction) DECLARE_POINTER(Function) END_POINTERS diff --git a/src/dobjtype.h b/src/dobjtype.h index 0018d38c4..dad47d44c 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -49,21 +49,6 @@ public: PSymbolConst() : PSymbol(NAME_None) {} }; -// A variable --------------------------------------------------------- - -class PSymbolVariable : public PSymbol -{ - DECLARE_CLASS(PSymbolVariable, PSymbol); -public: - FExpressionType ValueType; - //int size; - intptr_t offset; - bool bUserVar; - - PSymbolVariable(FName name) : PSymbol(name) {} - PSymbolVariable() : PSymbol(NAME_None) {} -}; - // An action function ------------------------------------------------------- struct FState; diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index 30ad5c3f3..0c7cfcfa7 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -700,10 +700,10 @@ class FxClassMember : public FxExpression { public: FxExpression *classx; - PSymbolVariable *membervar; + PField *membervar; bool AddressRequested; - FxClassMember(FxExpression*, PSymbolVariable*, const FScriptPosition&); + FxClassMember(FxExpression*, PField*, const FScriptPosition&); ~FxClassMember(); FxExpression *Resolve(FCompileContext&); void RequestAddress(); diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index aed00e339..d5fd9b0d2 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -2261,10 +2261,10 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars()); newex = FxConstant::MakeConstant(sym, ScriptPosition); } - else if (sym->IsKindOf(RUNTIME_CLASS(PSymbolVariable))) + else if (sym->IsKindOf(RUNTIME_CLASS(PField))) { - PSymbolVariable *vsym = static_cast(sym); - ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->offset); + PField *vsym = static_cast(sym); + ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->Offset); newex = new FxClassMember((new FxSelf(ScriptPosition))->Resolve(ctx), vsym, ScriptPosition); } else @@ -2370,7 +2370,7 @@ ExpEmit FxSelf::Emit(VMFunctionBuilder *build) // //========================================================================== -FxClassMember::FxClassMember(FxExpression *x, PSymbolVariable* mem, const FScriptPosition &pos) +FxClassMember::FxClassMember(FxExpression *x, PField* mem, const FScriptPosition &pos) : FxExpression(pos) { classx = x; @@ -2418,30 +2418,35 @@ FxExpression *FxClassMember::Resolve(FCompileContext &ctx) delete this; return NULL; } - switch (membervar->ValueType.Type) + PType *type = membervar->Type; + PArray *arraytype = dyn_cast(type); + + if (arraytype != NULL) + { + type = arraytype->ElementType; + } + if (type->IsKindOf(RUNTIME_CLASS(PPointer))) + { + ValueType = VAL_Object; + } + else if (type->IsKindOf(RUNTIME_CLASS(PInt))) { - case VAL_Int: - case VAL_Bool: ValueType = VAL_Int; - break; - - case VAL_Float: - case VAL_Fixed: - case VAL_Angle: + } + else if (type->IsKindOf(RUNTIME_CLASS(PFloat))) + { ValueType = VAL_Float; - break; - - case VAL_Object: - case VAL_Class: - case VAL_Array: - ValueType = membervar->ValueType; - break; - - default: + } + else + { ScriptPosition.Message(MSG_ERROR, "Invalid type for member variable %s", membervar->SymbolName.GetChars()); delete this; return NULL; } + if (arraytype != NULL) + { + ValueType.MakeArray(arraytype->ElementCount); + } return this; } @@ -2452,17 +2457,17 @@ ExpEmit FxClassMember::Emit(VMFunctionBuilder *build) if (AddressRequested) { - if (membervar->offset == 0) + if (membervar->Offset == 0) { return obj; } obj.Free(build); ExpEmit out(build, REGT_POINTER); - build->Emit(OP_ADDA_RK, out.RegNum, obj.RegNum, build->GetConstantInt((int)membervar->offset)); + build->Emit(OP_ADDA_RK, out.RegNum, obj.RegNum, build->GetConstantInt((int)membervar->Offset)); return out; } - int offsetreg = build->GetConstantInt((int)membervar->offset); + int offsetreg = build->GetConstantInt((int)membervar->Offset); ExpEmit loc, tmp; if (obj.Konst) @@ -2476,53 +2481,8 @@ ExpEmit FxClassMember::Emit(VMFunctionBuilder *build) obj = newobj; } - switch (membervar->ValueType.Type) - { - case VAL_Int: - case VAL_Sound: - case VAL_Name: - case VAL_Color: - loc = ExpEmit(build, REGT_INT); - build->Emit(OP_LW, loc.RegNum, obj.RegNum, offsetreg); - break; - - case VAL_Bool: - loc = ExpEmit(build, REGT_INT); - // Some implementations have 1 byte bools, and others have - // 4 byte bools. For all I know, there might be some with - // 2 byte bools, too. - build->Emit((sizeof(bool) == 1 ? OP_LBU : sizeof(bool) == 2 ? OP_LHU : OP_LW), - loc.RegNum, obj.RegNum, offsetreg); - break; - - case VAL_Float: - loc = ExpEmit(build, REGT_FLOAT); - build->Emit(OP_LDP, loc.RegNum, obj.RegNum, offsetreg); - break; - - case VAL_Fixed: - loc = ExpEmit(build, REGT_FLOAT); - build->Emit(OP_LX, loc.RegNum, obj.RegNum, offsetreg); - break; - - case VAL_Angle: - loc = ExpEmit(build, REGT_FLOAT); - tmp = ExpEmit(build, REGT_INT); - build->Emit(OP_LW, tmp.RegNum, obj.RegNum, offsetreg); - build->Emit(OP_CAST, loc.RegNum, tmp.RegNum, CAST_I2F); - build->Emit(OP_MULF_RK, loc.RegNum, loc.RegNum, build->GetConstantFloat(90.0 / ANGLE_90)); - tmp.Free(build); - break; - - case VAL_Object: - case VAL_Class: - loc = ExpEmit(build, REGT_POINTER); - build->Emit(OP_LO, loc.RegNum, obj.RegNum, offsetreg); - break; - - default: - assert(0); - } + loc = ExpEmit(build, membervar->Type->GetRegType()); + build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, obj.RegNum, offsetreg); obj.Free(build); return loc; } diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 17cb90135..50a9f7f53 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -288,7 +288,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls) static void ParseNativeVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cls) { - FExpressionType valuetype; + PType *valuetype; if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { @@ -301,27 +301,23 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable *symt, PClassActor * switch (sc.TokenType) { case TK_Int: - valuetype = VAL_Int; + valuetype = TypeSInt32; break; case TK_Float: - valuetype = VAL_Float; + valuetype = TypeFloat64; break; case TK_Angle_t: - valuetype = VAL_Angle; + valuetype = TypeAngle; break; case TK_Fixed_t: - valuetype = VAL_Fixed; - break; - - case TK_Bool: - valuetype = VAL_Bool; + valuetype = TypeFixed; break; case TK_Identifier: - valuetype = VAL_Object; + valuetype = NULL; // Todo: Object type sc.ScriptError("Object type variables not implemented yet!"); break; @@ -343,7 +339,7 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable *symt, PClassActor * int maxelems = static_cast(expr)->GetValue().GetInt(); delete expr; sc.MustGetToken(']'); - valuetype.MakeArray(maxelems); + valuetype = NewArray(valuetype, maxelems); } sc.MustGetToken(';'); @@ -353,18 +349,20 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable *symt, PClassActor * sc.ScriptError("Unknown native variable '%s'", symname.GetChars()); } - PSymbolVariable *sym = new PSymbolVariable(symname); - sym->offset = vi->address; // todo - sym->ValueType = valuetype; - sym->bUserVar = false; + PField *sym = new PField(symname, valuetype, VARF_Native); + sym->Offset = (unsigned)vi->address; // todo - if (symt->AddSymbol (sym) == NULL) + if (symt->AddSymbol(sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } + else + { + cls->Fields.Push(sym); + } } //========================================================================== @@ -377,7 +375,8 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable *symt, PClassActor * static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cls) { - FExpressionType valuetype; + PType *type; + int maxelems = 1; // Only non-native classes may have user variables. if (!cls->bRuntimeClass) @@ -392,7 +391,7 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl sc.ScriptMessage("User variables must be of type int"); FScriptPosition::ErrorCounter++; } - valuetype = VAL_Int; + type = TypeSInt32; sc.MustGetToken(TK_Identifier); // For now, restrict user variables to those that begin with "user_" to guarantee @@ -407,7 +406,6 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl if (sc.CheckToken('[')) { FxExpression *expr = ParseExpression(sc, cls); - int maxelems; if (!expr->isConstant()) { sc.ScriptMessage("Array size must be a constant"); @@ -425,14 +423,12 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl FScriptPosition::ErrorCounter++; maxelems = 1; } - valuetype.MakeArray(maxelems); + type = NewArray(type, maxelems); } sc.MustGetToken(';'); - PSymbolVariable *sym = new PSymbolVariable(symname); - sym->offset = cls->Extend(sizeof(int) * (valuetype.Type == VAL_Array ? valuetype.size : 1)); - sym->ValueType = valuetype; - sym->bUserVar = true; + PField *sym = new PField(symname, type, 0); + sym->Offset = cls->Extend(sizeof(int) * maxelems); if (symt->AddSymbol(sym) == NULL) { delete sym;