Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
157 commits
Select commit Hold shift + click to select a range
46ffbfb
Initial commit
softmattertheory Dec 27, 2024
19db60c
Empty module
softmattertheory Dec 27, 2024
901c2c0
Updates to ComplexMatrix
softmattertheory Dec 28, 2024
cf37b90
Printing, getting and setting implementation
softmattertheory Dec 1, 2025
bd9873e
Correct function labelling
softmattertheory Dec 1, 2025
d8e4977
Include BLAS and LAPACK
softmattertheory Dec 1, 2025
acb255a
Simplify interfaces and add cloning
softmattertheory Dec 1, 2025
18d4c51
Complex matrix implementation
softmattertheory Dec 4, 2025
3dba2e4
Change type definitions
softmattertheory Dec 5, 2025
699ac21
Constructor for ComplexMatrix
softmattertheory Dec 5, 2025
519f14a
Generic objectxmatrix_printfn
softmattertheory Dec 5, 2025
269be26
Correct indices
softmattertheory Dec 5, 2025
e1b2aa9
Printing of ComplexMatrix type
softmattertheory Dec 5, 2025
d076fdf
Complex matrix addition
softmattertheory Dec 11, 2025
d61dd38
Complex matrix multiplication
softmattertheory Dec 11, 2025
ed23c04
XMatrix mulr method
softmattertheory Dec 11, 2025
bfebcb4
Dimensions
softmattertheory Dec 11, 2025
093fc69
dimensions, count
softmattertheory Dec 11, 2025
2cf8a61
Inner products
softmattertheory Dec 13, 2025
f97622f
IdentityMatrix constructor
softmattertheory Dec 14, 2025
1e3f59f
Linear solve for regular matrix
softmattertheory Dec 14, 2025
fd7a7d3
Harmonize ComplexMatrix and XMatrix
softmattertheory Dec 14, 2025
fe58a94
Towards linear solve for complex matrices
softmattertheory Dec 14, 2025
e37b5cb
Matrix type interfaces and generic solve
softmattertheory Dec 14, 2025
62d28b5
reshape
softmattertheory Dec 15, 2025
1f109bb
Added in provisional norms
softmattertheory Dec 19, 2025
9bd2a8a
Error return system
softmattertheory Dec 19, 2025
4a66542
Functions use new error API
softmattertheory Dec 19, 2025
e8b55d5
Improve error checking and reporting
softmattertheory Dec 19, 2025
b17715e
getcolumn
softmattertheory Dec 21, 2025
7e729c6
Getcolumn/Setcolumn
softmattertheory Dec 21, 2025
5c66fa1
assign() method
softmattertheory Dec 21, 2025
4d9a4dd
enumerate
softmattertheory Dec 21, 2025
270147c
Simplify printelfn
softmattertheory Dec 21, 2025
2ad8655
Accumulate
softmattertheory Dec 21, 2025
bcb7819
inverse()
softmattertheory Dec 22, 2025
44796d6
Common index method implementation
softmattertheory Dec 22, 2025
885e022
trace
softmattertheory Dec 22, 2025
481a1ca
Eigenvalues and Eigensystem
softmattertheory Dec 23, 2025
f4ea120
Add scalar or nil to XMatrix
softmattertheory Dec 23, 2025
a58595d
Add scalars, nil and more to complexmatrix
softmattertheory Dec 23, 2025
464293c
Transpose
softmattertheory Dec 24, 2025
664c5a0
Add in additional tests
softmattertheory Dec 24, 2025
d319dfc
Delete TEST_COVERAGE_ANALYSIS.md
softmattertheory Dec 24, 2025
9401167
Fix minor errors
softmattertheory Dec 24, 2025
001fdcf
Generic setindex methods
softmattertheory Dec 24, 2025
a2103d9
Matrix roll
softmattertheory Dec 24, 2025
974a450
Use memcpy for speed
softmattertheory Dec 24, 2025
dd74b99
Matrix sum
softmattertheory Dec 24, 2025
c1ad48b
Formatted output
softmattertheory Dec 24, 2025
553f59f
Add test script
softmattertheory Dec 24, 2025
c01bc5c
Fixes to test suite
softmattertheory Dec 25, 2025
9989535
Correct remaining test suite items
softmattertheory Dec 25, 2025
cd2d932
Remove extraneous TODO
softmattertheory Dec 25, 2025
c8ddcbe
ComplexMatrix constructors
softmattertheory Dec 25, 2025
33676a4
Correct norms
softmattertheory Dec 25, 2025
6a3f377
Create complexmatrix_roll_negative.morpho
softmattertheory Dec 25, 2025
b6e39e1
Fix matrix-matrix subtraction
softmattertheory Dec 25, 2025
761c661
ComplexMatrix constructor from Matrix
softmattertheory Dec 25, 2025
143a7c7
Vector constructors
softmattertheory Dec 25, 2025
5be55fc
ComplexMatrix_add__xmatrix
softmattertheory Dec 26, 2025
e35181f
ComplexMatrix sub matrix
softmattertheory Dec 26, 2025
364a15c
Multiply by a complex number
softmattertheory Dec 27, 2025
d34dd2b
Complexmatrix-Matrix multiplication
softmattertheory Dec 27, 2025
6512fed
Refactor of complexmatrix-matrix multiply
softmattertheory Dec 27, 2025
e61439b
Shorten and make common functions
softmattertheory Dec 27, 2025
4437ef3
Fix incorrect check
softmattertheory Dec 27, 2025
f2c2ac9
Minor fix for consistency
softmattertheory Dec 27, 2025
9a28747
Vector-like constructors
softmattertheory Dec 27, 2025
9ddec57
ComplexMatrix real() and imag()
softmattertheory Dec 27, 2025
dc274ae
conj() and conjTranspose()
softmattertheory Dec 27, 2025
5ad57f5
Free partially allocated objects
softmattertheory Dec 27, 2025
b9fbdad
ComplexMatrix_div__xmatrix and divr
softmattertheory Dec 27, 2025
a7767ae
Add line ending to a test
softmattertheory Dec 27, 2025
70e9aa1
Outer product
softmattertheory Jan 3, 2026
5ceb32a
complexmatrix_r1update
softmattertheory Jan 5, 2026
ba43832
Matrix slices
softmattertheory Jan 5, 2026
8b7e722
Improvements to slice
softmattertheory Jan 6, 2026
b07203e
Matrix_setindex uses slices
softmattertheory Jan 6, 2026
f9b2027
Merge validation
softmattertheory Jan 6, 2026
8566793
Change interface to _slice_validate
softmattertheory Jan 6, 2026
231dda3
Consolidate copy loop into _slice_copy
softmattertheory Jan 6, 2026
ca0cb9b
complexmatrix_setslice
softmattertheory Jan 6, 2026
444efe9
Singular value decomposition for real matrices
softmattertheory Jan 7, 2026
62a2fc0
Complex SVD
softmattertheory Jan 7, 2026
4aa3521
Fix test case
softmattertheory Jan 7, 2026
86db518
Matrix types now inherit from Object
softmattertheory Jan 7, 2026
8f3a758
Missing constructor tests
softmattertheory Jan 8, 2026
7839307
Minor bug fixes
softmattertheory Jan 8, 2026
fe609dc
QR decomposition
softmattertheory Jan 9, 2026
3bb2a01
Move files into subfolder to facilitate merge
softmattertheory Jan 14, 2026
3389130
Revert "Move files into subfolder to facilitate merge"
softmattertheory Jan 14, 2026
ad8fe08
Move files into a subfolder to stage the merge
softmattertheory Jan 14, 2026
d086e89
Merge morpho-newlinalg repository preserving history
softmattertheory Jan 14, 2026
21bd642
Change xmatrix_ and xcomplexmatrix_ in newlinalg to correct filenames
softmattertheory Jan 14, 2026
2122542
Update function and type names for xmatrix integration
softmattertheory Jan 14, 2026
1523bd9
Update macros and method implementations
softmattertheory Jan 14, 2026
b237612
Update objectxmatrix, method signatures and a few other pieces of the…
softmattertheory Jan 14, 2026
d8e894c
Transfer new libary into the source tree
softmattertheory Jan 15, 2026
37097b4
Correct more tests
softmattertheory Jan 15, 2026
0841a3a
Initial integration
softmattertheory Jan 15, 2026
253f8d7
Fix matrix library includes
softmattertheory Jan 15, 2026
b36d1cc
Correct includes
softmattertheory Jan 15, 2026
bd32f5c
Patch some API calls
softmattertheory Jan 15, 2026
dd4b118
matrix_zero and other API patches
softmattertheory Jan 15, 2026
a4755c7
Correct output type
softmattertheory Jan 15, 2026
fa1a2d8
Patch field arithmetic functions
softmattertheory Jan 15, 2026
33b3604
matrix_countdof
softmattertheory Jan 15, 2026
df1e430
Matrix operations in functional.c
softmattertheory Jan 15, 2026
2d71241
Conversion of functional.c matrix_ calls to new API
softmattertheory Jan 15, 2026
42f520e
matrix_setcolumnptr and matrix_addtocolumnptr for integration
softmattertheory Jan 15, 2026
39af4d5
Fix header files and replace matrix_setcolumn with matrix_setcolumnptr
softmattertheory Jan 16, 2026
0ffa0bb
Remove circular dependency in includes
softmattertheory Jan 16, 2026
1a9912a
Fix undefined error message
softmattertheory Jan 16, 2026
cff963e
Migrate some helper functions for sparse constructor functions
softmattertheory Jan 16, 2026
e556459
Fix error messages and unmangle Method implementation names
softmattertheory Jan 16, 2026
b3d0b79
Unmangle function names
softmattertheory Jan 16, 2026
0edffda
matrix_copyat
softmattertheory Jan 16, 2026
e1b76fa
Fix duplicate error
softmattertheory Jan 16, 2026
2c491f9
Fix uses of setcolumn in mesh.c
softmattertheory Jan 16, 2026
3fdb421
Fixes for test suite
softmattertheory Jan 16, 2026
cec3db2
Fix error labels
softmattertheory Jan 16, 2026
5455866
Delete unused errors
softmattertheory Jan 16, 2026
a0e657e
Remove unused errors
softmattertheory Jan 16, 2026
836dc1d
Remove unused errors
softmattertheory Jan 16, 2026
eaffbbe
Remove unused error
softmattertheory Jan 16, 2026
d29e6f9
A whole bunch of useful errors
softmattertheory Jan 16, 2026
8f3e885
Platform independent re-entrant qsort
softmattertheory Jan 16, 2026
34b9650
Tuple sort functions
softmattertheory Jan 16, 2026
df0f322
Remove extraneous spaces
softmattertheory Jan 16, 2026
4d48f7f
Add non-camelcase method name for Matrix.setColumn
softmattertheory Jan 16, 2026
0dac41d
Fix return type check in sparsedok_copymatrixat
softmattertheory Jan 16, 2026
bd94b31
Fix field initialization to match new matrix type
softmattertheory Jan 16, 2026
0e591d1
Fix test for zero in eigenvalue creation
softmattertheory Jan 17, 2026
e2d3668
Add delayed signature parsing
softmattertheory Jan 17, 2026
ace41d7
Correct erroneous error checks
softmattertheory Jan 17, 2026
2386259
Correct error in test suite
softmattertheory Jan 17, 2026
0577692
Correct MORPHO_STATICMATRIX
softmattertheory Jan 17, 2026
38ab79d
Correct field_addpool
softmattertheory Jan 17, 2026
bb4278a
Correct error message
softmattertheory Jan 17, 2026
6916c7d
Add list and tuple to indexing
softmattertheory Jan 17, 2026
e06b4cb
Fix matrix slicing and permit negative indices
softmattertheory Jan 20, 2026
248db48
Fixed slicing test
softmattertheory Jan 20, 2026
e15a127
Check return values of matrix_getcolumnptr
softmattertheory Jan 20, 2026
35f046c
Matrix concatenation
softmattertheory Jan 20, 2026
5f27916
Raise error correctly if MORPHO_INCLUDE_SPARSE is not defined
softmattertheory Jan 20, 2026
1945149
Fix more errors due to incorrect error checks
softmattertheory Jan 20, 2026
dfd4d26
Fix error checks in functional_symmetrysumforces
softmattertheory Jan 20, 2026
b60c811
Fix Identity constructor
softmattertheory Jan 20, 2026
f3a14c9
Fix Identity Matrix constructor error
softmattertheory Jan 20, 2026
52f138b
Correct error checking in matrix_listconstructor to raise error in in…
softmattertheory Jan 20, 2026
54bc65e
Fix error in matrix_sum usage.
softmattertheory Jan 20, 2026
809d05b
Linear Algebra tests integrated
softmattertheory Jan 21, 2026
905f10b
Remove newlinalg folder and contents, completing integration
softmattertheory Jan 21, 2026
956d289
Update LAPACKE path for linux build
softmattertheory Jan 26, 2026
dcfdf7c
Revised boxing scheme
softmattertheory Jan 27, 2026
0255436
Fix issues with QR decomposition
softmattertheory Jan 27, 2026
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
1,717 changes: 1,717 additions & 0 deletions help/errors.md

Large diffs are not rendered by default.

54 changes: 45 additions & 9 deletions src/builtin/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,39 @@ objecttypedefn objectbuiltinfunctiondefn = {
.cmpfn=NULL
};

/* **********************************************************************
* Signature parsing
* ********************************************************************** */

/** This mechanism allows builtin classes to cross-reference one another in method signature declarations */

typedef struct _sigparses {
const char *sig;
signature *dest;
} _sigparse;

DECLARE_VARRAY(_sigparse, _sigparse)
DEFINE_VARRAY(_sigparse, _sigparse)

varray__sigparse sigparseworklist;

/** Add a signature to be parsed on the next call to builtin_parsesignatures */
void builtin_addparsesignature(const char *sig, signature *dest) {
_sigparse s = { .sig = sig, .dest = dest };
varray__sigparsewrite(&sigparseworklist, s);
}

/** Parses all signatures on the worklist */
bool builtin_parsesignatures(void) {
_sigparse s;
while (varray__sigparsepop(&sigparseworklist, &s)) {
if (!signature_parse(s.sig, s.dest)) {
return false;
}
}
return true;
}

/* **********************************************************************
* Create and find builtin functions
* ********************************************************************** */
Expand Down Expand Up @@ -264,10 +297,7 @@ bool morpho_addfunction(char *name, char *signature, builtinfunction func, built
if (!name) goto morpho_addfunction_cleanup;

// Parse function signature if provided
if (signature &&
!signature_parse(signature, &new->sig)) {
UNREACHABLE("Syntax error in signature definition.");
}
if (signature) builtin_addparsesignature(signature, &new->sig);

value newfn = MORPHO_OBJECT(new);

Expand Down Expand Up @@ -340,9 +370,7 @@ bool morpho_addclass(char *name, builtinclassentry desc[], int nparents, value *
newmethod->klass=new;
newmethod->name=object_stringfromcstring(desc[i].name, strlen(desc[i].name));
newmethod->flags=desc[i].flags;
if (desc[i].signature) {
success &= signature_parse(desc[i].signature, &newmethod->sig);
}
if (desc[i].signature) builtin_addparsesignature(desc[i].signature, &newmethod->sig);

dictionary_intern(&builtin_symboltable, newmethod->name);
value method = MORPHO_OBJECT(newmethod);
Expand Down Expand Up @@ -425,10 +453,12 @@ void builtin_initialize(void) {
builtin_setclasstable(&builtin_classtable);

// Initialize core object types
objectstringtype=object_addtype(&objectstringdefn);
objectclasstype=object_addtype(&objectclassdefn);
objectstringtype=object_addtype(&objectstringdefn);
objectbuiltinfunctiontype=object_addtype(&objectbuiltinfunctiondefn);

varray__sigparseinit(&sigparseworklist);

/* Initialize builtin classes and functions */
instance_initialize(); // Must initialize first so that Object exists

Expand Down Expand Up @@ -462,7 +492,7 @@ void builtin_initialize(void) {

// Initialize linear algebra
#ifdef MORPHO_INCLUDE_LINALG
matrix_initialize();
linalg_initialize();
#endif

#ifdef MORPHO_INCLUDE_SPARSE
Expand All @@ -473,6 +503,10 @@ void builtin_initialize(void) {
// Initialize geometry
geometry_initialize();
#endif

if (!builtin_parsesignatures()) {
UNREACHABLE("Syntax error in signature.");
}

morpho_addfinalizefn(builtin_finalize);
}
Expand All @@ -484,6 +518,8 @@ void builtin_finalize(void) {
builtin_objects=next;
}

varray__sigparseclear(&sigparseworklist);

dictionary_clear(&builtin_functiontable);
dictionary_clear(&builtin_classtable);
dictionary_clear(&builtin_symboltable);
Expand Down
3 changes: 3 additions & 0 deletions src/builtin/builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include "signature.h"

/** Call to pase method and function signatures */
bool builtin_parsesignatures(void);

/* -------------------------------------------------------
* Built in function objects
* ------------------------------------------------------- */
Expand Down
5 changes: 2 additions & 3 deletions src/builtin/functiondefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "common.h"
#include "cmplx.h"

#include "matrix.h"
#include "linalg.h"
#include "sparse.h"

#include "mesh.h"
Expand Down Expand Up @@ -324,7 +324,7 @@ value builtin_arctan(vm *v, int nargs, value *args) {

morpho_runtimeerror(v, MATH_NUMARGS, "arctan");
return MORPHO_NIL;
}
}
}

/** Remainder */
Expand Down Expand Up @@ -747,7 +747,6 @@ void functiondefs_initialize(void) {
/* Define errors */
morpho_defineerror(MATH_ARGS, ERROR_HALT, MATH_ARGS_MSG);
morpho_defineerror(MATH_NUMARGS, ERROR_HALT, MATH_NUMARGS_MSG);
morpho_defineerror(MATH_ATANARGS, ERROR_HALT, MATH_ATANARGS_MSG);
morpho_defineerror(TYPE_NUMARGS, ERROR_HALT, TYPE_NUMARGS_MSG);
morpho_defineerror(MAX_ARGS, ERROR_HALT, MAX_ARGS_MSG);
morpho_defineerror(APPLY_ARGS, ERROR_HALT, APPLY_ARGS_MSG);
Expand Down
3 changes: 0 additions & 3 deletions src/builtin/functiondefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@
#define MATH_NUMARGS "ExpctArgNm"
#define MATH_NUMARGS_MSG "Function '%s' expects a single numerical argument."

#define MATH_ATANARGS "AtanArgNm"
#define MATH_ATANARGS_MSG "Function 'arctan' expects either 1 or 2 numerical arguments."

#define TYPE_NUMARGS "TypArgNm"
#define TYPE_NUMARGS_MSG "Function '%s' expects one argument."

Expand Down
12 changes: 7 additions & 5 deletions src/classes/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void array_print(vm *v, objectarray *a) {
errorid array_error(objectarrayerror err) {
switch (err) {
case ARRAY_OUTOFBOUNDS: return VM_OUTOFBOUNDS;
case ARRAY_WRONGDIM: return VM_ARRAYWRONGDIM;
case ARRAY_WRONGDIM: return ARRAY_DIMENSION;
case ARRAY_NONINTINDX: return VM_NONNUMINDX;
case ARRAY_ALLOC_FAILED: return ERROR_ALLOCATIONFAILED;
case ARRAY_OK: UNREACHABLE("array_error called incorrectly.");
Expand All @@ -193,9 +193,9 @@ errorid array_error(objectarrayerror err) {
errorid array_to_matrix_error(objectarrayerror err) {
#ifdef MORPHO_INCLUDE_LINALG
switch (err) {
case ARRAY_OUTOFBOUNDS: return MATRIX_INDICESOUTSIDEBOUNDS;
case ARRAY_WRONGDIM: return MATRIX_INVLDNUMINDICES;
case ARRAY_NONINTINDX: return MATRIX_INVLDINDICES;
case ARRAY_OUTOFBOUNDS: return LINALG_INDICESOUTSIDEBOUNDS;
case ARRAY_WRONGDIM: return ARRAY_DIMENSION;
case ARRAY_NONINTINDX: return ARRAY_INVLDINDICES;
case ARRAY_ALLOC_FAILED: return ERROR_ALLOCATIONFAILED;
case ARRAY_OK: UNREACHABLE("array_to_matrix_error called incorrectly.");
}
Expand Down Expand Up @@ -457,7 +457,7 @@ value array_constructor(vm *v, int nargs, value *args) {
new = array_constructfromlist(ndim, dim, MORPHO_GETLIST(initializer));
if (!new) morpho_runtimeerror(v, ARRAY_CMPT);
} else {
morpho_runtimeerror(v, ARRAY_ARGS);
morpho_runtimeerror(v, ARRAY_INIT);
}

// Bind the new array to the VM
Expand Down Expand Up @@ -630,4 +630,6 @@ void array_initialize(void) {
morpho_defineerror(ARRAY_ARGS, ERROR_HALT, ARRAY_ARGS_MSG);
morpho_defineerror(ARRAY_INIT, ERROR_HALT, ARRAY_INIT_MSG);
morpho_defineerror(ARRAY_CMPT, ERROR_HALT, ARRAY_CMPT_MSG);
morpho_defineerror(ARRAY_DIMENSION, ERROR_HALT, ARRAY_DIMENSION_MSG);
morpho_defineerror(ARRAY_INVLDINDICES, ERROR_HALT, ARRAY_INVLDINDICES_MSG);
}
6 changes: 6 additions & 0 deletions src/classes/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ objectarray *object_arrayfromvalueindices(unsigned int ndim, value *dim);
#define ARRAY_CMPT "ArrayCmpt"
#define ARRAY_CMPT_MSG "Array initializer is not compatible with the requested dimensions."

#define ARRAY_DIMENSION "ArrayDim"
#define ARRAY_DIMENSION_MSG "Incorrect number of dimensions for Array."

#define ARRAY_INVLDINDICES "ArrayIndx"
#define ARRAY_INVLDINDICES_MSG "Array requires integers as indices."

/* -------------------------------------------------------
* Array interface
* ------------------------------------------------------- */
Expand Down
2 changes: 1 addition & 1 deletion src/classes/classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
//#include "system.h"
#include "json.h"

#include "matrix.h"
#include "linalg.h"

#endif /* classes_h */
1 change: 0 additions & 1 deletion src/classes/clss.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,5 +196,4 @@ void class_initialize(void) {
// No constructor function; classes are generated by the compiler

// Class error messages
morpho_defineerror(CLASS_INVK, ERROR_HALT, CLASS_INVK_MSG);
}
3 changes: 0 additions & 3 deletions src/classes/clss.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ typedef struct sobjectclass {
* Class error messages
* ------------------------------------------------------- */

#define CLASS_INVK "ClssInvk"
#define CLASS_INVK_MSG "Cannot invoke method '%s' on a class."

/* -------------------------------------------------------
* Class interface
* ------------------------------------------------------- */
Expand Down
1 change: 0 additions & 1 deletion src/classes/invocation.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,4 @@ void invocation_initialize(void) {

// Invocation error messages
morpho_defineerror(INVOCATION_ARGS, ERROR_HALT, INVOCATION_ARGS_MSG);
morpho_defineerror(INVOCATION_METHOD, ERROR_HALT, INVOCATION_METHOD_MSG);
}
3 changes: 0 additions & 3 deletions src/classes/invocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ objectinvocation *object_newinvocation(value receiver, value method);
#define INVOCATION_ARGS "InvocationArgs"
#define INVOCATION_ARGS_MSG "Invocation must be called with an object and a method name as arguments."

#define INVOCATION_METHOD "InvocationMethod"
#define INVOCATION_METHOD_MSG "Method not found."

/* -------------------------------------------------------
* Invocation interface
* ------------------------------------------------------- */
Expand Down
63 changes: 29 additions & 34 deletions src/classes/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,35 +130,45 @@ int list_sortfunction(const void *a, const void *b) {
}

/** Sort the contents of a list */
void list_sort(objectlist *list) {
qsort(list->val.data, list->val.count, sizeof(value), list_sortfunction);
void list_sortcontents(value *values, size_t count) {
qsort(values, count, sizeof(value), list_sortfunction);
}

static vm *list_sortwithfn_vm;
static value list_sortwithfn_fn;
static bool list_sortwithfn_err;

/** Sort function for list_sort */
int list_sortfunctionwfn(const void *a, const void *b) {
value args[2] = {*(value *) a, *(value *) b};
value ret;
/** Sort the contents of a list */
void list_sort(objectlist *list) {
list_sortcontents(list->val.data, list->val.count);
}

if (morpho_call(list_sortwithfn_vm, list_sortwithfn_fn, 2, args, &ret)) {
/** Sort the contents of a list using a re-entrant comparison function */
typedef struct {
vm *v;
value cmpfn;
bool errq;
} _sortfninfo;

static int _sortfn(const void *a, const void *b, void *context) {
_sortfninfo *info = (_sortfninfo *) context;
value ret, args[2] = {*(value *) a, *(value *) b};

if (morpho_call(info->v, info->cmpfn, 2, args, &ret)) {
if (MORPHO_ISINTEGER(ret)) return MORPHO_GETINTEGERVALUE(ret);
if (MORPHO_ISFLOAT(ret)) return morpho_comparevalue(MORPHO_FLOAT(0), ret);
}

list_sortwithfn_err=true;
info->errq=true;
return 0;
}

/** Sort a list of values */
bool list_sortcontentswithfn(vm *v, value cmpfn, value *values, size_t count) {
_sortfninfo info = { .v = v, .cmpfn = cmpfn, .errq=false };
platform_qsort_r(values, count, sizeof(value), &info, _sortfn);
return !info.errq;
}

/** Sort the contents of a list */
bool list_sortwithfn(vm *v, value fn, objectlist *list) {
list_sortwithfn_vm=v;
list_sortwithfn_fn=fn;
list_sortwithfn_err=false;
qsort(list->val.data, list->val.count, sizeof(value), list_sortfunctionwfn);
return !list_sortwithfn_err;
bool list_sortwithfn(vm *v, value cmpfn, objectlist *list) {
return list_sortcontentswithfn(v, cmpfn, list->val.data, list->val.count);
}

/** Sort function for list_order */
Expand Down Expand Up @@ -612,21 +622,6 @@ value List_roll(vm *v, int nargs, value *args) {
return out;
}

/** Sorts a list */
value XList_sort(vm *v, int nargs, value *args) {
objectlist *slf = MORPHO_GETLIST(MORPHO_SELF(args));

if (nargs==0) {
list_sort(slf);
} else if (nargs==1 && MORPHO_ISCALLABLE(MORPHO_GETARG(args, 0))) {
if (!list_sortwithfn(v, MORPHO_GETARG(args, 0), slf)) {
morpho_runtimeerror(v, LIST_SRTFN);
}
}

return MORPHO_NIL;
}

/** Sorts a list */
value List_sort(vm *v, int nargs, value *args) {
list_sort(MORPHO_GETLIST(MORPHO_SELF(args)));
Expand Down
4 changes: 4 additions & 0 deletions src/classes/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ bool list_resize(objectlist *list, int size);
void list_append(objectlist *list, value v);
unsigned int list_length(objectlist *list);
bool list_getelement(objectlist *list, int i, value *out);
void list_sortcontents(value *values, size_t count);
void list_sort(objectlist *list);
bool list_sortcontentswithfn(vm *v, value cmpfn, value *values, size_t count);
bool list_sortwithfn(vm *v, value cmpfn, objectlist *list);

objectlist *list_clone(objectlist *list);

void list_initialize(void);
Expand Down
29 changes: 29 additions & 0 deletions src/classes/tuple.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,33 @@ value Tuple_join(vm *v, int nargs, value *args) {
return out;
}

/** Sorts the contents of a tuple, returning a new tuple */
value Tuple_sort(vm *v, int nargs, value *args) {
objecttuple *src = MORPHO_GETTUPLE(MORPHO_SELF(args));

objecttuple *new = object_newtuple(src->length, src->tuple);
if (new) list_sortcontents(new->tuple, new->length);

return morpho_wrapandbind(v, (object *) new);
}

/** Sorts the contents of a tuple using a comparison function, returning a new tuple */
value Tuple_sort_fn(vm *v, int nargs, value *args) {
objecttuple *src = MORPHO_GETTUPLE(MORPHO_SELF(args));

objecttuple *new=object_newtuple(src->length, src->tuple);
if (new) {
bool success=list_sortcontentswithfn(v, MORPHO_GETARG(args, 0), new->tuple, new->length);
if (!success) {
morpho_runtimeerror(v, LIST_SRTFN);
object_free((object *) new);
return MORPHO_NIL;
}
}

return morpho_wrapandbind(v, (object *) new);
}

/** Tests if a tuple has a value as a member */
value Tuple_ismember(vm *v, int nargs, value *args) {
objecttuple *slf = MORPHO_GETTUPLE(MORPHO_SELF(args));
Expand All @@ -276,6 +303,8 @@ MORPHO_METHOD(MORPHO_GETINDEX_METHOD, Tuple_getindex, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD(MORPHO_SETINDEX_METHOD, Tuple_setindex, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD(MORPHO_ENUMERATE_METHOD, Tuple_enumerate, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD_SIGNATURE(MORPHO_JOIN_METHOD, "Tuple (_)", Tuple_join, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD_SIGNATURE(LIST_SORT_METHOD, "Tuple ()", Tuple_sort, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD_SIGNATURE(LIST_SORT_METHOD, "Tuple (_)", Tuple_sort_fn, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD_SIGNATURE(LIST_ISMEMBER_METHOD, "Bool (_)", Tuple_ismember, BUILTIN_FLAGSEMPTY),
MORPHO_METHOD_SIGNATURE(MORPHO_CONTAINS_METHOD, "Bool (_)", Tuple_ismember, BUILTIN_FLAGSEMPTY)
MORPHO_ENDCLASS
Expand Down
Loading
Loading