Improve parser errors slightly
This commit is contained in:
@@ -79,7 +79,12 @@ int main(int argc, const char **argv) {
|
||||
}
|
||||
|
||||
struct ucl_object *sexp = ucl_parse(line);
|
||||
struct ucl_object *result = ucl_evaluate(scope, ucl_car(sexp));
|
||||
struct ucl_object *result = NULL;
|
||||
if (sexp->type == UCL_TYPE_ERROR) {
|
||||
result = sexp;
|
||||
} else {
|
||||
result = ucl_evaluate(scope, ucl_car(sexp));
|
||||
}
|
||||
ucl_print_obj(result);
|
||||
printf("\n");
|
||||
|
||||
|
||||
38
src/parse.c
38
src/parse.c
@@ -1,5 +1,6 @@
|
||||
#include "uclisp.h"
|
||||
#include "internal.h"
|
||||
#include "utility.h"
|
||||
|
||||
// TODO: remove these
|
||||
#include <stdbool.h>
|
||||
@@ -20,6 +21,8 @@ static const char *reserved_symbols[] = {
|
||||
};
|
||||
|
||||
// TODO: remove malloc and strndup calls
|
||||
// TODO: refresh this with newer 'object' code
|
||||
// TODO: Syntatic sugar for quote
|
||||
|
||||
static bool ucl_is_whitespace(char c) {
|
||||
return c == ' ' || c == '\n' || c == '\t';
|
||||
@@ -68,6 +71,7 @@ struct ucl_object *ucl_token_next(const char **curr_src) {
|
||||
str = strndup(start + 1, *curr_src - start - 2);
|
||||
return ucl_cell_create(ucl_string_create(str), NULL);
|
||||
case '0'...'9': {
|
||||
// TODO: Add support for negative integers
|
||||
char *end = NULL;
|
||||
long value = strtol(*curr_src, &end, 0);
|
||||
*curr_src = end;
|
||||
@@ -141,6 +145,9 @@ static struct ucl_object *ucl_parse_tokens_recursive(struct ucl_object **token_i
|
||||
assert((*token_iter)->type == UCL_TYPE_CELL);
|
||||
|
||||
struct ucl_object *token = (*token_iter)->cell.car;
|
||||
if (token == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
struct ucl_object *next_sexp = ucl_parse_token_atom(token);
|
||||
if (next_sexp != NULL) {
|
||||
*token_iter = (*token_iter)->cell.cdr;
|
||||
@@ -154,7 +161,13 @@ static struct ucl_object *ucl_parse_tokens_recursive(struct ucl_object **token_i
|
||||
// Consume the START_LIST_CHAR
|
||||
*token_iter = (*token_iter)->cell.cdr;
|
||||
while (1) {
|
||||
if (*token_iter == NULL) {
|
||||
// Unexpected end of parsing
|
||||
return ucl_error_create("Unmatched open parenthesis");
|
||||
}
|
||||
|
||||
token = (*token_iter)->cell.car;
|
||||
|
||||
if (token->type == UCL_TYPE_SYMBOL && token->symbol[0] == END_LIST_CHAR) {
|
||||
*token_iter = (*token_iter)->cell.cdr;
|
||||
if (list == NULL) {
|
||||
@@ -164,6 +177,7 @@ static struct ucl_object *ucl_parse_tokens_recursive(struct ucl_object **token_i
|
||||
}
|
||||
|
||||
next_sexp = ucl_parse_tokens_recursive(token_iter);
|
||||
UCL_RET_IF_ERROR(next_sexp);
|
||||
if (next_sexp == NULL) {
|
||||
// Error somewhere in the recursive parsing
|
||||
ucl_object_delete(list);
|
||||
@@ -174,12 +188,11 @@ static struct ucl_object *ucl_parse_tokens_recursive(struct ucl_object **token_i
|
||||
next_node = &(*next_node)->cell.cdr;
|
||||
}
|
||||
} else if (token->symbol[0] == END_LIST_CHAR) {
|
||||
// Mismatched parens
|
||||
return NULL;
|
||||
return ucl_error_create("Unmatched closed parenthesis");
|
||||
}
|
||||
// Any other symbol type should have been an atom, this shouldn't happen
|
||||
assert(false);
|
||||
return NULL;
|
||||
return ucl_error_create("Unreachable parse error");
|
||||
}
|
||||
|
||||
// parse_tokens -> doesn't care about quotes, terminates on EOF
|
||||
@@ -192,8 +205,8 @@ struct ucl_object *ucl_parse_tokens(struct ucl_object *tokens) {
|
||||
|
||||
while (*token_iter != NULL) {
|
||||
struct ucl_object *new_sexp = ucl_parse_tokens_recursive(token_iter);
|
||||
if (new_sexp == NULL) {
|
||||
goto error;
|
||||
if (new_sexp == NULL || new_sexp->type == UCL_TYPE_ERROR) {
|
||||
return new_sexp;
|
||||
}
|
||||
|
||||
*next_cell = ucl_cell_create(new_sexp, NULL);
|
||||
@@ -206,7 +219,6 @@ struct ucl_object *ucl_parse_tokens(struct ucl_object *tokens) {
|
||||
|
||||
return resultl;
|
||||
error:
|
||||
ucl_object_delete(resultl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -214,13 +226,13 @@ struct ucl_object *ucl_parse_tokens(struct ucl_object *tokens) {
|
||||
// all sexps in the source (return a list of sexps)?
|
||||
struct ucl_object *ucl_parse(const char *source) {
|
||||
struct ucl_object *tokens = ucl_tokenize(source);
|
||||
if (tokens == NULL) {
|
||||
tokens = ucl_nil_create();
|
||||
}
|
||||
UCL_RET_IF_ERROR(tokens);
|
||||
struct ucl_object *sexp = ucl_parse_tokens(tokens);
|
||||
ucl_object_delete(tokens);
|
||||
if (sexp == NULL) {
|
||||
return ucl_nil_create();
|
||||
}
|
||||
return sexp;
|
||||
}
|
||||
|
||||
/* struct ParseResult *ucl_parse(const char *source) { */
|
||||
/* struct Cell *tokens = ucl_tokenize(source); */
|
||||
/* struct Cell *sexp = n */
|
||||
|
||||
/* } */
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// TODO: Macro support?
|
||||
|
||||
struct ucl_object *ucl_special_let(struct ucl_scope *scope, struct ucl_object *args) {
|
||||
// TODO: Check arguments
|
||||
struct ucl_object *assignments = ucl_car(args);
|
||||
|
||||
Reference in New Issue
Block a user