Commits

mitsuhiko  committed 41970eb

Added list concatenation and improved error message for missing methods.

  • Participants
  • Parent commits c508dad

Comments (0)

Files changed (4)

File arana/list.c

     list->allocated = AR_DEFAULT_LIST_SIZE;
 }
 
+/* invoked by AR_LIST_COPY */
+AR
+_arana_api_list_copy(AR_SIG, AR self)
+{
+    ArList *list = (ArList*)AR_LIST2(AR_LIST_SIZE(self));
+    list->size = AR_LIST_SIZE(self);
+    memcpy(list->items, ((ArList*)self)->items, sizeof(AR) * list->size);
+    return (AR)list;
+}
+
+/* helper for _arana_api_list_concat */
+void
+_arana_list_concat_append(AR_SIG, AR value, AR list)
+{
+    AR_LIST_APPEND(list, value);
+}
+
+/* invoked by AR_LIST_CONCAT */
+AR
+_arana_api_list_concat(AR_SIG, AR self, AR other)
+{
+    AR result = AR_LIST_COPY(self);
+    AR_EACH(other, (ArIterationFunc)_arana_list_concat_append, (void*)result);
+    return result;
+}
+
 static AR
 arana_list_get(AR_SIG, AR self, AR args)
 {
 }
 
 static AR
+arana_list_concat(AR_SIG, AR self, AR args)
+{
+    AR other;
+    AR_PARSE(args, "O::concat", &other);
+    return AR_LIST_CONCAT(self, other);
+}
+
+static AR
 arana_list_length(AR_SIG, AR self, AR args)
 {
     AR_ASSERT_EMPTY_ARGS(args, "length");
 }
 
 static AR
+arana_list_copy(AR_SIG, AR self, AR args)
+{
+    AR_ASSERT_EMPTY_ARGS(args, "copy");
+    return AR_LIST_COPY(self);
+}
+
+static AR
 arana_list_to_string(AR_SIG, AR self, AR args)
 {
     Ar_size_t i;
     AR type = AR_CREATE_TYPE(ArListType);
     AR_BIND_METHOD(type, ":getitem", arana_list_get);
     AR_BIND_METHOD(type, ":setitem", arana_list_set);
+    AR_BIND_METHOD(type, ":concat", arana_list_concat);
     AR_BIND_METHOD(type, "length", arana_list_length);
     AR_BIND_METHOD(type, "append", arana_list_append);
     AR_BIND_METHOD(type, "delete", arana_list_delete);
     AR_BIND_METHOD(type, "clear", arana_list_clear);
+    AR_BIND_METHOD(type, "copy", arana_list_copy);
     AR_BIND_METHOD(type, "to_string", arana_list_to_string);
     AR_BIND_METHOD(type, "get_iterator", arana_list_get_iterator);
     return type;

File arana/list.h

 #define AR_LIST_CLEAR(l) _arana_api_list_clear(AR_ISIG, l)
 #define AR_LIST_SIZE(l) ((ArList *)(l))->size
 #define AR_LIST_EMPTY(l) (AR_LIST_SIZE(l) == 0)
+#define AR_LIST_COPY(l) _arana_api_list_copy(AR_ISIG, l)
+#define AR_LIST_CONCAT(l, o) _arana_api_list_concat(AR_ISIG, l, o)
 
 typedef struct _ArList {
     AR_OBJECT_HEAD;
 AR_API_FUNC(void) _arana_api_list_append(AR_SIG, AR self, AR value);
 AR_API_FUNC(AR) _arana_api_list_delete(AR_SIG, AR self, Ar_size_t index);
 AR_API_FUNC(void) _arana_api_list_clear(AR_SIG, AR self);
+AR_API_FUNC(AR) _arana_api_list_copy(AR_SIG, AR self);
+AR_API_FUNC(AR) _arana_api_list_concat(AR_SIG, AR self, AR other);
 AR_API_FUNC(AR) arana_create_list_type(AR_SIG);
 AR_API_FUNC(AR) arana_create_list_iterator_type(AR_SIG);
 

File arana/object.c

 {
     AR method;
     int from_type;
-    if (!arana_lookup_member(AR_ISIG, object, member, &method, &from_type))
-        AR_RAISE(AR_ATTRIBUTE_ERROR(member, "No such method"));
-    if (!AR_IS_FUNCTION(method))
-        AR_RAISE(AR_TYPE_ERROR("Receiver is not callable"));
+    if (!arana_lookup_member(AR_ISIG, object, member, &method, &from_type)) {
+        char errorbuf[300];
+        snprintf(errorbuf, 300, "'%s' has no method named '%s'",
+                 AR_TYPE_NAME(object), member);
+        AR_RAISE(AR_ATTRIBUTE_ERROR(member, errorbuf));
+    }
     return arana_call_with_self(AR_ISIG, method, object, args);
 }
 

File arana/tuple.c

     return (AR)result;
 }
 
+/* invoked by AR_TUPLE_CONCAT */
 AR
 _arana_api_tuple_concat(AR_SIG, AR self, AR other)
 {