Add constant string values

This commit is contained in:
Laria 2022-04-23 22:14:42 +02:00
parent 0de243995b
commit bb89b2ae49
4 changed files with 39 additions and 12 deletions

View file

@ -609,6 +609,8 @@ enum apfl_result apfl_push_bool(apfl_ctx, bool);
enum apfl_result apfl_push_number(apfl_ctx, apfl_number);
// Push a string onto the stack
enum apfl_result apfl_push_string_view_copy(apfl_ctx, struct apfl_string_view);
// Push a constant string.
enum apfl_result apfl_push_const_string(apfl_ctx, const char *);
// Create a new empty list on the stack
enum apfl_result apfl_list_create(apfl_ctx, size_t initial_capacity);
// Append a value to a list. The value will be dropped.

View file

@ -295,6 +295,15 @@ apfl_push_string_view_copy(apfl_ctx ctx, struct apfl_string_view sv)
)
}
enum apfl_result
apfl_push_const_string(apfl_ctx ctx, const char *string)
{
return apfl_stack_push(ctx, (struct apfl_value) {
.type = VALUE_CONST_STRING,
.const_string = apfl_string_view_from(string),
}) ? APFL_RESULT_OK : APFL_RESULT_ERR_FATAL;
}
enum apfl_result
apfl_list_create(apfl_ctx ctx, size_t initial_cap)
{

View file

@ -75,6 +75,19 @@ apfl_dict_deinit(struct dict_header *header)
apfl_hashmap_deinit(&header->map);
}
static struct apfl_string_view
as_string_view(struct apfl_value value)
{
switch (value.type) {
case VALUE_STRING:
return apfl_string_view_from(*value.string);
case VALUE_CONST_STRING:
return value.const_string;
default:
return (struct apfl_string_view) { .bytes = NULL, .len = 0 };
}
}
static bool
format(unsigned indent, struct apfl_format_writer w, struct apfl_value value, bool skip_first_indent)
{
@ -91,8 +104,9 @@ format(unsigned indent, struct apfl_format_writer w, struct apfl_value value, bo
TRY(apfl_format_put_number(w, value.number));
return true;
case VALUE_STRING:
case VALUE_CONST_STRING:
TRY(apfl_format_put_string(w, "\""));
TRY(apfl_format_put_string(w, *value.string));
TRY(apfl_format_put_string(w, as_string_view(value)));
TRY(apfl_format_put_string(w, "\""));
return true;
case VALUE_LIST:
@ -205,23 +219,21 @@ dict_eq(const apfl_dict a, const apfl_dict b)
bool
apfl_value_eq(const struct apfl_value a, const struct apfl_value b)
{
if (a.type != b.type) {
return false;
}
switch (a.type) {
case VALUE_NIL:
return true;
return b.type == VALUE_NIL && true;
case VALUE_BOOLEAN:
return a.boolean == b.boolean;
return b.type == VALUE_BOOLEAN && a.boolean == b.boolean;
case VALUE_NUMBER:
return a.number == b.number;
return b.type == VALUE_NUMBER && a.number == b.number;
case VALUE_STRING:
return a.string == b.string || apfl_string_eq(*a.string, *b.string);
case VALUE_CONST_STRING:
return (b.type == VALUE_STRING || b.type == VALUE_CONST_STRING)
&& apfl_string_eq(as_string_view(a), as_string_view(b));
case VALUE_LIST:
return list_eq(a.list, b.list);
return b.type == VALUE_LIST && list_eq(a.list, b.list);
case VALUE_DICT:
return dict_eq(a.dict, b.dict);
return b.type == VALUE_DICT && dict_eq(a.dict, b.dict);
}
assert(false);
@ -463,7 +475,8 @@ apfl_value_hash(const struct apfl_value value)
case VALUE_NUMBER:
return apfl_hash_fnv1a_add(&value.number, sizeof(apfl_number), hash);
case VALUE_STRING:
sv = apfl_string_view_from(*value.string);
case VALUE_CONST_STRING:
sv = as_string_view(value);
return apfl_hash_fnv1a_add(sv.bytes, sv.len, hash);
case VALUE_LIST:
for (size_t i = 0; i < value.list->len; i++) {
@ -490,6 +503,7 @@ apfl_value_get_gc_object(struct apfl_value value)
case VALUE_NIL:
case VALUE_BOOLEAN:
case VALUE_NUMBER:
case VALUE_CONST_STRING:
return NULL;
case VALUE_STRING:
return GC_OBJECT_FROM(value.string, GC_TYPE_STRING);

View file

@ -20,6 +20,7 @@ enum value_type {
VALUE_BOOLEAN,
VALUE_NUMBER,
VALUE_STRING,
VALUE_CONST_STRING,
VALUE_LIST,
VALUE_DICT,
// TODO: functions/closures
@ -45,6 +46,7 @@ struct apfl_value {
bool boolean;
apfl_number number;
struct apfl_string *string;
struct apfl_string_view const_string;
struct list_header *list;
struct dict_header *dict;
};