add a basm code generator
[bosc.git] / src / main.cpp
blobc2426f151e284fa0d29d887c87a2efc3d4a03f14
1 #include <cstdio>
2 #include <cstdlib>
4 #include <stdexcept>
6 #include "ast.h"
7 #include "logging.h"
8 #include "compiler.h"
9 #include "codegen_basm.h"
12 using namespace std;
14 extern "C"
16 int yyparse(void);
17 int yylex(void);
18 int yyparse(void);
19 int yyerror(const char*);
20 extern FILE* yyin;
23 extern Block *root;
25 static char _filename_to_del[PATH_MAX];
26 void kill_at_exit(void)
28 unlink(_filename_to_del);
31 /// Preprocess a file and return a pointer to the preprocessed data
32 FILE* preprocess_file(const char* filename)
34 char tmp[L_tmpnam+1];
35 char *ptr;
36 char cmdline[L_tmpnam+strlen(filename)+16];
37 char tmp2[PATH_MAX];
39 ptr = tmpnam(tmp);
40 if (!ptr)
41 throw runtime_error("unable to allocate temporary file");
42 if (getenv("TEMP")) {
43 strcpy(tmp2, getenv("TEMP"));
44 strcat(tmp2, ptr);
45 ptr = tmp2;
47 sprintf(cmdline, "cpp \"%s\" -o \"%s\"", filename, ptr);
48 LOG("running cpp: %s\n", cmdline);
49 if (system(cmdline) != 0)
50 throw runtime_error("unable to call cpp");
51 strcpy(_filename_to_del, ptr);
52 atexit(kill_at_exit);
53 return fopen(ptr, "r");
56 int main(int argc, char** argv)
58 try {
59 if (argc > 2)
60 throw runtime_error("bad command line, usage: bosc <filename>");
61 else if (argc == 2) {
62 if (strcmp("--", argv[1]) == 0)
63 yyin = stdin;
64 else {
65 FILE* test = fopen(argv[1], "r");
66 if (test) fclose(test);
67 else throw runtime_error("cannot open input file");
68 yyin = preprocess_file(argv[1]);
69 if (!yyin)
70 throw runtime_error("cannot run cpp");
73 else
74 yyin = stdin;
75 } catch(const runtime_error& e) {
76 fprintf(stderr, "runtime error: %s\n", e.what());
77 fclose(yyin);
78 return 1;
80 int retval = yyparse();
81 fclose(yyin);
82 simplify_ast(root);
83 constant_expression_optimization(root);
84 if (!tree_check_parents(root)) {
85 EPRINTF("internal error: AST check failed\n");
86 printf("%s", root->toString().c_str());
87 return 255;
89 parse_info pi;
90 validate_tree(pi, root);
91 check_parse_results(pi);
92 if (pi.errors != 0) {
93 EPRINTF("%d error(s), compilation aborted\n", pi.errors);
94 return 1;
96 printf("%s", root->toString().c_str());
98 CodeGeneratorBasm codegen(pi);
99 codegen.init();
100 codegen.emitAST(root);
101 printf("<!--\n%s\n-->", codegen.getCode().c_str());
102 return retval;