Embed os, dir, time, fileio modules in core; only 'math' is still a separate shared library
This commit is contained in:
parent
1d8f308b0d
commit
34e7eb4e57
45
src/debug.c
45
src/debug.c
@ -1,7 +1,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
void krk_disassembleChunk(FILE * f, KrkFunction * func, const char * name) {
|
void krk_disassembleChunk(FILE * f, KrkFunction * func, const char * name) {
|
||||||
KrkChunk * chunk = &func->chunk;
|
KrkChunk * chunk = &func->chunk;
|
||||||
@ -180,3 +182,46 @@ size_t krk_disassembleInstruction(FILE * f, KrkFunction * func, size_t offset) {
|
|||||||
return offset + size;
|
return offset + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dis.dis(object)
|
||||||
|
*/
|
||||||
|
KRK_FUNC(dis,{
|
||||||
|
if (argc < 1) {
|
||||||
|
krk_runtimeError(vm.exceptions->argumentError, "dis() takes ");
|
||||||
|
return BOOLEAN_VAL(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_CLOSURE(argv[0])) {
|
||||||
|
KrkFunction * func = AS_CLOSURE(argv[0])->function;
|
||||||
|
krk_disassembleChunk(stdout, func, func->name ? func->name->chars : "(unnamed)");
|
||||||
|
} else if (IS_BOUND_METHOD(argv[0])) {
|
||||||
|
if (AS_BOUND_METHOD(argv[0])->method->type == OBJ_CLOSURE) {
|
||||||
|
KrkFunction * func = ((KrkClosure*)AS_BOUND_METHOD(argv[0])->method)->function;
|
||||||
|
const char * methodName = func->name ? func->name->chars : "(unnamed)";
|
||||||
|
const char * typeName = IS_CLASS(AS_BOUND_METHOD(argv[0])->receiver) ? AS_CLASS(AS_BOUND_METHOD(argv[0])->receiver)->name->chars : krk_typeName(AS_BOUND_METHOD(argv[0])->receiver);
|
||||||
|
char * tmp = malloc(strlen(methodName) + strlen(typeName) + 2);
|
||||||
|
sprintf(tmp, "%s.%s", typeName, methodName);
|
||||||
|
krk_disassembleChunk(stdout, func, tmp);
|
||||||
|
free(tmp);
|
||||||
|
} else {
|
||||||
|
krk_runtimeError(vm.exceptions->typeError, "Can not disassemble built-in method of '%s'", krk_typeName(AS_BOUND_METHOD(argv[0])->receiver));
|
||||||
|
}
|
||||||
|
} else if (IS_CLASS(argv[0])) {
|
||||||
|
krk_runtimeError(vm.exceptions->typeError, "todo: class disassembly");
|
||||||
|
} else {
|
||||||
|
krk_runtimeError(vm.exceptions->typeError, "Don't know how to disassemble '%s'", krk_typeName(argv[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NONE_VAL();
|
||||||
|
})
|
||||||
|
|
||||||
|
_noexport
|
||||||
|
void _createAndBind_disMod(void) {
|
||||||
|
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||||
|
krk_attachNamedObject(&vm.modules, "dis", (KrkObj*)module);
|
||||||
|
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("dis"));
|
||||||
|
krk_attachNamedValue(&module->fields, "__file__", NONE_VAL());
|
||||||
|
krk_attachNamedObject(&module->fields, "__doc__",
|
||||||
|
(KrkObj*)S("Provides tools for disassembling bytecode."));
|
||||||
|
BIND_FUNC(module, dis);
|
||||||
|
}
|
||||||
|
@ -7,3 +7,4 @@
|
|||||||
extern void krk_disassembleChunk(FILE * f, KrkFunction * func, const char * name);
|
extern void krk_disassembleChunk(FILE * f, KrkFunction * func, const char * name);
|
||||||
extern size_t krk_disassembleInstruction(FILE * f, KrkFunction * func, size_t offset);
|
extern size_t krk_disassembleInstruction(FILE * f, KrkFunction * func, size_t offset);
|
||||||
extern size_t krk_lineNumber(KrkChunk * chunk, size_t offset);
|
extern size_t krk_lineNumber(KrkChunk * chunk, size_t offset);
|
||||||
|
extern void _createAndBind_disMod(void);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Native module for providing access to stdio.
|
* Provides an interface to C FILE* streams.
|
||||||
*/
|
*/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -462,11 +462,14 @@ KRK_METHOD(Directory,__repr__,{
|
|||||||
return OBJECT_VAL(out);
|
return OBJECT_VAL(out);
|
||||||
})
|
})
|
||||||
|
|
||||||
KrkValue krk_module_onload_fileio(void) {
|
_noexport
|
||||||
|
void _createAndBind_fileioMod(void) {
|
||||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||||
/* Store it on the stack for now so we can do stuff that may trip GC
|
krk_attachNamedObject(&vm.modules, "fileio", (KrkObj*)module);
|
||||||
* and not lose it to garbage colletion... */
|
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("fileio"));
|
||||||
krk_push(OBJECT_VAL(module));
|
krk_attachNamedValue(&module->fields, "__file__", NONE_VAL());
|
||||||
|
krk_attachNamedObject(&module->fields, "__doc__",
|
||||||
|
(KrkObj*)S("Provides access to C <stdio> buffered file I/O functions."));
|
||||||
|
|
||||||
/* Define a class to represent files. (Should this be a helper method?) */
|
/* Define a class to represent files. (Should this be a helper method?) */
|
||||||
krk_makeClass(module, &File, "File", vm.baseClasses->objectClass);
|
krk_makeClass(module, &File, "File", vm.baseClasses->objectClass);
|
||||||
@ -511,9 +514,4 @@ KrkValue krk_module_onload_fileio(void) {
|
|||||||
/* Our base will be the open method */
|
/* Our base will be the open method */
|
||||||
BIND_FUNC(module,open);
|
BIND_FUNC(module,open);
|
||||||
BIND_FUNC(module,opendir);
|
BIND_FUNC(module,opendir);
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
assert(AS_INSTANCE(krk_pop()) == module);
|
|
||||||
return OBJECT_VAL(module);
|
|
||||||
}
|
}
|
@ -465,10 +465,6 @@ _finishArgs:
|
|||||||
|
|
||||||
#ifdef BUNDLE_LIBS
|
#ifdef BUNDLE_LIBS
|
||||||
/* Add any other modules you want to include that are normally built as shared objects. */
|
/* Add any other modules you want to include that are normally built as shared objects. */
|
||||||
BUNDLED(fileio);
|
|
||||||
BUNDLED(dis);
|
|
||||||
BUNDLED(os);
|
|
||||||
BUNDLED(time);
|
|
||||||
BUNDLED(math);
|
BUNDLED(math);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
/**
|
|
||||||
* Currently just dis().
|
|
||||||
*/
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "vm.h"
|
|
||||||
#include "value.h"
|
|
||||||
#include "object.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
#define S(c) (krk_copyString(c,sizeof(c)-1))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dis.dis(object)
|
|
||||||
*/
|
|
||||||
static KrkValue krk_dis(int argc, KrkValue argv[], int hasKw) {
|
|
||||||
if (argc < 1) {
|
|
||||||
krk_runtimeError(vm.exceptions->argumentError, "dis() takes ");
|
|
||||||
return BOOLEAN_VAL(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_DISASSEMBLY
|
|
||||||
if (IS_CLOSURE(argv[0])) {
|
|
||||||
KrkFunction * func = AS_CLOSURE(argv[0])->function;
|
|
||||||
krk_disassembleChunk(stdout, func, func->name ? func->name->chars : "(unnamed)");
|
|
||||||
} else if (IS_BOUND_METHOD(argv[0])) {
|
|
||||||
if (AS_BOUND_METHOD(argv[0])->method->type == OBJ_CLOSURE) {
|
|
||||||
KrkFunction * func = ((KrkClosure*)AS_BOUND_METHOD(argv[0])->method)->function;
|
|
||||||
const char * methodName = func->name ? func->name->chars : "(unnamed)";
|
|
||||||
const char * typeName = IS_CLASS(AS_BOUND_METHOD(argv[0])->receiver) ? AS_CLASS(AS_BOUND_METHOD(argv[0])->receiver)->name->chars : krk_typeName(AS_BOUND_METHOD(argv[0])->receiver);
|
|
||||||
char * tmp = malloc(strlen(methodName) + strlen(typeName) + 2);
|
|
||||||
sprintf(tmp, "%s.%s", typeName, methodName);
|
|
||||||
krk_disassembleChunk(stdout, func, tmp);
|
|
||||||
free(tmp);
|
|
||||||
} else {
|
|
||||||
krk_runtimeError(vm.exceptions->typeError, "Can not disassemble built-in method of '%s'", krk_typeName(AS_BOUND_METHOD(argv[0])->receiver));
|
|
||||||
}
|
|
||||||
} else if (IS_CLASS(argv[0])) {
|
|
||||||
krk_runtimeError(vm.exceptions->typeError, "todo: class disassembly");
|
|
||||||
} else {
|
|
||||||
krk_runtimeError(vm.exceptions->typeError, "Don't know how to disassemble '%s'", krk_typeName(argv[0]));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
krk_runtimeError(vm.exceptions->typeError, "Kuroko was built with debug methods stripped; disassembly is not available.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NONE_VAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
KrkValue krk_module_onload_dis(void) {
|
|
||||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
|
||||||
krk_push(OBJECT_VAL(module));
|
|
||||||
krk_defineNative(&module->fields, "dis", krk_dis);
|
|
||||||
assert(AS_INSTANCE(krk_pop()) == module);
|
|
||||||
return OBJECT_VAL(module);
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
/**
|
|
||||||
* Currently just sleep().
|
|
||||||
*/
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "vm.h"
|
|
||||||
#include "value.h"
|
|
||||||
#include "object.h"
|
|
||||||
|
|
||||||
#define S(c) (krk_copyString(c,sizeof(c)-1))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* system.sleep(seconds)
|
|
||||||
*/
|
|
||||||
static KrkValue _time_sleep(int argc, KrkValue argv[], int hasKw) {
|
|
||||||
if (argc < 1) {
|
|
||||||
krk_runtimeError(vm.exceptions->argumentError, "sleep: expect at least one argument.");
|
|
||||||
return BOOLEAN_VAL(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Accept an integer or a floating point. Anything else, just ignore. */
|
|
||||||
unsigned int usecs = (IS_INTEGER(argv[0]) ? AS_INTEGER(argv[0]) :
|
|
||||||
(IS_FLOATING(argv[0]) ? AS_FLOATING(argv[0]) : 0)) *
|
|
||||||
1000000;
|
|
||||||
|
|
||||||
usleep(usecs);
|
|
||||||
|
|
||||||
return BOOLEAN_VAL(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static KrkValue _time_time(int argc, KrkValue argv[], int hasKw) {
|
|
||||||
time_t out = time(NULL);
|
|
||||||
return FLOATING_VAL(out); /* TODO actually support subsecond values */
|
|
||||||
}
|
|
||||||
|
|
||||||
KrkValue krk_module_onload_time(void) {
|
|
||||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
|
||||||
/* Store it on the stack for now so we can do stuff that may trip GC
|
|
||||||
* and not lose it to garbage colletion... */
|
|
||||||
krk_push(OBJECT_VAL(module));
|
|
||||||
|
|
||||||
krk_defineNative(&module->fields, "sleep", _time_sleep);
|
|
||||||
krk_defineNative(&module->fields, "time", _time_time);
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
assert(AS_INSTANCE(krk_pop()) == module);
|
|
||||||
return OBJECT_VAL(module);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
|||||||
/**
|
|
||||||
* Currently just uname().
|
|
||||||
*/
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -480,11 +477,14 @@ KRK_FUNC(execvp,{
|
|||||||
return krk_runtimeError(OSError, "Expected to not return from exec, but did.");
|
return krk_runtimeError(OSError, "Expected to not return from exec, but did.");
|
||||||
})
|
})
|
||||||
|
|
||||||
KrkValue krk_module_onload_os(void) {
|
_noexport
|
||||||
|
void _createAndBind_osMod(void) {
|
||||||
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||||
/* Store it on the stack for now so we can do stuff that may trip GC
|
krk_attachNamedObject(&vm.modules, "os", (KrkObj*)module);
|
||||||
* and not lose it to garbage colletion... */
|
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("os"));
|
||||||
krk_push(OBJECT_VAL(module));
|
krk_attachNamedValue(&module->fields, "__file__", NONE_VAL());
|
||||||
|
krk_attachNamedObject(&module->fields, "__doc__",
|
||||||
|
(KrkObj*)S("Provides access to low-level system operations."));
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
krk_attachNamedObject(&module->fields, "name", (KrkObj*)S("nt"));
|
krk_attachNamedObject(&module->fields, "name", (KrkObj*)S("nt"));
|
||||||
@ -590,11 +590,6 @@ KrkValue krk_module_onload_os(void) {
|
|||||||
|
|
||||||
|
|
||||||
_loadEnviron(module);
|
_loadEnviron(module);
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
assert(AS_INSTANCE(krk_pop()) == module);
|
|
||||||
return OBJECT_VAL(module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
src/time.c
Normal file
46
src/time.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "vm.h"
|
||||||
|
#include "value.h"
|
||||||
|
#include "object.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
KRK_FUNC(sleep,{
|
||||||
|
FUNCTION_TAKES_EXACTLY(1);
|
||||||
|
|
||||||
|
if (!IS_INTEGER(argv[0]) && !IS_FLOATING(argv[0])) {
|
||||||
|
return TYPE_ERROR(int or float,argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int usecs = (IS_INTEGER(argv[0]) ? AS_INTEGER(argv[0]) :
|
||||||
|
(IS_FLOATING(argv[0]) ? AS_FLOATING(argv[0]) : 0)) *
|
||||||
|
1000000;
|
||||||
|
|
||||||
|
usleep(usecs);
|
||||||
|
|
||||||
|
return BOOLEAN_VAL(1);
|
||||||
|
})
|
||||||
|
|
||||||
|
KRK_FUNC(time,{
|
||||||
|
FUNCTION_TAKES_NONE();
|
||||||
|
time_t out = time(NULL);
|
||||||
|
return FLOATING_VAL(out);
|
||||||
|
})
|
||||||
|
|
||||||
|
_noexport
|
||||||
|
void _createAndBind_timeMod(void) {
|
||||||
|
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
|
||||||
|
krk_attachNamedObject(&vm.modules, "time", (KrkObj*)module);
|
||||||
|
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("time"));
|
||||||
|
krk_attachNamedValue(&module->fields, "__file__", NONE_VAL());
|
||||||
|
krk_attachNamedObject(&module->fields, "__doc__",
|
||||||
|
(KrkObj*)S("Provides timekeeping functions."));
|
||||||
|
BIND_FUNC(module,sleep);
|
||||||
|
BIND_FUNC(module,time);
|
||||||
|
}
|
||||||
|
|
4
src/vm.c
4
src/vm.c
@ -1162,6 +1162,10 @@ void krk_initVM(int flags) {
|
|||||||
_createAndBind_setClass();
|
_createAndBind_setClass();
|
||||||
_createAndBind_exceptions();
|
_createAndBind_exceptions();
|
||||||
_createAndBind_gcMod();
|
_createAndBind_gcMod();
|
||||||
|
_createAndBind_disMod();
|
||||||
|
_createAndBind_timeMod();
|
||||||
|
_createAndBind_osMod();
|
||||||
|
_createAndBind_fileioMod();
|
||||||
#ifdef ENABLE_THREADING
|
#ifdef ENABLE_THREADING
|
||||||
_createAndBind_threadsMod();
|
_createAndBind_threadsMod();
|
||||||
#endif
|
#endif
|
||||||
|
3
src/vm.h
3
src/vm.h
@ -233,6 +233,9 @@ extern void _createAndBind_builtins(void);
|
|||||||
extern void _createAndBind_type(void);
|
extern void _createAndBind_type(void);
|
||||||
extern void _createAndBind_exceptions(void);
|
extern void _createAndBind_exceptions(void);
|
||||||
extern void _createAndBind_gcMod(void);
|
extern void _createAndBind_gcMod(void);
|
||||||
|
extern void _createAndBind_timeMod(void);
|
||||||
|
extern void _createAndBind_osMod(void);
|
||||||
|
extern void _createAndBind_fileioMod(void);
|
||||||
|
|
||||||
extern int krk_doRecursiveModuleLoad(KrkString * name);
|
extern int krk_doRecursiveModuleLoad(KrkString * name);
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
oh no! sleep: expect at least one argument.
|
oh no! sleep() takes exactly 1 argument (0 given)
|
||||||
Back from try/except
|
Back from try/except
|
||||||
|
Loading…
Reference in New Issue
Block a user