reader: implement read_vec and setup errors for random closed brackets
This commit is contained in:
@@ -16,6 +16,9 @@ typedef enum
|
|||||||
READ_ERR_OK = 0,
|
READ_ERR_OK = 0,
|
||||||
READ_ERR_EOF,
|
READ_ERR_EOF,
|
||||||
READ_ERR_EXPECTED_CLOSED_BRACE,
|
READ_ERR_EXPECTED_CLOSED_BRACE,
|
||||||
|
READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET,
|
||||||
|
READ_ERR_UNEXPECTED_CLOSED_BRACE,
|
||||||
|
READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET,
|
||||||
READ_ERR_UNKNOWN_CHAR,
|
READ_ERR_UNKNOWN_CHAR,
|
||||||
} read_err_t;
|
} read_err_t;
|
||||||
|
|
||||||
|
|||||||
47
src/reader.c
47
src/reader.c
@@ -21,6 +21,15 @@ const char *read_err_to_cstr(read_err_t err)
|
|||||||
return "EOF";
|
return "EOF";
|
||||||
case READ_ERR_UNKNOWN_CHAR:
|
case READ_ERR_UNKNOWN_CHAR:
|
||||||
return "UNKNOWN_CHAR";
|
return "UNKNOWN_CHAR";
|
||||||
|
break;
|
||||||
|
case READ_ERR_EXPECTED_CLOSED_BRACE:
|
||||||
|
return "EXPECTED_CLOSED_BRACE";
|
||||||
|
case READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET:
|
||||||
|
return "EXPECTED_CLOSED_SQUARE_BRACKET";
|
||||||
|
case READ_ERR_UNEXPECTED_CLOSED_BRACE:
|
||||||
|
return "UNEXPECTED_CLOSED_BRACE";
|
||||||
|
case READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET:
|
||||||
|
return "UNEXPECTED_CLOSED_SQUARE_BRACKET";
|
||||||
default:
|
default:
|
||||||
FAIL("Unreachable");
|
FAIL("Unreachable");
|
||||||
}
|
}
|
||||||
@@ -128,7 +137,11 @@ read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
|
|||||||
{
|
{
|
||||||
lisp_t *item = NIL;
|
lisp_t *item = NIL;
|
||||||
read_err_t err = read(sys, stream, &item);
|
read_err_t err = read(sys, stream, &item);
|
||||||
if (err)
|
if (err == READ_ERR_EOF)
|
||||||
|
{
|
||||||
|
return READ_ERR_EXPECTED_CLOSED_BRACE;
|
||||||
|
}
|
||||||
|
else if (err)
|
||||||
{
|
{
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -152,9 +165,33 @@ read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
|
|||||||
return READ_ERR_OK;
|
return READ_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_err_t read_vec(sys_t *, stream_t *, lisp_t **)
|
read_err_t read_vec(sys_t *sys, stream_t *stream, lisp_t **ret)
|
||||||
{
|
{
|
||||||
TODO("read_vec: not implemented");
|
(void)stream_next(stream);
|
||||||
|
lisp_t *container = make_vec(sys, 0);
|
||||||
|
while (!stream_eoc(stream) && stream_peek(stream) != ']')
|
||||||
|
{
|
||||||
|
lisp_t *item = NIL;
|
||||||
|
read_err_t err = read(sys, stream, &item);
|
||||||
|
if (err == READ_ERR_EOF)
|
||||||
|
{
|
||||||
|
return READ_ERR_EXPECTED_CLOSED_BRACE;
|
||||||
|
}
|
||||||
|
else if (err)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec_append(as_vec(container), &item, sizeof(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream_peek(stream) != ']')
|
||||||
|
return READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET;
|
||||||
|
stream_next(stream);
|
||||||
|
*ret = container;
|
||||||
|
return READ_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_err_t read_quote(sys_t *sys, stream_t *stream, lisp_t **ret)
|
read_err_t read_quote(sys_t *sys, stream_t *stream, lisp_t **ret)
|
||||||
@@ -201,8 +238,12 @@ read_err_t read(sys_t *sys, stream_t *stream, lisp_t **ret)
|
|||||||
return read_quote(sys, stream, ret);
|
return read_quote(sys, stream, ret);
|
||||||
else if (c == '(')
|
else if (c == '(')
|
||||||
return read_list(sys, stream, ret);
|
return read_list(sys, stream, ret);
|
||||||
|
else if (c == ')')
|
||||||
|
return READ_ERR_UNEXPECTED_CLOSED_BRACE;
|
||||||
else if (c == '[')
|
else if (c == '[')
|
||||||
return read_vec(sys, stream, ret);
|
return read_vec(sys, stream, ret);
|
||||||
|
else if (c == ']')
|
||||||
|
return READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET;
|
||||||
|
|
||||||
return READ_ERR_UNKNOWN_CHAR;
|
return READ_ERR_UNKNOWN_CHAR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user