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 ProgramValue GetArray(const ProgramValue& key) = 0;
|
||||||
virtual void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset) = 0;
|
virtual void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset) = 0;
|
||||||
virtual void ResizeArray(int newLen) = 0;
|
virtual void ResizeArray(int newLen) = 0;
|
||||||
|
virtual ProgramValue ScanArray(const ProgramValue& value, ValueCompareStrings& cmp) = 0;
|
||||||
|
|
||||||
virtual ~SFallArray() = default;
|
virtual ~SFallArray() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,6 +129,16 @@ public:
|
||||||
ListSort(values, newLen, std::less<ProgramValue>());
|
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 {
|
class SFallArrayAssoc : public SFallArray {
|
||||||
|
@ -232,6 +244,16 @@ public:
|
||||||
MapSort(newLen);
|
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)
|
void SFallArrayAssoc::MapSort(int type)
|
||||||
|
@ -389,4 +411,14 @@ int StackArray(const ProgramValue& key, const ProgramValue& val)
|
||||||
return 0;
|
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 "interpreter.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include <functional>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
@ -13,6 +14,8 @@ namespace fallout {
|
||||||
|
|
||||||
using ArrayId = unsigned int;
|
using ArrayId = unsigned int;
|
||||||
|
|
||||||
|
using ValueCompareStrings = const std::function<bool(const ProgramValue&, const ProgramValue&)>;
|
||||||
|
|
||||||
ArrayId CreateArray(int len, uint32_t flags);
|
ArrayId CreateArray(int len, uint32_t flags);
|
||||||
ArrayId CreateTempArray(int len, uint32_t flags);
|
ArrayId CreateTempArray(int len, uint32_t flags);
|
||||||
ProgramValue GetArrayKey(ArrayId array_id, int index);
|
ProgramValue GetArrayKey(ArrayId array_id, int index);
|
||||||
|
@ -25,6 +28,7 @@ void ResizeArray(ArrayId array_id, int newLen);
|
||||||
void DeleteAllTempArrays();
|
void DeleteAllTempArrays();
|
||||||
void sfallArraysReset();
|
void sfallArraysReset();
|
||||||
int StackArray(const ProgramValue& key, const ProgramValue& val);
|
int StackArray(const ProgramValue& key, const ProgramValue& val);
|
||||||
|
ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, ValueCompareStrings& cmp);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* SFALL_ARRAYS */
|
#endif /* SFALL_ARRAYS */
|
|
@ -533,18 +533,37 @@ static void opSetArray(Program* program)
|
||||||
SetArray(arrayId, key, value, true);
|
SetArray(arrayId, key, value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// arrayexpr
|
// arrayexpr
|
||||||
static void opStackArray(Program* program)
|
static void opStackArray(Program* program)
|
||||||
{
|
{
|
||||||
auto value = programStackPopValue(program);
|
auto value = programStackPopValue(program);
|
||||||
auto key = programStackPopValue(program);
|
auto key = programStackPopValue(program);
|
||||||
auto returnValue = StackArray(key, value);
|
auto returnValue = StackArray(key, value);
|
||||||
programStackPushInteger(program, returnValue);
|
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
|
// get_array
|
||||||
static void opGetArray(Program* program)
|
static void opGetArray(Program* program)
|
||||||
|
@ -598,8 +617,8 @@ static void opPartyMemberList(Program* program)
|
||||||
|
|
||||||
// type_of
|
// type_of
|
||||||
static void opTypeOf(Program* program)
|
static void opTypeOf(Program* program)
|
||||||
{
|
{
|
||||||
auto value = programStackPopValue(program);
|
auto value = programStackPopValue(program);
|
||||||
if (value.isInt()) {
|
if (value.isInt()) {
|
||||||
programStackPushInteger(program, 1);
|
programStackPushInteger(program, 1);
|
||||||
} else if (value.isFloat()) {
|
} else if (value.isFloat()) {
|
||||||
|
@ -753,6 +772,7 @@ void sfallOpcodesInit()
|
||||||
interpreterRegisterOpcode(0x8233, opFixArray);
|
interpreterRegisterOpcode(0x8233, opFixArray);
|
||||||
interpreterRegisterOpcode(0x8237, opParseInt);
|
interpreterRegisterOpcode(0x8237, opParseInt);
|
||||||
interpreterRegisterOpcode(0x8238, op_atof);
|
interpreterRegisterOpcode(0x8238, op_atof);
|
||||||
|
interpreterRegisterOpcode(0x8239, opScanArray);
|
||||||
interpreterRegisterOpcode(0x824B, op_tile_under_cursor);
|
interpreterRegisterOpcode(0x824B, op_tile_under_cursor);
|
||||||
interpreterRegisterOpcode(0x824F, opGetStringLength);
|
interpreterRegisterOpcode(0x824F, opGetStringLength);
|
||||||
interpreterRegisterOpcode(0x8253, opTypeOf);
|
interpreterRegisterOpcode(0x8253, opTypeOf);
|
||||||
|
|
Loading…
Reference in New Issue