From b24f60713317aeed7fce25a0d53399f4861b2303 Mon Sep 17 00:00:00 2001 From: Vasilii Rogin Date: Mon, 15 May 2023 17:50:49 +0300 Subject: [PATCH] Add StringSplit opcode --- src/sfall_arrays.cc | 79 +++++++++++++++++++++++++++++++++++++++++--- src/sfall_arrays.h | 2 ++ src/sfall_opcodes.cc | 8 ++--- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/sfall_arrays.cc b/src/sfall_arrays.cc index 6020828..43a0007 100644 --- a/src/sfall_arrays.cc +++ b/src/sfall_arrays.cc @@ -155,6 +155,16 @@ public: 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 out; @@ -177,7 +187,7 @@ public: return out; default: throw(std::exception()); - } + } } bool operator<(ArrayElement const& other) const @@ -217,7 +227,8 @@ public: } } - ~ArrayElement(){ + ~ArrayElement() + { if (type == ArrayElementType::STRING) { free(stringValue); }; @@ -233,6 +244,7 @@ public: virtual ProgramValue GetArrayKey(int index, 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, ArrayElement&& val, bool allowUnset) = 0; virtual void ResizeArray(int newLen) = 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) + { + SetArray(key, ArrayElement { val, program }, allowUnset); + } + void SetArray(const ProgramValue& key, ArrayElement&& val, bool allowUnset) { if (key.isInt()) { auto index = key.asInt(); 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) { if (newLen == -1 || size() == newLen) { @@ -459,7 +479,7 @@ std::unordered_map> arrays; std::unordered_set temporaryArrays; ArrayId CreateArray(int len, uint32_t flags) -{ +{ flags = (flags & ~1); // reset 1 bit if (len < 0) { @@ -469,7 +489,6 @@ ArrayId CreateArray(int len, uint32_t flags) }; ArrayId array_id = nextArrayID++; - stackArrayId = array_id; if (flags & SFALL_ARRAYFLAG_ASSOC) { @@ -603,4 +622,54 @@ ProgramValue ScanArray(ArrayId array_id, const ProgramValue& val, Program* progr 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; +} + } \ No newline at end of file diff --git a/src/sfall_arrays.h b/src/sfall_arrays.h index 7313434..9f4f2ca 100644 --- a/src/sfall_arrays.h +++ b/src/sfall_arrays.h @@ -27,5 +27,7 @@ void sfallArraysReset(); int StackArray(const ProgramValue& key, 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 */ \ No newline at end of file diff --git a/src/sfall_opcodes.cc b/src/sfall_opcodes.cc index 7b72bbc..1d4f08a 100644 --- a/src/sfall_opcodes.cc +++ b/src/sfall_opcodes.cc @@ -568,14 +568,12 @@ static void opStringSplit(Program* program) { auto split = programStackPopString(program); auto str = programStackPopString(program); - - // TODO - auto returnValue = 0; + + auto returnValue = StringSplit(str, split); programStackPushInteger(program, returnValue); } - // set_array static void opSetArray(Program* program) { @@ -619,7 +617,7 @@ static void opGetArray(Program* program) auto& strVal = arrayId; auto pos = key.asInt(); auto str = programGetString(program, strVal.opcode, strVal.integerValue); - + char buf[2] = { 0 }; if (pos < strlen(str)) { buf[0] = str[pos];