[Chapter14&Chunks] - Starting the new interpreter with chunks of bytecode

This commit is contained in:
Adnan Ioricce 2024-10-06 13:50:40 +00:00
parent b94a25bd31
commit 96ce1a8271
17 changed files with 237 additions and 0 deletions

19
clox/Makefile Normal file

@ -0,0 +1,19 @@
CC = gcc
CFLAGS = -Wall -Wextra -g
SOURCES = main.c chunk.c memory.c debug.c value.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = clox
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJECTS) $(EXECUTABLE)
.PHONY: all clean

36
clox/chunk.c Normal file

@ -0,0 +1,36 @@
#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;
}

25
clox/chunk.h Normal file

@ -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

BIN
clox/chunk.o Normal file

Binary file not shown.

BIN
clox/clox Executable file

Binary file not shown.

8
clox/common.h Normal file

@ -0,0 +1,8 @@
#ifndef clox_common_h
#define clox_common_h
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#endif

45
clox/debug.c Normal file

@ -0,0 +1,45 @@
#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;
}
}

9
clox/debug.h Normal file

@ -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

BIN
clox/debug.o Normal file

Binary file not shown.

16
clox/main.c Normal file

@ -0,0 +1,16 @@
#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;
}

BIN
clox/main.o Normal file

Binary file not shown.

14
clox/memory.c Normal file

@ -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;
}

18
clox/memory.h Normal file

@ -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

BIN
clox/memory.o Normal file

Binary file not shown.

28
clox/value.c Normal file

@ -0,0 +1,28 @@
#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);
}

19
clox/value.h Normal file

@ -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

BIN
clox/value.o Normal file

Binary file not shown.