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
|
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
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 "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
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 <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();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue