eval.c: Handle errors during evaluating string constants
This commit is contained in:
parent
b29219af25
commit
4cd95d32c5
1 changed files with 38 additions and 21 deletions
59
src/eval.c
59
src/eval.c
|
|
@ -27,33 +27,53 @@ apfl_ctx_destroy(apfl_ctx ctx)
|
|||
free(ctx);
|
||||
}
|
||||
|
||||
static struct apfl_value
|
||||
static struct apfl_result
|
||||
fatal(void)
|
||||
{
|
||||
return (struct apfl_result) { .type = APFL_RESULT_ERR_FATAL };
|
||||
}
|
||||
|
||||
static struct apfl_result
|
||||
evaluate_constant(struct apfl_expr_const *constant)
|
||||
{
|
||||
struct apfl_refcounted_string *rcstring;
|
||||
|
||||
switch (constant->type) {
|
||||
case APFL_EXPR_CONST_NIL:
|
||||
return (struct apfl_value) {
|
||||
.type = APFL_VALUE_NIL,
|
||||
return (struct apfl_result) {
|
||||
.type = APFL_RESULT_OK,
|
||||
.value = {
|
||||
.type = APFL_VALUE_NIL,
|
||||
},
|
||||
};
|
||||
case APFL_EXPR_CONST_BOOLEAN:
|
||||
return (struct apfl_value) {
|
||||
.type = APFL_VALUE_BOOLEAN,
|
||||
.boolean = constant->boolean,
|
||||
return (struct apfl_result) {
|
||||
.type = APFL_RESULT_OK,
|
||||
.value = {
|
||||
.type = APFL_VALUE_BOOLEAN,
|
||||
.boolean = constant->boolean,
|
||||
},
|
||||
};
|
||||
case APFL_EXPR_CONST_STRING:
|
||||
rcstring = apfl_string_move_into_new_refcounted(&constant->string);
|
||||
assert(rcstring != NULL); // TODO: This can fail!
|
||||
if (rcstring == NULL) {
|
||||
return fatal();
|
||||
}
|
||||
|
||||
return (struct apfl_value) {
|
||||
.type = APFL_VALUE_STRING,
|
||||
.string = rcstring,
|
||||
return (struct apfl_result) {
|
||||
.type = APFL_RESULT_OK,
|
||||
.value = {
|
||||
.type = APFL_VALUE_STRING,
|
||||
.string = rcstring,
|
||||
},
|
||||
};
|
||||
case APFL_EXPR_CONST_NUMBER:
|
||||
return (struct apfl_value) {
|
||||
.type = APFL_VALUE_NUMBER,
|
||||
.number = constant->number,
|
||||
return (struct apfl_result) {
|
||||
.type = APFL_RESULT_OK,
|
||||
.value = {
|
||||
.type = APFL_VALUE_NUMBER,
|
||||
.number = constant->number,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -83,13 +103,13 @@ evaluate_list_expr_to_list(apfl_ctx ctx, struct apfl_expr *expr, struct apfl_lis
|
|||
list->len
|
||||
)) {
|
||||
apfl_value_deinit(&result.value);
|
||||
return (struct apfl_result) { .type = APFL_RESULT_ERR_FATAL };
|
||||
return fatal();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < list->len; i++) {
|
||||
if (!apfl_value_copy(&out->items[out->len], list->items[i])) {
|
||||
apfl_value_deinit(&result.value);
|
||||
return (struct apfl_result) { .type = APFL_RESULT_ERR_FATAL };
|
||||
return fatal();
|
||||
}
|
||||
out->len++;
|
||||
}
|
||||
|
|
@ -124,7 +144,7 @@ evaluate_expr_list_into_list(apfl_ctx ctx, struct apfl_expr_list *list, struct a
|
|||
1
|
||||
)) {
|
||||
apfl_value_deinit(&result.value);
|
||||
return (struct apfl_result) { .type = APFL_RESULT_ERR_FATAL };
|
||||
return fatal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +157,7 @@ evaluate_list(apfl_ctx ctx, struct apfl_expr_list *list)
|
|||
{
|
||||
struct apfl_list *out = apfl_list_new();
|
||||
if (out == NULL) {
|
||||
return (struct apfl_result) { .type = APFL_RESULT_ERR_FATAL };
|
||||
return fatal();
|
||||
}
|
||||
|
||||
struct apfl_result result = evaluate_expr_list_into_list(ctx, list, out);
|
||||
|
|
@ -161,10 +181,7 @@ evaluate(apfl_ctx ctx, struct apfl_expr *expr)
|
|||
(void)ctx;
|
||||
switch (expr->type) {
|
||||
case APFL_EXPR_CONSTANT:
|
||||
return (struct apfl_result) {
|
||||
.type = APFL_RESULT_OK,
|
||||
.value = evaluate_constant(&expr->constant),
|
||||
};
|
||||
return evaluate_constant(&expr->constant);
|
||||
case APFL_EXPR_LIST:
|
||||
return evaluate_list(ctx, &expr->list);
|
||||
case APFL_EXPR_VAR:
|
||||
|
|
|
|||
Loading…
Reference in a new issue