diff --git a/exceptions/stdex.h b/exceptions/stdex.h index 676cb1e..04b864c 100644 --- a/exceptions/stdex.h +++ b/exceptions/stdex.h @@ -3,7 +3,7 @@ #include "../oop.h" -#define Exception construct(Exception) +//#define Exception construct(Exception) extern class(Exception, Object_class, NO_INTERFACES, true) { extends(Object_t); @@ -15,7 +15,7 @@ extern class(Exception, Object_class, NO_INTERFACES, true) { void method(Exception, populate)(Exception_t*, class_t); Exception_t* method(Exception, construct)(const char*); -#define NullPointerException construct(NullPointerException) +//#define NullPointerException construct(NullPointerException) extern class(NullPointerException, Exception_class, NO_INTERFACES, true) { extends(Exception_t); @@ -25,7 +25,7 @@ extern class(NullPointerException, Exception_class, NO_INTERFACES, true) { void method(NullPointerException, populate)(NullPointerException_t*, class_t); NullPointerException_t* method(NullPointerException, construct)(void); -#define OutOfMemoryException construct(OutOfMemoryException) +//#define OutOfMemoryException construct(OutOfMemoryException) extern class(OutOfMemoryException, Exception_class, NO_INTERFACES, true) { extends(Exception_t); @@ -35,7 +35,7 @@ extern class(OutOfMemoryException, Exception_class, NO_INTERFACES, true) { void method(OutOfMemoryException, populate)(OutOfMemoryException_t*, class_t); OutOfMemoryException_t* method(OutOfMemoryException, construct)(void); -#define IndexOutOfBoundsException construct(IndexOutOfBoundsException) +//#define IndexOutOfBoundsException construct(IndexOutOfBoundsException) extern class(IndexOutOfBoundsException, Exception_class, NO_INTERFACES, true) { extends(Exception_t); @@ -45,7 +45,7 @@ extern class(IndexOutOfBoundsException, Exception_class, NO_INTERFACES, true) { void method(IndexOutOfBoundsException, populate)(IndexOutOfBoundsException_t*, class_t); IndexOutOfBoundsException_t* method(IndexOutOfBoundsException, construct)(size_t, size_t); -#define IllegalArgumentException construct(IllegalArgumentException) +//#define IllegalArgumentException construct(IllegalArgumentException) extern class(IllegalArgumentException, Exception_class, NO_INTERFACES, true) { extends(Exception_t); @@ -55,7 +55,7 @@ extern class(IllegalArgumentException, Exception_class, NO_INTERFACES, true) { void method(IllegalArgumentException, populate)(IllegalArgumentException_t*, class_t); IllegalArgumentException_t* method(IllegalArgumentException, construct)(const char*); -#define ClassNotInstanceableException construct(ClassNotInstanceableException) +//#define ClassNotInstanceableException construct(ClassNotInstanceableException) extern class(ClassNotInstanceableException, Exception_class, NO_INTERFACES, true) { extends(Exception_t); diff --git a/lists/arraylist.c b/lists/arraylist.c index b201efe..af2c2c1 100644 --- a/lists/arraylist.c +++ b/lists/arraylist.c @@ -30,7 +30,7 @@ size_t method(ArrayList, length)(void* this) { void method(ArrayList, add)(void* this, void* obj) { throws(NullPointerException_t, OutOfMemoryException_t); if (this == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); to_list(list, this); @@ -46,12 +46,12 @@ void method(ArrayList, add)(void* this, void* obj) { void* method(ArrayList, get)(void* this, size_t index) { throws(NullPointerException_t, IndexOutOfBoundsException_t); if (this == NULL) - throwr(new NullPointerException(), NULL); + throwr(new (NullPointerException)(), NULL); to_list(list, this); if (index >= list->currentSize) - throwr(new IndexOutOfBoundsException(index, list->currentSize), NULL); + throwr(new (IndexOutOfBoundsException)(index, list->currentSize), NULL); return list->data[index]; @@ -59,12 +59,12 @@ void* method(ArrayList, get)(void* this, size_t index) { void method(ArrayList, remove)(void* this, size_t index) { throws(NullPointerException_t, OutOfMemoryException_t); if (this == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); to_list(list, this); if (index >= list->currentSize) - throw(new IndexOutOfBoundsException(index, list->currentSize)); + throw(new (IndexOutOfBoundsException)(index, list->currentSize)); for(size_t i = index; i < list->currentSize - 1; i++) { list->data[i] = list->data[i + 1]; @@ -78,7 +78,7 @@ void method(ArrayList, remove)(void* this, size_t index) { void method(ArrayList, push)(void* this, void* obj) { throws(NullPointerException_t); if (this == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); to_list(list, this); @@ -88,7 +88,7 @@ void method(ArrayList, push)(void* this, void* obj) { void* method(ArrayList, pop)(void* this) { throws(NullPointerException_t, OutOfMemoryException_t); if (this == NULL) - throwr(new NullPointerException(), NULL); + throwr(new (NullPointerException)(), NULL); to_list(list, this); @@ -99,12 +99,59 @@ void* method(ArrayList, pop)(void* this) { return element; } +void* method(ArrayList, clone)(void* this) { + throws(NullPointerException_t, OutOfMemoryException_t); + if (this == NULL) + throwr(new (NullPointerException)(), NULL); + + to_list(list, this); + + ArrayList_t* listn = new (ArrayList)(); + + listn->currentSize = list->currentSize; + listn->steps = list->steps; + listn->sizeStep = list->sizeStep; + + sr_(listn->data = clone(list->data, list->currentSize), NULL); + + return (void*) listn; +} + +int method(ArrayList, compare)(void* this, void* other) { + throws(NullPointerException_t); + if (this == NULL) + throwr(new (NullPointerException)(), -1); + + if (other == NULL) + throwr(new (NullPointerException)(), -1); + + to_list(list, this); + + Object_t* obj = (Object_t*) other; + if (oop_get_class_from_obj(obj).id != oop_get_class_from_obj((Object_t*) list).id) + throwr(new (IllegalArgumentException)("Compared objects are not instances of the same class."), -1); + + to_list(olist, obj); + + if (list->currentSize == olist->currentSize) + return 0; + else if (list->currentSize > olist->currentSize) + return 1; + else + return -1; +} + void method(ArrayList, destruct)(ArrayList_t* this) { throws(NullPointerException_t); if (this == NULL) - throw(new NullPointerException()); - + throw(new (NullPointerException)()); + to_list(list, this); + + if (list->data != NULL) + free(list->data); + + list->super.destruct((Object_t*) list); } void method(ArrayList, populate)(ArrayList_t* obj, class_t c) { @@ -115,6 +162,8 @@ void method(ArrayList, populate)(ArrayList_t* obj, class_t c) { obj->steps = 0; obj->sizeStep = DEFAULT_SIZE_STEP; + add_hashcode(obj); + add_method(obj, ArrayList, destruct); add_method(obj, ArrayList, length); add_method(obj, ArrayList, add); diff --git a/lists/arraylist.h b/lists/arraylist.h index 4921bcd..cf6d56d 100644 --- a/lists/arraylist.h +++ b/lists/arraylist.h @@ -4,13 +4,16 @@ #include "../oop.h" #include "lists.h" -#define ArrayList construct(ArrayList) -extern class(ArrayList, Object_class, (interfaces){4 namely {Cloneable_class and List_class and Countable_class and Stack_class}}, true) { +// #define ArrayList construct(ArrayList) +extern class(ArrayList, Object_class, (interfaces){5 namely {Cloneable_class and List_class and Countable_class and Stack_class and Compareable_class}}, true) { extends(Object_t); implements(Cloneable); implements(List); implements(Countable); implements(Stack); + implements(Compareable); + def_hashcode(); + void (*destruct)(defclass ArrayList*); size_t currentSize; diff --git a/lists/lists.h b/lists/lists.h index 20f79a0..35f7b9a 100644 --- a/lists/lists.h +++ b/lists/lists.h @@ -18,6 +18,12 @@ extern interface(Stack) #define Stack_interface void (*push)(void*, void*); void* (*pop)(void*); #define Stack(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Stack.\""); +/*typedef Object_t Set_t; +extern interface(Set) +#define Set_interface void (*add)(void*, void*); void (*remove)(void*, void*); void* (*contains)(void*, void*); +#define Set(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Set.\""); +*/ + typedef struct iterator_args { void* list; void* parameter; diff --git a/memory.c b/memory.c index ae91017..7b14e62 100644 --- a/memory.c +++ b/memory.c @@ -8,13 +8,13 @@ void allocate_sub(size_t size, void** ptr) { throws(OutOfMemoryException_t); *ptr = malloc(size); if (*ptr == NULL) { - throw(new OutOfMemoryException()); + throw(new (OutOfMemoryException)()); } } 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); + throwr(new (ClassNotInstanceableException)(oop_get_class_name(c)), NULL); void* ptr; sr_(allocate_sub(size, &ptr), NULL); return ptr; @@ -29,7 +29,7 @@ void* allocate(size_t size) { throws(OutOfMemoryException_t); void reallocate_sub(size_t size, void** ptr, void* old) { throws(OutOfMemoryException_t); *ptr = realloc(old, size); if (*ptr == NULL) { - throw(new OutOfMemoryException()); + throw(new (OutOfMemoryException)()); } } diff --git a/oop.c b/oop.c index 6940560..86b0eb1 100644 --- a/oop.c +++ b/oop.c @@ -2,6 +2,7 @@ #include "memory.h" #include "try.h" #include "exceptions/stdex.h" +#include "misc.h" #include #include @@ -98,7 +99,7 @@ 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.")); + throw(new (IllegalArgumentException)("Object is not instance of interface.")); } @@ -120,7 +121,17 @@ Object_t* method(Object, construct)() { throws(OutOfMemoryException_t); return obj; } +int method(Object, hashCode)(Object_t* obj) { + UNUSED(obj); + return 0; +} + void method(Object, populate)(Object_t* obj, class_t type) { obj->meta_obj.type = type; add_method(obj, Object, destruct); } + + +int method(DefMethods, hashCode)(void* obj) { + return ((Object_t*) obj)->hashCode(obj); +} diff --git a/oop.h b/oop.h index e06fec6..735e0be 100644 --- a/oop.h +++ b/oop.h @@ -8,7 +8,8 @@ #define interface(name) class_t name##_class; __attribute__ ((constructor)) static void add_##name##_interface(void) { name##_class.id = oop_add_class(#name, true, NO_SUPER_CLASS, NO_INTERFACES, false);} #define class(name, superclass, interfaces, instanceable) class_t name##_class; __attribute__ ((constructor)) static void add_##name##_class(void) { name##_class.id = oop_add_class(#name, false, superclass, interfaces, instanceable);} typedef struct name #define method(class, method) class ##_method_## method -#define add_method(object, class, method) object->method = class ##_method_## method +#define add_method(object, class, method) override_method(object, class, class, method) +#define override_method(object, class, mclass, method) ((class ## _t*) object)->method = mclass ##_method_## method #define implements(i) i##_interface #define extends(type) type super @@ -19,7 +20,7 @@ #define instanceof(obj, class) oop_instance_of(obj, class) #define call(obj, method) (obj)->method((obj)) -#define new +#define new(class) construct(class) #define defclass struct #define MAX_CLASSES 1024 @@ -58,10 +59,11 @@ typedef struct meta_object { 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, false) { meta_object_t meta_obj; void (*destruct)(defclass Object*); + int (*hashCode)(void*); } Object_t; extern interface(Cloneable) @@ -72,6 +74,10 @@ extern interface(Compareable) #define Compareable_interface int(*compare)(void*) #define Compareable(...) NULL; _Pragma("GCC error \"Cannot make instance of interface Compareable.\""); +#define def_hashcode() int(*hashCode)(void*) +#define add_hashcode(obj) obj->hashCode = DefMethods_method_hashCode +int method(DefMethods, hashCode)(void*); + bool oop_instance_of_id(void*, class_id_t); bool oop_instance_of(void*, class_t); const char* oop_get_class_name(class_t); @@ -84,6 +90,6 @@ class_t oop_get_class_from_obj(Object_t*); void oop_check_interface(class_t, Object_t*); Object_t* method(Object, construct)(void); -void method(Object, populate)(Object_t* obj, class_t); +void method(Object, populate)(Object_t*, class_t); #endif diff --git a/tools/strbuilder.c b/tools/strbuilder.c index 7333d9b..3f1fd27 100644 --- a/tools/strbuilder.c +++ b/tools/strbuilder.c @@ -12,7 +12,7 @@ void method(Strbuilder, clear)(Strbuilder_t* this) { throws(NullPointerException_t); if (this == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); for (int i = 0; i < this->nrstrings; i++) { free(this->strings[i]); @@ -26,7 +26,7 @@ void method(Strbuilder, destruct)(Strbuilder_t* this) { throws(NullPointerException_t); if (this == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); this->clear(this); this->super.destruct((Object_t*) this); @@ -36,7 +36,7 @@ void method(Strbuilder, add)(Strbuilder_t* this, const char* string) { throws(OutOfMemoryException_t, NullPointerException_t); if (this == NULL || string == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); s_(this->strings = reallocate(this->strings, ++this->nrstrings * sizeof(char*))); s_(this->strings[this->nrstrings - 1] = allocate(strlen(string) + 1)); @@ -47,7 +47,7 @@ size_t method(Strbuilder, length)(Strbuilder_t* this) { throws(NullPointerException_t); if (this == NULL) - throwr(new NullPointerException(), 0); + throwr(new (NullPointerException)(), 0); size_t length = 0; if (this->string != NULL) @@ -62,7 +62,7 @@ void method(Strbuilder, build)(Strbuilder_t* this) { throws(OutOfMemoryException_t, NullPointerException_t); if (this == NULL) - throw(new NullPointerException()); + throw(new (NullPointerException)()); size_t length = this->length(this); bool empty = this->string == NULL; @@ -80,7 +80,7 @@ const char* method(Strbuilder, get)(Strbuilder_t* this) { throws(NullPointerException_t); if (this == NULL) - throwr(new NullPointerException(), NULL); + throwr(new (NullPointerException)(), NULL); if (this->string == NULL) return ""; @@ -88,6 +88,7 @@ const char* method(Strbuilder, get)(Strbuilder_t* this) { return this->string; } + Strbuilder_t* method(Strbuilder, construct)(const char* string) { throws(OutOfMemoryException_t); @@ -103,6 +104,18 @@ Strbuilder_t* method(Strbuilder, construct)(const char* string) { return obj; } +int method(Strbuilder, hashCode)(void* obj) { + throws(NullPointerException_t); + if (obj == NULL) + throwr(new (NullPointerException)(), 0); + + Strbuilder_t* builder = (Strbuilder_t*) obj; + + + UNUSED(builder); + + return 0; +} void method(Strbuilder, populate)(Strbuilder_t* obj, class_t c) { populate(Object)((Object_t*) obj, c); @@ -111,6 +124,9 @@ void method(Strbuilder, populate)(Strbuilder_t* obj, class_t c) { obj->strings = NULL; obj->nrstrings = 0; + add_hashcode(obj); + override_method(obj, Object, Strbuilder, hashCode); + add_method(obj, Strbuilder, destruct); add_method(obj, Strbuilder, add); add_method(obj, Strbuilder, build); diff --git a/tools/strbuilder.h b/tools/strbuilder.h index d3a8d74..56f6df4 100644 --- a/tools/strbuilder.h +++ b/tools/strbuilder.h @@ -4,9 +4,10 @@ #include #include "../oop.h" -#define Strbuilder construct(Strbuilder) +//#define Strbuilder construct(Strbuilder) extern class(Strbuilder, Object_class, NO_INTERFACES, true) { extends(Object_t); + def_hashcode(); char* string; char** strings; diff --git a/try.c b/try.c index 641d246..5739c0b 100644 --- a/try.c +++ b/try.c @@ -109,7 +109,7 @@ void try_throw(try_t id, void* exception) { e->msg); #endif - e->destruct(); // destruct of exception (not sub classes), because we don't know what this is + e->destruct(e); // destruct of exception (not sub classes), because we don't know what this is _print_backtrace(stderr, 2); } else {