mirror of
https://github.com/janet-lang/janet
synced 2025-02-02 18:29:10 +00:00
Remove faulty quoting logic in parser.
This commit is contained in:
parent
96a605fbc0
commit
6d3e3d8246
@ -126,6 +126,7 @@ int debug_repl(Gst *vm) {
|
|||||||
/* Check if file read in correctly */
|
/* Check if file read in correctly */
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
printf("Parse error: %s\n", p.error);
|
printf("Parse error: %s\n", p.error);
|
||||||
|
buffer = reader = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Check that parser is complete */
|
/* Check that parser is complete */
|
||||||
|
@ -73,6 +73,13 @@ void gst_buffer_append(Gst *vm, GstBuffer *buffer, const uint8_t *string, uint32
|
|||||||
buffer->count = newSize;
|
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 */
|
/* Convert the buffer to a string */
|
||||||
const uint8_t *gst_buffer_to_string(Gst *vm, GstBuffer *buffer) {
|
const uint8_t *gst_buffer_to_string(Gst *vm, GstBuffer *buffer) {
|
||||||
return gst_string_b(vm, buffer->data, buffer->count);
|
return gst_string_b(vm, buffer->data, buffer->count);
|
||||||
|
57
core/parse.c
57
core/parse.c
@ -27,7 +27,6 @@ static const char UNEXPECTED_CLOSING_DELIM[] = "Unexpected closing delimiter";
|
|||||||
|
|
||||||
/* The type of a ParseState */
|
/* The type of a ParseState */
|
||||||
typedef enum ParseType {
|
typedef enum ParseType {
|
||||||
PTYPE_ROOT,
|
|
||||||
PTYPE_FORM,
|
PTYPE_FORM,
|
||||||
PTYPE_STRING,
|
PTYPE_STRING,
|
||||||
PTYPE_TOKEN
|
PTYPE_TOKEN
|
||||||
@ -36,7 +35,6 @@ typedef enum ParseType {
|
|||||||
/* Contain a parse state that goes on the parse stack */
|
/* Contain a parse state that goes on the parse stack */
|
||||||
struct GstParseState {
|
struct GstParseState {
|
||||||
ParseType type;
|
ParseType type;
|
||||||
uint32_t quoteCount;
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
uint8_t endDelimiter;
|
uint8_t endDelimiter;
|
||||||
@ -62,7 +60,6 @@ struct GstParseState {
|
|||||||
/* Get the top ParseState in the parse stack */
|
/* Get the top ParseState in the parse stack */
|
||||||
static GstParseState *parser_peek(GstParser *p) {
|
static GstParseState *parser_peek(GstParser *p) {
|
||||||
if (!p->count) {
|
if (!p->count) {
|
||||||
p_error(p, "parser stack underflow");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return p->data + p->count - 1;
|
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->data = data;
|
||||||
p->cap = newCap;
|
p->cap = newCap;
|
||||||
}
|
}
|
||||||
if (p->count) {
|
|
||||||
top = parser_peek(p);
|
|
||||||
top->quoteCount = p->quoteCount;
|
|
||||||
p->quoteCount = 0;
|
|
||||||
}
|
|
||||||
++p->count;
|
++p->count;
|
||||||
top = parser_peek(p);
|
top = parser_peek(p);
|
||||||
if (!top) return;
|
if (!top) return;
|
||||||
top->type = type;
|
top->type = type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PTYPE_ROOT:
|
|
||||||
break;
|
|
||||||
case PTYPE_STRING:
|
case PTYPE_STRING:
|
||||||
top->buf.string.state = STRING_STATE_BASE;
|
top->buf.string.state = STRING_STATE_BASE;
|
||||||
case PTYPE_TOKEN:
|
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 = ']';
|
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. */
|
/* Append a value to the top-most state in the Parser's stack. */
|
||||||
static void parser_append(GstParser *p, GstValue x) {
|
static void parser_append(GstParser *p, GstValue x) {
|
||||||
GstParseState *top = parser_peek(p);
|
GstParseState *top = parser_peek(p);
|
||||||
if (!top) return;
|
if (!top) {
|
||||||
while (top->quoteCount--)
|
p->value = x;
|
||||||
x = quote(p, x);
|
p->status = GST_PARSER_FULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (top->type) {
|
switch (top->type) {
|
||||||
case PTYPE_ROOT:
|
|
||||||
p->value = x;
|
|
||||||
p->status = GST_PARSER_FULL;
|
|
||||||
break;
|
|
||||||
case PTYPE_FORM:
|
case PTYPE_FORM:
|
||||||
gst_array_push(p->vm, top->buf.form.array, x);
|
gst_array_push(p->vm, top->buf.form.array, x);
|
||||||
break;
|
break;
|
||||||
@ -394,10 +383,6 @@ static int root_state(GstParser *p, uint8_t c) {
|
|||||||
parser_push(p, PTYPE_STRING, c);
|
parser_push(p, PTYPE_STRING, c);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (c == '\'') {
|
|
||||||
p->quoteCount++;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (is_symbol_char(c)) {
|
if (is_symbol_char(c)) {
|
||||||
parser_push(p, PTYPE_TOKEN, c);
|
parser_push(p, PTYPE_TOKEN, c);
|
||||||
return 0;
|
return 0;
|
||||||
@ -447,19 +432,20 @@ static void dispatch_char(GstParser *p, uint8_t c) {
|
|||||||
/* Dispatch character to state */
|
/* Dispatch character to state */
|
||||||
while (!done) {
|
while (!done) {
|
||||||
GstParseState *top = parser_peek(p);
|
GstParseState *top = parser_peek(p);
|
||||||
switch (top->type) {
|
if (!top) {
|
||||||
case PTYPE_ROOT:
|
done = root_state(p, c);
|
||||||
done = root_state(p, c);
|
} else {
|
||||||
break;
|
switch (top->type) {
|
||||||
case PTYPE_TOKEN:
|
case PTYPE_TOKEN:
|
||||||
done = token_state(p, c);
|
done = token_state(p, c);
|
||||||
break;
|
break;
|
||||||
case PTYPE_FORM:
|
case PTYPE_FORM:
|
||||||
done = form_state(p, c);
|
done = form_state(p, c);
|
||||||
break;
|
break;
|
||||||
case PTYPE_STRING:
|
case PTYPE_STRING:
|
||||||
done = string_state(p, c);
|
done = string_state(p, c);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,7 +504,6 @@ void gst_parser(GstParser *p, Gst *vm) {
|
|||||||
p->error = NULL;
|
p->error = NULL;
|
||||||
p->status = GST_PARSER_ROOT;
|
p->status = GST_PARSER_ROOT;
|
||||||
p->value.type = GST_NIL;
|
p->value.type = GST_NIL;
|
||||||
parser_push(p, PTYPE_ROOT, ' ');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GC mark a parser */
|
/* 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) {
|
for (i = 0; i < p->count; ++i) {
|
||||||
GstParseState *ps = p->data + i;
|
GstParseState *ps = p->data + i;
|
||||||
switch (ps->type) {
|
switch (ps->type) {
|
||||||
case PTYPE_ROOT:
|
|
||||||
break;
|
|
||||||
case PTYPE_FORM:
|
case PTYPE_FORM:
|
||||||
gst_mark_value(vm, gst_wrap_array(ps->buf.form.array));
|
gst_mark_value(vm, gst_wrap_array(ps->buf.form.array));
|
||||||
break;
|
break;
|
||||||
|
69
core/stl.c
69
core/stl.c
@ -525,7 +525,7 @@ int gst_stl_serialize(Gst *vm) {
|
|||||||
* def */
|
* def */
|
||||||
int gst_stl_export(Gst *vm) {
|
int gst_stl_export(Gst *vm) {
|
||||||
gst_table_put(vm, vm->registry, gst_arg(vm, 0), gst_arg(vm, 1));
|
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 */
|
/* Get everything in the current namespace */
|
||||||
@ -700,6 +700,72 @@ int gst_stl_gcollect(Gst *vm) {
|
|||||||
return GST_RETURN_OK;
|
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, "<visited ");
|
||||||
|
gst_buffer_append(vm, b, str, gst_string_length(str));
|
||||||
|
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 */
|
/* Bootstraping */
|
||||||
/****/
|
/****/
|
||||||
@ -750,6 +816,7 @@ static const GstModuleItem const std_module[] = {
|
|||||||
{"close", gst_stl_close},
|
{"close", gst_stl_close},
|
||||||
{"dasm", gst_stl_dasm},
|
{"dasm", gst_stl_dasm},
|
||||||
{"gcollect", gst_stl_gcollect},
|
{"gcollect", gst_stl_gcollect},
|
||||||
|
{"debugp", gst_stl_debugp},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -344,6 +344,7 @@ void gst_buffer_ensure(Gst *vm, GstBuffer *buffer, uint32_t capacity);
|
|||||||
int gst_buffer_get(GstBuffer *buffer, uint32_t index);
|
int gst_buffer_get(GstBuffer *buffer, uint32_t index);
|
||||||
void gst_buffer_push(Gst *vm, GstBuffer *buffer, uint8_t c);
|
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(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);
|
const uint8_t *gst_buffer_to_string(Gst *vm, GstBuffer *buffer);
|
||||||
|
|
||||||
/* Define a push function for pushing a certain type to the buffer */
|
/* Define a push function for pushing a certain type to the buffer */
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
(: seen (if seen seen {}))
|
(: seen (if seen seen {}))
|
||||||
(if (get seen a) (get seen a)
|
(if (get seen a) (get seen a)
|
||||||
(do
|
(do
|
||||||
|
(set! seen a "<cycle>")
|
||||||
(: parts [])
|
(: parts [])
|
||||||
(: len (length a))
|
(: len (length a))
|
||||||
(: i 0)
|
(: i 0)
|
||||||
@ -25,6 +26,7 @@
|
|||||||
(: seen (if seen seen {}))
|
(: seen (if seen seen {}))
|
||||||
(if (get seen s) (get seen s)
|
(if (get seen s) (get seen s)
|
||||||
(do
|
(do
|
||||||
|
(set! seen s "<cycle>")
|
||||||
(: parts [])
|
(: parts [])
|
||||||
(: key (next s))
|
(: key (next s))
|
||||||
(while (not (= key nil))
|
(while (not (= key nil))
|
||||||
@ -54,6 +56,10 @@
|
|||||||
(handler x seen)))
|
(handler x seen)))
|
||||||
|
|
||||||
"Export pretty print"
|
"Export pretty print"
|
||||||
(export! 'pp pp)
|
(export! "pp" pp)
|
||||||
|
|
||||||
|
(: arr [1 2 3 4])
|
||||||
|
(push! arr arr)
|
||||||
|
(print (pp arr))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user