mirror of
https://github.com/janet-lang/janet
synced 2024-12-30 18:30:26 +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:
parent
687a3c91f5
commit
a363dce943
@ -43,7 +43,8 @@ int main() {
|
||||
/* Set up VM */
|
||||
int status;
|
||||
JanetTable *env;
|
||||
env = janet_core_env();
|
||||
|
||||
env = janet_core_env(NULL);
|
||||
|
||||
/* Run bootstrap script to generate core image */
|
||||
status = janet_dobytes(env, janet_gen_boot, janet_gen_boot_size, "boot.janet", NULL);
|
||||
|
@ -1460,14 +1460,6 @@ value, one key will be ignored."
|
||||
(file/write stderr "compile error: " msg " while compiling " where "\n")
|
||||
(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
|
||||
"Run a context. This evaluates expressions of janet in an environment,
|
||||
and is encapsulates the parsing, compilation, and evaluation.
|
||||
|
@ -243,6 +243,29 @@ static Janet janet_core_hash(int32_t argc, Janet *argv) {
|
||||
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[] = {
|
||||
{
|
||||
"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, "
|
||||
"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}
|
||||
};
|
||||
|
||||
@ -618,8 +647,8 @@ static const uint32_t bnot_asm[] = {
|
||||
};
|
||||
#endif /* ifndef JANET_NO_BOOTSTRAP */
|
||||
|
||||
JanetTable *janet_core_env(void) {
|
||||
JanetTable *env = janet_table(0);
|
||||
JanetTable *janet_core_env(JanetTable *replacements) {
|
||||
JanetTable *env = (NULL != replacements) ? replacements : janet_table(0);
|
||||
janet_core_cfuns(env, NULL, corelib_cfuns);
|
||||
|
||||
#ifdef JANET_BOOTSTRAP
|
||||
@ -791,7 +820,6 @@ JanetTable *janet_core_env(void) {
|
||||
janet_lib_typed_array(env);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef JANET_BOOTSTRAP
|
||||
/* Run bootstrap source */
|
||||
janet_dobytes(env, janet_gen_core, janet_gen_core_size, "core.janet", NULL);
|
||||
|
@ -328,16 +328,27 @@ const JanetAbstractType *janet_get_abstract_type(Janet key) {
|
||||
#ifndef JANET_BOOTSTRAP
|
||||
void janet_core_def(JanetTable *env, const char *name, Janet x, const 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) regprefix;
|
||||
while (cfuns->name) {
|
||||
Janet name = janet_csymbolv(cfuns->name);
|
||||
Janet fun = janet_wrap_cfunction(cfuns->cfun);
|
||||
janet_core_def(env, cfuns->name, fun, cfuns->documentation);
|
||||
janet_table_put(janet_vm_registry, fun, name);
|
||||
cfuns++;
|
||||
}
|
||||
}
|
||||
|
@ -1015,7 +1015,7 @@ struct JanetCompileResult {
|
||||
JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where);
|
||||
|
||||
/* 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_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);
|
||||
|
@ -33,7 +33,14 @@ int main(int argc, char **argv) {
|
||||
|
||||
/* Set up VM */
|
||||
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 */
|
||||
args = janet_array(argc);
|
||||
@ -41,11 +48,6 @@ int main(int argc, char **argv) {
|
||||
janet_array_push(args, janet_cstringv(argv[i]));
|
||||
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 */
|
||||
status = janet_dobytes(env, janet_gen_init, janet_gen_init_size, "init.janet", NULL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user