commit 5f4f4b5c785e6658fd17a81249ed573c2e989330
parent 2c03e51a3f90198a4432228d3b1958adca43ea01
Author: Andres Navarro <canavarro82@gmail.com>
Date: Mon, 14 Nov 2011 21:53:37 -0300
Added sexp comments to the reader (syntax: "#; <sexp>")
Diffstat:
4 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/src/kread.c b/src/kread.c
@@ -6,7 +6,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
#include "kread.h"
#include "kobject.h"
@@ -142,8 +141,9 @@ void change_shared_def(klisp_State *K, TValue def_token, TValue value)
/* TEMP: For now we'll use just one big function */
TValue kread_fsm(klisp_State *K)
{
- assert(ks_sisempty(K));
- assert(ttisnil(K->shared_dict));
+ /* TODO replace some read errors with asserts where appropriate */
+ klisp_assert(ks_sisempty(K));
+ klisp_assert(ttisnil(K->shared_dict));
push_state(K, ST_READ);
/* read next token or process obj */
@@ -152,11 +152,12 @@ TValue kread_fsm(klisp_State *K)
TValue obj = KINERT; /* put some value for gc */
/* the source code information of that obj */
TValue obj_si = KNIL; /* put some value for gc */
+ int32_t sexp_comments = 0;
krooted_vars_push(K, &obj);
krooted_vars_push(K, &obj_si);
- while (!(get_state(K) == ST_READ && !read_next_token)) {
+ while (!(get_state(K) == ST_READ && sexp_comments == 0 && !read_next_token)) {
if (read_next_token) {
TValue tok = ktok_read_token(K); /* only root it when necessary */
@@ -344,6 +345,14 @@ TValue kread_fsm(klisp_State *K)
}
break;
}
+ case ';': { /* sexp comment */
+ /* TODO save sexp comment source info */
+ klisp_assert(sexp_comments < 1000);
+ ++sexp_comments;
+ push_state(K, ST_READ);
+ read_next_token = true;
+ break;
+ }
default:
/* shouldn't happen */
kread_error(K, "unknown special token");
@@ -353,10 +362,17 @@ TValue kread_fsm(klisp_State *K)
} else if (ttiseof(tok)) {
switch (get_state(K)) {
case ST_READ:
+ if (sexp_comments == 0) {
/* will exit in next loop */
- obj = tok;
- obj_si = ktok_get_source_info(K);
- read_next_token = false;
+ obj = tok;
+ obj_si = ktok_get_source_info(K);
+ read_next_token = false;
+ } else {
+ /* TODO show source info (and number of sexp comments) */
+ kread_error(K, "EOF found while reading sexp comment");
+ /* avoid warning */
+ return KINERT;
+ }
break;
case ST_FIRST_LIST:
case ST_MIDDLE_LIST:
@@ -469,10 +485,20 @@ TValue kread_fsm(klisp_State *K)
break;
}
case ST_READ:
- /* this shouldn't happen, should've exited the while */
- kread_error(K, "invalid read state (read in while)");
- /* avoid warning */
- return KINERT;
+ if (sexp_comments == 0) {
+ /* this shouldn't happen, should've exited the while */
+ kread_error(K, "invalid read state (read in while)");
+ /* avoid warning */
+ return KINERT;
+ } else {
+ /* was a sexp comment
+ and read proceeds like from before the comment marker */
+ klisp_assert(sexp_comments > 0);
+ --sexp_comments;
+ pop_state(K);
+ read_next_token = true;
+ break;
+ }
default:
/* shouldn't happen */
kread_error(K, "unknown read state in process obj");
@@ -486,7 +512,7 @@ TValue kread_fsm(klisp_State *K)
krooted_vars_pop(K);
pop_state(K);
- assert(ks_sisempty(K));
+ klisp_assert(ks_sisempty(K));
return obj;
}
@@ -497,7 +523,7 @@ TValue kread(klisp_State *K)
{
TValue obj;
- assert(ttisnil(K->shared_dict));
+ klisp_assert(ttisnil(K->shared_dict));
/* TEMP: workaround repl problem with eofs */
K->ktok_seen_eof = false;
diff --git a/src/kstate.c b/src/kstate.c
@@ -172,6 +172,7 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) {
K->ktok_lparen = kcons(K, ch2tv('('), KNIL);
K->ktok_rparen = kcons(K, ch2tv(')'), KNIL);
K->ktok_dot = kcons(K, ch2tv('.'), KNIL);
+ K->ktok_sexp_comment = kcons(K, ch2tv(';'), KNIL);
/* TEMP: For now just hardcode it to 8 spaces tab-stop */
K->ktok_source_info.tab_width = 8;
diff --git a/src/kstate.h b/src/kstate.h
@@ -123,6 +123,7 @@ struct klisp_State {
TValue ktok_lparen;
TValue ktok_rparen;
TValue ktok_dot;
+ TValue ktok_sexp_comment;
/* WORKAROUND for repl */
bool ktok_seen_eof;
diff --git a/src/ktoken.c b/src/ktoken.c
@@ -311,6 +311,9 @@ TValue ktok_read_token(klisp_State *K)
K->ktok_nested_comments = 1;
ktok_ignore_multi_line_comment(K);
continue;
+ case ';': /* sexp comment */
+ ktok_getc(K); /* discard the ';' */
+ return K->ktok_sexp_comment;
default:
return ktok_read_special(K);
}
@@ -351,7 +354,7 @@ TValue ktok_read_token(klisp_State *K)
if (chi == EOF || chi != '#')
goto unrecognized_error;
ktok_getc(K);
- ktok_error(K, "unmatched |# found");
+ ktok_error(K, "unmatched multiline comment close (\"|#\")");
/* avoid warning */
return KINERT;
default: