Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- struct node_type;
- struct sh_context;
- struct node
- {
- struct node_type *type;
- };
- struct node_type {
- const char *name;
- void (*free)(struct node *node);
- // a real world example would have an output stream
- void (*print)(struct node *node);
- int (*exec)(struct node *node, struct sh_context *context);
- };
- static void node_free(struct node *node) {
- if (node)
- node->type->free(node);
- }
- static void node_print(struct node *node) {
- if (node == NULL)
- printf("<null node>");
- else
- node->type->print(node);
- }
- static int node_exec(struct node *node, struct sh_context *context) {
- return node->type->exec(node, context);
- }
- static void *alloc_node(size_t size, struct node_type *type) {
- struct node *res = malloc(size);
- res->type = type;
- return res;
- }
- // type must be both a node_type instance, and a struct
- // inheriting from node
- #define make_node(Type) \
- ((struct Type*[]){alloc_node(sizeof(struct Type), &(Type))})[0]
- struct node_if
- {
- struct node base;
- struct node *condition;
- struct node *branch;
- struct node *else_branch;
- };
- static void node_if_free(struct node *base_node) {
- struct node_if *node = (void*)base_node;
- node_free(node->condition);
- node_free(node->branch);
- node_free(node->else_branch);
- free(node);
- }
- static void node_if_print(struct node *base_node) {
- struct node_if *node = (void*)base_node;
- printf("if (");
- node_print(node->condition);
- printf(") {");
- node_print(node->branch);
- printf("}");
- if (node->else_branch) {
- printf("{");
- node_print(node->else_branch);
- printf("}");
- }
- }
- static int node_if_exec(struct node *base_node, struct sh_context *context) {
- struct node_if *node = (void*)base_node;
- int cond_res = node_exec(node->condition, context);
- if (cond_res == 0)
- return node_exec(node->branch, context);
- if (node->else_branch == NULL)
- return cond_res;
- return node_exec(node->else_branch, context);
- }
- struct node_type node_if = {
- .name = "if",
- .free = node_if_free,
- .print = node_if_print,
- .exec = node_if_exec,
- };
- int main(void) {
- struct node_if *node = make_node(node_if);
- node->condition = NULL;
- node->branch = NULL;
- node->else_branch = NULL;
- node_print(&node->base);
- node_free(&node->base);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement