Add symbol and structure support
[fur] / c / rope.c
1 #ifndef ROPE_C
2 #define ROPE_C
3
4 #include <assert.h>
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8
9 enum RopeType;
10 typedef enum RopeType RopeType;
11 enum RopeType {
12   ROPETYPE_CONCATENATION,
13   ROPETYPE_STRING
14 };
15
16 struct Concatenation;
17 typedef struct Concatenation Concatenation;
18 struct Concatenation {
19   Rope* r0;
20   Rope* r1;
21 };
22
23 struct String;
24 typedef struct String String;
25 struct String {
26   size_t length;
27   uint32_t* characters;
28 };
29
30 union RopeInstance;
31 typedef union RopeInstance RopeInstance;
32 union RopeInstance {
33   Concatenation concatenation;
34   String string;
35 };
36
37 struct Rope {
38   volatile size_t referenceCount;
39   RopeType type;
40   RopeInstance instance;
41 };
42
43 Rope* Rope_rereference(Rope* self) {
44   __sync_add_and_fetch(&(self->referenceCount), 1);
45   return self;
46 }
47
48 void Rope_destruct(Rope* self) {
49   size_t referenceCount = __sync_sub_and_fetch(&(self->referenceCount), 1);
50
51   if(referenceCount == 0) {
52     switch(self->type) {
53       case ROPETYPE_CONCATENATION:
54         Rope_destruct(self->instance.concatenation.r0);
55         Rope_destruct(self->instance.concatenation.r1);
56         break;
57
58       case ROPETYPE_STRING:
59         free(self->instance.string.characters);
60         break;
61
62       default:
63         assert(false);
64     }
65
66     free(self);
67   }
68 }
69
70 void Rope_write(Rope*, Encoding, FILE) {
71   // TODO Implement
72   printf("Not implemented");
73 }
74
75 Rope* Rope_read(Encoding, FILE) {
76   // TODO Implement
77   printf("Not implemented");
78   return NULL;
79 }
80
81 Rope* Rope_concatenate(Rope* r0, Rope* r1) {
82   Rope* result = malloc(sizeof(Rope));
83   result->referenceCount = 0;
84   result->type = ROPETYPE_CONCATENATION;
85   result->instance.concatenation.r0 = Rope_rereference(r0);
86   result->instance.concatenation.r1 = Rope_rereference(r1);
87   return result;
88 }
89
90 __attribute__((pure)) size_t Rope_length(Rope* self) {
91   switch(self->type) {
92     case ROPETYPE_CONCATENATION:
93       return Rope_length(self->instance.concatenation.r0) + Rope_length(self->instance.concatenation.r0);
94     case ROPETYPE_STRING:
95       return self->instance.string.length;
96   }
97 }
98
99 #endif