aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-24 18:26:42 +0200
committerBad Diode <bd@badd10de.dev>2021-10-24 18:26:42 +0200
commite2c284b57641b5feec9a8d04313b0cd6d556e860 (patch)
tree3edf7d008f0d68b57727c234a22a0123fe91e383
parent35f93683d56d8b7f57c3f27fa7085847e2ad4598 (diff)
downloadbdl-e2c284b57641b5feec9a8d04313b0cd6d556e860.tar.gz
bdl-e2c284b57641b5feec9a8d04313b0cd6d556e860.zip
Add lambda type and minor file cleanup
-rw-r--r--src/bytecode/chunk.c43
-rwxr-xr-xsrc/bytecode/chunk.h43
-rwxr-xr-xsrc/bytecode/debug.h5
-rwxr-xr-xsrc/bytecode/main.c2
-rw-r--r--src/bytecode/objects.c126
-rwxr-xr-xsrc/bytecode/objects.h124
-rwxr-xr-xsrc/bytecode/vm.h4
7 files changed, 190 insertions, 157 deletions
diff --git a/src/bytecode/chunk.c b/src/bytecode/chunk.c
new file mode 100644
index 0000000..3dc2421
--- /dev/null
+++ b/src/bytecode/chunk.c
@@ -0,0 +1,43 @@
1#include "chunk.h"
2#include "objects.h"
3
4Chunk *
5chunk_init(void) {
6 Chunk *chunk = malloc(sizeof(Chunk));
7 array_init(chunk->code, 0);
8 array_init(chunk->constants, 0);
9 array_init(chunk->lines, 0);
10 return chunk;
11}
12
13void
14chunk_free(Chunk *chunk) {
15 array_free(chunk->code);
16 for (size_t i = 0; i < array_size(chunk->constants); i++) {
17 Object obj = chunk->constants[i];
18 object_free(obj);
19 }
20 array_free(chunk->constants);
21 array_free(chunk->lines);
22 free(chunk);
23}
24
25void
26add_code(Chunk *chunk, u8 byte, size_t line, size_t col) {
27 array_push(chunk->code, byte);
28 LineInfo info = (LineInfo){line, col};
29 array_push(chunk->lines, info);
30}
31
32size_t
33add_constant(Chunk *chunk, Object obj) {
34 size_t pos = array_size(chunk->constants);
35 for (size_t i = 0; i < pos; i++) {
36 if (object_equal(obj, chunk->constants[i])) {
37 return i;
38 }
39 }
40 array_push(chunk->constants, obj);
41 return pos;
42}
43
diff --git a/src/bytecode/chunk.h b/src/bytecode/chunk.h
index 5fbc000..3e1c005 100755
--- a/src/bytecode/chunk.h
+++ b/src/bytecode/chunk.h
@@ -1,9 +1,10 @@
1#ifndef BDL_CHUNK_H 1#ifndef BDL_CHUNK_H
2#define BDL_CHUNK_H 2#define BDL_CHUNK_H
3 3
4#include "objects.h"
5#include "darray.h" 4#include "darray.h"
6 5
6typedef struct Object Object;
7
7typedef struct LineInfo { 8typedef struct LineInfo {
8 size_t line; 9 size_t line;
9 size_t col; 10 size_t col;
@@ -20,44 +21,4 @@ void add_code(Chunk *chunk, u8 byte, size_t line, size_t col);
20size_t add_constant(Chunk *chunk, Object obj); 21size_t add_constant(Chunk *chunk, Object obj);
21void chunk_free(Chunk *chunk); 22void chunk_free(Chunk *chunk);
22 23
23Chunk *
24chunk_init(void) {
25 Chunk *chunk = malloc(sizeof(Chunk));
26 array_init(chunk->code, 0);
27 array_init(chunk->constants, 0);
28 array_init(chunk->lines, 0);
29 return chunk;
30}
31
32void
33chunk_free(Chunk *chunk) {
34 array_free(chunk->code);
35 for (size_t i = 0; i < array_size(chunk->constants); i++) {
36 Object obj = chunk->constants[i];
37 object_free(obj);
38 }
39 array_free(chunk->constants);
40 array_free(chunk->lines);
41 free(chunk);
42}
43
44void
45add_code(Chunk *chunk, u8 byte, size_t line, size_t col) {
46 array_push(chunk->code, byte);
47 LineInfo info = (LineInfo){line, col};
48 array_push(chunk->lines, info);
49}
50
51size_t
52add_constant(Chunk *chunk, Object obj) {
53 size_t pos = array_size(chunk->constants);
54 for (size_t i = 0; i < pos; i++) {
55 if (object_equal(obj, chunk->constants[i])) {
56 return i;
57 }
58 }
59 array_push(chunk->constants, obj);
60 return pos;
61}
62
63#endif // BDL_CHUNK_H 24#endif // BDL_CHUNK_H
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h
index 6703e68..7673703 100755
--- a/src/bytecode/debug.h
+++ b/src/bytecode/debug.h
@@ -2,6 +2,7 @@
2#define BDL_DEBUG_H 2#define BDL_DEBUG_H
3 3
4#include "chunk.h" 4#include "chunk.h"
5#include "objects.h"
5 6
6void disassemble_chunk(Chunk *chunk, const char *name); 7void disassemble_chunk(Chunk *chunk, const char *name);
7size_t disassemble_instruction(Chunk *chunk, size_t offset); 8size_t disassemble_instruction(Chunk *chunk, size_t offset);
@@ -51,7 +52,7 @@ disassemble_chunk(Chunk *chunk, const char *name) {
51 offset = 0; 52 offset = 0;
52 while (offset < array_size(chunk->constants)) { 53 while (offset < array_size(chunk->constants)) {
53 printf("\t%03ld -> ", offset); 54 printf("\t%03ld -> ", offset);
54 display(chunk->constants[offset]); 55 object_display(chunk->constants[offset]);
55 printf("\n"); 56 printf("\n");
56 offset++; 57 offset++;
57 } 58 }
@@ -72,7 +73,7 @@ disassemble_instruction(Chunk *chunk, size_t offset) {
72 case OP_CONSTANT: { 73 case OP_CONSTANT: {
73 u8 constant = chunk->code[offset + 1]; 74 u8 constant = chunk->code[offset + 1];
74 printf("%-16s %4d -> ", ops_str[instruction], constant); 75 printf("%-16s %4d -> ", ops_str[instruction], constant);
75 display(chunk->constants[constant]); 76 object_display(chunk->constants[constant]);
76 printf("\n"); 77 printf("\n");
77 return offset + 2; 78 return offset + 2;
78 } break; 79 } break;
diff --git a/src/bytecode/main.c b/src/bytecode/main.c
index 85882b3..f938e36 100755
--- a/src/bytecode/main.c
+++ b/src/bytecode/main.c
@@ -14,6 +14,8 @@
14 14
15#include "vm.h" 15#include "vm.h"
16#include "errors.c" 16#include "errors.c"
17#include "chunk.c"
18#include "objects.c"
17#include "compiler.h" 19#include "compiler.h"
18#include "ops.h" 20#include "ops.h"
19#include "debug.h" 21#include "debug.h"
diff --git a/src/bytecode/objects.c b/src/bytecode/objects.c
new file mode 100644
index 0000000..515a19d
--- /dev/null
+++ b/src/bytecode/objects.c
@@ -0,0 +1,126 @@
1#include "objects.h"
2
3Object
4make_string(StringView sv) {
5 Object obj = {
6 .type = OBJ_TYPE_STRING,
7 .text = NULL,
8 };
9 array_init(obj.text, sv.n);
10 array_insert(obj.text, sv.start, sv.n);
11 return obj;
12}
13
14Object
15make_symbol(StringView sv) {
16 Object obj = {
17 .type = OBJ_TYPE_SYMBOL,
18 .text = NULL,
19 };
20 array_init(obj.text, sv.n);
21 array_insert(obj.text, sv.start, sv.n);
22 return obj;
23}
24
25Object
26make_lambda(void) {
27 Object obj = {
28 .type = OBJ_TYPE_LAMBDA,
29 .chunk = chunk_init(),
30 };
31 return obj;
32}
33
34void
35object_display(Object obj) {
36 switch (obj.type) {
37 case OBJ_TYPE_FIXNUM: {
38 printf("%zd", obj.fixnum);
39 } break;
40 case OBJ_TYPE_TRUE: {
41 printf("true");
42 } break;
43 case OBJ_TYPE_FALSE: {
44 printf("false");
45 } break;
46 case OBJ_TYPE_NIL: {
47 printf("()");
48 } break;
49 case OBJ_TYPE_STRING: {
50 printf("\"%.*s\"", (int)array_size(obj.text), obj.text);
51 } break;
52 case OBJ_TYPE_SYMBOL: {
53 printf(":%.*s", (int)array_size(obj.text), obj.text);
54 } break;
55 case OBJ_TYPE_PAIR: {
56 // printf("(");
57 // display_pair(obj);
58 // printf(")");
59 } break;
60 case OBJ_TYPE_LAMBDA: {
61 printf("#{procedure}");
62 } break;
63 case OBJ_TYPE_ERR: {
64 printf("#{error}");
65 } break;
66 }
67 return;
68}
69
70void
71object_free(Object obj) {
72 if (IS_STRING(obj) || IS_SYMBOL(obj)) {
73 array_free(obj.text);
74 return;
75 }
76 if (IS_LAMBDA(obj)) {
77 chunk_free(obj.chunk);
78 }
79}
80
81bool
82object_equal(Object a, Object b) {
83 if (a.type != b.type) {
84 return false;
85 }
86 switch (a.type) {
87 case OBJ_TYPE_TRUE:
88 case OBJ_TYPE_FALSE: {
89 return true;
90 } break;
91 case OBJ_TYPE_FIXNUM: {
92 return a.fixnum == b.fixnum;
93 } break;
94 case OBJ_TYPE_SYMBOL:
95 case OBJ_TYPE_STRING: {
96 if (array_size(a.text) != array_size(b.text)) {
97 return false;
98 }
99 for (size_t i = 0; i < array_size(a.text); i++) {
100 if (a.text[i] != b.text[i]) {
101 return false;
102 }
103 }
104 } break;
105 default: {
106 return false;
107 } break;
108 }
109 return true;
110}
111
112Object
113object_copy(Object src) {
114 switch (src.type) {
115 case OBJ_TYPE_SYMBOL:
116 case OBJ_TYPE_STRING: {
117 Object copy = src;
118 copy.text = NULL;
119 array_init(copy.text, array_size(src.text));
120 array_insert(copy.text, src.text, array_size(src.text));
121 return copy;
122 } break;
123 default: { break; } break;
124 }
125 return src;
126}
diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h
index 9744071..72f7420 100755
--- a/src/bytecode/objects.h
+++ b/src/bytecode/objects.h
@@ -3,6 +3,7 @@
3 3
4#include "string_view.h" 4#include "string_view.h"
5#include "darray.h" 5#include "darray.h"
6#include "chunk.h"
6 7
7typedef enum ObjectType { 8typedef enum ObjectType {
8 OBJ_TYPE_NIL, 9 OBJ_TYPE_NIL,
@@ -16,8 +17,6 @@ typedef enum ObjectType {
16 OBJ_TYPE_ERR, 17 OBJ_TYPE_ERR,
17} ObjectType; 18} ObjectType;
18 19
19struct Environment;
20
21typedef struct Object { 20typedef struct Object {
22 ObjectType type; 21 ObjectType type;
23 bool marked; 22 bool marked;
@@ -38,6 +37,9 @@ typedef struct Object {
38 // }; 37 // };
39 38
40 // OBJ_TYPE_LAMBDA 39 // OBJ_TYPE_LAMBDA
40 struct {
41 Chunk *chunk;
42 };
41 // struct { 43 // struct {
42 // struct Object *params; 44 // struct Object *params;
43 // struct Object *body; 45 // struct Object *body;
@@ -46,7 +48,13 @@ typedef struct Object {
46 }; 48 };
47} Object; 49} Object;
48 50
49void display(Object obj); 51Object make_string(StringView sv);
52Object make_symbol(StringView sv);
53Object make_lambda(void);
54void object_display(Object obj);
55void object_free(Object obj);
56bool object_equal(Object a, Object b);
57Object object_copy(Object src);
50 58
51// Value initialization. 59// Value initialization.
52#define NIL_VAL ((Object){.type = OBJ_TYPE_NIL}) 60#define NIL_VAL ((Object){.type = OBJ_TYPE_NIL})
@@ -64,115 +72,7 @@ void display(Object obj);
64#define IS_FIXNUM(VAL) ((VAL).type == OBJ_TYPE_FIXNUM) 72#define IS_FIXNUM(VAL) ((VAL).type == OBJ_TYPE_FIXNUM)
65#define IS_STRING(VAL) ((VAL).type == OBJ_TYPE_STRING) 73#define IS_STRING(VAL) ((VAL).type == OBJ_TYPE_STRING)
66#define IS_SYMBOL(VAL) ((VAL).type == OBJ_TYPE_SYMBOL) 74#define IS_SYMBOL(VAL) ((VAL).type == OBJ_TYPE_SYMBOL)
75#define IS_LAMBDA(VAL) ((VAL).type == OBJ_TYPE_LAMBDA)
67 76
68Object make_string(StringView sv) {
69 Object obj = {
70 .type = OBJ_TYPE_STRING,
71 .text = NULL,
72 };
73 array_init(obj.text, sv.n);
74 array_insert(obj.text, sv.start, sv.n);
75 return obj;
76}
77
78Object make_symbol(StringView sv) {
79 Object obj = {
80 .type = OBJ_TYPE_SYMBOL,
81 .text = NULL,
82 };
83 array_init(obj.text, sv.n);
84 array_insert(obj.text, sv.start, sv.n);
85 return obj;
86}
87
88void
89display(Object obj) {
90 switch (obj.type) {
91 case OBJ_TYPE_FIXNUM: {
92 printf("%zd", obj.fixnum);
93 } break;
94 case OBJ_TYPE_TRUE: {
95 printf("true");
96 } break;
97 case OBJ_TYPE_FALSE: {
98 printf("false");
99 } break;
100 case OBJ_TYPE_NIL: {
101 printf("()");
102 } break;
103 case OBJ_TYPE_STRING: {
104 printf("\"%.*s\"", (int)array_size(obj.text), obj.text);
105 } break;
106 case OBJ_TYPE_SYMBOL: {
107 printf(":%.*s", (int)array_size(obj.text), obj.text);
108 } break;
109 case OBJ_TYPE_PAIR: {
110 // printf("(");
111 // display_pair(obj);
112 // printf(")");
113 } break;
114 case OBJ_TYPE_LAMBDA: {
115 printf("#{procedure}");
116 } break;
117 case OBJ_TYPE_ERR: {
118 printf("#{error}");
119 } break;
120 }
121 return;
122}
123
124void
125object_free(Object obj) {
126 if (IS_STRING(obj) || IS_SYMBOL(obj)) {
127 array_free(obj.text);
128 }
129}
130
131bool
132object_equal(Object a, Object b) {
133 if (a.type != b.type) {
134 return false;
135 }
136 switch (a.type) {
137 case OBJ_TYPE_TRUE:
138 case OBJ_TYPE_FALSE: {
139 return true;
140 } break;
141 case OBJ_TYPE_FIXNUM: {
142 return a.fixnum == b.fixnum;
143 } break;
144 case OBJ_TYPE_SYMBOL:
145 case OBJ_TYPE_STRING: {
146 if (array_size(a.text) != array_size(b.text)) {
147 return false;
148 }
149 for (size_t i = 0; i < array_size(a.text); i++) {
150 if (a.text[i] != b.text[i]) {
151 return false;
152 }
153 }
154 } break;
155 default: {
156 return false;
157 } break;
158 }
159 return true;
160}
161
162Object
163object_copy(Object src) {
164 switch (src.type) {
165 case OBJ_TYPE_SYMBOL:
166 case OBJ_TYPE_STRING: {
167 Object copy = src;
168 copy.text = NULL;
169 array_init(copy.text, array_size(src.text));
170 array_insert(copy.text, src.text, array_size(src.text));
171 return copy;
172 } break;
173 default: { break; } break;
174 }
175 return src;
176}
177 77
178#endif // BDL_OBJECTS_H 78#endif // BDL_OBJECTS_H
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 96e36de..b6f9848 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -140,7 +140,7 @@ vm_interpret(VM *vm, Chunk *chunk) {
140#ifdef DEBUG_TRACE_EXECUTION 140#ifdef DEBUG_TRACE_EXECUTION
141 printf("stack: [ "); 141 printf("stack: [ ");
142 for (size_t i = 0; i < array_size(vm->stack); i++) { 142 for (size_t i = 0; i < array_size(vm->stack); i++) {
143 display(vm->stack[i]); 143 object_display(vm->stack[i]);
144 if (i < array_size(vm->stack) - 1) { 144 if (i < array_size(vm->stack) - 1) {
145 printf(" | "); 145 printf(" | ");
146 } 146 }
@@ -211,7 +211,7 @@ vm_interpret(VM *vm, Chunk *chunk) {
211 } 211 }
212 } break; 212 } break;
213 case OP_DISPLAY: { 213 case OP_DISPLAY: {
214 display(array_pop(vm->stack)); 214 object_display(array_pop(vm->stack));
215 } break; 215 } break;
216 case OP_PRINT: { 216 case OP_PRINT: {
217 Object obj = array_pop(vm->stack); 217 Object obj = array_pop(vm->stack);