klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 108007f8ea3acd454ff8676b7967e622701ca748
parent 01cb406bffe88b68eea68b495631414f11a56093
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Thu, 24 Nov 2011 20:48:36 -0300

Added get-environment-variable and get-environment-variables to the ground environment.

Diffstat:
Msrc/kgsystem.c | 88++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 83 insertions(+), 5 deletions(-)

diff --git a/src/kgsystem.c b/src/kgsystem.c @@ -5,6 +5,7 @@ */ #include <assert.h> +#include <string.h> #include <stdlib.h> #include <stdbool.h> #include <stdio.h> @@ -175,20 +176,93 @@ void rename_file(klisp_State *K) } } -/* used for both get_script_arguments and get_interpreter_arguments */ +/* ?.? get-script-arguments, get-interpreter-arguments */ void get_arguments(klisp_State *K) { /* - * xparams[0]: immutable argument list + ** xparams[0]: immutable argument list */ TValue ptree = K->next_value; TValue *xparams = K->next_xparams; - check_0p(K, ptree); + TValue denv = K->next_env; + klisp_assert(ttisenvironment(K->next_env)); + UNUSED(denv); + check_0p(K, ptree); TValue res = xparams[0]; kapply_cc(K, res); } +/* ?.? get-environment-variable, get-environment-variables */ +void get_environment_variable(klisp_State *K) +{ + TValue ptree = K->next_value; + TValue *xparams = K->next_xparams; + TValue denv = K->next_env; + klisp_assert(ttisenvironment(K->next_env)); + UNUSED(xparams); + UNUSED(denv); + + bind_1tp(K, ptree, "string", ttisstring, name); + char *str = getenv(kstring_buf(name)); + /* I follow r7rs here, but should probably throw error */ + TValue res; + if (str == NULL) { + res = KFALSE; + } else { + res = kstring_new_b_imm(K, str); + } + kapply_cc(K, res); +} + +void get_environment_variables(klisp_State *K) +{ + /* + ** xparams[0]: immutable variable list + */ + TValue ptree = K->next_value; + TValue *xparams = K->next_xparams; + TValue denv = K->next_env; + klisp_assert(ttisenvironment(K->next_env)); + UNUSED(denv); + + check_0p(K, ptree); + kapply_cc(K, xparams[0]); +} + +/* This should work in mingw as well as gcc */ +/* TODO test, if that doesn't work, try to find a way + avoiding taking extra params in main */ +/* I think it's defined in unistd, but it needs to have __USE_GNU + defined. The correct way to do that would be to define _GNU_SOURCE + before including any system files... That's not good for an + embeddable interpreter... */ +extern char **environ; + +/* Helper for get-environment-variables */ +TValue create_env_var_list(klisp_State *K) +{ + /* no need for gc guarding in this context */ + TValue var_name, var_value; + TValue tail = KNIL; + + /* This should work in mingw as well as gcc */ + /* TODO test, if that doesn't work, try to find a way + avoiding taking extra params in main */ + for(char **env = environ; *env != NULL; ++env) { + /* *env is of the form: "<name>=<value>", presumably, name can't have + an equal sign! */ + char *eq = strchr(*env, '='); + int name_len = eq - *env; + klisp_assert(eq != NULL); /* shouldn't happen */ + var_name = kstring_new_bs_imm(K, *env, name_len); + var_value = kstring_new_b_imm(K, *env + name_len + 1); + TValue new_entry = kimm_cons(K, var_name, var_value); + tail = kimm_cons(K, new_entry, tail); + } + return tail; +} + /* init ground */ void kinit_system_ground_env(klisp_State *K) { @@ -210,10 +284,14 @@ void kinit_system_ground_env(klisp_State *K) /* ?.? rename-file */ add_applicative(K, ground_env, "rename-file", rename_file, 0); /* The value for these two will get set later by the interpreter */ - /* ?.? get-script-arguments */ + /* ?.? get-script-arguments, get-interpreter-arguments */ add_applicative(K, ground_env, "get-script-arguments", get_arguments, 1, KNIL); - /* ?.? get-interpreter-arguments */ add_applicative(K, ground_env, "get-interpreter-arguments", get_arguments, 1, KNIL); + /* ?.? get-environment-variable, get-environment-variables */ + add_applicative(K, ground_env, "get-environment-variable", + get_environment_variable, 0); + add_applicative(K, ground_env, "get-environment-variables", + get_environment_variables, 1, create_env_var_list(K)); }