Chapter 16.1

This commit is contained in:
Tom Willemse 2021-08-02 18:09:03 -07:00
parent 9b60cf334c
commit b131e343bb
Signed by: ryuslash
GPG key ID: 7D5C407B435025C1
8 changed files with 114 additions and 30 deletions

View file

@ -10,6 +10,10 @@ add_executable(Lox
value.c value.c
vm.h vm.h
vm.c vm.c
compiler.h
compiler.c
scanner.h
scanner.c
main.c) main.c)
install(TARGETS Lox) install(TARGETS Lox)

7
clox/src/compiler.c Normal file
View file

@ -0,0 +1,7 @@
#include <stdio.h>
#include "common.h"
#include "compiler.h"
#include "scanner.h"
void compile(const char *source) { initScanner(source); }

6
clox/src/compiler.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef COMPILER_H
#define COMPILER_H
void compile(const char *source);
#endif

View file

@ -1,36 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chunk.h" #include "chunk.h"
#include "common.h" #include "common.h"
#include "debug.h" #include "debug.h"
#include "vm.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[]) { int main(int argc, const char *argv[]) {
initVM(); initVM();
Chunk chunk; if (argc == 1) {
initChunk(&chunk); 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(); freeVM();
freeChunk(&chunk);
return 0; return 0;
} }

19
clox/src/scanner.c Normal file
View file

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

6
clox/src/scanner.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef SCANNER_H
#define SCANNER_H
void initScanner(const char *source);
#endif

View file

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include "common.h" #include "common.h"
#include "compiler.h"
#include "debug.h" #include "debug.h"
#include "vm.h" #include "vm.h"
@ -79,8 +80,7 @@ static InterpretResult run() {
#undef BINARY_OP #undef BINARY_OP
} }
InterpretResult interpret(Chunk *chunk) { InterpretResult interpret(const char *source) {
vm.chunk = chunk; compile(source);
vm.ip = vm.chunk->code; return INTERPRET_OK;
return run();
} }

View file

@ -10,7 +10,7 @@ typedef struct {
Chunk *chunk; Chunk *chunk;
uint8_t *ip; uint8_t *ip;
Value stack[STACK_MAX]; Value stack[STACK_MAX];
Value* stackTop; Value *stackTop;
} VM; } VM;
typedef enum { typedef enum {
@ -21,7 +21,7 @@ typedef enum {
void initVM(); void initVM();
void freeVM(); void freeVM();
InterpretResult interpret(Chunk *chunk); InterpretResult interpret(const char *source);
void push(Value value); void push(Value value);
Value pop(); Value pop();