kuroko: Updates for 1.1-preview and threading support

This commit is contained in:
K. Lange 2021-02-16 18:50:17 +09:00
parent 230870ad7b
commit 97d02d6e23
9 changed files with 367 additions and 262 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@
/.make/*
/base/bin/*
/base/lib/kuroko
/base/src
/_base
/cdrom/extra

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "kuroko"]
path = kuroko
url = git@github.com:klange/kuroko
url = git@github.com:kuroko-lang/kuroko

View File

@ -164,7 +164,7 @@ base/cdrom:
mkdir -p $@
base/var:
mkdir -p $@
base/usr/local/lib/kuroko:
base/lib/kuroko:
mkdir -p $@
fatbase/efi/boot:
mkdir -p $@
@ -172,7 +172,7 @@ cdrom:
mkdir -p $@
.make:
mkdir -p .make
dirs: base/dev base/tmp base/proc base/bin base/lib base/cdrom base/usr/local/lib/kuroko cdrom base/var fatbase/efi/boot .make
dirs: base/dev base/tmp base/proc base/bin base/lib base/cdrom base/lib/kuroko cdrom base/var fatbase/efi/boot .make
# C Library
@ -201,13 +201,13 @@ kuroko/%.o: kuroko/%.c
$(CC) $(CFLAGS) -DDEBUG -fPIC -c -o $@ $^
KUROKO_CMODS=$(patsubst kuroko/src/module_%.c,%,$(wildcard kuroko/src/module_*.c)) $(patsubst lib/kuroko/%.c,%,$(wildcard lib/kuroko/*.c))
KUROKO_CMODS_X=$(foreach lib,$(KUROKO_CMODS),base/usr/local/lib/kuroko/$(lib).so)
KUROKO_CMODS_X=$(foreach lib,$(KUROKO_CMODS),base/lib/kuroko/$(lib).so)
KUROKO_CMODS_Y=$(foreach lib,$(KUROKO_CMODS),.make/$(lib).kmak)
KUROKO_KRK_MODS=$(patsubst kuroko/modules/%.krk,base/usr/local/lib/kuroko/%.krk,$(wildcard kuroko/modules/*.krk kuroko/modules/*/*.krk))
KUROKO_KRK_MODS=$(patsubst kuroko/modules/%.krk,base/lib/kuroko/%.krk,$(wildcard kuroko/modules/*.krk kuroko/modules/*/*.krk))
KUROKO_FILES=$(KUROKO_CMODS_X) $(KUROKO_KRK_MODS) base/lib/libkuroko.so
base/usr/local/lib/kuroko/%.krk: kuroko/modules/%.krk
base/lib/kuroko/%.krk: kuroko/modules/%.krk
@mkdir -p `dirname $@`
cp $< $@

View File

@ -954,12 +954,12 @@ void recalculate_syntax(line_t * line, int line_no) {
s->state.i = 0;
while (1) {
ptrdiff_t before = vm.stackTop - vm.stack;
ptrdiff_t before = krk_currentThread.stackTop - krk_currentThread.stack;
krk_push(OBJECT_VAL(s));
KrkValue result = krk_callSimple(OBJECT_VAL(env->syntax->krkFunc), 1, 0);
vm.stackTop = vm.stack + before;
if (IS_NONE(result) && (vm.flags & KRK_HAS_EXCEPTION)) {
render_error("Exception occurred in plugin: %s", AS_INSTANCE(vm.currentException)->_class->name->chars);
krk_currentThread.stackTop = krk_currentThread.stack + before;
if (IS_NONE(result) && (krk_currentThread.flags & KRK_HAS_EXCEPTION)) {
render_error("Exception occurred in plugin: %s", AS_INSTANCE(krk_currentThread.currentException)->_class->name->chars);
krk_dumpTraceback();
fprintf(stderr,"\n\nThis syntax highlighter will be disabled in this environment.\n\n");
int key = 0;
@ -5477,11 +5477,11 @@ BIM_COMMAND(theme,"theme","Set color theme") {
} else {
for (struct theme_def * d = themes; themes && d->name; ++d) {
if (!strcmp(argv[1], d->name)) {
ptrdiff_t before = vm.stackTop - vm.stack;
ptrdiff_t before = krk_currentThread.stackTop - krk_currentThread.stack;
KrkValue result = krk_callSimple(OBJECT_VAL(d->callable), 0, 0);
vm.stackTop = vm.stack + before;
if (IS_NONE(result) && (vm.flags & KRK_HAS_EXCEPTION)) {
render_error("Exception occurred in theme: %s", AS_INSTANCE(vm.currentException)->_class->name->chars);
krk_currentThread.stackTop = krk_currentThread.stack + before;
if (IS_NONE(result) && (krk_currentThread.flags & KRK_HAS_EXCEPTION)) {
render_error("Exception occurred in theme: %s", AS_INSTANCE(krk_currentThread.currentException)->_class->name->chars);
krk_dumpTraceback();
int key = 0;
while ((key = bim_getkey(DEFAULT_KEY_WAIT)) == KEY_TIMEOUT);
@ -9930,7 +9930,7 @@ int process_krk_command(const char * cmd, KrkValue * outVal) {
krk_push(NONE_VAL());
/* If we don't set outSlots for the top frame a syntax error will
* get printed by the interpreter and we can't catch it here. */
vm.frames[0].outSlots = 1;
krk_currentThread.frames[0].outSlots = 1;
/* Call the interpreter */
KrkValue out = krk_interpret(cmd,0,"<bim>","<bim>");
/* If the user typed just a command name, try to execute it. */
@ -9942,8 +9942,8 @@ int process_krk_command(const char * cmd, KrkValue * outVal) {
int retval = (IS_INTEGER(out)) ? AS_INTEGER(out) : 0;
int hadOutput = 0;
/* If we got an exception during execution, print it now */
if (vm.flags & KRK_HAS_EXCEPTION) {
if (krk_isInstanceOf(vm.currentException, vm.exceptions.syntaxError)) {
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_isInstanceOf(krk_currentThread.currentException, vm.exceptions->syntaxError)) {
}
set_fg_color(COLOR_RED);
fflush(stdout);
@ -10026,10 +10026,10 @@ BIM_COMMAND(runkrk,"runkrk", "Run a kuroko script") {
if (argc < 2) return 1;
/* In case we're running in a weird context? */
int previousExitFrame = vm.exitOnFrame;
vm.exitOnFrame = vm.frameCount;
int previousExitFrame = krk_currentThread.exitOnFrame;
krk_currentThread.exitOnFrame = krk_currentThread.frameCount;
krk_runfile(argv[1],1,"<bim>",argv[1]);
vm.exitOnFrame = previousExitFrame;
krk_currentThread.exitOnFrame = previousExitFrame;
redraw_all();
@ -10163,9 +10163,9 @@ static int checkClass(KrkClass * _class, KrkClass * base) {
}
static KrkValue krk_bim_syntax_dict;
static KrkValue krk_bim_register_syntax(int argc, KrkValue argv[]) {
static KrkValue krk_bim_register_syntax(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !IS_CLASS(argv[0]) || !checkClass(AS_CLASS(argv[0]), syntaxStateClass))
return krk_runtimeError(vm.exceptions.typeError, "Can not register '%s' as a syntax highlighter, expected subclass of SyntaxState.", krk_typeName(argv[0]));
return krk_runtimeError(vm.exceptions->typeError, "Can not register '%s' as a syntax highlighter, expected subclass of SyntaxState.", krk_typeName(argv[0]));
KrkValue name = NONE_VAL(), extensions = NONE_VAL(), spaces = BOOLEAN_VAL(0), calculate = NONE_VAL();
krk_tableGet(&AS_CLASS(argv[0])->fields, OBJECT_VAL(S("name")), &name);
@ -10173,13 +10173,13 @@ static KrkValue krk_bim_register_syntax(int argc, KrkValue argv[]) {
krk_tableGet(&AS_CLASS(argv[0])->fields, OBJECT_VAL(S("spaces")), &spaces);
krk_tableGet(&AS_CLASS(argv[0])->methods, OBJECT_VAL(S("calculate")), &calculate);
if (!IS_STRING(name))
return krk_runtimeError(vm.exceptions.typeError, "%s.name must be str", AS_CLASS(argv[0])->name->chars);
return krk_runtimeError(vm.exceptions->typeError, "%s.name must be str", AS_CLASS(argv[0])->name->chars);
if (!IS_TUPLE(extensions))
return krk_runtimeError(vm.exceptions.typeError, "%s.extensions must by tuple<str>", AS_CLASS(argv[0])->name->chars);
return krk_runtimeError(vm.exceptions->typeError, "%s.extensions must by tuple<str>", AS_CLASS(argv[0])->name->chars);
if (!IS_BOOLEAN(spaces))
return krk_runtimeError(vm.exceptions.typeError, "%s.spaces must be bool", AS_CLASS(argv[0])->name->chars);
return krk_runtimeError(vm.exceptions->typeError, "%s.spaces must be bool", AS_CLASS(argv[0])->name->chars);
if (!IS_CLOSURE(calculate))
return krk_runtimeError(vm.exceptions.typeError, "%s.calculate must be method, not '%s'", AS_CLASS(argv[0])->name->chars, krk_typeName(calculate));
return krk_runtimeError(vm.exceptions->typeError, "%s.calculate must be method, not '%s'", AS_CLASS(argv[0])->name->chars, krk_typeName(calculate));
/* Convert tuple of strings */
char ** ext = malloc(sizeof(char *) * (AS_TUPLE(extensions)->values.count + 1)); /* +1 for NULL */
@ -10187,7 +10187,7 @@ static KrkValue krk_bim_register_syntax(int argc, KrkValue argv[]) {
for (size_t i = 0; i < AS_TUPLE(extensions)->values.count; ++i) {
if (!IS_STRING(AS_TUPLE(extensions)->values.values[i])) {
free(ext);
return krk_runtimeError(vm.exceptions.typeError, "%s.extensions must by tuple<str>", AS_CLASS(argv[0])->name->chars);
return krk_runtimeError(vm.exceptions->typeError, "%s.extensions must by tuple<str>", AS_CLASS(argv[0])->name->chars);
}
ext[i] = AS_CSTRING(AS_TUPLE(extensions)->values.values[i]);
}
@ -10210,9 +10210,9 @@ static KrkValue krk_bim_register_syntax(int argc, KrkValue argv[]) {
}
static KrkValue krk_bim_theme_dict;
static KrkValue krk_bim_define_theme(int argc, KrkValue argv[]) {
static KrkValue krk_bim_define_theme(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !IS_CLOSURE(argv[0]))
return krk_runtimeError(vm.exceptions.typeError, "themes must be functions, not '%s'", krk_typeName(argv[0]));
return krk_runtimeError(vm.exceptions->typeError, "themes must be functions, not '%s'", krk_typeName(argv[0]));
KrkValue name = OBJECT_VAL(AS_CLOSURE(argv[0])->function->name);
@ -10230,35 +10230,35 @@ int c_keyword_qualifier(int c) {
}
#define BIM_STATE() \
if (argc < 1 || !krk_isInstanceOf(argv[0],syntaxStateClass)) return krk_runtimeError(vm.exceptions.typeError, "expected state"); \
if (argc < 1 || !krk_isInstanceOf(argv[0],syntaxStateClass)) return krk_runtimeError(vm.exceptions->typeError, "expected state"); \
KrkInstance * _self = AS_INSTANCE(argv[0]); \
struct SyntaxState * self = (struct SyntaxState*)_self; \
struct syntax_state * state = &self->state;
static KrkValue bim_krk_state_getstate(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_getstate(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
return INTEGER_VAL(state->state);
}
static KrkValue bim_krk_state_setstate(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_setstate(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
if (argc > 1 && IS_INTEGER(argv[1])) {
state->state = AS_INTEGER(argv[1]);
} else if (argc > 1 && IS_NONE(argv[1])) {
state->state = -1;
} else {
return krk_runtimeError(vm.exceptions.typeError, "expected int");
return krk_runtimeError(vm.exceptions->typeError, "expected int");
}
return NONE_VAL();
}
static KrkValue bim_krk_state_index(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_index(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
return INTEGER_VAL(state->i);
}
static KrkValue bim_krk_state_lineno(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_lineno(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
return INTEGER_VAL(state->line_no);
}
static KrkValue bim_krk_state_get(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_get(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
long arg = AS_INTEGER(argv[1]);
int charRel = charrel(arg);
@ -10267,26 +10267,26 @@ static KrkValue bim_krk_state_get(int argc, KrkValue argv[]) {
size_t len = to_eight(charRel, tmp);
return OBJECT_VAL(krk_copyString(tmp,len));
}
static KrkValue bim_krk_state_isdigit(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_isdigit(int argc, KrkValue argv[], int hasKw) {
if (IS_NONE(argv[1])) return BOOLEAN_VAL(0);
if (!IS_STRING(argv[1])) {
krk_runtimeError(vm.exceptions.typeError, "not a string: %s", krk_typeName(argv[1]));
krk_runtimeError(vm.exceptions->typeError, "not a string: %s", krk_typeName(argv[1]));
return BOOLEAN_VAL(0);
}
if (AS_STRING(argv[1])->codesLength > 1) {
krk_runtimeError(vm.exceptions.typeError, "arg must be str of len 1");
krk_runtimeError(vm.exceptions->typeError, "arg must be str of len 1");
return BOOLEAN_VAL(0);
}
unsigned int c = krk_unicodeCodepoint(AS_STRING(argv[1]), 0);
return BOOLEAN_VAL(!!isdigit(c));
}
static KrkValue bim_krk_state_isxdigit(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_isxdigit(int argc, KrkValue argv[], int hasKw) {
if (!IS_STRING(argv[1])) return BOOLEAN_VAL(0);
if (AS_STRING(argv[1])->length > 1) return BOOLEAN_VAL(0);
int c = AS_CSTRING(argv[1])[0];
return BOOLEAN_VAL(!!isxdigit(c));
}
static KrkValue bim_krk_state_paint(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_paint(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
long howMuch = AS_INTEGER(argv[1]);
if (howMuch == -1) howMuch = state->line->actual;
@ -10294,17 +10294,17 @@ static KrkValue bim_krk_state_paint(int argc, KrkValue argv[]) {
paint(howMuch, whatFlag);
return NONE_VAL();
}
static KrkValue bim_krk_state_paintComment(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_paintComment(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
paint_comment(state);
return NONE_VAL();
}
static KrkValue bim_krk_state_skip(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_skip(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
skip();
return NONE_VAL();
}
static KrkValue bim_krk_state_cKeywordQualifier(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_cKeywordQualifier(int argc, KrkValue argv[], int hasKw) {
if (IS_INTEGER(argv[1])) return BOOLEAN_VAL(!!c_keyword_qualifier(AS_INTEGER(argv[1])));
if (!IS_STRING(argv[1])) return BOOLEAN_VAL(0);
if (AS_STRING(argv[1])->length > 1) return BOOLEAN_VAL(0);
@ -10319,10 +10319,10 @@ static int callQualifier(KrkValue qualifier, int codepoint) {
return 0;
}
static KrkValue bim_krk_state_findKeywords(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_findKeywords(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
if (argc < 4 || !krk_isInstanceOf(argv[1], vm.baseClasses.listClass) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "invalid arguments to SyntaxState.findKeywords");
if (argc < 4 || !krk_isInstanceOf(argv[1], vm.baseClasses->listClass) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions->typeError, "invalid arguments to SyntaxState.findKeywords");
KrkValue qualifier = argv[3];
int flag = AS_INTEGER(argv[2]);
@ -10332,7 +10332,7 @@ static KrkValue bim_krk_state_findKeywords(int argc, KrkValue argv[]) {
for (size_t keyword = 0; keyword < AS_LIST(argv[1])->count; ++keyword) {
if (!IS_STRING(AS_LIST(argv[1])->values[keyword]))
return krk_runtimeError(vm.exceptions.typeError, "expected list of strings, found '%s'", krk_typeName(AS_LIST(argv[1])->values[keyword]));
return krk_runtimeError(vm.exceptions->typeError, "expected list of strings, found '%s'", krk_typeName(AS_LIST(argv[1])->values[keyword]));
KrkString * me = AS_STRING(AS_LIST(argv[1])->values[keyword]);
size_t d = 0;
@ -10354,10 +10354,10 @@ static KrkValue bim_krk_state_findKeywords(int argc, KrkValue argv[]) {
}
return BOOLEAN_VAL(0);
}
static KrkValue bim_krk_state_matchAndPaint(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_matchAndPaint(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
if (argc < 4 || !IS_STRING(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "invalid arguments to SyntaxState.matchAndPaint");
return krk_runtimeError(vm.exceptions->typeError, "invalid arguments to SyntaxState.matchAndPaint");
KrkValue qualifier = argv[3];
int flag = AS_INTEGER(argv[2]);
KrkString * me = AS_STRING(argv[1]);
@ -10379,19 +10379,19 @@ static KrkValue bim_krk_state_matchAndPaint(int argc, KrkValue argv[]) {
}
return BOOLEAN_VAL(0);
}
static KrkValue bim_krk_state_rewind(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_rewind(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
state->i -= AS_INTEGER(argv[1]);
return NONE_VAL();
}
static KrkValue bim_krk_state_commentBuzzwords(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_commentBuzzwords(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
return BOOLEAN_VAL(common_comment_buzzwords(state));
}
static KrkValue bim_krk_state_init(int argc, KrkValue argv[]) {
static KrkValue bim_krk_state_init(int argc, KrkValue argv[], int hasKw) {
BIM_STATE();
if (argc < 2 || !krk_isInstanceOf(argv[1], syntaxStateClass)) {
return krk_runtimeError(vm.exceptions.typeError, "Can only initialize subhighlighter from an existing highlighter.");
return krk_runtimeError(vm.exceptions->typeError, "Can only initialize subhighlighter from an existing highlighter.");
}
*state = ((struct SyntaxState*)AS_INSTANCE(argv[1]))->state;
@ -10399,8 +10399,8 @@ static KrkValue bim_krk_state_init(int argc, KrkValue argv[]) {
return argv[0];
}
static KrkValue krk_bim_get_commands(int argc, KrkValue argv[]) {
KrkValue myList = krk_list_of(0, NULL);
static KrkValue krk_bim_get_commands(int argc, KrkValue argv[], int hasKw) {
KrkValue myList = krk_list_of(0, NULL,0);
krk_push(myList);
for (struct command_def * c = regular_commands; regular_commands && c->name; ++c) {
krk_writeValueArray(AS_LIST(myList), OBJECT_VAL(krk_copyString(c->name,strlen(c->name))));
@ -10417,7 +10417,7 @@ struct ActionDef {
struct action_def * action;
};
static KrkValue bim_krk_action_call(int argc, KrkValue argv[]) {
static KrkValue bim_krk_action_call(int argc, KrkValue argv[], int hasKw) {
struct ActionDef * self = (void*)AS_OBJECT(argv[0]);
/* Figure out arguments */
@ -10429,7 +10429,7 @@ static KrkValue bim_krk_action_call(int argc, KrkValue argv[]) {
int argsAsInts[3] = { 0, 0, 0 };
for (int i = 0; i < args; i++) {
if (argc < i + 2)
return krk_runtimeError(vm.exceptions.argumentError, "%s() takes %d argument%s",
return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %d argument%s",
self->action->name, args, args == 1 ? "" : "s");
if (IS_INTEGER(argv[i+1])) {
argsAsInts[i] = AS_INTEGER(argv[i+1]);
@ -10438,7 +10438,7 @@ static KrkValue bim_krk_action_call(int argc, KrkValue argv[]) {
} else if (IS_BOOLEAN(argv[i+1])) {
argsAsInts[i] = AS_BOOLEAN(argv[i+1]);
} else {
return krk_runtimeError(vm.exceptions.typeError,
return krk_runtimeError(vm.exceptions->typeError,
"argument to %s() must be int, bool, or str of len 1",
self->action->name);
}
@ -10449,7 +10449,7 @@ static KrkValue bim_krk_action_call(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue bim_krk_command_call(int argc, KrkValue argv[]) {
static KrkValue bim_krk_command_call(int argc, KrkValue argv[], int hasKw) {
struct CommandDef * self = (void*)AS_OBJECT(argv[0]);
char ** args = malloc(sizeof(char*)*argc);
@ -10614,20 +10614,22 @@ void initialize(void) {
global_config.tab_indicator = strdup(">");
global_config.space_indicator = strdup("-");
fprintf(stderr, "init vm\n");
krk_initVM(0); /* no debug flags */
fprintf(stderr, "done\n");
KrkInstance * bimModule = krk_newInstance(vm.moduleClass);
KrkInstance * bimModule = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "bim", (KrkObj*)bimModule);
krk_attachNamedObject(&bimModule->fields, "__name__", (KrkObj*)S("bim"));
krk_defineNative(&bimModule->fields, "bindHighlighter", krk_bim_register_syntax);
krk_defineNative(&bimModule->fields, "getCommands", krk_bim_get_commands);
krk_bim_theme_dict = krk_dict_of(0,NULL);
krk_bim_theme_dict = krk_dict_of(0,NULL,0);
krk_attachNamedValue(&bimModule->fields, "themes", krk_bim_theme_dict);
krk_defineNative(&bimModule->fields, "defineTheme", krk_bim_define_theme);
krk_bim_syntax_dict = krk_dict_of(0,NULL);
krk_bim_syntax_dict = krk_dict_of(0,NULL,0);
krk_attachNamedValue(&bimModule->fields, "highlighters", krk_bim_syntax_dict);
makeClass(bimModule, &ActionDef, "Action", vm.objectClass);
makeClass(bimModule, &ActionDef, "Action", vm.baseClasses->objectClass);
ActionDef->allocSize = sizeof(struct ActionDef);
krk_defineNative(&ActionDef->methods, ".__call__", bim_krk_action_call);
krk_finalizeClass(ActionDef);
@ -10638,12 +10640,12 @@ void initialize(void) {
krk_attachNamedObject(&vm.builtins->fields, a->name, (KrkObj*)actionObj);
}
makeClass(bimModule, &CommandDef, "Command", vm.objectClass);
makeClass(bimModule, &CommandDef, "Command", vm.baseClasses->objectClass);
CommandDef->allocSize = sizeof(struct CommandDef);
krk_defineNative(&CommandDef->methods, ".__call__", bim_krk_command_call);
krk_finalizeClass(CommandDef);
KrkInstance * global = krk_newInstance(vm.objectClass);
KrkInstance * global = krk_newInstance(vm.baseClasses->objectClass);
krk_attachNamedObject(&vm.builtins->fields, "global", (KrkObj*)global);
for (struct command_def * c = regular_commands; regular_commands && c->name; ++c) {
@ -10656,7 +10658,7 @@ void initialize(void) {
}
}
makeClass(bimModule, &syntaxStateClass, "SyntaxState", vm.objectClass);
makeClass(bimModule, &syntaxStateClass, "SyntaxState", vm.baseClasses->objectClass);
syntaxStateClass->allocSize = sizeof(struct SyntaxState);
krk_defineNative(&syntaxStateClass->methods, ":state", bim_krk_state_getstate);
krk_defineNative(&syntaxStateClass->methods, ".set_state", bim_krk_state_setstate); /* TODO property? */
@ -10694,16 +10696,18 @@ void initialize(void) {
krk_resetStack();
krk_startModule("<bim-syntax>");
import_directory("syntax");
krk_startModule("<bim-themes>");
import_directory("themes");
/* Start context for command line */
krk_startModule("<bim-repl>");
/* Load bimrc */
load_bimrc();
krk_resetStack();
/* Start context for command line */
krk_startModule("<bim-repl>");
/* Initialize space for buffers */
buffers_avail = 4;
buffers = malloc(sizeof(buffer_t *) * buffers_avail);

47
apps/krk_test_noise.krk Executable file
View File

@ -0,0 +1,47 @@
#!/bin/kuroko
import os
if 'KUROKO_TEST_ENV' in os.environ:
return 0
from time import sleep
from fileio import open, stdin
from threading import Thread
let d = {}
let stop = False
for y in range(0x40):
for x in range(0x40):
d[(y,x)] = 0
class NoisePainter(Thread):
def run(self):
let myRando = open('/dev/urandom','rb')
while not stop:
let bytes = myRando.read(3)
let x = bytes[0] & 0x3F
let y = bytes[1] & 0x3F
d[(y,x)] = bytes[2]
let painters = [NoisePainter() for i in range(5)]
for painter in painters:
painter.start()
def drawScreen():
print("\[[H",end="")
for y in range(0x20):
for x in range(0x40):
let top = d[(y*2,x)]
let bottom = d[(y*2+1,x)]
print("\[[38","2",top,top,top,"48","2",bottom,bottom,bottom,sep=";",end="m▀")
print("\[[0m")
for i in range(5):
drawScreen()
stop = True
for painter in painters:
painter.join()
drawScreen()

View File

@ -11,6 +11,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#ifdef __toaru__
#include <toaru/rline.h>
@ -33,13 +34,13 @@
static int enableRline = 1;
static int exitRepl = 0;
static KrkValue exitFunc(int argc, KrkValue argv[]) {
static KrkValue exitFunc(int argc, KrkValue argv[], int hasKw) {
exitRepl = 1;
return NONE_VAL();
}
static int pasteEnabled = 0;
static KrkValue paste(int argc, KrkValue argv[]) {
static KrkValue paste(int argc, KrkValue argv[], int hasKw) {
pasteEnabled = !pasteEnabled;
fprintf(stderr, "Pasting is %s.\n", pasteEnabled ? "enabled" : "disabled");
return NONE_VAL();
@ -123,7 +124,7 @@ static void tab_complete_func(rline_context_t * c) {
if (n <= count) {
/* Now work forwards, starting from the current globals. */
KrkValue root = OBJECT_VAL(vm.module);
KrkValue root = OBJECT_VAL(krk_currentThread.module);
int isGlobal = 1;
while (n > base) {
/* And look at the potential fields for instances/classes */
@ -148,10 +149,10 @@ static void tab_complete_func(rline_context_t * c) {
int matchCount = 0;
/* Take the last symbol name from the chain and get its member list from dir() */
KRK_PAUSE_GC();
for (;;) {
KrkValue dirList = krk_dirObject(1,(KrkValue[]){root});
KrkValue dirList = krk_dirObject(1,(KrkValue[]){root},0);
krk_push(dirList);
if (!IS_INSTANCE(dirList)) {
fprintf(stderr,"\nInternal error while tab completting.\n");
goto _cleanup;
@ -159,13 +160,17 @@ static void tab_complete_func(rline_context_t * c) {
for (size_t i = 0; i < AS_LIST(dirList)->count; ++i) {
KrkString * s = AS_STRING(AS_LIST(dirList)->values[i]);
krk_push(OBJECT_VAL(s));
KrkToken asToken = {.start = s->chars, .literalWidth = s->length};
KrkValue thisValue = findFromProperty(root, asToken);
krk_push(thisValue);
if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) ||
(IS_NATIVE(thisValue) && ((KrkNative*)AS_OBJECT(thisValue))->isMethod != 2)) {
char * tmp = malloc(s->length + 2);
sprintf(tmp, "%s(", s->chars);
s = krk_takeString(tmp, strlen(tmp));
krk_pop();
krk_push(OBJECT_VAL(s));
}
/* If this symbol is shorter than the current submatch, skip it. */
@ -192,16 +197,17 @@ static void tab_complete_func(rline_context_t * c) {
* If the object we were scanning was the current module,
* then we should also throw the builtins into the ring.
*/
if (isGlobal && AS_OBJECT(root) == (KrkObj*)vm.module) {
if (isGlobal && AS_OBJECT(root) == (KrkObj*)krk_currentThread.module) {
root = OBJECT_VAL(vm.builtins);
continue;
} else if (isGlobal && AS_OBJECT(root) == (KrkObj*)vm.builtins) {
extern char * syn_krk_keywords[];
KrkInstance * fakeKeywordsObject = krk_newInstance(vm.objectClass);
KrkInstance * fakeKeywordsObject = krk_newInstance(vm.baseClasses->objectClass);
root = OBJECT_VAL(fakeKeywordsObject);
krk_push(root);
for (char ** keyword = syn_krk_keywords; *keyword; keyword++) {
krk_attachNamedValue(&fakeKeywordsObject->fields, *keyword, NONE_VAL());
}
root = OBJECT_VAL(fakeKeywordsObject);
continue;
} else {
break;
@ -262,15 +268,15 @@ _toomany:
_cleanup:
free(tmp);
free(space);
KRK_RESUME_GC();
krk_resetStack();
return;
}
}
#endif
static void handleSigint(int sigNum) {
if (vm.frameCount) {
krk_runtimeError(vm.exceptions.keyboardInterrupt, "Keyboard interrupt.");
if (krk_currentThread.frameCount) {
krk_runtimeError(vm.exceptions->keyboardInterrupt, "Keyboard interrupt.");
}
signal(sigNum, handleSigint);
@ -282,7 +288,7 @@ static void findInterpreter(char * argv[]) {
#else
/* Try asking /proc */
char * binpath = realpath("/proc/self/exe", NULL);
if (!binpath) {
if (!binpath || (access(binpath, X_OK) != 0)) {
if (strchr(argv[0], '/')) {
binpath = realpath(argv[0], NULL);
} else {
@ -295,7 +301,7 @@ static void findInterpreter(char * argv[]) {
char tmp[4096];
sprintf(tmp, "%s/%s", path, argv[0]);
if (access(tmp, X_OK)) {
if (access(tmp, X_OK) == 0) {
binpath = strdup(tmp);
break;
}
@ -310,14 +316,57 @@ static void findInterpreter(char * argv[]) {
#endif
}
static int runString(char * argv[], char * string) {
static int runString(char * argv[], int flags, char * string) {
findInterpreter(argv);
krk_initVM(0);
krk_initVM(flags);
krk_startModule("__main__");
krk_interpret(string, 1, "<stdin>","<stdin>");
krk_freeVM();
return 0;
}
/* This isn't normally exposed. */
extern KrkFunction * krk_compile(const char * src, int newScope, char * fileName);
static int compileFile(char * argv[], int flags, char * fileName) {
findInterpreter(argv);
krk_initVM(flags);
/* Open the file. */
FILE * f = fopen(fileName,"r");
if (!f) {
fprintf(stderr, "%s: could not read file '%s': %s\n", argv[0], fileName, strerror(errno));
return 1;
}
/* Read it like we normally do... */
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
char * buf = malloc(size+1);
if (fread(buf, 1, size, f) != size) return 2;
fclose(f);
buf[size] = '\0';
/* Set up a module scope */
krk_startModule("__main__");
/* Call the compiler directly. */
KrkFunction * func = krk_compile(buf, 0, fileName);
/* See if there was an exception. */
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
krk_dumpTraceback();
}
/* Free the source string */
free(buf);
/* Close out the compiler */
krk_freeVM();
return func == NULL;
}
#ifdef BUNDLE_LIBS
#define BUNDLED(name) do { \
extern KrkValue krk_module_onload_ ## name (); \
@ -332,10 +381,10 @@ int main(int argc, char * argv[]) {
int flags = 0;
int moduleAsMain = 0;
int opt;
while ((opt = getopt(argc, argv, "c:dgm:rstMV-:")) != -1) {
while ((opt = getopt(argc, argv, "+c:C:dgm:rstMV-:")) != -1) {
switch (opt) {
case 'c':
return runString(argv, optarg);
return runString(argv, flags, optarg);
case 'd':
/* Disassemble code blocks after compilation. */
flags |= KRK_ENABLE_DISASSEMBLY;
@ -360,12 +409,14 @@ int main(int argc, char * argv[]) {
enableRline = 0;
break;
case 'M':
return runString(argv,"import kuroko; print(kuroko.module_paths)\n");
return runString(argv,0,"import kuroko; print(kuroko.module_paths)\n");
case 'V':
return runString(argv,"import kuroko; print('Kuroko',kuroko.version)\n");
return runString(argv,0,"import kuroko; print('Kuroko',kuroko.version)\n");
case 'C':
return compileFile(argv,flags,optarg);
case '-':
if (!strcmp(optarg,"version")) {
return runString(argv,"import kuroko; print('Kuroko',kuroko.version)\n");
return runString(argv,0,"import kuroko; print('Kuroko',kuroko.version)\n");
} else if (!strcmp(optarg,"help")) {
fprintf(stderr,"usage: %s [flags] [FILE...]\n"
"\n"
@ -376,6 +427,8 @@ int main(int argc, char * argv[]) {
" -r Disable complex line editing in the REPL.\n"
" -s Debug output from the scanner/tokenizer.\n"
" -t Disassemble instructions as they are exceuted.\n"
" -C file Compile 'file', but do not execute it.\n"
" -M Print the default module import paths.\n"
" -V Print version information.\n"
"\n"
" --version Print version information.\n"
@ -401,7 +454,7 @@ _finishArgs:
for (int arg = optind; arg < argc; ++arg) {
krk_push(OBJECT_VAL(krk_copyString(argv[arg],strlen(argv[arg]))));
}
KrkValue argList = krk_list_of(argc - optind + (optind == argc), &vm.stackTop[-(argc - optind + (optind == argc))]);
KrkValue argList = krk_list_of(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))],0);
krk_push(argList);
krk_attachNamedValue(&vm.system->fields, "argv", argList);
krk_pop();
@ -432,7 +485,7 @@ _finishArgs:
AS_STRING(AS_LIST(argList)->values[0]),
&module,
AS_STRING(krk_peek(0)));
if (vm.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
krk_dumpTraceback();
krk_resetStack();
}
@ -445,7 +498,7 @@ _finishArgs:
/* The repl runs in the context of a top-level module so each input
* line can share a globals state with the others. */
krk_startModule("<module>");
krk_attachNamedValue(&vm.module->fields,"__doc__", NONE_VAL());
krk_attachNamedValue(&krk_currentThread.module->fields,"__doc__", NONE_VAL());
#ifndef NO_RLINE
/* Set ^D to send EOF */
@ -646,6 +699,7 @@ _finishArgs:
(void)blockWidth;
}
} else {
krk_startModule("__main__");
result = krk_runfile(argv[optind],1,"__main__",argv[optind]);
}

2
kuroko

@ -1 +1 @@
Subproject commit 4eceb98ffed5c49f57d362887134613a2c6733ba
Subproject commit 6a95c4a97921e9aa76fda65e1f289428dd95e4b2

View File

@ -94,7 +94,7 @@ static KrkClass * MenuEntrySeparatorClass;
* handling stack push/pop to keep things from being prematurely GC'd.
*/
KrkClass * krk_createClass(KrkInstance * inModule, const char * name, KrkClass * base) {
if (!base) base = vm.objectClass;
if (!base) base = vm.baseClasses->objectClass;
KrkString * str_Name = krk_copyString(name, strlen(name));
krk_push(OBJECT_VAL(str_Name));
KrkClass * obj_Class = krk_newClass(str_Name, base);
@ -122,7 +122,7 @@ 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[], int hasKw) {
assert(argc == 2);
KrkInstance * self = AS_INSTANCE(argv[0]);
@ -203,7 +203,7 @@ static KrkValue _message_getattr(int argc, KrkValue argv[]) {
} break;
}
krk_runtimeError(vm.exceptions.attributeError, "no attribute '%s'", AS_CSTRING(argv[1]));
krk_runtimeError(vm.exceptions->attributeError, "no attribute '%s'", AS_CSTRING(argv[1]));
return NONE_VAL();
}
#undef DO_FIELD
@ -212,7 +212,7 @@ static KrkValue _message_getattr(int argc, KrkValue argv[]) {
#undef TO_INT
#undef WID
static KrkValue _yutani_repr(int argc, KrkValue argv[]) {
static KrkValue _yutani_repr(int argc, KrkValue argv[], int hasKw) {
struct YutaniClass * self = (struct YutaniClass*)AS_INSTANCE(argv[0]);
char out[500];
size_t len = sprintf(out, "Yutani(fd=%d,server=%s,display_width=%d,display_height=%d)",
@ -225,7 +225,7 @@ static KrkValue _yutani_repr(int argc, KrkValue argv[]) {
static KrkValue _yutani_init(int argc, KrkValue argv[], int hasKw) {
if (yctxInstance) {
krk_runtimeError(vm.exceptions.valueError, "class 'Yutani' is a singleton and has already been initialized.");
krk_runtimeError(vm.exceptions->valueError, "class 'Yutani' is a singleton and has already been initialized.");
return NONE_VAL();
}
@ -234,7 +234,7 @@ static KrkValue _yutani_init(int argc, KrkValue argv[], int hasKw) {
/* Connect and let's go. */
yutani_t * yctx = yutani_init();
if (!yctx) {
krk_runtimeError(vm.exceptions.ioError, "Failed to connect to compositor.");
krk_runtimeError(vm.exceptions->ioError, "Failed to connect to compositor.");
return NONE_VAL();
}
@ -249,15 +249,15 @@ static KrkValue _yutani_init(int argc, KrkValue argv[], int hasKw) {
#define CHECK_YUTANI() \
if (argc < 1 || !krk_isInstanceOf(argv[0], Yutani)) \
return krk_runtimeError(vm.exceptions.typeError, "expected Yutani"); \
return krk_runtimeError(vm.exceptions->typeError, "expected Yutani"); \
struct YutaniClass * self = (struct YutaniClass*)AS_INSTANCE(argv[0])
static KrkValue _yutani_display_width(int argc, KrkValue argv[]) {
static KrkValue _yutani_display_width(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
return INTEGER_VAL(self->yctx->display_width);
}
static KrkValue _yutani_display_height(int argc, KrkValue argv[]) {
static KrkValue _yutani_display_height(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
return INTEGER_VAL(self->yctx->display_height);
}
@ -283,9 +283,9 @@ static KrkValue _yutani_poll(int argc, KrkValue argv[], int hasKw) {
return krk_pop();
}
static KrkValue _yutani_wait_for(int argc, KrkValue argv[]) {
static KrkValue _yutani_wait_for(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
if (argc != 2 || !IS_INTEGER(argv[1])) { krk_runtimeError(vm.exceptions.argumentError, "expected int for msgtype"); return NONE_VAL(); }
if (argc != 2 || !IS_INTEGER(argv[1])) { krk_runtimeError(vm.exceptions->argumentError, "expected int for msgtype"); return NONE_VAL(); }
yutani_msg_t * result = yutani_wait_for(self->yctx, AS_INTEGER(argv[1]));
KrkInstance * out = krk_newInstance(Message);
krk_push(OBJECT_VAL(out));
@ -295,38 +295,38 @@ static KrkValue _yutani_wait_for(int argc, KrkValue argv[]) {
return krk_pop();
}
static KrkValue _yutani_subscribe(int argc, KrkValue argv[]) {
static KrkValue _yutani_subscribe(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
yutani_subscribe_windows(self->yctx);
return NONE_VAL();
}
static KrkValue _yutani_unsubscribe(int argc, KrkValue argv[]) {
static KrkValue _yutani_unsubscribe(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
yutani_unsubscribe_windows(self->yctx);
return NONE_VAL();
}
static KrkValue _yutani_query_windows(int argc, KrkValue argv[]) {
static KrkValue _yutani_query_windows(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
yutani_query_windows(self->yctx);
return NONE_VAL();
}
static KrkValue _yutani_fileno(int argc, KrkValue argv[]) {
static KrkValue _yutani_fileno(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
return INTEGER_VAL(fileno(self->yctx->sock));
}
static KrkValue _yutani_query(int argc, KrkValue argv[]) {
static KrkValue _yutani_query(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
return INTEGER_VAL(yutani_query(self->yctx));
}
static KrkValue _yutani_menu_process_event(int argc, KrkValue argv[]) {
static KrkValue _yutani_menu_process_event(int argc, KrkValue argv[], int hasKw) {
CHECK_YUTANI();
if (argc < 2 || !krk_isInstanceOf(argv[1],Message))
return krk_runtimeError(vm.exceptions.typeError, "expected Message");
return krk_runtimeError(vm.exceptions->typeError, "expected Message");
struct MessageClass* msg = (struct MessageClass*)AS_INSTANCE(argv[1]);
return INTEGER_VAL(menu_process_event(self->yctx, msg->msg));
@ -335,18 +335,18 @@ static KrkValue _yutani_menu_process_event(int argc, KrkValue argv[]) {
#define GET_ARG(p,name,type) do { \
if (hasKw && krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S(#name)), &name)) { \
if (!krk_isInstanceOf(name,type)) \
return krk_runtimeError(vm.exceptions.typeError, #name " argument should be " #type ", not '%s'", krk_typeName(name)); \
return krk_runtimeError(vm.exceptions->typeError, #name " argument should be " #type ", not '%s'", krk_typeName(name)); \
} else if (argc > p) { \
name = argv[p]; \
if (!krk_isInstanceOf(name,type)) \
return krk_runtimeError(vm.exceptions.typeError, #name " argument should be " #type ", not '%s'", krk_typeName(name)); \
return krk_runtimeError(vm.exceptions->typeError, #name " argument should be " #type ", not '%s'", krk_typeName(name)); \
} \
} while (0)
#define GFX_PROPERTY(name) \
static KrkValue _gfx_ ## name (int argc, KrkValue argv[]) { \
static KrkValue _gfx_ ## name (int argc, KrkValue argv[], int hasKw) { \
if (argc != 1 || !krk_isInstanceOf(argv[0], GraphicsContext)) \
return krk_runtimeError(vm.exceptions.typeError, "Expected GraphicsContext"); \
return krk_runtimeError(vm.exceptions->typeError, "Expected GraphicsContext"); \
struct GraphicsContext * self = (struct GraphicsContext *)AS_INSTANCE(argv[0]); \
return INTEGER_VAL(self->ctx-> name); \
}
@ -356,19 +356,19 @@ GFX_PROPERTY(height);
#define CHECK_GFX() \
if (argc < 1 || !krk_isInstanceOf(argv[0], GraphicsContext)) \
return krk_runtimeError(vm.exceptions.typeError, "expected GraphicsContext"); \
return krk_runtimeError(vm.exceptions->typeError, "expected GraphicsContext"); \
struct GraphicsContext * self = (struct GraphicsContext*)AS_INSTANCE(argv[0])
static KrkValue _gfx_fill(int argc, KrkValue argv[]) {
static KrkValue _gfx_fill(int argc, KrkValue argv[], int hasKw) {
CHECK_GFX();
if (argc < 2 || !krk_isInstanceOf(argv[1], YutaniColor))
return krk_runtimeError(vm.exceptions.typeError, "fill() takes one color() argument");
return krk_runtimeError(vm.exceptions->typeError, "fill() takes one color() argument");
struct YutaniColor * color = (struct YutaniColor*)AS_INSTANCE(argv[1]);
draw_fill(self->ctx, color->color);
return NONE_VAL();
}
static KrkValue _gfx_flip(int argc, KrkValue argv[]) {
static KrkValue _gfx_flip(int argc, KrkValue argv[], int hasKw) {
CHECK_GFX();
if (self->doubleBuffered) {
flip(self->ctx);
@ -376,16 +376,16 @@ static KrkValue _gfx_flip(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _gfx_blur(int argc, KrkValue argv[]) {
static KrkValue _gfx_blur(int argc, KrkValue argv[], int hasKw) {
CHECK_GFX();
int radius = 2;
if (argc > 1 && IS_INTEGER(argv[1])) radius = AS_INTEGER(argv[1]);
else if (argc > 1) return krk_runtimeError(vm.exceptions.typeError, "expected int");
else if (argc > 1) return krk_runtimeError(vm.exceptions->typeError, "expected int");
blur_context_box(self->ctx, radius);
return NONE_VAL();
}
static KrkValue _gfx_line(int argc, KrkValue argv[]) {
static KrkValue _gfx_line(int argc, KrkValue argv[], int hasKw) {
CHECK_GFX();
if (argc < 6 ||
!IS_INTEGER(argv[1]) ||
@ -393,7 +393,7 @@ static KrkValue _gfx_line(int argc, KrkValue argv[]) {
!IS_INTEGER(argv[3]) ||
!IS_INTEGER(argv[4]) ||
!krk_isInstanceOf(argv[5], YutaniColor)) {
return krk_runtimeError(vm.exceptions.typeError, "line() expects 4 ints and a color");
return krk_runtimeError(vm.exceptions->typeError, "line() expects 4 ints and a color");
}
int32_t x0 = AS_INTEGER(argv[1]);
@ -408,7 +408,7 @@ static KrkValue _gfx_line(int argc, KrkValue argv[]) {
} else if (IS_FLOATING(argv[6])) {
draw_line_aa(self->ctx,x0,x1,y0,y1,color->color,AS_FLOATING(argv[6]));
} else {
return krk_runtimeError(vm.exceptions.typeError, "thickness must be int or float, not '%s'", krk_typeName(argv[6]));
return krk_runtimeError(vm.exceptions->typeError, "thickness must be int or float, not '%s'", krk_typeName(argv[6]));
}
} else {
draw_line(self->ctx,x0,x1,y0,y1,color->color);
@ -426,7 +426,7 @@ static KrkValue _gfx_rect(int argc, KrkValue argv[], int hasKw) {
!IS_INTEGER(argv[3]) ||
!IS_INTEGER(argv[4]) ||
!krk_isInstanceOf(argv[5], YutaniColor)) {
return krk_runtimeError(vm.exceptions.typeError, "rect() expects 4 ints and a color");
return krk_runtimeError(vm.exceptions->typeError, "rect() expects 4 ints and a color");
}
int32_t x = AS_INTEGER(argv[1]);
@ -442,11 +442,11 @@ static KrkValue _gfx_rect(int argc, KrkValue argv[], int hasKw) {
}
if (!IS_BOOLEAN(solid))
return krk_runtimeError(vm.exceptions.typeError, "solid must be bool");
return krk_runtimeError(vm.exceptions->typeError, "solid must be bool");
if (!IS_NONE(radius) && !IS_INTEGER(radius))
return krk_runtimeError(vm.exceptions.typeError, "radius must be int");
return krk_runtimeError(vm.exceptions->typeError, "radius must be int");
if (!IS_NONE(radius) && AS_BOOLEAN(solid))
return krk_runtimeError(vm.exceptions.typeError, "radius and solid can not be used together");
return krk_runtimeError(vm.exceptions->typeError, "radius and solid can not be used together");
if (AS_BOOLEAN(solid)) {
draw_rectangle_solid(self->ctx, x, y, width, height, color->color);
@ -463,10 +463,10 @@ static KrkValue _gfx_draw_sprite(int argc, KrkValue argv[], int hasKw) {
CHECK_GFX();
if (argc < 2 || !krk_isInstanceOf(argv[1], YutaniSprite))
return krk_runtimeError(vm.exceptions.typeError, "expected Sprite");
return krk_runtimeError(vm.exceptions->typeError, "expected Sprite");
if (argc < 4 || !IS_INTEGER(argv[2]) || !IS_INTEGER(argv[3]))
return krk_runtimeError(vm.exceptions.typeError, "expected integer coordinate pair");
return krk_runtimeError(vm.exceptions->typeError, "expected integer coordinate pair");
/* Potential kwargs: rotation:float, alpha:float, scale:(int,int)... */
KrkValue rotation = NONE_VAL(), alpha = NONE_VAL(), scale=NONE_VAL(), color=NONE_VAL();
@ -478,17 +478,17 @@ static KrkValue _gfx_draw_sprite(int argc, KrkValue argv[], int hasKw) {
}
if (!IS_NONE(alpha) && !IS_FLOATING(alpha))
return krk_runtimeError(vm.exceptions.typeError, "alpha must be float");
return krk_runtimeError(vm.exceptions->typeError, "alpha must be float");
if (!IS_NONE(rotation) && !IS_FLOATING(rotation))
return krk_runtimeError(vm.exceptions.typeError, "rotation must be float");
return krk_runtimeError(vm.exceptions->typeError, "rotation must be float");
if (!IS_NONE(color) && !krk_isInstanceOf(color,YutaniColor))
return krk_runtimeError(vm.exceptions.typeError, "color must be color");
return krk_runtimeError(vm.exceptions->typeError, "color must be color");
if (!IS_NONE(scale) && (!IS_TUPLE(scale) || AS_TUPLE(scale)->values.count != 2 ||
!IS_INTEGER(AS_TUPLE(scale)->values.values[0]) ||
!IS_INTEGER(AS_TUPLE(scale)->values.values[1])))
return krk_runtimeError(vm.exceptions.typeError, "scale must be 2-tuple of ints");
return krk_runtimeError(vm.exceptions->typeError, "scale must be 2-tuple of ints");
if (!IS_NONE(rotation) + !IS_NONE(scale) + !IS_NONE(color) > 1)
return krk_runtimeError(vm.exceptions.typeError, "can not combine rotation / scale / color");
return krk_runtimeError(vm.exceptions->typeError, "can not combine rotation / scale / color");
if ((!IS_NONE(rotation) || !IS_NONE(color)) && IS_NONE(alpha))
alpha = FLOATING_VAL(1.0);
@ -526,7 +526,7 @@ static void _sprite_sweep(KrkInstance * self) {
if (sprite->ctx) free(sprite->ctx);
}
static KrkValue _sprite_repr(int argc, KrkValue argv[]) {
static KrkValue _sprite_repr(int argc, KrkValue argv[], int hasKw) {
struct YutaniSprite * self = (struct YutaniSprite *)AS_INSTANCE(argv[0]);
KrkValue file;
@ -540,18 +540,18 @@ static KrkValue _sprite_repr(int argc, KrkValue argv[]) {
return OBJECT_VAL(krk_copyString(out,len));
}
static KrkValue _sprite_init(int argc, KrkValue argv[]) {
static KrkValue _sprite_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], YutaniSprite))
return krk_runtimeError(vm.exceptions.typeError, "expected sprite");
return krk_runtimeError(vm.exceptions->typeError, "expected sprite");
if (argc < 2 || !IS_STRING(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "Sprite() takes one str argument");
return krk_runtimeError(vm.exceptions->typeError, "Sprite() takes one str argument");
struct YutaniSprite * self = (struct YutaniSprite*)AS_INSTANCE(argv[0]);
int result = load_sprite(&self->sprite, AS_CSTRING(argv[1]));
if (result) {
return krk_runtimeError(vm.exceptions.ioError, "Sprite() could not be initialized");
return krk_runtimeError(vm.exceptions->ioError, "Sprite() could not be initialized");
}
self->ctx = init_graphics_sprite(&self->sprite);
@ -562,11 +562,11 @@ static KrkValue _sprite_init(int argc, KrkValue argv[]) {
#define CHECK_WINDOW() \
if (argc < 1 || !krk_isInstanceOf(argv[0], YutaniWindow)) \
return krk_runtimeError(vm.exceptions.typeError, "expected Window"); \
return krk_runtimeError(vm.exceptions->typeError, "expected Window"); \
struct WindowClass * self = (struct WindowClass*)AS_INSTANCE(argv[0]); \
if (!self->window) return krk_runtimeError(vm.exceptions.valueError, "Window is closed")
if (!self->window) return krk_runtimeError(vm.exceptions->valueError, "Window is closed")
static KrkValue _window_repr(int argc, KrkValue argv[]) {
static KrkValue _window_repr(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
KrkValue title;
krk_tableGet(&self->inst.fields, OBJECT_VAL(S("title")), &title);
@ -580,12 +580,12 @@ static KrkValue _window_repr(int argc, KrkValue argv[]) {
}
static KrkValue _window_init(int argc, KrkValue argv[], int hasKw) {
if (!yctxInstance) return krk_runtimeError(vm.exceptions.valueError, "Compositor is not initialized");
if (!yctxInstance) return krk_runtimeError(vm.exceptions->valueError, "Compositor is not initialized");
if (argc < 1 || !krk_isInstanceOf(argv[0], YutaniWindow))
return krk_runtimeError(vm.exceptions.typeError, "Failed to initialize window");
return krk_runtimeError(vm.exceptions->typeError, "Failed to initialize window");
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.argumentError, "Expected at least two (integer) arguments (width, height)");
return krk_runtimeError(vm.exceptions->argumentError, "Expected at least two (integer) arguments (width, height)");
KrkInstance * _self = AS_INSTANCE(argv[0]);
struct WindowClass * self = (struct WindowClass*)_self;
@ -593,10 +593,10 @@ static KrkValue _window_init(int argc, KrkValue argv[], int hasKw) {
krk_integer_type height = AS_INTEGER(argv[2]);
KrkValue flags = INTEGER_VAL(0), title = NONE_VAL(), icon = NONE_VAL(), doublebuffer = BOOLEAN_VAL(0);
GET_ARG(3, flags, vm.baseClasses.intClass);
GET_ARG(4, title, vm.baseClasses.strClass);
GET_ARG(5, icon, vm.baseClasses.strClass);
GET_ARG(6, doublebuffer, vm.baseClasses.boolClass);
GET_ARG(3, flags, vm.baseClasses->intClass);
GET_ARG(4, title, vm.baseClasses->strClass);
GET_ARG(5, icon, vm.baseClasses->strClass);
GET_ARG(6, doublebuffer, vm.baseClasses->boolClass);
self->window = yutani_window_create_flags(((struct YutaniClass*)yctxInstance)->yctx,
width, height, AS_INTEGER(flags));
@ -624,7 +624,7 @@ static KrkValue _window_init(int argc, KrkValue argv[], int hasKw) {
return argv[0];
}
static KrkValue _window_flip(int argc, KrkValue argv[]) {
static KrkValue _window_flip(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (self->doubleBuffered) {
flip(self->ctx);
@ -633,23 +633,23 @@ static KrkValue _window_flip(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _window_move(int argc, KrkValue argv[]) {
static KrkValue _window_move(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected two integer arguments");
return krk_runtimeError(vm.exceptions->typeError, "expected two integer arguments");
yutani_window_move(((struct YutaniClass*)yctxInstance)->yctx, self->window, AS_INTEGER(argv[1]), AS_INTEGER(argv[2]));
return NONE_VAL();
}
static KrkValue _window_set_focused(int argc, KrkValue argv[]) {
static KrkValue _window_set_focused(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_INTEGER(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected integer argument");
return krk_runtimeError(vm.exceptions->typeError, "expected integer argument");
self->window->focused = AS_INTEGER(argv[1]);
return NONE_VAL();
}
static KrkValue _window_close(int argc, KrkValue argv[]) {
static KrkValue _window_close(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
yutani_close(((struct YutaniClass*)yctxInstance)->yctx, self->window);
self->window = NULL;
@ -658,90 +658,90 @@ static KrkValue _window_close(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _window_set_stack(int argc, KrkValue argv[]) {
static KrkValue _window_set_stack(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions.typeError, "expected int for z-order");
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected int for z-order");
int z = AS_INTEGER(argv[1]);
yutani_set_stack(((struct YutaniClass*)yctxInstance)->yctx, self->window, z);
return NONE_VAL();
}
static KrkValue _window_update_shape(int argc, KrkValue argv[]) {
static KrkValue _window_update_shape(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions.typeError, "expected int for shape specifier");
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected int for shape specifier");
int set_shape = AS_INTEGER(argv[1]);
yutani_window_update_shape(((struct YutaniClass*)yctxInstance)->yctx, self->window, set_shape);
return NONE_VAL();
}
static KrkValue _window_warp_mouse(int argc, KrkValue argv[]) {
static KrkValue _window_warp_mouse(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected two int values for x, y");
return krk_runtimeError(vm.exceptions->typeError, "expected two int values for x, y");
int32_t x = AS_INTEGER(argv[1]);
int32_t y = AS_INTEGER(argv[2]);
yutani_window_warp_mouse(((struct YutaniClass*)yctxInstance)->yctx, self->window, x, y);
return NONE_VAL();
}
static KrkValue _window_show_mouse(int argc, KrkValue argv[]) {
static KrkValue _window_show_mouse(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions.typeError, "expected int for show_mouse");
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected int for show_mouse");
int show_mouse = AS_INTEGER(argv[1]);
yutani_window_show_mouse(((struct YutaniClass*)yctxInstance)->yctx, self->window, show_mouse);
return NONE_VAL();
}
static KrkValue _window_resize_start(int argc, KrkValue argv[]) {
static KrkValue _window_resize_start(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions.typeError, "expected int for direction");
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected int for direction");
yutani_scale_direction_t direction = AS_INTEGER(argv[1]);
yutani_window_resize_start(((struct YutaniClass*)yctxInstance)->yctx, self->window, direction);
return NONE_VAL();
}
static KrkValue _window_resize(int argc, KrkValue argv[]) {
static KrkValue _window_resize(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected two int values for width, height");
return krk_runtimeError(vm.exceptions->typeError, "expected two int values for width, height");
uint32_t width = AS_INTEGER(argv[1]);
uint32_t height = AS_INTEGER(argv[2]);
yutani_window_resize(((struct YutaniClass*)yctxInstance)->yctx, self->window, width, height);
return NONE_VAL();
}
static KrkValue _window_resize_offer(int argc, KrkValue argv[]) {
static KrkValue _window_resize_offer(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected two int values for width, height");
return krk_runtimeError(vm.exceptions->typeError, "expected two int values for width, height");
uint32_t width = AS_INTEGER(argv[1]);
uint32_t height = AS_INTEGER(argv[2]);
yutani_window_resize_offer(((struct YutaniClass*)yctxInstance)->yctx, self->window, width, height);
return NONE_VAL();
}
static KrkValue _window_resize_accept(int argc, KrkValue argv[]) {
static KrkValue _window_resize_accept(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected two int values for width, height");
return krk_runtimeError(vm.exceptions->typeError, "expected two int values for width, height");
uint32_t width = AS_INTEGER(argv[1]);
uint32_t height = AS_INTEGER(argv[2]);
yutani_window_resize_accept(((struct YutaniClass*)yctxInstance)->yctx, self->window, width, height);
return NONE_VAL();
}
static KrkValue _window_resize_done(int argc, KrkValue argv[]) {
static KrkValue _window_resize_done(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
yutani_window_resize_done(((struct YutaniClass*)yctxInstance)->yctx, self->window);
return NONE_VAL();
}
static KrkValue _window_advertise(int argc, KrkValue argv[]) {
static KrkValue _window_advertise(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_STRING(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected string for title");
return krk_runtimeError(vm.exceptions->typeError, "expected string for title");
if (argc > 2 && !IS_STRING(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected string for icon");
return krk_runtimeError(vm.exceptions->typeError, "expected string for icon");
if (argc > 2) {
yutani_window_advertise_icon(((struct YutaniClass*)yctxInstance)->yctx, self->window, AS_CSTRING(argv[1]), AS_CSTRING(argv[2]));
@ -751,24 +751,24 @@ static KrkValue _window_advertise(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _window_special_request(int argc, KrkValue argv[]) {
static KrkValue _window_special_request(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions.typeError, "expected int for request");
if (argc < 2 || !IS_INTEGER(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected int for request");
uint32_t request = AS_INTEGER(argv[1]);
yutani_special_request(((struct YutaniClass*)yctxInstance)->yctx, self->window, request);
return NONE_VAL();
}
static KrkValue _window_reinit(int argc, KrkValue argv[]) {
static KrkValue _window_reinit(int argc, KrkValue argv[], int hasKw) {
CHECK_WINDOW();
reinit_graphics_yutani(self->ctx, self->window);
return NONE_VAL();
}
#define WINDOW_PROPERTY(name) \
static KrkValue _window_ ## name (int argc, KrkValue argv[]) { \
static KrkValue _window_ ## name (int argc, KrkValue argv[], int hasKw) { \
if (argc != 1 || !krk_isInstanceOf(argv[0], YutaniWindow)) \
return krk_runtimeError(vm.exceptions.typeError, "Expected Window"); \
return krk_runtimeError(vm.exceptions->typeError, "Expected Window"); \
struct WindowClass * self = (struct WindowClass*)AS_INSTANCE(argv[0]); \
return INTEGER_VAL(self->window-> name); \
}
@ -778,39 +778,38 @@ WINDOW_PROPERTY(x);
WINDOW_PROPERTY(y);
WINDOW_PROPERTY(focused);
static KrkValue _decor_get_bounds(int argc, KrkValue argv[]) {
static KrkValue _decor_get_bounds(int argc, KrkValue argv[], int hasKw) {
if (argc > 0 && !krk_isInstanceOf(argv[0], YutaniWindow))
return krk_runtimeError(vm.exceptions.typeError, "expected window");
return krk_runtimeError(vm.exceptions->typeError, "expected window");
struct decor_bounds bounds;
decor_get_bounds((argc > 0) ? ((struct WindowClass*)AS_INSTANCE(argv[0]))->window : NULL,
&bounds);
KRK_PAUSE_GC();
KrkValue result = krk_dict_of(0, NULL, 0);
krk_push(result);
KrkValue result = krk_dict_of(6 * 2, (KrkValue[]) {
OBJECT_VAL(S("top_height")), INTEGER_VAL(bounds.top_height),
OBJECT_VAL(S("bottom_height")), INTEGER_VAL(bounds.bottom_height),
OBJECT_VAL(S("left_width")), INTEGER_VAL(bounds.left_width),
OBJECT_VAL(S("right_width")), INTEGER_VAL(bounds.right_width),
OBJECT_VAL(S("width")), INTEGER_VAL(bounds.width),
OBJECT_VAL(S("height")), INTEGER_VAL(bounds.height)
});
#define SET(val) krk_attachNamedValue(AS_DICT(result), #val, INTEGER_VAL(bounds. val));
KRK_RESUME_GC();
SET(top_height);
SET(bottom_height);
SET(left_width);
SET(right_width);
SET(width);
SET(height);
return result;
return krk_pop();
}
static KrkValue _decor_handle_event(int argc, KrkValue argv[]) {
static KrkValue _decor_handle_event(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], Message))
return krk_runtimeError(vm.exceptions.typeError, "expected message");
return krk_runtimeError(vm.exceptions->typeError, "expected message");
return INTEGER_VAL(decor_handle_event(((struct YutaniClass*)yctxInstance)->yctx, ((struct MessageClass*)AS_INSTANCE(argv[0]))->msg));
}
static KrkValue _decor_render(int argc, KrkValue argv[]) {
static KrkValue _decor_render(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], YutaniWindow))
return krk_runtimeError(vm.exceptions.typeError, "expected window");
return krk_runtimeError(vm.exceptions->typeError, "expected window");
char * title = (argc > 1 && IS_STRING(argv[1])) ? AS_CSTRING(argv[1]) : NULL;
if (title == NULL) {
KrkValue winTitle;
@ -825,11 +824,11 @@ static KrkValue _decor_render(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _decor_show_default_menu(int argc, KrkValue argv[]) {
static KrkValue _decor_show_default_menu(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], YutaniWindow))
return krk_runtimeError(vm.exceptions.typeError, "show_default_menu() expects Window");
return krk_runtimeError(vm.exceptions->typeError, "show_default_menu() expects Window");
if (argc < 3 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "show_default_menu() expects int coordinate pair");
return krk_runtimeError(vm.exceptions->typeError, "show_default_menu() expects int coordinate pair");
struct WindowClass * window = (void*)AS_INSTANCE(argv[0]);
int32_t x = AS_INTEGER(argv[1]);
@ -839,10 +838,10 @@ static KrkValue _decor_show_default_menu(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _yutani_color_init(int argc, KrkValue argv[]) {
static KrkValue _yutani_color_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 4 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]) || !IS_INTEGER(argv[3]) ||
(argc > 5) || (argc == 5 && !IS_INTEGER(argv[4]))) return krk_runtimeError(vm.exceptions.typeError, "color() expects three or four integer arguments");
if (!krk_isInstanceOf(argv[0], YutaniColor)) return krk_runtimeError(vm.exceptions.typeError, "expected color [__init__], not '%s'", krk_typeName(argv[0]));
(argc > 5) || (argc == 5 && !IS_INTEGER(argv[4]))) return krk_runtimeError(vm.exceptions->typeError, "color() expects three or four integer arguments");
if (!krk_isInstanceOf(argv[0], YutaniColor)) return krk_runtimeError(vm.exceptions->typeError, "expected color [__init__], not '%s'", krk_typeName(argv[0]));
struct YutaniColor * self = (struct YutaniColor*)AS_INSTANCE(argv[0]);
if (argc == 5) {
self->color = rgba(AS_INTEGER(argv[1]),AS_INTEGER(argv[2]),AS_INTEGER(argv[3]),AS_INTEGER(argv[4]));
@ -852,8 +851,8 @@ static KrkValue _yutani_color_init(int argc, KrkValue argv[]) {
return argv[0];
}
static KrkValue _yutani_color_repr(int argc, KrkValue argv[]) {
if (argc != 1 || !krk_isInstanceOf(argv[0], YutaniColor)) return krk_runtimeError(vm.exceptions.typeError, "expected color [__repr__], not '%s'", krk_typeName(argv[0]));
static KrkValue _yutani_color_repr(int argc, KrkValue argv[], int hasKw) {
if (argc != 1 || !krk_isInstanceOf(argv[0], YutaniColor)) return krk_runtimeError(vm.exceptions->typeError, "expected color [__repr__], not '%s'", krk_typeName(argv[0]));
struct YutaniColor * self = (struct YutaniColor*)AS_INSTANCE(argv[0]);
char tmp[30];
if (_ALP(self->color) != 255) {
@ -864,8 +863,8 @@ static KrkValue _yutani_color_repr(int argc, KrkValue argv[]) {
return OBJECT_VAL(krk_copyString(tmp,strlen(tmp)));
}
static KrkValue _yutani_color_str(int argc, KrkValue argv[]) {
if (argc != 1 || !krk_isInstanceOf(argv[0], YutaniColor)) return krk_runtimeError(vm.exceptions.typeError, "expected color [__str__], not '%s'", krk_typeName(argv[0]));
static KrkValue _yutani_color_str(int argc, KrkValue argv[], int hasKw) {
if (argc != 1 || !krk_isInstanceOf(argv[0], YutaniColor)) return krk_runtimeError(vm.exceptions->typeError, "expected color [__str__], not '%s'", krk_typeName(argv[0]));
struct YutaniColor * self = (struct YutaniColor*)AS_INSTANCE(argv[0]);
char tmp[30];
if (_ALP(self->color) != 255) {
@ -878,16 +877,16 @@ static KrkValue _yutani_color_str(int argc, KrkValue argv[]) {
#define CHECK_FONT() \
if (argc < 1 || !krk_isInstanceOf(argv[0], YutaniFont)) \
return krk_runtimeError(vm.exceptions.typeError, "expected Font"); \
return krk_runtimeError(vm.exceptions->typeError, "expected Font"); \
struct YutaniFont * self = (struct YutaniFont*)AS_INSTANCE(argv[0])
static KrkValue _font_init(int argc, KrkValue argv[], int hasKw) {
CHECK_FONT();
if (argc < 2 || !IS_INTEGER(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected int for font type");
return krk_runtimeError(vm.exceptions->typeError, "expected int for font type");
if (argc < 3 || !IS_INTEGER(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected int for font size");
return krk_runtimeError(vm.exceptions->typeError, "expected int for font size");
KrkValue fontGamma = FLOATING_VAL(1.7);
KrkValue fontStroke = FLOATING_VAL(0.75);
@ -896,9 +895,9 @@ static KrkValue _font_init(int argc, KrkValue argv[], int hasKw) {
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("gamma")), &fontGamma);
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("stroke")), &fontStroke);
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("color")), &fontColor);
if (!IS_FLOATING(fontGamma)) return krk_runtimeError(vm.exceptions.typeError, "expected float for gamma");
if (!IS_FLOATING(fontStroke)) return krk_runtimeError(vm.exceptions.typeError, "expected float for stroke");
if (!krk_isInstanceOf(fontColor, YutaniColor)) return krk_runtimeError(vm.exceptions.typeError, "expected color");
if (!IS_FLOATING(fontGamma)) return krk_runtimeError(vm.exceptions->typeError, "expected float for gamma");
if (!IS_FLOATING(fontStroke)) return krk_runtimeError(vm.exceptions->typeError, "expected float for stroke");
if (!krk_isInstanceOf(fontColor, YutaniColor)) return krk_runtimeError(vm.exceptions->typeError, "expected color");
}
self->fontType = AS_INTEGER(argv[1]);
@ -910,19 +909,19 @@ static KrkValue _font_init(int argc, KrkValue argv[], int hasKw) {
return argv[0];
}
static KrkValue _font_size(int argc, KrkValue argv[]) {
static KrkValue _font_size(int argc, KrkValue argv[], int hasKw) {
CHECK_FONT();
return INTEGER_VAL(self->fontSize);
}
static KrkValue _font_draw_string(int argc, KrkValue argv[]) {
static KrkValue _font_draw_string(int argc, KrkValue argv[], int hasKw) {
CHECK_FONT();
if (argc < 2 || !krk_isInstanceOf(argv[1], GraphicsContext))
return krk_runtimeError(vm.exceptions.typeError, "expected GraphicsContext");
return krk_runtimeError(vm.exceptions->typeError, "expected GraphicsContext");
if (argc < 3 || !IS_STRING(argv[2]))
return krk_runtimeError(vm.exceptions.typeError, "expected str");
return krk_runtimeError(vm.exceptions->typeError, "expected str");
if (argc < 5 || !IS_INTEGER(argv[3]) || !IS_INTEGER(argv[4]))
return krk_runtimeError(vm.exceptions.typeError, "expected int coordinate pair");
return krk_runtimeError(vm.exceptions->typeError, "expected int coordinate pair");
gfx_context_t * ctx = ((struct GraphicsContext*)AS_INSTANCE(argv[1]))->ctx;
const char * str = AS_CSTRING(argv[2]);
@ -932,10 +931,10 @@ static KrkValue _font_draw_string(int argc, KrkValue argv[]) {
return INTEGER_VAL(draw_sdf_string_stroke(ctx,x,y,str,self->fontSize,self->fontColor,self->fontType,self->fontGamma,self->fontStroke));
}
static KrkValue _font_width(int argc, KrkValue argv[]) {
static KrkValue _font_width(int argc, KrkValue argv[], int hasKw) {
CHECK_FONT();
if (argc < 2 || !IS_STRING(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected str");
return krk_runtimeError(vm.exceptions->typeError, "expected str");
const char * str = AS_CSTRING(argv[1]);
return INTEGER_VAL(draw_sdf_string_width(str, self->fontSize, self->fontType));
@ -961,11 +960,11 @@ static void _menubar_callback(struct menu_bar * _self) {
}
}
static KrkValue _MenuBar_init(int argc, KrkValue argv[]) {
static KrkValue _MenuBar_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuBarClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuBar");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuBar");
if (argc < 2 || !IS_TUPLE(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected tuple of tuples");
return krk_runtimeError(vm.exceptions->typeError, "expected tuple of tuples");
struct MenuBarClass * self = (struct MenuBarClass*)AS_INSTANCE(argv[0]);
self->menuBar.entries = malloc(sizeof(struct menu_bar_entries) * (AS_TUPLE(argv[1])->values.count + 1));
@ -974,7 +973,7 @@ static KrkValue _MenuBar_init(int argc, KrkValue argv[]) {
AS_TUPLE(AS_TUPLE(argv[1])->values.values[i])->values.count != 2 ||
!IS_STRING(AS_TUPLE(AS_TUPLE(argv[1])->values.values[i])->values.values[0]) ||
!IS_STRING(AS_TUPLE(AS_TUPLE(argv[1])->values.values[i])->values.values[1])) {
return krk_runtimeError(vm.exceptions.typeError, "invalid menu bar entry: expected (str,str) but %d is '%s'",
return krk_runtimeError(vm.exceptions->typeError, "invalid menu bar entry: expected (str,str) but %d is '%s'",
(int)i, krk_typeName(AS_TUPLE(argv[1])->values.values[i]));
}
@ -994,20 +993,20 @@ static KrkValue _MenuBar_init(int argc, KrkValue argv[]) {
krk_attachNamedValue(&self->inst.fields, "entries", argv[1]);
/* Give ourselves a dict to track the same information */
KrkValue dict = krk_dict_of(0,NULL);
KrkValue dict = krk_dict_of(0,NULL, 0);
krk_attachNamedValue(&self->inst.fields, "set", dict);
return argv[0];
}
static KrkValue _MenuBar_place(int argc, KrkValue argv[]) {
static KrkValue _MenuBar_place(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuBarClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuBar");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuBar");
struct MenuBarClass * self = (struct MenuBarClass*)AS_INSTANCE(argv[0]);
if (argc < 4 || !IS_INTEGER(argv[1]) || !IS_INTEGER(argv[2]) || !IS_INTEGER(argv[3]))
return krk_runtimeError(vm.exceptions.typeError, "expected int for x, y, width");
return krk_runtimeError(vm.exceptions->typeError, "expected int for x, y, width");
if (argc < 5 || !krk_isInstanceOf(argv[4],YutaniWindow))
return krk_runtimeError(vm.exceptions.typeError, "expected Window");
return krk_runtimeError(vm.exceptions->typeError, "expected Window");
self->menuBar.x = AS_INTEGER(argv[1]);
self->menuBar.y = AS_INTEGER(argv[2]);
@ -1016,23 +1015,23 @@ static KrkValue _MenuBar_place(int argc, KrkValue argv[]) {
return NONE_VAL();
}
static KrkValue _MenuBar_render(int argc, KrkValue argv[]) {
static KrkValue _MenuBar_render(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuBarClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuBar");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuBar");
struct MenuBarClass * self = (struct MenuBarClass*)AS_INSTANCE(argv[0]);
if (argc < 2 || !krk_isInstanceOf(argv[1], GraphicsContext))
return krk_runtimeError(vm.exceptions.typeError, "expected GraphicsContext");
return krk_runtimeError(vm.exceptions->typeError, "expected GraphicsContext");
menu_bar_render(&self->menuBar, ((struct GraphicsContext*)AS_INSTANCE(argv[1]))->ctx);
return NONE_VAL();
}
static KrkValue _MenuBar_mouse_event(int argc, KrkValue argv[]) {
static KrkValue _MenuBar_mouse_event(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuBarClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuBar");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuBar");
struct MenuBarClass * self = (struct MenuBarClass*)AS_INSTANCE(argv[0]);
if (argc < 3 || !krk_isInstanceOf(argv[1], YutaniWindow) ||
!krk_isInstanceOf(argv[2], Message))
return krk_runtimeError(vm.exceptions.typeError, "expected Window and Message");
return krk_runtimeError(vm.exceptions->typeError, "expected Window and Message");
struct MessageClass * msg = ((struct MessageClass*)AS_INSTANCE(argv[2]));
struct yutani_msg_window_mouse_event * me = (struct yutani_msg_window_mouse_event*)msg->msg->data;
@ -1042,44 +1041,44 @@ static KrkValue _MenuBar_mouse_event(int argc, KrkValue argv[]) {
&self->menuBar, me, me->new_x, me->new_y));
}
static KrkValue _MenuBar_insert(int argc, KrkValue argv[]) {
static KrkValue _MenuBar_insert(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuBarClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuBar");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuBar");
struct MenuBarClass * self = (struct MenuBarClass*)AS_INSTANCE(argv[0]);
if (argc < 3 || !IS_STRING(argv[1]) || !krk_isInstanceOf(argv[2], MenuListClass))
return krk_runtimeError(vm.exceptions.typeError, "expected str and MenuList");
return krk_runtimeError(vm.exceptions->typeError, "expected str and MenuList");
menu_set_insert(self->menuBar.set, AS_CSTRING(argv[1]), ((struct MenuListClass*)AS_INSTANCE(argv[2]))->menuList);
/* Also assign it to our dict */
KrkValue dict = NONE_VAL();
krk_tableGet(&self->inst.fields, OBJECT_VAL(S("set")), &dict);
if (IS_NONE(dict) || !krk_isInstanceOf(dict,vm.baseClasses.dictClass))
return krk_runtimeError(vm.exceptions.baseException, "Failed to get set entries?");
if (IS_NONE(dict) || !krk_isInstanceOf(dict,vm.baseClasses->dictClass))
return krk_runtimeError(vm.exceptions->baseException, "Failed to get set entries?");
krk_tableSet(AS_DICT(dict), argv[1], argv[2]);
return NONE_VAL();
}
static KrkValue _MenuList_init(int argc, KrkValue argv[]) {
static KrkValue _MenuList_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuListClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuList");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuList");
struct MenuListClass * self = (struct MenuListClass*)AS_INSTANCE(argv[0]);
self->menuList = menu_create();
/* Give us a list to put entries in for GC tracking and retrieval by kuroko code */
KrkValue list = krk_list_of(0,NULL);
KrkValue list = krk_list_of(0,NULL,0);
krk_attachNamedValue(&self->inst.fields, "entries", list);
return argv[0];
}
static KrkValue _MenuList_insert(int argc, KrkValue argv[]) {
static KrkValue _MenuList_insert(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuListClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuList");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuList");
struct MenuListClass * self = (struct MenuListClass*)AS_INSTANCE(argv[0]);
if (argc < 2 || !krk_isInstanceOf(argv[1], MenuEntryClass))
return krk_runtimeError(vm.exceptions.typeError, "Expected MenuEntry");
return krk_runtimeError(vm.exceptions->typeError, "Expected MenuEntry");
/* Append to menu */
menu_insert(self->menuList, ((struct MenuEntryClass*)AS_INSTANCE(argv[1]))->menuEntry);
@ -1087,8 +1086,8 @@ static KrkValue _MenuList_insert(int argc, KrkValue argv[]) {
/* Append to internal list */
KrkValue list = NONE_VAL();
krk_tableGet(&self->inst.fields, OBJECT_VAL(S("entries")), &list);
if (IS_NONE(list) || !krk_isInstanceOf(list,vm.baseClasses.listClass))
return krk_runtimeError(vm.exceptions.baseException, "Failed to get entries?");
if (IS_NONE(list) || !krk_isInstanceOf(list,vm.baseClasses->listClass))
return krk_runtimeError(vm.exceptions->baseException, "Failed to get entries?");
krk_writeValueArray(AS_LIST(list), argv[1]);
return NONE_VAL();
@ -1104,20 +1103,20 @@ static void _MenuEntry_callback_internal(struct MenuEntry * _self) {
static KrkValue _MenuEntry_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuEntryClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuEntry");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuEntry");
struct MenuEntryClass * self = (struct MenuEntryClass*)AS_INSTANCE(argv[0]);
if (argc < 3 || !IS_STRING(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected title and callback");
return krk_runtimeError(vm.exceptions->typeError, "expected title and callback");
KrkValue icon = NONE_VAL(), action = NONE_VAL();
if (hasKw) {
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("icon")), &icon);
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("action")), &action);
if (!IS_NONE(icon) && !IS_STRING(icon))
return krk_runtimeError(vm.exceptions.typeError, "icon must be str, not '%s'", krk_typeName(icon));
return krk_runtimeError(vm.exceptions->typeError, "icon must be str, not '%s'", krk_typeName(icon));
if (!IS_NONE(action) && !IS_STRING(action))
return krk_runtimeError(vm.exceptions.typeError, "action must be str, not '%s'", krk_typeName(action));
return krk_runtimeError(vm.exceptions->typeError, "action must be str, not '%s'", krk_typeName(action));
}
self->menuEntry = menu_create_normal(
@ -1137,21 +1136,21 @@ static KrkValue _MenuEntry_init(int argc, KrkValue argv[], int hasKw) {
static KrkValue _MenuEntrySubmenu_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuEntrySubmenuClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuEntrySubmenu");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuEntrySubmenu");
struct MenuEntryClass * self = (struct MenuEntryClass*)AS_INSTANCE(argv[0]);
if (argc < 2 || !IS_STRING(argv[1]))
return krk_runtimeError(vm.exceptions.typeError, "expected title to be a str");
return krk_runtimeError(vm.exceptions->typeError, "expected title to be a str");
KrkValue icon = NONE_VAL(), action = NONE_VAL();
if (hasKw) {
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("icon")), &icon);
krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("action")), &action);
if (!IS_NONE(icon) && !IS_STRING(icon))
return krk_runtimeError(vm.exceptions.typeError, "icon must be str, not '%s'", krk_typeName(icon));
return krk_runtimeError(vm.exceptions->typeError, "icon must be str, not '%s'", krk_typeName(icon));
if (!IS_NONE(action) && !IS_STRING(action))
return krk_runtimeError(vm.exceptions.typeError, "action must be str, not '%s'", krk_typeName(action));
return krk_runtimeError(vm.exceptions->typeError, "action must be str, not '%s'", krk_typeName(action));
}
self->menuEntry = menu_create_submenu(
@ -1164,9 +1163,9 @@ static KrkValue _MenuEntrySubmenu_init(int argc, KrkValue argv[], int hasKw) {
return argv[0];
}
static KrkValue _MenuEntrySeparator_init(int argc, KrkValue argv[]) {
static KrkValue _MenuEntrySeparator_init(int argc, KrkValue argv[], int hasKw) {
if (argc < 1 || !krk_isInstanceOf(argv[0], MenuEntrySeparatorClass))
return krk_runtimeError(vm.exceptions.typeError, "expected MenuEntrySeparator");
return krk_runtimeError(vm.exceptions->typeError, "expected MenuEntrySeparator");
struct MenuEntryClass * self = (struct MenuEntryClass*)AS_INSTANCE(argv[0]);
self->menuEntry = menu_create_separator();
self->menuEntry->_private = self;
@ -1174,7 +1173,7 @@ static KrkValue _MenuEntrySeparator_init(int argc, KrkValue argv[]) {
}
KrkValue krk_module_onload__yutani(void) {
module = krk_newInstance(vm.moduleClass);
module = krk_newInstance(vm.baseClasses->moduleClass);
/* Store it on the stack for now so we can do stuff that may trip GC
* and not lose it to garbage colletion... */
krk_push(OBJECT_VAL(module));

View File

@ -179,7 +179,7 @@ if __name__ == "__main__":
elif command == "--makekurokomod":
libname = os.path.basename(filename).replace(".c","").replace("module_","")
_libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname]
print("base/usr/local/lib/kuroko/{lib}.so: {source} {headers} util/auto-dep.py | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) -DDEBUG {includes} -shared -fPIC -o $@ $< {libraries}".format(
print("base/lib/kuroko/{lib}.so: {source} {headers} util/auto-dep.py | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) -DDEBUG {includes} -shared -fPIC -o $@ $< {libraries}".format(
lib=libname,
source=filename,
headers=" ".join([toheader(x) for x in c.libs]),