commit 9f464f5bd174710f1505ac1a7b9920b30cbc66b1
parent 083d1496630d0d27dbd673957327cbb122d16a79
Author: Andres Navarro <canavarro82@gmail.com>
Date: Wed, 30 Nov 2011 04:17:32 -0300
Updated the manual, interpreter tests, bugfix in ktoken, some comments.
Diffstat:
10 files changed, 77 insertions(+), 84 deletions(-)
diff --git a/doc/klisp.1 b/doc/klisp.1
@@ -30,7 +30,12 @@ the klisp program in file
is loaded and evaluated.
All evaluations, including the initialization
that is described below, take place in the same
-(initially) standard environment.
+(initially) standard environment. All values that
+result from these evaluation are discarded, but
+if the root continuation or error continuation
+are passed value, the interpretation of arguments
+is interrupted and the EXIT_STATUS is as described
+in the corresponding section.
The given
.I args
are available to
@@ -42,9 +47,10 @@ then they should be quoted
(but note that the quotes will be removed by the shell).
The arguments in the returned string start with the string
.RI ' script '.
-The arguments given in the command line before
+All the arguments given in the command line
.IR script ,
-including the name of the interpreter,
+including the name of the interpreter, options,
+, the script, and its arguments
are available via the applicative
.RI ' get-interpreter-arguments '.
.LP
@@ -119,8 +125,8 @@ or
reach EOF or if there is no script,
.B EXIT_SUCCESS
is returned.
-If there is an error during the evaluation of
-the options,
+If the root continuation is passed an object during
+init, arguments or script evaluation
.B EXIT_FAILURE
is returned.
If the
diff --git a/src/klisp.c b/src/klisp.c
@@ -148,7 +148,7 @@ static int report (klisp_State *K, int status)
static void print_version(void)
{
- k_message(NULL, KLISP_RELEASE " " KLISP_COPYRIGHT);
+ printf("%s\n", KLISP_RELEASE " " KLISP_COPYRIGHT);
}
/* REFACTOR maybe these should be moved to a general place to be used
@@ -541,11 +541,14 @@ static void populate_argument_lists(klisp_State *K, char **argv, int argc,
static int handle_klispinit(klisp_State *K)
{
- const char *init = getenv(KLISP_INIT);
- if (init == NULL)
- return EXIT_SUCCESS;
- else
- return dostring(K, init, "=" KLISP_INIT);
+ const char *init = getenv(KLISP_INIT);
+ int res;
+ if (init == NULL)
+ res = EXIT_SUCCESS;
+ else
+ res = dostring(K, init, "=" KLISP_INIT);
+
+ return res;
}
/* This is weird but was done to follow lua scheme */
diff --git a/src/kread.c b/src/kread.c
@@ -539,7 +539,7 @@ TValue kread_fsm(klisp_State *K, bool listp)
read_next_token = false;
}
}
- } else { /* if(read_next_token) */
+ } else { /* read_next_token == false */
/* process the object just read */
switch(get_state(K)) {
case ST_FIRST_EOF_LIST:
@@ -676,24 +676,20 @@ TValue kread_fsm(klisp_State *K, bool listp)
*/
TValue kread(klisp_State *K, bool listp)
{
- TValue obj;
-
klisp_assert(ttisnil(K->shared_dict));
- /* WORKAROUND: for repl problem with eofs */
- K->ktok_seen_eof = false;
-
- obj = kread_fsm(K, listp);
-
- /* NOTE: clear after function to allow earlier gc */
- clear_shared_dict(K);
+ TValue obj = kread_fsm(K, listp);
+ clear_shared_dict(K); /* clear after function to allow earlier gc */
return obj;
}
/* port is protected from GC in curr_port */
TValue kread_from_port_g(klisp_State *K, TValue port, bool mut, bool listp)
{
- K->curr_port = port;
+ if (!tv_equal(port, K->curr_port)) {
+ K->ktok_seen_eof = false; /* WORKAROUND: for repl problem with eofs */
+ K->curr_port = port;
+ }
K->read_mconsp = mut;
ktok_set_source_info(K, kport_filename(port),
@@ -735,10 +731,10 @@ TValue kread_peek_char_from_port(klisp_State *K, TValue port, bool peek)
klisp_assert(kport_is_open(port));
klisp_assert(kport_is_textual(port));
- /* Reset the EOF flag in the tokenizer. The flag is shared,
- by operations on all ports. */
- K->ktok_seen_eof = false;
- K->curr_port = port;
+ if (!tv_equal(port, K->curr_port)) {
+ K->ktok_seen_eof = false; /* WORKAROUND: for repl problem with eofs */
+ K->curr_port = port;
+ }
int ch;
if (peek) {
ch = ktok_peekc(K);
@@ -759,10 +755,10 @@ TValue kread_peek_u8_from_port(klisp_State *K, TValue port, bool peek)
klisp_assert(kport_is_open(port));
klisp_assert(kport_is_binary(port));
- /* Reset the EOF flag in the tokenizer. The flag is shared,
- by operations on all ports. */
- K->ktok_seen_eof = false;
- K->curr_port = port;
+ if (!tv_equal(port, K->curr_port)) {
+ K->ktok_seen_eof = false; /* WORKAROUND: for repl problem with eofs */
+ K->curr_port = port;
+ }
int32_t u8;
if (peek) {
u8 = ktok_peekc(K);
@@ -783,10 +779,10 @@ TValue kread_line_from_port(klisp_State *K, TValue port)
klisp_assert(kport_is_open(port));
klisp_assert(kport_is_textual(port));
- /* Reset the EOF flag in the tokenizer. The flag is shared,
- by operations on all ports. */
- K->ktok_seen_eof = false;
- K->curr_port = port;
+ if (!tv_equal(port, K->curr_port)) {
+ K->ktok_seen_eof = false; /* WORKAROUND: for repl problem with eofs */
+ K->curr_port = port;
+ }
uint32_t size = MINREADLINEBUFFER;
uint32_t i = 0;
@@ -830,13 +826,13 @@ TValue kread_line_from_port(klisp_State *K, TValue port)
}
/* This is needed by the repl to ignore trailing spaces (especially newlines)
- that could affect the source info */
-/* XXX This should be replaced somehow, as it doesn't work for sexp and
- multi line comments */
-void kread_ignore_whitespace_and_comments_from_port(klisp_State *K,
- TValue port)
+ that could affect the (freshly reset) source info */
+void kread_clear_leading_whitespace_from_port(klisp_State *K, TValue port)
{
- K->curr_port = port;
+ if (!tv_equal(port, K->curr_port)) {
+ K->ktok_seen_eof = false; /* WORKAROUND: for repl problem with eofs */
+ K->curr_port = port;
+ }
/* source code info isn't important because it will be reset later */
- ktok_ignore_whitespace_and_comments(K);
+ ktok_ignore_whitespace(K);
}
diff --git a/src/kread.h b/src/kread.h
@@ -18,9 +18,7 @@ TValue kread_list_from_port(klisp_State *K, TValue port, bool mut);
TValue kread_peek_char_from_port(klisp_State *K, TValue port, bool peek);
TValue kread_peek_u8_from_port(klisp_State *K, TValue port, bool peek);
TValue kread_line_from_port(klisp_State *K, TValue port);
-/* XXX soon to be replaced */
-void kread_ignore_whitespace_and_comments_from_port(klisp_State *K,
- TValue port);
+void kread_clear_leading_whitespace_from_port(klisp_State *K, TValue port);
#endif
diff --git a/src/krepl.c b/src/krepl.c
@@ -45,13 +45,10 @@ void do_repl_read(klisp_State *K)
TValue port = kcdr(K->kd_in_port_key);
klisp_assert(kfport_file(port) == stdin);
-#if 0 /* Let's disable this for now */
- /* workaround to the problem of the dangling '\n' in repl
+ /* Workaround to the problem of the dangling '\n' in repl
(from previous line) */
- kread_ignore_whitespace_and_comments_from_port(K, port);
-
- kport_reset_source_info(port);
-#endif
+ kread_clear_leading_whitespace_from_port(K, port);
+ kport_reset_source_info(port); /* always start with a clean source info */
obj = kread_from_port(K, port, true); /* read mutable pairs */
kapply_cc(K, obj);
}
diff --git a/src/kstate.h b/src/kstate.h
@@ -50,12 +50,14 @@ typedef struct stringtable {
/* NOTE: when adding TValues here, remember to add them to
markroot in kgc.c!! */
+/* TODO split this struct in substructs (e.g. run_context, tokenizer,
+ gc, etc) */
struct klisp_State {
stringtable strt; /* hash table for immutable strings & symbols */
TValue name_table; /* hash tables for naming objects */
TValue cont_name_table; /* hash tables for naming continuation functions*/
- TValue curr_cont;
+ TValue curr_cont;
/*
** If next_env is NIL, then the next_func from a continuation
** and otherwise next_func is from an operative
@@ -134,9 +136,10 @@ struct klisp_State {
TValue ktok_sexp_comment;
/* WORKAROUND for repl */
- bool ktok_seen_eof;
+ bool ktok_seen_eof; /* to keep track of eofs that later dissapear */
+ /* source info tracking */
ksource_info_t ktok_source_info;
- /* tokenizer buffer */
+ /* tokenizer buffer (XXX this could be done with a string) */
int32_t ktok_buffer_size;
int32_t ktok_buffer_idx;
char *ktok_buffer;
@@ -151,11 +154,13 @@ struct klisp_State {
/* writer */
bool write_displayp;
- /* auxiliary stack */
+ /* auxiliary stack (XXX this could be a vector) */
int32_t ssize; /* total size of array */
int32_t stop; /* top of the stack (all elements are below this index) */
TValue *sbuf;
+ /* These could be eliminated if a stack was adopted for the c interface */
+ /* (like in lua) */
/* TValue stack to protect values from gc, must not grow, otherwise
it may call the gc */
int32_t rooted_tvs_top;
@@ -166,6 +171,7 @@ struct klisp_State {
int32_t rooted_vars_top;
TValue *rooted_vars_buf[GC_PROTECT_SIZE];
+ /* XXX These should be replaced with calls to krooted_vars_push */
/* These three are useful for constructing lists by means of set-car &
set-cdr. The idea is that these dummy pairs start as the head of
the list (protecting the entire chain from GC) and at the end of the
diff --git a/src/ksystem.win32.c b/src/ksystem.win32.c
@@ -61,6 +61,12 @@ bool ksystem_isatty(klisp_State *K, TValue port)
*
* TEMP: use GetConsoleMode()
*/
+/*
+** Lua uses _isatty in Windows, shouldn't that work?
+** e.g. _isatty(_fileno(kport_file(port)))
+** I'll try to test it when I have access to a Windows box
+** Andres Navarro
+*/
DWORD mode;
return GetConsoleMode(h, &mode);
diff --git a/src/ktoken.c b/src/ktoken.c
@@ -532,29 +532,6 @@ void ktok_ignore_whitespace(klisp_State *K)
}
}
-/* XXX temp for repl */
-void ktok_ignore_whitespace_and_comments(klisp_State *K)
-{
- /* NOTE: if it's not whitespace do nothing (even on eof) */
- while(true) {
- int chi = ktok_peekc(K);
-
- if (chi == EOF) {
- return;
- } else {
- char ch = (char) chi;
- if (ktok_is_whitespace(ch)) {
- ktok_getc(K);
- } else if (ch == ';') {
- ktok_ignore_single_line_comment(K);
- } else {
- return;
- }
- }
- }
-}
-
-
/*
** Delimiter checking
*/
diff --git a/src/ktoken.h b/src/ktoken.h
@@ -33,7 +33,7 @@ inline int ktok_getc(klisp_State *K) { return ktok_peekc_getc(K, false); }
inline int ktok_peekc(klisp_State *K) { return ktok_peekc_getc(K, true); }
/* needed by the repl */
-void ktok_ignore_whitespace_and_comments(klisp_State *K);
+void ktok_ignore_whitespace(klisp_State *K);
/* This is needed for string->symbol to check if a symbol has external
representation as an identifier */
diff --git a/src/tests/test-interpreter.sh b/src/tests/test-interpreter.sh
@@ -145,12 +145,14 @@ check_oi '2' '(display (+ 1 1))' $KLISP -
check_o 'abcdef' $KLISP '-e (display "abc")' '-e' '(display "def")'
# option: -i
+# The interpreter always show name and version
+# WAS check_oi 'klisp> ' '' $KLISP -i
-check_oi 'klisp> ' '' $KLISP -i
+check_oi '/klisp [0-9.][0-9.]* .*\n.*klisp> /' '' $KLISP -i
# option: -v
-check_o '/klisp [0-9.]+ .*/' $KLISP -v
+check_o '/klisp [0-9.][0-9.]* .*/' $KLISP -v
# '--' on the command line
@@ -169,6 +171,11 @@ check_os '' 0 $KLISP -e '(exit)'
check_os '' 0 $KLISP -e '1'
check_os '' 3 $KLISP -e '(apply-continuation root-continuation 3)'
+## FIX the root continuation should exit without running any more
+## arguments, but it doesn't...
+check_os '' 0 $KLISP -e '(exit 0)' -e '(exit 1)'
+check_os '' 1 $KLISP -e '(exit 1)' -e '(exit 0)'
+
# KLISP_INIT environment variable
export KLISP_INIT='(display "init...")'
@@ -192,10 +199,7 @@ check_o '("/dev/null")' $KLISP -e '(write(get-script-arguments))' -- /dev/null
# interpreter arguments
# (get-interpreter-arguments) returns all command line
# arguments.
-#
-# TODO: The man page says that (interpreter-arguments)
-# returns the arguments _before_ the script name.
-#
+
check_o "(\"$KLISP\" \"-e\" \"(write(get-interpreter-arguments))\")" \
$KLISP -e '(write(get-interpreter-arguments))'