110 lines
2.5 KiB
C
110 lines
2.5 KiB
C
#ifndef APFL_VALUE_H
|
|
#define APFL_VALUE_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
|
|
#include "apfl.h"
|
|
|
|
#include "gc.h"
|
|
|
|
#include "hashmap.h"
|
|
|
|
enum value_type {
|
|
VALUE_NIL,
|
|
VALUE_BOOLEAN,
|
|
VALUE_NUMBER,
|
|
VALUE_STRING,
|
|
VALUE_CONST_STRING,
|
|
VALUE_LIST,
|
|
VALUE_DICT,
|
|
// TODO: functions/closures
|
|
};
|
|
|
|
struct list_header {
|
|
struct apfl_value *items;
|
|
size_t len;
|
|
size_t cap;
|
|
bool copy_on_write;
|
|
};
|
|
|
|
struct dict_header {
|
|
struct apfl_hashmap map;
|
|
bool copy_on_write;
|
|
};
|
|
|
|
typedef struct dict_header *apfl_dict;
|
|
|
|
struct apfl_value {
|
|
enum value_type type;
|
|
union {
|
|
bool boolean;
|
|
apfl_number number;
|
|
struct apfl_string *string;
|
|
struct apfl_string_view const_string;
|
|
struct list_header *list;
|
|
struct dict_header *dict;
|
|
};
|
|
};
|
|
|
|
enum apfl_value_type apfl_value_type_to_abstract_type(enum value_type);
|
|
|
|
#define VALUE_IS_A(v, t) (apfl_value_type_to_abstract_type((v).type) == (t))
|
|
|
|
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_print(struct apfl_value, struct apfl_format_writer);
|
|
apfl_hash apfl_value_hash(const struct apfl_value);
|
|
|
|
enum get_item_result {
|
|
GET_ITEM_OK,
|
|
GET_ITEM_KEY_DOESNT_EXIST,
|
|
GET_ITEM_NOT_A_CONTAINER,
|
|
GET_ITEM_WRONG_KEY_TYPE,
|
|
};
|
|
|
|
enum get_item_result apfl_value_get_item(struct apfl_value container, struct apfl_value key, struct apfl_value *out);
|
|
|
|
// Set the Copy On Write flag of a value (if it's a value with such a flag).
|
|
// Returns the same value again.
|
|
struct apfl_value apfl_value_set_cow_flag(struct apfl_value);
|
|
|
|
struct list_header *apfl_list_new(struct gc *, size_t initial_cap);
|
|
|
|
size_t apfl_list_len(struct list_header *);
|
|
void apfl_list_deinit(struct apfl_allocator, struct list_header *);
|
|
|
|
bool
|
|
apfl_list_splice(
|
|
struct gc *gc,
|
|
struct list_header **dst_ptr,
|
|
size_t cut_start,
|
|
size_t cut_len,
|
|
const struct apfl_value *other,
|
|
size_t other_len
|
|
);
|
|
|
|
struct dict_header *apfl_dict_new(struct gc *);
|
|
bool apfl_dict_set_raw(
|
|
struct gc *gc,
|
|
struct dict_header **_dict,
|
|
struct apfl_value k,
|
|
struct apfl_value v
|
|
);
|
|
void apfl_dict_deinit(struct dict_header *);
|
|
|
|
// Functions for garbage collection
|
|
struct gc_object *apfl_value_get_gc_object(struct apfl_value);
|
|
void apfl_gc_list_traverse(struct list_header *, gc_visitor, void *);
|
|
void apfl_gc_dict_traverse(struct dict_header *, gc_visitor, void *);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|