44 * @brief Morpho built in functions and classes
55*/
66
7+ #include <stdarg.h>
8+
79#include "builtin.h"
810#include "common.h"
911#include "object.h"
@@ -184,7 +186,7 @@ void builtin_setclasstable(dictionary *dict) {
184186 _currentclasstable = dict ;
185187}
186188
187- /** Add a builtin function.
189+ /** Add a builtin function (old interface)
188190 * @param name name of the function
189191 * @param func the corresponding C function
190192 * @param flags flags to define the function
@@ -295,22 +297,39 @@ bool morpho_addfunction(char *name, char *signature, builtinfunction func, built
295297/** Defines a built in class
296298 * @param[in] name the name of the class
297299 * @param[in] desc class description; use MORPHO_GETCLASSDEFINITION(name) to obtain this
298- * @param[in] superclass the class's superclass
299- * @returns the class object */
300- value builtin_addclass (char * name , builtinclassentry desc [], value superclass ) {
300+ * @param[in] nparents number of parent classes
301+ * @param[in] parents the parent classes
302+ * @param[out] out the class object
303+ * @returns true on success */
304+ bool morpho_addclass (char * name , builtinclassentry desc [], int nparents , value * parents , value * out ) {
301305 value label = object_stringfromcstring (name , strlen (name ));
302306 builtin_bindobject (MORPHO_GETOBJECT (label ));
303307 objectclass * new = object_newclass (label );
304308 builtin_bindobject ((object * ) new );
305- objectclass * superklass = NULL ;
309+ bool success = true ;
306310
307- if (!new ) return MORPHO_NIL ;
311+ if (!new ) return false;
312+
313+ if (dictionary_get (_currentclasstable , label , NULL )) {
314+ UNREACHABLE ("Redefinition of class in same extension [in builtin.c]" );
315+ }
316+
317+ dictionary_insert (_currentclasstable , label , MORPHO_OBJECT (new ));
308318
309319 /** Copy methods from superclass */
310- if (MORPHO_ISCLASS (superclass )) {
311- superklass = MORPHO_GETCLASS (superclass );
312- dictionary_copy (& superklass -> methods , & new -> methods );
313- new -> superclass = superklass ;
320+ for (int i = 0 ; i < nparents ; i ++ ) {
321+ if (MORPHO_ISCLASS (parents [i ])) {
322+ objectclass * parentclass = MORPHO_GETCLASS (parents [i ]);
323+ dictionary_copy (& parentclass -> methods , & new -> methods );
324+ if (i == 0 ) new -> superclass = parentclass ;
325+ varray_valuewrite (& new -> parents , parents [i ]);
326+ varray_valuewrite (& parentclass -> children , MORPHO_OBJECT (new ));
327+ }
328+ }
329+
330+ /** Compute the class linearization */
331+ if (!class_linearize (new )) {
332+ UNREACHABLE ("Class definition not linearizable." );
314333 }
315334
316335 for (unsigned int i = 0 ; desc [i ].name != NULL ; i ++ ) {
@@ -322,7 +341,7 @@ value builtin_addclass(char *name, builtinclassentry desc[], value superclass) {
322341 newmethod -> name = object_stringfromcstring (desc [i ].name , strlen (desc [i ].name ));
323342 newmethod -> flags = desc [i ].flags ;
324343 if (desc [i ].signature ) {
325- signature_parse (desc [i ].signature , & newmethod -> sig );
344+ success &= signature_parse (desc [i ].signature , & newmethod -> sig );
326345 }
327346
328347 dictionary_intern (& builtin_symboltable , newmethod -> name );
@@ -334,22 +353,35 @@ value builtin_addclass(char *name, builtinclassentry desc[], value superclass) {
334353 }
335354 }
336355
337- if (dictionary_get (_currentclasstable , label , NULL )) {
338- UNREACHABLE ("Redefinition of class in same extension [in builtin.c]" );
339- }
340-
341- dictionary_insert (_currentclasstable , label , MORPHO_OBJECT (new ));
342-
343- return MORPHO_OBJECT (new );
356+ if (success )* out = MORPHO_OBJECT (new );
357+ return success ;
358+ }
359+
360+ /** Defines a built in class (old interface)
361+ * @param[in] name the name of the class
362+ * @param[in] desc class description; use MORPHO_GETCLASSDEFINITION(name) to obtain this
363+ * @param[in] superclass the class's superclass
364+ * @returns the class object */
365+ value builtin_addclass (char * name , builtinclassentry desc [], value superclass ) {
366+ value out = MORPHO_NIL ;
367+ morpho_addclass (name , desc , 1 , & superclass , & out );
368+ return out ;
344369}
345370
346- /** Finds a builtin class from its name */
371+ /** Finds a builtin class from its label */
347372value builtin_findclass (value name ) {
348373 value out = MORPHO_NIL ;
349- dictionary_get (& builtin_classtable , name , & out );
374+ if (_currentclasstable ) dictionary_get (_currentclasstable , name , & out );
375+ if (MORPHO_ISNIL (out )) dictionary_get (& builtin_classtable , name , & out );
350376 return out ;
351377}
352378
379+ /** Finds a builtin class from a cstring label */
380+ value builtin_findclassfromcstring (char * label ) {
381+ objectstring objname = MORPHO_STATICSTRING (label );
382+ return builtin_findclass (MORPHO_OBJECT (& objname ));
383+ }
384+
353385/** Copies the built in symbol table into a new dictionary */
354386void builtin_copysymboltable (dictionary * out ) {
355387 dictionary_copy (& builtin_symboltable , out );
@@ -400,8 +432,14 @@ void builtin_initialize(void) {
400432 /* Initialize builtin classes and functions */
401433 instance_initialize (); // Must initialize first so that Object exists
402434
435+ float_initialize (); // Veneer classes
436+ int_initialize ();
437+ bool_initialize ();
438+ nil_initialize ();
439+
403440 string_initialize (); // Classes
404441 function_initialize ();
442+ cfunction_initialize ();
405443 metafunction_initialize ();
406444 class_initialize ();
407445 upvalue_initialize ();
@@ -415,10 +453,6 @@ void builtin_initialize(void) {
415453 err_initialize ();
416454 tuple_initialize ();
417455
418- float_initialize ();// Veneer classes
419- int_initialize ();
420- bool_initialize ();
421-
422456 file_initialize ();
423457 system_initialize ();
424458 json_initialize ();
0 commit comments