From 6d3e3d8246cd0980694fe03dff3349ccd614eda3 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 7 May 2017 18:20:11 -0400 Subject: [PATCH] Remove faulty quoting logic in parser. --- client/main.c | 1 + core/ds.c | 7 +++++ core/parse.c | 57 ++++++++++++++------------------------- core/stl.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++- include/gst/gst.h | 1 + libs/pp.gst | 8 +++++- 6 files changed, 104 insertions(+), 39 deletions(-) diff --git a/client/main.c b/client/main.c index 011c9080..70906319 100644 --- a/client/main.c +++ b/client/main.c @@ -126,6 +126,7 @@ int debug_repl(Gst *vm) { /* Check if file read in correctly */ if (p.error) { printf("Parse error: %s\n", p.error); + buffer = reader = NULL; continue; } /* Check that parser is complete */ diff --git a/core/ds.c b/core/ds.c index e3b13afa..fde0c9b0 100644 --- a/core/ds.c +++ b/core/ds.c @@ -73,6 +73,13 @@ void gst_buffer_append(Gst *vm, GstBuffer *buffer, const uint8_t *string, uint32 buffer->count = newSize; } +/* Push a cstring to buffer */ +void gst_buffer_append_cstring(Gst *vm, GstBuffer *buffer, const char *cstring) { + uint32_t len = 0; + while (cstring[len]) ++len; + gst_buffer_append(vm, buffer, (const uint8_t *) cstring, len); +} + /* Convert the buffer to a string */ const uint8_t *gst_buffer_to_string(Gst *vm, GstBuffer *buffer) { return gst_string_b(vm, buffer->data, buffer->count); diff --git a/core/parse.c b/core/parse.c index 3611c80e..db56ef4b 100644 --- a/core/parse.c +++ b/core/parse.c @@ -27,7 +27,6 @@ static const char UNEXPECTED_CLOSING_DELIM[] = "Unexpected closing delimiter"; /* The type of a ParseState */ typedef enum ParseType { - PTYPE_ROOT, PTYPE_FORM, PTYPE_STRING, PTYPE_TOKEN @@ -36,7 +35,6 @@ typedef enum ParseType { /* Contain a parse state that goes on the parse stack */ struct GstParseState { ParseType type; - uint32_t quoteCount; union { struct { uint8_t endDelimiter; @@ -62,7 +60,6 @@ struct GstParseState { /* Get the top ParseState in the parse stack */ static GstParseState *parser_peek(GstParser *p) { if (!p->count) { - p_error(p, "parser stack underflow"); return NULL; } return p->data + p->count - 1; @@ -96,18 +93,11 @@ static void parser_push(GstParser *p, ParseType type, uint8_t character) { p->data = data; p->cap = newCap; } - if (p->count) { - top = parser_peek(p); - top->quoteCount = p->quoteCount; - p->quoteCount = 0; - } ++p->count; top = parser_peek(p); if (!top) return; top->type = type; switch (type) { - case PTYPE_ROOT: - break; case PTYPE_STRING: top->buf.string.state = STRING_STATE_BASE; case PTYPE_TOKEN: @@ -118,20 +108,19 @@ static void parser_push(GstParser *p, ParseType type, uint8_t character) { if (character == '(') top->buf.form.endDelimiter = ')'; if (character == '[') top->buf.form.endDelimiter = ']'; if (character == '{') top->buf.form.endDelimiter = '}'; + break; } } /* Append a value to the top-most state in the Parser's stack. */ static void parser_append(GstParser *p, GstValue x) { GstParseState *top = parser_peek(p); - if (!top) return; - while (top->quoteCount--) - x = quote(p, x); + if (!top) { + p->value = x; + p->status = GST_PARSER_FULL; + return; + } switch (top->type) { - case PTYPE_ROOT: - p->value = x; - p->status = GST_PARSER_FULL; - break; case PTYPE_FORM: gst_array_push(p->vm, top->buf.form.array, x); break; @@ -394,10 +383,6 @@ static int root_state(GstParser *p, uint8_t c) { parser_push(p, PTYPE_STRING, c); return 1; } - if (c == '\'') { - p->quoteCount++; - return 1; - } if (is_symbol_char(c)) { parser_push(p, PTYPE_TOKEN, c); return 0; @@ -447,19 +432,20 @@ static void dispatch_char(GstParser *p, uint8_t c) { /* Dispatch character to state */ while (!done) { GstParseState *top = parser_peek(p); - switch (top->type) { - case PTYPE_ROOT: - done = root_state(p, c); - break; - case PTYPE_TOKEN: - done = token_state(p, c); - break; - case PTYPE_FORM: - done = form_state(p, c); - break; - case PTYPE_STRING: - done = string_state(p, c); - break; + if (!top) { + done = root_state(p, c); + } else { + switch (top->type) { + case PTYPE_TOKEN: + done = token_state(p, c); + break; + case PTYPE_FORM: + done = form_state(p, c); + break; + case PTYPE_STRING: + done = string_state(p, c); + break; + } } } } @@ -518,7 +504,6 @@ void gst_parser(GstParser *p, Gst *vm) { p->error = NULL; p->status = GST_PARSER_ROOT; p->value.type = GST_NIL; - parser_push(p, PTYPE_ROOT, ' '); } /* GC mark a parser */ @@ -532,8 +517,6 @@ static void gst_stl_parser_mark(Gst *vm, void *data, uint32_t len) { for (i = 0; i < p->count; ++i) { GstParseState *ps = p->data + i; switch (ps->type) { - case PTYPE_ROOT: - break; case PTYPE_FORM: gst_mark_value(vm, gst_wrap_array(ps->buf.form.array)); break; diff --git a/core/stl.c b/core/stl.c index 5b8888e8..1382427c 100644 --- a/core/stl.c +++ b/core/stl.c @@ -525,7 +525,7 @@ int gst_stl_serialize(Gst *vm) { * def */ int gst_stl_export(Gst *vm) { gst_table_put(vm, vm->registry, gst_arg(vm, 0), gst_arg(vm, 1)); - gst_c_return(vm, gst_wrap_nil()); + gst_c_return(vm, gst_arg(vm, 1)); } /* Get everything in the current namespace */ @@ -700,6 +700,72 @@ int gst_stl_gcollect(Gst *vm) { return GST_RETURN_OK; } +/* Static debug print helper */ +static GstInteger gst_stl_debugp_helper(Gst *vm, GstBuffer *b, GstTable *seen, GstValue x, GstInteger next) { + GstValue check = gst_table_get(seen, x); + const uint8_t *str; + if (check.type == GST_INTEGER) { + str = gst_to_string(vm, check); + gst_buffer_append_cstring(vm, b, ""); + } else { + uint8_t open, close; + uint32_t len, i; + const GstValue *data; + switch (x.type) { + default: + str = gst_to_string(vm, x); + gst_buffer_append(vm, b, str, gst_string_length(str)); + return next; + case GST_STRUCT: + open = '<'; close = '>'; + break; + case GST_TABLE: + open = '{'; close = '}'; + break; + case GST_TUPLE: + open = '('; close = ')'; + break; + case GST_ARRAY: + open = '['; close = ']'; + break; + } + gst_table_put(vm, seen, x, gst_wrap_integer(next++)); + gst_buffer_push(vm, b, open); + if (gst_hashtable_view(x, &data, &len)) { + int isfirst = 1; + for (i = 0; i < len; i += 2) { + if (data[i].type != GST_NIL) { + if (isfirst) + isfirst = 0; + else + gst_buffer_push(vm, b, ' '); + next = gst_stl_debugp_helper(vm, b, seen, data[i], next); + gst_buffer_push(vm, b, ' '); + next = gst_stl_debugp_helper(vm, b, seen, data[i + 1], next); + } + } + } else if (gst_seq_view(x, &data, &len)) { + for (i = 0; i < len; ++i) { + next = gst_stl_debugp_helper(vm, b, seen, data[i], next); + if (i != len - 1) + gst_buffer_push(vm, b, ' '); + } + } + gst_buffer_push(vm, b, close); + } + return next; +} + +/* Debug print */ +int gst_stl_debugp(Gst *vm) { + GstValue x = gst_arg(vm, 0); + GstBuffer *buf = gst_buffer(vm, 10); + gst_stl_debugp_helper(vm, buf, gst_table(vm, 10), x, 0); + gst_c_return(vm, gst_wrap_string(gst_buffer_to_string(vm, buf))); +} + /****/ /* Bootstraping */ /****/ @@ -750,6 +816,7 @@ static const GstModuleItem const std_module[] = { {"close", gst_stl_close}, {"dasm", gst_stl_dasm}, {"gcollect", gst_stl_gcollect}, + {"debugp", gst_stl_debugp}, {NULL, NULL} }; diff --git a/include/gst/gst.h b/include/gst/gst.h index 0689786f..74f094ea 100644 --- a/include/gst/gst.h +++ b/include/gst/gst.h @@ -344,6 +344,7 @@ void gst_buffer_ensure(Gst *vm, GstBuffer *buffer, uint32_t capacity); int gst_buffer_get(GstBuffer *buffer, uint32_t index); void gst_buffer_push(Gst *vm, GstBuffer *buffer, uint8_t c); void gst_buffer_append(Gst *vm, GstBuffer *buffer, const uint8_t *string, uint32_t length); +void gst_buffer_append_cstring(Gst *vm, GstBuffer *buffer, const char *cstring); const uint8_t *gst_buffer_to_string(Gst *vm, GstBuffer *buffer); /* Define a push function for pushing a certain type to the buffer */ diff --git a/libs/pp.gst b/libs/pp.gst index 8474ce54..a63fe3e2 100644 --- a/libs/pp.gst +++ b/libs/pp.gst @@ -7,6 +7,7 @@ (: seen (if seen seen {})) (if (get seen a) (get seen a) (do + (set! seen a "") (: parts []) (: len (length a)) (: i 0) @@ -25,6 +26,7 @@ (: seen (if seen seen {})) (if (get seen s) (get seen s) (do + (set! seen s "") (: parts []) (: key (next s)) (while (not (= key nil)) @@ -54,6 +56,10 @@ (handler x seen))) "Export pretty print" -(export! 'pp pp) +(export! "pp" pp) + +(: arr [1 2 3 4]) +(push! arr arr) +(print (pp arr)) )