Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/more string methods #725

Merged
merged 11 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth adding some tests to ensure the original string is also untouched

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();