-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoc.cc
172 lines (151 loc) · 4.34 KB
/
oc.cc
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "astree.h"
#include "treeutils.h"
#include "auxlib.h"
#include "lyutils.h"
#include "stringset.h"
#include "symtable.h"
#include "typetable.h"
#include "codeutils.h"
string CPP = "/usr/bin/cpp";
string yyin_cpp_command;
const size_t LINESIZE = 1024;
const string OPT_STRING = "-lyD:@:";
int option;
int file_arg_i = 0;
extern int scan_linenr;
extern int scan_offset;
extern vector<string> included_filenames;
FILE* tok_file = NULL;
// Open a pipe from the C preprocessor.
// Exit failure if can't.
// Assignes opened pipe to FILE* yyin.
void yyin_cpp_popen (const char* filename) {
yyin_cpp_command = CPP + " " + filename;
yyin = popen (yyin_cpp_command.c_str(), "r");
if (yyin == NULL) {
syserrprintf (yyin_cpp_command.c_str());
exit (get_exitstatus());
}
}
void yyin_cpp_pclose (void) {
int pclose_rc = pclose (yyin);
if (pclose_rc != 0) set_exitstatus (EXIT_FAILURE);
}
int main (int argc, char** argv) {
set_execname (argv[0]);
yy_flex_debug = 0;
yydebug = 0;
// Scan options
while ( (option = getopt(argc, argv, OPT_STRING.c_str())) != -1 ) {
switch(option) {
case '?':
fprintf(stderr,
"Usage: oc [-ly] [-@ flag] [-D string] program.oc\n");
set_exitstatus(1);
return get_exitstatus();
break;
case 'l':
yy_flex_debug = 1;
break;
case 'y':
yydebug = 1;
break;
case 'D':
CPP += " -D" + string(optarg);
break;
case '@':
set_debugflags(optarg);
break;
case 1:
// Set the index of the program file
if (file_arg_i) {
// This is run if more than 1 file is passed.
fprintf(stderr,
"Usage: oc [-ly] [-@ flag] [-D string] program.oc\n");
set_exitstatus(1);
return get_exitstatus();
}
file_arg_i = optind-1;
break;
}
}
// Check that a file was passed to oc.
if (!file_arg_i) {
fprintf(stderr,
"Usage: oc [-ly] [-@ flag] [-D string] program.oc\n");
set_exitstatus(1);
return get_exitstatus();
}
char* filename = argv[file_arg_i];
char* filebase = basename(filename);
char* ext = strchr(filebase, '.');
// If there is no period in the filename.
if (ext == NULL) {
fprintf(stderr, "Error: oc accepts .oc files only \n");
set_exitstatus(1);
return get_exitstatus();
}
char* program_name = strndup(filebase, ext-filebase);
// Remove all trailing slashes
for (int i = strlen(ext+1); i > 0; i--) {
if (ext[i] == '/') {
ext[i] = '\0';
} else {
break;
}
}
// Check file extension
if (strcmp(ext+1, "oc")) {
fprintf(stderr, "Error: oc accepts .oc files only \n");
set_exitstatus(1);
return get_exitstatus();
}
// Open up the output files.
// str
string str_path = string(program_name) + ".str";
FILE* str_file = fopen(str_path.c_str(), "w");
// tok
str_path = string(program_name) + ".tok";
tok_file = fopen(str_path.c_str(), "w");
// ast
str_path = string(program_name) + ".ast";
FILE* ast_file = fopen(str_path.c_str(), "w");
// sym
str_path = string(program_name) + ".sym";
FILE* sym_file = fopen(str_path.c_str(), "w");
// oil
str_path = string(program_name) + ".oil";
FILE* oil_file = fopen(str_path.c_str(), "w");
yyin_cpp_popen(filename);
yyparse();
yyin_cpp_pclose();
build_table_traversal(yyparse_astree);
type_check_traversal(yyparse_astree);
if (!get_exitstatus()) {
run_code_gen(yyparse_astree, oil_file);
fclose(oil_file);
string call = "gcc -g -o " + string(program_name) + " -x c " + string(program_name) + ".oil oclib.c";
system(call.c_str());
}
dump_astree(ast_file, yyparse_astree);
fclose(ast_file);
global_table->dump(sym_file, 0);
fclose(sym_file);
DEBUGSTMT ('s', dump_stringset (stderr););
yylex_destroy();
fclose(tok_file);
// Dump the stringset
dump_stringset (str_file);
fclose(str_file);
return get_exitstatus();
}