Implement tostring and use it in print
This commit is contained in:
parent
4ecfeabded
commit
363334967a
5 changed files with 62 additions and 1 deletions
|
|
@ -655,6 +655,8 @@ enum apfl_value_type apfl_get_type(apfl_ctx, apfl_stackidx);
|
|||
|
||||
// Drop a value from the stack
|
||||
void apfl_drop(apfl_ctx, apfl_stackidx);
|
||||
// Move a value to the top of the stack
|
||||
void apfl_move_to_top_of_stack(apfl_ctx, apfl_stackidx);
|
||||
// Push a nil onto the stack
|
||||
void apfl_push_nil(apfl_ctx);
|
||||
// Push a boolean onto the stack
|
||||
|
|
@ -684,6 +686,8 @@ size_t apfl_len(apfl_ctx, apfl_stackidx);
|
|||
// Get a string view into a APFL_VALUE_STRING value. The value stays on the stack.
|
||||
// The returned string view is only guaranteed to be valid, as long as the value is on the stack.
|
||||
struct apfl_string_view apfl_get_string(apfl_ctx, apfl_stackidx);
|
||||
// Pops a value off the stack and turns it into a string.
|
||||
void apfl_tostring(apfl_ctx, apfl_stackidx);
|
||||
// Pops a value from the stack and returns whether is was truthy. All values except false and nil are truthy.
|
||||
bool apfl_is_truthy(apfl_ctx, apfl_stackidx);
|
||||
// Pops a number from the stack and returns it.
|
||||
|
|
|
|||
|
|
@ -419,6 +419,14 @@ current_stack_move_to_top(apfl_ctx ctx, apfl_stackidx index)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
apfl_move_to_top_of_stack(apfl_ctx ctx, apfl_stackidx index)
|
||||
{
|
||||
if (!current_stack_move_to_top(ctx, index)) {
|
||||
apfl_raise_invalid_stackidx(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
apfl_stack_clear(apfl_ctx ctx)
|
||||
{
|
||||
|
|
@ -1102,6 +1110,33 @@ apfl_get_type(apfl_ctx ctx, apfl_stackidx index)
|
|||
return apfl_value_type_to_abstract_type(value.type);
|
||||
}
|
||||
|
||||
void
|
||||
apfl_tostring(apfl_ctx ctx, apfl_stackidx index)
|
||||
{
|
||||
apfl_move_to_top_of_stack(ctx, index);
|
||||
struct apfl_value value = apfl_stack_must_get(ctx, -1);
|
||||
if (apfl_value_type_to_abstract_type(value.type) == APFL_VALUE_STRING) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct apfl_string_builder sb = apfl_string_builder_init(ctx->gc.allocator);
|
||||
if (!apfl_value_format(value, apfl_format_string_writer(&sb))) {
|
||||
apfl_string_builder_deinit(&sb);
|
||||
apfl_stack_drop(ctx, -1);
|
||||
apfl_raise_alloc_error(ctx);
|
||||
}
|
||||
|
||||
struct apfl_string str = apfl_string_builder_move_string(&sb);
|
||||
apfl_string_builder_deinit(&sb);
|
||||
if (!apfl_move_string_onto_stack(ctx, str)) {
|
||||
apfl_string_deinit(ctx->gc.allocator, &str);
|
||||
apfl_stack_drop(ctx, -1);
|
||||
apfl_raise_alloc_error(ctx);
|
||||
}
|
||||
|
||||
apfl_stack_drop(ctx, -2); // Drop original value
|
||||
}
|
||||
|
||||
bool
|
||||
apfl_is_truthy(apfl_ctx ctx, apfl_stackidx index)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ print(apfl_ctx ctx)
|
|||
}
|
||||
|
||||
apfl_get_list_member_by_index(ctx, 0, i);
|
||||
apfl_tostring(ctx, -1);
|
||||
struct apfl_string_view sv = apfl_get_string(ctx, -1);
|
||||
TRY_FORMAT(ctx, apfl_format_put_string(w, sv));
|
||||
apfl_drop(ctx, -1);
|
||||
|
|
@ -204,6 +205,19 @@ disasm(apfl_ctx ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tostring(apfl_ctx ctx)
|
||||
{
|
||||
size_t len = apfl_len(ctx, 0);
|
||||
if (len != 1) {
|
||||
apfl_raise_const_error(ctx, APFL_RESULT_ERR, "tostring needs exactly 1 argument");
|
||||
}
|
||||
|
||||
apfl_get_list_member_by_index(ctx, 0, 0);
|
||||
apfl_drop(ctx, 0);
|
||||
apfl_tostring(ctx, -1);
|
||||
}
|
||||
|
||||
static const struct global_def globals[] = {
|
||||
{"if", impl_if},
|
||||
{"==", impl_eq},
|
||||
|
|
@ -214,6 +228,7 @@ static const struct global_def globals[] = {
|
|||
{"print", print},
|
||||
{"dump", dump},
|
||||
{"disasm", disasm},
|
||||
{"tostring", tostring},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -274,10 +274,16 @@ apfl_value_move(struct apfl_value *src)
|
|||
return out;
|
||||
}
|
||||
|
||||
bool
|
||||
apfl_value_format(struct apfl_value value, struct apfl_format_writer w)
|
||||
{
|
||||
return format(0, w, value, false);
|
||||
}
|
||||
|
||||
bool
|
||||
apfl_value_print(struct apfl_value value, struct apfl_format_writer w)
|
||||
{
|
||||
TRY(format(0, w, value, false));
|
||||
TRY(apfl_value_format(value, w));
|
||||
TRY(apfl_format_put_string(w, "\n"));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ enum apfl_value_type apfl_value_type_to_abstract_type(enum value_type);
|
|||
|
||||
bool apfl_value_eq(const struct apfl_value, const struct apfl_value);
|
||||
struct apfl_value apfl_value_move(struct apfl_value *src);
|
||||
bool apfl_value_format(struct apfl_value, struct apfl_format_writer);
|
||||
bool apfl_value_print(struct apfl_value, struct apfl_format_writer);
|
||||
apfl_hash apfl_value_hash(const struct apfl_value);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue