Chapter 16.1
This commit is contained in:
parent
9b60cf334c
commit
b131e343bb
8 changed files with 114 additions and 30 deletions
|
@ -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)
|
||||
|
|
7
clox/src/compiler.c
Normal file
7
clox/src/compiler.c
Normal 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
6
clox/src/compiler.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef COMPILER_H
|
||||
#define COMPILER_H
|
||||
|
||||
void compile(const char *source);
|
||||
|
||||
#endif
|
|
@ -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"
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
19
clox/src/scanner.c
Normal file
19
clox/src/scanner.c
Normal 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
6
clox/src/scanner.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef SCANNER_H
|
||||
#define SCANNER_H
|
||||
|
||||
void initScanner(const char *source);
|
||||
|
||||
#endif
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue