Skip to content

Commit

Permalink
Merge pull request #725 from briandowns/feature/more_string_methods
Browse files Browse the repository at this point in the history
Feature/more string methods
  • Loading branch information
Jason2605 authored Jan 22, 2024
2 parents a548039 + 7f997cc commit 8ba7fb5
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 3 deletions.
16 changes: 16 additions & 0 deletions docs/docs/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,19 @@ Returns the number of words in the given string. Empty strings are considered fa
"This is a sentence".wordCount(); // 4
"This is an even longer sentence".wordCount(); // 6
```

### string.collapseSpaces() -> String

Returns a string with extraneous whitespace removed.

```cs
"This is a huge string of a lot of spaces.".collapseSpaces(); // "This is a huge string of a lot of spaces."
```

### string.wrap(Number) -> String

Returns a new string with new lines inserted at the given length.

```cs
"This is a really really long string that will need to be broken up for whatever reason the caller has determined. Not our business as to why, but we can provide the functionality for them to do so.".wrap(80);
```
1 change: 0 additions & 1 deletion src/vm/datatypes/sets.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,3 @@ void declareSetMethods(DictuVM *vm) {
defineNative(vm, &vm->setMethods, "containsAll", containsAllSet);
defineNative(vm, &vm->setMethods, "toBool", boolNative); // Defined in util
}

59 changes: 58 additions & 1 deletion src/vm/datatypes/strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,62 @@ static Value isLowerString(DictuVM *vm, int argCount, Value *args) {
return BOOL_VAL(true);
}

static Value collapseSpacesString(DictuVM *vm, int argCount, Value *args) {
if (argCount != 0) {
runtimeError(vm, "collapseSpaces() takes no arguments (%d given)", argCount);
return EMPTY_VAL;
}

ObjString *string = AS_STRING(args[0]);
char *temp = ALLOCATE(vm, char, string->length + 1);
strcpy(temp, string->chars);

int i, j;
for (i = j = 0; temp[i]; ++i) {
if (!isspace(temp[i]) || (i > 0 && !isspace(temp[i-1]))) {
temp[j++] = temp[i];
}
}

temp[j+1] = '\0';

if (i != j) {
temp = SHRINK_ARRAY(vm, temp, char, string->length + 1, j + 1);
}

return OBJ_VAL(takeString(vm, temp, j));
}

static Value wrapString(DictuVM *vm, int argCount, Value *args) {
if (argCount != 1) {
runtimeError(vm, "wrap() takes 1 argument (%d given)", argCount);
return EMPTY_VAL;
}

ObjString *string = AS_STRING(args[0]);
char *temp = ALLOCATE(vm, char, string->length + 1);

int len = AS_NUMBER(args[1]);

int last = 0;
int count = 0;

for (int cur = 0; string->chars[cur] != '\0'; cur++, count++) {
temp[cur] = string->chars[cur];

if (isspace(temp[cur])) {
last = cur;
}

if (count >= len) {
temp[last] = '\n';
count = 0;
}
}

return OBJ_VAL(takeString(vm, temp, strlen(temp)));
}

void declareStringMethods(DictuVM *vm) {
defineNative(vm, &vm->stringMethods, "len", lenString);
defineNative(vm, &vm->stringMethods, "toNumber", toNumberString);
Expand All @@ -691,5 +747,6 @@ void declareStringMethods(DictuVM *vm) {
defineNative(vm, &vm->stringMethods, "repeat", repeatString);
defineNative(vm, &vm->stringMethods, "isUpper", isUpperString);
defineNative(vm, &vm->stringMethods, "isLower", isLowerString);

defineNative(vm, &vm->stringMethods, "collapseSpaces", collapseSpacesString);
defineNative(vm, &vm->stringMethods, "wrap", wrapString);
}
20 changes: 20 additions & 0 deletions tests/strings/collapseSpaces.du
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* collapseSpaces.du
*
* Testing the str.collapseSpaces() method
*
* .collapseSpaces() returns a string with extraneous spaces removed.
*/
from UnitTest import UnitTest;

class TestStringCollapseSpaces < UnitTest {
testStringCollapseSpaces() {
const testString = "This is a huge string of a lot of spaces.";
const expected = "This is a huge string of a lot of spaces.";
const res = testString.collapseSpaces();
this.assertEquals(res, expected);
this.assertNotEquals(testString, expected);
}
}

TestStringCollapseSpaces().run();
2 changes: 1 addition & 1 deletion tests/strings/concat.du
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ class TestStringConcat < UnitTest {
}
}

TestStringConcat().run();
TestStringConcat().run();
2 changes: 2 additions & 0 deletions tests/strings/import.du
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ import "title.du";
import "isUpper.du";
import "isLower.du";
import "wordCount.du";
import "collapseSpaces.du";
import "wrap.du";
21 changes: 21 additions & 0 deletions tests/strings/wrap.du
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* wrap.du
*
* Testing the str.wrap() method
*
* .wrap() returns a new string with new lines inserted at the given length.
*/
from UnitTest import UnitTest;

class TestStringWrap < UnitTest {
const maxLen = 80;

testStringWrap() {
const testString = "This is a really really long string that will need to be broken up for whatever reason the caller has determined. Not out business as to why, but we can provide the functionality for them to do so.";
const res = testString.wrap(this.maxLen);
const idx = res.find("\n");
this.assertTruthy(res.find("\n") <= this.maxLen);
}
}

TestStringWrap().run();

0 comments on commit 8ba7fb5

Please sign in to comment.