mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Implemented quicksort in _sort()
This commit is contained in:
@@ -996,6 +996,97 @@ static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void swapLiteralsUtil(Toy_Literal* lhs, Toy_Literal* rhs) {
|
||||
Toy_Literal tmp = *lhs;
|
||||
*lhs = *rhs;
|
||||
*rhs = tmp;
|
||||
}
|
||||
|
||||
//https://www.youtube.com/watch?v=MZaf_9IZCrc
|
||||
static void recursiveLiteralQuicksortUtil(Toy_Interpreter* interpreter, Toy_Literal* ptr, int literalCount, Toy_Literal fnCompareLiteral) {
|
||||
//base case
|
||||
if (literalCount <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int runner = 0;
|
||||
|
||||
//iterate through the array
|
||||
for (int checker = 0; checker < literalCount - 1; checker++) {
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_LiteralArray returns;
|
||||
|
||||
Toy_initLiteralArray(&arguments);
|
||||
Toy_initLiteralArray(&returns);
|
||||
|
||||
Toy_pushLiteralArray(&arguments, ptr[literalCount - 1]); //backwards
|
||||
Toy_pushLiteralArray(&arguments, ptr[checker]);
|
||||
|
||||
Toy_callLiteralFn(interpreter, fnCompareLiteral, &arguments, &returns);
|
||||
|
||||
Toy_Literal lessThan = Toy_popLiteralArray(&returns);
|
||||
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Toy_freeLiteralArray(&returns);
|
||||
|
||||
if (TOY_IS_TRUTHY(lessThan)) {
|
||||
swapLiteralsUtil(&ptr[runner++], &ptr[checker]);
|
||||
}
|
||||
|
||||
Toy_freeLiteral(lessThan);
|
||||
}
|
||||
|
||||
//"shift everything up" so the pivot is in the middle
|
||||
swapLiteralsUtil(&ptr[runner], &ptr[literalCount - 1]);
|
||||
|
||||
//recurse on each end
|
||||
recursiveLiteralQuicksortUtil(interpreter, &ptr[0], runner, fnCompareLiteral);
|
||||
recursiveLiteralQuicksortUtil(interpreter, &ptr[runner + 1], literalCount - runner - 1, fnCompareLiteral);
|
||||
}
|
||||
|
||||
static int nativeSort(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _sort\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the args
|
||||
Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
//parse to value if needed
|
||||
Toy_Literal selfLiteralIdn = selfLiteral;
|
||||
if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
|
||||
Toy_freeLiteral(selfLiteralIdn);
|
||||
}
|
||||
|
||||
Toy_Literal fnLiteralIdn = fnLiteral;
|
||||
if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
|
||||
Toy_freeLiteral(fnLiteralIdn);
|
||||
}
|
||||
|
||||
//check type
|
||||
if (!TOY_IS_ARRAY(selfLiteral) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _sort\n");
|
||||
Toy_freeLiteral(selfLiteral);
|
||||
Toy_freeLiteral(fnLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//call the quicksort util
|
||||
if (TOY_IS_ARRAY(selfLiteral)) {
|
||||
recursiveLiteralQuicksortUtil(interpreter, TOY_AS_ARRAY(selfLiteral)->literals, TOY_AS_ARRAY(selfLiteral)->count, fnLiteral);
|
||||
}
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, selfLiteral);
|
||||
|
||||
Toy_freeLiteral(fnLiteral);
|
||||
Toy_freeLiteral(selfLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
@@ -1451,7 +1542,7 @@ int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
||||
{"_map", nativeMap}, //array, dictionary
|
||||
{"_reduce", nativeReduce}, //array, dictionary
|
||||
{"_some", nativeSome}, //array, dictionary
|
||||
// {"_sort", native}, //array
|
||||
{"_sort", nativeSort}, //array
|
||||
{"_toLower", nativeToLower}, //string
|
||||
{"_toString", nativeToString}, //array, dictionary
|
||||
{"_toUpper", nativeToUpper}, //string
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
//polyfill the _insert function
|
||||
fn _insert(self, k, v) {
|
||||
var tmp1 = v;
|
||||
var tmp2;
|
||||
for (var i = k; i < self.length(); i++) {
|
||||
tmp2 = self[i];
|
||||
self[i] = tmp1;
|
||||
tmp1 = tmp2;
|
||||
import compound;
|
||||
|
||||
fn less(a, b) {
|
||||
return a < b;
|
||||
}
|
||||
|
||||
self.push(tmp1);
|
||||
return self;
|
||||
fn greater(a, b) {
|
||||
return a > b;
|
||||
}
|
||||
|
||||
var a = [1, 2, 3];
|
||||
var a = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||
var b = [7, 2, 1, 4, 6, 3, 5, 8];
|
||||
var c = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
var d = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||
|
||||
a = a.insert(1, 42);
|
||||
a = a.sort(less);
|
||||
b = b.sort(less);
|
||||
c = c.sort(less);
|
||||
d = d.sort(greater);
|
||||
|
||||
assert a == [1, 5, 2, 3], "index assignment left failed";
|
||||
assert a == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) failed";
|
||||
assert b == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) with pivot high failed";
|
||||
assert c == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) pre-sorted array failed";
|
||||
assert d == [8, 7, 6, 5, 4, 3, 2, 1], "array.sort(greater) failed";
|
||||
|
||||
|
||||
print "All good";
|
||||
@@ -228,6 +228,33 @@ import compound;
|
||||
}
|
||||
|
||||
|
||||
//test sort
|
||||
{
|
||||
fn less(a, b) {
|
||||
return a < b;
|
||||
}
|
||||
|
||||
fn greater(a, b) {
|
||||
return a > b;
|
||||
}
|
||||
|
||||
var a = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||
var b = [7, 2, 1, 4, 6, 3, 5, 8];
|
||||
var c = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
var d = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||
|
||||
a = a.sort(less);
|
||||
b = b.sort(less);
|
||||
c = c.sort(less);
|
||||
d = d.sort(greater);
|
||||
|
||||
assert a == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) failed";
|
||||
assert b == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) with pivot high failed";
|
||||
assert c == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) pre-sorted array failed";
|
||||
assert d == [8, 7, 6, 5, 4, 3, 2, 1], "array.sort(greater) failed";
|
||||
}
|
||||
|
||||
|
||||
//test toLower
|
||||
{
|
||||
assert "Hello World".toLower() == "hello world", "_toLower() failed";
|
||||
|
||||
Reference in New Issue
Block a user