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
|
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
typedef void* yyscan_t;
#include "ast.h"
#include "code-generation.h"
#include "common.h"
#include "draw.h"
#include "semantic-analysis.h"
#include "state.h"
#include "parser.h"
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int ccmmc_parser_lex_init_extra(void *extra, yyscan_t *scanner);
extern int ccmmc_parser_lex_destroy(yyscan_t *scanner);
extern int ccmmc_parser_set_in(FILE *source_handle, yyscan_t scanner);
const char *ccmmc_main_name;
int main (int argc, char **argv)
{
ERR_DECL;
setlocale (LC_ALL, "");
prog_name = strrchr (argv[0], '/');
prog_name = prog_name == NULL ? prog_name : prog_name + 1;
if (argc != 2) {
fprintf(stderr, "Usage: %s SOURCE\n", prog_name);
exit(1);
}
// Workaround a clang bug: https://llvm.org/bugs/show_bug.cgi?id=20144
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Warray-bounds"
#endif
const char *source_name = argv[1];
FILE *source_handle =
strcmp(source_name, "-") == 0 ? stdin : fopen(source_name, "r");
#ifdef __clang__
# pragma clang diagnostic pop
#endif
if (source_handle == NULL) {
fprintf(stderr, "%s: %s: %s\n", prog_name, source_name, ERR_MSG);
exit(1);
}
CcmmcState state_struct;
CcmmcState *state = &state_struct;
ccmmc_state_init(state);
yyscan_t scanner;
ccmmc_parser_lex_init_extra(state, &scanner);
ccmmc_parser_set_in(source_handle, scanner);
switch (ccmmc_parser_parse(scanner, state)) {
case 1:
fprintf(stderr, "%s: failed because of invalid input\n", prog_name);
exit(1);
case 2:
fprintf(stderr, "%s: failed because of memory exhaustion\n", prog_name);
exit(1);
default:
; // silence warnings
}
ccmmc_parser_lex_destroy(scanner);
// Dump the AST
const char *dump_ast = getenv("CCMMC_DUMP_AST");
if (dump_ast != NULL && *dump_ast != '\0')
ccmmc_draw_ast(stdout, source_name, state->ast);
CcmmcSymbolTable table_struct;
state->table = &table_struct;
ccmmc_symbol_table_init(state->table);
bool check_succeeded = ccmmc_semantic_check(state->ast, state->table);
const char *dump_symbol = getenv("CCMMC_DUMP_SYMBOL");
if (dump_symbol != NULL && *dump_symbol != '\0') {
CcmmcSymbolScope *scope = state->table->all;
for (unsigned int i = 0; scope != NULL; scope = scope->all_next, i++) {
if (i == 0)
puts(" * Global Scope *");
else
printf(" * Scope %u *\n", i);
ccmmc_draw_symbol_scope(stdout, scope);
}
}
const char *dump_ast_after = getenv("CCMMC_DUMP_AST_AFTER");
if (dump_ast_after != NULL && *dump_ast_after != '\0')
ccmmc_draw_ast(stdout, source_name, state->ast);
if (check_succeeded)
puts("Parsing completed. No errors found.");
else
exit(1);
state->asm_output = fopen("output.s", "w");
if (state->asm_output == NULL) {
fprintf(stderr, "%s: output.s: %s\n", prog_name, ERR_MSG);
exit(1);
}
ccmmc_code_generation(state);
ccmmc_state_fini(state);
fclose(source_handle);
return 0;
}
// vim: set sw=4 ts=4 sts=4 et:
|