Anonymous avatar Anonymous committed 8b4d54f Merge

Merged.

Comments (0)

Files changed (6)

 }
 
 static AR
-arana_list_length(AR_SIG, AR self, AR args)
+arana_list_length_get(AR_SIG, AR self, AR args)
 {
-    AR_ASSERT_EMPTY_ARGS(args, "length");
+    AR_ASSERT_EMPTY_ARGS(args, "length:get");
     return AR_INTEGER(AR_LIST_SIZE(self));
 }
 
     AR_BIND_METHOD(type, ":setitem", arana_list_set);
     AR_BIND_METHOD(type, ":concat", arana_list_concat);
     AR_BIND_METHOD(type, ":mul", arana_list_mul);
-    AR_BIND_METHOD(type, "length", arana_list_length);
+    AR_BIND_METHOD(type, "length:get", arana_list_length_get);
     AR_BIND_METHOD(type, "append", arana_list_append);
     AR_BIND_METHOD(type, "delete", arana_list_delete);
     AR_BIND_METHOD(type, "clear", arana_list_clear);
     return arana_call_with_self(AR_ISIG, object, AR_NONE, args);
 }
 
+static AR
+arana_call_method_unchecked(AR_SIG, AR object, const char *member, AR args,
+                            int try_getter)
+{
+    AR method;
+    int from_type;
+    if (!arana_lookup_member(AR_ISIG, object, member, &method, &from_type,
+                             try_getter))
+        return AR_NULL;
+    return arana_call_with_self(AR_ISIG, method, object, args);
+}
+
 AR
 arana_call_method(AR_SIG, AR object, const char *member, AR args)
 {
-    AR method;
-    int from_type;
-    if (!arana_lookup_member(AR_ISIG, object, member, &method, &from_type)) {
+    AR result = arana_call_method_unchecked(AR_ISIG, object, member, args, 1);
+    if (!result) {
         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);
+    return result;
 }
 
 AR
 
 int
 arana_lookup_member(AR_SIG, AR object, const char *member,
-                    AR *value_out, int *from_type_out)
+                    AR *value_out, int *from_type_out, int try_getter)
 {
     int from_type = 0;
     AR value = AR_NULL;
             type = AR_PARENT_TYPE(type);
         }
     }
+    if (!value && try_getter) {
+        Ar_size_t length = strlen(member);
+        char *getter_name = AR_ALLOC(length + 5);
+        memcpy(getter_name, member, length);
+        memcpy(getter_name + length, ":get", 5);
+        value = arana_call_method_unchecked(AR_ISIG, object, getter_name,
+                                            AR_TUPLE(0), 0);
+    }
+
     if (!value)
         return 0;
 
         AR_RAISE(AR_TYPE_ERROR("member names have to be strings"));
 
     if (!arana_lookup_member(AR_ISIG, object, AR_AS_CHARP(member),
-                             &value, &from_type))
-        return AR_NULL;
+                             &value, &from_type, 1)) {
+        char errorbuf[300];
+        snprintf(errorbuf, 300, "'%s' has no attribute named '%s'",
+                 AR_TYPE_NAME(object), AR_AS_CHARP(member));
+        AR_RAISE(AR_ATTRIBUTE_ERROR(AR_AS_CHARP(member), errorbuf));
+    }
 
     /* if we are dealing with attribute on a type object
        we always return a method with "self" bound to the
        coming from the type and we don't have a type
        object. */
     if (AR_IS_FUNCTION(value) && (AR_IS_TYPE(object) || from_type))
-            value = arana_method_new(AR_ISIG, value, object);
+        value = arana_method_new(AR_ISIG, value, object);
 
     return value;
 }
 AR_API_FUNC(AR) arana_get_parent_type(AR_SIG, AR type);
 AR_API_FUNC(AR) arana_get_member(AR_SIG, AR object, AR member);
 AR_API_FUNC(int) arana_lookup_member(AR_SIG, AR object, const char *member,
-                                     AR *value_out, int *from_type_out);
+                                     AR *value_out, int *from_type_out,
+                                     int try_getter);
 AR_API_FUNC(void) arana_each(AR_SIG, AR object, ArIterationFunc func,
                              void *closure);
 AR_API_FUNC(AR) arana_generic_get_self_iterator(AR_SIG, AR self, AR args);
 }
 
 static AR
+arana_string_length_get(AR_SIG, AR self, AR args)
+{
+    AR_ASSERT_EMPTY_ARGS(args, "length:get");
+    return AR_INTEGER(AR_STRING_SIZE(self));
+}
+
+static AR
 arana_string_to_string(AR_SIG, AR self, AR args)
 {
     AR_ASSERT_EMPTY_ARGS(args, "to_string");
     AR type = AR_CREATE_TYPE(ArStringType);
     AR_BIND_METHOD(type, ":concat", arana_string_concat);
     AR_BIND_METHOD(type, ":mul", arana_string_mul);
+    AR_BIND_METHOD(type, "length:get", arana_string_length_get);
     AR_BIND_METHOD(type, "to_string", arana_string_to_string);
     AR_BIND_METHOD(type, "to_repr", arana_string_to_repr);
     AR_BIND_METHOD(type, "get_iterator", arana_string_get_iterator);
 }
 
 static AR
-arana_tuple_length(AR_SIG, AR self, AR args)
+arana_tuple_length_get(AR_SIG, AR self, AR args)
 {
-    AR_ASSERT_EMPTY_ARGS(args, "length");
+    AR_ASSERT_EMPTY_ARGS(args, "length:get");
     return AR_INTEGER(AR_TUPLE_SIZE(self));
 }
 
     AR type = AR_CREATE_TYPE(ArTupleType);
     AR_BIND_METHOD(type, ":getitem", arana_tuple_get);
     AR_BIND_METHOD(type, ":concat", arana_tuple_concat);
-    AR_BIND_METHOD(type, "length", arana_tuple_length);
+    AR_BIND_METHOD(type, "length:get", arana_tuple_length_get);
     AR_BIND_METHOD(type, "to_string", arana_tuple_to_string);
     AR_BIND_METHOD(type, "get_iterator", arana_tuple_get_iterator);
     return type;
+name = "World"
+"A list with stuff in: #{["Hello #{name}!", 42, 23]}\n".print()
+
+list = [1, 2, 3]
+"Length of list: #{list.length}\n".print()
+
+for item in [1, 2, 3, 4, 5]:
+    "Item: #{item.to_repr()}\n".print()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.