+inline void free_class_attrs(type *clss) {
+ assert(clss && (clss->type_op == type_class));
+ DEL_ARR_F(clss->attr.ca.members);
+ DEL_ARR_F(clss->attr.ca.subtypes);
+ DEL_ARR_F(clss->attr.ca.supertypes);
+}
+/* manipulate private fields of class type */
+void add_class_member (type *clss, entity *member) {
+ assert(clss && (clss->type_op == type_class));
+ ARR_APP1 (entity *, clss->attr.ca.members, member);
+}
+int get_class_n_member (type *clss) {
+ assert(clss && (clss->type_op == type_class));
+ return (ARR_LEN (clss->attr.ca.members))-1;
+}
+entity *get_class_member (type *clss, int pos) {
+ assert(clss && (clss->type_op == type_class));
+ return clss->attr.ca.members[pos+1];
+}
+void set_class_member (type *clss, entity *member, int pos) {
+ assert(clss && (clss->type_op == type_class));
+ clss->attr.ca.members[pos+1] = member;
+}
+void remove_class_member(type *clss, entity *member) {
+ int i;
+ assert(clss && (clss->type_op == type_class));
+ for (i = 1; i < (ARR_LEN (clss->attr.ca.members))-1; i++)
+ if (clss->attr.ca.members[i+1] == member) {
+ for(i++; i < (ARR_LEN (clss->attr.ca.members)) - 1; i++)
+ clss->attr.ca.members[i] = clss->attr.ca.members[i + 1];
+ ARR_SETLEN(entity*, clss->attr.ca.members, ARR_LEN(clss->attr.ca.members) - 1);
+ break;
+ }
+}
+
+void add_class_subtype (type *clss, type *subtype) {
+ int i;
+ assert(clss && (clss->type_op == type_class));
+ ARR_APP1 (type *, clss->attr.ca.subtypes, subtype);
+ for (i = 0; i < get_class_n_supertype(subtype); i++)
+ if (get_class_supertype(subtype, i) == clss)
+ /* Class already registered */
+ return;
+ ARR_APP1 (type *, subtype->attr.ca.supertypes, clss);
+}
+int get_class_n_subtype (type *clss) {
+ assert(clss && (clss->type_op == type_class));
+ return (ARR_LEN (clss->attr.ca.subtypes))-1;
+}
+type *get_class_subtype (type *clss, int pos) {
+ assert(clss && (clss->type_op == type_class));
+ return clss->attr.ca.subtypes[pos+1] = skip_tid(clss->attr.ca.subtypes[pos+1]);
+}
+void set_class_subtype (type *clss, type *subtype, int pos) {
+ assert(clss && (clss->type_op == type_class));
+ clss->attr.ca.subtypes[pos+1] = subtype;
+}
+void remove_class_subtype(type *clss, type *subtype) {
+ int i;
+ assert(clss && (clss->type_op == type_class));
+ for (i = 1; i < (ARR_LEN (clss->attr.ca.subtypes))-1; i++)
+ if (clss->attr.ca.subtypes[i+1] == subtype) {
+ for(i++; i < (ARR_LEN (clss->attr.ca.subtypes))-1; i++)
+ clss->attr.ca.subtypes[i] = clss->attr.ca.subtypes[i+1];
+ ARR_SETLEN(entity*, clss->attr.ca.subtypes, ARR_LEN(clss->attr.ca.subtypes) - 1);
+ break;
+ }
+}
+
+void add_class_supertype (type *clss, type *supertype) {
+ int i;
+ assert(clss && (clss->type_op == type_class));
+ assert(supertype && (supertype -> type_op == type_class));
+ ARR_APP1 (type *, clss->attr.ca.supertypes, supertype);
+ for (i = 0; i < get_class_n_subtype(supertype); i++)
+ if (get_class_subtype(supertype, i) == clss)
+ /* Class already registered */
+ return;
+ ARR_APP1 (type *, supertype->attr.ca.subtypes, clss);
+}
+int get_class_n_supertype (type *clss) {
+ assert(clss && (clss->type_op == type_class));
+ return (ARR_LEN (clss->attr.ca.supertypes))-1;
+}
+type *get_class_supertype (type *clss, int pos) {
+ assert(clss && (clss->type_op == type_class));
+ return clss->attr.ca.supertypes[pos+1] = skip_tid(clss->attr.ca.supertypes[pos+1]);
+}
+void set_class_supertype (type *clss, type *supertype, int pos) {
+ assert(clss && (clss->type_op == type_class));
+ clss->attr.ca.supertypes[pos+1] = supertype;
+}
+void remove_class_supertype(type *clss, type *supertype) {
+ int i;
+ assert(clss && (clss->type_op == type_class));
+ for (i = 1; i < (ARR_LEN (clss->attr.ca.supertypes))-1; i++)
+ if (clss->attr.ca.supertypes[i+1] == supertype) {
+ for(i++; i < (ARR_LEN (clss->attr.ca.supertypes))-1; i++)
+ clss->attr.ca.supertypes[i] = clss->attr.ca.supertypes[i+1];
+ ARR_SETLEN(entity*, clss->attr.ca.supertypes, ARR_LEN(clss->attr.ca.supertypes) - 1);
+ break;
+ }
+}
+/* typecheck */
+bool is_class_type(type *clss) {
+ assert(clss);
+ if (clss->type_op == type_class) return 1; else return 0;