diff --git a/apps/bim.c b/apps/bim.c index 7533febb..f4a2a01a 100644 --- a/apps/bim.c +++ b/apps/bim.c @@ -3873,24 +3873,29 @@ void open_file(char * file) { if (spaces) { int one = 0, two = 0, three = 0, four = 0; /* If you use more than that, I don't like you. */ + int lastCount = 0; for (int i = 0; i < env->line_count; ++i) { if (env->lines[i]->actual > 1 && !line_is_comment(env->lines[i])) { /* Count spaces at beginning */ - int c = 0; + int c = 0, diff = 0; while (c < env->lines[i]->actual && env->lines[i]->text[c].codepoint == ' ') c++; - if (c) { - one += 1; - two += ((c % 2) == 0); - three += ((c % 3) == 0); - four += ((c % 4) == 0); + if (c > lastCount) { + diff = c - lastCount; + } else if (c < lastCount) { + diff = lastCount - c; } + if (diff == 1) one++; + if (diff == 2) two++; + if (diff == 3) three++; + if (diff == 4) four++; + lastCount = c; } } - if (four && (four > three) && (four >= two)) { + if (four > three && four > two && four > one) { env->tabstop = 4; - } else if (three && (three > two) && (three >= one)) { + } else if (three > two && three > one) { env->tabstop = 3; - } else if (two && (two > (one / 2))) { + } else if (two > one) { env->tabstop = 2; } else { env->tabstop = 1; @@ -4904,9 +4909,7 @@ int convert_to_html(void) { recalculate_tabs(env->lines[i]); } env->syntax = match_syntax(".htm"); - for (int i = 0; i < env->line_count; ++i) { - recalculate_syntax(env->lines[i],i); - } + schedule_complete_recalc(); return 0; } @@ -9757,7 +9760,10 @@ void normal_mode(void) { if (env->mode == MODE_NORMAL) { place_cursor_actual(); - int key = bim_getkey(DEFAULT_KEY_WAIT); + int key = 0; + do { + key = bim_getkey(DEFAULT_KEY_WAIT); + } while (key == KEY_TIMEOUT); if (handle_nav_buffer(key)) { if (!handle_action(NORMAL_MAP, key)) if (!handle_action(NAVIGATION_MAP, key)) @@ -10252,6 +10258,11 @@ int c_keyword_qualifier(int c) { static KrkValue bim_krk_state_getstate(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; + } return INTEGER_VAL(state->state); } static KrkValue bim_krk_state_setstate(int argc, KrkValue argv[], int hasKw) { @@ -10334,6 +10345,11 @@ static int callQualifier(KrkValue qualifier, int codepoint) { return 0; } +#define KRK_STRING_FAST(string,offset) (uint32_t)\ + (string->type <= 1 ? ((uint8_t*)string->codes)[offset] : \ + (string->type == 2 ? ((uint16_t*)string->codes)[offset] : \ + ((uint32_t*)string->codes)[offset])) + 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])) @@ -10641,6 +10657,7 @@ static KrkValue krk_bim_getDocumentText(int argc, KrkValue argv[], int hasKw) { } static KrkValue krk_bim_renderError(int argc, KrkValue argv[], int hasKw) { + static const char * _method_name = "renderError"; if (argc != 1 || !IS_STRING(argv[0])) return TYPE_ERROR(str,argv[0]); if (AS_STRING(argv[0])->length == 0) redraw_commandline(); @@ -10705,7 +10722,7 @@ void initialize(void) { makeClass(bimModule, &ActionDef, "Action", vm.baseClasses->objectClass); ActionDef->allocSize = sizeof(struct ActionDef); - krk_defineNative(&ActionDef->methods, ".__call__", bim_krk_action_call); + krk_defineNative(&ActionDef->methods, "__call__", bim_krk_action_call); krk_finalizeClass(ActionDef); for (struct action_def * a = mappable_actions; mappable_actions && a->name; ++a) { @@ -10716,7 +10733,7 @@ void initialize(void) { makeClass(bimModule, &CommandDef, "Command", vm.baseClasses->objectClass); CommandDef->allocSize = sizeof(struct CommandDef); - krk_defineNative(&CommandDef->methods, ".__call__", bim_krk_command_call); + krk_defineNative(&CommandDef->methods, "__call__", bim_krk_command_call); krk_finalizeClass(CommandDef); KrkInstance * global = krk_newInstance(vm.baseClasses->objectClass); @@ -10734,23 +10751,23 @@ void initialize(void) { 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? */ - krk_defineNative(&syntaxStateClass->methods, ":i", bim_krk_state_index); - krk_defineNative(&syntaxStateClass->methods, ":lineno", bim_krk_state_lineno); - krk_defineNative(&syntaxStateClass->methods, ".__init__", bim_krk_state_init); + krk_defineNative(&syntaxStateClass->methods, "set_state", bim_krk_state_setstate); /* TODO property? */ + krk_defineNative(&syntaxStateClass->methods, "state", bim_krk_state_getstate)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&syntaxStateClass->methods, "i", bim_krk_state_index)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&syntaxStateClass->methods, "lineno", bim_krk_state_lineno)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&syntaxStateClass->methods, "__init__", bim_krk_state_init); /* These ones take argumens so they're methods instead of dynamic fields */ - krk_defineNative(&syntaxStateClass->methods, ".findKeywords", bim_krk_state_findKeywords); - krk_defineNative(&syntaxStateClass->methods, ".cKeywordQualifier", bim_krk_state_cKeywordQualifier); - krk_defineNative(&syntaxStateClass->methods, ".isdigit", bim_krk_state_isdigit); - krk_defineNative(&syntaxStateClass->methods, ".isxdigit", bim_krk_state_isxdigit); - krk_defineNative(&syntaxStateClass->methods, ".paint", bim_krk_state_paint); - krk_defineNative(&syntaxStateClass->methods, ".paintComment", bim_krk_state_paintComment); - krk_defineNative(&syntaxStateClass->methods, ".skip", bim_krk_state_skip); - krk_defineNative(&syntaxStateClass->methods, ".matchAndPaint", bim_krk_state_matchAndPaint); - krk_defineNative(&syntaxStateClass->methods, ".commentBuzzwords", bim_krk_state_commentBuzzwords); - krk_defineNative(&syntaxStateClass->methods, ".rewind", bim_krk_state_rewind); - krk_defineNative(&syntaxStateClass->methods, ".__getitem__", bim_krk_state_get); + krk_defineNative(&syntaxStateClass->methods, "findKeywords", bim_krk_state_findKeywords); + krk_defineNative(&syntaxStateClass->methods, "cKeywordQualifier", bim_krk_state_cKeywordQualifier); + krk_defineNative(&syntaxStateClass->methods, "isdigit", bim_krk_state_isdigit); + krk_defineNative(&syntaxStateClass->methods, "isxdigit", bim_krk_state_isxdigit); + krk_defineNative(&syntaxStateClass->methods, "paint", bim_krk_state_paint); + krk_defineNative(&syntaxStateClass->methods, "paintComment", bim_krk_state_paintComment); + krk_defineNative(&syntaxStateClass->methods, "skip", bim_krk_state_skip); + krk_defineNative(&syntaxStateClass->methods, "matchAndPaint", bim_krk_state_matchAndPaint); + krk_defineNative(&syntaxStateClass->methods, "commentBuzzwords", bim_krk_state_commentBuzzwords); + krk_defineNative(&syntaxStateClass->methods, "rewind", bim_krk_state_rewind); + krk_defineNative(&syntaxStateClass->methods, "__getitem__", bim_krk_state_get); krk_attachNamedValue(&syntaxStateClass->methods, "FLAG_NONE", INTEGER_VAL(FLAG_NONE)); krk_attachNamedValue(&syntaxStateClass->methods, "FLAG_KEYWORD", INTEGER_VAL(FLAG_KEYWORD)); krk_attachNamedValue(&syntaxStateClass->methods, "FLAG_STRING", INTEGER_VAL(FLAG_STRING)); @@ -11236,6 +11253,7 @@ int main(int argc, char * argv[]) { global_config.go_to_line = 0; open_file(optarg); for (int i = 0; i < env->line_count; ++i) { + recalculate_syntax(env->lines[i], i); if (opt == 'C') { draw_line_number(i); } @@ -11312,6 +11330,9 @@ int main(int argc, char * argv[]) { initialize(); global_config.go_to_line = 0; open_file(argv[optind]); + for (int i = 0; i < env->line_count; ++i) { + recalculate_syntax(env->lines[i], i); + } convert_to_html(); /* write to stdout */ output_file(env, stdout); diff --git a/apps/kuroko.c b/apps/kuroko.c index 8508b621..69e60d42 100644 --- a/apps/kuroko.c +++ b/apps/kuroko.c @@ -13,23 +13,18 @@ #include #include -#ifdef __toaru__ #include -#include -#else -#ifndef NO_RLINE -#include "rline.h" -#endif -#include "kuroko.h" -#endif -#include "chunk.h" -#include "debug.h" -#include "vm.h" -#include "memory.h" -#include "scanner.h" -#include "compiler.h" -#include "util.h" +#define DEBUG +#include + +#include +#include +#include +#include +#include +#include +#include #define PROMPT_MAIN ">>> " #define PROMPT_BLOCK " > " @@ -263,7 +258,7 @@ static void tab_complete_func(rline_context_t * c) { 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)) { + (IS_NATIVE(thisValue) && !(((KrkNative*)AS_OBJECT(thisValue))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY))) { size_t allocSize = s->length + 2; char * tmp = malloc(allocSize); size_t len = snprintf(tmp, allocSize, "%s(", s->chars); diff --git a/base/usr/include/kuroko b/base/usr/include/kuroko new file mode 120000 index 00000000..9432f989 --- /dev/null +++ b/base/usr/include/kuroko @@ -0,0 +1 @@ +../../../kuroko/src/kuroko \ No newline at end of file diff --git a/base/usr/include/kuroko/chunk.h b/base/usr/include/kuroko/chunk.h deleted file mode 100644 index 0d10c17b..00000000 --- a/base/usr/include/kuroko/chunk.h +++ /dev/null @@ -1,219 +0,0 @@ -#pragma once -/** - * @file chunk.h - * @brief Structures and enums for bytecode chunks. - */ -#include "kuroko.h" -#include "value.h" - -/** - * @brief Instruction opcode values - * - * The instruction opcode table is divided in four parts. The high two bits of each - * opcode encodes the number of operands to pull from the codeobject and thus the - * size (generally) of the instruction (note that OP_CLOSURE(_LONG) has additional - * arguments depending on the function it points to). - * - * 0-operand opcodes are "simple" instructions that generally only deal with stack - * values and require no additional arguments. - * - * 1- and 3- operand opcodes are paired as 'short' and 'long'. While the VM does not - * currently depend on these instructions having the same values in the lower 6 bits, - * it is recommended that this property remain true. - * - * 2-operand opcodes are generally jump instructions. - */ -typedef enum { - OP_ADD = 1, - OP_BITAND, - OP_BITNEGATE, - OP_BITOR, - OP_BITXOR, - OP_CLEANUP_WITH, - OP_CLOSE_UPVALUE, - OP_DIVIDE, - OP_DOCSTRING, - OP_EQUAL, - OP_FALSE, - OP_FINALIZE, - OP_GREATER, - OP_INHERIT, - OP_INVOKE_DELETE, - OP_INVOKE_DELSLICE, - OP_INVOKE_GETSLICE, - OP_INVOKE_GETTER, - OP_INVOKE_SETSLICE, - OP_INVOKE_SETTER, - OP_IS, - OP_LESS, - OP_MODULO, - OP_MULTIPLY, - OP_NEGATE, - OP_NONE, - OP_NOT, - OP_POP, - OP_POW, - OP_RAISE, - OP_RETURN, - OP_SHIFTLEFT, - OP_SHIFTRIGHT, - OP_SUBTRACT, - OP_SWAP, - OP_TRUE, - OP_FILTER_EXCEPT, - OP_INVOKE_ITER, - OP_INVOKE_CONTAINS, - OP_BREAKPOINT, /* NEVER output this instruction in the compiler or bad things can happen */ - OP_YIELD, - OP_ANNOTATE, - /* current highest: 44 */ - - OP_CALL = 64, - OP_CLASS, - OP_CLOSURE, - OP_CONSTANT, - OP_DEFINE_GLOBAL, - OP_DEL_GLOBAL, - OP_DEL_PROPERTY, - OP_DUP, - OP_EXPAND_ARGS, - OP_GET_GLOBAL, - OP_GET_LOCAL, - OP_GET_PROPERTY, - OP_GET_SUPER, - OP_GET_UPVALUE, - OP_IMPORT, - OP_IMPORT_FROM, - OP_INC, - OP_KWARGS, - OP_CLASS_PROPERTY, - OP_SET_GLOBAL, - OP_SET_LOCAL, - OP_SET_PROPERTY, - OP_SET_UPVALUE, - OP_TUPLE, - OP_UNPACK, - OP_LIST_APPEND, - OP_DICT_SET, - OP_SET_ADD, - OP_MAKE_LIST, - OP_MAKE_DICT, - OP_MAKE_SET, - OP_REVERSE, - - OP_JUMP_IF_FALSE = 128, - OP_JUMP_IF_TRUE, - OP_JUMP, - OP_LOOP, - OP_PUSH_TRY, - OP_PUSH_WITH, - - OP_CALL_LONG = 192, - OP_CLASS_LONG, - OP_CLOSURE_LONG, - OP_CONSTANT_LONG, - OP_DEFINE_GLOBAL_LONG, - OP_DEL_GLOBAL_LONG, - OP_DEL_PROPERTY_LONG, - OP_DUP_LONG, - OP_EXPAND_ARGS_LONG, - OP_GET_GLOBAL_LONG, - OP_GET_LOCAL_LONG, - OP_GET_PROPERTY_LONG, - OP_GET_SUPER_LONG, - OP_GET_UPVALUE_LONG, - OP_IMPORT_LONG, - OP_IMPORT_FROM_LONG, - OP_INC_LONG, - OP_KWARGS_LONG, - OP_CLASS_PROPERTY_LONG, - OP_SET_GLOBAL_LONG, - OP_SET_LOCAL_LONG, - OP_SET_PROPERTY_LONG, - OP_SET_UPVALUE_LONG, - OP_TUPLE_LONG, - OP_UNPACK_LONG, - OP_LIST_APPEND_LONG, - OP_DICT_SET_LONG, - OP_SET_ADD_LONG, - OP_MAKE_LIST_LONG, - OP_MAKE_DICT_LONG, - OP_MAKE_SET_LONG, - OP_REVERSE_LONG, -} KrkOpCode; - -/** - * @brief Map entry of instruction offsets to line numbers. - * - * Each code object contains an array of line mappings, indicating - * the start offset of each line. Since a line typically maps to - * multiple opcodes, and spans of many lines may map to no opcodes - * in the case of blank lines or docstrings, this array is stored - * as a sequence of pairs rather than a simple - * array of one or the other. - */ -typedef struct { - size_t startOffset; - size_t line; -} KrkLineMap; - -/** - * @brief Opcode chunk of a code object. - * - * Opcode chunks are internal to code objects and I'm not really - * sure why we're still separating them from the KrkCodeObjects. - * - * Stores four flexible arrays using three different formats: - * - Code, representing opcodes and operands. - * - Lines, representing offset-to-line mappings. - * - Filename, the string name of the source file. - * - Constants, an array of values referenced by the code object. - */ -typedef struct { - size_t count; - size_t capacity; - uint8_t * code; - - size_t linesCount; - size_t linesCapacity; - KrkLineMap * lines; - - KrkString * filename; - KrkValueArray constants; -} KrkChunk; - -/** - * @brief Initialize an opcode chunk. - * @memberof KrkChunk - */ -extern void krk_initChunk(KrkChunk * chunk); - -/** - * @memberof KrkChunk - * @brief Append a byte to an opcode chunk. - */ -extern void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line); - -/** - * @brief Release the resources allocated to an opcode chunk. - * @memberof KrkChunk - */ -extern void krk_freeChunk(KrkChunk * chunk); - -/** - * @brief Add a new constant value to an opcode chunk. - * @memberof KrkChunk - */ -extern size_t krk_addConstant(KrkChunk * chunk, KrkValue value); - -/** - * @brief Write an OP_CONSTANT(_LONG) instruction. - * @memberof KrkChunk - */ -extern void krk_emitConstant(KrkChunk * chunk, size_t ind, size_t line); - -/** - * @brief Add a new constant and write an instruction for it. - * @memberof KrkChunk - */ -extern size_t krk_writeConstant(KrkChunk * chunk, KrkValue value, size_t line); diff --git a/base/usr/include/kuroko/compiler.h b/base/usr/include/kuroko/compiler.h deleted file mode 100644 index 82baaec2..00000000 --- a/base/usr/include/kuroko/compiler.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -/** - * @file compiler.h - * @brief Exported methods for the source compiler. - */ -#include "object.h" - -/** - * @brief Compile a string to a code object. - * - * Compiles the source string 'src' into a code object. - * - * @param src Source code string to compile. - * @param fileName Path name of the source file or a representative string like "" - * @return The code object resulting from the compilation, or NULL if compilation failed. - */ -extern KrkCodeObject * krk_compile(const char * src, char * fileName); - -/** - * @brief Mark objects owned by the compiler as in use. - */ -extern void krk_markCompilerRoots(void); diff --git a/base/usr/include/kuroko/debug.h b/base/usr/include/kuroko/debug.h deleted file mode 100644 index 9c6e1e8d..00000000 --- a/base/usr/include/kuroko/debug.h +++ /dev/null @@ -1,248 +0,0 @@ -#pragma once -/** - * @file debug.h - * @brief Functions for debugging bytecode execution. - * - * This header provides functions for disassembly bytecode to - * readable instruction traces, mapping bytecode offsets to - * source code lines, and handling breakpoint instructions. - * - * Several of these functions are also exported to user code - * in the @ref mod_dis module. - * - * Note that these functions are not related to manage code - * exception handling, but instead inteaded to provide a low - * level interface to the VM's execution process and allow - * for the implementation of debuggers and debugger extensions. - */ -#include -#include "vm.h" -#include "chunk.h" -#include "object.h" - -/** - * @brief Print a disassembly of 'func' to the stream 'f'. - * - * Generates and prints a bytecode disassembly of the code object 'func', - * writing it to the requested stream. - * - * @param f Stream to write to. - * @param func Code object to disassemble. - * @param name Function name to display in disassembly output. - */ -extern void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name); - -/** - * @brief Print a disassembly of a single opcode instruction. - * - * Generates and prints a bytecode disassembly for one instruction from - * the code object 'func' at byte offset 'offset', printing the result to - * the requested stream and returning the size of the instruction. - * - * @param f Stream to write to. - * @param func Code object to disassemble. - * @param offset Byte offset of the instruction to disassemble. - * @return The size of the instruction in bytes. - */ -extern size_t krk_disassembleInstruction(FILE * f, KrkCodeObject * func, size_t offset); - -/** - * @brief Obtain the line number for a byte offset into a bytecode chunk. - * - * Scans the line mapping table for the given chunk to find the - * correct line number from the original source file for the instruction - * at byte index 'offset'. - * - * @param chunk Bytecode chunk containing the instruction. - * @param offset Byte offset of the instruction to locate. - * @return Line number, 1-indexed. - */ -extern size_t krk_lineNumber(KrkChunk * chunk, size_t offset); - -/* Internal stuff */ -extern void _createAndBind_disMod(void); - -/** - * @brief Called by the VM when a breakpoint is encountered. - * - * Internal method, should not generally be called. - */ -extern int krk_debugBreakpointHandler(void); - -/** - * @brief Called by the VM on single step. - * - * Handles calling the registered debugger hook, if one has - * been set, and performing the requested response action. - * Also takes care of re-enabling REPEAT breakpoints. - * - * Internal method, should not generally be called. - */ -extern int krk_debuggerHook(KrkCallFrame * frame); - -/** - * @brief Function pointer for a debugger hook. - * @ref krk_debug_registerCallback() - */ -typedef int (*KrkDebugCallback)(KrkCallFrame *frame); - -/** - * @brief Register a debugger callback. - * - * The registered function @p hook will be called when an - * OP_BREAKPOINT instruction is encountered. The debugger - * is provided a pointer to the active frame and can use - * functions from the krk_debug_* suite to examine the - * thread state, execute more code, and resume execution. - * - * The debugger hook will be called from the thread that - * encountered the breakpoint, and should return one of - * the KRK_DEBUGGER_ status values to inform the VM of - * what action to take. - * - * @param hook The hook function to attach. - * @return 0 if the hook was registered; 1 if a hook was - * already registered, in which case the new hook - * has not been registered. - */ -extern int krk_debug_registerCallback(KrkDebugCallback hook); - -/** - * @brief Add a breakpoint to the given line of a file. - * - * The interpreter will scan all code objects and attach - * a breakpoint instruction to the first such object that - * has a match filename and contains an instruction with - * a matching line mapping. Breakpoints can only be added - * to code which has already been compiled. - * - * @param filename KrkString * representation of a source - * code filename to look for. - * @param line The line to set the breakpoint at. - * @param flags Allows configuring the disposition of the breakpoint. - * @return A breakpoint identifier handle on success, or -1 on failure. - */ -extern int krk_debug_addBreakpointFileLine(KrkString * filename, size_t line, int flags); - -/** - * @brief Add a breakpoint to the given code object. - * - * A new breakpoint is added to the breakpoint table and - * the code object's bytecode is overwritten to insert - * the OP_BREAKPOINT instruction. - * - * Callers must ensure that @p offset points to the opcode - * portion of an instruction, and not an operand, or the - * attempt to add a breakpoint can corrupt the bytecode. - * - * @param codeObject KrkCodeObject* for the code object to break on. - * @param offset Bytecode offset to insert the breakpoint at. - * @param flags Allows configuring the disposition of the breakpoint. - * @return A breakpoint identifier handle on success, or -1 on failure. - */ -extern int krk_debug_addBreakpointCodeOffset(KrkCodeObject * codeObject, size_t offset, int flags); - -/** - * @brief Remove a breakpoint from the breakpoint table. - * - * Removes the breakpoint @p breakpointId from the breakpoint - * table, restoring the bytecode instruction for it if it - * was enabled. - * - * @param breakpointId The breakpoint to remove. - * @return 0 on success, 1 if the breakpoint identifier is invalid. - */ -extern int krk_debug_removeBreakpoint(int breakpointId); - -/** - * @brief Enable a breakpoint. - * - * Writes the OP_BREAKPOINT instruction into the function - * bytecode chunk for the given breakpoint. - * - * @param breakpointId The breakpoint to enable. - * @return 0 on success, 1 if the breakpoint identifier is invalid. - */ -extern int krk_debug_enableBreakpoint(int breakpointId); - -/** - * @brief Disable a breakpoint. - * - * Restores the bytecode instructions for the given breakpoint - * if it is currently enabled. - * - * No error is returned if the breakpoint was already disabled. - * - * @param breakpointId The breakpoint to disable. - * @return 0 on success, 1 if the breakpoint identifier is invalid. - */ -extern int krk_debug_disableBreakpoint(int breakpointId); - -/** - * @brief Enable single stepping in the current thread. - */ -extern void krk_debug_enableSingleStep(void); - -/** - * @brief Disable single stepping in the current thread. - */ -extern void krk_debug_disableSingleStep(void); - -/** - * @brief Safely dump a traceback to stderr. - * - * Wraps @ref krk_dumpTraceback() so it can be safely - * called from a debugger. - */ -extern void krk_debug_dumpTraceback(void); - -/** - * @brief Retreive information on a breakpoint. - * - * Can be called by debuggers to examine the details of a breakpoint by its handle. - * Information is returned through the pointers provided as parameters. - * - * @param breakIndex Breakpoint handle to examine. - * @param funcOut (Out) The code object this breakpoint is in. - * @param offsetOut (Out) The bytecode offset within the code object where the breakpoint is located. - * @param flagsOut (Out) The configuration flags for the breakpoint. - * @param enabledOut (Out) Whether the breakpoint is enabled or not. - * @return 0 on success, -1 on out of range, -2 if the selected slot was removed. - */ -extern int krk_debug_examineBreakpoint(int breakIndex, KrkCodeObject ** funcOut, size_t * offsetOut, int * flagsOut, int *enabledOut); - -/** - * @brief Print the elements on the stack. - * - * Prints the elements on the stack for the current thread to @p file, - * highlighting @p frame as the activate call point and indicating - * where its arguments start. - */ -extern void krk_debug_dumpStack(FILE * f, KrkCallFrame * frame); - -/** - * @def KRK_BREAKPOINT_NORMAL - * - * This breakpoint should fire once and then remain in the table - * to be re-enabled later. - * - * @def KRK_BREAKPOINT_ONCE - * - * This breakpoint should fire once and then be removed from the - * breakpoint table. - * - * @def KRK_BREAKPOINT_REPEAT - * - * After this breakpoint has fired and execution resumes, the - * interpreter should re-enable it to fire again until it is - * removed by a call to @ref krk_debug_removeBreakpoint() - */ -#define KRK_BREAKPOINT_NORMAL 0 -#define KRK_BREAKPOINT_ONCE 1 -#define KRK_BREAKPOINT_REPEAT 2 - -#define KRK_DEBUGGER_CONTINUE 0 -#define KRK_DEBUGGER_ABORT 1 -#define KRK_DEBUGGER_STEP 2 -#define KRK_DEBUGGER_RAISE 3 -#define KRK_DEBUGGER_QUIT 4 diff --git a/base/usr/include/kuroko/kuroko.h b/base/usr/include/kuroko/kuroko.h deleted file mode 100644 index 0ed6dd50..00000000 --- a/base/usr/include/kuroko/kuroko.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -/** - * @file kuroko.h - * @brief Top-level header with configuration macros. - */ -#include -#include -#include - -#if defined(__EMSCRIPTEN__) -typedef long long krk_integer_type; -# define PRIkrk_int "%lld" -# define PRIkrk_hex "%llx" -# define parseStrInt strtoll -#elif defined(_WIN32) -typedef long long krk_integer_type; -# define PRIkrk_int "%I64d" -# define PRIkrk_hex "%I64x" -# define parseStrInt strtoll -# define ENABLE_THREADING -# else -typedef long krk_integer_type; -# define PRIkrk_int "%ld" -# define PRIkrk_hex "%lx" -# define parseStrInt strtol -# define ENABLE_THREADING -#endif - -#define ENABLE_THREADING - -#ifdef DEBUG -#define ENABLE_DISASSEMBLY -#define ENABLE_TRACING -#define ENABLE_SCAN_TRACING -#define ENABLE_STRESS_GC -#endif - diff --git a/base/usr/include/kuroko/memory.h b/base/usr/include/kuroko/memory.h deleted file mode 100644 index 0efecce7..00000000 --- a/base/usr/include/kuroko/memory.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once -/** - * @file memory.h - * @brief Functions for dealing with garbage collection and memory allocation. - */ -#include "kuroko.h" -#include "object.h" -#include "table.h" - -#define GROW_CAPACITY(c) ((c) < 8 ? 8 : (c) * 2) -#define GROW_ARRAY(t,p,o,n) (t*)krk_reallocate(p,sizeof(t)*o,sizeof(t)*n) - -#define FREE_ARRAY(t,a,c) krk_reallocate(a,sizeof(t) * c, 0) -#define FREE(t,p) krk_reallocate(p,sizeof(t),0) - -#define ALLOCATE(type, count) (type*)krk_reallocate(NULL,0,sizeof(type)*(count)) - -/** - * @brief Resize an allocated heap object. - * - * Allocates or reallocates the heap object 'ptr', tracking changes - * in sizes from 'old' to 'new'. If 'ptr' is NULL, 'old' should be 0, - * and a new pointer will be allocated of size 'new'. - * - * @param ptr Heap object to resize. - * @param old Current size of the object. - * @param new New size of the object. - * @return New pointer for heap object. - */ -extern void * krk_reallocate(void * ptr, size_t old, size_t new); - -/** - * @brief Release all objects. - * - * Generally called automatically by krk_freeVM(); releases all of - * the GC-tracked heap objects. - */ -extern void krk_freeObjects(void); - -/** - * @brief Run a cycle of the garbage collector. - * - * Runs one scan-sweep cycle of the garbage collector, potentially - * freeing unused resources and advancing potentially-unused - * resources to the next stage of removal. - * - * @return The number of bytes released by this collection cycle. - */ -extern size_t krk_collectGarbage(void); - -/** - * @brief During a GC scan cycle, mark a value as used. - * - * When defining a new type in a C extension, this function should - * be used by the type's _ongcscan callback to mark any values not - * already tracked by the garbage collector. - * - * @param value The value to mark. - */ -extern void krk_markValue(KrkValue value); - -/** - * @brief During a GC scan cycle, mark an object as used. - * - * Equivalent to krk_markValue but operates directly on an object. - * - * @param object The object to mark. - */ -extern void krk_markObject(KrkObj * object); - -/** - * @brief During a GC scan cycle, mark the contents of a table as used. - * - * Marks all keys and values in a table as used. Generally applied - * to the internal storage of mapping types. - * - * @param table The table to mark. - */ -extern void krk_markTable(KrkTable * table); - diff --git a/base/usr/include/kuroko/object.h b/base/usr/include/kuroko/object.h deleted file mode 100644 index df137c28..00000000 --- a/base/usr/include/kuroko/object.h +++ /dev/null @@ -1,411 +0,0 @@ -#pragma once -/** - * @file object.h - * @brief Struct definitions for core object types. - */ -#include -#include "kuroko.h" -#include "value.h" -#include "chunk.h" -#include "table.h" - -#ifdef ENABLE_THREADING -#include -#endif - -typedef enum { - KRK_OBJ_CODEOBJECT, - KRK_OBJ_NATIVE, - KRK_OBJ_CLOSURE, - KRK_OBJ_STRING, - KRK_OBJ_UPVALUE, - KRK_OBJ_CLASS, - KRK_OBJ_INSTANCE, - KRK_OBJ_BOUND_METHOD, - KRK_OBJ_TUPLE, - KRK_OBJ_BYTES, -} KrkObjType; - -#undef KrkObj -/** - * @brief The most basic object type. - * - * This is the base of all object types and contains - * the core structures for garbage collection. - */ -typedef struct KrkObj { - KrkObjType type; - unsigned char isMarked:1; - unsigned char inRepr:1; - unsigned char generation:2; - unsigned char isImmortal:1; - uint32_t hash; - struct KrkObj * next; -} KrkObj; - -typedef enum { - KRK_STRING_ASCII = 0, - KRK_STRING_UCS1 = 1, - KRK_STRING_UCS2 = 2, - KRK_STRING_UCS4 = 4, - KRK_STRING_INVALID = 5, -} KrkStringType; - -#undef KrkString -/** - * @brief Immutable sequence of Unicode codepoints. - * @extends KrkObj - */ -typedef struct KrkString { - KrkObj obj; - KrkStringType type; - size_t length; - size_t codesLength; - char * chars; - void * codes; -} KrkString; - -/** - * @brief Immutable sequence of bytes. - * @extends KrkObj - */ -typedef struct { - KrkObj obj; - size_t length; - uint8_t * bytes; -} KrkBytes; - -/** - * @brief Storage for values referenced from nested functions. - * @extends KrkObj - */ -typedef struct KrkUpvalue { - KrkObj obj; - int location; - KrkValue closed; - struct KrkUpvalue * next; - struct KrkThreadState * owner; -} KrkUpvalue; - -/** - * @brief Metadata on a local variable name in a function. - * - * This is used by the disassembler to print the names of - * locals when they are referenced by instructions. - */ -typedef struct { - size_t id; - size_t birthday; - size_t deathday; - KrkString * name; -} KrkLocalEntry; - -struct KrkInstance; - -/** - * @brief Code object. - * @extends KrkObj - * - * Contains the static data associated with a chunk of bytecode. - */ -typedef struct { - KrkObj obj; - short requiredArgs; - short keywordArgs; - size_t upvalueCount; - KrkChunk chunk; - KrkString * name; - KrkString * docstring; - KrkValueArray requiredArgNames; - KrkValueArray keywordArgNames; - size_t localNameCapacity; - size_t localNameCount; - KrkLocalEntry * localNames; - unsigned char collectsArguments:1; - unsigned char collectsKeywords:1; - unsigned char isGenerator:1; - struct KrkInstance * globalsContext; - KrkString * qualname; -} KrkCodeObject; - -/** - * @brief Function object. - * @extends KrkObj - * - * Not to be confused with code objects, a closure is a single instance of a function. - */ -typedef struct { - KrkObj obj; - KrkCodeObject * function; - KrkUpvalue ** upvalues; - size_t upvalueCount; - unsigned char isClassMethod:1; - unsigned char isStaticMethod:1; - KrkValue annotations; - KrkTable fields; -} KrkClosure; - -typedef void (*KrkCleanupCallback)(struct KrkInstance *); - -/** - * @brief Type object. - * @extends KrkObj - * - * Represents classes defined in user code as well as classes defined - * by C extensions to represent method tables for new types. - */ -typedef struct KrkClass { - KrkObj obj; - KrkString * name; - KrkString * filename; - KrkString * docstring; - struct KrkClass * base; - KrkTable methods; - size_t allocSize; - KrkCleanupCallback _ongcscan; - KrkCleanupCallback _ongcsweep; - - /* Quick access for common stuff */ - KrkObj * _getter; - KrkObj * _setter; - KrkObj * _getslice; - KrkObj * _reprer; - KrkObj * _tostr; - KrkObj * _call; - KrkObj * _init; - KrkObj * _eq; - KrkObj * _len; - KrkObj * _enter; - KrkObj * _exit; - KrkObj * _delitem; - KrkObj * _iter; - KrkObj * _getattr; - KrkObj * _dir; - KrkObj * _setslice; - KrkObj * _delslice; - KrkObj * _contains; - KrkObj * _descget; - KrkObj * _descset; - KrkObj * _classgetitem; -} KrkClass; - -/** - * @brief An object of a class. - * @extends KrkObj - * - * Created by class initializers, instances are the standard type of objects - * built by managed code. Not all objects are instances, but all instances are - * objects, and all instances have well-defined class. - */ -typedef struct KrkInstance { - KrkObj obj; - KrkClass * _class; - KrkTable fields; -} KrkInstance; - -/** - * @brief A function that has been attached to an object to serve as a method. - * @extends KrkObj - * - * When a bound method is called, its receiver is implicitly extracted as - * the first argument. Bound methods are created whenever a method is retreived - * from the class of a value. - */ -typedef struct { - KrkObj obj; - KrkValue receiver; - KrkObj * method; -} KrkBoundMethod; - -typedef KrkValue (*NativeFn)(int argCount, KrkValue* args, int hasKwargs); - -/** - * @brief Managed binding to a C function. - * @extends KrkObj - * - * Represents a C function that has been exposed to managed code. - */ -typedef struct { - KrkObj obj; - NativeFn function; - const char * name; - const char * doc; - int isMethod; -} KrkNative; - -/** - * @brief Immutable sequence of arbitrary values. - * @extends KrkObj - * - * Tuples are fixed-length non-mutable collections of values intended - * for use in situations where the flexibility of a list is not needed. - */ -typedef struct { - KrkObj obj; - KrkValueArray values; -} KrkTuple; - -/** - * @brief Mutable array of values. - * @extends KrkInstance - * - * A list is a flexible array of values that can be extended, cleared, - * sorted, rearranged, iterated over, etc. - */ -typedef struct { - KrkInstance inst; - KrkValueArray values; -#ifdef ENABLE_THREADING - pthread_rwlock_t rwlock; -#endif -} KrkList; - -/** - * @brief Flexible mapping type. - * @extends KrkInstance - * - * Provides key-to-value mappings as a first-class object type. - */ -typedef struct { - KrkInstance inst; - KrkTable entries; -} KrkDict; - -struct DictItems { - KrkInstance inst; - KrkValue dict; - size_t i; -}; - -struct DictKeys { - KrkInstance inst; - KrkValue dict; - size_t i; -}; - -/** - * @brief Yield ownership of a C string to the GC and obtain a string object. - * @memberof KrkString - * - * Creates a string object represented by the characters in 'chars' and of - * length 'length'. The source string must be nil-terminated and must - * remain valid for the lifetime of the object, as its ownership is yielded - * to the GC. Useful for strings which were allocated on the heap by - * other mechanisms. - * - * 'chars' must be a nil-terminated C string representing a UTF-8 - * character sequence. - * - * @param chars C string to take ownership of. - * @param length Length of the C string. - * @return A string object. - */ -extern KrkString * krk_takeString(char * chars, size_t length); - -/** - * @brief Obtain a string object representation of the given C string. - * @memberof KrkString - * - * Converts the C string 'chars' into a string object by checking the - * string table for it. If the string table does not have an equivalent - * string, a new one will be created by copying 'chars'. - * - * 'chars' must be a nil-terminated C string representing a UTF-8 - * character sequence. - * - * @param chars C string to convert to a string object. - * @param length Length of the C string. - * @return A string object. - */ -extern KrkString * krk_copyString(const char * chars, size_t length); - -/** - * @brief Ensure that a codepoint representation of a string is available. - * @memberof KrkString - * - * Obtain an untyped pointer to the codepoint representation of a string. - * If the string does not have a codepoint representation allocated, it will - * be generated by this function and remain with the string for the duration - * of its lifetime. - * - * @param string String to obtain the codepoint representation of. - * @return A pointer to the bytes of the codepoint representation. - */ -extern void * krk_unicodeString(KrkString * string); - -/** - * @brief Obtain the codepoint at a given index in a string. - * @memberof KrkString - * - * This is a convenience function which ensures that a Unicode codepoint - * representation has been generated and returns the codepoint value at - * the requested index. If you need to find multiple codepoints, it - * is recommended that you use the KRK_STRING_FAST macro after calling - * krk_unicodeString instead. - * - * @note This function does not perform any bounds checking. - * - * @param string String to index into. - * @param index Offset of the codepoint to obtain. - * @return Integer representation of the codepoint at the requested index. - */ -extern uint32_t krk_unicodeCodepoint(KrkString * string, size_t index); - -/** - * @brief Convert an integer codepoint to a UTF-8 byte representation. - * @memberof KrkString - * - * Converts a single codepoint to a sequence of bytes containing the - * UTF-8 representation. 'out' must be allocated by the caller. - * - * @param value Codepoint to encode. - * @param out Array to write UTF-8 sequence into. - * @return The length of the UTF-8 sequence, in bytes. - */ -extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out); - -/* Internal stuff. */ -extern NativeFn KrkGenericAlias; -extern KrkCodeObject * krk_newCodeObject(void); -extern KrkNative * krk_newNative(NativeFn function, const char * name, int type); -extern KrkClosure * krk_newClosure(KrkCodeObject * function); -extern KrkUpvalue * krk_newUpvalue(int slot); -extern KrkClass * krk_newClass(KrkString * name, KrkClass * base); -extern KrkInstance * krk_newInstance(KrkClass * _class); -extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method); -extern KrkTuple * krk_newTuple(size_t length); -extern KrkBytes * krk_newBytes(size_t length, uint8_t * source); -extern void krk_bytesUpdateHash(KrkBytes * bytes); -extern void krk_tupleUpdateHash(KrkTuple * self); - -#define KRK_STRING_FAST(string,offset) (uint32_t)\ - (string->type <= 1 ? ((uint8_t*)string->codes)[offset] : \ - (string->type == 2 ? ((uint16_t*)string->codes)[offset] : \ - ((uint32_t*)string->codes)[offset])) - -#define CODEPOINT_BYTES(cp) (cp < 0x80 ? 1 : (cp < 0x800 ? 2 : (cp < 0x10000 ? 3 : 4))) - -#define krk_isObjType(v,t) (IS_OBJECT(v) && (AS_OBJECT(v)->type == (t))) -#define OBJECT_TYPE(value) (AS_OBJECT(value)->type) -#define IS_STRING(value) krk_isObjType(value, KRK_OBJ_STRING) -#define AS_STRING(value) ((KrkString *)AS_OBJECT(value)) -#define AS_CSTRING(value) (((KrkString *)AS_OBJECT(value))->chars) -#define IS_BYTES(value) krk_isObjType(value, KRK_OBJ_BYTES) -#define AS_BYTES(value) ((KrkBytes*)AS_OBJECT(value)) -#define IS_NATIVE(value) krk_isObjType(value, KRK_OBJ_NATIVE) -#define AS_NATIVE(value) ((KrkNative *)AS_OBJECT(value)) -#define IS_CLOSURE(value) krk_isObjType(value, KRK_OBJ_CLOSURE) -#define AS_CLOSURE(value) ((KrkClosure *)AS_OBJECT(value)) -#define IS_CLASS(value) krk_isObjType(value, KRK_OBJ_CLASS) -#define AS_CLASS(value) ((KrkClass *)AS_OBJECT(value)) -#define IS_INSTANCE(value) krk_isObjType(value, KRK_OBJ_INSTANCE) -#define AS_INSTANCE(value) ((KrkInstance *)AS_OBJECT(value)) -#define IS_BOUND_METHOD(value) krk_isObjType(value, KRK_OBJ_BOUND_METHOD) -#define AS_BOUND_METHOD(value) ((KrkBoundMethod*)AS_OBJECT(value)) -#define IS_TUPLE(value) krk_isObjType(value, KRK_OBJ_TUPLE) -#define AS_TUPLE(value) ((KrkTuple *)AS_OBJECT(value)) -#define AS_LIST(value) (&((KrkList *)AS_OBJECT(value))->values) -#define AS_DICT(value) (&((KrkDict *)AS_OBJECT(value))->entries) - -#define IS_codeobject(value) krk_isObjType(value, KRK_OBJ_CODEOBJECT) -#define AS_codeobject(value) ((KrkCodeObject *)AS_OBJECT(value)) diff --git a/base/usr/include/kuroko/opcodes.h b/base/usr/include/kuroko/opcodes.h deleted file mode 100644 index 12e19dff..00000000 --- a/base/usr/include/kuroko/opcodes.h +++ /dev/null @@ -1,80 +0,0 @@ -SIMPLE(OP_RETURN) -SIMPLE(OP_ADD) -SIMPLE(OP_SUBTRACT) -SIMPLE(OP_MULTIPLY) -SIMPLE(OP_DIVIDE) -SIMPLE(OP_NEGATE) -SIMPLE(OP_MODULO) -SIMPLE(OP_NONE) -SIMPLE(OP_TRUE) -SIMPLE(OP_FALSE) -SIMPLE(OP_NOT) -SIMPLE(OP_EQUAL) -SIMPLE(OP_GREATER) -SIMPLE(OP_LESS) -SIMPLE(OP_POP) -SIMPLE(OP_INHERIT) -SIMPLE(OP_RAISE) -SIMPLE(OP_CLOSE_UPVALUE) -SIMPLE(OP_DOCSTRING) -SIMPLE(OP_BITOR) -SIMPLE(OP_BITXOR) -SIMPLE(OP_BITAND) -SIMPLE(OP_SHIFTLEFT) -SIMPLE(OP_SHIFTRIGHT) -SIMPLE(OP_BITNEGATE) -SIMPLE(OP_INVOKE_GETTER) -SIMPLE(OP_INVOKE_SETTER) -SIMPLE(OP_INVOKE_DELETE) -SIMPLE(OP_INVOKE_GETSLICE) -SIMPLE(OP_INVOKE_SETSLICE) -SIMPLE(OP_INVOKE_DELSLICE) -SIMPLE(OP_INVOKE_ITER) -SIMPLE(OP_INVOKE_CONTAINS) -SIMPLE(OP_SWAP) -SIMPLE(OP_FINALIZE) -SIMPLE(OP_IS) -SIMPLE(OP_POW) -SIMPLE(OP_CLEANUP_WITH) -SIMPLE(OP_FILTER_EXCEPT) -SIMPLE(OP_BREAKPOINT) -SIMPLE(OP_YIELD) -SIMPLE(OP_ANNOTATE) -CONSTANT(OP_DEFINE_GLOBAL,(void)0) -CONSTANT(OP_CONSTANT,(void)0) -CONSTANT(OP_GET_GLOBAL,(void)0) -CONSTANT(OP_SET_GLOBAL,(void)0) -CONSTANT(OP_DEL_GLOBAL,(void)0) -CONSTANT(OP_CLASS,(void)0) -CONSTANT(OP_GET_PROPERTY, (void)0) -CONSTANT(OP_SET_PROPERTY, (void)0) -CONSTANT(OP_DEL_PROPERTY,(void)0) -CONSTANT(OP_CLASS_PROPERTY, (void)0) -CONSTANT(OP_CLOSURE, CLOSURE_MORE) -CONSTANT(OP_IMPORT, (void)0) -CONSTANT(OP_IMPORT_FROM, (void)0) -CONSTANT(OP_GET_SUPER, (void)0) -OPERAND(OP_KWARGS, (void)0) -OPERAND(OP_SET_LOCAL, LOCAL_MORE) -OPERAND(OP_GET_LOCAL, LOCAL_MORE) -OPERAND(OP_SET_UPVALUE, (void)0) -OPERAND(OP_GET_UPVALUE, (void)0) -OPERAND(OP_CALL, (void)0) -OPERAND(OP_INC, (void)0) -OPERAND(OP_TUPLE, (void)0) -OPERAND(OP_UNPACK, (void)0) -OPERAND(OP_DUP,(void)0) -OPERAND(OP_EXPAND_ARGS,EXPAND_ARGS_MORE) -OPERAND(OP_LIST_APPEND, (void)0) -OPERAND(OP_DICT_SET, (void)0) -OPERAND(OP_SET_ADD, (void)0) -OPERAND(OP_MAKE_LIST, (void)0) -OPERAND(OP_MAKE_DICT, (void)0) -OPERAND(OP_MAKE_SET, (void)0) -OPERAND(OP_REVERSE, (void)0) -JUMP(OP_JUMP,+) -JUMP(OP_JUMP_IF_FALSE,+) -JUMP(OP_JUMP_IF_TRUE,+) -JUMP(OP_LOOP,-) -JUMP(OP_PUSH_TRY,+) -JUMP(OP_PUSH_WITH,+) diff --git a/base/usr/include/kuroko/scanner.h b/base/usr/include/kuroko/scanner.h deleted file mode 100644 index d713adec..00000000 --- a/base/usr/include/kuroko/scanner.h +++ /dev/null @@ -1,186 +0,0 @@ -#pragma once -/** - * @file scanner.h - * @brief Definitions used by the token scanner. - */ - -typedef enum { - TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, - TOKEN_LEFT_BRACE, TOKEN_RIGHT_BRACE, - TOKEN_LEFT_SQUARE, TOKEN_RIGHT_SQUARE, - TOKEN_COLON, - TOKEN_COMMA, - TOKEN_DOT, - TOKEN_MINUS, - TOKEN_PLUS, - TOKEN_SEMICOLON, - TOKEN_SOLIDUS, - TOKEN_ASTERISK, - TOKEN_POW, - TOKEN_MODULO, - TOKEN_AT, - TOKEN_CARET, /* ^ (xor) */ - TOKEN_AMPERSAND, /* & (and) */ - TOKEN_PIPE, /* | (or) */ - TOKEN_TILDE, /* ~ (negate) */ - TOKEN_LEFT_SHIFT, /* << */ - TOKEN_RIGHT_SHIFT,/* >> */ - TOKEN_BANG, - TOKEN_GREATER, - TOKEN_LESS, - TOKEN_ARROW, /* -> */ - TOKEN_WALRUS, /* := */ - - /* Comparisons */ - TOKEN_GREATER_EQUAL, - TOKEN_LESS_EQUAL, - TOKEN_BANG_EQUAL, - TOKEN_EQUAL_EQUAL, - - /* Assignments */ - TOKEN_EQUAL, - TOKEN_LSHIFT_EQUAL, /* <<= */ - TOKEN_RSHIFT_EQUAL, /* >>= */ - TOKEN_PLUS_EQUAL, /* += */ - TOKEN_MINUS_EQUAL, /* -= */ - TOKEN_PLUS_PLUS, /* ++ */ - TOKEN_MINUS_MINUS, /* -- */ - TOKEN_CARET_EQUAL, - TOKEN_PIPE_EQUAL, - TOKEN_AMP_EQUAL, - TOKEN_SOLIDUS_EQUAL, - TOKEN_ASTERISK_EQUAL, - TOKEN_POW_EQUAL, - TOKEN_MODULO_EQUAL, - - TOKEN_STRING, - TOKEN_BIG_STRING, - TOKEN_NUMBER, - - /* - * Everything after this, up to indentation, - * consists of alphanumerics. - */ - TOKEN_IDENTIFIER, - TOKEN_AND, - TOKEN_CLASS, - TOKEN_DEF, - TOKEN_DEL, - TOKEN_ELSE, - TOKEN_FALSE, - TOKEN_FOR, - TOKEN_IF, - TOKEN_IMPORT, - TOKEN_IN, - TOKEN_IS, - TOKEN_LET, - TOKEN_NONE, - TOKEN_NOT, - TOKEN_OR, - TOKEN_ELIF, - TOKEN_PASS, - TOKEN_RETURN, - TOKEN_SELF, - TOKEN_SUPER, - TOKEN_TRUE, - TOKEN_WHILE, - TOKEN_TRY, - TOKEN_EXCEPT, - TOKEN_RAISE, - TOKEN_BREAK, - TOKEN_CONTINUE, - TOKEN_AS, - TOKEN_FROM, - TOKEN_LAMBDA, - TOKEN_ASSERT, - TOKEN_YIELD, - TOKEN_WITH, - - TOKEN_PREFIX_B, - TOKEN_PREFIX_F, - - TOKEN_INDENTATION, - - TOKEN_EOL, - TOKEN_RETRY, - TOKEN_ERROR, - TOKEN_EOF, -} KrkTokenType; - -/** - * @brief A token from the scanner. - * - * Represents a single scanned item from the scanner, such as a keyword, - * string literal, numeric literal, identifier, etc. - */ -typedef struct { - KrkTokenType type; - const char * start; - size_t length; - size_t line; - const char * linePtr; - size_t col; - size_t literalWidth; -} KrkToken; - -/** - * @brief Token scanner state. - * - * Stores the state of the compiler's scanner, reading from a source - * character string and tracking the current line. - */ -typedef struct { - const char * start; - const char * cur; - const char * linePtr; - size_t line; - int startOfLine; - int hasUnget; - KrkToken unget; -} KrkScanner; - -/** - * @brief Initialize the compiler to scan tokens from 'src'. - * - * FIXME: There is currently only a single static scanner state; - * along with making the compiler re-entrant, the scanner - * needs to also be re-entrant; there's really no reason - * these can't all just take a KrkScanner* argument. - */ -extern void krk_initScanner(const char * src); - -/** - * @brief Read the next token from the scanner. - * - * FIXME: Or, maybe the scanner shouldn't even be available outside - * of the compiler, that would make some sense as well, as it's - * a low-level detail, but we use it for tab completion in the - * main repl, so I'm not sure that's feasible right now. - */ -extern KrkToken krk_scanToken(void); - -/** - * @brief Push a token back to the scanner to be reprocessed. - * - * Pushes a previously-scanned token back to the scanner. - * Used to implement small backtracking operations at the - * end of block constructs like 'if' and 'try'. - */ -extern void krk_ungetToken(KrkToken token); - -/** - * @brief Rewind the scanner to a previous state. - * - * Resets the current scanner to the state in 'to'. Used by - * the compiler to implement comprehensions, which would otherwise - * not be possible in a single-pass compiler. - */ -extern void krk_rewindScanner(KrkScanner to); - -/** - * @brief Retreive a copy of the current scanner state. - * - * Used with krk_rewindScanner() to implement rescanning - * for comprehensions. - */ -extern KrkScanner krk_tellScanner(void); diff --git a/base/usr/include/kuroko/table.h b/base/usr/include/kuroko/table.h deleted file mode 100644 index 8ac343ab..00000000 --- a/base/usr/include/kuroko/table.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once -/** - * @file table.h - * @brief Implementation of a generic hash table. - * - * I was going to just use the ToaruOS hashmap library, but to make following - * the book easier, let's just start from their Table implementation; it has - * an advantage of using stored entries and fixed arrays, so it has some nice - * properties despite being chained internally... - */ - -#include -#include "kuroko.h" -#include "value.h" -#include "threads.h" - -/** - * @brief One (key,value) pair in a table. - */ -typedef struct { - KrkValue key; - KrkValue value; -} KrkTableEntry; - -/** - * @brief Simple hash table of arbitrary keys to values. - */ -typedef struct { - size_t count; - size_t capacity; - KrkTableEntry * entries; -} KrkTable; - -/** - * @brief Initialize a hash table. - * @memberof KrkTable - * - * This should be called for any new hash table, especially ones - * initialized in heap or stack space, to set up the capacity, count - * and initial entries pointer. - * - * @param table Hash table to initialize. - */ -extern void krk_initTable(KrkTable * table); - -/** - * @brief Release resources associated with a hash table. - * @memberof KrkTable - * - * Frees the entries array for the table and resets count and capacity. - * - * @param table Hash table to release. - */ -extern void krk_freeTable(KrkTable * table); - -/** - * @brief Add all key-value pairs from 'from' into 'to'. - * @memberof KrkTable - * - * Copies each key-value pair from one hash table to another. If a key - * from 'from' already exists in 'to', the existing value in 'to' will be - * overwritten with the value from 'from'. - * - * @param from Source table. - * @param to Destination table. - */ -extern void krk_tableAddAll(KrkTable * from, KrkTable * to); - -/** - * @brief Find a character sequence in the string interning table. - * @memberof KrkTable - * - * Scans through the entries in a given table - usually vm.strings - to find - * an entry equivalent to the string specified by the 'chars' and 'length' - * parameters, using the 'hash' parameter to speed up lookup. - * - * @param table Should always be @c &vm.strings - * @param chars C array of chars representing the string. - * @param length Length of the string. - * @param hash Precalculated hash value for the string. - * @return If the string was found, the string object representation, else NULL. - */ -extern KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t length, uint32_t hash); - -/** - * @brief Assign a value to a key in a table. - * @memberof KrkTable - * - * Inserts the key-value pair specified by 'key' and 'value' into the hash - * table 'table', replacing any value that was already preseng with the - * same key. - * - * @param table Table to assign to. - * @param key Key to assign. - * @param value Value to assign to the key. - * @return 0 if the key was already present and has been overwritten, 1 if the key is new to the table. - */ -extern int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value); - -/** - * @brief Obtain the value associated with a key in a table. - * @memberof KrkTable - * - * Scans the table 'table' for the key 'key' and, if found, outputs - * the associated value to *value. If the key is not found, then - * *value will not be changed. - * - * @param table Table to look up. - * @param key Key to look for. - * @param value Output pointer to place resulting value in. - * @return 0 if the key was not found, 1 if it was. - */ -extern int krk_tableGet(KrkTable * table, KrkValue key, KrkValue * value); - -/** - * @brief Remove a key from a hash table. - * @memberof KrkTable - * - * Scans the table 'table' for the key 'key' and, if found, removes - * the entry, replacing it with a tombstone value. - * - * @param table Table to delete from. - * @param key Key to delete. - * @return 1 if the value was found and deleted, 0 if it was not present. - */ -extern int krk_tableDelete(KrkTable * table, KrkValue key); - -/** - * @brief Internal table scan function. - * @memberof KrkTable - * - * Scans through the the entry array 'entries' to find the appropriate entry - * for 'key', return a pointer to the entry, which may be or may not have - * an associated pair. - * - * @param entries Table entry array to scan. - * @param capacity Size of the table entry array, in entries. - * @param key Key to locate. - * @return A pointer to the entry for 'key'. - */ -extern KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue key); - -/** - * @brief Calculate the hash for a value. - * @memberof KrkValue - * - * Retreives or calculates the hash value for 'value'. - * - * @param value Value to hash. - * @return An unsigned 32-bit hash value. - */ -extern uint32_t krk_hashValue(KrkValue value); - diff --git a/base/usr/include/kuroko/threads.h b/base/usr/include/kuroko/threads.h deleted file mode 100644 index ede5e91b..00000000 --- a/base/usr/include/kuroko/threads.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -/** - * @file threads.h - * @brief Convience header for providing atomic operations to threads. - */ - -#ifdef ENABLE_THREADING -#include -#include - -#ifdef _WIN32 -#include -#include -#define sched_yield() YieldProcessor() -#endif - -static inline void _krk_internal_spin_lock(int volatile * lock) { - while(__sync_lock_test_and_set(lock, 0x01)) { - sched_yield(); - } -} - -static inline void _krk_internal_spin_unlock(int volatile * lock) { - __sync_lock_release(lock); -} - -#define _obtain_lock(v) _krk_internal_spin_lock(&v); -#define _release_lock(v) _krk_internal_spin_unlock(&v); - -#else - -#define _obtain_lock(v) -#define _release_lock(v) - -#define pthread_rwlock_init(a,b) -#define pthread_rwlock_wrlock(a) -#define pthread_rwlock_rdlock(a) -#define pthread_rwlock_unlock(a) - -#endif - diff --git a/base/usr/include/kuroko/util.h b/base/usr/include/kuroko/util.h deleted file mode 100644 index c78c904b..00000000 --- a/base/usr/include/kuroko/util.h +++ /dev/null @@ -1,296 +0,0 @@ -#pragma once -/** - * @file util.h - * @brief Utilities for creating native bindings. - * - * This is intended for use in C extensions to provide a uniform interface - * for defining extension methods and ensuring they have consistent argument - * and keyword argument usage. - */ -#include "object.h" -#include "vm.h" -#include "memory.h" - -/* Quick macro for turning string constants into KrkString*s */ -#define S(c) (krk_copyString(c,sizeof(c)-1)) - -#define likely(cond) __builtin_expect(!!(cond), 1) -#define unlikely(cond) __builtin_expect(!!(cond), 0) -#ifndef _WIN32 -#define _noexport __attribute__((visibility("hidden"))) -#else -#define _noexport -#endif - -/** - * Binding macros. - * - * These macros are intended to be used together to define functions for a class. - */ -static inline const char * _method_name(const char * func) { - const char * out = func; - if (*out == '_') out++; - while (*out && *out != '_') out++; - if (*out == '_') out++; - return out; -} - -#define ADD_BASE_CLASS(obj, name, baseClass) krk_makeClass(vm.builtins, &obj, name, baseClass) - -/* _method_name works for this, but let's skip the inlined function call where possible */ -#define _function_name(f) (f+5) - -#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->attributeError, "attribute '%s' is not assignable", \ - _method_name(__func__)); } while (0) - -#define METHOD_TAKES_NONE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \ - _method_name(__func__), (argc-1)); } while (0) - -#define METHOD_TAKES_EXACTLY(n) do { if (argc != (n+1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ - _method_name(__func__), "exactly", n, (n != 1) ? "s" : "", (argc-1)); } while (0) - -#define METHOD_TAKES_AT_LEAST(n) do { if (argc < (n+1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ - _method_name(__func__), "at least", n, (n != 1) ? "s" : "", (argc-1)); } while (0) - -#define METHOD_TAKES_AT_MOST(n) do { if (argc > (n+1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ - _method_name(__func__), "at most", n, (n != 1) ? "s" : "", (argc-1)); } while (0) - -#define FUNCTION_TAKES_NONE() do { if (argc != 0) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \ - _function_name(__func__), (argc)); } while (0) - -#define FUNCTION_TAKES_EXACTLY(n) do { if (argc != n) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ - _function_name(__func__), "exactly", n, (n != 1) ? "s" : "", (argc)); } while (0) - -#define FUNCTION_TAKES_AT_LEAST(n) do { if (argc < n) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ - _function_name(__func__), "at least", n, (n != 1) ? "s" : "", (argc)); } while (0) - -#define FUNCTION_TAKES_AT_MOST(n) do { if (argc > n) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \ - _function_name(__func__), "at most", n, (n != 1) ? "s" : "", (argc)); } while (0) - -#define TYPE_ERROR(expected,value) krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'", \ - /* Function name */ _method_name(__func__), /* expected type */ #expected, krk_typeName(value)) - -#define NOT_ENOUGH_ARGS() krk_runtimeError(vm.exceptions->argumentError, "%s() missing required positional argument", \ - /* Function name */ _method_name(__func__)) - -#define CHECK_ARG(i, type, ctype, name) \ - if (argc < (i+1)) return NOT_ENOUGH_ARGS(); \ - if (!IS_ ## type (argv[i])) return TYPE_ERROR(type,argv[i]); \ - ctype name __attribute__((unused)) = AS_ ## type (argv[i]) - -#define FUNC_NAME(klass, name) _ ## klass ## _ ## name -#define FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (int argc, KrkValue argv[], int hasKw) -#define KRK_METHOD(klass, name, body) FUNC_SIG(klass, name) { \ - CHECK_ARG(0,klass,CURRENT_CTYPE,CURRENT_NAME); \ - body; return NONE_VAL(); } - -#define KRK_FUNC(name,body) static KrkValue _krk_ ## name (int argc, KrkValue argv[], int hasKw) { \ - body; return NONE_VAL(); } - -/* This assumes you have a KrkInstance called `module` in the current scope. */ -#define MAKE_CLASS(klass) do { krk_makeClass(module,&klass,#klass,vm.baseClasses->objectClass); klass ->allocSize = sizeof(struct klass); } while (0) -#define BIND_METHOD(klass,method) krk_defineNative(&klass->methods, "." #method, _ ## klass ## _ ## method) -#define BIND_FIELD(klass,method) krk_defineNative(&klass->methods, ":" #method, _ ## klass ## _ ## method) -#define BIND_PROP(klass,method) krk_defineNativeProperty(&klass->methods, #method, _ ## klass ## _ ## method) -#define BIND_FUNC(module,func) krk_defineNative(&module->fields, #func, _krk_ ## func) - -/** - * @brief Inline flexible string array. - */ -struct StringBuilder { - size_t capacity; - size_t length; - char * bytes; -}; - -/** - * @brief Add a character to the end of a string builder. - * - * @param sb String builder to append to. - * @param c Character to append. - */ -static inline void pushStringBuilder(struct StringBuilder * sb, char c) { - if (sb->capacity < sb->length + 1) { - size_t old = sb->capacity; - sb->capacity = GROW_CAPACITY(old); - sb->bytes = GROW_ARRAY(char, sb->bytes, old, sb->capacity); - } - sb->bytes[sb->length++] = c; -} - -/** - * @brief Append a string to the end of a string builder. - * - * @param sb String builder to append to. - * @param str C string to add. - * @param len Length of the C string. - */ -static inline void pushStringBuilderStr(struct StringBuilder * sb, char *str, size_t len) { - if (sb->capacity < sb->length + len) { - while (sb->capacity < sb->length + len) { - size_t old = sb->capacity; - sb->capacity = GROW_CAPACITY(old); - } - sb->bytes = realloc(sb->bytes, sb->capacity); - } - for (size_t i = 0; i < len; ++i) { - sb->bytes[sb->length++] = *(str++); - } -} - -/** - * @brief Finalize a string builder into a string object. - * - * Creates a string object from the contents of the string builder and - * frees the space allocated for the builder, returning a value representing - * the newly created string object. - * - * @param sb String builder to finalize. - * @return A value representing a string object. - */ -static inline KrkValue finishStringBuilder(struct StringBuilder * sb) { - KrkValue out = OBJECT_VAL(krk_copyString(sb->bytes, sb->length)); - FREE_ARRAY(char,sb->bytes, sb->capacity); - return out; -} - -/** - * @brief Finalize a string builder in a bytes object. - * - * Converts the contents of a string builder into a bytes object and - * frees the space allocated for the builder. - * - * @param sb String builder to finalize. - * @return A value representing a bytes object. - */ -static inline KrkValue finishStringBuilderBytes(struct StringBuilder * sb) { - KrkValue out = OBJECT_VAL(krk_newBytes(sb->length, (uint8_t*)sb->bytes)); - FREE_ARRAY(char,sb->bytes, sb->capacity); - return out; -} - -/** - * @brief Discard the contents of a string builder. - * - * Frees the resources allocated for the string builder without converting - * it to a string or bytes object. Call this when an error has been encountered - * and the contents of a string builder are no longer needed. - * - * @param sb String builder to discard. - * @return None, as a convenience. - */ -static inline KrkValue discardStringBuilder(struct StringBuilder * sb) { - FREE_ARRAY(char,sb->bytes, sb->capacity); - return NONE_VAL(); -} - -#define IS_int(o) (IS_INTEGER(o)) -#define AS_int(o) (AS_INTEGER(o)) - -#define IS_bool(o) (IS_BOOLEAN(o)) -#define AS_bool(o) (AS_BOOLEAN(o)) - -#define IS_float(o) (IS_FLOATING(o)) -#define AS_float(o) (AS_FLOATING(o)) - -#define IS_list(o) krk_isInstanceOf(o,vm.baseClasses->listClass) -#define AS_list(o) (KrkList*)AS_OBJECT(o) - -#define IS_listiterator(o) krk_isInstanceOf(o,vm.baseClasses->listiteratorClass) -#define AS_listiterator(o) AS_INSTANCE(o) - -#define IS_str(o) (IS_STRING(o)||krk_isInstanceOf(o,vm.baseClasses->strClass)) -#define AS_str(o) (KrkString*)AS_OBJECT(o) - -#define IS_striterator(o) (krk_isInstanceOf(o,vm.baseClasses->striteratorClass)) -#define AS_striterator(o) (AS_INSTANCE(o)) - -#define IS_dict(o) krk_isInstanceOf(o,vm.baseClasses->dictClass) -#define AS_dict(o) (KrkDict*)AS_OBJECT(o) - -#define IS_dictitems(o) krk_isInstanceOf(o,vm.baseClasses->dictitemsClass) -#define AS_dictitems(o) ((struct DictItems*)AS_OBJECT(o)) - -#define IS_dictkeys(o) krk_isInstanceOf(o,vm.baseClasses->dictkeysClass) -#define AS_dictkeys(o) ((struct DictKeys*)AS_OBJECT(o)) - -#define IS_bytesiterator(o) (krk_isInstanceOf(o,vm.baseClasses->bytesiteratorClass)) -#define AS_bytesiterator(o) (AS_INSTANCE(o)) - -#ifndef unpackError -#define unpackError(fromInput) return krk_runtimeError(vm.exceptions->typeError, "'%s' object is not iterable", krk_typeName(fromInput)); -#endif - -#define unpackIterable(fromInput) do { \ - KrkClass * type = krk_getType(fromInput); \ - if (type->_iter) { \ - size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack; \ - krk_push(fromInput); \ - krk_push(krk_callSimple(OBJECT_VAL(type->_iter), 1, 0)); \ - do { \ - krk_push(krk_currentThread.stack[stackOffset]); \ - krk_push(krk_callSimple(krk_peek(0), 0, 1)); \ - if (krk_valuesSame(krk_currentThread.stack[stackOffset], krk_peek(0))) { \ - krk_pop(); \ - krk_pop(); \ - break; \ - } \ - unpackArray(1,krk_peek(0)); \ - krk_pop(); \ - } while (1); \ - } else { \ - unpackError(fromInput); \ - } \ -} while (0) - -#define unpackIterableFast(fromInput) do { \ - KrkValue iterableValue = (fromInput); \ - if (IS_TUPLE(iterableValue)) { \ - unpackArray(AS_TUPLE(iterableValue)->values.count, AS_TUPLE(iterableValue)->values.values[i]); \ - } else if (IS_INSTANCE(iterableValue) && AS_INSTANCE(iterableValue)->_class == vm.baseClasses->listClass) { \ - unpackArray(AS_LIST(iterableValue)->count, AS_LIST(iterableValue)->values[i]); \ - } else if (IS_INSTANCE(iterableValue) && AS_INSTANCE(iterableValue)->_class == vm.baseClasses->dictClass) { \ - unpackArray(AS_DICT(iterableValue)->count, krk_dict_nth_key_fast(AS_DICT(iterableValue)->capacity, AS_DICT(iterableValue)->entries, i)); \ - } else if (IS_STRING(iterableValue)) { \ - unpackArray(AS_STRING(iterableValue)->codesLength, krk_string_get(2,(KrkValue[]){iterableValue,INTEGER_VAL(i)},0)); \ - } else { \ - unpackIterable(iterableValue); \ - } \ -} while (0) - -static inline void _setDoc_class(KrkClass * thing, const char * text, size_t size) { - thing->docstring = krk_copyString(text, size); -} -static inline void _setDoc_instance(KrkInstance * thing, const char * text, size_t size) { - krk_attachNamedObject(&thing->fields, "__doc__", (KrkObj*)krk_copyString(text, size)); -} -static inline void _setDoc_native(KrkNative * thing, const char * text, size_t size) { - (void)size; - thing->doc = text; -} - -/** - * @def KRK_DOC(thing,text) - * @brief Attach documentation to a thing of various types. - * - * Classes store their docstrings directly, rather than in their attribute tables. - * Instances use the attribute table and store strings with the name @c \__doc__. - * Native functions store direct C string pointers for documentation. - * - * This macro provides a generic interface for applying documentation strings to - * any of the above types, and handles not attaching documentation when built - * with KRK_NO_DOCUMENTATION. - */ -#ifdef KRK_NO_DOCUMENTATION -# define KRK_DOC(thing, text) (thing); -#else -# define KRK_DOC(thing, text) \ - _Generic(&((thing)[0]), \ - KrkClass*: _setDoc_class, \ - KrkInstance*: _setDoc_instance, \ - KrkNative*: _setDoc_native \ - )(thing,text,sizeof(text)-1) -#endif - -#define BUILTIN_FUNCTION(name, func, docStr) KRK_DOC(krk_defineNative(&vm.builtins->fields, name, func), docStr) - diff --git a/base/usr/include/kuroko/value.h b/base/usr/include/kuroko/value.h deleted file mode 100644 index 79587ae1..00000000 --- a/base/usr/include/kuroko/value.h +++ /dev/null @@ -1,210 +0,0 @@ -#pragma once -/** - * @file value.h - * @brief Definitions for primitive stack references. - */ -#include -#include "kuroko.h" - -/** - * @brief Base structure of all heap objects. - * - * KrkObj is the base type of all objects stored on the heap and - * managed by the garbage collector. - */ -typedef struct KrkObj KrkObj; -typedef struct KrkString KrkString; - -/** - * @brief Tag enum for basic value types. - * - * Value types are tagged unions of a handful of small - * types represented directly on the stack: Integers, - * double-precision floating point values, booleans, - * exception handler references, complex function argument - * processing sentinels, object reference pointers, and None. - */ -typedef enum { - KRK_VAL_NONE, - KRK_VAL_BOOLEAN, - KRK_VAL_INTEGER, - KRK_VAL_FLOATING, - KRK_VAL_HANDLER, - KRK_VAL_OBJECT, - KRK_VAL_KWARGS, -} KrkValueType; - -/** - * @brief Stack value representation of a 'with' or 'try' block. - * - * When a 'with' or 'try' block is entered, a handler value is - * created on the stack representing the type (with, try) and the - * jump target to leave the block (entering the 'except' block of - * a 'try', if present, or calling the __exit__ method of an object - * __enter__'d by a 'with' block). When the relevant conditions are - * triggered in the VM, the stack will be scanned from top to bottom - * to look for these values. - */ -typedef struct { - unsigned short type; - unsigned short target; -} KrkJumpTarget; - -/** - * @brief Stack reference or primative value. - * - * This type stores a stack reference to an object, or the contents of - * a primitive type. Each VM thread's stack consists of an array of - * these values, and they are generally passed around in the VM through - * direct copying rather than as pointers, avoiding the need to track - * memory used by them. - * - * Each value is a tagged union with a type (see the enum KrkValueType) - * and its contents. - */ -typedef struct { - KrkValueType type; - union { - char boolean; - krk_integer_type integer; - double floating; - KrkJumpTarget handler; - KrkObj * object; - } as; -} KrkValue; - -/** - * @brief Flexible vector of stack references. - * - * Value Arrays provide a resizable collection of values and are the - * backbone of lists and tuples. - */ -typedef struct { - size_t capacity; /**< Available allocated space. */ - size_t count; /**< Current number of used slots. */ - KrkValue * values; /**< Pointer to heap-allocated storage. */ -} KrkValueArray; - -/** - * @brief Initialize a value array. - * @memberof KrkValueArray - * - * This should be called for any new value array, especially ones - * initialized in heap or stack space, to set up the capacity, count - * and initial value pointer. - * - * @param array Value array to initialize. - */ -extern void krk_initValueArray(KrkValueArray * array); - -/** - * @brief Add a value to a value array. - * @memberof KrkValueArray - * - * Appends 'value' to the end of the given array, adjusting count values - * and resizing as necessary. - * - * @param array Array to append to. - * @param value Value to append to array. - */ -extern void krk_writeValueArray(KrkValueArray * array, KrkValue value); - -/** - * @brief Release relesources used by a value array. - * @memberof KrkValueArray - * - * Frees the storage associated with a given value array and resets - * its capacity and count. Does not directly free resources associated - * with heap objects referenced by the values in this array: The GC - * is responsible for taking care of that. - * - * @param array Array to release. - */ -extern void krk_freeValueArray(KrkValueArray * array); - -/** - * @brief Print a string representation of a value. - * @memberof KrkValue - * - * Print a string representation of 'value' to the stream 'f'. - * For primitives, performs appropriate formatting. For objects, - * this will call __str__ on the object's representative type. - * If the type does not have a __str__ method, __repr__ will be - * tried before falling back to krk_typeName to directly print - * the name of the class with no information on the value. - * - * This function provides the backend for the print() built-in. - * - * @param f Stream to write to. - * @param value Value to display. - */ -extern void krk_printValue(FILE * f, KrkValue value); - -/** - * @brief Print a value without calling the VM. - * @memberof KrkValue - * - * Print a string representation of 'value' to the stream 'f', - * avoiding calls to managed code by using simplified representations - * where necessary. This is intended for use in debugging code, such - * as during disassembly, or when printing values in an untrusted context. - * - * @note This function will truncate long strings and print them in a form - * closer to the 'repr()' representation, with escaped bytes, rather - * than directly printing them to the stream. - * - * @param f Stream to write to. - * @param value Value to display. - */ -extern void krk_printValueSafe(FILE * f, KrkValue value); - -/** - * @brief Compare two values for equality. - * @memberof KrkValue - * - * Performs a relaxed equality comparison between two values, - * check for equivalence by contents. This may call managed - * code to run __eq__ methods. - * - * @return 1 if values are equivalent, 0 otherwise. - */ -extern int krk_valuesEqual(KrkValue a, KrkValue b); - -/** - * @brief Compare two values by identity. - * @memberof KrkValue - * - * Performs a strict comparison between two values, comparing - * their identities. For primitive values, this is generally - * the same as comparing by equality. For objects, this compares - * pointer values directly. - * - * @return 1 if values represent the same object or value, 0 otherwise. - */ -extern int krk_valuesSame(KrkValue a, KrkValue b); - -#define BOOLEAN_VAL(value) ((KrkValue){KRK_VAL_BOOLEAN, {.integer = value}}) -#define NONE_VAL(value) ((KrkValue){KRK_VAL_NONE, {.integer = 0}}) -#define INTEGER_VAL(value) ((KrkValue){KRK_VAL_INTEGER, {.integer = value}}) -#define FLOATING_VAL(value) ((KrkValue){KRK_VAL_FLOATING,{.floating = value}}) -#define HANDLER_VAL(ty,ta) ((KrkValue){KRK_VAL_HANDLER, {.handler = (KrkJumpTarget){.type = ty, .target = ta}}}) -#define OBJECT_VAL(value) ((KrkValue){KRK_VAL_OBJECT, {.object = (KrkObj*)value}}) -#define KWARGS_VAL(value) ((KrkValue){KRK_VAL_KWARGS, {.integer = value}}) - -#define AS_BOOLEAN(value) ((value).as.integer) -#define AS_INTEGER(value) ((value).as.integer) -#define AS_FLOATING(value) ((value).as.floating) -#define AS_HANDLER(value) ((value).as.handler) -#define AS_OBJECT(value) ((value).as.object) - -#define IS_BOOLEAN(value) ((value).type == KRK_VAL_BOOLEAN) -#define IS_NONE(value) ((value).type == KRK_VAL_NONE) -#define IS_INTEGER(value) (((value).type == KRK_VAL_INTEGER) || ((value.type) == KRK_VAL_BOOLEAN)) -#define IS_FLOATING(value) ((value).type == KRK_VAL_FLOATING) -#define IS_HANDLER(value) ((value).type == KRK_VAL_HANDLER) -#define IS_OBJECT(value) ((value).type == KRK_VAL_OBJECT) -#define IS_KWARGS(value) ((value).type == KRK_VAL_KWARGS) - -#define IS_TRY_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_PUSH_TRY) -#define IS_WITH_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_PUSH_WITH) - diff --git a/base/usr/include/kuroko/vm.h b/base/usr/include/kuroko/vm.h deleted file mode 100644 index 41ea3983..00000000 --- a/base/usr/include/kuroko/vm.h +++ /dev/null @@ -1,820 +0,0 @@ -#pragma once -/** - * @file vm.h - * @brief Core API for the bytecode virtual machine. - * - * Functions and structures declared here make up the bulk of the public C API - * for Kuroko, including initializing the VM and passing code to be interpreted. - */ -#include -#include -#include "kuroko.h" -#include "value.h" -#include "table.h" -#include "object.h" - -/** - * @def KRK_CALL_FRAMES_MAX - * @brief Maximum depth of the call stack in managed-code function calls. - */ -#define KRK_CALL_FRAMES_MAX 64 - -/** - * @def KRK_THREAD_SCRATCH_SIZE - * @brief Extra space for each thread to store a set of working values safe from the GC. - * - * Various operations require threads to remove values from the stack but ensure - * they are not lost to garbage collection. This space allows each thread to keep - * a few things around during those operations. - */ -#define KRK_THREAD_SCRATCH_SIZE 3 - -/** - * @brief Represents a managed call state in a VM thread. - * - * For every managed function call, including the top-level module, - * a call frame is added to the stack to track the running function, - * the current opcode instruction, the offset into the stack, and - * the valid globals table. - * - * Call frames are used directly by the VM as the source of - * opcodes and operands during execution, and are used by the exception - * handler to roll back execution to the appropriate environment. - */ -typedef struct { - KrkClosure * closure; /**< Pointer to the function object containing the code object for this frame */ - uint8_t * ip; /**< Instruction pointer within the code object's bytecode data */ - size_t slots; /**< Offset into the stack at which this function call's arguments begin */ - size_t outSlots; /**< Offset into the stack at which stackTop will be reset upon return */ - KrkTable * globals; /**< Pointer to the attribute table containing valud global vairables for this call */ -} KrkCallFrame; - -/** - * @brief Index numbers for always-available interned strings representing important method and member names. - * - * The VM must look up many methods and members by fixed names. To avoid - * continuously having to box and unbox these from C strings to the appropriate - * interned @c KrkString, we keep an array of the @c KrkString pointers in the global VM state. - * - * These values are the offsets into that index for each of the relevant - * function names (generally with extra underscores removed). For example - * @c METHOD_INIT is the offset for the string value for @c "__init__". - */ -typedef enum { - METHOD_INIT, - METHOD_STR, - METHOD_REPR, - METHOD_GET, - METHOD_SET, - METHOD_CLASS, - METHOD_NAME, - METHOD_FILE, - METHOD_INT, - METHOD_FLOAT, - METHOD_CHR, - METHOD_LEN, - METHOD_DOC, - METHOD_BASE, - METHOD_GETSLICE, - METHOD_ORD, - METHOD_CALL, - METHOD_EQ, - METHOD_ENTER, - METHOD_EXIT, - METHOD_DELITEM, - METHOD_ITER, - METHOD_GETATTR, - METHOD_DIR, - METHOD_SETSLICE, - METHOD_DELSLICE, - METHOD_CONTAINS, - METHOD_DESCGET, - METHOD_DESCSET, - METHOD_CLASSGETITEM, - - METHOD__MAX, -} KrkSpecialMethods; - -/** - * @brief Table of basic exception types. - * - * These are the core exception types, available in managed code - * from the builtin namespace. A single instance of this struct - * is attached to the global VM state so that C code can quickly - * access these exception types for use with krk_runtimeException. - * - * @see krk_runtimeException - */ -struct Exceptions { - KrkClass * baseException; /**< @exception Exception The base exception type. */ - KrkClass * typeError; /**< @exception TypeError An argument or value was not of the expected type. */ - KrkClass * argumentError; /**< @exception ArgumentException The number of arguments passed to a function was not as expected. */ - KrkClass * indexError; /**< @exception IndexError An attempt was made to reference an invalid array index. */ - KrkClass * keyError; /**< @exception KeyError An attempt was made to reference an invalid mapping key. */ - KrkClass * attributeError; /**< @exception AttributeError An attempt was made to reference an invalid object property. */ - KrkClass * nameError; /**< @exception NameError An attempt was made to reference an undeclared global variable. */ - KrkClass * importError; /**< @exception ImportError An error was encountered when attempting to import a module. */ - KrkClass * ioError; /**< @exception IOError An error was encountered in operating system's IO library. */ - KrkClass * valueError; /**< @exception ValueError The value of a parameter or variable is not valid. */ - KrkClass * keyboardInterrupt; /**< @exception KeyboardInterrupt An interrupt signal was received. */ - KrkClass * zeroDivisionError; /**< @exception ZeroDivisionError A mathematical function attempted to divide by zero. */ - KrkClass * notImplementedError; /**< @exception NotImplementedError The method is not implemented, either for the given arguments or in general. */ - KrkClass * syntaxError; /**< @exception SyntaxError The compiler encountered an unrecognized or invalid source code input. */ - KrkClass * assertionError; /**< @exception AssertionError An @c assert statement failed. */ -}; - -/** - * @brief Table of classes for built-in object types. - * - * For use by C modules and within the VM, an instance of this struct - * is attached to the global VM state. At VM initialization, each - * built-in class is attached to this table, and the class values - * stored here are used for integrated type checking with krk_isInstanceOf. - * - * @note As this and other tables are used directly by embedders, do not - * reorder the layout of the individual class pointers, even if - * it looks nicer. The ordering here is part of our library ABI. - */ -struct BaseClasses { - KrkClass * objectClass; /**< The base of all classes within the type tree. */ - KrkClass * moduleClass; /**< A class for representing imported modules, both managed and C. */ - KrkClass * typeClass; /**< Classes themselves are of this class. */ - KrkClass * intClass; /**< Primitive integer type. */ - KrkClass * floatClass; /**< Primitive double-precision floating-point type. */ - KrkClass * boolClass; /**< Primitive boolean type. */ - KrkClass * noneTypeClass; /**< The class of the None value. */ - KrkClass * strClass; /**< Built-in Unicode string type. */ - KrkClass * functionClass; /**< Represents a function object (KrkClosure) or native bind (KrkNative) */ - KrkClass * methodClass; /**< Represents a bound method (KrkBoundMethod) */ - KrkClass * tupleClass; /**< An immutable collection of arbitrary values. */ - KrkClass * bytesClass; /**< An immutable sequence of bytes. */ - KrkClass * listiteratorClass; /**< Iterator over lists */ - KrkClass * rangeClass; /**< An object representing a start and end point for a sequence of integers. */ - KrkClass * rangeiteratorClass; /**< Iterator over a range of values */ - KrkClass * striteratorClass; /**< Iterator over characters (by codepoint) in a string */ - KrkClass * tupleiteratorClass; /**< Iterator over values in a tuple */ - KrkClass * listClass; /**< Mutable collection of arbitrary values. */ - KrkClass * dictClass; /**< Mutable mapping of hashable keys to arbitrary values. */ - KrkClass * dictitemsClass; /**< Iterator over the (key,value) pairs of a dict */ - KrkClass * dictkeysClass; /**< Iterator over the keys of a dict */ - KrkClass * bytesiteratorClass; /**< Iterator over the integer byte values of a bytes object. */ - KrkClass * propertyClass; /**< Magic object that calls a function when accessed from an instance through the dot operator. */ - KrkClass * codeobjectClass; /**< Static compiled bytecode container (KrkCodeObject) */ - KrkClass * generatorClass; /**< Generator object. */ -}; - -/** - * @brief Execution state of a VM thread. - * - * Each thread in the VM has its own local thread state, which contains - * the thread's stack, stack pointer, call frame stack, a thread-specific - * VM flags bitarray, and an exception state. - * - * @see krk_currentThread - */ -typedef struct KrkThreadState { - struct KrkThreadState * next; /**< Invasive list pointer to next thread. */ - - KrkCallFrame * frames; /**< Call frame stack for this thread, max KRK_CALL_FRAMES_MAX */ - size_t frameCount; /**< Number of active call frames. */ - size_t stackSize; /**< Size of the allocated stack space for this thread. */ - KrkValue * stack; /**< Pointer to the bottom of the stack for this thread. */ - KrkValue * stackTop; /**< Pointer to the top of the stack. */ - KrkUpvalue * openUpvalues; /**< Flexible array of unclosed upvalues. */ - ssize_t exitOnFrame; /**< When called in a nested context, the frame offset to exit the VM dispatch loop on. */ - - KrkInstance * module; /**< The current module execution context. */ - KrkValue currentException; /**< When an exception is thrown, it is stored here. */ - int flags; /**< Thread-local VM flags; each thread inherits the low byte of the global VM flags. */ - long watchdog; /**< Decrementing watchdog timer for embedding. */ - - KrkValue scratchSpace[KRK_THREAD_SCRATCH_SIZE]; /**< A place to store a few values to keep them from being prematurely GC'd. */ -} KrkThreadState; - -/** - * @brief Global VM state. - * - * This state is shared by all VM threads and stores the - * path to the VM binary, global execution flags, the - * string and module tables, tables of builtin types, - * and the state of the (shared) garbage collector. - */ -typedef struct KrkVM { - int globalFlags; /**< Global VM state flags */ - char * binpath; /**< A string representing the name of the interpreter binary. */ - KrkTable strings; /**< Strings table */ - KrkTable modules; /**< Module cache */ - KrkInstance * builtins; /**< '\__builtins__' module */ - KrkInstance * system; /**< 'kuroko' module */ - KrkValue * specialMethodNames; /**< Cached strings of important method and function names */ - struct BaseClasses * baseClasses; /**< Pointer to a (static) namespacing struct for the KrkClass*'s of built-in object types */ - struct Exceptions * exceptions; /**< Pointer to a (static) namespacing struct for the KrkClass*'s of basic exception types */ - - /* Garbage collector state */ - KrkObj * objects; /**< Linked list of all objects in the GC */ - size_t bytesAllocated; /**< Running total of bytes allocated */ - size_t nextGC; /**< Point at which we should sweep again */ - size_t grayCount; /**< Count of objects marked by scan. */ - size_t grayCapacity; /**< How many objects we can fit in the scan list. */ - KrkObj** grayStack; /**< Scan list */ - - KrkThreadState * threads; /**< Invasive linked list of all VM threads. */ -} KrkVM; - -/* Thread-specific flags */ -#define KRK_THREAD_ENABLE_TRACING (1 << 0) -#define KRK_THREAD_ENABLE_DISASSEMBLY (1 << 1) -#define KRK_THREAD_ENABLE_SCAN_TRACING (1 << 2) -#define KRK_THREAD_HAS_EXCEPTION (1 << 3) -#define KRK_THREAD_SINGLE_STEP (1 << 4) -#define KRK_THREAD_SIGNALLED (1 << 5) - -/* Global flags */ -#define KRK_GLOBAL_ENABLE_STRESS_GC (1 << 8) -#define KRK_GLOBAL_GC_PAUSED (1 << 9) -#define KRK_GLOBAL_CLEAN_OUTPUT (1 << 10) - -#ifdef ENABLE_THREADING -# define threadLocal __thread -#else -# define threadLocal -#endif - -/** - * @brief Thread-local VM state. - * - * See @c KrkThreadState for more information. - */ -#if defined(_WIN32) && !defined(KRKINLIB) -#define krk_currentThread (*krk_getCurrentThread()) -#else -extern threadLocal KrkThreadState krk_currentThread; -#endif - -/** - * @brief Singleton instance of the shared VM state. - */ -extern KrkVM krk_vm; - -/** - * @def vm - * @brief Convenience macro for namespacing. - */ -#define vm krk_vm - -/** - * @brief Initialize the VM at program startup. - * @memberof KrkVM - * - * All library users must call this exactly once on startup to create - * the built-in types, modules, and functions for the VM and prepare - * the string and module tables. Optionally, callers may set `vm.binpath` - * before calling krk_initVM to allow the VM to locate the interpreter - * binary and establish the default module paths. - * - * @param flags Combination of global VM flags and initial thread flags. - */ -extern void krk_initVM(int flags); - -/** - * @brief Release resources from the VM. - * @memberof KrkVM - * - * Generally, it is desirable to call this once before the hosting program exits. - * If a fresh VM state is needed, krk_freeVM should be called before a further - * call to krk_initVM is made. The resources released here can include allocated - * heap memory, FILE pointers or descriptors, or various other things which were - * initialized by C extension modules. - */ -extern void krk_freeVM(void); - -/** - * @brief Reset the current thread's stack state to the top level. - * - * In a repl, this should be called before or after each iteration to clean up any - * remnant stack entries from an uncaught exception. It should not be called - * during normal execution by C extensions. Values on the stack may be lost - * to garbage collection after a call to @c krk_resetStack . - */ -extern void krk_resetStack(void); - -/** - * @brief Compile and execute a source code input. - * - * This is the lowest level call for most usecases, including execution - * of commands from a REPL or when executing a file. - * - * @param src Source code to compile and run. - * @param fromFile Path to the source file, or a representative string like "". - * @return The value of the executed code, which is either the value of an explicit 'return' - * statement, or the last expression value from an executed statement. If an uncaught - * exception occurred, this will be @c None and @c krk_currentThread.flags should - * indicate @c KRK_THREAD_HAS_EXCEPTION and @c krk_currentThread.currentException - * should contain the raised exception value. - */ -extern KrkValue krk_interpret(const char * src, char * fromFile); - -/** - * @brief Load and run a source file and return when execution completes. - * - * Loads and runs a source file. Can be used by interpreters to run scripts, - * either in the context of a new a module or as if they were continuations - * of the current module state (eg. as if they were lines entered on a repl) - * - * @param fileName Path to the source file to read and execute. - * @param fromFile Value to assign to @c \__file__ - * @return As with @c krk_interpret, an object representing the newly created module, - * or the final return value of the VM execution. - */ -extern KrkValue krk_runfile(const char * fileName, char * fromFile); - -/** - * @brief Load and run a file as a module. - * - * Similar to @c krk_runfile but ensures that execution of the VM returns to the caller - * after the file is run. This should be run after calling @c krk_startModule to initialize - * a new module context and is used internally by the import mechanism. - * - * @param fileName Path to the source file to read and execute. - * @param fromFile Value to assign to @c \__file__ - * @return The object representing the module, or None if execution of the file failed. - */ -extern KrkValue krk_callfile(const char * fileName, char * fromFile); - -/** - * @brief Push a stack value. - * - * Pushes a value onto the current thread's stack, triggering a - * stack resize if there is not enough space to hold the new value. - * - * @param value Value to push. - */ -extern void krk_push(KrkValue value); - -/** - * @brief Pop the top of the stack. - * - * Removes and returns the value at the top of current thread's stack. - * Generally, it is preferably to leave values on the stack and use - * krk_peek if the value is desired, as removing a value from the stack - * may result in it being garbage collected. - * - * @return The value previously at the top of the stack. - */ -extern KrkValue krk_pop(void); - -/** - * @brief Peek down from the top of the stack. - * - * Obtains a value from the current thread's stack without modifying the stack. - * - * @param distance How far down from the top of the stack to peek (0 = the top) - * @return The value from the stack. - */ -extern KrkValue krk_peek(int distance); - -/** - * @brief Swap the top of the stack of the value @p distance slots down. - * - * Exchanges the values at the top of the stack and @p distance slots from the top - * without removing or shuffling anything in between. - * - * @param distance How from down from the top of the stack to swap (0 = the top) - */ -extern void krk_swap(int distance); - -/** - * @brief Get the name of the type of a value. - * @memberof KrkValue - * - * Obtains the C string representing the name of the class - * associated with the given value. Useful for crafting - * exception messages, such as those describing TypeErrors. - * - * @param value Value to examine - * @return Nul-terminated C string of the type of @p value - */ -extern const char * krk_typeName(KrkValue value); - -/** - * @brief Attach a native C function to an attribute table. - * @memberof KrkTable - * - * Attaches the given native function pointer to an attribute table - * while managing the stack shuffling and boxing of both the name and - * the function object. If @p name begins with a '.', the native function - * is marked as a method. If @p name begins with a ':', the native function - * is marked as a dynamic property. - * - * @param table Attribute table to attach to, such as @c &someInstance->fields - * @param name Nil-terminated C string with the name to assign - * @param function Native function pointer to attach - * @return A pointer to the object representing the attached function. - */ -extern KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn function); - -/** - * @brief Attach a native dynamic property to an attribute table. - * @memberof KrkTable - * - * Mostly the same as @c krk_defineNative, but ensures the creation of a dynamic property. - * The intention of this function is to replace uses of defineNative with ":" names, - * and replace specialized methods with @c KrkProperty* objects. - * - * @param table Attribute table to attach to, such as @c &someInstance->fields - * @param name Nil-terminated C string with the name to assign - * @param func Native function pointer to attach - * @return A pointer to the property object created. - */ -extern KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, NativeFn func); - -/** - * @brief Attach a value to an attribute table. - * @memberof KrkTable - * - * Manages the stack shuffling and boxing of the name string when attaching - * a value to an attribute table. Rather than using @c krk_tableSet, this is - * the preferred method of supplying fields to objects from C code. - * - * @param table Attribute table to attach to, such as @c &someInstance->fields - * @param name Nil-terminated C string with the name to assign - * @param obj Value to attach. - */ -extern void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue obj); - -/** - * @brief Attach an object to an attribute table. - * @memberof KrkTable - * - * Manages the stack shuffling and boxing of the name string when attaching - * an object to an attribute table. Rather than using @c krk_tableSet, this is - * the preferred method of supplying fields to objects from C code. - * - * This is a convenience wrapper around @c krk_attachNamedValue. - * - * @param table Attribute table to attach to, such as @c &someInstance->fields - * @param name Nil-terminated C string with the name to assign - * @param obj Object to attach. - */ -extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj); - -/** - * @brief Raise an exception. - * - * Creates an instance of the given exception type, passing a formatted - * string to the initializer. All of the core exception types take an option - * string value to attach to the exception, but third-party exception types - * may have different initializer signatures and need separate initialization. - * - * The created exception object is attached to the current thread state and - * the @c KRK_THREAD_HAS_EXCEPTION flag is set. - * - * @param type Class pointer for the exception type, eg. @c vm.exceptions->valueError - * @param fmt Format string. - * @return As a convenience to C extension authors, returns @c None - */ -extern KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...); - -/** - * @brief Get a pointer to the current thread state. - * - * Generally equivalent to @c &krk_currentThread, though @c krk_currentThread - * itself may be implemented as a macro that calls this function depending - * on the platform's thread support. - * - * @return Pointer to current thread's thread state. - */ -extern KrkThreadState * krk_getCurrentThread(void); - -/** - * @brief Continue VM execution until the next exit trigger. - * - * Resumes the VM dispatch loop, returning to the caller when - * the next exit trigger event happens. Generally, callers will - * want to set the current thread's exitOnFrame before calling - * @c krk_runNext. Alternatively, see @c krk_callValue which manages - * exit triggers automatically when calling function objects. - * - * @return Value returned by the exit trigger, generally the value - * returned by the inner function before the VM returned - * to the exit frame. - */ -extern KrkValue krk_runNext(void); - -/** - * @brief Get the class representing a value. - * @memberof KrkValue - * - * Returns the class object representing the type of a value. - * This may be the direct class of an instance, or a pseudoclass - * for other value types. - * - * @param value Reference value to examine. - * @return A pointer to the value's type's class object. - */ -extern KrkClass * krk_getType(KrkValue value); - -/** - * @brief Determine if a class is an instance or subclass of a given type. - * @memberof KrkValue - * - * Searches the class hierarchy of the given value to determine if it is - * a subtype of @p type. As this chains through the inheritence tree, the - * more deeply subclassed @p obj is, the longer it may take to determine - * if it is a subtype of @p type. All types should eventually be subtypes - * of the @ref object type, so this condition should not be checked. For - * some types, convenience macros are available. If you need to check if - * @p obj is a specific type, exclusive of subtypes, look at - * @c krk_getType() instead of using this function. - * - * @param obj Value to examine. - * @param type Class object to test for membership of. - * @return 1 if @p obj is an instance of @p type or of a subclass of @p type - */ -extern int krk_isInstanceOf(KrkValue obj, KrkClass * type); - -/** - * @brief Perform method binding on the stack. - * @memberof KrkClass - * - * Performs attribute lookup from the class @p _class for @p name. - * If @p name is not a valid method, the binding fails. - * If @p name is a valid method, the method will be retrieved and - * bound to the instance on the top of the stack, replacing it - * with a @ref BoundMethod object. - * - * @param _class Class object to resolve methods from. - * @param name String object with the name of the method to resolve. - * @return 1 if the method has been bound, 0 if binding failed. - */ -extern int krk_bindMethod(KrkClass * _class, KrkString * name); - -/** - * @brief Call a callable value in the current stack context. - * @memberof KrkValue - * - * Executes the given callable object (function, bound method, object - * with a @c \__call__() method, etc.) using @p argCount arguments from the stack. - * - * @param callee Value referencing a callable object. - * @param argCount Arguments to retreive from stack. - * @param extra Whether extra arguments below argCount should be - * considered as part of this call frame. Generally, - * when this is 1, the value below the arguments is - * the callable object. Most library users will want - * to leave this as 0 when calling normal functions, - * bound method objects, or ubound methods when the - * instance is included in the arguments already. - * @return An indicator of how the result should be obtained: - * 1: The VM must be resumed to run managed code. - * 2: The callable was a native function and result should be popped now. - * Else: The call failed. An exception may have already been set. - */ -extern int krk_callValue(KrkValue callee, int argCount, int extra); - -/** - * @brief Create a list object. - * @memberof KrkList - * - * This is the native function bound to @c listOf - */ -extern KrkValue krk_list_of(int argc, KrkValue argv[], int hasKw); - -/** - * @brief Create a dict object. - * @memberof KrkDict - * - * This is the native function bound to @c dictOf - */ -extern KrkValue krk_dict_of(int argc, KrkValue argv[], int hasKw); - -/** - * @brief Create a tuple object. - * @memberof KrkTuple - * - * This is the native function bound to @c tupleOf - */ -extern KrkValue krk_tuple_of(int argc, KrkValue argv[], int hasKw); - -/** - * @brief Create a set object. - * @memberof Set - * - * This is the native function bound to @c setOf - */ -extern KrkValue krk_set_of(int argc, KrkValue argv[], int hasKw); - -/** - * @brief Call a callable and manage VM state to obtain the return value. - * @memberof KrkValue - * - * This is a wrapper around various mechanisms including krk_callValue - * intended for use by C extensions to call arbitrary functions without - * knowledge of their implementation details. See the notes for - * @c krk_callValue 's @c extra paramater for details on how @p isMethod is used. - * - * @param value Callable object reference. - * @param argCount Arguments to collect from the stack. - * @param isMethod This should almost always be 0. - * @return The return value of the function. - */ -extern KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod); - -/** - * @brief Convenience function for creating new types. - * @memberof KrkClass - * - * Creates a class object, output to @p _class, setting its name to @p name, inheriting - * from @p base, and attaching it with its name to the fields table of the given @p module. - * - * @param module Pointer to an instance for a module to attach to, or @c NULL to skip attaching. - * @param _class Output pointer to assign the new class object to. - * @param name Name of the new class. - * @param base Pointer to class object to inherit from. - * @return A pointer to the class object, equivalent to the value assigned to @p _class. - */ -extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base); - -/** - * @brief Finalize a class by collecting pointers to core methods. - * @memberof KrkClass - * - * Scans through the methods table of a class object to find special - * methods and assign them to the class object's pointer table so they - * can be referenced directly without performing hash lookups. - * - * @param _class Class object to finalize. - */ -extern void krk_finalizeClass(KrkClass * _class); - -/** - * @brief If there is an active exception, print a traceback to @c stderr - * - * This function is exposed as a convenience for repl developers. Normally, - * the VM will call @c krk_dumpTraceback() itself if an exception is unhandled and no - * exit trigger is current set. The traceback is obtained from the exception - * object. If the exception object does not have a traceback, only the - * exception itself will be printed. The traceback printer will attempt to - * open source files to print faulting lines and may call into the VM if the - * exception object has a managed implementation of @c \__str__. - */ -extern void krk_dumpTraceback(); - -/** - * @brief Set up a new module object in the current thread. - * - * Creates a new instance of the module type and attaches a @c \__builtins__ - * reference to its fields. The module becomes the current thread's - * main module, but is not directly attached to the module table. - * - * @param name Name of the module, which is assigned to @c \__name__ - * @return The instance object representing the module. - */ -extern KrkInstance * krk_startModule(const char * name); - -/** - * @brief Obtain a list of properties for an object. - * - * This is the native function bound to @c object.__dir__ - */ -extern KrkValue krk_dirObject(int argc, KrkValue argv[], int hasKw); - -/** - * @brief Load a module from a file with a specified name. - * - * This is generally called by the import mechanisms to load a single module and - * will establish a module context internally to load the new module into, return - * a KrkValue representing that module context through the @p moduleOut parameter. - * - * @param path Dotted path of the module, used for file lookup. - * @param moduleOut Receives a value with the module object. - * @param runAs Name to attach to @c \__name__ for this module, different from @p path - * @return 1 if the module was loaded, 0 if an @ref ImportError occurred. - */ -extern int krk_loadModule(KrkString * path, KrkValue * moduleOut, KrkString * runAs); - -/** - * @brief Load a module by a dotted name. - * - * Given a package identifier, attempt to the load module into the module table. - * This is a thin wrapper around `krk_importModule()`. - * - * @param name String object of the dot-separated package path to import. - * @return 1 if the module was loaded, 0 if an @ref ImportError occurred. - */ -extern int krk_doRecursiveModuleLoad(KrkString * name); - -/** - * @brief Load the dotted name @p name with the final element as @p runAs - * - * If @p name was imported previously with a name different from @p runAs, - * it will be imported again with the new name; this may result in - * unexpected behaviour. Generally, @p runAs is used to specify that the - * module should be run as `__main__`. - * - * @param name Dotted path name of a module. - * @param runAs Alternative name to attach to @c \__name__ for the module. - * @return 1 on success, 0 on failure. - */ -extern int krk_importModule(KrkString * name, KrkString * runAs); - -/** - * @brief Determine the truth of a value. - * @memberof KrkValue - * - * Determines if a value represents a "falsey" value. - * Empty collections, 0-length strings, False, numeric 0, - * None, etc. are "falsey". Other values are generally "truthy". - * - * @param value Value to examine. - * @return 1 if falsey, 0 if truthy - */ -extern int krk_isFalsey(KrkValue value); - -/** - * @brief Obtain a property of an object by name. - * @memberof KrkValue - * - * This is a convenience function that works in essentially the - * same way as the OP_GET_PROPERTY instruction. - * - * @param value Value to examine. - * @param name C-string of the property name to query. - * @return The requested property, or None with an @ref AttributeError - * exception set in the current thread if the attribute was - * not found. - */ -extern KrkValue krk_valueGetAttribute(KrkValue value, char * name); - -/** - * @brief See @ref krk_valueGetAttribute - */ -extern KrkValue krk_valueGetAttribute_default(KrkValue value, char * name, KrkValue defaultVal); - -/** - * @brief Set a property of an object by name. - * @memberof KrkValue - * - * This is a convenience function that works in essentially the - * same way as the OP_SET_PROPERTY instruction. - * - * @param owner The owner of the property to modify. - * @param name C-string of the property name to modify. - * @param to The value to assign. - * @return The set value, or None with an @ref AttributeError - * exception set in the current thread if the object can - * not have a property set. - */ -extern KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to); - -/** - * @brief Concatenate two strings. - * - * This is a convenience function which calls @c str.__add__ on the top stack - * values. Generally, this should be avoided - use @c StringBuilder instead. - */ -extern void krk_addObjects(void); - -/* - * All of the remaining stuff is internal and shouldn't be used by library users or embedders. - * FIXME This stuff needs to be moved to another header! FIXME - */ - -extern KrkValue _str___getitem__(int argc, KrkValue argv[], int hasKw); -#define krk_string_get _str___getitem__ -extern KrkValue _str___int__(int argc, KrkValue argv[], int hasKw); -#define krk_string_int _str___int__ -extern KrkValue _str___float__(int argc, KrkValue argv[], int hasKw); -#define krk_string_float _str___float__ -extern KrkValue _str_split(int argc, KrkValue argv[], int hasKw); -#define krk_string_split _str_split -extern KrkValue _str_format(int argc, KrkValue argv[], int hasKw); -#define krk_string_format _str_format - -extern KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index); - -extern void _createAndBind_numericClasses(void); -extern void _createAndBind_strClass(void); -extern void _createAndBind_listClass(void); -extern void _createAndBind_tupleClass(void); -extern void _createAndBind_bytesClass(void); -extern void _createAndBind_dictClass(void); -extern void _createAndBind_functionClass(void); -extern void _createAndBind_rangeClass(void); -extern void _createAndBind_setClass(void); -extern void _createAndBind_builtins(void); -extern void _createAndBind_type(void); -extern void _createAndBind_exceptions(void); -extern void _createAndBind_gcMod(void); -extern void _createAndBind_timeMod(void); -extern void _createAndBind_osMod(void); -extern void _createAndBind_fileioMod(void); -#ifdef ENABLE_THREADING -extern void _createAndBind_threadsMod(void); -#endif - -extern KrkValue krk_operator_lt(KrkValue,KrkValue); -extern KrkValue krk_operator_gt(KrkValue,KrkValue); - -extern void _createAndBind_generatorClass(void); -extern KrkInstance * krk_buildGenerator(KrkClosure *, KrkValue *, size_t); diff --git a/base/usr/share/bim/syntax/c.krk b/base/usr/share/bim/syntax/c.krk index ee4a5b9e..d784e919 100644 --- a/base/usr/share/bim/syntax/c.krk +++ b/base/usr/share/bim/syntax/c.krk @@ -30,13 +30,17 @@ class CHighlighter(Highlighter): "STDIN_FILENO","STDOUT_FILENO","STDERR_FILENO" ] + preprocessor_base_state = 5 + def paintCString(self): - self.paint(1, self.FLAG_STRING) let last = None while self[0] != None: if last != '\\' and self[0] == '"': self.paint(1, self.FLAG_STRING) - return + return 0 + else if self[0] == '\\' and not self[1]: + self.paint(1, self.FLAG_ESCAPE) + return 4 else if self[0] == '\\' and self[1] in 'nr\\': self.paint(2, self.FLAG_ESCAPE) last = None @@ -69,6 +73,7 @@ class CHighlighter(Highlighter): else: last = self[0] self.paint(1, self.FLAG_STRING) + return 0 def paintCChar(self): self.paint(1, self.FLAG_NUMERAL) @@ -100,7 +105,9 @@ class CHighlighter(Highlighter): def paintCPragma(self): while self[0] != None: if self[0] == '"': - self.paintCString() + self.paint(1, self.FLAG_STRING) + let result = self.paintCString() + if result != 0: return result else if self[0] == "'": self.paintCChar() else if self[0] == '\\' and self[1] == None: @@ -167,7 +174,7 @@ class CHighlighter(Highlighter): self.paint(2, self.FLAG_COMMENT) self.rewind(6) self.paint(-1, self.FLAG_COMMENT) - return 4 + return self.preprocessor_base_state else if self.matchAndPaint("else", self.FLAG_PRAGMA, self.cKeywordQualifier): # Do nothing? return self.paintCPragma() @@ -183,8 +190,8 @@ class CHighlighter(Highlighter): else if self.findKeywords(self.special, self.FLAG_NUMERAL, self.cKeywordQualifier): return 0 else if self[0] == '"': - self.paintCString() - return 0 + self.paint(1, self.FLAG_STRING) + return self.paintCString() else if self[0] == "'": self.paintCChar() return 0 @@ -202,6 +209,8 @@ class CHighlighter(Highlighter): if self.paintCComment() == 1: return 3 return self.paintCPragma() + else if cond == 4: + return self.paintCString() else: while self[0] == ' ' or self[0] == '\t': self.paint(1, self.FLAG_COMMENT) if self[0] == '#': @@ -212,11 +221,11 @@ class CHighlighter(Highlighter): return self.state + 1 else if self.matchAndPaint("else", self.FLAG_COMMENT, self.cKeywordQualifier) or self.matchAndPaint("elif", self.FLAG_COMMENT, self.cKeywordQualifier): self.paint(-1, self.FLAG_COMMENT) - if self.state == 4: return 0 + if self.state == self.preprocessor_base_state: return 0 return self.state else if self.matchAndPaint("endif", self.FLAG_COMMENT, self.cKeywordQualifier): self.paint(-1, self.FLAG_COMMENT) - if self.state == 4: return 0 + if self.state == self.preprocessor_base_state: return 0 return self.state - 1 else: self.paint(-1, self.FLAG_COMMENT) diff --git a/base/usr/share/bim/syntax/lisp.krk b/base/usr/share/bim/syntax/lisp.krk index 036c9925..5561e993 100644 --- a/base/usr/share/bim/syntax/lisp.krk +++ b/base/usr/share/bim/syntax/lisp.krk @@ -12,7 +12,7 @@ class LispHighlighter(Highlighter): def parenFromState(i): return self.parens[i % len(self.parens)] def calculate(): - if self.state == -1: self.state = 0 + if self.state == -1: self.set_state(0) while self[0]: if self[0] == ';': self.paintComment() diff --git a/kuroko b/kuroko index d477b0da..1ec1e59c 160000 --- a/kuroko +++ b/kuroko @@ -1 +1 @@ -Subproject commit d477b0dacbb48ff4efed79c8a3ee45c8d8a5f062 +Subproject commit 1ec1e59c5d621d4cbee8e33ff0d10ee6cef2a356 diff --git a/lib/kuroko/_yutani.c b/lib/kuroko/_yutani.c index 629aba5a..48897973 100644 --- a/lib/kuroko/_yutani.c +++ b/lib/kuroko/_yutani.c @@ -4,10 +4,10 @@ #include #include #include -#include "kuroko/src/kuroko.h" -#include "kuroko/src/vm.h" -#include "kuroko/src/value.h" -#include "kuroko/src/object.h" +#include +#include +#include +#include static KrkInstance * module; static KrkInstance * yctxInstance = NULL; @@ -49,9 +49,6 @@ struct YutaniSprite { sprite_t sprite; }; -static KrkClass * Decorator; -/* no additional fields */ - static KrkClass * YutaniColor; struct YutaniColor { KrkInstance inst; @@ -1199,7 +1196,7 @@ KrkValue krk_module_onload__yutani(void) { TYPE(SPECIAL_REQUEST); TYPE(WELCOME); TYPE(WINDOW_INIT); #undef TYPE /* Structure bindings */ - krk_defineNative(&Message->methods, ".__getattr__", _message_getattr); + krk_defineNative(&Message->methods, "__getattr__", _message_getattr); krk_finalizeClass(Message); /** @@ -1209,9 +1206,9 @@ KrkValue krk_module_onload__yutani(void) { YutaniColor = krk_createClass(module, "color", NULL); YutaniColor->allocSize = sizeof(struct YutaniColor); YutaniColor->docstring = S("color(r,g,b,a=255)\n Representation of an RGB(A) color."); - krk_defineNative(&YutaniColor->methods, ".__init__", _yutani_color_init); - krk_defineNative(&YutaniColor->methods, ".__repr__", _yutani_color_repr); - krk_defineNative(&YutaniColor->methods, ".__str__", _yutani_color_str); + krk_defineNative(&YutaniColor->methods, "__init__", _yutani_color_init); + krk_defineNative(&YutaniColor->methods, "__repr__", _yutani_color_repr); + krk_defineNative(&YutaniColor->methods, "__str__", _yutani_color_str); krk_finalizeClass(YutaniColor); /** @@ -1225,22 +1222,22 @@ KrkValue krk_module_onload__yutani(void) { Yutani = krk_createClass(module, "Yutani", NULL); Yutani->allocSize = sizeof(struct YutaniClass); Yutani->docstring = S("Yutani()\n Establish a connection to the compositor display server."); - krk_defineNative(&Yutani->methods, ":display_width", _yutani_display_width); - krk_defineNative(&Yutani->methods, ":display_height", _yutani_display_height); - krk_defineNative(&Yutani->methods, ".__repr__", _yutani_repr); - krk_defineNative(&Yutani->methods, ".__init__", _yutani_init); - krk_defineNative(&Yutani->methods, ".poll", _yutani_poll); - krk_defineNative(&Yutani->methods, ".wait_for", _yutani_wait_for); - krk_defineNative(&Yutani->methods, ".subscribe", _yutani_subscribe); - krk_defineNative(&Yutani->methods, ".unsubscribe", _yutani_unsubscribe); - krk_defineNative(&Yutani->methods, ".query_windows", _yutani_query_windows); - krk_defineNative(&Yutani->methods, ".fileno", _yutani_fileno); - krk_defineNative(&Yutani->methods, ".query", _yutani_query); - krk_defineNative(&Yutani->methods, ".menu_process_event", _yutani_menu_process_event); + krk_defineNative(&Yutani->methods, "display_width", _yutani_display_width)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&Yutani->methods, "display_height", _yutani_display_height)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&Yutani->methods, "__repr__", _yutani_repr); + krk_defineNative(&Yutani->methods, "__init__", _yutani_init); + krk_defineNative(&Yutani->methods, "poll", _yutani_poll); + krk_defineNative(&Yutani->methods, "wait_for", _yutani_wait_for); + krk_defineNative(&Yutani->methods, "subscribe", _yutani_subscribe); + krk_defineNative(&Yutani->methods, "unsubscribe", _yutani_unsubscribe); + krk_defineNative(&Yutani->methods, "query_windows", _yutani_query_windows); + krk_defineNative(&Yutani->methods, "fileno", _yutani_fileno); + krk_defineNative(&Yutani->methods, "query", _yutani_query); + krk_defineNative(&Yutani->methods, "menu_process_event", _yutani_menu_process_event); #if 0 - krk_defineNative(&Yutani->methods, ".focus_window", _yutani_focus_window); - krk_defineNative(&Yutani->methods, ".session_end", _yutani_session_end); - krk_defineNative(&Yutani->methods, ".key_bind", _yutani_key_bind); + krk_defineNative(&Yutani->methods, "focus_window", _yutani_focus_window); + krk_defineNative(&Yutani->methods, "session_end", _yutani_session_end); + krk_defineNative(&Yutani->methods, "key_bind", _yutani_key_bind); #endif krk_finalizeClass(Yutani); @@ -1250,28 +1247,28 @@ KrkValue krk_module_onload__yutani(void) { */ GraphicsContext = krk_createClass(module, "GraphicsContext", NULL); GraphicsContext->allocSize = sizeof(struct GraphicsContext); - krk_defineNative(&GraphicsContext->methods, ":width", _gfx_width); - krk_defineNative(&GraphicsContext->methods, ":height", _gfx_height); - krk_defineNative(&GraphicsContext->methods, ".fill", _gfx_fill)->doc = + krk_defineNative(&GraphicsContext->methods, "width", _gfx_width)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&GraphicsContext->methods, "height", _gfx_height)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&GraphicsContext->methods, "fill", _gfx_fill)->doc = "GraphicsContext.fill(color)\n" " Fill the entire context with the given color."; - krk_defineNative(&GraphicsContext->methods, ".flip", _gfx_flip)->doc = + krk_defineNative(&GraphicsContext->methods, "flip", _gfx_flip)->doc = "GraphicsContext.flip()\n" " If the context is double-buffered, flip its backbuffer."; - krk_defineNative(&GraphicsContext->methods, ".blur", _gfx_blur)->doc = + krk_defineNative(&GraphicsContext->methods, "blur", _gfx_blur)->doc = "GraphicsContext.blur(radius=2)\n" " Perform an in-place box blur on this graphics context."; - krk_defineNative(&GraphicsContext->methods, ".line", _gfx_line)->doc = + krk_defineNative(&GraphicsContext->methods, "line", _gfx_line)->doc = "GraphicsContext.line(x0,x1,y0,y1,color,thickness=None)\n" " Draw a line between the given points. If thickness is not provided, uses a\n" " a simple Bresenham algorithm. If thickness is an int, draws with a box-shaped pen.\n" " If thickness is a float, draws using a point-distance antialiasing algorithm."; - krk_defineNative(&GraphicsContext->methods, ".rect", _gfx_rect)->doc = + krk_defineNative(&GraphicsContext->methods, "rect", _gfx_rect)->doc = "GraphicsContext.rect(x,y,width,height,color,solid=False,radius=None)\n" " Draw a filled rectangle. If solid is True, paints the given color directly to\n" " the underlying backbuffer with no alpha calculations. If radius is provided,\n" " draws a rounded rectangle."; - krk_defineNative(&GraphicsContext->methods, ".draw_sprite", _gfx_draw_sprite)->doc = + krk_defineNative(&GraphicsContext->methods, "draw_sprite", _gfx_draw_sprite)->doc = "GraphicsContext.draw_sprite(sprite,x,y,alpha=None,rotation=None,scale=None,color=None)\n" " Blit a sprite to this graphics context at the given coordinates.\n" " alpha: float of opacity; 1.0 = fully opaque (default)\n" @@ -1292,29 +1289,30 @@ KrkValue krk_module_onload__yutani(void) { YutaniWindow->allocSize = sizeof(struct WindowClass); YutaniWindow->docstring = S("Window(width,height,flags=0,title=None,icon=None,doublebuffer=False)\n" " Create a new window and initializes a graphics rendering context for it."); - krk_defineNative(&YutaniWindow->methods, ".__repr__", _window_repr); - krk_defineNative(&YutaniWindow->methods, ".__init__", _window_init); - krk_defineNative(&YutaniWindow->methods, ".flip", _window_flip); - krk_defineNative(&YutaniWindow->methods, ".move", _window_move); - krk_defineNative(&YutaniWindow->methods, ".set_focused", _window_set_focused); - krk_defineNative(&YutaniWindow->methods, ".close", _window_close); - krk_defineNative(&YutaniWindow->methods, ".set_stack", _window_set_stack); - krk_defineNative(&YutaniWindow->methods, ".special_request", _window_special_request); - krk_defineNative(&YutaniWindow->methods, ".resize", _window_resize); - krk_defineNative(&YutaniWindow->methods, ".resize_start", _window_resize_start); - krk_defineNative(&YutaniWindow->methods, ".resize_done", _window_resize_done); - krk_defineNative(&YutaniWindow->methods, ".resize_offer", _window_resize_offer); - krk_defineNative(&YutaniWindow->methods, ".resize_accept", _window_resize_accept); - krk_defineNative(&YutaniWindow->methods, ".update_shape", _window_update_shape); - krk_defineNative(&YutaniWindow->methods, ".show_mouse", _window_show_mouse); - krk_defineNative(&YutaniWindow->methods, ".warp_mouse", _window_warp_mouse); - krk_defineNative(&YutaniWindow->methods, ".set_stack", _window_set_stack); - krk_defineNative(&YutaniWindow->methods, ".advertise", _window_advertise); - krk_defineNative(&YutaniWindow->methods, ".reinit", _window_reinit); - krk_defineNative(&YutaniWindow->methods, ":wid", _window_wid); - krk_defineNative(&YutaniWindow->methods, ":x", _window_x); - krk_defineNative(&YutaniWindow->methods, ":y", _window_y); - krk_defineNative(&YutaniWindow->methods, ":focused", _window_focused); + krk_defineNative(&YutaniWindow->methods, "__repr__", _window_repr); + krk_defineNative(&YutaniWindow->methods, "__init__", _window_init); + krk_defineNative(&YutaniWindow->methods, "flip", _window_flip); + krk_defineNative(&YutaniWindow->methods, "move", _window_move); + krk_defineNative(&YutaniWindow->methods, "set_focused", _window_set_focused); + krk_defineNative(&YutaniWindow->methods, "close", _window_close); + krk_defineNative(&YutaniWindow->methods, "set_stack", _window_set_stack); + krk_defineNative(&YutaniWindow->methods, "special_request", _window_special_request); + krk_defineNative(&YutaniWindow->methods, "resize", _window_resize); + krk_defineNative(&YutaniWindow->methods, "resize_start", _window_resize_start); + krk_defineNative(&YutaniWindow->methods, "resize_done", _window_resize_done); + krk_defineNative(&YutaniWindow->methods, "resize_offer", _window_resize_offer); + krk_defineNative(&YutaniWindow->methods, "resize_accept", _window_resize_accept); + krk_defineNative(&YutaniWindow->methods, "update_shape", _window_update_shape); + krk_defineNative(&YutaniWindow->methods, "show_mouse", _window_show_mouse); + krk_defineNative(&YutaniWindow->methods, "warp_mouse", _window_warp_mouse); + krk_defineNative(&YutaniWindow->methods, "set_stack", _window_set_stack); + krk_defineNative(&YutaniWindow->methods, "advertise", _window_advertise); + krk_defineNative(&YutaniWindow->methods, "reinit", _window_reinit); + + krk_defineNative(&YutaniWindow->methods, "wid", _window_wid)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&YutaniWindow->methods, "x", _window_x)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&YutaniWindow->methods, "y", _window_y)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; + krk_defineNative(&YutaniWindow->methods, "focused", _window_focused)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; krk_finalizeClass(YutaniWindow); /** @@ -1326,8 +1324,8 @@ KrkValue krk_module_onload__yutani(void) { YutaniSprite->allocSize = sizeof(struct YutaniSprite); YutaniSprite->_ongcsweep = _sprite_sweep; YutaniSprite->docstring = S("Sprite(filename)\n Create a sprite from the requested texture file."); - krk_defineNative(&YutaniSprite->methods, ".__repr__", _sprite_repr); - krk_defineNative(&YutaniSprite->methods, ".__init__", _sprite_init); + krk_defineNative(&YutaniSprite->methods, "__repr__", _sprite_repr); + krk_defineNative(&YutaniSprite->methods, "__init__", _sprite_init); krk_finalizeClass(YutaniSprite); /** @@ -1338,14 +1336,14 @@ KrkValue krk_module_onload__yutani(void) { YutaniFont->allocSize = sizeof(struct YutaniFont); YutaniFont->docstring = S("Font(type,size,gamma=1.7,stroke=0.75,color=color(0,0,0))\n" " Create a Font specification for rendering text."); - krk_defineNative(&YutaniFont->methods, ".__init__", _font_init); - krk_defineNative(&YutaniFont->methods, ".draw_string", _font_draw_string)->doc = + krk_defineNative(&YutaniFont->methods, "__init__", _font_init); + krk_defineNative(&YutaniFont->methods, "draw_string", _font_draw_string)->doc = "Font.draw_string(gfxContext, string, x, y)\n" " Draw text to a graphics context with this font."; - krk_defineNative(&YutaniFont->methods, ".width", _font_width)->doc = + krk_defineNative(&YutaniFont->methods, "width", _font_width)->doc = "Font.width(string)\n" " Calculate the rendered width of the given string when drawn with this font."; - krk_defineNative(&YutaniFont->methods, ":size", _font_size); + krk_defineNative(&YutaniFont->methods, "size", _font_size)->flags |= KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; /* Some static values */ #define ATTACH_FONT(name) krk_attachNamedValue(&YutaniFont->methods, #name, INTEGER_VAL(SDF_ ## name)) ATTACH_FONT(FONT_THIN); @@ -1361,37 +1359,38 @@ KrkValue krk_module_onload__yutani(void) { MenuBarClass = krk_createClass(module, "MenuBar", NULL); MenuBarClass->allocSize = sizeof(struct MenuBarClass); MenuBarClass->_ongcsweep = _MenuBar_gcsweep; - krk_defineNative(&MenuBarClass->methods, ".__init__", _MenuBar_init); - krk_defineNative(&MenuBarClass->methods, ".place", _MenuBar_place); - krk_defineNative(&MenuBarClass->methods, ".render", _MenuBar_render); - krk_defineNative(&MenuBarClass->methods, ".mouse_event", _MenuBar_mouse_event); - krk_defineNative(&MenuBarClass->methods, ".insert", _MenuBar_insert); + krk_defineNative(&MenuBarClass->methods, "__init__", _MenuBar_init); + krk_defineNative(&MenuBarClass->methods, "place", _MenuBar_place); + krk_defineNative(&MenuBarClass->methods, "render", _MenuBar_render); + krk_defineNative(&MenuBarClass->methods, "mouse_event", _MenuBar_mouse_event); + krk_defineNative(&MenuBarClass->methods, "insert", _MenuBar_insert); krk_finalizeClass(MenuBarClass); MenuListClass = krk_createClass(module, "MenuList", NULL); MenuListClass->allocSize = sizeof(struct MenuListClass); - krk_defineNative(&MenuListClass->methods, ".__init__", _MenuList_init); - krk_defineNative(&MenuListClass->methods, ".insert", _MenuList_insert); + krk_defineNative(&MenuListClass->methods, "__init__", _MenuList_init); + krk_defineNative(&MenuListClass->methods, "insert", _MenuList_insert); krk_finalizeClass(MenuListClass); MenuEntryClass = krk_createClass(module, "MenuEntry", NULL); MenuEntryClass->allocSize = sizeof(struct MenuEntryClass); - krk_defineNative(&MenuEntryClass->methods, ".__init__", _MenuEntry_init); + krk_defineNative(&MenuEntryClass->methods, "__init__", _MenuEntry_init); krk_finalizeClass(MenuEntryClass); MenuEntrySubmenuClass = krk_createClass(module, "MenuEntrySubmenu", MenuEntryClass); - krk_defineNative(&MenuEntrySubmenuClass->methods, ".__init__", _MenuEntrySubmenu_init); + krk_defineNative(&MenuEntrySubmenuClass->methods, "__init__", _MenuEntrySubmenu_init); krk_finalizeClass(MenuEntrySubmenuClass); MenuEntrySeparatorClass = krk_createClass(module, "MenuEntrySeparator", MenuEntryClass); - krk_defineNative(&MenuEntrySeparatorClass->methods, ".__init__", _MenuEntrySeparator_init); + krk_defineNative(&MenuEntrySeparatorClass->methods, "__init__", _MenuEntrySeparator_init); krk_finalizeClass(MenuEntrySeparatorClass); - Decorator = krk_createClass(module, "Decorator", NULL); - krk_defineNative(&Decorator->methods, "get_bounds", _decor_get_bounds); - krk_defineNative(&Decorator->methods, "render", _decor_render); - krk_defineNative(&Decorator->methods, "handle_event", _decor_handle_event); - krk_defineNative(&Decorator->methods, "show_default_menu", _decor_show_default_menu); -#define ATTACH_CONSTANT(name) krk_attachNamedValue(&Decorator->methods, #name, INTEGER_VAL(name)) + KrkInstance * Decorator = krk_newInstance(vm.baseClasses->objectClass); + krk_attachNamedObject(&module->fields, "Decorator", (KrkObj*)Decorator); + krk_defineNative(&Decorator->fields, "get_bounds", _decor_get_bounds); + krk_defineNative(&Decorator->fields, "render", _decor_render); + krk_defineNative(&Decorator->fields, "handle_event", _decor_handle_event); + krk_defineNative(&Decorator->fields, "show_default_menu", _decor_show_default_menu); +#define ATTACH_CONSTANT(name) krk_attachNamedValue(&Decorator->fields, #name, INTEGER_VAL(name)) ATTACH_CONSTANT(DECOR_OTHER); ATTACH_CONSTANT(DECOR_CLOSE); ATTACH_CONSTANT(DECOR_RESIZE); @@ -1409,7 +1408,6 @@ KrkValue krk_module_onload__yutani(void) { ATTACH_CONSTANT(DECOR_FLAG_TILE_UP); ATTACH_CONSTANT(DECOR_FLAG_TILE_DOWN); #undef ATTACH_CONSTANT - krk_finalizeClass(Decorator); /* Pop the module object before returning; it'll get pushed again * by the VM before the GC has a chance to run, so it's safe. */ diff --git a/util/auto-dep.py b/util/auto-dep.py index f82f3cba..773c38ab 100755 --- a/util/auto-dep.py +++ b/util/auto-dep.py @@ -36,7 +36,6 @@ class Classifier(object): '': (None, '-ltoaru_textregion', ['', '','', '']), '': (None, '-ltoaru_button', ['','', '']), # Kuroko - '': ('../../../kuroko/src', '-lkuroko', []), '': (None, '-lkuroko', []), # OPTIONAL third-party libraries, for extensions / ports '': ('freetype2', '-lfreetype', []),