Add scan_array opcode
This commit is contained in:
parent
2f732ef209
commit
2dcae640c9
|
@ -55,6 +55,8 @@ public:
|
|||
virtual ProgramValue GetArray(const ProgramValue& key) = 0;
|
||||
virtual void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset) = 0;
|
||||
virtual void ResizeArray(int newLen) = 0;
|
||||
virtual ProgramValue ScanArray(const ProgramValue& value, ValueCompareStrings& cmp) = 0;
|
||||
|
||||
virtual ~SFallArray() = default;
|
||||
};
|
||||
|
||||
|
@ -127,6 +129,16 @@ public:
|
|||
ListSort(values, newLen, std::less<ProgramValue>());
|
||||
}
|
||||
}
|
||||
|
||||
ProgramValue ScanArray(const ProgramValue& value, ValueCompareStrings& cmp)
|
||||
{
|
||||
for (size_t i = 0; i < size(); i++) {
|
||||
if (cmp(value, values[i])) {
|
||||
return ProgramValue(i);
|
||||
}
|
||||
}
|
||||
return ProgramValue(-1);
|
||||
}
|
||||
};
|
||||
|
||||
class SFallArrayAssoc : public SFallArray {
|
||||
|
@ -232,6 +244,16 @@ public:
|
|||
MapSort(newLen);
|
||||
}
|
||||
};
|
||||
|
||||
ProgramValue ScanArray(const ProgramValue& value, ValueCompareStrings& cmp)
|
||||
{
|
||||
for (const auto &pair : map) {
|
||||
if (cmp(pair.second, value)) {
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
return ProgramValue(-1);
|
||||
}
|
||||
};
|
||||
|
||||
void SFallArrayAssoc::MapSort(int type)
|
||||
|
@ -389,4 +411,14 @@ int StackArray(const ProgramValue& key, const ProgramValue& val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, ValueCompareStrings& cmp)
|
||||
{
|
||||
auto arr = get_array_by_id(array_id);
|
||||
if (!arr) {
|
||||
return ProgramValue(-1);
|
||||
};
|
||||
|
||||
return arr->ScanArray(val, cmp);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "interpreter.h"
|
||||
#include "object.h"
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
|
||||
namespace fallout {
|
||||
|
@ -13,6 +14,8 @@ namespace fallout {
|
|||
|
||||
using ArrayId = unsigned int;
|
||||
|
||||
using ValueCompareStrings = const std::function<bool(const ProgramValue&, const ProgramValue&)>;
|
||||
|
||||
ArrayId CreateArray(int len, uint32_t flags);
|
||||
ArrayId CreateTempArray(int len, uint32_t flags);
|
||||
ProgramValue GetArrayKey(ArrayId array_id, int index);
|
||||
|
@ -25,6 +28,7 @@ void ResizeArray(ArrayId array_id, int newLen);
|
|||
void DeleteAllTempArrays();
|
||||
void sfallArraysReset();
|
||||
int StackArray(const ProgramValue& key, const ProgramValue& val);
|
||||
ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, ValueCompareStrings& cmp);
|
||||
|
||||
}
|
||||
#endif /* SFALL_ARRAYS */
|
|
@ -533,18 +533,37 @@ static void opSetArray(Program* program)
|
|||
SetArray(arrayId, key, value, true);
|
||||
}
|
||||
|
||||
|
||||
// arrayexpr
|
||||
static void opStackArray(Program* program)
|
||||
{
|
||||
auto value = programStackPopValue(program);
|
||||
auto key = programStackPopValue(program);
|
||||
auto key = programStackPopValue(program);
|
||||
auto returnValue = StackArray(key, value);
|
||||
programStackPushInteger(program, returnValue);
|
||||
}
|
||||
|
||||
// scan array
|
||||
static void opScanArray(Program* program)
|
||||
{
|
||||
auto value = programStackPopValue(program);
|
||||
auto arrayId = programStackPopInteger(program);
|
||||
|
||||
|
||||
auto returnValue = ScanArray(arrayId, value, [&program](const ProgramValue& a, const ProgramValue& b) -> bool {
|
||||
if (!a.isString()) {
|
||||
return a == b;
|
||||
};
|
||||
if (!b.isString()) {
|
||||
return false;
|
||||
};
|
||||
auto str1 = programGetString(program, a.opcode, a.integerValue);
|
||||
auto str2 = programGetString(program, a.opcode, a.integerValue);
|
||||
if (!str1 || !str2) {
|
||||
return false;
|
||||
};
|
||||
return strcmp(str1, str2) == 0;
|
||||
});
|
||||
programStackPushValue(program, returnValue);
|
||||
}
|
||||
|
||||
// get_array
|
||||
static void opGetArray(Program* program)
|
||||
|
@ -598,8 +617,8 @@ static void opPartyMemberList(Program* program)
|
|||
|
||||
// type_of
|
||||
static void opTypeOf(Program* program)
|
||||
{
|
||||
auto value = programStackPopValue(program);
|
||||
{
|
||||
auto value = programStackPopValue(program);
|
||||
if (value.isInt()) {
|
||||
programStackPushInteger(program, 1);
|
||||
} else if (value.isFloat()) {
|
||||
|
@ -753,6 +772,7 @@ void sfallOpcodesInit()
|
|||
interpreterRegisterOpcode(0x8233, opFixArray);
|
||||
interpreterRegisterOpcode(0x8237, opParseInt);
|
||||
interpreterRegisterOpcode(0x8238, op_atof);
|
||||
interpreterRegisterOpcode(0x8239, opScanArray);
|
||||
interpreterRegisterOpcode(0x824B, op_tile_under_cursor);
|
||||
interpreterRegisterOpcode(0x824F, opGetStringLength);
|
||||
interpreterRegisterOpcode(0x8253, opTypeOf);
|
||||
|
|
Loading…
Reference in New Issue