-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtype.c
103 lines (88 loc) · 2.4 KB
/
type.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "type.h"
#include <stdlib.h>
#include <stdarg.h>
static Type **declarations = NULL;
long declarations_used = 0L;
long declarations_size = 0L;
static void add_to_declarations(Type *);
static void create_declarations(void);
static void enlarge_declarations(void);
struct Object_ {
Type *type;
long reference_count;
void *value;
};
struct Type_ {
char *name;
void (*destructor)(void *);
void (*writer)(void *, Printf);
};
Type *declare(char *name, void (*destructor)(void *), void (*writer)(void *, Printf)) {
Type *type = (Type *)malloc(sizeof(Type));
type->name = name;
type->destructor = destructor;
type->writer = writer;
add_to_declarations(type);
return type;
}
Object *wrap(Type *type, void *value) {
Object *object = (Object *)malloc(sizeof(Object));
object->type = type;
object->reference_count = 1L;
object->value = value;
return object;
}
void destroy(Object *object) {
if (object != NULL) {
if (object->reference_count > 1L) {
object->reference_count--;
} else {
object->type->destructor(object->value);
free(object);
}
}
}
Object *clone(Object *object) {
object->reference_count++;
return object;
}
int is_a(Type *type, Object *object) {
return type == object->type;
}
char *type_name(Object *object) {
return object->type->name;
}
void *value(Object *object) {
return object == NULL ? NULL : object->value;
}
void write_object(Object *object, Printf printer) {
if (object != NULL) {
object->type->writer(value(object), printer);
}
}
void free_declarations(void) {
long i;
for (i = 0L; i < declarations_used; i++) {
free(declarations[i]);
}
free(declarations);
declarations = NULL;
declarations_used = 0L;
declarations_size = 0L;
}
static void add_to_declarations(Type *type) {
if (declarations == NULL) {
create_declarations();
} else if (declarations_used == declarations_size) {
enlarge_declarations();
}
declarations[declarations_used++] = type;
}
static void create_declarations(void) {
declarations = (Type **)malloc(sizeof(Type *) * 10L);
declarations_size = 10L;
}
static void enlarge_declarations(void) {
declarations = (Type **)realloc((void *)declarations, sizeof(Type *) * (declarations_size + 10L));
declarations_size = declarations_size + 10L;
}