-
Notifications
You must be signed in to change notification settings - Fork 0
/
assembler.c
114 lines (97 loc) · 3.05 KB
/
assembler.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 "assembler.h"
/* Append suffixes to paths */
char *assembly_path(char *file_name) {
return concatenate(file_name, ".as");
}
char *expanded_assembly_path(char *file_name) {
return concatenate(file_name, ".am");
}
char *object_path(char *file_name) {
return concatenate(file_name, ".ob");
}
char *entries_path(char *file_name) {
return concatenate(file_name, ".ent");
}
char *externals_path(char *file_name) {
return concatenate(file_name, ".ext");
}
/* On given path, run pre assembly, first pass, and second pass.
* After processing, export derived data to files.
*/
bool process_file(char *path) {
bool success;
char *path_container;
FILE *source_file, *expanded_source_file, *object_file;
FILE *entries_file, *externals_file;
path_container = assembly_path(path);
source_file = fopen(path_container, "r");
free(path_container);
if (source_file == NULL) {
printf("Failed to open file: %s. Skipping.\n", path);
return false;
}
path_container = expanded_assembly_path(path);
expanded_source_file = fopen(path_container, "w");
success = pre_assembly(source_file, expanded_source_file);
fclose(source_file);
fclose(expanded_source_file);
if (!success) {
remove(path_container);
free(path_container);
return false;
}
free(path_container);
path_container = expanded_assembly_path(path);
expanded_source_file = fopen(path_container, "r");
success = first_pass(expanded_source_file);
fclose(expanded_source_file);
free(path_container);
if (!success) {
return false;
}
path_container = expanded_assembly_path(path);
expanded_source_file = fopen(path_container, "r");
success = second_pass(expanded_source_file);
fclose(expanded_source_file);
free(path_container);
if (!success) {
return false;
}
path_container = object_path(path);
object_file = fopen(path_container, "w");
write_image_output(object_file);
fclose(object_file);
free(path_container);
if (entry_symbols_exist()) {
path_container = entries_path(path);
entries_file = fopen(path_container, "w");
write_entry_symbols(entries_file);
fclose(entries_file);
free(path_container);
}
if (external_symbols_exist()) {
path_container = externals_path(path);
externals_file = fopen(path_container, "w");
write_external_symbols(externals_file);
fclose(externals_file);
free(path_container);
}
return true;
}
/* Process all files provided in arguments. Clean up after each file. */
int main(int argc, char *argv[]) {
int index;
int success = SUCCESS;
int file_count = argc - 1;
char **file_names = argv + 1;
/* Go over all provided files */
for (index = 0; index < file_count; index++) {
printf("Processing: %s\n", file_names[index]);
if (!process_file(file_names[index])) {
success = FAILURE;
}
clear_symbols();
clear_images();
}
return success;
}