[Chapter14&Chunks] - Starting the new interpreter with chunks of bytecode
This commit is contained in:
parent
b94a25bd31
commit
96ce1a8271
19
clox/Makefile
Normal file
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
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
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
BIN
clox/chunk.o
Normal file
Binary file not shown.
BIN
clox/clox
Executable file
BIN
clox/clox
Executable file
Binary file not shown.
8
clox/common.h
Normal file
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
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
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
BIN
clox/debug.o
Normal file
Binary file not shown.
16
clox/main.c
Normal file
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
BIN
clox/main.o
Normal file
Binary file not shown.
14
clox/memory.c
Normal file
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
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
BIN
clox/memory.o
Normal file
Binary file not shown.
28
clox/value.c
Normal file
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
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
BIN
clox/value.o
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user