kuroko: More upstreams updates

This commit is contained in:
K. Lange 2021-01-23 09:26:04 +09:00
parent f05522baca
commit a53757a307
3 changed files with 79 additions and 35 deletions

View File

@ -4,6 +4,7 @@
* Reads lines from stdin with the `rline` library and executes them, * Reads lines from stdin with the `rline` library and executes them,
* or executes scripts from the argument list. * or executes scripts from the argument list.
*/ */
#define _DEFAULT_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
@ -155,10 +156,9 @@ static void tab_complete_func(rline_context_t * c) {
fprintf(stderr,"\nInternal error while tab completting.\n"); fprintf(stderr,"\nInternal error while tab completting.\n");
goto _cleanup; goto _cleanup;
} }
KrkValue _list_internal = OBJECT_VAL(AS_INSTANCE(dirList)->_internal);
for (size_t i = 0; i < AS_LIST(_list_internal)->count; ++i) { for (size_t i = 0; i < AS_LIST(dirList)->count; ++i) {
KrkString * s = AS_STRING(AS_LIST(_list_internal)->values[i]); KrkString * s = AS_STRING(AS_LIST(dirList)->values[i]);
KrkToken asToken = {.start = s->chars, .literalWidth = s->length}; KrkToken asToken = {.start = s->chars, .literalWidth = s->length};
KrkValue thisValue = findFromProperty(root, asToken); KrkValue thisValue = findFromProperty(root, asToken);
if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) || if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) ||
@ -276,15 +276,51 @@ static void handleSigint(int sigNum) {
signal(sigNum, handleSigint); signal(sigNum, handleSigint);
} }
static void findInterpreter(char * argv[]) {
#ifdef _WIN32
vm.binpath = strdup(_pgmptr);
#else
/* Try asking /proc */
char * binpath = realpath("/proc/self/exe", NULL);
if (!binpath) {
if (strchr(argv[0], '/')) {
binpath = realpath(argv[0], NULL);
} else {
/* Search PATH for argv[0] */
char * _path = strdup(getenv("PATH"));
char * path = _path;
while (path) {
char * next = strchr(path,':');
if (next) *next++ = '\0';
char tmp[4096];
sprintf(tmp, "%s/%s", path, argv[0]);
if (access(tmp, X_OK)) {
binpath = strdup(tmp);
break;
}
path = next;
}
free(_path);
}
}
if (binpath) {
vm.binpath = binpath;
} /* Else, give up at this point and just don't attach it at all. */
#endif
}
/* Runs the interpreter to get the version information. */ /* Runs the interpreter to get the version information. */
static int version(void) { static int version(char * argv[]) {
findInterpreter(argv);
krk_initVM(0); krk_initVM(0);
krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", 1, "<stdin>","<stdin>"); krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", 1, "<stdin>","<stdin>");
krk_freeVM(); krk_freeVM();
return 0; return 0;
} }
static int modulePaths(void) { static int modulePaths(char * argv[]) {
findInterpreter(argv);
krk_initVM(0); krk_initVM(0);
krk_interpret("import kuroko\nprint(kuroko.module_paths)\n", 1, "<stdin>","<stdin>"); krk_interpret("import kuroko\nprint(kuroko.module_paths)\n", 1, "<stdin>","<stdin>");
krk_freeVM(); krk_freeVM();
@ -331,12 +367,12 @@ int main(int argc, char * argv[]) {
enableRline = 0; enableRline = 0;
break; break;
case 'M': case 'M':
return modulePaths(); return modulePaths(argv);
case 'V': case 'V':
return version(); return version(argv);
case '-': case '-':
if (!strcmp(optarg,"version")) { if (!strcmp(optarg,"version")) {
return version(); return version(argv);
} else if (!strcmp(optarg,"help")) { } else if (!strcmp(optarg,"help")) {
fprintf(stderr,"usage: %s [flags] [FILE...]\n" fprintf(stderr,"usage: %s [flags] [FILE...]\n"
"\n" "\n"
@ -364,6 +400,7 @@ int main(int argc, char * argv[]) {
} }
_finishArgs: _finishArgs:
findInterpreter(argv);
krk_initVM(flags); krk_initVM(flags);
/* Attach kuroko.argv - argv[0] will be set to an empty string for the repl */ /* Attach kuroko.argv - argv[0] will be set to an empty string for the repl */
@ -399,7 +436,7 @@ _finishArgs:
KrkValue module; KrkValue module;
krk_push(OBJECT_VAL(krk_copyString("__main__",8))); krk_push(OBJECT_VAL(krk_copyString("__main__",8)));
int out = !krk_loadModule( int out = !krk_loadModule(
AS_STRING(AS_LIST(OBJECT_VAL(AS_INSTANCE(argList)->_internal))->values[0]), AS_STRING(AS_LIST(argList)->values[0]),
&module, &module,
AS_STRING(krk_peek(0))); AS_STRING(krk_peek(0)));
if (vm.flags & KRK_HAS_EXCEPTION) { if (vm.flags & KRK_HAS_EXCEPTION) {
@ -616,13 +653,7 @@ _finishArgs:
(void)blockWidth; (void)blockWidth;
} }
} else { } else {
/* Expect the rest of the arguments to be scripts to run; result = krk_runfile(argv[optind],1,"__main__",argv[optind]);
* collect the result of the last one and use it as the
* exit code if it's an integer. */
for (int i = optind; i < argc; ++i) {
KrkValue out = krk_runfile(argv[i],1,"__main__",argv[i]);
if (i + 1 == argc) result = out;
}
} }
krk_freeVM(); krk_freeVM();

2
kuroko

@ -1 +1 @@
Subproject commit a69ee8efcaaa685d99c9093e8223a5e2e0c25de3 Subproject commit 3e9061502108a80c4873a4d8dcff5e97ef55e538

View File

@ -14,6 +14,16 @@ static KrkInstance * yctxInstance = NULL;
#define S(c) (krk_copyString(c,sizeof(c)-1)) #define S(c) (krk_copyString(c,sizeof(c)-1))
struct MessageClass {
KrkInstance inst;
yutani_msg_t * msg;
};
struct YutaniClass {
KrkInstance inst;
yutani_t * yctx;
};
/** /**
* Convenience wrapper to make a class and attach it to the module, while * Convenience wrapper to make a class and attach it to the module, while
* handling stack push/pop to keep things from being prematurely GC'd. * handling stack push/pop to keep things from being prematurely GC'd.
@ -22,13 +32,9 @@ KrkClass * krk_createClass(KrkInstance * inModule, const char * name, KrkClass *
if (!base) base = vm.objectClass; if (!base) base = vm.objectClass;
KrkString * str_Name = krk_copyString(name, strlen(name)); KrkString * str_Name = krk_copyString(name, strlen(name));
krk_push(OBJECT_VAL(str_Name)); krk_push(OBJECT_VAL(str_Name));
KrkClass * obj_Class = krk_newClass(str_Name); KrkClass * obj_Class = krk_newClass(str_Name, base);
krk_push(OBJECT_VAL(obj_Class)); krk_push(OBJECT_VAL(obj_Class));
krk_attachNamedObject(&inModule->fields, name, (KrkObj *)obj_Class); krk_attachNamedObject(&inModule->fields, name, (KrkObj *)obj_Class);
krk_tableAddAll(&base->methods, &obj_Class->methods);
krk_tableAddAll(&base->fields, &obj_Class->fields);
krk_pop(); /* obj_Class */ krk_pop(); /* obj_Class */
krk_pop(); /* str_Name */ krk_pop(); /* str_Name */
@ -47,11 +53,15 @@ KrkClass * krk_createClass(KrkInstance * inModule, const char * name, KrkClass *
#define WID() DO_FIELD("wid", TO_INT(wid)) #define WID() DO_FIELD("wid", TO_INT(wid))
#define STRUCT(type) type * me = (void*)msg->data #define STRUCT(type) type * me = (void*)msg->data
static void _message_sweep(KrkInstance * self) {
free(((struct MessageClass*)self)->msg);
}
static KrkValue _message_getattr(int argc, KrkValue argv[]) { static KrkValue _message_getattr(int argc, KrkValue argv[]) {
assert(argc == 2); assert(argc == 2);
KrkInstance * self = AS_INSTANCE(argv[0]); KrkInstance * self = AS_INSTANCE(argv[0]);
yutani_msg_t * msg = self->_internal; yutani_msg_t * msg = ((struct MessageClass*)self)->msg;
if (!msg) return NONE_VAL(); if (!msg) return NONE_VAL();
DO_FIELD("magic", TO_INT_(magic)); DO_FIELD("magic", TO_INT_(magic));
@ -154,7 +164,7 @@ static KrkValue _yutani_init(int argc, KrkValue argv[], int hasKw) {
return NONE_VAL(); return NONE_VAL();
} }
fprintf(stderr, "Attaching field...\n"); fprintf(stderr, "Attaching field...\n");
self->_internal = yctx; ((struct YutaniClass*)self)->yctx = yctx;
yctxInstance = self; yctxInstance = self;
krk_attachNamedObject(&module->fields, "_yutani_t", (KrkObj*)self); krk_attachNamedObject(&module->fields, "_yutani_t", (KrkObj*)self);
@ -163,13 +173,13 @@ static KrkValue _yutani_init(int argc, KrkValue argv[], int hasKw) {
static KrkValue _yutani_display_width(int argc, KrkValue argv[]) { static KrkValue _yutani_display_width(int argc, KrkValue argv[]) {
KrkInstance * self = AS_INSTANCE(argv[0]); KrkInstance * self = AS_INSTANCE(argv[0]);
yutani_t * ctx = self->_internal; yutani_t * ctx = ((struct YutaniClass*)self)->yctx;
return INTEGER_VAL(ctx->display_width); return INTEGER_VAL(ctx->display_width);
} }
static KrkValue _yutani_display_height(int argc, KrkValue argv[]) { static KrkValue _yutani_display_height(int argc, KrkValue argv[]) {
KrkInstance * self = AS_INSTANCE(argv[0]); KrkInstance * self = AS_INSTANCE(argv[0]);
yutani_t * ctx = self->_internal; yutani_t * ctx = ((struct YutaniClass*)self)->yctx;
return INTEGER_VAL(ctx->display_height); return INTEGER_VAL(ctx->display_height);
} }
@ -179,16 +189,16 @@ static KrkValue _yutani_poll(int argc, KrkValue argv[], int hasKw) {
int sync = (argc > 1 && IS_BOOLEAN(argv[1])) ? AS_BOOLEAN(argv[1]) : 1; int sync = (argc > 1 && IS_BOOLEAN(argv[1])) ? AS_BOOLEAN(argv[1]) : 1;
yutani_msg_t * result; yutani_msg_t * result;
if (sync) { if (sync) {
result = yutani_poll((yutani_t*)self->_internal); result = yutani_poll(((struct YutaniClass*)self)->yctx);
} else { } else {
result = yutani_poll_async((yutani_t *)self->_internal); result = yutani_poll_async(((struct YutaniClass*)self)->yctx);
} }
if (!result) return NONE_VAL(); if (!result) return NONE_VAL();
KrkInstance * out = krk_newInstance(Message); KrkInstance * out = krk_newInstance(Message);
krk_push(OBJECT_VAL(out)); krk_push(OBJECT_VAL(out));
out->_internal = result; ((struct MessageClass*)out)->msg = result;
return krk_pop(); return krk_pop();
} }
@ -196,10 +206,10 @@ static KrkValue _yutani_poll(int argc, KrkValue argv[], int hasKw) {
static KrkValue _yutani_wait_for(int argc, KrkValue argv[]) { static KrkValue _yutani_wait_for(int argc, KrkValue argv[]) {
if (argc != 2) { krk_runtimeError(vm.exceptions.argumentError, "Expected two arguments"); return NONE_VAL(); } if (argc != 2) { krk_runtimeError(vm.exceptions.argumentError, "Expected two arguments"); return NONE_VAL(); }
KrkInstance * self = AS_INSTANCE(argv[0]); KrkInstance * self = AS_INSTANCE(argv[0]);
yutani_msg_t * result = yutani_wait_for((yutani_t*)self->_internal, AS_INTEGER(argv[1])); yutani_msg_t * result = yutani_wait_for(((struct YutaniClass*)self)->yctx, AS_INTEGER(argv[1]));
KrkInstance * out = krk_newInstance(Message); KrkInstance * out = krk_newInstance(Message);
krk_push(OBJECT_VAL(out)); krk_push(OBJECT_VAL(out));
out->_internal = result; ((struct MessageClass*)out)->msg = result;
return krk_pop(); return krk_pop();
} }
@ -216,6 +226,8 @@ KrkValue krk_module_onload__yutani(void) {
* MSG_... = ... # Directly from the library headers. * MSG_... = ... # Directly from the library headers.
*/ */
Message = krk_createClass(module, "Message", NULL); Message = krk_createClass(module, "Message", NULL);
Message->allocSize = sizeof(struct MessageClass);
Message->_ongcsweep = _message_sweep;
/* All the MSG_ constants */ /* All the MSG_ constants */
#define TYPE(type) krk_attachNamedValue(&Message->fields, "MSG_" #type, INTEGER_VAL(YUTANI_MSG_ ## type)) #define TYPE(type) krk_attachNamedValue(&Message->fields, "MSG_" #type, INTEGER_VAL(YUTANI_MSG_ ## type))
TYPE(HELLO); TYPE(WINDOW_NEW); TYPE(FLIP); TYPE(KEY_EVENT); TYPE(MOUSE_EVENT); TYPE(HELLO); TYPE(WINDOW_NEW); TYPE(FLIP); TYPE(KEY_EVENT); TYPE(MOUSE_EVENT);
@ -235,13 +247,14 @@ KrkValue krk_module_onload__yutani(void) {
/** /**
* class Yutani(object): * class Yutani(object):
* _internal = yutani_t * * yctx = yutani_t *
* display_width = _internal->display_width * display_width = yctx->display_width
* display_height = _internal->display_height * display_height = yctx->display_height
* *
* def __init__(self): # Call yutani_init(), attach _internal * def __init__(self): # Call yutani_init()
*/ */
Yutani = krk_createClass(module, "Yutani", NULL); Yutani = krk_createClass(module, "Yutani", NULL);
Yutani->allocSize = sizeof(struct YutaniClass);
krk_defineNative(&Yutani->methods, ":display_width", _yutani_display_width); krk_defineNative(&Yutani->methods, ":display_width", _yutani_display_width);
krk_defineNative(&Yutani->methods, ":display_height", _yutani_display_height); krk_defineNative(&Yutani->methods, ":display_height", _yutani_display_height);
krk_defineNative(&Yutani->methods, ".__init__", _yutani_init); krk_defineNative(&Yutani->methods, ".__init__", _yutani_init);