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