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 <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "vm.h"
|
||||
#include "util.h"
|
||||
|
||||
void krk_disassembleChunk(FILE * f, KrkFunction * func, const char * name) {
|
||||
KrkChunk * chunk = &func->chunk;
|
||||
@ -180,3 +182,46 @@ size_t krk_disassembleInstruction(FILE * f, KrkFunction * func, size_t offset) {
|
||||
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 size_t krk_disassembleInstruction(FILE * f, KrkFunction * func, 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 <stdio.h>
|
||||
@ -462,11 +462,14 @@ KRK_METHOD(Directory,__repr__,{
|
||||
return OBJECT_VAL(out);
|
||||
})
|
||||
|
||||
KrkValue krk_module_onload_fileio(void) {
|
||||
_noexport
|
||||
void _createAndBind_fileioMod(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_attachNamedObject(&vm.modules, "fileio", (KrkObj*)module);
|
||||
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("fileio"));
|
||||
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?) */
|
||||
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 */
|
||||
BIND_FUNC(module,open);
|
||||
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
|
||||
/* 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);
|
||||
#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 <stdio.h>
|
||||
#include <string.h>
|
||||
@ -480,11 +477,14 @@ KRK_FUNC(execvp,{
|
||||
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);
|
||||
/* 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_attachNamedObject(&vm.modules, "os", (KrkObj*)module);
|
||||
krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)S("os"));
|
||||
krk_attachNamedValue(&module->fields, "__file__", NONE_VAL());
|
||||
krk_attachNamedObject(&module->fields, "__doc__",
|
||||
(KrkObj*)S("Provides access to low-level system operations."));
|
||||
|
||||
#ifdef _WIN32
|
||||
krk_attachNamedObject(&module->fields, "name", (KrkObj*)S("nt"));
|
||||
@ -590,11 +590,6 @@ KrkValue krk_module_onload_os(void) {
|
||||
|
||||
|
||||
_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_exceptions();
|
||||
_createAndBind_gcMod();
|
||||
_createAndBind_disMod();
|
||||
_createAndBind_timeMod();
|
||||
_createAndBind_osMod();
|
||||
_createAndBind_fileioMod();
|
||||
#ifdef ENABLE_THREADING
|
||||
_createAndBind_threadsMod();
|
||||
#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_exceptions(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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user