From 9cda2079a2ddf21b261dc8d6a01d6cec430ffd6f Mon Sep 17 00:00:00 2001 From: Lexikos Date: Sun, 8 Apr 2018 18:28:46 +1000 Subject: [PATCH 1/3] Added Object.Count() and ObjCount(Object). --- source/script.cpp | 1 + source/script.h | 1 + source/script_object.cpp | 10 ++++++++++ source/script_object.h | 2 ++ source/script_object_bif.cpp | 1 + 5 files changed, 15 insertions(+) diff --git a/source/script.cpp b/source/script.cpp index 381110e3e..8533931f9 100644 --- a/source/script.cpp +++ b/source/script.cpp @@ -8487,6 +8487,7 @@ Func *Script::FindFunc(LPCTSTR aFuncName, size_t aFuncNameLength, int *apInsertP BIF_OBJ_CASE(Remove, 0, 2) // [min_key, max_key] BIF_OBJ_CASE(RemoveAt, 1, 2) // position [, count] BIF_OBJ_CASE(Pop, 0, 0) + BIF_OBJ_CASE(Count, 0, 0) BIF_OBJ_CASE(Length, 0, 0) BIF_OBJ_CASE(MinIndex, 0, 0) BIF_OBJ_CASE(MaxIndex, 0, 0) diff --git a/source/script.h b/source/script.h index b0861fb0f..bc149521b 100644 --- a/source/script.h +++ b/source/script.h @@ -3315,6 +3315,7 @@ BIF_DECL(BIF_ObjRemoveAt); BIF_DECL(BIF_ObjGetCapacity); BIF_DECL(BIF_ObjSetCapacity); BIF_DECL(BIF_ObjGetAddress); +BIF_DECL(BIF_ObjCount); BIF_DECL(BIF_ObjLength); BIF_DECL(BIF_ObjMaxIndex); BIF_DECL(BIF_ObjMinIndex); diff --git a/source/script_object.cpp b/source/script_object.cpp index 6cacaf0e7..936c6194e 100644 --- a/source/script_object.cpp +++ b/source/script_object.cpp @@ -750,6 +750,9 @@ int Object::GetBuiltinID(LPCTSTR aName) case 'D': if (!_tcsicmp(aName, _T("Delete"))) return FID_ObjDelete; + case 'C': + if (!_tcsicmp(aName, _T("Count"))) + return FID_ObjCount; break; } // Older methods which support the _ prefix: @@ -816,6 +819,7 @@ ResultType Object::CallBuiltin(int aID, ExprTokenType &aResultToken, ExprTokenTy case_method(InsertAt); case_method(RemoveAt); case_method(Delete); + case_method(Count); case_method(MinIndex); case_method(GetAddress); case_method(SetCapacity); @@ -1291,6 +1295,12 @@ ResultType Object::_MinIndex(ExprTokenType &aResultToken, ExprTokenType *aParam[ return OK; } +ResultType Object::_Count(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount) +{ + aResultToken.SetValue((__int64)mFieldCount); + return OK; +} + ResultType Object::_Length(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount) { IntKeyType max_index = mKeyOffsetObject ? mFields[mKeyOffsetObject - 1].key.i : 0; diff --git a/source/script_object.h b/source/script_object.h index 460be6ae6..802b7dc20 100644 --- a/source/script_object.h +++ b/source/script_object.h @@ -13,6 +13,7 @@ enum ObjectMethodID { // Partially ported from v2 BuiltInFunctionID. Used for c FID_ObjInsertAt, FID_ObjDelete, FID_ObjRemoveAt, FID_ObjPush, FID_ObjPop, FID_ObjLength , FID_ObjHasKey, FID_ObjGetCapacity, FID_ObjSetCapacity, FID_ObjGetAddress, FID_ObjClone , FID_ObjNewEnum, FID_ObjMaxIndex, FID_ObjMinIndex, FID_ObjRemove, FID_ObjInsert + , FID_ObjCount }; @@ -337,6 +338,7 @@ class Object : public ObjectBase ResultType _GetCapacity(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); ResultType _SetCapacity(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); ResultType _GetAddress(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); + ResultType _Count(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); ResultType _Length(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); ResultType _MaxIndex(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); ResultType _MinIndex(ExprTokenType &aResultToken, ExprTokenType *aParam[], int aParamCount); diff --git a/source/script_object_bif.cpp b/source/script_object_bif.cpp index 5cb22c0f4..176999b58 100644 --- a/source/script_object_bif.cpp +++ b/source/script_object_bif.cpp @@ -379,6 +379,7 @@ BIF_METHOD(RemoveAt) BIF_METHOD(GetCapacity) BIF_METHOD(SetCapacity) BIF_METHOD(GetAddress) +BIF_METHOD(Count) BIF_METHOD(Length) BIF_METHOD(MaxIndex) BIF_METHOD(MinIndex) From 0ba82cdeee4244988ea5392e0125b4494bfec82d Mon Sep 17 00:00:00 2001 From: Lexikos Date: Sun, 8 Apr 2018 18:54:33 +1000 Subject: [PATCH 2/3] Added ObjGetBase(Object) and ObjSetBase(Object, Base). --- source/script.cpp | 8 ++++++++ source/script.h | 1 + source/script_object_bif.cpp | 37 +++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/source/script.cpp b/source/script.cpp index 8533931f9..325cb0cf5 100644 --- a/source/script.cpp +++ b/source/script.cpp @@ -8507,6 +8507,14 @@ Func *Script::FindFunc(LPCTSTR aFuncName, size_t aFuncNameLength, int *apInsertP min_params = 3; max_params = 3; } + else if (!_tcsicmp(suffix, _T("GetBase"))) + bif = BIF_ObjBase; + else if (!_tcsicmp(suffix, _T("SetBase"))) + { + bif = BIF_ObjBase; + min_params = 2; + max_params = 2; + } else return NULL; } else if (!_tcsicmp(func_name, _T("Array"))) diff --git a/source/script.h b/source/script.h index bc149521b..7c6b35bdc 100644 --- a/source/script.h +++ b/source/script.h @@ -3304,6 +3304,7 @@ BIF_DECL(BIF_ObjIncDec); // Pseudo-operator. BIF_DECL(BIF_ObjAddRefRelease); BIF_DECL(BIF_ObjBindMethod); BIF_DECL(BIF_ObjRawSet); +BIF_DECL(BIF_ObjBase); // Built-ins also available as methods -- these are available as functions for use primarily by overridden methods (i.e. where using the built-in methods isn't possible as they're no longer accessible). BIF_DECL(BIF_ObjInsert); BIF_DECL(BIF_ObjInsertAt); diff --git a/source/script_object_bif.cpp b/source/script_object_bif.cpp index 176999b58..f580b2a01 100644 --- a/source/script_object_bif.cpp +++ b/source/script_object_bif.cpp @@ -448,4 +448,39 @@ BIF_DECL(BIF_ObjRawSet) aResultToken.symbol = SYM_STRING; aResultToken.marker = _T(""); -} \ No newline at end of file +} + + +// +// ObjSetBase/ObjGetBase - Change or return Object's base without invoking any meta-functions. +// + +BIF_DECL(BIF_ObjBase) +{ + Object *obj = dynamic_cast(TokenToObject(*aParam[0])); + if (!obj) + { + aResult = g_script.ScriptError(ERR_PARAM1_INVALID); + return; + } + if (ctoupper(aResultToken.marker[3]) == 'S') // ObjSetBase + { + IObject *new_base = TokenToObject(*aParam[1]); + if (!new_base && !TokenIsEmptyString(*aParam[1])) + { + aResult = g_script.ScriptError(ERR_PARAM2_INVALID); + return; + } + obj->SetBase(new_base); + } + else // ObjGetBase + { + if (IObject *obj_base = obj->Base()) + { + obj_base->AddRef(); + aResultToken.SetValue(obj_base); + return; + } + } + aResultToken.SetValue(_T("")); +} From 01b91e864863a21d2d516337ec97e7021abffd37 Mon Sep 17 00:00:00 2001 From: Lexikos Date: Sun, 8 Apr 2018 20:21:27 +1000 Subject: [PATCH 3/3] Added ObjRawGet(Object, Key). --- source/script.cpp | 8 +++++++- source/script.h | 2 +- source/script_object.h | 24 ++++++++++++++--------- source/script_object_bif.cpp | 37 ++++++++++++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/source/script.cpp b/source/script.cpp index 325cb0cf5..6643326ec 100644 --- a/source/script.cpp +++ b/source/script.cpp @@ -8503,10 +8503,16 @@ Func *Script::FindFunc(LPCTSTR aFuncName, size_t aFuncNameLength, int *apInsertP bif = BIF_ObjAddRefRelease; else if (!_tcsicmp(suffix, _T("RawSet"))) { - bif = BIF_ObjRawSet; + bif = BIF_ObjRaw; min_params = 3; max_params = 3; } + else if (!_tcsicmp(suffix, _T("RawGet"))) + { + bif = BIF_ObjRaw; + min_params = 2; + max_params = 2; + } else if (!_tcsicmp(suffix, _T("GetBase"))) bif = BIF_ObjBase; else if (!_tcsicmp(suffix, _T("SetBase"))) diff --git a/source/script.h b/source/script.h index 7c6b35bdc..dca1aa2dc 100644 --- a/source/script.h +++ b/source/script.h @@ -3303,7 +3303,7 @@ BIF_DECL(BIF_ObjNew); // Pseudo-operator. BIF_DECL(BIF_ObjIncDec); // Pseudo-operator. BIF_DECL(BIF_ObjAddRefRelease); BIF_DECL(BIF_ObjBindMethod); -BIF_DECL(BIF_ObjRawSet); +BIF_DECL(BIF_ObjRaw); BIF_DECL(BIF_ObjBase); // Built-ins also available as methods -- these are available as functions for use primarily by overridden methods (i.e. where using the built-in methods isn't possible as they're no longer accessible). BIF_DECL(BIF_ObjInsert); diff --git a/source/script_object.h b/source/script_object.h index 802b7dc20..810812912 100644 --- a/source/script_object.h +++ b/source/script_object.h @@ -234,23 +234,29 @@ class Object : public ObjectBase { return (int)mKeyOffsetObject; } - - bool GetItem(ExprTokenType &aToken, LPTSTR aKey) + + bool GetItem(ExprTokenType &aToken, ExprTokenType &aKey) { - KeyType key; - SymbolType key_type = IsPureNumeric(aKey, FALSE, FALSE, FALSE); // SYM_STRING or SYM_INTEGER. - if (key_type == SYM_INTEGER) - key.i = Exp32or64(ATOI,ATOI64)(aKey); - else - key.s = aKey; IndexType insert_pos; - FieldType *field = FindField(key_type, key, insert_pos); + TCHAR buf[MAX_NUMBER_SIZE]; + SymbolType key_type; + KeyType key; + FieldType *field = FindField(aKey, buf, key_type, key, insert_pos); if (!field) return false; field->ToToken(aToken); return true; } + bool GetItem(ExprTokenType &aToken, LPTSTR aKey) + { + ExprTokenType key; + key.symbol = SYM_OPERAND; + key.marker = aKey; + key.buf = NULL; + return GetItem(aToken, key); + } + bool SetItem(ExprTokenType &aKey, ExprTokenType &aValue) { IndexType insert_pos; diff --git a/source/script_object_bif.cpp b/source/script_object_bif.cpp index f580b2a01..bd4c753e6 100644 --- a/source/script_object_bif.cpp +++ b/source/script_object_bif.cpp @@ -435,7 +435,7 @@ BIF_DECL(BIF_ObjBindMethod) // ObjRawSet - set a value without invoking any meta-functions. // -BIF_DECL(BIF_ObjRawSet) +BIF_DECL(BIF_ObjRaw) { Object *obj = dynamic_cast(TokenToObject(*aParam[0])); if (!obj) @@ -443,9 +443,38 @@ BIF_DECL(BIF_ObjRawSet) aResult = g_script.ScriptError(ERR_PARAM1_INVALID); return; } - if (!obj->SetItem(*aParam[1], *aParam[2])) - aResult = g_script.ScriptError(ERR_OUTOFMEM); - + if (ctoupper(aResultToken.marker[6]) == 'S') + { + if (!obj->SetItem(*aParam[1], *aParam[2])) + { + aResult = g_script.ScriptError(ERR_OUTOFMEM); + return; + } + } + else + { + ExprTokenType value; + if (obj->GetItem(value, *aParam[1])) + { + switch (value.symbol) + { + case SYM_OPERAND: + aResultToken.symbol = SYM_STRING; + aResult = TokenSetResult(aResultToken, value.marker); + break; + case SYM_OBJECT: + aResultToken.symbol = SYM_OBJECT; + aResultToken.object = value.object; + aResultToken.object->AddRef(); + break; + default: + aResultToken.symbol = value.symbol; + aResultToken.value_int64 = value.value_int64; + break; + } + return; + } + } aResultToken.symbol = SYM_STRING; aResultToken.marker = _T(""); }