Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.35 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct node_type;
  5. struct sh_context;
  6.  
  7.  
  8. struct node
  9. {
  10. struct node_type *type;
  11. };
  12.  
  13. struct node_type {
  14. const char *name;
  15. void (*free)(struct node *node);
  16. // a real world example would have an output stream
  17. void (*print)(struct node *node);
  18. int (*exec)(struct node *node, struct sh_context *context);
  19. };
  20.  
  21. static void node_free(struct node *node) {
  22. if (node)
  23. node->type->free(node);
  24. }
  25.  
  26. static void node_print(struct node *node) {
  27. if (node == NULL)
  28. printf("<null node>");
  29. else
  30. node->type->print(node);
  31. }
  32.  
  33. static int node_exec(struct node *node, struct sh_context *context) {
  34. return node->type->exec(node, context);
  35. }
  36.  
  37. static void *alloc_node(size_t size, struct node_type *type) {
  38. struct node *res = malloc(size);
  39. res->type = type;
  40. return res;
  41. }
  42.  
  43. // type must be both a node_type instance, and a struct
  44. // inheriting from node
  45. #define make_node(Type) \
  46. ((struct Type*[]){alloc_node(sizeof(struct Type), &(Type))})[0]
  47.  
  48. struct node_if
  49. {
  50. struct node base;
  51. struct node *condition;
  52. struct node *branch;
  53. struct node *else_branch;
  54. };
  55.  
  56. static void node_if_free(struct node *base_node) {
  57. struct node_if *node = (void*)base_node;
  58. node_free(node->condition);
  59. node_free(node->branch);
  60. node_free(node->else_branch);
  61. free(node);
  62. }
  63.  
  64. static void node_if_print(struct node *base_node) {
  65. struct node_if *node = (void*)base_node;
  66. printf("if (");
  67. node_print(node->condition);
  68. printf(") {");
  69. node_print(node->branch);
  70. printf("}");
  71.  
  72. if (node->else_branch) {
  73. printf("{");
  74. node_print(node->else_branch);
  75. printf("}");
  76. }
  77. }
  78.  
  79. static int node_if_exec(struct node *base_node, struct sh_context *context) {
  80. struct node_if *node = (void*)base_node;
  81. int cond_res = node_exec(node->condition, context);
  82. if (cond_res == 0)
  83. return node_exec(node->branch, context);
  84.  
  85. if (node->else_branch == NULL)
  86. return cond_res;
  87.  
  88. return node_exec(node->else_branch, context);
  89. }
  90.  
  91. struct node_type node_if = {
  92. .name = "if",
  93. .free = node_if_free,
  94. .print = node_if_print,
  95. .exec = node_if_exec,
  96. };
  97.  
  98.  
  99. int main(void) {
  100. struct node_if *node = make_node(node_if);
  101. node->condition = NULL;
  102. node->branch = NULL;
  103. node->else_branch = NULL;
  104. node_print(&node->base);
  105. node_free(&node->base);
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement