aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src
diff options
context:
space:
mode:
authorGravatar Tom Willemse2021-07-08 02:24:24 -0700
committerGravatar Tom Willemse2021-07-08 02:25:13 -0700
commit2c007a8f94d65dc40f638b284db7e374a58b632f (patch)
tree260a1460cdb86c913e785171a85447afc03efddf /clox/src
parenta779473cede81f4d3b4eed6f6b4e4184d43ffa87 (diff)
downloadcrafting-interpreters-2c007a8f94d65dc40f638b284db7e374a58b632f.tar.gz
crafting-interpreters-2c007a8f94d65dc40f638b284db7e374a58b632f.zip
Chapter 14.1-6
Diffstat (limited to 'clox/src')
-rw-r--r--clox/src/.ccls0
-rw-r--r--clox/src/CMakeLists.txt11
-rw-r--r--clox/src/chunk.c37
-rw-r--r--clox/src/chunk.h25
-rw-r--r--clox/src/common.h8
-rw-r--r--clox/src/debug.c46
-rw-r--r--clox/src/debug.h9
-rw-r--r--clox/src/main.c18
-rw-r--r--clox/src/memory.c14
-rw-r--r--clox/src/memory.h18
-rw-r--r--clox/src/value.c30
-rw-r--r--clox/src/value.h19
12 files changed, 235 insertions, 0 deletions
diff --git a/clox/src/.ccls b/clox/src/.ccls
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/clox/src/.ccls
diff --git a/clox/src/CMakeLists.txt b/clox/src/CMakeLists.txt
new file mode 100644
index 0000000..6d7e73b
--- /dev/null
+++ b/clox/src/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(Lox
+ common.h
+ chunk.h
+ chunk.c
+ memory.h
+ memory.c
+ debug.h
+ debug.c
+ value.h
+ value.c
+ main.c)
diff --git a/clox/src/chunk.c b/clox/src/chunk.c
new file mode 100644
index 0000000..f368dec
--- /dev/null
+++ b/clox/src/chunk.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+
+#include "chunk.h"
+#include "memory.h"
+
+void initChunk(Chunk* chunk) {
+ chunk->count = 0;
+ chunk->capacity = 0;
+ chunk->code = NULL;
+ chunk->lines = NULL;
+ initValueArray(&chunk->constants);
+}
+
+void freeChunk(Chunk* chunk) {
+ FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
+ FREE_ARRAY(int, chunk->lines, chunk->capacity);
+ freeValueArray(&chunk->constants);
+ initChunk(chunk);
+}
+
+void writeChunk(Chunk* chunk, uint8_t byte, int line) {
+ if (chunk->capacity < chunk->count + 1) {
+ int oldCapacity = chunk->capacity;
+ chunk->capacity = GROW_CAPACITY(oldCapacity);
+ chunk->code = GROW_ARRAY(uint8_t, chunk->code, oldCapacity, chunk->capacity);
+ chunk->lines = GROW_ARRAY(int, chunk->lines, oldCapacity, chunk->capacity);
+ }
+
+ chunk->code[chunk->count] = byte;
+ chunk->lines[chunk->count] = line;
+ chunk->count++;
+}
+
+int addConstant(Chunk* chunk, Value value) {
+ writeValueArray(&chunk->constants, value);
+ return chunk->constants.count - 1;
+}
diff --git a/clox/src/chunk.h b/clox/src/chunk.h
new file mode 100644
index 0000000..466898b
--- /dev/null
+++ b/clox/src/chunk.h
@@ -0,0 +1,25 @@
+#ifndef clox_chunk_h
+#define clox_chunk_h
+
+#include "common.h"
+#include "value.h"
+
+typedef enum {
+ OP_CONSTANT,
+ OP_RETURN,
+} OpCode;
+
+typedef struct {
+ int count;
+ int capacity;
+ uint8_t* code;
+ int* lines;
+ ValueArray constants;
+} Chunk;
+
+void initChunk(Chunk* chunk);
+void freeChunk(Chunk* chunk);
+void writeChunk(Chunk* chunk, uint8_t byte, int line);
+int addConstant(Chunk* chunk, Value value);
+
+#endif
diff --git a/clox/src/common.h b/clox/src/common.h
new file mode 100644
index 0000000..c827b76
--- /dev/null
+++ b/clox/src/common.h
@@ -0,0 +1,8 @@
+#ifndef clox_common_h
+#define clox_common_h
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#endif
diff --git a/clox/src/debug.c b/clox/src/debug.c
new file mode 100644
index 0000000..68fdbc5
--- /dev/null
+++ b/clox/src/debug.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+#include "debug.h"
+#include "value.h"
+
+void disassembleChunk(Chunk* chunk, const char* name) {
+ printf("== %s ==\n", name);
+
+ for (int offset = 0; offset < chunk->count;) {
+ offset = disassembleInstruction(chunk, offset);
+ }
+}
+
+static int constantInstruction(const char* name, Chunk* chunk, int offset) {
+ uint8_t constant = chunk->code[offset + 1];
+ printf("%-16s %4d '", name, constant);
+ printValue(chunk->constants.values[constant]);
+ printf("'\n");
+ return offset + 2;
+}
+
+static int simpleInstruction(const char* name, int offset) {
+ printf("%s\n", name);
+ return offset + 1;
+}
+
+int disassembleInstruction(Chunk* chunk, int offset) {
+ printf("%04d ", offset);
+ if (offset > 0 &&
+ chunk->lines[offset] == chunk->lines[offset - 1]) {
+ printf(" | ");
+ } else {
+ printf("%4d ", chunk->lines[offset]);
+ }
+
+ uint8_t instruction = chunk->code[offset];
+ switch (instruction) {
+ case OP_CONSTANT:
+ return constantInstruction("OP_CONSTANT", chunk, offset);
+ case OP_RETURN:
+ return simpleInstruction("OP_RETURN", offset);
+ default:
+ printf("Unknown opcode %d\n", instruction);
+ return offset + 1;
+ }
+}
diff --git a/clox/src/debug.h b/clox/src/debug.h
new file mode 100644
index 0000000..5731d05
--- /dev/null
+++ b/clox/src/debug.h
@@ -0,0 +1,9 @@
+#ifndef clox_debug_h
+#define clox_debug_h
+
+#include "chunk.h"
+
+void disassembleChunk(Chunk* chunk, const char* name);
+int disassembleInstruction(Chunk* chunk, int offset);
+
+#endif
diff --git a/clox/src/main.c b/clox/src/main.c
new file mode 100644
index 0000000..9aeb8fd
--- /dev/null
+++ b/clox/src/main.c
@@ -0,0 +1,18 @@
+#include "common.h"
+#include "chunk.h"
+#include "debug.h"
+
+int main(int argc, const char* argv[]) {
+ Chunk chunk;
+ initChunk(&chunk);
+
+ int constant = addConstant(&chunk, 1.2);
+ writeChunk(&chunk, OP_CONSTANT, 123);
+ writeChunk(&chunk, constant, 123);
+
+ writeChunk(&chunk, OP_RETURN, 123);
+
+ disassembleChunk(&chunk, "test chunk");
+ freeChunk(&chunk);
+ return 0;
+}
diff --git a/clox/src/memory.c b/clox/src/memory.c
new file mode 100644
index 0000000..ead60c8
--- /dev/null
+++ b/clox/src/memory.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+
+#include "memory.h"
+
+void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
+ if (newSize == 0) {
+ free(pointer);
+ return NULL;
+ }
+
+ void* result = realloc(pointer, newSize);
+ if (result == NULL) exit(1);
+ return result;
+}
diff --git a/clox/src/memory.h b/clox/src/memory.h
new file mode 100644
index 0000000..3c4bdb7
--- /dev/null
+++ b/clox/src/memory.h
@@ -0,0 +1,18 @@
+#ifndef clox_memory_h
+#define clox_memory_h
+
+#include "common.h"
+
+#define GROW_CAPACITY(capacity) \
+ ((capacity) < 8 ? 8 : (capacity) * 2)
+
+#define GROW_ARRAY(type, pointer, oldCount, newCount) \
+ (type*)reallocate(pointer, sizeof(type) * (oldCount), \
+ sizeof(type) * (newCount))
+
+#define FREE_ARRAY(type, pointer, oldCount) \
+ reallocate(pointer, sizeof(type) * (oldCount), 0)
+
+void* reallocate(void* pointer, size_t oldSize, size_t newSize);
+
+#endif
diff --git a/clox/src/value.c b/clox/src/value.c
new file mode 100644
index 0000000..9a27034
--- /dev/null
+++ b/clox/src/value.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+#include "memory.h"
+#include "value.h"
+
+void initValueArray(ValueArray* array) {
+ array->values = NULL;
+ array->capacity = 0;
+ array->count = 0;
+}
+
+void writeValueArray(ValueArray* array, Value value) {
+ if (array->capacity < array->count + 1) {
+ int oldCapacity = array->capacity;
+ array->capacity = GROW_CAPACITY(oldCapacity);
+ array->values = GROW_ARRAY(Value, array->values, oldCapacity, array->capacity);
+ }
+
+ array->values[array->count] = value;
+ array->count++;
+}
+
+void freeValueArray(ValueArray* array) {
+ FREE_ARRAY(Value, array->values, array->capacity);
+ initValueArray(array);
+}
+
+void printValue(Value value) {
+ printf("%g", value);
+}
diff --git a/clox/src/value.h b/clox/src/value.h
new file mode 100644
index 0000000..86d4b1c
--- /dev/null
+++ b/clox/src/value.h
@@ -0,0 +1,19 @@
+#ifndef clox_value_h
+#define clox_value_h
+
+#include "common.h"
+
+typedef double Value;
+
+typedef struct {
+ int capacity;
+ int count;
+ Value* values;
+} ValueArray;
+
+void initValueArray(ValueArray* array);
+void writeValueArray(ValueArray* array, Value value);
+void freeValueArray(ValueArray* array);
+void printValue(Value value);
+
+#endif