-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
114 lines (92 loc) · 2.7 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "h/chunk.h"
#include "h/vm.h"
#include "h/compiler.h"
#include "h/binary.h"
static void repl() {
while (true) {
char line[1024];
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);
const 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);
}
const 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 int runFile(const char* path) {
char* source = readFile(path);
const InterpretResult result = interpret(source);
free(source);
switch (result) {
case INTERPRET_OK: return 0;
case INTERPRET_EXIT: return vm.exit_code;
case INTERPRET_COMPILE_ERROR: return 65;
case INTERPRET_RUNTIME_ERROR: return 70;
}
return 0;
}
static int runBinaryFile(const char* path) {
ObjFunction* compiled = loadBinary(path);
const InterpretResult result = interpretCompiled(compiled);
switch (result) {
case INTERPRET_EXIT: return vm.exit_code;
case INTERPRET_RUNTIME_ERROR: return 70;
default: return 0;
}
}
static int compileFile(const char* src_path, const char* dest_path) {
char* source = readFile(src_path);
ObjFunction* code = compile(source);
free(source);
if (code == NULL) return INTERPRET_COMPILE_ERROR;
writeBinary(code, dest_path);
return 0;
}
int main(const int argc, char* argv[]) {
int exitCode = 0;
const clock_t start = clock();
initVM();
if (argc == 1) {
repl();
} else if (argc == 2) {
exitCode = runFile(argv[1]);
} else if (argc == 3 && !strcmp(argv[2], "--bin")) {
exitCode = runBinaryFile(argv[1]);
} else if (argc == 4 && !strcmp(argv[2], "--save")) {
exitCode = compileFile(argv[1], argv[3]);
} else {
exitCode = 65;
fprintf(stderr, "Usage: clox [path] | [src_path --save dest_path] | [--bin bin_path]\n");
}
const clock_t end = clock();
printf("Execution time: %.6f seconds\n", ((float) (end - start)) / CLOCKS_PER_SEC);
freeVM();
exit(exitCode);
}