Skip to content

Commit 0798807

Browse files
Merge pull request #309 from Morpho-lang/typecheck
This commit implements type checking in morpho. Declare a variable with a restricted type as follows: Int a = 5 The morpho compiler will now ensure that anything assigned to this variable meets the type restriction. This is done through a combination of compile time checking (using type inference) and runtime (dynamic) checking.
2 parents 9e55680 + 3915aca commit 0798807

149 files changed

Lines changed: 2727 additions & 735 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/build.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
* Version
1111
* ********************************************************************** */
1212

13-
#define MORPHO_VERSIONSTRING "0.6.3"
13+
#define MORPHO_VERSIONSTRING "0.6.4"
1414

1515
#define MORPHO_VERSION_MAJOR 0
1616
#define MORPHO_VERSION_MINOR 6
17-
#define MORPHO_VERSION_PATCH 3
17+
#define MORPHO_VERSION_PATCH 4
1818

1919
/* **********************************************************************
2020
* Paths and file system

src/builtin/builtin.c

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
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 */
347372
value 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 */
354386
void 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();

src/builtin/builtin.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ typedef unsigned int builtinfunctionflags;
2626
#define BUILTIN_FLAGSEMPTY 0
2727

2828
#define MORPHO_FN_FLAGSEMPTY (0)
29-
#define MORPHO_FN_PUREFN (1<<1)
30-
#define MORPHO_FN_CONSTRUCTOR (1<<2)
31-
#define MORPHO_FN_REENTRANT (1<<3)
32-
#define MORPHO_FN_OPTARGS (1<<4)
29+
#define MORPHO_FN_PUREFN (1<<1) // Pure function: no side effects
30+
#define MORPHO_FN_CONSTRUCTOR (1<<2) // Constructor function
31+
#define MORPHO_FN_REENTRANT (1<<3) // Function that re-enters the vm, e.g. but using morph_call
32+
#define MORPHO_FN_OPTARGS (1<<4) // Function that has optional arguments
3333

3434
/** Type of C function that implements a built in Morpho function */
3535
typedef value (*builtinfunction) (vm *v, int nargs, value *args);
@@ -127,6 +127,7 @@ bool morpho_addfunction(char *name, char *signature, builtinfunction func, built
127127

128128
value builtin_addclass(char *name, builtinclassentry desc[], value superclass);
129129
value builtin_findclass(value name);
130+
value builtin_findclassfromcstring(char *label);
130131

131132
void builtin_copysymboltable(dictionary *out);
132133

@@ -143,11 +144,11 @@ bool builtin_enumerateloop(vm *v, value obj, builtin_loopfunction fn, void *ref)
143144
* Veneer classes
144145
* ------------------------------------------------------- */
145146

146-
void object_setveneerclass(objecttype type, value class);
147+
void object_setveneerclass(objecttype type, value klass);
147148
objectclass *object_getveneerclass(objecttype type);
148149
bool object_veneerclasstotype(objectclass *clss, objecttype *type);
149150

150-
void value_setveneerclass(value type, value class);
151+
void value_setveneerclass(value type, value klass);
151152
objectclass *value_getveneerclass(value type);
152153
objectclass *value_veneerclassfromtype(int type);
153154
bool value_veneerclasstotype(objectclass *clss, int *type);

0 commit comments

Comments
 (0)