Use a custom formatter for krk_runtimeError
This commit is contained in:
parent
b9c8e36414
commit
26a31b713e
@ -49,7 +49,7 @@ static KrkValue myfunction(int argc, KrkValue argv[], int hasKw) {
|
||||
int myarg;
|
||||
|
||||
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "myfunction() expects exactly 1 argument, %d given", argc);
|
||||
if (!IS_INTEGER(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected int, not '%s'", krk_typeName(argv[0]));
|
||||
if (!IS_INTEGER(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected int, not '%T'", argv[0]);
|
||||
|
||||
myarg = AS_INTEGER(argv[0]);
|
||||
|
||||
|
@ -175,7 +175,7 @@ KRK_Method(object,__format__) {
|
||||
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]));
|
||||
if (!type->_tostr) return krk_runtimeError(vm.exceptions->typeError, "'%T' can not be converted to str", argv[0]);
|
||||
krk_push(argv[0]);
|
||||
return krk_callDirect(type->_tostr, 1);
|
||||
}
|
||||
@ -190,7 +190,7 @@ KRK_Function(len) {
|
||||
if (IS_TUPLE(argv[0])) return INTEGER_VAL(AS_TUPLE(argv[0])->values.count);
|
||||
|
||||
KrkClass * type = krk_getType(argv[0]);
|
||||
if (!type->_len) return krk_runtimeError(vm.exceptions->typeError, "object of type '%s' has no len()", krk_typeName(argv[0]));
|
||||
if (!type->_len) return krk_runtimeError(vm.exceptions->typeError, "object of type '%T' has no len()", argv[0]);
|
||||
krk_push(argv[0]);
|
||||
|
||||
return krk_callDirect(type->_len, 1);
|
||||
@ -311,7 +311,7 @@ int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, c
|
||||
} else {
|
||||
KrkClass * type = krk_getType(iterable);
|
||||
if (unlikely(!type->_iter)) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%s' object is not iterable", krk_typeName(iterable));
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", iterable);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -413,7 +413,7 @@ KRK_Method(map,__init__) {
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
KrkClass * type = krk_getType(argv[i]);
|
||||
if (!type->_iter) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%s' object is not iterable", krk_typeName(argv[i]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[i]);
|
||||
}
|
||||
krk_push(argv[i]);
|
||||
KrkValue asIter = krk_callDirect(type->_iter, 1);
|
||||
@ -477,7 +477,7 @@ KRK_Method(zip,__init__) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
KrkClass * type = krk_getType(argv[i]);
|
||||
if (!type->_iter) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%s' object is not iterable", krk_typeName(argv[i]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[i]);
|
||||
}
|
||||
krk_push(argv[i]);
|
||||
KrkValue asIter = krk_callDirect(type->_iter, 1);
|
||||
@ -527,7 +527,7 @@ KRK_Method(filter,__init__) {
|
||||
krk_attachNamedValue(&self->fields, "_function", argv[1]);
|
||||
KrkClass * type = krk_getType(argv[2]);
|
||||
if (!type->_iter) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%s' object is not iterable", krk_typeName(argv[2]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[2]);
|
||||
}
|
||||
krk_push(argv[2]);
|
||||
KrkValue asIter = krk_callDirect(type->_iter, 1);
|
||||
@ -593,7 +593,7 @@ KRK_Method(enumerate,__init__) {
|
||||
/* Attach iterator */
|
||||
KrkClass * type = krk_getType(argv[1]);
|
||||
if (!type->_iter) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%s' object is not iterable", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[1]);
|
||||
}
|
||||
krk_push(argv[1]);
|
||||
KrkValue asIter = krk_callDirect(type->_iter, 1);
|
||||
@ -724,12 +724,12 @@ KRK_Function(print) {
|
||||
char * end = "\n"; size_t endLen = 1;
|
||||
if (hasKw) {
|
||||
if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("sep")), &sepVal)) {
|
||||
if (!IS_STRING(sepVal)) return krk_runtimeError(vm.exceptions->typeError, "'%s' should be a string, not '%s'", "sep", krk_typeName(sepVal));
|
||||
if (!IS_STRING(sepVal)) return krk_runtimeError(vm.exceptions->typeError, "'%s' should be a string, not '%T'", "sep", sepVal);
|
||||
sep = AS_CSTRING(sepVal);
|
||||
sepLen = AS_STRING(sepVal)->length;
|
||||
}
|
||||
if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("end")), &endVal)) {
|
||||
if (!IS_STRING(endVal)) return krk_runtimeError(vm.exceptions->typeError, "'%s' should be a string, not '%s'", "end", krk_typeName(endVal));
|
||||
if (!IS_STRING(endVal)) return krk_runtimeError(vm.exceptions->typeError, "'%s' should be a string, not '%T'", "end", endVal);
|
||||
end = AS_CSTRING(endVal);
|
||||
endLen = AS_STRING(endVal)->length;
|
||||
}
|
||||
@ -1037,7 +1037,7 @@ KRK_Method(property,__get__) {
|
||||
|
||||
KrkValue fget;
|
||||
if (!krk_tableGet(&self->fields, OBJECT_VAL(S("fget")), &fget))
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", "property", "fget");
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", argv[0], "fget");
|
||||
|
||||
krk_push(fget);
|
||||
krk_push(argv[1]);
|
||||
@ -1068,7 +1068,7 @@ KRK_Method(property,__set__) {
|
||||
|
||||
KRK_Function(id) {
|
||||
FUNCTION_TAKES_EXACTLY(1);
|
||||
if (!IS_OBJECT(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "'%s' has no identity", krk_typeName(argv[0]));
|
||||
if (!IS_OBJECT(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "'%T' has no identity", argv[0]);
|
||||
return INTEGER_VAL((size_t)AS_OBJECT(argv[0]));
|
||||
}
|
||||
|
||||
@ -1095,8 +1095,7 @@ KRK_Function(abs) {
|
||||
return FLOATING_VAL(i >= 0 ? i : -i);
|
||||
} else {
|
||||
trySlowMethod(OBJECT_VAL(S("__abs__")));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for 'abs()': '%s'",
|
||||
krk_typeName(argv[0]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for 'abs()': '%T'", argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1107,7 +1106,7 @@ KRK_Function(format) {
|
||||
KrkClass * type = krk_getType(argv[0]);
|
||||
|
||||
if (!type->_format) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%s' has no __format__ method", krk_typeName(argv[0]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "'%T' has no __format__ method", argv[0]);
|
||||
}
|
||||
|
||||
krk_push(argv[0]);
|
||||
|
@ -603,7 +603,7 @@ KRK_Function(dis) {
|
||||
krk_disassembleCodeObject(stdout, func, tmp);
|
||||
free(tmp);
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Can not disassemble built-in method of '%s'", krk_typeName(AS_BOUND_METHOD(argv[0])->receiver));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Can not disassemble built-in method of '%T'", AS_BOUND_METHOD(argv[0])->receiver);
|
||||
}
|
||||
} else if (IS_CLASS(argv[0])) {
|
||||
KrkValue code;
|
||||
@ -613,7 +613,7 @@ KRK_Function(dis) {
|
||||
}
|
||||
/* TODO Methods! */
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Don't know how to disassemble '%s'", krk_typeName(argv[0]));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Don't know how to disassemble '%T'", argv[0]);
|
||||
}
|
||||
|
||||
return NONE_VAL();
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
#define ADD_BASE_CLASS(obj, name, baseClass) krk_makeClass(vm.builtins, &obj, name, baseClass)
|
||||
|
||||
#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", \
|
||||
krk_typeName(argv[0]), _method_name); } while (0)
|
||||
#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", \
|
||||
argv[0], _method_name); } while (0)
|
||||
|
||||
#define METHOD_TAKES_NONE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \
|
||||
_method_name, (argc-1)); } while (0)
|
||||
@ -52,8 +52,8 @@
|
||||
#define FUNCTION_TAKES_AT_MOST(n) do { if (unlikely(argc > n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
|
||||
_method_name, "at most", n, (n != 1) ? "s" : "", (argc)); } while (0)
|
||||
|
||||
#define TYPE_ERROR(expected,value) krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'", \
|
||||
/* Function name */ _method_name, /* expected type */ #expected, krk_typeName(value))
|
||||
#define TYPE_ERROR(expected,value) krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%T'", \
|
||||
/* Function name */ _method_name, /* expected type */ #expected, value)
|
||||
|
||||
#define NOT_ENOUGH_ARGS(name) krk_runtimeError(vm.exceptions->argumentError, "Expected more args.")
|
||||
|
||||
|
@ -472,12 +472,25 @@ extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj *
|
||||
* The created exception object is attached to the current thread state and
|
||||
* the @c KRK_THREAD_HAS_EXCEPTION flag is set.
|
||||
*
|
||||
* If the format string is exactly "%V", the first format argument will
|
||||
* be attached the exception as the 'msg' attribute.
|
||||
*
|
||||
* No field width or precisions are supported on any conversion specifiers.
|
||||
*
|
||||
* Standard conversion specifiers 'c', 's', 'd', 'u' are available, and the
|
||||
* 'd' and 'u' specifiers may have length modifiers of l, L, or z.
|
||||
*
|
||||
* Additional format specifiers are as follows:
|
||||
*
|
||||
* %S - Accepts one KrkString* to be printed in its entirety.
|
||||
* %R - Accepts one KrkValue and calls repr on it.
|
||||
* %T - Accepts one KrkValue and emits the name of its type.
|
||||
*
|
||||
* @param type Class pointer for the exception type, eg. @c vm.exceptions->valueError
|
||||
* @param fmt Format string.
|
||||
* @return As a convenience to C extension authors, returns @c None
|
||||
*/
|
||||
extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the current thread state.
|
||||
@ -749,6 +762,9 @@ extern int krk_isFalsey(KrkValue value);
|
||||
* This is a convenience function that works in essentially the
|
||||
* same way as the OP_GET_PROPERTY instruction.
|
||||
*
|
||||
* @warning As this function takes a C string, it will not work with
|
||||
* @warning attribute names that have nil bytes.
|
||||
*
|
||||
* @param value Value to examine.
|
||||
* @param name C-string of the property name to query.
|
||||
* @return The requested property, or None with an @ref AttributeError
|
||||
@ -769,6 +785,9 @@ extern KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkVa
|
||||
* This is a convenience function that works in essentially the
|
||||
* same way as the OP_SET_PROPERTY instruction.
|
||||
*
|
||||
* @warning As this function takes a C string, it will not work with
|
||||
* @warning attribute names that have nil bytes.
|
||||
*
|
||||
* @param owner The owner of the property to modify.
|
||||
* @param name C-string of the property name to modify.
|
||||
* @param to The value to assign.
|
||||
@ -785,6 +804,9 @@ extern KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to);
|
||||
* This is a convenience function that works in essentially the
|
||||
* same way as the OP_DEL_PROPERTY instruction.
|
||||
*
|
||||
* @warning As this function takes a C string, it will not work with
|
||||
* @warning attribute names that have nil bytes.
|
||||
*
|
||||
* @param owner The owner of the property to delete.
|
||||
* @param name C-string of the property name to delete.
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@
|
||||
} }
|
||||
|
||||
#define REAL_NUMBER_NOT(name, garbage) { \
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() argument must be real number, not %s", #name, krk_typeName(garbage)); \
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() argument must be real number, not '%T'", #name, garbage); \
|
||||
return NONE_VAL(); \
|
||||
}
|
||||
|
||||
|
@ -113,20 +113,20 @@ static int socket_parse_address(struct socket * self, KrkValue address, struct s
|
||||
if (self->family == AF_INET) {
|
||||
/* Should be 2-tuple */
|
||||
if (!IS_tuple(address)) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Expected 2-tuple, not '%s'", krk_typeName(address));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Expected 2-tuple, not '%T'", address);
|
||||
return 1;
|
||||
}
|
||||
KrkTuple * addr = AS_TUPLE(address);
|
||||
if (addr->values.count != 2) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Expected 2-tuple, not '%s'", krk_typeName(address));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Expected 2-tuple, not '%T'", address);
|
||||
return 1;
|
||||
}
|
||||
if (!IS_str(addr->values.values[0])) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Address should be int, not '%s'", krk_typeName(addr->values.values[0]));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Address should be int, not '%T'", addr->values.values[0]);
|
||||
return 1;
|
||||
}
|
||||
if (!IS_int(addr->values.values[1])) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Port should be int, not '%s'", krk_typeName(addr->values.values[1]));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Port should be int, not '%T'", addr->values.values[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@ KRK_Method(bytes,__init__) {
|
||||
krk_push(OBJECT_VAL(out));
|
||||
for (size_t i = 0; i < AS_TUPLE(argv[1])->values.count; ++i) {
|
||||
if (!IS_INTEGER(AS_TUPLE(argv[1])->values.values[i])) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'",
|
||||
"bytes", "tuple of ints", krk_typeName(AS_TUPLE(argv[1])->values.values[i]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%T'",
|
||||
"bytes", "tuple of ints", AS_TUPLE(argv[1])->values.values[i]);
|
||||
}
|
||||
out->bytes[i] = AS_INTEGER(AS_TUPLE(argv[1])->values.values[i]);
|
||||
}
|
||||
@ -38,8 +38,8 @@ KRK_Method(bytes,__init__) {
|
||||
krk_push(OBJECT_VAL(out));
|
||||
for (size_t i = 0; i < AS_LIST(argv[1])->count; ++i) {
|
||||
if (!IS_INTEGER(AS_LIST(argv[1])->values[i])) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'",
|
||||
"bytes", "list of ints", krk_typeName(AS_LIST(argv[1])->values[i]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%T'",
|
||||
"bytes", "list of ints", AS_LIST(argv[1])->values[i]);
|
||||
}
|
||||
out->bytes[i] = AS_INTEGER(AS_LIST(argv[1])->values[i]);
|
||||
}
|
||||
@ -50,7 +50,7 @@ KRK_Method(bytes,__init__) {
|
||||
AS_BYTES(AS_bytearray(argv[1])->actual)->bytes));
|
||||
}
|
||||
|
||||
return krk_runtimeError(vm.exceptions->typeError, "Can not convert '%s' to bytes", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "Can not convert '%T' to bytes", argv[1]);
|
||||
}
|
||||
|
||||
#undef IS_bytes
|
||||
@ -198,8 +198,8 @@ static int _bytes_join_callback(void * context, const KrkValue * values, size_t
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (!IS_BYTES(values[i])) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'",
|
||||
"join", "bytes", krk_typeName(values[i]));
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%T'",
|
||||
"join", "bytes", values[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,6 @@
|
||||
#include <kuroko/memory.h>
|
||||
#include <kuroko/util.h>
|
||||
|
||||
#define KEY_ERROR(value) {\
|
||||
KrkClass * type = krk_getType(value); \
|
||||
krk_push(value); \
|
||||
KrkValue asString = krk_callDirect(type->_reprer, 1); \
|
||||
if (IS_STRING(asString)) return krk_runtimeError(vm.exceptions->keyError, "%s", AS_CSTRING(asString)); \
|
||||
return krk_runtimeError(vm.exceptions->keyError, "key error"); }
|
||||
|
||||
/**
|
||||
* Exposed method called to produce dictionaries from `{expr: expr, ...}` sequences in managed code.
|
||||
* Expects arguments as `key,value,key,value`...
|
||||
@ -131,7 +124,7 @@ KRK_Method(dict,__getitem__) {
|
||||
KrkValue out;
|
||||
if (!krk_tableGet(&self->entries, argv[1], &out)) {
|
||||
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
|
||||
KEY_ERROR(argv[1]);
|
||||
return krk_runtimeError(vm.exceptions->keyError, "%V", argv[1]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -156,7 +149,7 @@ KRK_Method(dict,__delitem__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (!krk_tableDelete(&self->entries, argv[1])) {
|
||||
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
|
||||
KEY_ERROR(argv[1]);
|
||||
return krk_runtimeError(vm.exceptions->keyError, "%V", argv[1]);
|
||||
}
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
@ -253,11 +253,11 @@ int krk_getAwaitable(void) {
|
||||
krk_push(krk_callStack(0));
|
||||
KrkClass * _type = krk_getType(krk_peek(0));
|
||||
if (!_type || !_type->_iter) {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "__await__ returned non-iterator of type '%s'", krk_typeName(krk_peek(0)));
|
||||
krk_runtimeError(vm.exceptions->attributeError, "__await__ returned non-iterator of type '%T'", krk_peek(0));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object is not awaitable", krk_typeName(krk_peek(0)));
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%T' object is not awaitable", krk_peek(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -365,14 +365,14 @@ KRK_Method(list,index) {
|
||||
if (IS_INTEGER(argv[2]))
|
||||
min = AS_INTEGER(argv[2]);
|
||||
else
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s must be int, not '%s'", "min", krk_typeName(argv[2]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s must be int, not '%T'", "min", argv[2]);
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
if (IS_INTEGER(argv[3]))
|
||||
max = AS_INTEGER(argv[3]);
|
||||
else
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s must be int, not '%s'", "max", krk_typeName(argv[3]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s must be int, not '%T'", "max", argv[3]);
|
||||
}
|
||||
|
||||
pthread_rwlock_rdlock(&self->rwlock);
|
||||
|
@ -1190,15 +1190,12 @@ KRK_Method(long,__init__) {
|
||||
} else if (IS_STRING(argv[1])) {
|
||||
/* XXX This should probably work like int(...) does and default to base 10... and take a base at all... */
|
||||
if (krk_long_parse_string(AS_CSTRING(argv[1]),self->value,0,AS_STRING(argv[1])->length)) {
|
||||
krk_push(argv[1]);
|
||||
KrkValue repred = krk_callDirect(vm.baseClasses->strClass->_reprer, 1);
|
||||
return krk_runtimeError(vm.exceptions->valueError, "invalid literal for long() with base " PRIkrk_int "%s%s",
|
||||
(krk_integer_type)0, IS_STRING(repred) ? ": " : "", IS_STRING(repred) ? AS_CSTRING(repred) : "");
|
||||
return krk_runtimeError(vm.exceptions->valueError, "invalid literal for long() with base 0: %R", argv[1]);
|
||||
}
|
||||
} else if (IS_long(argv[1])) {
|
||||
krk_long_init_copy(self->value,AS_long(argv[1])->value);
|
||||
} else {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%s'", "int", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%T'", "int", argv[1]);
|
||||
}
|
||||
/* our value should be set */
|
||||
return argv[0];
|
||||
|
@ -28,16 +28,14 @@ FUNC_SIG(int,__init__) {
|
||||
}
|
||||
KrkValue result = krk_parse_int(AS_CSTRING(argv[1]), AS_STRING(argv[1])->length, _base);
|
||||
if (IS_NONE(result)) {
|
||||
krk_push(argv[1]);
|
||||
KrkValue repred = krk_callDirect(vm.baseClasses->strClass->_reprer, 1);
|
||||
return krk_runtimeError(vm.exceptions->valueError, "invalid literal for int() with base " PRIkrk_int "%s%s",
|
||||
_base, IS_STRING(repred) ? ": " : "", IS_STRING(repred) ? AS_CSTRING(repred) : "");
|
||||
return krk_runtimeError(vm.exceptions->valueError,
|
||||
"invalid literal for int() with base %zd: %R", (ssize_t)_base, argv[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (IS_FLOATING(argv[1])) return INTEGER_VAL(AS_FLOATING(argv[1]));
|
||||
if (IS_BOOLEAN(argv[1])) return INTEGER_VAL(AS_BOOLEAN(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%s'", "int", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%T'", "int", argv[1]);
|
||||
}
|
||||
|
||||
KRK_Method(int,__str__) {
|
||||
@ -573,7 +571,7 @@ FUNC_SIG(float,__init__) {
|
||||
|
||||
trySlowMethod(vm.specialMethodNames[METHOD_FLOAT]);
|
||||
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%s'", "float", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%T'", "float", argv[1]);
|
||||
}
|
||||
|
||||
KRK_Method(float,__int__) { return INTEGER_VAL(self); }
|
||||
|
@ -108,7 +108,7 @@ KRK_Method(set,__and__) {
|
||||
|
||||
KrkClass * type = krk_getType(argv[1]);
|
||||
if (!type->_contains)
|
||||
return krk_runtimeError(vm.exceptions->typeError, "unsupported operand types for %s: '%s' and '%s'", "&", "set", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "unsupported operand types for %s: '%T' and '%T'", "&", argv[0], argv[1]);
|
||||
|
||||
for (size_t i = 0; i < self->entries.capacity; ++i) {
|
||||
KrkTableEntry * entry = &self->entries.entries[i];
|
||||
@ -136,7 +136,7 @@ KRK_Method(set,__xor__) {
|
||||
|
||||
KrkClass * type = krk_getType(argv[1]);
|
||||
if (!type->_contains)
|
||||
return krk_runtimeError(vm.exceptions->typeError, "unsupported operand types for %s: '%s' and '%s'", "&", "set", krk_typeName(argv[1]));
|
||||
return krk_runtimeError(vm.exceptions->typeError, "unsupported operand types for %s: '%T' and '%T'", "&", argv[0], argv[1]);
|
||||
|
||||
for (size_t i = 0; i < self->entries.capacity; ++i) {
|
||||
KrkTableEntry * entry = &self->entries.entries[i];
|
||||
|
@ -41,7 +41,7 @@ KRK_Method(str,__init__) {
|
||||
if (IS_STRING(argv[1])) return argv[1]; /* strings are immutable, so we can just return the arg */
|
||||
/* Find the type of arg */
|
||||
krk_push(argv[1]);
|
||||
if (!krk_getType(argv[1])->_tostr) return krk_runtimeError(vm.exceptions->typeError, "Can not convert %s to str", krk_typeName(argv[1]));
|
||||
if (!krk_getType(argv[1])->_tostr) return krk_runtimeError(vm.exceptions->typeError, "Can not convert '%T' to str", argv[1]);
|
||||
return krk_callDirect(krk_getType(argv[1])->_tostr, 1);
|
||||
}
|
||||
|
||||
@ -423,8 +423,8 @@ static int _str_join_callback(void * context, const KrkValue * values, size_t co
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (!IS_STRING(values[i])) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'",
|
||||
"join", "str", krk_typeName(values[i]));
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%T'",
|
||||
"join", "str", values[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -596,8 +596,7 @@ KRK_Method(str,__mod__) {
|
||||
} else if (IS_FLOATING(arg)) {
|
||||
krk_push(INTEGER_VAL(AS_FLOATING(arg)));
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%%i format: a number is required, not %s",
|
||||
krk_typeName(arg));
|
||||
krk_runtimeError(vm.exceptions->typeError, "%%i format: a number is required, not '%T'", arg);
|
||||
goto _exception;
|
||||
}
|
||||
krk_push(krk_callDirect(krk_getType(arg)->_tostr, 1));
|
||||
@ -606,8 +605,7 @@ KRK_Method(str,__mod__) {
|
||||
if (ti >= myTuple->values.count) goto _notEnough;
|
||||
KrkValue arg = myTuple->values.values[ti++];
|
||||
if (!krk_getType(arg)->_tostr) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%%s format: cannot convert %s to string",
|
||||
krk_typeName(arg));
|
||||
krk_runtimeError(vm.exceptions->typeError, "%%s format: cannot convert '%T' to string", arg);
|
||||
goto _exception;
|
||||
}
|
||||
|
||||
|
@ -177,8 +177,7 @@ KRK_Method(tuple,__add__) {
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
if (!IS_tuple(argv[1]))
|
||||
return krk_runtimeError(vm.exceptions->typeError,
|
||||
"can only concatenate tuple (not \"%s\") to tuple",
|
||||
krk_typeName(argv[1]));
|
||||
"can only concatenate tuple (not '%T') to tuple", argv[1]);
|
||||
|
||||
KrkTuple * other = AS_tuple(argv[1]);
|
||||
KrkTuple * out = krk_newTuple(self->values.count + other->values.count);
|
||||
|
@ -55,7 +55,7 @@ inline int krk_hashValue(KrkValue value, uint32_t *hashOut) {
|
||||
}
|
||||
_unhashable:
|
||||
if (IS_NONE(krk_currentThread.currentException))
|
||||
krk_runtimeError(vm.exceptions->typeError, "unhashable type: '%s'", krk_typeName(value));
|
||||
krk_runtimeError(vm.exceptions->typeError, "unhashable type: '%T'", value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
242
src/vm.c
242
src/vm.c
@ -371,17 +371,132 @@ static void raiseException(KrkValue base, KrkValue cause) {
|
||||
* found in vm.exceptions and are initialized on startup.
|
||||
*/
|
||||
KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...) {
|
||||
char buf[1024] = {0};
|
||||
KrkValue msg = KWARGS_VAL(0);
|
||||
struct StringBuilder sb = {0};
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
size_t len = vsnprintf(buf, 1024, fmt, args);
|
||||
|
||||
if (!strcmp(fmt,"%V")) {
|
||||
msg = va_arg(args, KrkValue);
|
||||
goto _finish;
|
||||
}
|
||||
|
||||
for (const char * f = fmt; *f; ++f) {
|
||||
if (*f != '%') {
|
||||
pushStringBuilder(&sb, *f);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Unset exception flag if it was already set. */
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
|
||||
krk_currentThread.flags &= ~(KRK_THREAD_HAS_EXCEPTION);
|
||||
}
|
||||
|
||||
++f;
|
||||
|
||||
int size = ' ';
|
||||
|
||||
if (*f == 'z') size = *f++;
|
||||
else if (*f == 'l') size = *f++;
|
||||
else if (*f == 'L') size = *f++;
|
||||
|
||||
switch (*f) {
|
||||
case 0: break;
|
||||
case '%':
|
||||
pushStringBuilder(&sb, '%');
|
||||
break;
|
||||
|
||||
case 'c': {
|
||||
char val = (char)va_arg(args, int);
|
||||
pushStringBuilder(&sb, val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 's': {
|
||||
const char * c = va_arg(args, const char *);
|
||||
pushStringBuilderStr(&sb, c, strlen(c));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'u': {
|
||||
size_t val;
|
||||
if (size == ' ') {
|
||||
val = va_arg(args, unsigned int);
|
||||
} else if (size == 'l') {
|
||||
val = va_arg(args, unsigned long);
|
||||
} else if (size == 'L') {
|
||||
val = va_arg(args, unsigned long long);
|
||||
} else if (size == 'z') {
|
||||
val = va_arg(args, size_t);
|
||||
}
|
||||
char tmp[100];
|
||||
snprintf(tmp, 32, "%zu", val);
|
||||
pushStringBuilderStr(&sb, tmp, strlen(tmp));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'd': {
|
||||
ssize_t val;
|
||||
if (size == ' ') {
|
||||
val = va_arg(args, int);
|
||||
} else if (size == 'l') {
|
||||
val = va_arg(args, long);
|
||||
} else if (size == 'L') {
|
||||
val = va_arg(args, long long);
|
||||
} else if (size == 'z') {
|
||||
val = va_arg(args, ssize_t);
|
||||
}
|
||||
char tmp[100];
|
||||
snprintf(tmp, 32, "%zd", val);
|
||||
pushStringBuilderStr(&sb, tmp, strlen(tmp));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'T': {
|
||||
KrkValue val = va_arg(args, KrkValue);
|
||||
const char * typeName = krk_typeName(val);
|
||||
pushStringBuilderStr(&sb, typeName, strlen(typeName));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'S': {
|
||||
KrkString * val = va_arg(args, KrkString*);
|
||||
pushStringBuilderStr(&sb, val->chars, val->length);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'R': {
|
||||
KrkValue val = va_arg(args, KrkValue);
|
||||
KrkClass * type = krk_getType(val);
|
||||
if (likely(type->_reprer != NULL)) {
|
||||
krk_push(val);
|
||||
KrkValue res = krk_callDirect(type->_reprer, 1);
|
||||
if (IS_STRING(res)) {
|
||||
pushStringBuilderStr(&sb, AS_CSTRING(res), AS_STRING(res)->length);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
va_arg(args, void*);
|
||||
pushStringBuilderStr(&sb, "(unsupported: ", 14);
|
||||
pushStringBuilder(&sb, *f);
|
||||
pushStringBuilder(&sb, ')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_finish:
|
||||
va_end(args);
|
||||
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
|
||||
|
||||
/* Allocate an exception object of the requested type. */
|
||||
KrkInstance * exceptionObject = krk_newInstance(type);
|
||||
krk_push(OBJECT_VAL(exceptionObject));
|
||||
krk_attachNamedValue(&exceptionObject->fields, "arg", OBJECT_VAL(krk_copyString(buf, len)));
|
||||
krk_attachNamedValue(&exceptionObject->fields, "arg", msg == KWARGS_VAL(0) ? finishStringBuilder(&sb) : msg);
|
||||
krk_attachNamedValue(&exceptionObject->fields, "__cause__", NONE_VAL());
|
||||
krk_attachNamedValue(&exceptionObject->fields, "__context__", NONE_VAL());
|
||||
krk_pop();
|
||||
@ -658,11 +773,11 @@ static inline int checkArgumentCount(const KrkClosure * closure, int argCount) {
|
||||
}
|
||||
|
||||
static void multipleDefs(const KrkClosure * closure, int destination) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%s'",
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%S'",
|
||||
closure->function->name ? closure->function->name->chars : "<unnamed>",
|
||||
(destination < closure->function->requiredArgs ? AS_CSTRING(closure->function->requiredArgNames.values[destination]) :
|
||||
(destination - closure->function->requiredArgs < closure->function->keywordArgs ? AS_CSTRING(closure->function->keywordArgNames.values[destination - closure->function->requiredArgs]) :
|
||||
"<unnamed>")));
|
||||
(destination < closure->function->requiredArgs ? AS_STRING(closure->function->requiredArgNames.values[destination]) :
|
||||
(destination - closure->function->requiredArgs < closure->function->keywordArgs ? AS_STRING(closure->function->keywordArgNames.values[destination - closure->function->requiredArgs]) :
|
||||
S("<unnamed>"))));
|
||||
}
|
||||
|
||||
static int _unpack_op(void * context, const KrkValue * values, size_t count) {
|
||||
@ -725,7 +840,7 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa
|
||||
return 0;
|
||||
}
|
||||
if (!krk_tableSet(keywords, entry->key, entry->value)) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%s'", name, AS_CSTRING(entry->key));
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%S'", name, AS_STRING(entry->key));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -735,7 +850,7 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa
|
||||
}
|
||||
} else if (IS_STRING(key)) {
|
||||
if (!krk_tableSet(keywords, key, value)) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%s'", name, AS_CSTRING(key));
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%S'", name, AS_STRING(key));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -855,9 +970,9 @@ static inline int _callManaged(KrkClosure * closure, int argCount, int returnDep
|
||||
}
|
||||
}
|
||||
if (!(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS)) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got an unexpected keyword argument '%s'",
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() got an unexpected keyword argument '%S'",
|
||||
closure->function->name ? closure->function->name->chars : "<unnamed>",
|
||||
AS_CSTRING(name));
|
||||
AS_STRING(name));
|
||||
goto _errorAfterPositionals;
|
||||
}
|
||||
continue;
|
||||
@ -880,9 +995,9 @@ _finishKwarg:
|
||||
|
||||
for (size_t i = 0; i < (size_t)closure->function->requiredArgs; ++i) {
|
||||
if (IS_KWARGS(krk_currentThread.stackTop[-argCount + i])) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() missing required positional argument: '%s'",
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() missing required positional argument: '%S'",
|
||||
closure->function->name ? closure->function->name->chars : "<unnamed>",
|
||||
AS_CSTRING(closure->function->requiredArgNames.values[i]));
|
||||
AS_STRING(closure->function->requiredArgNames.values[i]));
|
||||
goto _errorAfterKeywords;
|
||||
}
|
||||
}
|
||||
@ -1041,7 +1156,7 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) {
|
||||
returnDepth = returnDepth ? (returnDepth - 1) : 0;
|
||||
return (_class->_call->type == KRK_OBJ_CLOSURE) ? _callManaged((KrkClosure*)_class->_call, argCount, returnDepth) : _callNative((KrkNative*)_class->_call, argCount, returnDepth);
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%s' object is not callable", krk_typeName(callee));
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%T' object is not callable", callee);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1056,8 +1171,8 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) {
|
||||
returnDepth = returnDepth ? (returnDepth - 1) : 0;
|
||||
goto _innerObject;
|
||||
} else if (unlikely(argCount != 0)) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "%s() takes no arguments (%d given)",
|
||||
_class->name->chars, argCount);
|
||||
krk_runtimeError(vm.exceptions->typeError, "%S() takes no arguments (%d given)",
|
||||
_class->name, argCount);
|
||||
return 0;
|
||||
}
|
||||
krk_currentThread.stackTop -= argCount + returnDepth;
|
||||
@ -1081,7 +1196,7 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%s' object is not callable", krk_typeName(callee));
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%T' object is not callable", callee);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1676,8 +1791,8 @@ const char * krk_typeName(KrkValue value) {
|
||||
} \
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL(); \
|
||||
return krk_runtimeError(vm.exceptions->typeError, \
|
||||
"unsupported operand types for %s: '%s' and '%s'", \
|
||||
operator, krk_typeName(a), krk_typeName(b)); \
|
||||
"unsupported operand types for %s: '%T' and '%T'", \
|
||||
operator, a, b); \
|
||||
}
|
||||
#define MAKE_BIN_OP(name,operator,inv) \
|
||||
MAKE_COMPARE_OP(name,operator,inv) \
|
||||
@ -1729,7 +1844,7 @@ KrkValue krk_operator_is(KrkValue a, KrkValue b) {
|
||||
return krk_callDirect(type-> sname, 1); \
|
||||
} \
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL(); \
|
||||
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for unary %s: '%s'", #op, krk_typeName(value)); \
|
||||
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for unary %s: '%T'", #op, value); \
|
||||
}
|
||||
|
||||
MAKE_UNARY_OP(_invert,invert,~)
|
||||
@ -1871,8 +1986,8 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr
|
||||
/* Try to import that. */
|
||||
KrkValue dotted_main = krk_peek(0);
|
||||
if (!krk_importModule(AS_STRING(dotted_main),runAs)) {
|
||||
krk_runtimeError(vm.exceptions->importError, "No module named %s; '%s' is a package and cannot be executed directly",
|
||||
AS_CSTRING(dotted_main), AS_CSTRING(packageName));
|
||||
krk_runtimeError(vm.exceptions->importError, "No module named '%S'; '%S' is a package and cannot be executed directly",
|
||||
AS_STRING(dotted_main), AS_STRING(packageName));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1955,7 +2070,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr
|
||||
if (!dlRef) {
|
||||
*moduleOut = NONE_VAL();
|
||||
krk_runtimeError(vm.exceptions->importError,
|
||||
"Failed to load native module '%s' from shared object '%s'", runAs->chars, fileName);
|
||||
"Failed to load native module '%S' from shared object '%s'", runAs, fileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1989,7 +2104,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr
|
||||
if (!krk_isInstanceOf(*moduleOut, vm.baseClasses->moduleClass)) {
|
||||
dlClose(dlRef);
|
||||
krk_runtimeError(vm.exceptions->importError,
|
||||
"Failed to load module '%s' from '%s'", runAs->chars, fileName);
|
||||
"Failed to load module '%S' from '%s'", runAs, fileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2024,7 +2139,7 @@ int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs, Kr
|
||||
krk_push(OBJECT_VAL(runAs));
|
||||
}
|
||||
|
||||
krk_runtimeError(vm.exceptions->importError, "No module named '%s'", AS_CSTRING(krk_peek(0)));
|
||||
krk_runtimeError(vm.exceptions->importError, "No module named '%S'", AS_STRING(krk_peek(0)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2205,7 +2320,7 @@ int krk_importModule(KrkString * name, KrkString * runAs) {
|
||||
/* Is this a package? */
|
||||
KrkValue tmp;
|
||||
if (!krk_tableGet_fast(&AS_INSTANCE(current)->fields, S("__ispackage__"), &tmp) || !IS_BOOLEAN(tmp) || AS_BOOLEAN(tmp) != 1) {
|
||||
krk_runtimeError(vm.exceptions->importError, "'%s' is not a package", AS_CSTRING(krk_currentThread.stack[argBase+2]));
|
||||
krk_runtimeError(vm.exceptions->importError, "'%S' is not a package", AS_STRING(krk_currentThread.stack[argBase+2]));
|
||||
return 0;
|
||||
}
|
||||
krk_currentThread.stack[argBase-1] = krk_pop();
|
||||
@ -2336,15 +2451,17 @@ static int valueGetMethod(KrkString * name) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int krk_getAttribute(KrkString * name) {
|
||||
return valueGetProperty(name);
|
||||
}
|
||||
|
||||
KrkValue krk_valueGetAttribute(KrkValue value, char * name) {
|
||||
krk_push(OBJECT_VAL(krk_copyString(name,strlen(name))));
|
||||
krk_push(value);
|
||||
if (!valueGetProperty(AS_STRING(krk_peek(1)))) {
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(0)), name);
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(0), name);
|
||||
}
|
||||
krk_swap(1);
|
||||
krk_pop(); /* String */
|
||||
@ -2387,11 +2504,15 @@ static int valueDelProperty(KrkString * name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int krk_delAttribute(KrkString * name) {
|
||||
return valueDelProperty(name);
|
||||
}
|
||||
|
||||
KrkValue krk_valueDelAttribute(KrkValue owner, char * name) {
|
||||
krk_push(OBJECT_VAL(krk_copyString(name,strlen(name))));
|
||||
krk_push(owner);
|
||||
if (!valueDelProperty(AS_STRING(krk_peek(1)))) {
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(0)), name);
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(0), name);
|
||||
}
|
||||
krk_pop(); /* String */
|
||||
return NONE_VAL();
|
||||
@ -2486,12 +2607,16 @@ static int valueSetProperty(KrkString * name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int krk_setAttribute(KrkString * name) {
|
||||
return valueSetProperty(name);
|
||||
}
|
||||
|
||||
KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to) {
|
||||
krk_push(OBJECT_VAL(krk_copyString(name,strlen(name))));
|
||||
krk_push(owner);
|
||||
krk_push(to);
|
||||
if (!valueSetProperty(AS_STRING(krk_peek(2)))) {
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(1)), name);
|
||||
return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(1), name);
|
||||
}
|
||||
krk_swap(1);
|
||||
krk_pop(); /* String */
|
||||
@ -2564,7 +2689,7 @@ static inline int doFormatString(int options) {
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError,
|
||||
"Can not convert %s to str", krk_typeName(krk_peek(0)));
|
||||
"Can not convert '%T' to str", krk_peek(0));
|
||||
return 1;
|
||||
}
|
||||
} else if (options & FORMAT_OP_REPR) {
|
||||
@ -2574,7 +2699,7 @@ static inline int doFormatString(int options) {
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError,
|
||||
"Can not repr %s", krk_typeName(krk_peek(0)));
|
||||
"Can not repr '%T'", krk_peek(0));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -2594,7 +2719,7 @@ static inline int doFormatString(int options) {
|
||||
krk_push(krk_callDirect(type->_format, 2));
|
||||
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(1)), "__format__");
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", krk_peek(1), "__format__");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2612,7 +2737,7 @@ static inline void commonMethodInvoke(size_t methodOffset, int args, const char
|
||||
if (likely(method != NULL)) {
|
||||
krk_push(krk_callDirect(method, args));
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->attributeError, msgFormat, krk_typeName(krk_peek(args-1)));
|
||||
krk_runtimeError(vm.exceptions->attributeError, msgFormat, krk_peek(args-1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2790,25 +2915,25 @@ _finishReturn: (void)0;
|
||||
krk_pop();
|
||||
break;
|
||||
case OP_INVOKE_GETTER: {
|
||||
commonMethodInvoke(offsetof(KrkClass,_getter), 2, "'%s' object is not subscriptable");
|
||||
commonMethodInvoke(offsetof(KrkClass,_getter), 2, "'%T' object is not subscriptable");
|
||||
break;
|
||||
}
|
||||
case OP_INVOKE_SETTER: {
|
||||
commonMethodInvoke(offsetof(KrkClass,_setter), 3, "'%s' object doesn't support item assignment");
|
||||
commonMethodInvoke(offsetof(KrkClass,_setter), 3, "'%T' object doesn't support item assignment");
|
||||
break;
|
||||
}
|
||||
case OP_INVOKE_DELETE: {
|
||||
commonMethodInvoke(offsetof(KrkClass,_delitem), 2, "'%s' object doesn't support item deletion");
|
||||
commonMethodInvoke(offsetof(KrkClass,_delitem), 2, "'%T' object doesn't support item deletion");
|
||||
krk_pop(); /* unused result */
|
||||
break;
|
||||
}
|
||||
case OP_INVOKE_ITER: {
|
||||
commonMethodInvoke(offsetof(KrkClass,_iter), 1, "'%s' object is not iterable");
|
||||
commonMethodInvoke(offsetof(KrkClass,_iter), 1, "'%T' object is not iterable");
|
||||
break;
|
||||
}
|
||||
case OP_INVOKE_CONTAINS: {
|
||||
krk_swap(1); /* operands are backwards */
|
||||
commonMethodInvoke(offsetof(KrkClass,_contains), 2, "'%s' object can not be tested for membership");
|
||||
commonMethodInvoke(offsetof(KrkClass,_contains), 2, "'%T' object can not be tested for membership");
|
||||
break;
|
||||
}
|
||||
case OP_INVOKE_AWAIT: {
|
||||
@ -2826,13 +2951,12 @@ _finishReturn: (void)0;
|
||||
case OP_INHERIT: {
|
||||
KrkValue superclass = krk_peek(0);
|
||||
if (unlikely(!IS_CLASS(superclass))) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Superclass must be a class, not '%s'",
|
||||
krk_typeName(superclass));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Superclass must be a class, not '%T'", superclass);
|
||||
goto _finishException;
|
||||
}
|
||||
if (AS_OBJECT(superclass)->flags & KRK_OBJ_FLAGS_NO_INHERIT) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%s' can not be subclassed",
|
||||
AS_CLASS(superclass)->name->chars);
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%S' can not be subclassed",
|
||||
AS_CLASS(superclass)->name);
|
||||
goto _finishException;
|
||||
}
|
||||
KrkClass * subclass = AS_CLASS(krk_peek(1));
|
||||
@ -2932,7 +3056,7 @@ _finishReturn: (void)0;
|
||||
krk_swap(1);
|
||||
krk_pop();
|
||||
} else {
|
||||
krk_runtimeError(vm.exceptions->typeError, "Can not annotate '%s'.", krk_typeName(krk_peek(0)));
|
||||
krk_runtimeError(vm.exceptions->typeError, "Can not annotate '%T'.", krk_peek(0));
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
@ -3079,7 +3203,7 @@ _finishReturn: (void)0;
|
||||
KrkValue value;
|
||||
if (!krk_tableGet_fast(frame->globals, name, &value)) {
|
||||
if (!krk_tableGet_fast(&vm.builtins->fields, name, &value)) {
|
||||
krk_runtimeError(vm.exceptions->nameError, "Undefined variable '%s'.", name->chars);
|
||||
krk_runtimeError(vm.exceptions->nameError, "Undefined variable '%S'.", name);
|
||||
goto _finishException;
|
||||
}
|
||||
}
|
||||
@ -3092,7 +3216,7 @@ _finishReturn: (void)0;
|
||||
ONE_BYTE_OPERAND;
|
||||
KrkString * name = READ_STRING(OPERAND);
|
||||
if (!krk_tableSetIfExists(frame->globals, OBJECT_VAL(name), krk_peek(0))) {
|
||||
krk_runtimeError(vm.exceptions->nameError, "Undefined variable '%s'.", name->chars);
|
||||
krk_runtimeError(vm.exceptions->nameError, "Undefined variable '%S'.", name);
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
@ -3103,7 +3227,7 @@ _finishReturn: (void)0;
|
||||
ONE_BYTE_OPERAND;
|
||||
KrkString * name = READ_STRING(OPERAND);
|
||||
if (!krk_tableDelete(frame->globals, OBJECT_VAL(name))) {
|
||||
krk_runtimeError(vm.exceptions->nameError, "Undefined variable '%s'.", name->chars);
|
||||
krk_runtimeError(vm.exceptions->nameError, "Undefined variable '%S'.", name);
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
@ -3222,7 +3346,7 @@ _finishReturn: (void)0;
|
||||
/* Try to import... */
|
||||
KrkValue moduleName;
|
||||
if (!krk_tableGet(&AS_INSTANCE(krk_peek(0))->fields, vm.specialMethodNames[METHOD_NAME], &moduleName)) {
|
||||
krk_runtimeError(vm.exceptions->importError, "Can not import '%s' from non-module '%s' object", name->chars, krk_typeName(krk_peek(0)));
|
||||
krk_runtimeError(vm.exceptions->importError, "Can not import '%S' from non-module '%T' object", name, krk_peek(0));
|
||||
goto _finishException;
|
||||
}
|
||||
krk_push(moduleName);
|
||||
@ -3231,7 +3355,7 @@ _finishReturn: (void)0;
|
||||
krk_push(OBJECT_VAL(name));
|
||||
krk_addObjects();
|
||||
if (!krk_doRecursiveModuleLoad(AS_STRING(krk_peek(0)))) {
|
||||
krk_runtimeError(vm.exceptions->importError, "Can not import '%s' from '%s'", name->chars, AS_CSTRING(moduleName));
|
||||
krk_runtimeError(vm.exceptions->importError, "Can not import '%S' from '%S'", name, AS_STRING(moduleName));
|
||||
goto _finishException;
|
||||
}
|
||||
krk_currentThread.stackTop[-3] = krk_currentThread.stackTop[-1];
|
||||
@ -3244,7 +3368,7 @@ _finishReturn: (void)0;
|
||||
ONE_BYTE_OPERAND;
|
||||
KrkString * name = READ_STRING(OPERAND);
|
||||
if (unlikely(!valueGetProperty(name))) {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(0)), name->chars);
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(0), name);
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
@ -3255,7 +3379,7 @@ _finishReturn: (void)0;
|
||||
ONE_BYTE_OPERAND;
|
||||
KrkString * name = READ_STRING(OPERAND);
|
||||
if (unlikely(!valueDelProperty(name))) {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(0)), name->chars);
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(0), name);
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
@ -3266,7 +3390,7 @@ _finishReturn: (void)0;
|
||||
ONE_BYTE_OPERAND;
|
||||
KrkString * name = READ_STRING(OPERAND);
|
||||
if (unlikely(!valueSetProperty(name))) {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(1)), name->chars);
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(1), name);
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
@ -3293,7 +3417,7 @@ _finishReturn: (void)0;
|
||||
KrkValue baseClass = krk_peek(1);
|
||||
if (!IS_CLASS(baseClass)) {
|
||||
krk_runtimeError(vm.exceptions->typeError,
|
||||
"super() argument 1 must be class, not %s", krk_typeName(baseClass));
|
||||
"super() argument 1 must be class, not %T", baseClass);
|
||||
goto _finishException;
|
||||
}
|
||||
if (IS_KWARGS(krk_peek(0))) {
|
||||
@ -3303,14 +3427,14 @@ _finishReturn: (void)0;
|
||||
}
|
||||
if (!krk_isInstanceOf(krk_peek(0), AS_CLASS(baseClass))) {
|
||||
krk_runtimeError(vm.exceptions->typeError,
|
||||
"'%s' object is not an instance of '%s'",
|
||||
krk_typeName(krk_peek(0)), AS_CLASS(baseClass)->name->chars);
|
||||
"'%T' object is not an instance of '%S'",
|
||||
krk_peek(0), AS_CLASS(baseClass)->name);
|
||||
goto _finishException;
|
||||
}
|
||||
KrkClass * superclass = AS_CLASS(baseClass)->base ? AS_CLASS(baseClass)->base : vm.baseClasses->objectClass;
|
||||
if (!krk_bindMethod(superclass, name)) {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'",
|
||||
superclass->name->chars, name->chars);
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%S' object has no attribute '%S'",
|
||||
superclass->name, name);
|
||||
goto _finishException;
|
||||
}
|
||||
/* Swap bind and superclass */
|
||||
@ -3330,7 +3454,7 @@ _finishReturn: (void)0;
|
||||
krk_swap(2);
|
||||
krk_pop();
|
||||
} else if (unlikely(!result)) {
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", krk_typeName(krk_peek(0)), name->chars);
|
||||
krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", krk_peek(0), name);
|
||||
goto _finishException;
|
||||
} else {
|
||||
krk_swap(1); /* unbound-method object */
|
||||
@ -3493,7 +3617,7 @@ _finishReturn: (void)0;
|
||||
KrkValue s = krk_currentThread.stackTop[-(ssize_t)OPERAND+i];
|
||||
if (unlikely(!IS_STRING(s))) {
|
||||
discardStringBuilder(&sb);
|
||||
krk_runtimeError(vm.exceptions->valueError, "'%s' is not a string", krk_typeName(s));
|
||||
krk_runtimeError(vm.exceptions->valueError, "'%T' is not a string", s);
|
||||
goto _finishException;
|
||||
}
|
||||
pushStringBuilderStr(&sb, (char*)AS_STRING(s)->chars, AS_STRING(s)->length);
|
||||
|
Loading…
x
Reference in New Issue
Block a user