more interfaces, interface constructors + error message, instanceable filter + exception, and a few more things

This commit is contained in:
overflowerror 2017-03-12 18:58:29 +01:00
parent f5d8997c2a
commit 155dbb607f
12 changed files with 145 additions and 17 deletions

View file

@ -23,7 +23,10 @@ int main(void) {
} }
printf("\nremoving index %lu\n", list->length(list)); printf("\nremoving index %lu\n", list->length(list));
list->remove(list, list->length(list)); //list->remove(list, list->length(list));
//List_t* list2 = new List();
Object_t* obj = new Object();
return 0; return 0;
} }

View file

@ -1,7 +1,6 @@
#include "stdex.h" #include "stdex.h"
#include "../memory.h" #include "../memory.h"
#include "../try.h" #include "../try.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@ -18,7 +17,7 @@ void method(Exception, populate)(Exception_t* obj, class_t c) {
Exception_t* method(Exception, construct)(const char* msg) { Exception_t* method(Exception, construct)(const char* msg) {
throws(OutOfMemoryException_t); throws(OutOfMemoryException_t);
sr_(Exception_t* obj = allocate_object(Exception_t), NULL); sr_(Exception_t* obj = allocate_object(Exception), NULL);
populate(Exception)(obj, Exception_class); populate(Exception)(obj, Exception_class);
obj->msg = msg; obj->msg = msg;
@ -39,7 +38,7 @@ void method(NullPointerException, populate)(NullPointerException_t* obj, class_t
NullPointerException_t* method(NullPointerException, construct)() { NullPointerException_t* method(NullPointerException, construct)() {
throws(OutOfMemoryException_t); throws(OutOfMemoryException_t);
sr_(NullPointerException_t* obj = allocate_object(NullPointerException_t), NULL); sr_(NullPointerException_t* obj = allocate_object(NullPointerException), NULL);
populate(NullPointerException)(obj, NullPointerException_class); populate(NullPointerException)(obj, NullPointerException_class);
obj->super.msg = "Unexpected Null-pointer."; obj->super.msg = "Unexpected Null-pointer.";
@ -84,7 +83,7 @@ void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t* ob
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t index, size_t length) { IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t index, size_t length) {
throws(OutOfMemoryException_t); throws(OutOfMemoryException_t);
sr_(IndexOutOfBoundsException_t* obj = allocate_object(IndexOutOfBoundsException_t), NULL); sr_(IndexOutOfBoundsException_t* obj = allocate_object(IndexOutOfBoundsException), NULL);
populate(IndexOutOfBoundsException)(obj, IndexOutOfBoundsException_class); populate(IndexOutOfBoundsException)(obj, IndexOutOfBoundsException_class);
const char* format = "Requested index %i is out of bounds (%i)."; const char* format = "Requested index %i is out of bounds (%i).";
@ -102,3 +101,52 @@ IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t
return obj; return obj;
} }
class_t IllegalArgumentException_class;
void method(IllegalArgumentException, destruct)(IllegalArgumentException_t* this) {
this->super.destruct((Exception_t*) this);
}
void method(IllegalArgumentException, populate)(IllegalArgumentException_t* obj, class_t c) {
populate(Exception)((Exception_t*) obj, c);
add_method(obj, IllegalArgumentException, destruct);
}
IllegalArgumentException_t* method(IllegalArgumentException, construct)(const char* msg) {
throws(OutOfMemoryException_t);
sr_(IllegalArgumentException_t* obj = allocate_object(IllegalArgumentException), NULL);
populate(IllegalArgumentException)(obj, IllegalArgumentException_class);
obj->super.msg = msg;
return obj;
}
class_t ClassNotInstanceableException_class;
void method(ClassNotInstanceableException, destruct)(ClassNotInstanceableException_t* this) {
free((void*) this->super.msg);
this->super.destruct((Exception_t*) this);
}
void method(ClassNotInstanceableException, populate)(ClassNotInstanceableException_t* obj, class_t c) {
populate(Exception)((Exception_t*) obj, c);
add_method(obj, ClassNotInstanceableException, destruct);
}
ClassNotInstanceableException_t* method(ClassNotInstanceableException, construct)(const char* c) {
throws(OutOfMemoryException_t);
sr_(ClassNotInstanceableException_t* obj = allocate_object(ClassNotInstanceableException), NULL);
populate(ClassNotInstanceableException)(obj, ClassNotInstanceableException_class);
const char* format = "Class %s is not instanceable.";
size_t size = strlen(format) - 2 + strlen(c);
sr_(char* msg = allocate(size + 1), NULL);
snprintf(msg, size + 1, format, c);
obj->super.msg = msg;
return obj;
}

View file

@ -45,4 +45,24 @@ extern class(IndexOutOfBoundsException, Exception_class, NO_INTERFACES, true) {
void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t*, class_t); void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t*, class_t);
IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t, size_t); IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t, size_t);
#define IllegalArgumentException construct(IllegalArgumentException)
extern class(IllegalArgumentException, Exception_class, NO_INTERFACES, true) {
extends(Exception_t);
void (*destruct)(defclass IllegalArgumentException*);
} IllegalArgumentException_t;
void method(IllegalArgumentException, populate)(IllegalArgumentException_t*, class_t);
IllegalArgumentException_t* method(IllegalArgumentException, construct)(const char*);
#define ClassNotInstanceableException construct(ClassNotInstanceableException)
extern class(ClassNotInstanceableException, Exception_class, NO_INTERFACES, true) {
extends(Exception_t);
void (*destruct)(defclass ClassNotInstanceableException*);
} ClassNotInstanceableException_t;
void method(ClassNotInstanceableException, populate)(ClassNotInstanceableException_t*, class_t);
ClassNotInstanceableException_t* method(ClassNotInstanceableException, construct)(const char*);
#endif #endif

View file

@ -16,7 +16,7 @@ class_t ArrayList_class;
ArrayList_t* method(ArrayList, construct)(void) { ArrayList_t* method(ArrayList, construct)(void) {
throws(OutOfMemoryException_t); throws(OutOfMemoryException_t);
sr_(ArrayList_t* list = allocate_object(ArrayList_t), NULL); sr_(ArrayList_t* list = allocate_object(ArrayList), NULL);
populate(ArrayList)(list, ArrayList_class); populate(ArrayList)(list, ArrayList_class);
return list; return list;

View file

@ -3,3 +3,4 @@
class_t Countable_class; class_t Countable_class;
class_t List_class; class_t List_class;
class_t Stack_class; class_t Stack_class;
class_t Iterateable_class;

View file

@ -3,11 +3,33 @@
#include "../oop.h" #include "../oop.h"
typedef Object_t Countable_t;
extern interface(Countable) extern interface(Countable)
#define Countable_interface size_t (*length)(void*); #define Countable_interface size_t (*length)(void*);
#define Countable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Countable.\"");
typedef Object_t List_t;
extern interface(List) extern interface(List)
#define List_interface void (*add)(void*, void*); void* (*get)(void*, size_t); void (*remove)(void*, size_t); #define List_interface void (*add)(void*, void*); void* (*get)(void*, size_t); void (*remove)(void*, size_t);
#define List(...) NULL; _Pragma("GCC error \"Cannot make instance of interface List.\"");
typedef Object_t Stack_t;
extern interface(Stack) extern interface(Stack)
#define Stack_interface void (*push)(void*, void*); void* (*pop)(void*); #define Stack_interface void (*push)(void*, void*); void* (*pop)(void*);
#define Stack(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Stack.\"");
typedef struct iterator_args {
void* list;
void* parameter;
void* obj;
int num; // -1 if no id
} iterator_args;
typedef bool (*iterator)(iterator_args);
typedef Object_t Iterateable_t;
extern interface(Iterateable)
#define Iterateable_interface bool (*iterate)(void*, iterator, void*)
#define Iterateable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Iterateable.\"");
#endif #endif

View file

@ -5,33 +5,41 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
void allocate_sub(size_t size, void** ptr) { throws(Exception_t); void allocate_sub(size_t size, void** ptr) { throws(OutOfMemoryException_t);
*ptr = malloc(size); *ptr = malloc(size);
if (*ptr == NULL) { if (*ptr == NULL) {
throw(new Exception(strerror(errno))); throw(new OutOfMemoryException());
} }
} }
void* allocate(size_t size) { throws(Exception_t); void* allocate_o(class_t c, size_t size) { throws(OutOfMemoryException_t, ClassNotInstanceableException_t);
if (!oop_is_instanceable(c))
throwr(new ClassNotInstanceableException(oop_get_class_name(c)), NULL);
void* ptr; void* ptr;
sr_(allocate_sub(size, &ptr), NULL); sr_(allocate_sub(size, &ptr), NULL);
return ptr; return ptr;
} }
void reallocate_sub(size_t size, void** ptr, void* old) { throws(Exception_t); void* allocate(size_t size) { throws(OutOfMemoryException_t);
void* ptr;
sr_(allocate_sub(size, &ptr), NULL);
return ptr;
}
void reallocate_sub(size_t size, void** ptr, void* old) { throws(OutOfMemoryException_t);
*ptr = realloc(old, size); *ptr = realloc(old, size);
if (*ptr == NULL) { if (*ptr == NULL) {
throw(new Exception(strerror(errno))); throw(new OutOfMemoryException());
} }
} }
void* reallocate(void* old, size_t size) { throws(Exception_t); void* reallocate(void* old, size_t size) { throws(OutOfMemoryException_t);
void* ptr; void* ptr;
sr_(reallocate_sub(size, &ptr, old), NULL); sr_(reallocate_sub(size, &ptr, old), NULL);
return ptr; return ptr;
} }
void* clone(const void* org, size_t size) { throws(Exception_t); void* clone(const void* org, size_t size) { throws(OutOfMemoryException_t);
void* ptr; void* ptr;
sr_(allocate_sub(size, &ptr), NULL); sr_(allocate_sub(size, &ptr), NULL);
memcpy(ptr, org, size); memcpy(ptr, org, size);

View file

@ -4,11 +4,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define allocate_object(type) allocate(sizeof(type)); #include "oop.h"
#include "try.h"
#include "exceptions/stdex.h"
#define allocate_object(type) allocate_o(type##_class, sizeof(type##_t));
#define clone_string(s) clone((void*) s, strlen(s) + 1) #define clone_string(s) clone((void*) s, strlen(s) + 1)
#define clone_obj(obj, class) clone((void*) obj, sizeof(class)) #define clone_obj(obj, class) clone((void*) obj, sizeof(class))
void* allocate_o(class_t, size_t);
void* allocate(size_t); void* allocate(size_t);
void* reallocate(void*, size_t); void* reallocate(void*, size_t);
void* clone(const void*, size_t); void* clone(const void*, size_t);

14
oop.c
View file

@ -78,6 +78,10 @@ bool oop_class_exists(const char* class_name) {
return oop_id_from_name(class_name) != NO_CLASS_ID; return oop_id_from_name(class_name) != NO_CLASS_ID;
} }
bool oop_is_instanceable(class_t c) {
return classes[c.id].instanceable;
}
class_t oop_class_from_id(class_id_t id) { class_t oop_class_from_id(class_id_t id) {
return (class_t) {.id = id}; return (class_t) {.id = id};
} }
@ -90,12 +94,20 @@ class_t oop_get_class_from_obj(Object_t* obj) {
return oop_class_from_id(((Object_t*) obj)->meta_obj.type.id); return oop_class_from_id(((Object_t*) obj)->meta_obj.type.id);
} }
void oop_check_interface(class_t c, Object_t* obj) {
throws(IllegalArgumentException_t);
if (!instanceof(obj, c))
throw(new IllegalArgumentException("Object is not instance of interface."));
}
// defined by class macro in h-file // defined by class macro in h-file
class_t Object_class; class_t Object_class;
// defined by interface macro in h-file // defined by interface macro in h-file
class_t Cloneable_class; class_t Cloneable_class;
class_t Compareable_class;
void method(Object, destruct)(Object_t* obj) { void method(Object, destruct)(Object_t* obj) {
@ -103,7 +115,7 @@ void method(Object, destruct)(Object_t* obj) {
} }
Object_t* method(Object, construct)() { throws(OutOfMemoryException_t); Object_t* method(Object, construct)() { throws(OutOfMemoryException_t);
sr_(Object_t* obj = allocate_object(Object_t), NULL); sr_(Object_t* obj = allocate_object(Object), NULL);
populate(Object)(obj, Object_class); populate(Object)(obj, Object_class);
return obj; return obj;
} }

9
oop.h
View file

@ -59,13 +59,18 @@ typedef struct meta_object {
class_id_t oop_add_class(const char*, bool, class_t, iflist_t, bool); class_id_t oop_add_class(const char*, bool, class_t, iflist_t, bool);
#define Object construct(Object) #define Object construct(Object)
extern class(Object, NO_SUPER_CLASS, NO_INTERFACES, true) { extern class(Object, NO_SUPER_CLASS, NO_INTERFACES, false) {
meta_object_t meta_obj; meta_object_t meta_obj;
void (*destruct)(defclass Object*); void (*destruct)(defclass Object*);
} Object_t; } Object_t;
extern interface(Cloneable) extern interface(Cloneable)
#define Cloneable_interface void*(*clone)(void*) #define Cloneable_interface void*(*clone)(void*)
#define Cloneable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Cloneable.\"");
extern interface(Compareable)
#define Compareable_interface int(*compare)(void*)
#define Compareable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Compareable.\"");
bool oop_instance_of_id(void*, class_id_t); bool oop_instance_of_id(void*, class_id_t);
bool oop_instance_of(void*, class_t); bool oop_instance_of(void*, class_t);
@ -74,7 +79,9 @@ class_id_t oop_id_from_name(const char*);
bool oop_class_exists(const char*); bool oop_class_exists(const char*);
class_t oop_class_from_id(class_id_t); class_t oop_class_from_id(class_id_t);
class_t oop_get_super_class(class_t); class_t oop_get_super_class(class_t);
bool oop_is_instanceable(class_t);
class_t oop_get_class_from_obj(Object_t*); class_t oop_get_class_from_obj(Object_t*);
void oop_check_interface(class_t, Object_t*);
Object_t* method(Object, construct)(void); Object_t* method(Object, construct)(void);
void method(Object, populate)(Object_t* obj, class_t); void method(Object, populate)(Object_t* obj, class_t);

View file

@ -91,7 +91,7 @@ const char* method(Strbuilder, get)(Strbuilder_t* this) {
Strbuilder_t* method(Strbuilder, construct)(const char* string) { Strbuilder_t* method(Strbuilder, construct)(const char* string) {
throws(OutOfMemoryException_t); throws(OutOfMemoryException_t);
sr_(Strbuilder_t* obj = allocate_object(Strbuilder_t), NULL); sr_(Strbuilder_t* obj = allocate_object(Strbuilder), NULL);
populate(Strbuilder)(obj, Strbuilder_class); populate(Strbuilder)(obj, Strbuilder_class);

2
try.c
View file

@ -109,6 +109,8 @@ void try_throw(try_t id, void* exception) {
e->msg); e->msg);
#endif #endif
e->destruct(); // destruct of exception (not sub classes), because we don't know what this is
_print_backtrace(stderr, 2); _print_backtrace(stderr, 2);
} else { } else {
trys[id].exception = exception; trys[id].exception = exception;