Use pinned, immutable errors
This allows for extra refactoring to reduce the reliance on 'struct ucl' for allocation strictly for allocating error responses.
This commit is contained in:
@@ -72,8 +72,8 @@ LISP_FUNC_1(ucl_builtin_cdr, state, scope, arg) {
|
||||
}
|
||||
|
||||
LISP_FUNC_2(ucl_builtin_nth, state, scope, n, list) {
|
||||
UCL_COND_OR_RET_ERROR(state, n->type == UCL_TYPE_INT, "First argument to nth must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(state, list->type == UCL_TYPE_CELL, "Second argument to nth must be a list");
|
||||
UCL_COND_OR_RET_ERROR(n->type == UCL_TYPE_INT, "First argument to nth must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(list->type == UCL_TYPE_CELL, "Second argument to nth must be a list");
|
||||
|
||||
return ucl_list_nth(state, list, n->integer);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ LISP_FUNC_2(ucl_builtin_div, state, scope, arg0, arg1) {
|
||||
return ucl_error_create(state, "Invalid type of argument 1 to 'div'");
|
||||
}
|
||||
|
||||
UCL_COND_OR_RET_ERROR(state, arg1->integer != 0, "Division by zero");
|
||||
UCL_COND_OR_RET_ERROR(arg1->integer != 0, "Division by zero");
|
||||
return ucl_int_create(state, arg0->integer / arg1->integer);
|
||||
}
|
||||
|
||||
@@ -230,32 +230,32 @@ LISP_FUNC_2(ucl_builtin_equal, state, scope, arg0, arg1) {
|
||||
}
|
||||
|
||||
LISP_FUNC_2(ucl_builtin_gt, state, scope, arg0, arg1) {
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "First argument to > must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "Second argument to > must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to > must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to > must be an integer");
|
||||
return ucl_predicate(state, arg0->integer > arg1->integer);
|
||||
}
|
||||
|
||||
LISP_FUNC_2(ucl_builtin_ge, state, scope, arg0, arg1) {
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "First argument to >= must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "Second argument to >= must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to >= must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to >= must be an integer");
|
||||
return ucl_predicate(state, arg0->integer > arg1->integer);
|
||||
}
|
||||
|
||||
LISP_FUNC_2(ucl_builtin_lt, state, scope, arg0, arg1) {
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "First argument to < must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "Second argument to < must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to < must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to < must be an integer");
|
||||
return ucl_predicate(state, arg0->integer < arg1->integer);
|
||||
}
|
||||
|
||||
LISP_FUNC_2(ucl_builtin_le, state, scope, arg0, arg1) {
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "First argument to <= must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "Second argument to <= must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to <= must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to <= must be an integer");
|
||||
return ucl_predicate(state, arg0->integer < arg1->integer);
|
||||
}
|
||||
|
||||
LISP_FUNC_2(ucl_builtin_num_eq, state, scope, arg0, arg1) {
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "First argument to = must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(state, arg0->type == UCL_TYPE_INT, "Second argument to = must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to = must be an integer");
|
||||
UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to = must be an integer");
|
||||
return ucl_predicate(state, arg0->integer == arg1->integer);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,15 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define UCL_COND_OR_RET_ERROR(ucl, cond, msg) \
|
||||
#define UCL_COND_OR_RET_ERROR(cond, msg) \
|
||||
do { \
|
||||
static struct ucl_object err = { \
|
||||
.type = UCL_TYPE_ERROR, \
|
||||
.error = (msg), \
|
||||
.flags = UCL_OBJ_FLAG_PINNED \
|
||||
}; \
|
||||
if (!(cond)) { \
|
||||
return ucl_error_create(ucl, msg); \
|
||||
return &err; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ static struct ucl_object* ucl_object_alloc(struct ucl* ucl) {
|
||||
}
|
||||
|
||||
static void ucl_object_delete_internal(struct ucl_arena* obj_arena, struct ucl_object *obj) {
|
||||
if (obj == NULL) {
|
||||
if (obj == NULL || obj->flags & UCL_OBJ_FLAG_PINNED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +92,8 @@ struct ucl_object *ucl_special_dotimes(struct ucl *state, struct ucl_scope *scop
|
||||
struct ucl_object *var = ucl_car(state, assignment);
|
||||
struct ucl_object *times = ucl_evaluate_in_scope(state, scope, ucl_list_nth(state, assignment, 1));
|
||||
|
||||
UCL_COND_OR_RET_ERROR(state, var->type == UCL_TYPE_SYMBOL, "'var' argument to dotimes must be an symbol");
|
||||
UCL_COND_OR_RET_ERROR(state, times->type == UCL_TYPE_INT, "'times' argument to dotimes must be an int");
|
||||
UCL_COND_OR_RET_ERROR(var->type == UCL_TYPE_SYMBOL, "'var' argument to dotimes must be an symbol");
|
||||
UCL_COND_OR_RET_ERROR(times->type == UCL_TYPE_INT, "'times' argument to dotimes must be an int");
|
||||
|
||||
struct ucl_scope *let_scope = ucl_scope_create_child(state, scope);
|
||||
|
||||
@@ -114,8 +114,8 @@ struct ucl_object *ucl_special_dolist(struct ucl *state, struct ucl_scope *scope
|
||||
struct ucl_object *var = ucl_car(state, assignment);
|
||||
struct ucl_object *list = ucl_evaluate_in_scope(state, scope, ucl_list_nth(state, assignment, 1));
|
||||
|
||||
UCL_COND_OR_RET_ERROR(state, var->type == UCL_TYPE_SYMBOL, "'var' argument to dolist must be an symbol");
|
||||
UCL_COND_OR_RET_ERROR(state, list->type == UCL_TYPE_CELL, "'list' argument to dolist must be a list");
|
||||
UCL_COND_OR_RET_ERROR(var->type == UCL_TYPE_SYMBOL, "'var' argument to dolist must be an symbol");
|
||||
UCL_COND_OR_RET_ERROR(list->type == UCL_TYPE_CELL, "'list' argument to dolist must be a list");
|
||||
|
||||
struct ucl_scope *let_scope = ucl_scope_create_child(state, scope);
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
struct ucl_object *ucl_car(struct ucl *state, struct ucl_object *list) {
|
||||
UCL_COND_OR_RET_ERROR(
|
||||
state,
|
||||
list != NULL && list->type == UCL_TYPE_CELL,
|
||||
"Invalid type of argument 0 to 'ucl_car'");
|
||||
|
||||
@@ -24,7 +23,7 @@ struct ucl_object *ucl_car(struct ucl *state, struct ucl_object *list) {
|
||||
}
|
||||
|
||||
struct ucl_object *ucl_cdr(struct ucl* state, struct ucl_object *list) {
|
||||
UCL_COND_OR_RET_ERROR(state,
|
||||
UCL_COND_OR_RET_ERROR(
|
||||
list != NULL && list->type == UCL_TYPE_CELL,
|
||||
"Invalid type of argument 0 to 'ucl_cdr'");
|
||||
|
||||
@@ -54,7 +53,6 @@ struct ucl_object *ucl_predicate(struct ucl* state, bool value) {
|
||||
|
||||
struct ucl_object *ucl_list_length(struct ucl *state, struct ucl_object *list) {
|
||||
UCL_COND_OR_RET_ERROR(
|
||||
state,
|
||||
list != NULL && list->type == UCL_TYPE_CELL,
|
||||
"Invalid type of argument 0 to 'ucl_list_length'");
|
||||
|
||||
@@ -74,13 +72,12 @@ struct ucl_object *ucl_list_length(struct ucl *state, struct ucl_object *list) {
|
||||
|
||||
struct ucl_object *ucl_list_nth(struct ucl *state, struct ucl_object *list, int n) {
|
||||
UCL_COND_OR_RET_ERROR(
|
||||
state,
|
||||
list != NULL && list->type == UCL_TYPE_CELL,
|
||||
"Invalid type of argument 0 to 'ucl_list_nth'");
|
||||
|
||||
int length = ucl_list_length(state, list)->integer;
|
||||
UCL_COND_OR_RET_ERROR(state, length > n, "Position n >= list length in ucl_list_nth");
|
||||
UCL_COND_OR_RET_ERROR(state, n >= 0, "Index to ucl_list_nth was less that zero");
|
||||
UCL_COND_OR_RET_ERROR(length > n, "Position n >= list length in ucl_list_nth");
|
||||
UCL_COND_OR_RET_ERROR(n >= 0, "Index to ucl_list_nth was less that zero");
|
||||
|
||||
struct ucl_object *node = list;
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
||||
Reference in New Issue
Block a user