2021-12-10 20:22:16 +00:00
|
|
|
#ifndef APFL_H
|
|
|
|
|
#define APFL_H
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
typedef double apfl_number;
|
|
|
|
|
|
|
|
|
|
struct apfl_position {
|
|
|
|
|
int line;
|
|
|
|
|
int col;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool apfl_position_eq(struct apfl_position, struct apfl_position);
|
|
|
|
|
|
|
|
|
|
// Strings
|
|
|
|
|
|
|
|
|
|
struct apfl_string_view {
|
|
|
|
|
const char *bytes;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_string {
|
|
|
|
|
char *bytes;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-04 20:22:46 +00:00
|
|
|
struct apfl_refcounted_string_data;
|
|
|
|
|
|
|
|
|
|
typedef struct apfl_refcounted_string_data *apfl_refcounted_string;
|
2022-01-02 16:55:05 +00:00
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
#define APFL_STR_FMT "%.*s"
|
|
|
|
|
#define APFL_STR_FMT_ARGS(s) (int)(s).len,(s).bytes
|
|
|
|
|
|
|
|
|
|
struct apfl_string_view apfl_string_view_from_view(struct apfl_string_view);
|
|
|
|
|
struct apfl_string_view apfl_string_view_from_cstr(char *);
|
|
|
|
|
struct apfl_string_view apfl_string_view_from_const_cstr(const char *);
|
|
|
|
|
struct apfl_string_view apfl_string_view_from_string(struct apfl_string);
|
2022-01-04 20:22:46 +00:00
|
|
|
struct apfl_string_view apfl_string_view_from_refcounted_string(apfl_refcounted_string);
|
|
|
|
|
|
|
|
|
|
#define apfl_string_view_from(s) _Generic((s), \
|
|
|
|
|
struct apfl_string: apfl_string_view_from_string, \
|
|
|
|
|
struct apfl_string_view: apfl_string_view_from_view, \
|
|
|
|
|
apfl_refcounted_string: apfl_string_view_from_refcounted_string, \
|
|
|
|
|
char *: apfl_string_view_from_cstr, \
|
|
|
|
|
const char *: apfl_string_view_from_const_cstr \
|
2021-12-10 20:22:16 +00:00
|
|
|
)(s)
|
|
|
|
|
|
|
|
|
|
int apfl_string_view_cmp(struct apfl_string_view, struct apfl_string_view);
|
|
|
|
|
|
|
|
|
|
#define apfl_string_cmp(a, b) apfl_string_view_cmp(apfl_string_view_from(a), apfl_string_view_from(b))
|
2022-01-02 15:51:19 +00:00
|
|
|
#define apfl_string_eq(a, b) (apfl_string_cmp((a), (b)) == 0)
|
2021-12-10 20:22:16 +00:00
|
|
|
|
2022-01-02 16:01:51 +00:00
|
|
|
struct apfl_string apfl_string_blank(void);
|
2021-12-10 20:22:16 +00:00
|
|
|
void apfl_string_deinit(struct apfl_string *);
|
|
|
|
|
struct apfl_string apfl_string_move(struct apfl_string *src);
|
|
|
|
|
|
2022-01-02 16:01:51 +00:00
|
|
|
/**
|
|
|
|
|
* Copies a string from src to dst. dst must point to a blank string.
|
|
|
|
|
* Returns true on success, false otherwise (if the necessary memory could not
|
|
|
|
|
* be allocated).
|
|
|
|
|
*/
|
|
|
|
|
bool apfl_string_copy(struct apfl_string *dst, struct apfl_string_view src);
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_string_builder {
|
|
|
|
|
char *bytes;
|
|
|
|
|
size_t len;
|
|
|
|
|
size_t cap;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void apfl_string_builder_init(struct apfl_string_builder *);
|
|
|
|
|
void apfl_string_builder_deinit(struct apfl_string_builder *);
|
|
|
|
|
bool apfl_string_builder_append(struct apfl_string_builder *, struct apfl_string_view);
|
|
|
|
|
bool apfl_string_builder_append_byte(struct apfl_string_builder *, char byte);
|
|
|
|
|
struct apfl_string apfl_string_builder_move_string(struct apfl_string_builder *);
|
|
|
|
|
|
|
|
|
|
#define apfl_string_builder_append_cstr(builder, cstr) (apfl_string_builder_append((builder), apfl_string_view_from_cstr((cstr))))
|
|
|
|
|
|
2022-01-14 22:16:19 +00:00
|
|
|
apfl_refcounted_string apfl_string_copy_into_new_refcounted(struct apfl_string_view);
|
|
|
|
|
|
2022-01-04 20:22:46 +00:00
|
|
|
apfl_refcounted_string apfl_string_move_into_new_refcounted(struct apfl_string *);
|
|
|
|
|
|
|
|
|
|
/* Increases the reference of the refcounted string.
|
|
|
|
|
* Returns the same apfl_refcounted_string value.
|
|
|
|
|
*/
|
|
|
|
|
apfl_refcounted_string apfl_refcounted_string_incref(apfl_refcounted_string);
|
2022-01-02 16:55:05 +00:00
|
|
|
|
|
|
|
|
/* Unrefs the refcounted string. It is no longer allowed to use the pointer
|
|
|
|
|
* after calling this function with it!
|
|
|
|
|
*/
|
2022-01-04 20:22:46 +00:00
|
|
|
void apfl_refcounted_string_unref(apfl_refcounted_string );
|
2022-01-02 16:55:05 +00:00
|
|
|
|
2022-01-18 20:18:27 +00:00
|
|
|
/* Like apfl_refcounted_string_unref, but accepts a pointer to a refcounted_string.
|
|
|
|
|
* The pointed to value will be set to NULL.
|
|
|
|
|
*/
|
|
|
|
|
void apfl_refcounted_string_unref_ptr(apfl_refcounted_string *);
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
// Tokens
|
|
|
|
|
|
|
|
|
|
enum apfl_token_type {
|
|
|
|
|
APFL_TOK_LPAREN,
|
|
|
|
|
APFL_TOK_RPAREN,
|
|
|
|
|
APFL_TOK_LBRACKET,
|
|
|
|
|
APFL_TOK_RBRACKET,
|
|
|
|
|
APFL_TOK_LBRACE,
|
|
|
|
|
APFL_TOK_RBRACE,
|
|
|
|
|
APFL_TOK_MAPSTO,
|
|
|
|
|
APFL_TOK_EXPAND,
|
|
|
|
|
APFL_TOK_DOT,
|
|
|
|
|
APFL_TOK_AT,
|
|
|
|
|
APFL_TOK_SEMICOLON,
|
|
|
|
|
APFL_TOK_LINEBREAK,
|
|
|
|
|
APFL_TOK_CONTINUE_LINE,
|
|
|
|
|
APFL_TOK_COMMENT,
|
|
|
|
|
APFL_TOK_COMMA,
|
|
|
|
|
APFL_TOK_QUESTION_MARK,
|
|
|
|
|
APFL_TOK_STRINGIFY,
|
|
|
|
|
APFL_TOK_ASSIGN,
|
|
|
|
|
APFL_TOK_LOCAL_ASSIGN,
|
|
|
|
|
APFL_TOK_NUMBER,
|
|
|
|
|
APFL_TOK_NAME,
|
|
|
|
|
APFL_TOK_STRING,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_token {
|
|
|
|
|
enum apfl_token_type type;
|
|
|
|
|
struct apfl_position position;
|
|
|
|
|
union {
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string text;
|
2021-12-10 20:22:16 +00:00
|
|
|
apfl_number number;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void apfl_token_deinit(struct apfl_token *);
|
|
|
|
|
|
|
|
|
|
const char *apfl_token_type_name(enum apfl_token_type);
|
|
|
|
|
|
|
|
|
|
void apfl_token_print(struct apfl_token, FILE *);
|
|
|
|
|
|
|
|
|
|
// Errors
|
|
|
|
|
|
|
|
|
|
enum apfl_error_type {
|
|
|
|
|
APFL_ERR_MALLOC_FAILED,
|
|
|
|
|
APFL_ERR_INPUT_ERROR,
|
|
|
|
|
APFL_ERR_UNEXPECTED_EOF,
|
|
|
|
|
APFL_ERR_EXPECTED_EQ_AFTER_COLON,
|
2022-01-07 22:39:06 +00:00
|
|
|
APFL_ERR_UNEXPECTED_BYTE,
|
2021-12-10 20:22:16 +00:00
|
|
|
APFL_ERR_UNEXPECTED_BYTE_IN_NUMBER,
|
|
|
|
|
APFL_ERR_EXPECTED_DIGIT,
|
|
|
|
|
APFL_ERR_EXPECTED_HEX_IN_HEX_ESCAPE,
|
|
|
|
|
APFL_ERR_INVALID_ESCAPE_SEQUENCE,
|
|
|
|
|
APFL_ERR_NO_LINEBREAK_AFTER_CONTINUE_LINE,
|
|
|
|
|
APFL_ERR_UNEXPECTED_TOKEN,
|
|
|
|
|
APFL_ERR_MISMATCHING_CLOSING_BRACKET,
|
|
|
|
|
APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN,
|
|
|
|
|
APFL_ERR_STATEMENTS_BEFORE_PARAMETERS,
|
|
|
|
|
APFL_ERR_EMPTY_ASSIGNMENT_BEFORE_PARAMETERS,
|
|
|
|
|
APFL_ERR_UNEXPECTED_EXPRESSION,
|
|
|
|
|
APFL_ERR_INVALID_ASSIGNMENT_LHS,
|
|
|
|
|
APFL_ERR_EMPTY_ASSIGNMENT,
|
2022-01-07 22:08:25 +00:00
|
|
|
APFL_ERR_ONLY_ONE_EXPAND_ALLOWED,
|
2022-01-08 21:55:24 +00:00
|
|
|
APFL_ERR_UNEXPECTED_CONSTANT_IN_MEMBER_ACCESS,
|
|
|
|
|
APFL_ERR_UNEXPECTED_EXPR_IN_MEMBER_ACCESS,
|
2022-01-08 22:20:29 +00:00
|
|
|
APFL_ERR_UNEXPECTED_BLANK_IN_MEMBER_ACCESS,
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
|
|
|
|
|
2021-12-18 23:27:34 +00:00
|
|
|
const char *apfl_error_type_name(enum apfl_error_type);
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_error {
|
|
|
|
|
enum apfl_error_type type;
|
|
|
|
|
|
|
|
|
|
// Optional data
|
|
|
|
|
struct apfl_position position;
|
|
|
|
|
struct apfl_position position2;
|
|
|
|
|
enum apfl_token_type token_type;
|
|
|
|
|
enum apfl_token_type token_type2;
|
|
|
|
|
char byte;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void apfl_error_print(struct apfl_error, FILE *);
|
|
|
|
|
|
|
|
|
|
struct apfl_error apfl_error_simple(enum apfl_error_type);
|
|
|
|
|
bool apfl_error_is_fatal_type(enum apfl_error_type);
|
|
|
|
|
|
|
|
|
|
#define APFL_ERROR_IS_FATAL(err) (apfl_error_is_fatal_type((err).type))
|
|
|
|
|
|
|
|
|
|
enum apfl_expr_type {
|
|
|
|
|
APFL_EXPR_LIST,
|
|
|
|
|
APFL_EXPR_DICT,
|
|
|
|
|
APFL_EXPR_CALL,
|
|
|
|
|
APFL_EXPR_SIMPLE_FUNC,
|
|
|
|
|
APFL_EXPR_COMPLEX_FUNC,
|
|
|
|
|
APFL_EXPR_ASSIGNMENT,
|
|
|
|
|
APFL_EXPR_DOT,
|
|
|
|
|
APFL_EXPR_AT,
|
|
|
|
|
APFL_EXPR_CONSTANT,
|
|
|
|
|
APFL_EXPR_VAR,
|
2022-01-08 22:20:29 +00:00
|
|
|
APFL_EXPR_BLANK,
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_list_item {
|
|
|
|
|
struct apfl_expr *expr;
|
|
|
|
|
bool expand;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_list {
|
|
|
|
|
struct apfl_expr_list_item *items;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_dict_pair {
|
|
|
|
|
struct apfl_expr *k;
|
|
|
|
|
struct apfl_expr *v;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_dict {
|
|
|
|
|
struct apfl_expr_dict_pair *items;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_call {
|
|
|
|
|
struct apfl_expr *callee;
|
|
|
|
|
struct apfl_expr_list arguments;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_body {
|
|
|
|
|
struct apfl_expr *items;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum apfl_expr_const_type {
|
|
|
|
|
APFL_EXPR_CONST_NIL,
|
|
|
|
|
APFL_EXPR_CONST_BOOLEAN,
|
|
|
|
|
APFL_EXPR_CONST_STRING,
|
|
|
|
|
APFL_EXPR_CONST_NUMBER,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_const {
|
|
|
|
|
enum apfl_expr_const_type type;
|
|
|
|
|
|
|
|
|
|
union {
|
|
|
|
|
// variant nil is without data
|
|
|
|
|
bool boolean;
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string string;
|
2021-12-10 20:22:16 +00:00
|
|
|
apfl_number number;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_param_predicate {
|
|
|
|
|
struct apfl_expr_param *lhs;
|
|
|
|
|
struct apfl_expr *rhs;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_param_list {
|
|
|
|
|
struct apfl_expr_param *children;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum apfl_expr_param_type {
|
|
|
|
|
APFL_EXPR_PARAM_VAR,
|
|
|
|
|
APFL_EXPR_PARAM_CONSTANT,
|
|
|
|
|
APFL_EXPR_PARAM_PREDICATE,
|
|
|
|
|
APFL_EXPR_PARAM_LIST,
|
2022-01-08 22:20:29 +00:00
|
|
|
APFL_EXPR_PARAM_BLANK,
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_params {
|
2022-01-07 22:08:25 +00:00
|
|
|
struct apfl_expr_params_item *params;
|
2021-12-10 20:22:16 +00:00
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_param {
|
|
|
|
|
enum apfl_expr_param_type type;
|
|
|
|
|
|
|
|
|
|
union {
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string var;
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_expr_const constant;
|
|
|
|
|
struct apfl_expr_param_predicate predicate;
|
|
|
|
|
struct apfl_expr_params list;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-07 22:08:25 +00:00
|
|
|
struct apfl_expr_params_item {
|
|
|
|
|
bool expand;
|
|
|
|
|
struct apfl_expr_param param;
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_expr_subfunc {
|
|
|
|
|
struct apfl_expr_params params;
|
|
|
|
|
struct apfl_expr_body body;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_complex_func {
|
|
|
|
|
struct apfl_expr_subfunc *subfuncs;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum apfl_expr_assignable_type {
|
2022-01-08 21:55:24 +00:00
|
|
|
APFL_EXPR_ASSIGNABLE_VAR_OR_MEMBER,
|
2021-12-10 20:22:16 +00:00
|
|
|
APFL_EXPR_ASSIGNABLE_CONSTANT,
|
|
|
|
|
APFL_EXPR_ASSIGNABLE_PREDICATE,
|
|
|
|
|
APFL_EXPR_ASSIGNABLE_LIST,
|
2022-01-08 22:20:29 +00:00
|
|
|
APFL_EXPR_ASSIGNABLE_BLANK,
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
|
|
|
|
|
2022-01-08 21:55:24 +00:00
|
|
|
enum apfl_expr_assignable_var_or_member_type {
|
|
|
|
|
APFL_EXPR_ASSIGNABLE_VAR_OR_MEMBER_VAR,
|
|
|
|
|
APFL_EXPR_ASSIGNABLE_VAR_OR_MEMBER_DOT,
|
|
|
|
|
APFL_EXPR_ASSIGNABLE_VAR_OR_MEMBER_AT,
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
2022-01-08 21:55:24 +00:00
|
|
|
|
|
|
|
|
struct apfl_expr_assignable_var_or_member_dot {
|
|
|
|
|
struct apfl_expr_assignable_var_or_member *lhs;
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string rhs;
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
2022-01-08 21:55:24 +00:00
|
|
|
struct apfl_expr_assignable_var_or_member_at {
|
|
|
|
|
struct apfl_expr_assignable_var_or_member *lhs;
|
|
|
|
|
struct apfl_expr *rhs;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_assignable_var_or_member {
|
|
|
|
|
enum apfl_expr_assignable_var_or_member_type type;
|
|
|
|
|
|
|
|
|
|
union {
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string var;
|
2022-01-08 21:55:24 +00:00
|
|
|
struct apfl_expr_assignable_var_or_member_dot dot;
|
|
|
|
|
struct apfl_expr_assignable_var_or_member_at at;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_assignable_predicate {
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_expr_assignable *lhs;
|
|
|
|
|
struct apfl_expr *rhs;
|
|
|
|
|
};
|
|
|
|
|
struct apfl_expr_assignable_list {
|
2022-01-07 22:08:25 +00:00
|
|
|
struct apfl_expr_assignable_list_item *items;
|
2021-12-10 20:22:16 +00:00
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_assignable {
|
|
|
|
|
enum apfl_expr_assignable_type type;
|
|
|
|
|
|
|
|
|
|
union {
|
2022-01-08 21:55:24 +00:00
|
|
|
struct apfl_expr_assignable_var_or_member var_or_member;
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_expr_const constant;
|
|
|
|
|
struct apfl_expr_assignable_predicate predicate;
|
|
|
|
|
struct apfl_expr_assignable_list list;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-07 22:08:25 +00:00
|
|
|
struct apfl_expr_assignable_list_item {
|
|
|
|
|
struct apfl_expr_assignable assignable;
|
|
|
|
|
bool expand;
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_expr_assignment {
|
|
|
|
|
bool local;
|
|
|
|
|
struct apfl_expr_assignable lhs;
|
|
|
|
|
struct apfl_expr *rhs;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_dot {
|
|
|
|
|
struct apfl_expr *lhs;
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string rhs;
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr_at {
|
|
|
|
|
struct apfl_expr *lhs;
|
|
|
|
|
struct apfl_expr *rhs;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_expr {
|
|
|
|
|
enum apfl_expr_type type;
|
|
|
|
|
|
|
|
|
|
union {
|
|
|
|
|
struct apfl_expr_list list;
|
|
|
|
|
struct apfl_expr_dict dict;
|
|
|
|
|
struct apfl_expr_call call;
|
|
|
|
|
struct apfl_expr_body simple_func;
|
|
|
|
|
struct apfl_expr_complex_func complex_func;
|
|
|
|
|
struct apfl_expr_assignment assignment;
|
|
|
|
|
struct apfl_expr_dot dot;
|
|
|
|
|
struct apfl_expr_at at;
|
|
|
|
|
struct apfl_expr_const constant;
|
2022-01-18 20:18:27 +00:00
|
|
|
apfl_refcounted_string var;
|
2022-01-08 22:20:29 +00:00
|
|
|
// blank has no further data
|
2021-12-10 20:22:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_position position;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void apfl_expr_print(struct apfl_expr, FILE *);
|
|
|
|
|
|
|
|
|
|
bool apfl_expr_eq(struct apfl_expr, struct apfl_expr);
|
|
|
|
|
|
|
|
|
|
// Begin deinit functions
|
|
|
|
|
|
|
|
|
|
void apfl_expr_deinit(struct apfl_expr *);
|
|
|
|
|
void apfl_expr_list_deinit(struct apfl_expr_list *);
|
|
|
|
|
void apfl_expr_list_item_deinit(struct apfl_expr_list_item *);
|
|
|
|
|
void apfl_expr_dict_pair_deinit(struct apfl_expr_dict_pair *);
|
|
|
|
|
void apfl_expr_dict_deinit(struct apfl_expr_dict *);
|
|
|
|
|
void apfl_expr_call_deinit(struct apfl_expr_call *);
|
|
|
|
|
void apfl_expr_body_deinit(struct apfl_expr_body *);
|
|
|
|
|
void apfl_expr_const_deinit(struct apfl_expr_const *);
|
|
|
|
|
void apfl_expr_param_predicate_deinit(struct apfl_expr_param_predicate *);
|
|
|
|
|
void apfl_expr_param_list_deinit(struct apfl_expr_param_list *);
|
|
|
|
|
void apfl_expr_params_deinit(struct apfl_expr_params *);
|
2022-01-07 22:08:25 +00:00
|
|
|
void apfl_expr_params_item_deinit(struct apfl_expr_params_item *);
|
2021-12-10 20:22:16 +00:00
|
|
|
void apfl_expr_param_deinit(struct apfl_expr_param *);
|
|
|
|
|
void apfl_expr_subfunc_deinit(struct apfl_expr_subfunc *);
|
|
|
|
|
void apfl_expr_complex_func_deinit(struct apfl_expr_complex_func *);
|
|
|
|
|
void apfl_expr_assignable_predicate_deinit(struct apfl_expr_assignable_predicate *);
|
2022-01-07 22:08:25 +00:00
|
|
|
void apfl_expr_assignable_list_item_deinit(struct apfl_expr_assignable_list_item *);
|
2021-12-10 20:22:16 +00:00
|
|
|
void apfl_expr_assignable_list_deinit(struct apfl_expr_assignable_list *);
|
2022-01-08 21:55:24 +00:00
|
|
|
void apfl_expr_assignable_var_or_member_dot_deinit(struct apfl_expr_assignable_var_or_member_dot *);
|
|
|
|
|
void apfl_expr_assignable_var_or_member_at_deinit(struct apfl_expr_assignable_var_or_member_at *);
|
|
|
|
|
void apfl_expr_assignable_var_or_member_deinit(struct apfl_expr_assignable_var_or_member *);
|
2021-12-10 20:22:16 +00:00
|
|
|
void apfl_expr_assignable_deinit(struct apfl_expr_assignable *);
|
|
|
|
|
void apfl_expr_assignment_deinit(struct apfl_expr_assignment *);
|
|
|
|
|
void apfl_expr_dot_deinit(struct apfl_expr_dot *);
|
|
|
|
|
void apfl_expr_at_deinit(struct apfl_expr_at *);
|
|
|
|
|
|
|
|
|
|
// End deinit functions
|
|
|
|
|
|
|
|
|
|
// Begin move functions
|
|
|
|
|
|
2022-01-08 21:55:24 +00:00
|
|
|
struct apfl_expr apfl_expr_move(struct apfl_expr *);
|
|
|
|
|
struct apfl_expr_list apfl_expr_list_move(struct apfl_expr_list *);
|
|
|
|
|
struct apfl_expr_list_item apfl_expr_list_item_move(struct apfl_expr_list_item *);
|
|
|
|
|
struct apfl_expr_dict_pair apfl_expr_dict_pair_move(struct apfl_expr_dict_pair *);
|
|
|
|
|
struct apfl_expr_dict apfl_expr_dict_move(struct apfl_expr_dict *);
|
|
|
|
|
struct apfl_expr_call apfl_expr_call_move(struct apfl_expr_call *);
|
|
|
|
|
struct apfl_expr_body apfl_expr_body_move(struct apfl_expr_body *);
|
|
|
|
|
struct apfl_expr_const apfl_expr_const_move(struct apfl_expr_const *);
|
|
|
|
|
struct apfl_expr_param_predicate apfl_expr_param_predicate_move(struct apfl_expr_param_predicate *);
|
|
|
|
|
struct apfl_expr_param_list apfl_expr_param_list_move(struct apfl_expr_param_list *);
|
|
|
|
|
struct apfl_expr_params apfl_expr_params_move(struct apfl_expr_params *);
|
|
|
|
|
struct apfl_expr_param apfl_expr_param_move(struct apfl_expr_param *);
|
|
|
|
|
struct apfl_expr_subfunc apfl_expr_subfunc_move(struct apfl_expr_subfunc *);
|
|
|
|
|
struct apfl_expr_complex_func apfl_expr_complex_func_move(struct apfl_expr_complex_func *);
|
|
|
|
|
struct apfl_expr_assignable_var_or_member apfl_expr_assignable_var_or_member_move(struct apfl_expr_assignable_var_or_member *);
|
|
|
|
|
struct apfl_expr_assignable_predicate apfl_expr_assignable_predicate_move(struct apfl_expr_assignable_predicate *);
|
|
|
|
|
struct apfl_expr_assignable_dot apfl_expr_assignable_dot_move(struct apfl_expr_assignable_dot *);
|
|
|
|
|
struct apfl_expr_assignable_at apfl_expr_assignable_at_move(struct apfl_expr_assignable_at *);
|
|
|
|
|
struct apfl_expr_assignable_list apfl_expr_assignable_list_move(struct apfl_expr_assignable_list *);
|
|
|
|
|
struct apfl_expr_assignable apfl_expr_assignable_move(struct apfl_expr_assignable *);
|
|
|
|
|
struct apfl_expr_assignment apfl_expr_assignment_move(struct apfl_expr_assignment *);
|
|
|
|
|
struct apfl_expr_dot apfl_expr_dot_move(struct apfl_expr_dot *);
|
|
|
|
|
struct apfl_expr_at apfl_expr_at_move(struct apfl_expr_at *);
|
2021-12-10 20:22:16 +00:00
|
|
|
|
|
|
|
|
// End move functions
|
|
|
|
|
|
|
|
|
|
enum apfl_parse_result {
|
|
|
|
|
APFL_PARSE_OK,
|
|
|
|
|
APFL_PARSE_EOF,
|
|
|
|
|
APFL_PARSE_ERROR,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_tokenizer;
|
|
|
|
|
|
|
|
|
|
typedef struct apfl_tokenizer *apfl_tokenizer_ptr;
|
|
|
|
|
|
|
|
|
|
typedef bool (*apfl_source_reader_cb)(void *context, char *buf, size_t *len, bool need);
|
|
|
|
|
|
|
|
|
|
apfl_tokenizer_ptr apfl_tokenizer_new(apfl_source_reader_cb, void *context);
|
|
|
|
|
void apfl_tokenizer_destroy(apfl_tokenizer_ptr);
|
|
|
|
|
|
|
|
|
|
enum apfl_parse_result apfl_tokenizer_next(apfl_tokenizer_ptr, bool need);
|
|
|
|
|
|
|
|
|
|
/* Get the current token.
|
|
|
|
|
* Return value is undefined when the last call to apfl_tokenizer_next did not
|
|
|
|
|
* return APFL_PARSE_OK.
|
|
|
|
|
*/
|
|
|
|
|
struct apfl_token apfl_tokenizer_get_token(apfl_tokenizer_ptr);
|
|
|
|
|
|
|
|
|
|
/* Get the current error.
|
|
|
|
|
* Return value is undefined when the last call to apfl_tokenizer_next did not
|
|
|
|
|
* return APFL_PARSE_ERROR.
|
|
|
|
|
*/
|
|
|
|
|
struct apfl_error apfl_tokenizer_get_error(apfl_tokenizer_ptr);
|
|
|
|
|
|
|
|
|
|
|
2021-12-16 21:49:41 +00:00
|
|
|
/* An apfl_source_reader_cb implementation to have a string view as a source.
|
|
|
|
|
* Use together with apfl_string_source_reader_new.
|
|
|
|
|
*/
|
|
|
|
|
bool apfl_string_source_reader(void *, char *, size_t *len, bool);
|
|
|
|
|
|
|
|
|
|
void *apfl_string_source_reader_new(struct apfl_string_view);
|
|
|
|
|
void apfl_string_source_reader_destroy(void *);
|
|
|
|
|
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_parser_token_source {
|
|
|
|
|
enum apfl_parse_result (*next)(void *, bool need);
|
|
|
|
|
struct apfl_token (*get_token)(void *);
|
|
|
|
|
struct apfl_error (*get_error)(void *);
|
|
|
|
|
void *opaque;
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-15 20:28:44 +00:00
|
|
|
struct apfl_parser_token_source apfl_tokenizer_as_token_source(apfl_tokenizer_ptr);
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
struct apfl_parser;
|
|
|
|
|
|
|
|
|
|
typedef struct apfl_parser *apfl_parser_ptr;
|
|
|
|
|
|
|
|
|
|
apfl_parser_ptr apfl_parser_new(struct apfl_parser_token_source);
|
|
|
|
|
|
|
|
|
|
/* Destroys the parser.
|
|
|
|
|
* Note that if the token source needs it's own destruction, you'll have to do
|
|
|
|
|
* that yourself after destroying the parser.
|
|
|
|
|
*/
|
|
|
|
|
void apfl_parser_destroy(apfl_parser_ptr);
|
|
|
|
|
|
|
|
|
|
enum apfl_parse_result apfl_parser_next(apfl_parser_ptr);
|
|
|
|
|
|
|
|
|
|
/* Get the current error.
|
|
|
|
|
* Return value is undefined when the last call to apfl_parser_next did not
|
|
|
|
|
* return APFL_PARSE_ERROR.
|
|
|
|
|
*/
|
|
|
|
|
struct apfl_error apfl_parser_get_error(apfl_parser_ptr);
|
|
|
|
|
|
2021-12-15 20:28:44 +00:00
|
|
|
/* Get the current expression.
|
|
|
|
|
* Return value is undefined when the last call to apfl_parser_next did not
|
|
|
|
|
* return APFL_PARSE_OK.
|
|
|
|
|
*/
|
|
|
|
|
struct apfl_expr apfl_parser_get_expr(apfl_parser_ptr);
|
|
|
|
|
|
2022-01-02 16:19:54 +00:00
|
|
|
|
|
|
|
|
struct apfl_ctx_data;
|
|
|
|
|
typedef struct apfl_ctx_data *apfl_ctx;
|
|
|
|
|
|
|
|
|
|
enum apfl_value_type {
|
|
|
|
|
APFL_VALUE_NIL,
|
|
|
|
|
APFL_VALUE_BOOLEAN,
|
|
|
|
|
APFL_VALUE_NUMBER,
|
|
|
|
|
APFL_VALUE_STRING,
|
|
|
|
|
APFL_VALUE_LIST,
|
2022-01-04 20:51:44 +00:00
|
|
|
APFL_VALUE_DICT,
|
|
|
|
|
// TODO: functions/closures
|
2022-01-02 16:19:54 +00:00
|
|
|
};
|
|
|
|
|
|
2022-01-04 22:11:38 +00:00
|
|
|
struct apfl_list_data;
|
|
|
|
|
typedef struct apfl_list_data *apfl_list;
|
|
|
|
|
|
2022-01-04 20:51:44 +00:00
|
|
|
struct apfl_dict_data;
|
|
|
|
|
typedef struct apfl_dict_data *apfl_dict;
|
|
|
|
|
|
2022-01-02 16:19:54 +00:00
|
|
|
struct apfl_value {
|
|
|
|
|
enum apfl_value_type type;
|
|
|
|
|
union {
|
|
|
|
|
bool boolean;
|
|
|
|
|
apfl_number number;
|
2022-01-04 20:22:46 +00:00
|
|
|
apfl_refcounted_string string;
|
2022-01-04 22:11:38 +00:00
|
|
|
apfl_list list;
|
2022-01-04 20:51:44 +00:00
|
|
|
apfl_dict dict;
|
2022-01-02 16:19:54 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-04 23:25:41 +00:00
|
|
|
|
2022-01-04 20:51:44 +00:00
|
|
|
bool apfl_value_eq(const struct apfl_value, const struct apfl_value);
|
|
|
|
|
struct apfl_value apfl_value_move(struct apfl_value *src);
|
2022-01-04 22:11:38 +00:00
|
|
|
struct apfl_value apfl_value_incref(struct apfl_value);
|
2022-01-02 16:19:54 +00:00
|
|
|
void apfl_value_print(struct apfl_value, FILE *);
|
|
|
|
|
void apfl_value_deinit(struct apfl_value *);
|
|
|
|
|
|
2022-01-04 23:25:41 +00:00
|
|
|
enum apfl_value_get_item_result {
|
|
|
|
|
APFL_VALUE_GET_ITEM_OK,
|
|
|
|
|
APFL_VALUE_GET_ITEM_KEY_DOESNT_EXIST,
|
|
|
|
|
APFL_VALUE_GET_ITEM_NOT_A_CONTAINER,
|
|
|
|
|
APFL_VALUE_GET_ITEM_WRONG_KEY_TYPE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum apfl_value_get_item_result apfl_value_get_item(struct apfl_value container, struct apfl_value key, struct apfl_value *out);
|
|
|
|
|
|
|
|
|
|
apfl_list apfl_list_incref(apfl_list);
|
2022-01-14 22:16:19 +00:00
|
|
|
size_t apfl_list_len(apfl_list);
|
2022-01-04 23:25:41 +00:00
|
|
|
bool apfl_list_get_item(apfl_list, size_t index, struct apfl_value *out);
|
|
|
|
|
void apfl_list_unref(apfl_list);
|
|
|
|
|
|
|
|
|
|
apfl_dict apfl_dict_incref(apfl_dict);
|
|
|
|
|
bool apfl_dict_get_item(apfl_dict, struct apfl_value key, struct apfl_value *out);
|
|
|
|
|
void apfl_dict_unref(apfl_dict);
|
|
|
|
|
|
2022-01-04 22:11:38 +00:00
|
|
|
struct apfl_editable_list_data;
|
|
|
|
|
typedef struct apfl_editable_list_data *apfl_editable_list;
|
|
|
|
|
|
|
|
|
|
apfl_editable_list apfl_editable_list_new(void);
|
|
|
|
|
apfl_editable_list apfl_editable_list_new_from_list(apfl_list);
|
|
|
|
|
bool apfl_editable_list_append(apfl_editable_list, struct apfl_value);
|
|
|
|
|
bool apfl_editable_list_append_list(apfl_editable_list, apfl_list);
|
|
|
|
|
void apfl_editable_list_destroy(apfl_editable_list);
|
|
|
|
|
|
|
|
|
|
/* Finalize the list and return a non-editable list.
|
|
|
|
|
* This also destroys the editable list object, so it's no longer safe to use it.
|
|
|
|
|
* Returns NULL on failure
|
|
|
|
|
*/
|
|
|
|
|
apfl_list apfl_editable_list_finalize(apfl_editable_list);
|
|
|
|
|
|
2022-01-04 20:51:44 +00:00
|
|
|
struct apfl_editable_dict_data;
|
|
|
|
|
typedef struct apfl_editable_dict_data *apfl_editable_dict;
|
|
|
|
|
|
|
|
|
|
apfl_editable_dict apfl_editable_dict_new(void);
|
|
|
|
|
apfl_editable_dict apfl_editable_dict_new_from_dict(apfl_dict);
|
2022-01-15 22:09:24 +00:00
|
|
|
bool apfl_editable_dict_get(apfl_editable_dict, struct apfl_value key, struct apfl_value *out);
|
2022-01-04 20:51:44 +00:00
|
|
|
bool apfl_editable_dict_set(apfl_editable_dict, struct apfl_value key, struct apfl_value value);
|
|
|
|
|
void apfl_editable_dict_delete(apfl_editable_dict, struct apfl_value key);
|
|
|
|
|
void apfl_editable_dict_destroy(apfl_editable_dict);
|
|
|
|
|
|
|
|
|
|
/* Finalize the dictionary and return a non-editable dictionary.
|
|
|
|
|
* This also destroys the editable dictionary object, so it's no longer safe to use it.
|
|
|
|
|
* Returns NULL on failure
|
|
|
|
|
*/
|
|
|
|
|
apfl_dict apfl_editable_dict_finalize(apfl_editable_dict);
|
|
|
|
|
|
2022-01-02 16:19:54 +00:00
|
|
|
enum apfl_result_type {
|
|
|
|
|
APFL_RESULT_OK,
|
|
|
|
|
APFL_RESULT_ERR,
|
|
|
|
|
APFL_RESULT_ERR_FATAL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct apfl_result {
|
|
|
|
|
enum apfl_result_type type;
|
|
|
|
|
struct apfl_value value;
|
|
|
|
|
// TODO: No further details are yet provided on (fatal) error. Not quite
|
|
|
|
|
// sure what to return / how errors/exceptions should work. Maybe a
|
|
|
|
|
// value + a backtrace?
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
apfl_ctx apfl_ctx_new(void);
|
|
|
|
|
|
|
|
|
|
void apfl_ctx_destroy(apfl_ctx);
|
|
|
|
|
|
|
|
|
|
struct apfl_result apfl_eval(apfl_ctx, struct apfl_expr);
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|