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
|
import "std/file.cup"
// FIXME: The order of the following lines is important.
// Perhaps have multiple passes?
import "compiler/builtins.cup"
import "compiler/parser.cup"
import "compiler/codegen.cup"
fn print_usage_and_exit(name: char*, status: int) {
puts("Usage: "); puts(name); putsln(" [options] <file>");
putsln("Options:");
putsln(" -c <code> Code to compile");
putsln(" -h Show this help");
putsln(" -o <file> Output file");
putsln(" -d Dump AST to stdout");
putsln("Output file will be named 'build/host.nasm' by default");
exit(status);
}
// FIXME: Allow variables functions to be static to a file?
// we can avoid the prefixes then.
const MAX_STDIN_SOURCE_LEN = 4096;
let m_filename: char*;
let m_outut_filename = "build/host.nasm";
let m_source: char*;
let m_source_len = 0;
let m_dump_ast = false;
fn parse_cli_args(argc: int, argv: char**) {
for (let i = 1; i < argc; ++i) {
if (streq(argv[i], "-c")) {
m_source_len = strlen(argv[i+1]);
m_source = argv[i+1];
++i;
m_filename = "CLI";
} else if (streq(argv[i], "-h")) {
print_usage_and_exit(argv[0], 0);
} else if (streq(argv[i], "-d")) {
m_dump_ast = true;
} else if (streq(argv[i], "-o")) {
++i;
m_outut_filename = argv[i];
} else if (m_filename == null) {
if (streq(argv[i], "-")) {
m_filename = "stdin";
m_source = malloc(MAX_STDIN_SOURCE_LEN);
m_source_len = read(0, m_source, MAX_STDIN_SOURCE_LEN);
m_source[m_source_len] = 0;
if (m_source_len == MAX_STDIN_SOURCE_LEN) {
putsln("Source too long to use through stdin");
exit(1);
}
} else {
m_filename = argv[i];
let file = fopen(m_filename, 'r');
m_source = fread_to_string(file, &m_source_len);
fclose(file);
}
} else {
print_usage_and_exit(argv[0], 1);
}
}
if (m_filename == null) {
print_usage_and_exit(argv[0], 1);
}
}
fn main(argc: int, argv: char **): int {
parse_cli_args(argc, argv);
let lexer = lexer_new(m_filename, m_source, m_source_len);
let ast = parse_program(lexer);
if (m_dump_ast)
dump_ast(ast, 0);
let out_file = fopen(m_outut_filename, 'w');
generate_program(ast, out_file);
fclose(out_file); // TODO: Defer on self-host
// puts("---------------------------\n");
// puts("Total amount of memory used by malloc: ");
// putu(__malloc_buf_pos);
// putsln("\nDone.");
}
|