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 + +#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 +#include +#include + #include "chunk.h" #include "common.h" #include "debug.h" #include "vm.h" +static void repl() { + char line[1024]; + for (;;) { + printf("> "); + + if (!fgets(line, sizeof(line), stdin)) { + printf("\n"); + break; + } + + interpret(line); + } +} + +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); + } + + fseek(file, 0L, SEEK_END); + size_t fileSize = ftell(file); + rewind(file); + + char *buffer = (char *)malloc(fileSize + 1); + if (buffer == NULL) { + fprintf(stderr, "Not enough memory to read \"%s\".\n", path); + exit(74); + } + + 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(); - Chunk chunk; - initChunk(&chunk); + if (argc == 1) { + repl(); + } else if (argc = 2) { + runFile(argv[1]); + } else { + fprintf(stderr, "Usage: clox [path]\n"); + exit(64); + } - int constant = addConstant(&chunk, 1.2); - writeChunk(&chunk, OP_CONSTANT, 123); - writeChunk(&chunk, constant, 123); - - constant = addConstant(&chunk, 3.4); - writeChunk(&chunk, OP_CONSTANT, 123); - writeChunk(&chunk, constant, 123); - - writeChunk(&chunk, OP_ADD, 123); - - constant = addConstant(&chunk, 5.6); - writeChunk(&chunk, OP_CONSTANT, 123); - writeChunk(&chunk, constant, 123); - - writeChunk(&chunk, OP_DIVIDE, 123); - writeChunk(&chunk, OP_NEGATE, 123); - - writeChunk(&chunk, OP_RETURN, 123); - - 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 +#include + +#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 #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();