print() should __str__, not __repr__; repl should __repr__, not printValue...

printValue() probably shouldn't exist... and that's about it.
This commit is contained in:
K. Lange 2021-01-10 12:30:34 +09:00
parent 01176579f6
commit 98fea9bb64
7 changed files with 63 additions and 14 deletions

View File

@ -477,11 +477,24 @@ for i in l:
# 3
```
If an iterator returns tuples, the values can be unpacked into multiple variables:
```py
let l = [(1,2),(3,4),(5,6)]
for left, right in l:
print(left, right)
# → 1 2
# 3 4
# 5 6
```
An exception will be raised if a tuple returned by the iterator has the wrong size for unpacking, or if a value returned is not a tuple.
### Iterators
The special method `__iter__` should return an iterator. An iterator should be a function which increments an internal state and returns the next value. If there are no values remaining, return the iterator itself.
An example of an iterator is the `range` built-in class, which is defined like this:
An example of an iterator is the `range` built-in class, which was previously defined like this:
```py
class range:
@ -531,7 +544,7 @@ f[7] = "bar"
# You asked to set ind=7 to bar
```
### String Slicing
### Slicing
Substrings can be extracted from strings via slicing:
@ -546,9 +559,16 @@ print("Hello world!"[-1:])
_**NOTE**: Step values are not yet supported._
Lists can also be sliced:
```py
print([1,2,3,4,5,6][3:])
# → [4, 5, 6]
```
### String Conversion
If an object implements the `__str__` method, it will be called to produce string values when concatenating or printing.
If an object implements the `__str__` method, it will be called to produce string values through casting or printing.
```py
class Foo:
@ -559,6 +579,23 @@ print(f)
# → (I am a Foo!)
```
The `__repr__` method serves a similar purpose and is used when the REPL displays values or when they used in string representations of collections. The implementations of `__str__` and `__repr__` can be different:
```py
class Foo:
def __str__():
return "What is a Foo but a miserable pile of methods?"
def __repr__():
return "[Foo instance]"
let f = Foo()
print(f)
print([f,f,f])
# → What is a Foo but a miserable pile of methods?
# [[Foo instance], [Foo instance], [Foo instance]]
```
As in Python, `__repr__` is intended to provide a canonical string representation which, if possible, should be usable to recreate the object.
### File I/O
The module `fileio` provides an interface for opening, reading, and writing files, including `stdin`/`stdout`/`stderr`.

View File

@ -54,6 +54,7 @@ const char krk_builtinsSrc[] =
" self._dict[v] = 1\n"
" def __contains__(self, v):\n"
" return v in self._dict\n"
" def __str__(self): return self.__repr__()\n"
" def __repr__(self):\n"
" if self.__inrepr: return '{}' # sets are supposed to be unhashable, but whatever\n"
" let b='{'+', '.join([repr(k) for k in self._dict.keys()])+'}'\n"

View File

@ -53,6 +53,7 @@ class set():
self._dict[v] = 1
def __contains__(self, v):
return v in self._dict
def __str__(self): return self.__repr__()
def __repr__(self):
if self.__inrepr: return '{}' # sets are supposed to be unhashable, but whatever
let b='{'+', '.join([repr(k) for k in self._dict.keys()])+'}'

View File

@ -512,9 +512,17 @@ int main(int argc, char * argv[]) {
if (valid) {
KrkValue result = krk_interpret(allData, 0, "<module>","<stdin>");
if (!IS_NONE(result)) {
fprintf(stdout, " \033[1;30m=> ");
krk_printValue(stdout, result);
fprintf(stdout, "\033[0m\n");
KrkClass * type = AS_CLASS(krk_typeOf(1,&result));
const char * formatStr = " \033[1;30m=> %s\033[0m\n";
if (type->_reprer) {
krk_push(result);
result = krk_callSimple(OBJECT_VAL(type->_reprer), 1, 0);
fprintf(stdout, formatStr, AS_CSTRING(result));
} else if (type->_tostr) {
krk_push(result);
result = krk_callSimple(OBJECT_VAL(type->_reprer), 1, 0);
fprintf(stdout, formatStr, AS_CSTRING(result));
}
krk_resetStack();
}
free(allData);

View File

@ -303,6 +303,7 @@ KrkValue krk_module_onload_fileio(void) {
krk_defineNative(&FileClass->methods, ".__init__", krk_file_reject_init);
krk_defineNative(&FileClass->methods, ".__enter__", krk_file_enter);
krk_defineNative(&FileClass->methods, ".__exit__", krk_file_exit);
krk_finalizeClass(FileClass);
/* Make an instance for stdout, stderr, and stdin */
makeFileInstance(module, "stdin",stdin);

16
value.c
View File

@ -53,16 +53,16 @@ void krk_printValue(FILE * f, KrkValue printable) {
}
return;
}
krk_push(printable);
if (krk_bindMethod(AS_CLASS(krk_typeOf(1,(KrkValue[]){printable})), AS_STRING(vm.specialMethodNames[METHOD_REPR]))) {
switch (krk_callValue(krk_peek(0), 0, 0)) {
case 2: printable = krk_pop(); break;
case 1: printable = krk_runNext(); break;
default: fprintf(f, "[unable to print object at address %p]", (void*)AS_OBJECT(printable)); return;
}
KrkClass * type = AS_CLASS(krk_typeOf(1,&printable));
if (type->_tostr) {
krk_push(printable);
printable = krk_callSimple(OBJECT_VAL(type->_tostr), 1, 0);
fprintf(f, "%s", AS_CSTRING(printable));
} else if (type->_reprer) {
krk_push(printable);
printable = krk_callSimple(OBJECT_VAL(type->_reprer), 1, 0);
fprintf(f, "%s", AS_CSTRING(printable));
} else {
krk_pop();
fprintf(f, "%s", krk_typeName(printable));
}
}

1
vm.c
View File

@ -2625,6 +2625,7 @@ void krk_initVM(int flags) {
/* Attach new repr/str */
krk_defineNative(&vm.moduleClass->methods, ".__repr__", _module_repr);
krk_defineNative(&vm.moduleClass->methods, ".__str__", _module_repr);
krk_finalizeClass(vm.moduleClass);
/* Build a __builtins__ namespace for some extra functions. */
vm.builtins = krk_newInstance(vm.moduleClass);