Browse Source

Merge pull request #101 from hallzy/add-arg-to-upper-lower

Add args to upper lower
Marco Bambini 8 years ago
parent
commit
84b771fa98

+ 4 - 0
docs/types.html

@@ -115,9 +115,13 @@
 
 	n = "A".repeat(10)      // n is now "AAAAAAAAAA"
 
+	// upper() and lower() operate on the whole string when 0 arguments are passed
 	n = b.upper()           // n is now "HELLO WORLD"
 	n = b.lower()           // n is now "hello world"
 
+	// upper() and lower() can both take multiple integer arguments
+	n = b.upper(1, -1)     // n is now "HEllo WorlD"
+
 	// You are also able to edit strings by character...
 	b[0] = "Z"              // b is now "Zello World"
 	b[1] = "abc"            // b is now "Zabco World"

+ 48 - 22
src/runtime/gravity_core.c

@@ -1536,41 +1536,67 @@ static bool string_repeat (gravity_vm *vm, gravity_value_t *args, uint16_t nargs
 }
 
 static bool string_upper (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
-	if (nargs != 1) {
-		RETURN_ERROR("String.upper() expects no argument");
-	}
-	
 	gravity_string_t *main_str = VALUE_AS_STRING(GET_VALUE(0));
 
-	// I don't want this function to modify the main_str directly. I just want
-	// this method to return a new capitalized string, so copy main_str to a
-	// different string and manipulate that.
-	char new_str[main_str->len + 1]; // + 1 for the null character
+	char ret[main_str->len + 1];
+	strcpy(ret, main_str->s);
 
-	for (int i = 0; i <= main_str->len; i++) {
-		new_str[i] = toupper(main_str->s[i]);
+	// if no arguments passed, change the whole string to uppercase
+	if (nargs == 1) {
+		for (int i = 0; i <= main_str->len; i++) {
+		 ret[i] = toupper(ret[i]);
+		}
 	}
+	// otherwise, evaluate all the arguments
+	else {
+		for (int i = 1; i < nargs; ++i) {
+			gravity_value_t value = GET_VALUE(i);
+			if (VALUE_ISA_INT(value)) {
+				int32_t index = (int32_t)VALUE_AS_INT(value);
 
-	RETURN_VALUE(VALUE_FROM_CSTRING(vm, new_str), rindex);
-}
+				if (index < 0) index = main_str->len + index;
+				if ((index < 0) || ((uint32_t)index >= main_str->len)) RETURN_ERROR("Out of bounds error: index %d beyond bounds 0...%d", index, main_str->len-1);
 
-static bool string_lower (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
-	if (nargs != 1) {
-		RETURN_ERROR("String.lower() expects no argument");
+				ret[index] = toupper(ret[index]);
+			}
+			else {
+				RETURN_ERROR("upper() expects either no arguments, or integer arguments.");
+			}
+		}
 	}
+	RETURN_VALUE(VALUE_FROM_CSTRING(vm, ret), rindex);
+}
 
+static bool string_lower (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
 	gravity_string_t *main_str = VALUE_AS_STRING(GET_VALUE(0));
 
-	// I don't want this function to modify the main_str directly. I just want
-	// this method to return a new capitalized string, so copy main_str to a
-	// different string and manipulate that.
-	char new_str[main_str->len + 1]; // + 1 for the null character
+	char ret[main_str->len + 1];
+	strcpy(ret, main_str->s);
 
-	for (int i = 0; i <= main_str->len; i++) {
-		new_str[i] = tolower(main_str->s[i]);
+	// if no arguments passed, change the whole string to lowercase
+	if (nargs == 1) {
+		for (int i = 0; i <= main_str->len; i++) {
+		 ret[i] = tolower(ret[i]);
+		}
 	}
+	// otherwise, evaluate all the arguments
+	else {
+		for (int i = 1; i < nargs; ++i) {
+			gravity_value_t value = GET_VALUE(i);
+			if (VALUE_ISA_INT(value)) {
+				int32_t index = (int32_t)VALUE_AS_INT(value);
 
-	RETURN_VALUE(VALUE_FROM_CSTRING(vm, new_str), rindex);
+				if (index < 0) index = main_str->len + index;
+				if ((index < 0) || ((uint32_t)index >= main_str->len)) RETURN_ERROR("Out of bounds error: index %d beyond bounds 0...%d", index, main_str->len-1);
+
+				ret[index] = tolower(ret[index]);
+			}
+			else {
+				RETURN_ERROR("lower() expects either no arguments, or integer arguments.");
+			}
+		}
+	}
+	RETURN_VALUE(VALUE_FROM_CSTRING(vm, ret), rindex);
 }
 
 static bool string_loadat (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {

+ 29 - 0
test/string/lower_method.gravity

@@ -0,0 +1,29 @@
+#unittest {
+	name: "lower() methods for string -- complex";
+	error: NONE;
+	result: true;
+};
+
+func main () {
+	var s = "tHIS IS JUST A REALLY LONG TEST STRING TO TRY AND GET AS much VARIATION AS POSSIBLE"
+
+	// Numbers Only
+	// The V in VARIATION
+	var a_int = s.lower(62) == "tHIS IS JUST A REALLY LONG TEST STRING TO TRY AND GET AS much vARIATION AS POSSIBLE"
+	if (a_int == false) { System.print("a) int failed\n"); return false }
+
+	var b_int = s.lower(-21) == s.lower(62)
+	if (a_int == false) { System.print("b) int failed\n"); return false }
+
+	var c_int = s.lower(2) == "tHiS IS JUST A REALLY LONG TEST STRING TO TRY AND GET AS much VARIATION AS POSSIBLE"
+	if (a_int == false) { System.print("c) int failed\n"); return false }
+
+	var d_int = s.lower(-81) == s.lower(2)
+	if (a_int == false) { System.print("d) int failed\n"); return false }
+
+	// Try a character that is already lowercase
+	var e_int = s.lower(0) == "tHIS IS JUST A REALLY LONG TEST STRING TO TRY AND GET AS much VARIATION AS POSSIBLE"
+	if (a_int == false) { System.print("e) int failed\n"); return false }
+	
+	return true
+}

+ 9 - 0
test/string/lower_method_float.gravity

@@ -0,0 +1,9 @@
+#unittest {
+	name: "lower() bad argument";
+	error: RUNTIME;
+};
+
+func main () {
+	var s = "HELLO"
+	s.lower(2.3)
+}

+ 9 - 0
test/string/lower_method_out_of_bounds.gravity

@@ -0,0 +1,9 @@
+#unittest {
+	name: "lower() method out of bounds";
+	error: RUNTIME;
+};
+
+func main () {
+	var s = "Hello"
+	s.lower(5)
+}

+ 26 - 0
test/string/upper_lower_method_non_alpha.gravity

@@ -0,0 +1,26 @@
+#unittest {
+	name: "upper() and lower methods for string -- non alpha tests";
+	error: NONE;
+	result: true;
+};
+
+func main () {
+	var s = "Hello, World!"
+
+	// Full string
+	var a = s.upper() == "HELLO, WORLD!"
+	if (a == false) { System.print("a) failed"); return false }
+
+	var b = s.lower() == "hello, world!"
+	if (b == false) { System.print("b) failed"); return false }
+
+	// Single integer or string -- upper
+	var c = s.upper(5) == s
+	if (c == false) { System.print("c) failed"); return false }
+
+	// Single integer or string -- lower
+	var d = s.lower(5) == s
+	if (d == false) { System.print("d) failed"); return false }
+
+	return true
+}

+ 0 - 0
test/string/upper_lower_method.gravity → test/string/upper_lower_method_simple.gravity


+ 28 - 0
test/string/upper_lower_multiple_args.gravity

@@ -0,0 +1,28 @@
+#unittest {
+	name: "upper() methods for string -- multiple args";
+	error: NONE;
+	result: true;
+};
+
+func main () {
+	var s = "Hello World"
+
+	// UPPER
+	var a = s.upper(1, 2, 3) == "HELLo World"
+	if (a == false) { System.print("a) upper failed"); return false }
+
+	// Try swappings the order
+	var b = s.upper(3, 2, 1) == s.upper(1, 2, 3)
+	if (b == false) { System.print("b) upper failed"); return false }
+
+
+	s = "HELLO WORLD"
+	// LOWER
+	a = s.lower(0, 2, 4) == "hElLo WORLD"
+	if (a == false) { System.print("a) lower failed"); return false }
+
+	b = s.lower(4, 2, 0) == s.lower(0, 2, 4)
+	if (b == false) { System.print("b) lower failed"); return false }
+
+	return true
+}

+ 29 - 0
test/string/upper_method.gravity

@@ -0,0 +1,29 @@
+#unittest {
+	name: "upper() methods for string -- complex";
+	error: NONE;
+	result: true;
+};
+
+func main () {
+	var s = "This is just a really long test string to try and get as MUCH variation as possible"
+
+	// Numbers Only
+	// the v in variation
+	var a_int = s.upper(62) == "This is just a really long test string to try and get as MUCH Variation as possible"
+	if (a_int == false) { System.print("a) int failed"); return false }
+
+	var b_int = s.upper(-21) == s.upper(62)
+	if (b_int == false) { System.print("b) int failed"); return false }
+
+	var c_int = s.upper(2) == "ThIs is just a really long test string to try and get as MUCH variation as possible"
+	if (c_int == false) { System.print("c) int failed"); return false }
+
+	var d_int = s.upper(-81) == s.upper(2)
+	if (d_int == false) { System.print("d) int failed"); return false }
+
+	// Try a character that is already uppercase
+	var e_int = s.upper(0) == "This is just a really long test string to try and get as MUCH variation as possible"
+	if (e_int == false) { System.print("e) int failed"); return false }
+	
+	return true
+}

+ 9 - 0
test/string/upper_method_float.gravity

@@ -0,0 +1,9 @@
+#unittest {
+	name: "upper() method bad argument";
+	error: RUNTIME;
+};
+
+func main () {
+	var s = "Hello"
+	s.upper(2.3)
+}

+ 9 - 0
test/string/upper_method_out_of_bounds.gravity

@@ -0,0 +1,9 @@
+#unittest {
+	name: "upper() method out of bounds";
+	error: RUNTIME;
+};
+
+func main () {
+	var s = "Hello"
+	s.upper(5)
+}