format() and object.__format__()

This commit is contained in:
K. Lange 2022-07-10 16:10:07 +09:00
parent f1c0af711e
commit d8a1861c23
5 changed files with 42 additions and 7 deletions

View File

@ -174,6 +174,16 @@ KRK_Method(object,__str__) {
return out;
}
KRK_Method(object,__format__) {
METHOD_TAKES_EXACTLY(1);
if (!IS_STRING(argv[1])) return TYPE_ERROR(str,argv[1]);
if (AS_STRING(argv[1])->length != 0) return krk_runtimeError(vm.exceptions->typeError, "Unsupported format string");
KrkClass * type = krk_getType(argv[0]);
if (!type->_tostr) return krk_runtimeError(vm.exceptions->typeError, "'%s' can not be converted to str", krk_typeName(argv[0]));
krk_push(argv[0]);
return krk_callDirect(type->_tostr, 1);
}
#undef CURRENT_CTYPE
#undef CURRENT_NAME
@ -1098,6 +1108,27 @@ KRK_Function(abs) {
}
}
KRK_Function(format) {
FUNCTION_TAKES_AT_LEAST(1);
FUNCTION_TAKES_AT_MOST(2);
KrkClass * type = krk_getType(argv[0]);
if (!type->_format) {
return krk_runtimeError(vm.exceptions->typeError, "'%s' has no __format__ method", krk_typeName(argv[0]));
}
krk_push(argv[0]);
if (argc < 2) krk_push(OBJECT_VAL(S("")));
else krk_push(argv[1]);
KrkValue result = krk_callDirect(type->_format, 2);
if (!IS_STRING(result)) {
return krk_runtimeError(vm.exceptions->typeError, "__format__ result was not a string");
}
return result;
}
static void module_sweep(KrkInstance * inst) {
#ifndef STATIC_ONLY
struct KrkModule * module = (struct KrkModule*)inst;
@ -1118,6 +1149,7 @@ void _createAndBind_builtins(void) {
BIND_METHOD(object,__str__);
BIND_METHOD(object,__hash__);
BIND_METHOD(object,__eq__);
BIND_METHOD(object,__format__);
BIND_METHOD(object,__setattr__)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
krk_defineNative(&object->methods, "__repr__", FUNC_NAME(object,__str__));
krk_finalizeClass(object);
@ -1369,5 +1401,8 @@ void _createAndBind_builtins(void) {
BUILTIN_FUNCTION("abs", FUNC_NAME(krk,abs),
"@brief Obtain the absolute value of a numeric.\n"
"@arguments iterable");
BUILTIN_FUNCTION("format", FUNC_NAME(krk,format),
"@brief Format a value for string printing.\n"
"@arguments value[,format_spec]");
}

View File

@ -1,4 +1,4 @@
['__class__', '__dir__', '__eq__', '__hash__', '__repr__', '__setattr__', '__str__', 'longList', 'ofAttributes', 'onThatObject', 'thatWeWantToSet']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__', 'longList', 'ofAttributes', 'onThatObject', 'thatWeWantToSet']
1
2
3

View File

@ -7,10 +7,10 @@ False
[1, 3, 4, 5]
[1, 3, 4]
list index out of range: 3
['__class__', '__dir__', '__eq__', '__hash__', '__repr__', '__setattr__', '__str__', 'baz', 'qux']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__', 'baz', 'qux']
42
['__class__', '__dir__', '__eq__', '__hash__', '__repr__', '__setattr__', '__str__', 'qux']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__', 'qux']
hi
'object' object has no attribute 'baz'
['__class__', '__dir__', '__eq__', '__hash__', '__repr__', '__setattr__', '__str__']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__']
'object' object has no attribute 'bar'

View File

@ -1,3 +1,3 @@
['__class__', '__dir__', '__eq__', '__func__', '__getattr__', '__hash__', '__init__', '__module__', '__qualname__', '__repr__', '__setattr__', '__str__', '_dict']
['__class__', '__dir__', '__eq__', '__format__', '__func__', '__getattr__', '__hash__', '__init__', '__module__', '__qualname__', '__repr__', '__setattr__', '__str__', '_dict']
1
['__class__', '__dir__', '__eq__', '__func__', '__hash__', '__module__', '__qualname__', '__repr__', '__setattr__', '__str__', 'butts']
['__class__', '__dir__', '__eq__', '__format__', '__func__', '__hash__', '__module__', '__qualname__', '__repr__', '__setattr__', '__str__', 'butts']

View File

@ -1,6 +1,6 @@
True
True
['__class__', '__dir__', '__doc__', '__eq__', '__get__', '__hash__', '__init__', '__module__', '__name__', '__repr__', '__set__', '__setattr__', '__str__', 'fget', 'setter']
['__class__', '__dir__', '__doc__', '__eq__', '__format__', '__get__', '__hash__', '__init__', '__module__', '__name__', '__repr__', '__set__', '__setattr__', '__str__', 'fget', 'setter']
p retrieved from A
{'a': 45}
calling property from subclass