Chapter 14.1-6
This commit is contained in:
parent
a779473ced
commit
2c007a8f94
17 changed files with 339 additions and 1 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
jlox.sum
|
jlox.sum
|
||||||
jlox.log
|
jlox.log
|
||||||
|
|
||||||
|
.ccls-cache/
|
||||||
|
|
1
clox/.gitignore
vendored
Normal file
1
clox/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
_build/
|
5
clox/CMakeLists.txt
Normal file
5
clox/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
cmake_minimum_required(VERSION 2.19)
|
||||||
|
|
||||||
|
project(Lox C)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
92
clox/compile_commands.json
Normal file
92
clox/compile_commands.json
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/gnu/store/qwhrv8glpw1qk8q1krhdkz6yqr93ac32-gcc-11.1.0/bin/gcc",
|
||||||
|
"-o",
|
||||||
|
"CMakeFiles/Lox.dir/chunk.c.o",
|
||||||
|
"-c",
|
||||||
|
"/home/chelys/projects/study/craftinginterpreters/clox/src/chunk.c",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include/c++",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include"
|
||||||
|
],
|
||||||
|
"directory": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src",
|
||||||
|
"file": "/home/chelys/projects/study/craftinginterpreters/clox/src/chunk.c",
|
||||||
|
"output": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src/CMakeFiles/Lox.dir/chunk.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/gnu/store/qwhrv8glpw1qk8q1krhdkz6yqr93ac32-gcc-11.1.0/bin/gcc",
|
||||||
|
"-o",
|
||||||
|
"CMakeFiles/Lox.dir/memory.c.o",
|
||||||
|
"-c",
|
||||||
|
"/home/chelys/projects/study/craftinginterpreters/clox/src/memory.c",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include/c++",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include"
|
||||||
|
],
|
||||||
|
"directory": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src",
|
||||||
|
"file": "/home/chelys/projects/study/craftinginterpreters/clox/src/memory.c",
|
||||||
|
"output": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src/CMakeFiles/Lox.dir/memory.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/gnu/store/qwhrv8glpw1qk8q1krhdkz6yqr93ac32-gcc-11.1.0/bin/gcc",
|
||||||
|
"-o",
|
||||||
|
"CMakeFiles/Lox.dir/debug.c.o",
|
||||||
|
"-c",
|
||||||
|
"/home/chelys/projects/study/craftinginterpreters/clox/src/debug.c",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include/c++",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include"
|
||||||
|
],
|
||||||
|
"directory": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src",
|
||||||
|
"file": "/home/chelys/projects/study/craftinginterpreters/clox/src/debug.c",
|
||||||
|
"output": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src/CMakeFiles/Lox.dir/debug.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/gnu/store/qwhrv8glpw1qk8q1krhdkz6yqr93ac32-gcc-11.1.0/bin/gcc",
|
||||||
|
"-o",
|
||||||
|
"CMakeFiles/Lox.dir/value.c.o",
|
||||||
|
"-c",
|
||||||
|
"/home/chelys/projects/study/craftinginterpreters/clox/src/value.c",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include/c++",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include"
|
||||||
|
],
|
||||||
|
"directory": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src",
|
||||||
|
"file": "/home/chelys/projects/study/craftinginterpreters/clox/src/value.c",
|
||||||
|
"output": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src/CMakeFiles/Lox.dir/value.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/gnu/store/qwhrv8glpw1qk8q1krhdkz6yqr93ac32-gcc-11.1.0/bin/gcc",
|
||||||
|
"-o",
|
||||||
|
"CMakeFiles/Lox.dir/main.c.o",
|
||||||
|
"-c",
|
||||||
|
"/home/chelys/projects/study/craftinginterpreters/clox/src/main.c",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include/c++",
|
||||||
|
"-I",
|
||||||
|
"/gnu/store/aj7v07smsn9wc5sk4yir3abzcya1rgbb-profile/include"
|
||||||
|
],
|
||||||
|
"directory": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src",
|
||||||
|
"file": "/home/chelys/projects/study/craftinginterpreters/clox/src/main.c",
|
||||||
|
"output": "/home/chelys/projects/study/craftinginterpreters/clox/_build/src/CMakeFiles/Lox.dir/main.c.o"
|
||||||
|
}
|
||||||
|
]
|
0
clox/src/.ccls
Normal file
0
clox/src/.ccls
Normal file
11
clox/src/CMakeLists.txt
Normal file
11
clox/src/CMakeLists.txt
Normal file
|
@ -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)
|
37
clox/src/chunk.c
Normal file
37
clox/src/chunk.c
Normal file
|
@ -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;
|
||||||
|
}
|
25
clox/src/chunk.h
Normal file
25
clox/src/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
|
8
clox/src/common.h
Normal file
8
clox/src/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
|
46
clox/src/debug.c
Normal file
46
clox/src/debug.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
9
clox/src/debug.h
Normal file
9
clox/src/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
|
18
clox/src/main.c
Normal file
18
clox/src/main.c
Normal file
|
@ -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;
|
||||||
|
}
|
14
clox/src/memory.c
Normal file
14
clox/src/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/src/memory.h
Normal file
18
clox/src/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
|
30
clox/src/value.c
Normal file
30
clox/src/value.c
Normal file
|
@ -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);
|
||||||
|
}
|
19
clox/src/value.h
Normal file
19
clox/src/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
|
|
@ -6,4 +6,7 @@
|
||||||
(list (specification->package "openjdk") "jdk")
|
(list (specification->package "openjdk") "jdk")
|
||||||
(specification->package "coreutils")
|
(specification->package "coreutils")
|
||||||
(specification->package "make")
|
(specification->package "make")
|
||||||
(specification->package "dejagnu")))
|
(specification->package "dejagnu")
|
||||||
|
(specification->package "gcc-toolchain")
|
||||||
|
(specification->package "ccls")
|
||||||
|
(specification->package "bear")))
|
||||||
|
|
Loading…
Reference in a new issue