view src/expr.h @ 148:1620bde57dcb

expr: Implement yexpr_equal
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 03 Sep 2019 12:16:44 +0200
parents 63650268d006
children 53dc68a0488d
line wrap: on
line source

#ifndef src_expr_h
#define src_expr_h

#include "types.h"

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

/**
 * @file expr.h
 * @addtogroup language
 * @{
 */

/**
 * Initialize a yexpr_t to the undefined value.
 */
void yexpr_init(yexpr_t* v);

/**
 * Return an initialized yexpr_t.
 */
yexpr_t yexpr_new(void);

/**
 * Deallocate all memory occupied by expr and any subexpressions.
 */
void yexpr_destroy(yexpr_t* v);

/**
 * Return a deep copy of `orig`. References in `orig` are resolved and copied as well.
 */
yexpr_t yexpr_copy(yexpr_t* orig);

/**
 * Initialize a yexpr_t with a number.
 */
void yexpr_set_number(yexpr_t* v, long long n);

/**
 * Initialize a yexpr_t value with a string, which must be null-terminated.
 * `yexpr_set_str()` takes ownership of the content in `str`; it should not be
 * destroyed afterwards.
 */
void yexpr_set_str(yexpr_t* v, ystr_t str);

/**
 * Initialize a yexpr_t value with a builtin.
 */
void yexpr_set_builtin(yexpr_t* v, YBUILTIN_TYPE b);

/**
 * Initialize a yexpr_t with an atom.
 */
void yexpr_set_atom(yexpr_t* v, yatom_t atom);

/**
 * Initialize a yexpr_t value with an atom, referenced by its name.
 *
 * Causes a new atom to be created in the atoms table, or an existing one to be
 * referenced.
 */
void yexpr_set_atom_name(yexpr_t* v, const char* atom_name);

/**
 * Set the value of `v` to be a reference `ref`. Ownership of `ref` goes to `v`,
 * it may not be freed after the call.
 */
void yexpr_set_ref(yexpr_t* v, yref_t ref);

/**
 * Set the value of `v` to the list/vector `vec`. Ownership of `vec` is
 * transferred to `v`; do not destroy `vec`.
 */
void yexpr_set_list(yexpr_t* v, yvec_t vec);

/**
 * Set the value of `v` to the given string and mark it as exception. `v` owns
 * the message afterwards.
 */
void yexpr_set_exception(yexpr_t* v, ystr_t message);

/**
 * Initialize a yexpr_t value if not yet done and append another value to it.
 *
 * Invariants: `v` must be of type `YEXPR_LIST` or `YEXPR_UNDEF`.
 */
void yexpr_append_value(yexpr_t* v, yexpr_t new_val);

/**
 * Check if two expressions are equal.
 */
bool yexpr_equal(yexpr_t* a, yexpr_t* b);

/****** helpers for parsing ******/

/**
 * If `expr` is uninitialized or a list: append `arg` to it. If it is a value:
 * Append value to a new list, append `arg` to the list, and assign the list to
 * `expr`.
 *
 * Ownership of arg goes to `expr`; do not explicitly destroy `arg`.
 */
void yexpr_init_or_extend(yexpr_t* expr, yexpr_t arg);

/**
 * Print the given expression to stderr in s-expr format.
 */
void yexpr_debug(yexpr_t* expr);

/**
 * Return a string representation of `expr`. The caller owns the returned string.
 */
ystr_t yexpr_debug_str(yexpr_t* expr);

/**
 * @}
 */
#endif