diff --git a/NOTES.md b/NOTES.md
new file mode 100644
index 0000000..93b459d
--- /dev/null
+++ b/NOTES.md
@@ -0,0 +1,46 @@
+# clox
+
+## Description
+My notes for Crafting Interpreters
+
+## Table of Contents
+
+- [Description](#description)
+- [Chunks of Bytecode](#chunks-of-bytecode)
+
+
+## Chunks of Bytecode
+
+### Why Bytecode
+Goes over the choice of bytecode vs machine code / assembly.
+Compiling to native instruction set the chip supports is what the fastest languages do.
+However, this is extremely low-level and time consuming. Portability is just exponential complexity at that level.
+We're exchanging performance for portability by writing an emulator in C.
+That emulator is a VM or virtual machine to run that bytecode one instruction at a time.
+
+### Dynamic Arrays
+Goes over his interface and implementation of dynamic arrays.
+The `struct` contains a pointer to items of "type". Ex. `uint8_t *data, void *ptr`, etc.
+It also contains the current length and capacity of the array.
+The implementation contains a reallocate, initType, freeType, and writeType function.
+It exposes three macros `GROW_CAP(cap), GROW_ARRAY(type,ptr,old*type,new*type), and FREE_ARRAY`.
+GROW_CAP is how you handle growing your capacity.
+FREE_ARRAY and GROW_ARRAY utilize our reallocate implementation.
+
+
+### Chunks
+Now we can build dynamic arrays or "Chunks" of instructions or operations. These will be `uint8_t *ptr`. Which is the instruction number or Enum.
+This gives us 255 available operations or instructions we can have.
+Once we have instructions, we also want to be able to have constant values. This is another dynamic array inside chunk.
+These type "values" are really the C primitive double type. 64 bits.
+Instead of writing to it like earlier make a function to add new values and return the index so we can track it.
+For line debugging we add an array of integers to act as a LUT with index of the operation. Each operation maps to a line.
+To disassemble, we just need to write a disassemble chunk function. Instead of iterating or incrementing the offset, disassembleInstruction returns the next offset.
+The offset of the first chunk is it's length. From there disassembleInstruction performs a switch statement on the operation or instruction to return the proper offset.
+disassembleChunk prints out the "name" which is going to be used for the __FILE__, the chunk maps to a line, operation, and possible value.
+
+
+
+
+
+
diff --git a/README.md b/README.md
index d66d7e7..84f8e5e 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@
## Description
My code/notes for Crafting Interpreters
+
## Table of Contents
- [Description](#description)
@@ -12,7 +13,7 @@ My code/notes for Crafting Interpreters
## Features / TODOS
-- [ ] Bytecode
+- [ ] Bytecode
## Usage
Just copy and paste into your projects.
diff --git a/include/chunk.h b/include/chunk.h
index d7fa84c..56f40a9 100644
--- a/include/chunk.h
+++ b/include/chunk.h
@@ -2,8 +2,10 @@
#define CHUNK_INCLUDED
#include "common.h"
+#include "value.h"
typedef enum {
+ OP_CONSTANT,
OP_RETURN,
OP_COUNT,
}OpCode;
@@ -12,10 +14,13 @@ typedef struct {
int len;
int cap;
uint8_t* code;
+ int *lines;
+ ValueArray constants;
} Chunk;
void initChunk(Chunk *chunk);
void freeChunk(Chunk *chunk);
-void writeChunk(Chunk *chunk, uint8_t byte);
+void writeChunk(Chunk *chunk, uint8_t byte,int line);
+int addConstant(Chunk *chunk, Value value);
#endif
diff --git a/include/value.h b/include/value.h
new file mode 100644
index 0000000..6257570
--- /dev/null
+++ b/include/value.h
@@ -0,0 +1,18 @@
+#ifndef VALUE_INCLUDED
+#define VALUE_INCLUDED
+
+#include "common.h"
+
+typedef double Value;
+
+typedef struct {
+ int len;
+ int cap;
+ Value *values;
+} ValueArray;
+
+void initValueArray(ValueArray *array);
+void writeValueArray(ValueArray *array, Value value);
+void freeValueArray(ValueArray *array);
+void printValue(Value value);
+#endif
diff --git a/src/chunk.c b/src/chunk.c
index 88ae661..cdf793b 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -4,18 +4,27 @@ void initChunk(Chunk *chunk){
chunk->len =0;
chunk->cap = 0;
chunk->code = NULL;
+ chunk->lines = NULL;
+ initValueArray(&chunk->constants);
}
void freeChunk(Chunk *chunk){
FREE_ARRAY(uint8_t, chunk->code, chunk->cap);
+ FREE_ARRAY(int,chunk->lines,chunk->cap);
+ freeValueArray(&chunk->constants);
initChunk(chunk);
}
-void writeChunk(Chunk *chunk, uint8_t byte){
+void writeChunk(Chunk *chunk, uint8_t byte, int line){
if(chunk->cap < chunk->len+1){// If we don't have room grow it.
int oldCap = chunk->cap;
chunk->cap = GROW_CAP(oldCap);
chunk->code = GROW_ARRAY(uint8_t, chunk->code, oldCap, chunk->cap);
+ chunk->lines =GROW_ARRAY(int,chunk->lines,oldCap,chunk->cap);
} // Else write byte to chunk
chunk->code[chunk->len] = byte;
+ chunk->lines[chunk->len] = line;
chunk->len++;
}
-
+int addConstant(Chunk *chunk, Value value){
+ writeValueArray(&chunk->constants,value);
+ return chunk->constants.len-1;
+}
diff --git a/src/debug.c b/src/debug.c
index 85ad94e..d834772 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1,5 +1,6 @@
#include
#include "../include/debug.h"
+#include "../include/value.h"
void disassembleChunk(Chunk *chunk, const char* name){
printf("== %s ==\n",name);
@@ -7,15 +8,32 @@ void disassembleChunk(Chunk *chunk, const char* name){
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\t",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:
diff --git a/src/value.c b/src/value.c
new file mode 100644
index 0000000..2df31e8
--- /dev/null
+++ b/src/value.c
@@ -0,0 +1,28 @@
+#include
+#include "../include/memory.h"
+#include "../include/value.h"
+
+void initValueArray(ValueArray *array){
+ array->values = NULL;
+ array->cap = 0;
+ array->len = 0;
+}
+
+void writeValueArray(ValueArray *array, Value value){
+ if(array->cap < array->len+1){
+ int oldCap = array->cap;
+ array->cap = GROW_CAP(oldCap);
+ array->values = GROW_ARRAY(Value,array->values,oldCap, array->cap);
+ }
+ array->values[array->len] = value;
+ array->len ++;
+}
+
+void freeValueArray(ValueArray *array){
+ FREE_ARRAY(Value, array->values,array->cap);
+ initValueArray(array);
+}
+
+void printValue(Value value){
+ printf("%g",value);
+}
diff --git a/tests/01_main.c b/tests/01_main.c
index 144e4d6..c7074bd 100644
--- a/tests/01_main.c
+++ b/tests/01_main.c
@@ -5,7 +5,11 @@
int main(void){
Chunk chunk;
initChunk(&chunk);
- writeChunk(&chunk, OP_RETURN);
+
+ int constant = addConstant(&chunk,1.2);
+ writeChunk(&chunk, OP_CONSTANT,10);
+ writeChunk(&chunk,constant,10);
+ writeChunk(&chunk, OP_RETURN,10);
disassembleChunk(&chunk,"Test Chunk");
freeChunk(&chunk);