aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--any_sexp.h56
1 files changed, 37 insertions, 19 deletions
diff --git a/any_sexp.h b/any_sexp.h
index aac2407..bbb186f 100644
--- a/any_sexp.h
+++ b/any_sexp.h
@@ -91,6 +91,8 @@ typedef struct any_sexp_cons {
typedef char (*any_sexp_getchar_t)(void *stream);
+typedef int (*any_sexp_fprintf_t)(void *stream, const char *format, ...);
+
typedef struct {
const char *source;
size_t length;
@@ -131,7 +133,11 @@ any_sexp_t any_sexp_cdr(any_sexp_t sexp);
any_sexp_t any_sexp_reverse(any_sexp_t sexp);
-void any_sexp_print(any_sexp_t sexp);
+int any_sexp_stream_print(any_sexp_t sexp, any_sexp_fprintf_t fprintf, void *stream);
+
+int any_sexp_fprint(any_sexp_t sexp, FILE *file);
+
+int any_sexp_print(any_sexp_t sexp);
void any_sexp_free(any_sexp_t sexp);
@@ -293,10 +299,15 @@ any_sexp_t any_sexp_parser_next(any_sexp_parser_t *parser)
// List
if (parser->c == ANY_SEXP_CHAR_OPEN) {
any_sexp_parser_advance(parser);
- any_sexp_parser_skip(parser);
any_sexp_t sexp = ANY_SEXP_NIL;
- while (!any_sexp_parser_eof(parser) && parser->c != ANY_SEXP_CHAR_CLOSE) {
+
+ while (!any_sexp_parser_eof(parser)) {
+ any_sexp_parser_skip(parser);
+
+ if (parser->c == ANY_SEXP_CHAR_CLOSE)
+ break;
+
any_sexp_t sub = any_sexp_parser_next(parser);
sexp = any_sexp_cons(sub, sexp); // reversed
@@ -304,8 +315,6 @@ any_sexp_t any_sexp_parser_next(any_sexp_parser_t *parser)
any_sexp_free(sexp);
return ANY_SEXP_ERROR;
}
-
- any_sexp_parser_skip(parser);
}
any_sexp_parser_advance(parser);
@@ -450,37 +459,46 @@ any_sexp_t any_sexp_reverse(any_sexp_t sexp)
return prev;
}
-void any_sexp_print(any_sexp_t sexp)
+int any_sexp_stream_print(any_sexp_t sexp, any_sexp_fprintf_t fprintf, void *stream)
{
+ int c = 0;
switch (ANY_SEXP_GET_TAG(sexp)) {
case ANY_SEXP_TAG_ERROR:
- printf("<error>");
- break;
+ return fprintf(stream, "<error>");
case ANY_SEXP_TAG_NIL:
- printf("()");
- break;
+ return fprintf(stream, "()");
case ANY_SEXP_TAG_CONS:
- putchar('(');
+ c += fprintf(stream, "(");
while (!ANY_SEXP_IS_NIL(sexp) && !ANY_SEXP_IS_ERROR(sexp)) {
- any_sexp_print(any_sexp_car(sexp));
+ c += any_sexp_stream_print(any_sexp_car(sexp), fprintf, stream);
sexp = any_sexp_cdr(sexp);
- if (!ANY_SEXP_IS_NIL(sexp)) putchar(' ');
+
+ if (!ANY_SEXP_IS_NIL(sexp))
+ c += fprintf(stream, " ");
}
- putchar(')');
- break;
+ c += fprintf(stream, ")");
+ return c;
case ANY_SEXP_TAG_SYMBOL:
- printf("%s", ANY_SEXP_GET_SYMBOL(sexp));
- break;
+ return fprintf(stream, "%s", ANY_SEXP_GET_SYMBOL(sexp));
case ANY_SEXP_TAG_STRING:
- printf("\"%s\"", ANY_SEXP_GET_STRING(sexp));
- break;
+ return fprintf(stream, "\"%s\"", ANY_SEXP_GET_STRING(sexp));
}
}
+int any_sexp_fprint(any_sexp_t sexp, FILE *file)
+{
+ return any_sexp_stream_print(sexp, (any_sexp_fprintf_t)fprintf, file);
+}
+
+int any_sexp_print(any_sexp_t sexp)
+{
+ return any_sexp_fprint(sexp, stdout);
+}
+
void any_sexp_free(any_sexp_t sexp)
{
switch (ANY_SEXP_GET_TAG(sexp)) {