Add StringSplit opcode
This commit is contained in:
parent
f90542f040
commit
b24f607133
|
@ -155,6 +155,16 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayElement(char* str)
|
||||||
|
{
|
||||||
|
type = ArrayElementType::STRING;
|
||||||
|
auto len = strlen(str);
|
||||||
|
auto buf = (char*)malloc(len + 1);
|
||||||
|
strcpy(buf, str);
|
||||||
|
stringValue = buf;
|
||||||
|
}
|
||||||
|
|
||||||
ProgramValue toValue(Program* program) const
|
ProgramValue toValue(Program* program) const
|
||||||
{
|
{
|
||||||
ProgramValue out;
|
ProgramValue out;
|
||||||
|
@ -177,7 +187,7 @@ public:
|
||||||
return out;
|
return out;
|
||||||
default:
|
default:
|
||||||
throw(std::exception());
|
throw(std::exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(ArrayElement const& other) const
|
bool operator<(ArrayElement const& other) const
|
||||||
|
@ -217,7 +227,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~ArrayElement(){
|
~ArrayElement()
|
||||||
|
{
|
||||||
if (type == ArrayElementType::STRING) {
|
if (type == ArrayElementType::STRING) {
|
||||||
free(stringValue);
|
free(stringValue);
|
||||||
};
|
};
|
||||||
|
@ -233,6 +244,7 @@ public:
|
||||||
virtual ProgramValue GetArrayKey(int index, Program* program) = 0;
|
virtual ProgramValue GetArrayKey(int index, Program* program) = 0;
|
||||||
virtual ProgramValue GetArray(const ProgramValue& key, Program* program) = 0;
|
virtual ProgramValue GetArray(const ProgramValue& key, Program* program) = 0;
|
||||||
virtual void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset, Program* program) = 0;
|
virtual void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset, Program* program) = 0;
|
||||||
|
virtual void SetArray(const ProgramValue& key, ArrayElement&& val, bool allowUnset) = 0;
|
||||||
virtual void ResizeArray(int newLen) = 0;
|
virtual void ResizeArray(int newLen) = 0;
|
||||||
virtual ProgramValue ScanArray(const ProgramValue& value, Program* program) = 0;
|
virtual ProgramValue ScanArray(const ProgramValue& value, Program* program) = 0;
|
||||||
|
|
||||||
|
@ -278,11 +290,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset, Program* program)
|
void SetArray(const ProgramValue& key, const ProgramValue& val, bool allowUnset, Program* program)
|
||||||
|
{
|
||||||
|
SetArray(key, ArrayElement { val, program }, allowUnset);
|
||||||
|
}
|
||||||
|
void SetArray(const ProgramValue& key, ArrayElement&& val, bool allowUnset)
|
||||||
{
|
{
|
||||||
if (key.isInt()) {
|
if (key.isInt()) {
|
||||||
auto index = key.asInt();
|
auto index = key.asInt();
|
||||||
if (index >= 0 && index < size()) {
|
if (index >= 0 && index < size()) {
|
||||||
values[index] = ArrayElement { val, program };
|
std::swap(values[index], val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,6 +418,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void SetArray(const ProgramValue& key, ArrayElement&& val, bool allowUnset)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
void ResizeArray(int newLen)
|
void ResizeArray(int newLen)
|
||||||
{
|
{
|
||||||
if (newLen == -1 || size() == newLen) {
|
if (newLen == -1 || size() == newLen) {
|
||||||
|
@ -459,7 +479,7 @@ std::unordered_map<ArrayId, std::unique_ptr<SFallArray>> arrays;
|
||||||
std::unordered_set<ArrayId> temporaryArrays;
|
std::unordered_set<ArrayId> temporaryArrays;
|
||||||
|
|
||||||
ArrayId CreateArray(int len, uint32_t flags)
|
ArrayId CreateArray(int len, uint32_t flags)
|
||||||
{
|
{
|
||||||
flags = (flags & ~1); // reset 1 bit
|
flags = (flags & ~1); // reset 1 bit
|
||||||
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
|
@ -469,7 +489,6 @@ ArrayId CreateArray(int len, uint32_t flags)
|
||||||
};
|
};
|
||||||
|
|
||||||
ArrayId array_id = nextArrayID++;
|
ArrayId array_id = nextArrayID++;
|
||||||
|
|
||||||
stackArrayId = array_id;
|
stackArrayId = array_id;
|
||||||
|
|
||||||
if (flags & SFALL_ARRAYFLAG_ASSOC) {
|
if (flags & SFALL_ARRAYFLAG_ASSOC) {
|
||||||
|
@ -603,4 +622,54 @@ ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, Program* progr
|
||||||
return arr->ScanArray(val, program);
|
return arr->ScanArray(val, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayId StringSplit(const char* str, const char* split)
|
||||||
|
{
|
||||||
|
int splitLen = strlen(split);
|
||||||
|
|
||||||
|
ArrayId array_id = CreateTempArray(0, 0);
|
||||||
|
auto arr = get_array_by_id(array_id);
|
||||||
|
|
||||||
|
if (!splitLen) {
|
||||||
|
int count = strlen(str);
|
||||||
|
|
||||||
|
arr->ResizeArray(count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
char buf[2] = { 0 };
|
||||||
|
buf[0] = str[i];
|
||||||
|
arr->SetArray(ProgramValue { i }, ArrayElement { buf }, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int count = 1;
|
||||||
|
const char *ptr = str, *newptr;
|
||||||
|
while (true) {
|
||||||
|
newptr = strstr(ptr, split);
|
||||||
|
if (!newptr) break;
|
||||||
|
count++;
|
||||||
|
ptr = newptr + splitLen;
|
||||||
|
}
|
||||||
|
arr->ResizeArray(count);
|
||||||
|
|
||||||
|
ptr = str;
|
||||||
|
count = 0;
|
||||||
|
auto buf = (char*)malloc(strlen(str) + 1);
|
||||||
|
while (true) {
|
||||||
|
newptr = strstr(ptr, split);
|
||||||
|
int len = (newptr) ? newptr - ptr : strlen(ptr);
|
||||||
|
|
||||||
|
memcpy(buf, ptr, len);
|
||||||
|
buf[len] = 0;
|
||||||
|
|
||||||
|
arr->SetArray(ProgramValue { count }, ArrayElement { buf }, false);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (!newptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr = newptr + splitLen;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
return array_id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -27,5 +27,7 @@ void sfallArraysReset();
|
||||||
int StackArray(const ProgramValue& key, const ProgramValue& val, Program* program);
|
int StackArray(const ProgramValue& key, const ProgramValue& val, Program* program);
|
||||||
ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, Program* program);
|
ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, Program* program);
|
||||||
|
|
||||||
|
ArrayId StringSplit(const char* str, const char* split);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* SFALL_ARRAYS */
|
#endif /* SFALL_ARRAYS */
|
|
@ -568,14 +568,12 @@ static void opStringSplit(Program* program)
|
||||||
{
|
{
|
||||||
auto split = programStackPopString(program);
|
auto split = programStackPopString(program);
|
||||||
auto str = programStackPopString(program);
|
auto str = programStackPopString(program);
|
||||||
|
|
||||||
// TODO
|
auto returnValue = StringSplit(str, split);
|
||||||
auto returnValue = 0;
|
|
||||||
|
|
||||||
programStackPushInteger(program, returnValue);
|
programStackPushInteger(program, returnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set_array
|
// set_array
|
||||||
static void opSetArray(Program* program)
|
static void opSetArray(Program* program)
|
||||||
{
|
{
|
||||||
|
@ -619,7 +617,7 @@ static void opGetArray(Program* program)
|
||||||
auto& strVal = arrayId;
|
auto& strVal = arrayId;
|
||||||
auto pos = key.asInt();
|
auto pos = key.asInt();
|
||||||
auto str = programGetString(program, strVal.opcode, strVal.integerValue);
|
auto str = programGetString(program, strVal.opcode, strVal.integerValue);
|
||||||
|
|
||||||
char buf[2] = { 0 };
|
char buf[2] = { 0 };
|
||||||
if (pos < strlen(str)) {
|
if (pos < strlen(str)) {
|
||||||
buf[0] = str[pos];
|
buf[0] = str[pos];
|
||||||
|
|
Loading…
Reference in New Issue