From e2c284b57641b5feec9a8d04313b0cd6d556e860 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 24 Oct 2021 18:26:42 +0200 Subject: Add lambda type and minor file cleanup --- src/bytecode/chunk.c | 43 +++++++++++++++++ src/bytecode/chunk.h | 43 +---------------- src/bytecode/debug.h | 5 +- src/bytecode/main.c | 2 + src/bytecode/objects.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ src/bytecode/objects.h | 124 +++++------------------------------------------- src/bytecode/vm.h | 4 +- 7 files changed, 190 insertions(+), 157 deletions(-) create mode 100644 src/bytecode/chunk.c create mode 100644 src/bytecode/objects.c 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 @@ +#include "chunk.h" +#include "objects.h" + +Chunk * +chunk_init(void) { + Chunk *chunk = malloc(sizeof(Chunk)); + array_init(chunk->code, 0); + array_init(chunk->constants, 0); + array_init(chunk->lines, 0); + return chunk; +} + +void +chunk_free(Chunk *chunk) { + array_free(chunk->code); + for (size_t i = 0; i < array_size(chunk->constants); i++) { + Object obj = chunk->constants[i]; + object_free(obj); + } + array_free(chunk->constants); + array_free(chunk->lines); + free(chunk); +} + +void +add_code(Chunk *chunk, u8 byte, size_t line, size_t col) { + array_push(chunk->code, byte); + LineInfo info = (LineInfo){line, col}; + array_push(chunk->lines, info); +} + +size_t +add_constant(Chunk *chunk, Object obj) { + size_t pos = array_size(chunk->constants); + for (size_t i = 0; i < pos; i++) { + if (object_equal(obj, chunk->constants[i])) { + return i; + } + } + array_push(chunk->constants, obj); + return pos; +} + 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 @@ #ifndef BDL_CHUNK_H #define BDL_CHUNK_H -#include "objects.h" #include "darray.h" +typedef struct Object Object; + typedef struct LineInfo { size_t line; size_t col; @@ -20,44 +21,4 @@ void add_code(Chunk *chunk, u8 byte, size_t line, size_t col); size_t add_constant(Chunk *chunk, Object obj); void chunk_free(Chunk *chunk); -Chunk * -chunk_init(void) { - Chunk *chunk = malloc(sizeof(Chunk)); - array_init(chunk->code, 0); - array_init(chunk->constants, 0); - array_init(chunk->lines, 0); - return chunk; -} - -void -chunk_free(Chunk *chunk) { - array_free(chunk->code); - for (size_t i = 0; i < array_size(chunk->constants); i++) { - Object obj = chunk->constants[i]; - object_free(obj); - } - array_free(chunk->constants); - array_free(chunk->lines); - free(chunk); -} - -void -add_code(Chunk *chunk, u8 byte, size_t line, size_t col) { - array_push(chunk->code, byte); - LineInfo info = (LineInfo){line, col}; - array_push(chunk->lines, info); -} - -size_t -add_constant(Chunk *chunk, Object obj) { - size_t pos = array_size(chunk->constants); - for (size_t i = 0; i < pos; i++) { - if (object_equal(obj, chunk->constants[i])) { - return i; - } - } - array_push(chunk->constants, obj); - return pos; -} - #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 @@ #define BDL_DEBUG_H #include "chunk.h" +#include "objects.h" void disassemble_chunk(Chunk *chunk, const char *name); size_t disassemble_instruction(Chunk *chunk, size_t offset); @@ -51,7 +52,7 @@ disassemble_chunk(Chunk *chunk, const char *name) { offset = 0; while (offset < array_size(chunk->constants)) { printf("\t%03ld -> ", offset); - display(chunk->constants[offset]); + object_display(chunk->constants[offset]); printf("\n"); offset++; } @@ -72,7 +73,7 @@ disassemble_instruction(Chunk *chunk, size_t offset) { case OP_CONSTANT: { u8 constant = chunk->code[offset + 1]; printf("%-16s %4d -> ", ops_str[instruction], constant); - display(chunk->constants[constant]); + object_display(chunk->constants[constant]); printf("\n"); return offset + 2; } 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 @@ #include "vm.h" #include "errors.c" +#include "chunk.c" +#include "objects.c" #include "compiler.h" #include "ops.h" #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 @@ +#include "objects.h" + +Object +make_string(StringView sv) { + Object obj = { + .type = OBJ_TYPE_STRING, + .text = NULL, + }; + array_init(obj.text, sv.n); + array_insert(obj.text, sv.start, sv.n); + return obj; +} + +Object +make_symbol(StringView sv) { + Object obj = { + .type = OBJ_TYPE_SYMBOL, + .text = NULL, + }; + array_init(obj.text, sv.n); + array_insert(obj.text, sv.start, sv.n); + return obj; +} + +Object +make_lambda(void) { + Object obj = { + .type = OBJ_TYPE_LAMBDA, + .chunk = chunk_init(), + }; + return obj; +} + +void +object_display(Object obj) { + switch (obj.type) { + case OBJ_TYPE_FIXNUM: { + printf("%zd", obj.fixnum); + } break; + case OBJ_TYPE_TRUE: { + printf("true"); + } break; + case OBJ_TYPE_FALSE: { + printf("false"); + } break; + case OBJ_TYPE_NIL: { + printf("()"); + } break; + case OBJ_TYPE_STRING: { + printf("\"%.*s\"", (int)array_size(obj.text), obj.text); + } break; + case OBJ_TYPE_SYMBOL: { + printf(":%.*s", (int)array_size(obj.text), obj.text); + } break; + case OBJ_TYPE_PAIR: { + // printf("("); + // display_pair(obj); + // printf(")"); + } break; + case OBJ_TYPE_LAMBDA: { + printf("#{procedure}"); + } break; + case OBJ_TYPE_ERR: { + printf("#{error}"); + } break; + } + return; +} + +void +object_free(Object obj) { + if (IS_STRING(obj) || IS_SYMBOL(obj)) { + array_free(obj.text); + return; + } + if (IS_LAMBDA(obj)) { + chunk_free(obj.chunk); + } +} + +bool +object_equal(Object a, Object b) { + if (a.type != b.type) { + return false; + } + switch (a.type) { + case OBJ_TYPE_TRUE: + case OBJ_TYPE_FALSE: { + return true; + } break; + case OBJ_TYPE_FIXNUM: { + return a.fixnum == b.fixnum; + } break; + case OBJ_TYPE_SYMBOL: + case OBJ_TYPE_STRING: { + if (array_size(a.text) != array_size(b.text)) { + return false; + } + for (size_t i = 0; i < array_size(a.text); i++) { + if (a.text[i] != b.text[i]) { + return false; + } + } + } break; + default: { + return false; + } break; + } + return true; +} + +Object +object_copy(Object src) { + switch (src.type) { + case OBJ_TYPE_SYMBOL: + case OBJ_TYPE_STRING: { + Object copy = src; + copy.text = NULL; + array_init(copy.text, array_size(src.text)); + array_insert(copy.text, src.text, array_size(src.text)); + return copy; + } break; + default: { break; } break; + } + return src; +} 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 @@ #include "string_view.h" #include "darray.h" +#include "chunk.h" typedef enum ObjectType { OBJ_TYPE_NIL, @@ -16,8 +17,6 @@ typedef enum ObjectType { OBJ_TYPE_ERR, } ObjectType; -struct Environment; - typedef struct Object { ObjectType type; bool marked; @@ -38,6 +37,9 @@ typedef struct Object { // }; // OBJ_TYPE_LAMBDA + struct { + Chunk *chunk; + }; // struct { // struct Object *params; // struct Object *body; @@ -46,7 +48,13 @@ typedef struct Object { }; } Object; -void display(Object obj); +Object make_string(StringView sv); +Object make_symbol(StringView sv); +Object make_lambda(void); +void object_display(Object obj); +void object_free(Object obj); +bool object_equal(Object a, Object b); +Object object_copy(Object src); // Value initialization. #define NIL_VAL ((Object){.type = OBJ_TYPE_NIL}) @@ -64,115 +72,7 @@ void display(Object obj); #define IS_FIXNUM(VAL) ((VAL).type == OBJ_TYPE_FIXNUM) #define IS_STRING(VAL) ((VAL).type == OBJ_TYPE_STRING) #define IS_SYMBOL(VAL) ((VAL).type == OBJ_TYPE_SYMBOL) +#define IS_LAMBDA(VAL) ((VAL).type == OBJ_TYPE_LAMBDA) -Object make_string(StringView sv) { - Object obj = { - .type = OBJ_TYPE_STRING, - .text = NULL, - }; - array_init(obj.text, sv.n); - array_insert(obj.text, sv.start, sv.n); - return obj; -} - -Object make_symbol(StringView sv) { - Object obj = { - .type = OBJ_TYPE_SYMBOL, - .text = NULL, - }; - array_init(obj.text, sv.n); - array_insert(obj.text, sv.start, sv.n); - return obj; -} - -void -display(Object obj) { - switch (obj.type) { - case OBJ_TYPE_FIXNUM: { - printf("%zd", obj.fixnum); - } break; - case OBJ_TYPE_TRUE: { - printf("true"); - } break; - case OBJ_TYPE_FALSE: { - printf("false"); - } break; - case OBJ_TYPE_NIL: { - printf("()"); - } break; - case OBJ_TYPE_STRING: { - printf("\"%.*s\"", (int)array_size(obj.text), obj.text); - } break; - case OBJ_TYPE_SYMBOL: { - printf(":%.*s", (int)array_size(obj.text), obj.text); - } break; - case OBJ_TYPE_PAIR: { - // printf("("); - // display_pair(obj); - // printf(")"); - } break; - case OBJ_TYPE_LAMBDA: { - printf("#{procedure}"); - } break; - case OBJ_TYPE_ERR: { - printf("#{error}"); - } break; - } - return; -} - -void -object_free(Object obj) { - if (IS_STRING(obj) || IS_SYMBOL(obj)) { - array_free(obj.text); - } -} - -bool -object_equal(Object a, Object b) { - if (a.type != b.type) { - return false; - } - switch (a.type) { - case OBJ_TYPE_TRUE: - case OBJ_TYPE_FALSE: { - return true; - } break; - case OBJ_TYPE_FIXNUM: { - return a.fixnum == b.fixnum; - } break; - case OBJ_TYPE_SYMBOL: - case OBJ_TYPE_STRING: { - if (array_size(a.text) != array_size(b.text)) { - return false; - } - for (size_t i = 0; i < array_size(a.text); i++) { - if (a.text[i] != b.text[i]) { - return false; - } - } - } break; - default: { - return false; - } break; - } - return true; -} - -Object -object_copy(Object src) { - switch (src.type) { - case OBJ_TYPE_SYMBOL: - case OBJ_TYPE_STRING: { - Object copy = src; - copy.text = NULL; - array_init(copy.text, array_size(src.text)); - array_insert(copy.text, src.text, array_size(src.text)); - return copy; - } break; - default: { break; } break; - } - return src; -} #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) { #ifdef DEBUG_TRACE_EXECUTION printf("stack: [ "); for (size_t i = 0; i < array_size(vm->stack); i++) { - display(vm->stack[i]); + object_display(vm->stack[i]); if (i < array_size(vm->stack) - 1) { printf(" | "); } @@ -211,7 +211,7 @@ vm_interpret(VM *vm, Chunk *chunk) { } } break; case OP_DISPLAY: { - display(array_pop(vm->stack)); + object_display(array_pop(vm->stack)); } break; case OP_PRINT: { Object obj = array_pop(vm->stack); -- cgit v1.2.1