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<ArrayId, std::unique_ptr<SFallArray>> arrays;
 std::unordered_set<ArrayId> 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];