From 027342ba3c2bb717944ca45565de9d7b8dd5aa10 Mon Sep 17 00:00:00 2001 From: Clemens Paumgarten <clemenspaumgarten@gmail.com> Date: Fri, 7 Jun 2019 11:42:40 +0200 Subject: [PATCH] Add semantic check and options to mcc file --- CMakeLists.txt | 2 +- app/mc_symbol_table.c | 9 +--- app/mc_type_check_trace.c | 3 -- app/mcc.c | 98 ++++++++++++++++++++++++++++++--------- include/mcc/mcc.h | 10 ++++ include/mcc/printer.h | 2 +- src/utils/printer.c | 20 ++++++-- 7 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 include/mcc/mcc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d6da10..6cb0552 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,4 +49,4 @@ add_executable(mcc src/utils/mcc_scope.c include/mcc/mcc_scope.h src/utils/dynamic_array.c - include/mcc/dynamic_array.h) + include/mcc/dynamic_array.h include/mcc/mcc.h) diff --git a/app/mc_symbol_table.c b/app/mc_symbol_table.c index c94ded4..eaa77e5 100644 --- a/app/mc_symbol_table.c +++ b/app/mc_symbol_table.c @@ -12,11 +12,6 @@ #include "mcc/printer.h" #include "mcc/mcc_scope.h" -void print_usage(const char *prg) { - printf("usage: %s <FILE>\n\n", prg); - printf(" <FILE> Input filepath or - for stdin\n"); -} - int main(int argc, char *argv[]) { char* symbol_scope = "program"; FILE* out = stdout; @@ -114,8 +109,8 @@ int main(int argc, char *argv[]) { } mcc_symbol_table_print(symbol_table,out); -// mcc_symbol_table_delete_table(symbol_table); - mcc_symbol_table_delete_error_collector(ec); + mcc_symbol_table_delete_table(symbol_table); + mcc_symbol_table_delete_error_collector(ec); mcc_ast_delete(prog); return EXIT_SUCCESS; diff --git a/app/mc_type_check_trace.c b/app/mc_type_check_trace.c index 0eab4a4..90c96b9 100644 --- a/app/mc_type_check_trace.c +++ b/app/mc_type_check_trace.c @@ -4,7 +4,6 @@ #include <getopt.h> #include <ctype.h> -#include "mcc/dynamic_array.h" #include "mcc/ast.h" #include "mcc/parser.h" #include "mcc/symbol_table.h" @@ -14,7 +13,6 @@ #include "mcc/mcc_scope.h" int main(int argc, char *argv[]) { - char* symbol_scope = "program"; FILE* out = stdout; @@ -54,7 +52,6 @@ int main(int argc, char *argv[]) { } } - // get input src char *input = NULL; if (optind < argc) { diff --git a/app/mcc.c b/app/mcc.c index 6dd2e2e..c0158c1 100644 --- a/app/mcc.c +++ b/app/mcc.c @@ -1,56 +1,110 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <getopt.h> +#include <ctype.h> +#include "mcc/mcc.h" #include "mcc/ast.h" #include "mcc/parser.h" +#include "mcc/symbol_table.h" +#include "mcc/symbol_table_parse.h" +#include "mcc/symbol_table_print.h" +#include "mcc/printer.h" +#include "mcc/mcc_scope.h" -void print_usage(const char *prg) -{ - printf("\n\nusage: %s [OPTIONS] file...s\n\n", prg); - printf("The mC compiler. It takes mC input files and produces an executable.\n\n"); - printf("<FILE> Input filepath or - for stdin\n\n"); -} - +int main(int argc, char *argv[]) { + FILE* out = stdout; -int main(int argc, char *argv[]) -{ if (argc < 2) { - print_usage(argv[0]); + mcc_print_usage(argv[0]); + return EXIT_FAILURE; + } + + int c; + static struct option options[] = { + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'v' }, + { "q", no_argument, 0, 'q' }, + { "output", required_argument, 0, 'o' }, + { 0, 0, 0, 0 } + }; + while ((c = getopt_long(argc, argv, "hfvq:o:", options, NULL)) != -1) { + switch(c) { + case 'h': + mcc_symbol_table_print_usage(argv[0]); + return EXIT_SUCCESS; + case 'v': + printf("%f\n", VERSION); + return EXIT_SUCCESS; + case 'q': + printf("Not implemented yet \n"); + return EXIT_SUCCESS; + case 'o': + out = fopen(optarg, "rw"); + break; + case '?': + if(isprint(optopt)) + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf(stderr, + "Unknown option character `\\x%x'.\n", + optopt); + return 1; + default: + abort(); + } + } + + // get input src + char *input = NULL; + if (optind < argc) { + input = argv[optind]; + } else { + fprintf(stderr, "%s: Missing input!\n", argv[0]); + mcc_symbol_table_print_usage(argv[0]); return EXIT_FAILURE; } - // determine input source FILE *in; - if (strcmp("-", argv[1]) == 0) { + if (strcmp("-", input) == 0) { in = stdin; } else { - in = fopen(argv[1], "r"); + in = fopen(input, "r"); if (!in) { perror("fopen"); return EXIT_FAILURE; } } - struct mcc_ast_program *prog = NULL; - // parsing phase + struct mcc_ast_program *prog = NULL; { struct mcc_parser_result result = mcc_parse_file(in); - fclose(in); if (result.status != MCC_PARSER_STATUS_OK) { - printf("NOT OK"); + // print error message + printf("%s", result.parser_error -> error_msg); + return EXIT_FAILURE; } prog = result.program; } - // TODO: - // - run semantic checks - { - + // create symbol table + struct mcc_symbol_table_error_collector *ec = mcc_symbol_table_new_error_collector(); + struct mcc_symbol_table *symbol_table; + + // check if scope should be limited + symbol_table = mcc_symbol_table_build(prog, ec); + + if (symbol_table == NULL) { + mcc_symbol_table_print_error(ec, out); + + return EXIT_FAILURE; } + mcc_symbol_table_delete_table(symbol_table); + mcc_symbol_table_delete_error_collector(ec); // - create three-address code // - output assembly code @@ -59,5 +113,7 @@ int main(int argc, char *argv[]) // cleanup mcc_ast_delete_program(prog); + printf("Compiled successfully \n"); + return EXIT_SUCCESS; } diff --git a/include/mcc/mcc.h b/include/mcc/mcc.h new file mode 100644 index 0000000..ee4c3bc --- /dev/null +++ b/include/mcc/mcc.h @@ -0,0 +1,10 @@ +// +// Created by Clemens Paumgarten on 07.06.19. +// + +#ifndef MCC_MCC_H +#define MCC_MCC_H + +#define VERSION 0.1 + +#endif //MCC_MCC_H diff --git a/include/mcc/printer.h b/include/mcc/printer.h index 9c07ca8..715d587 100644 --- a/include/mcc/printer.h +++ b/include/mcc/printer.h @@ -1,7 +1,7 @@ #ifndef MCC_PRINTER_H #define MCC_PRINTER_H -#include <stdio.h> +void mcc_print_usage(const char *prg); void mcc_ast_to_dot_print_usage(const char *prg); diff --git a/src/utils/printer.c b/src/utils/printer.c index e158800..cd8cd94 100644 --- a/src/utils/printer.c +++ b/src/utils/printer.c @@ -1,5 +1,19 @@ +#include <stdio.h> #include "mcc/printer.h" +void mcc_print_usage(const char *prg) { + printf("\n\nusage: %s [OPTIONS] file...\n\n", prg); + printf("The mC compiler. It takes mC input files and produces an executable.\n"); + printf("Use '-' as input file to read from stdin\n\n"); + printf("OPTIONS:\n"); + printf(" -h, --help displays this help message\n"); + printf(" -v, --help displays the version number\n"); + printf(" -q, --help suppress error output (not implemented yet)\n"); + printf(" -o, --output <file> write the output to <file> (defaults to stdout)\n"); + printf("Environment variables: \n"); + printf("MCC_BACKEND override the back-end compiler (defaults to 'gcc' in PATH) (not implemented yet)\n"); +} + void mcc_ast_to_dot_print_usage(const char *prg) { printf("\n\nusage: %s [OPTIONS] file...\n\n", prg); @@ -7,7 +21,7 @@ void mcc_ast_to_dot_print_usage(const char *prg) "can be visualised using graphviz. Errors are reported on invalid inputs.\n\n"); printf("Use '-' as input file to read from stdin\n\n"); printf("OPTIONS:\n"); - printf(" -h, --help displays this help message:\n"); + printf(" -h, --help displays this help message\n"); printf(" -o, --output <file> write the output to <file> (defaults to stdout)\n"); printf(" -f, --function <name> limit scope to the given function\n"); } @@ -19,7 +33,7 @@ void mcc_symbol_table_print_usage(const char *prg) "invalid inputs.\n\n"); printf("Use '-' as input file to read from stdin.\n\n"); printf("OPTIONS:\n"); - printf(" -h, --help displays this help message:\n"); + printf(" -h, --help displays this help message\n"); printf(" -o, --output <file> write the output to <file> (defaults to stdout)\n"); printf(" -f, --function <name> limit scope to the given function\n"); } @@ -31,7 +45,7 @@ void mcc_symbol_table_type_trace_usage(const char *prg) "invalid inputs.\n\n"); printf("Use '-' as input file to read from stdin.\n\n"); printf("OPTIONS:\n"); - printf(" -h, --help displays this help message:\n"); + printf(" -h, --help displays this help message\n"); printf(" -o, --output <file> write the output to <file> (defaults to stdout)\n"); printf(" -f, --function <name> limit scope to the given function\n"); } -- GitLab