cons
Loading...
Searching...
No Matches
Macros | Functions
cons_node.c File Reference

Implements functions for manipulating cons nodes. More...

#include <cons_node.h>
Include dependency graph for cons_node.c:

Go to the source code of this file.

Macros

#define NODE_FROM_CELL(_cell_)   ((struct cons_node *)((char *)(_cell_) - offsetof(struct cons_node, cell)))
 

Functions

static struct cons_nodenode_from_cell (struct cons *cell)
 
struct cons_nodecons_car_node (struct cons_node *node)
 Accessor for the parent node (super-node) of a cons node.
 
struct cons_nodecons_cdr_node (struct cons_node *node)
 Accessor for the next sibling node of a cons node.
 
struct cons_nodecons_sub_node (struct cons_node *node)
 Accessor for the first child node (sub-node) of a cons node.
 
struct cons_nodecons_node (struct cons_node *sub, struct cons_node *super)
 Constructs a cons node with the specified sub-node and new super-node.
 

Detailed Description

Implements functions for manipulating cons nodes.

This file implements functions for working with cons nodes, which are a specialised data structure built on top of cons cells. The functions allow for constructing a tree of cons nodes, where each node can have a parent (super-node) and a list of children (sub-nodes). The operations include linking and unlinking nodes in the tree structure, as well as accessing the parent and child nodes.

Definition in file cons_node.c.

Macro Definition Documentation

◆ NODE_FROM_CELL

#define NODE_FROM_CELL (   _cell_)    ((struct cons_node *)((char *)(_cell_) - offsetof(struct cons_node, cell)))

Definition at line 26 of file cons_node.c.

Function Documentation

◆ cons_car_node()

struct cons_node * cons_car_node ( struct cons_node node)

Accessor for the parent node (super-node) of a cons node.

Parameters
nodeThe cons node to access.
Return values
Pointerto the parent node, or NULL if there is no parent.

Retrieves the parent node from the car field of the cons cell.

Definition at line 36 of file cons_node.c.

36{ return (struct cons_node *)cons_car(&node->cell); }
static void * cons_car(const struct cons *cell)
Accessor for the car field of a cons cell.
Definition cons.h:97
Structure representing a cons node.
Definition cons_node.h:44
struct cons cell
The cons cell forming the basis of the node.
Definition cons_node.h:55

◆ cons_cdr_node()

struct cons_node * cons_cdr_node ( struct cons_node node)

Accessor for the next sibling node of a cons node.

Parameters
nodeThe cons node to access.
Returns
Pointer to the next sibling node, or NULL if there is no next sibling node.
Note
The next sibling node is stored in the cdr field of the node's cell. Up-casts the cdr field of the cons cell to a pointer to a node.

Definition at line 38 of file cons_node.c.

38{ return node_from_cell(cons_cdr(&node->cell)); }
static struct cons * cons_cdr(const struct cons *cell)
Accessor for the cdr field of a cons cell.
Definition cons.h:104

◆ cons_node()

struct cons_node * cons_node ( struct cons_node sub,
struct cons_node super 
)

Constructs a cons node with the specified sub-node and new super-node.

Parameters
subThe sub-node to be linked.
superThe new super-node to be linked.
Returns
Pointer to the super cons node for chaining.

Definition at line 45 of file cons_node.c.

45 {
46 /*
47 * Prevent a node from being its own super-node. Avoids creating a
48 * cycle in the tree, which would lead to undefined behaviour when
49 * traversing. If the sub-node is the same as the super-node, the
50 * function does not modify the tree structure.
51 */
52 if (sub == super)
53 return super;
54 struct cons_node *car = cons_car_node(sub);
55 if (car != NULL) {
56 /*
57 * The sub-node already has a super-node. Remove the sub-node from
58 * the list of sub-nodes of the current super-node. Remove it even
59 * if the current super-node is the same as the new super-node,
60 * because the sub-node may be in a different position in the list
61 * of sub-nodes of the new super-node when re-constructing the same
62 * sub-super linkage.
63 */
64 (void)cons_remove(&car->head, &sub->cell);
65 cons_rplaca(&sub->cell, NULL);
66 }
67 if (super != NULL) {
68 /*
69 * The new super-node is not NULL. Prepend the sub-node to the list
70 * of sub-nodes of the new super-node. Set the car field of the
71 * sub-node to point to the new super-node.
72 *
73 * This could be redundant if the sub-node is already a sub-node of
74 * the new super-node, but it is simpler to just do it
75 * unconditionally than to check for that case.
76 */
77 (void)cons(&super->head, &sub->cell);
78 cons_rplaca(&sub->cell, super);
79 }
80 return super;
81}
struct cons * cons_remove(struct cons **list, struct cons *cell)
Destructively removes the specified cons cell from the list.
Definition cons.c:81
static void cons_rplaca(struct cons *cell, void *car)
Mutator for the car field of a cons cell.
Definition cons.h:111
struct cons_node * cons_car_node(struct cons_node *node)
Accessor for the parent node (super-node) of a cons node.
Definition cons_node.c:36
struct cons * head
Pointer to the list of child nodes (sub-nodes).
Definition cons_node.h:62
Construct cell structure for building linked lists.
Definition cons.h:73

◆ cons_sub_node()

struct cons_node * cons_sub_node ( struct cons_node node)

Accessor for the first child node (sub-node) of a cons node.

Parameters
nodeThe cons node to access.
Returns
Pointer to the first child node, or NULL if there are no child nodes.
Note
The first child node is stored in the head field of the cons node. Up-casts the head field to a pointer to a node.

Definition at line 40 of file cons_node.c.

40{ return node_from_cell(node->head); }

◆ node_from_cell()

static struct cons_node * node_from_cell ( struct cons cell)
inlinestatic

Definition at line 34 of file cons_node.c.

34{ return CONS_NOT_NIL_P(cell) ? NODE_FROM_CELL(cell) : NULL; }
#define CONS_NOT_NIL_P(_cell)
Returns true if the cons cell is not CONS_NIL.
Definition cons.h:42