diff --git a/src/namedef.h b/src/namedef.h index ea4a7b890e..a5abfa5a12 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -730,3 +730,5 @@ xx(__decorate_internal_state__) xx(__decorate_internal_float__) xx(DamageFunction) +xx(Length) +xx(Unit) diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 039e428ff0..f8fd03946b 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -5535,6 +5535,18 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) PClass *cls; bool staticonly = false; + if (Self->IsVector()) + { + // handle builtins: Vectors got 2: Length and Unit. + if (MethodName == NAME_Length || MethodName == NAME_Unit) + { + auto x = new FxVectorBuiltin(Self, MethodName); + Self = nullptr; + delete this; + return x->Resolve(ctx); + } + } + if (Self->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer))) { cls = static_cast(Self->ValueType)->ClassRestriction; @@ -6096,6 +6108,51 @@ ExpEmit FxFlopFunctionCall::Emit(VMFunctionBuilder *build) return v; } + +//========================================================================== +// +// +//========================================================================== + +FxVectorBuiltin::FxVectorBuiltin(FxExpression *self, FName name) + :FxExpression(EFX_VectorBuiltin, self->ScriptPosition) +{ + Self = self; + Function = name; +} + +FxVectorBuiltin::~FxVectorBuiltin() +{ + SAFE_DELETE(Self); +} + +FxExpression *FxVectorBuiltin::Resolve(FCompileContext &ctx) +{ + SAFE_RESOLVE(Self, ctx); + assert(Self->IsVector()); // should never be created for anything else. + ValueType = Function == NAME_Length ? TypeFloat64 : Self->ValueType; + return this; +} + +ExpEmit FxVectorBuiltin::Emit(VMFunctionBuilder *build) +{ + ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount()); + ExpEmit op = Self->Emit(build); + if (Function == NAME_Length) + { + build->Emit(Self->ValueType == TypeVector2 ? OP_LENV2 : OP_LENV3, to.RegNum, op.RegNum); + } + else + { + ExpEmit len(build, REGT_FLOAT); + build->Emit(Self->ValueType == TypeVector2 ? OP_LENV2 : OP_LENV3, len.RegNum, op.RegNum); + build->Emit(Self->ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR, to.RegNum, op.RegNum, len.RegNum); + len.Free(build); + } + op.Free(build); + return to; +} + //========================================================================== // // FxSequence :: Resolve diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h index 570575bb98..6c7dec487a 100644 --- a/src/scripting/codegeneration/codegen.h +++ b/src/scripting/codegeneration/codegen.h @@ -266,6 +266,7 @@ enum EFxType EFX_SwitchStatement, EFX_CaseStatement, EFX_VectorInitializer, + EFX_VectorBuiltin, EFX_COUNT }; @@ -1254,6 +1255,25 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; +//========================================================================== +// +// FxFlopFunctionCall +// +//========================================================================== + +class FxVectorBuiltin : public FxExpression +{ + FName Function; + FxExpression *Self; + +public: + + FxVectorBuiltin(FxExpression *self, FName name); + ~FxVectorBuiltin(); + FxExpression *Resolve(FCompileContext&); + ExpEmit Emit(VMFunctionBuilder *build); +}; + //========================================================================== // // FxVMFunctionCall diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 6de64d07e5..3ab33bfd96 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -177,3 +177,5 @@ zscript/chex/chexweapons.txt zscript/chex/chexitems.txt zscript/chex/chexdecorations.txt zscript/chex/chexplayer.txt + +zscript/test2.txt