aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2021-08-02 18:09:03 -0700
committerGravatar Tom Willemse2021-08-02 18:09:03 -0700
commitb131e343bb8a2b126a5370138d826d87d74fce30 (patch)
tree06cd5d22c8eeac088e5393199357c4e8d34eb8f6
parent9b60cf334cdb030759c54f700d5c122338c5b3a8 (diff)
downloadcrafting-interpreters-b131e343bb8a2b126a5370138d826d87d74fce30.tar.gz
crafting-interpreters-b131e343bb8a2b126a5370138d826d87d74fce30.zip
Chapter 16.1
-rw-r--r--clox/src/CMakeLists.txt4
-rw-r--r--clox/src/compiler.c7
-rw-r--r--clox/src/compiler.h6
-rw-r--r--clox/src/main.c82
-rw-r--r--clox/src/scanner.c19
-rw-r--r--clox/src/scanner.h6
-rw-r--r--clox/src/vm.c8
-rw-r--r--clox/src/vm.h4
8 files changed, 110 insertions, 26 deletions
diff --git a/clox/src/CMakeLists.txt b/clox/src/CMakeLists.txt
index 12ad9ff..af21222 100644
--- a/clox/src/CMakeLists.txt
+++ b/clox/src/CMakeLists.txt
@@ -10,6 +10,10 @@ add_executable(Lox
value.c
vm.h
vm.c
+ compiler.h
+ compiler.c
+ scanner.h
+ scanner.c
main.c)
install(TARGETS Lox)
diff --git a/clox/src/compiler.c b/clox/src/compiler.c
new file mode 100644
index 0000000..71961ef
--- /dev/null
+++ b/clox/src/compiler.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+#include "common.h"
+#include "compiler.h"
+#include "scanner.h"
+
+void compile(const char *source) { initScanner(source); }
diff --git a/clox/src/compiler.h b/clox/src/compiler.h
new file mode 100644
index 0000000..49a45b0
--- /dev/null
+++ b/clox/src/compiler.h
@@ -0,0 +1,6 @@
+#ifndef COMPILER_H
+#define COMPILER_H
+
+void compile(const char *source);
+
+#endif
diff --git a/clox/src/main.c b/clox/src/main.c
index d1e747f..c95c7ba 100644
--- a/clox/src/main.c
+++ b/clox/src/main.c
@@ -1,36 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "chunk.h"
#include "common.h"
#include "debug.h"
#include "vm.h"
-int main(int argc, const char *argv[]) {
- initVM();
+static void repl() {
+ char line[1024];
+ for (;;) {
+ printf("> ");
- Chunk chunk;
- initChunk(&chunk);
+ if (!fgets(line, sizeof(line), stdin)) {
+ printf("\n");
+ break;
+ }
- int constant = addConstant(&chunk, 1.2);
- writeChunk(&chunk, OP_CONSTANT, 123);
- writeChunk(&chunk, constant, 123);
+ interpret(line);
+ }
+}
- constant = addConstant(&chunk, 3.4);
- writeChunk(&chunk, OP_CONSTANT, 123);
- writeChunk(&chunk, constant, 123);
+static char *readFile(const char *path) {
+ FILE *file = fopen(path, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "Could not open file \"%s\".\n", path);
+ exit(74);
+ }
- writeChunk(&chunk, OP_ADD, 123);
+ fseek(file, 0L, SEEK_END);
+ size_t fileSize = ftell(file);
+ rewind(file);
- constant = addConstant(&chunk, 5.6);
- writeChunk(&chunk, OP_CONSTANT, 123);
- writeChunk(&chunk, constant, 123);
+ char *buffer = (char *)malloc(fileSize + 1);
+ if (buffer == NULL) {
+ fprintf(stderr, "Not enough memory to read \"%s\".\n", path);
+ exit(74);
+ }
- writeChunk(&chunk, OP_DIVIDE, 123);
- writeChunk(&chunk, OP_NEGATE, 123);
+ size_t bytesRead = fread(buffer, sizeof(char), fileSize, file);
+ if (bytesRead < fileSize) {
+ fprintf(stderr, "Could not read file \"%s\".\n", path);
+ exit(74);
+ }
+
+ buffer[bytesRead] = '\0';
+
+ fclose(file);
+ return buffer;
+}
+
+static void runFile(const char *path) {
+ char *source = readFile(path);
+ InterpretResult result = interpret(source);
+ free(source);
+
+ if (result == INTERPRET_COMPILE_ERROR)
+ exit(65);
+ if (result == INTERPRET_RUNTIME_ERROR)
+ exit(70);
+}
+
+int main(int argc, const char *argv[]) {
+ initVM();
- writeChunk(&chunk, OP_RETURN, 123);
+ if (argc == 1) {
+ repl();
+ } else if (argc = 2) {
+ runFile(argv[1]);
+ } else {
+ fprintf(stderr, "Usage: clox [path]\n");
+ exit(64);
+ }
- disassembleChunk(&chunk, "test chunk");
- interpret(&chunk);
freeVM();
- freeChunk(&chunk);
return 0;
}
diff --git a/clox/src/scanner.c b/clox/src/scanner.c
new file mode 100644
index 0000000..2bcabb8
--- /dev/null
+++ b/clox/src/scanner.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+#include "scanner.h"
+
+typedef struct {
+ const char *start;
+ const char *current;
+ int line;
+} Scanner;
+
+Scanner scanner;
+
+void initScanner(const char *source) {
+ scanner.start = source;
+ scanner.current = source;
+ scanner.line = 1;
+}
diff --git a/clox/src/scanner.h b/clox/src/scanner.h
new file mode 100644
index 0000000..3b8a261
--- /dev/null
+++ b/clox/src/scanner.h
@@ -0,0 +1,6 @@
+#ifndef SCANNER_H
+#define SCANNER_H
+
+void initScanner(const char *source);
+
+#endif
diff --git a/clox/src/vm.c b/clox/src/vm.c
index a775acb..d9e5248 100644
--- a/clox/src/vm.c
+++ b/clox/src/vm.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include "common.h"
+#include "compiler.h"
#include "debug.h"
#include "vm.h"
@@ -79,8 +80,7 @@ static InterpretResult run() {
#undef BINARY_OP
}
-InterpretResult interpret(Chunk *chunk) {
- vm.chunk = chunk;
- vm.ip = vm.chunk->code;
- return run();
+InterpretResult interpret(const char *source) {
+ compile(source);
+ return INTERPRET_OK;
}
diff --git a/clox/src/vm.h b/clox/src/vm.h
index 2585bd2..a781647 100644
--- a/clox/src/vm.h
+++ b/clox/src/vm.h
@@ -10,7 +10,7 @@ typedef struct {
Chunk *chunk;
uint8_t *ip;
Value stack[STACK_MAX];
- Value* stackTop;
+ Value *stackTop;
} VM;
typedef enum {
@@ -21,7 +21,7 @@ typedef enum {
void initVM();
void freeVM();
-InterpretResult interpret(Chunk *chunk);
+InterpretResult interpret(const char *source);
void push(Value value);
Value pop();