aboutsummaryrefslogtreecommitdiffstats
path: root/src/treewalk/objects.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/treewalk/objects.c')
-rw-r--r--src/treewalk/objects.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/treewalk/objects.c b/src/treewalk/objects.c
new file mode 100644
index 0000000..c71bc40
--- /dev/null
+++ b/src/treewalk/objects.c
@@ -0,0 +1,141 @@
1#include "gc.h"
2#include "objects.h"
3
4//
5// Constructors.
6//
7
8Object *
9make_fixnum(ssize_t num) {
10 Object *obj = alloc_object(OBJ_TYPE_FIXNUM);
11 obj->fixnum = num;
12 return obj;
13}
14
15Object *
16make_procedure(Object *(*proc)(struct Environment *, struct Object *args)) {
17 Object *obj = alloc_object(OBJ_TYPE_PROCEDURE);
18 obj->proc = proc;
19 return obj;
20}
21
22Object *
23make_pair(Object *car, Object *cdr) {
24 Object *obj = alloc_object(OBJ_TYPE_PAIR);
25 obj->car = car;
26 obj->cdr = cdr;
27 return obj;
28}
29
30Object *
31make_symbol(StringView sv) {
32 Object *obj = alloc_object(OBJ_TYPE_SYMBOL);
33 obj->symbol = NULL;
34 array_init(obj->symbol, sv.n);
35 array_insert(obj->symbol, sv.start, sv.n);
36 return obj;
37}
38
39Object *
40make_string(void) {
41 Object *obj = alloc_object(OBJ_TYPE_STRING);
42 obj->string = NULL;
43 array_init(obj->string, 0);
44 return obj;
45}
46
47void
48append_string(Object *obj, const StringView sv) {
49 if (sv.n == 0) {
50 return;
51 }
52 array_insert(obj->string, sv.start, sv.n);
53}
54
55void
56display_pair(Object *root) {
57 display(root->car);
58 if (root->cdr->type == OBJ_TYPE_PAIR) {
59 printf(" ");
60 display_pair(root->cdr);
61 } else if (root->cdr == obj_nil) {
62 return;
63 } else {
64 printf(" . ");
65 display(root->cdr);
66 }
67}
68
69void
70display(Object *root) {
71 switch (root->type) {
72 case OBJ_TYPE_FIXNUM: {
73 printf("%zd", root->fixnum);
74 } break;
75 case OBJ_TYPE_BOOL: {
76 if (root == obj_true) {
77 printf("true");
78 } else {
79 printf("false");
80 }
81 } break;
82 case OBJ_TYPE_NIL: {
83 printf("()");
84 } break;
85 case OBJ_TYPE_STRING: {
86 printf("\"%.*s\"", (int)array_size(root->string), root->string);
87 } break;
88 case OBJ_TYPE_SYMBOL: {
89 printf(":%.*s", (int)array_size(root->symbol), root->symbol);
90 } break;
91 case OBJ_TYPE_PAIR: {
92 printf("(");
93 display_pair(root);
94 printf(")");
95 } break;
96 case OBJ_TYPE_LAMBDA:
97 case OBJ_TYPE_PROCEDURE: {
98 printf("#{procedure}");
99 } break;
100 case OBJ_TYPE_ERR: {
101 printf("#{error}");
102 } break;
103 }
104 return;
105}
106
107bool
108obj_eq(const Object *a, const Object* b) {
109 if (a->type != b->type) {
110 return false;
111 }
112 switch (a->type) {
113 case OBJ_TYPE_FIXNUM: {
114 return a->fixnum == b->fixnum;
115 } break;
116 case OBJ_TYPE_STRING: {
117 if (array_size(a->string) != array_size(b->string)) {
118 return false;
119 }
120 for (size_t i = 0; i < array_size(a->string); i++) {
121 if (a->string[i] != b->string[i]) {
122 return false;
123 }
124 }
125 } break;
126 case OBJ_TYPE_SYMBOL: {
127 if (array_size(a->symbol) != array_size(b->symbol)) {
128 return false;
129 }
130 for (size_t i = 0; i < array_size(a->symbol); i++) {
131 if (a->symbol[i] != b->symbol[i]) {
132 return false;
133 }
134 }
135 } break;
136 default: {
137 return a == b;
138 } break;
139 }
140 return true;
141}