1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-29 03:19:54 +00:00

Allow proper overriding of cfunctions in the core.

Allow overriding functions in the core libray to provide better
functionality on startup. Used to include our getline function in
the repl but use a simpler version in the core library.
This commit is contained in:
Calvin Rose 2019-03-08 11:39:18 -05:00
parent 687a3c91f5
commit a363dce943
6 changed files with 56 additions and 22 deletions

View File

@ -43,7 +43,8 @@ int main() {
/* Set up VM */ /* Set up VM */
int status; int status;
JanetTable *env; JanetTable *env;
env = janet_core_env();
env = janet_core_env(NULL);
/* Run bootstrap script to generate core image */ /* Run bootstrap script to generate core image */
status = janet_dobytes(env, janet_gen_boot, janet_gen_boot_size, "boot.janet", NULL); status = janet_dobytes(env, janet_gen_boot, janet_gen_boot_size, "boot.janet", NULL);

View File

@ -1460,14 +1460,6 @@ value, one key will be ignored."
(file/write stderr "compile error: " msg " while compiling " where "\n") (file/write stderr "compile error: " msg " while compiling " where "\n")
(when macrof (debug/stacktrace macrof))) (when macrof (debug/stacktrace macrof)))
(defn getline
"Read a line from stdin into a buffer."
[buf p &]
(default buf @"")
(when p (file/write stdout p))
(file/read stdin :line buf)
buf)
(defn run-context (defn run-context
"Run a context. This evaluates expressions of janet in an environment, "Run a context. This evaluates expressions of janet in an environment,
and is encapsulates the parsing, compilation, and evaluation. and is encapsulates the parsing, compilation, and evaluation.

View File

@ -243,6 +243,29 @@ static Janet janet_core_hash(int32_t argc, Janet *argv) {
return janet_wrap_number(janet_hash(argv[0])); return janet_wrap_number(janet_hash(argv[0]));
} }
static Janet janet_core_getline(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 2);
JanetBuffer *buf = (argc >= 2) ? janet_getbuffer(argv, 1) : janet_buffer(10);
if (argc >= 1) {
const char *prompt = (const char *) janet_getstring(argv, 0);
printf("%s", prompt);
fflush(stdout);
}
{
buf->count = 0;
int c;
for (;;) {
c = fgetc(stdin);
if (feof(stdin) || c < 0) {
break;
}
janet_buffer_push_u8(buf, (uint8_t) c);
if (c == '\n') break;
}
}
return janet_wrap_buffer(buf);
}
static const JanetReg corelib_cfuns[] = { static const JanetReg corelib_cfuns[] = {
{ {
"native", janet_core_native, "native", janet_core_native,
@ -393,6 +416,12 @@ static const JanetReg corelib_cfuns[] = {
"as a cheap hash function for all janet objects. If two values are strictly equal, " "as a cheap hash function for all janet objects. If two values are strictly equal, "
"then they will have the same hash value.") "then they will have the same hash value.")
}, },
{
"getline", janet_core_getline,
JDOC("(getline [, prompt=\"\" [, buffer=@\"\"]])\n\n"
"Reads a line of input into a buffer, including the newline character, using a prompt. Returns the modified buffer. "
"Use this function to implement a simple interface for a terminal program.")
},
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
@ -618,8 +647,8 @@ static const uint32_t bnot_asm[] = {
}; };
#endif /* ifndef JANET_NO_BOOTSTRAP */ #endif /* ifndef JANET_NO_BOOTSTRAP */
JanetTable *janet_core_env(void) { JanetTable *janet_core_env(JanetTable *replacements) {
JanetTable *env = janet_table(0); JanetTable *env = (NULL != replacements) ? replacements : janet_table(0);
janet_core_cfuns(env, NULL, corelib_cfuns); janet_core_cfuns(env, NULL, corelib_cfuns);
#ifdef JANET_BOOTSTRAP #ifdef JANET_BOOTSTRAP
@ -791,7 +820,6 @@ JanetTable *janet_core_env(void) {
janet_lib_typed_array(env); janet_lib_typed_array(env);
#endif #endif
#ifdef JANET_BOOTSTRAP #ifdef JANET_BOOTSTRAP
/* Run bootstrap source */ /* Run bootstrap source */
janet_dobytes(env, janet_gen_core, janet_gen_core_size, "core.janet", NULL); janet_dobytes(env, janet_gen_core, janet_gen_core_size, "core.janet", NULL);

View File

@ -328,16 +328,27 @@ const JanetAbstractType *janet_get_abstract_type(Janet key) {
#ifndef JANET_BOOTSTRAP #ifndef JANET_BOOTSTRAP
void janet_core_def(JanetTable *env, const char *name, Janet x, const void *p) { void janet_core_def(JanetTable *env, const char *name, Janet x, const void *p) {
(void) p; (void) p;
janet_table_put(env, janet_csymbolv(name), x); Janet key = janet_csymbolv(name);
Janet value;
/* During boot, allow replacing core library cfunctions with values from
* the env. */
Janet check = janet_table_get(env, key);
if (janet_checktype(check, JANET_NIL)) {
value = x;
} else {
value = check;
if (janet_checktype(check, JANET_CFUNCTION)) {
janet_table_put(janet_vm_registry, value, key);
}
}
janet_table_put(env, key, value);
} }
void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) { void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) {
(void) regprefix; (void) regprefix;
while (cfuns->name) { while (cfuns->name) {
Janet name = janet_csymbolv(cfuns->name);
Janet fun = janet_wrap_cfunction(cfuns->cfun); Janet fun = janet_wrap_cfunction(cfuns->cfun);
janet_core_def(env, cfuns->name, fun, cfuns->documentation); janet_core_def(env, cfuns->name, fun, cfuns->documentation);
janet_table_put(janet_vm_registry, fun, name);
cfuns++; cfuns++;
} }
} }

View File

@ -1015,7 +1015,7 @@ struct JanetCompileResult {
JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where); JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where);
/* Get the default environment for janet */ /* Get the default environment for janet */
JANET_API JanetTable *janet_core_env(void); JANET_API JanetTable *janet_core_env(JanetTable *replacements);
JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out); JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out);
JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out); JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);

View File

@ -33,7 +33,14 @@ int main(int argc, char **argv) {
/* Set up VM */ /* Set up VM */
janet_init(); janet_init();
env = janet_core_env();
/* Replace original getline with new line getter */
JanetTable *replacements = janet_table(0);
janet_table_put(replacements, janet_csymbolv("getline"), janet_wrap_cfunction(janet_line_getter));
janet_line_init();
/* Get core env */
env = janet_core_env(replacements);
/* Create args tuple */ /* Create args tuple */
args = janet_array(argc); args = janet_array(argc);
@ -41,11 +48,6 @@ int main(int argc, char **argv) {
janet_array_push(args, janet_cstringv(argv[i])); janet_array_push(args, janet_cstringv(argv[i]));
janet_def(env, "process/args", janet_wrap_array(args), "Command line arguments."); janet_def(env, "process/args", janet_wrap_array(args), "Command line arguments.");
/* Expose line getter */
janet_def(env, "getline", janet_wrap_cfunction(janet_line_getter), NULL);
janet_register("getline", janet_line_getter);
janet_line_init();
/* Run startup script */ /* Run startup script */
status = janet_dobytes(env, janet_gen_init, janet_gen_init_size, "init.janet", NULL); status = janet_dobytes(env, janet_gen_init, janet_gen_init_size, "init.janet", NULL);