diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index d66ba6d4..fff7920e 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -40,6 +40,8 @@ typedef struct py_Callbacks { char* (*importfile)(const char*); /// Used by `print` to output a string. void (*print)(const char*); + /// Used by `input` to get a character. + int (*getchar)(); } py_Callbacks; #define PY_RAISE diff --git a/src/common/sstream.c b/src/common/sstream.c index eaab46fb..5c57d9bd 100644 --- a/src/common/sstream.c +++ b/src/common/sstream.c @@ -244,45 +244,3 @@ void pk_sprintf(c11_sbuf* ss, const char* fmt, ...) { pk_vsprintf(ss, fmt, args); va_end(args); } - -int py_replinput(char* buf, int max_size) { - buf[0] = '\0'; // reset first char because we check '@' at the beginning - - int size = 0; - bool multiline = false; - printf(">>> "); - - while(true) { - int c = getchar(); - if(c == EOF) return -1; - - if(c == '\n') { - char last = '\0'; - if(size > 0) last = buf[size - 1]; - if(multiline) { - if(last == '\n') { - break; // 2 consecutive newlines to end multiline input - } else { - printf("... "); - } - } else { - if(last == ':' || last == '(' || last == '[' || last == '{' || buf[0] == '@') { - printf("... "); - multiline = true; - } else { - break; - } - } - } - - if(size == max_size - 1) { - buf[size] = '\0'; - return size; - } - - buf[size++] = c; - } - - buf[size] = '\0'; - return size; -} \ No newline at end of file diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 9275533d..986baf86 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -66,6 +66,7 @@ void VM__ctor(VM* self) { self->callbacks.importfile = pk_default_importfile; self->callbacks.print = pk_default_print; + self->callbacks.getchar = getchar; self->last_retval = *py_NIL(); self->curr_exception = *py_NIL(); @@ -748,3 +749,45 @@ bool pk_wrapper__NotImplementedError(int argc, py_Ref argv) { } py_TypeInfo* pk__type_info(py_Type type) { return TypeList__get(&pk_current_vm->types, type); } + +int py_replinput(char* buf, int max_size) { + buf[0] = '\0'; // reset first char because we check '@' at the beginning + + int size = 0; + bool multiline = false; + printf(">>> "); + + while(true) { + int c = pk_current_vm->callbacks.getchar(); + if(c == EOF) return -1; + + if(c == '\n') { + char last = '\0'; + if(size > 0) last = buf[size - 1]; + if(multiline) { + if(last == '\n') { + break; // 2 consecutive newlines to end multiline input + } else { + printf("... "); + } + } else { + if(last == ':' || last == '(' || last == '[' || last == '{' || buf[0] == '@') { + printf("... "); + multiline = true; + } else { + break; + } + } + } + + if(size == max_size - 1) { + buf[size] = '\0'; + return size; + } + + buf[size++] = c; + } + + buf[size] = '\0'; + return size; +} \ No newline at end of file diff --git a/src/public/modules.c b/src/public/modules.c index c4b35297..ec832d9d 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -1,4 +1,5 @@ #include "pocketpy/common/str.h" +#include "pocketpy/objects/base.h" #include "pocketpy/objects/codeobject.h" #include "pocketpy/pocketpy.h" #include "pocketpy/common/utils.h" @@ -208,7 +209,7 @@ static bool builtins_input(int argc, py_Ref argv) { c11_sbuf buf; c11_sbuf__ctor(&buf); while(true) { - int c = getchar(); + int c = pk_current_vm->callbacks.getchar(); if(c == '\n') break; if(c == EOF) break; c11_sbuf__write_char(&buf, c);