]> pd.if.org Git - lice/blobdiff - lice.c
autocommit for files dated 2014-11-17 20:13:30
[lice] / lice.c
diff --git a/lice.c b/lice.c
new file mode 100644 (file)
index 0000000..3710307
--- /dev/null
+++ b/lice.c
@@ -0,0 +1,127 @@
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <getopt.h>
+
+#include "lexer.h"
+#include "parse.h"
+#include "gen.h"
+#include "opt.h"
+
+bool compile_warning = true;
+
+static void compile_diagnostic(const char *type, const char *fmt, va_list va) {
+    fprintf(stderr, "%s %s: ", lexer_marker(), type);
+    vfprintf(stderr, fmt, va);
+    fprintf(stderr, "\n");
+}
+
+void compile_error(const char *fmt, ...) {
+    va_list  a;
+    va_start(a, fmt);
+    compile_diagnostic("error", fmt, a);
+    va_end(a);
+    exit(EXIT_FAILURE);
+}
+
+void compile_warn(const char *fmt, ...) {
+    if (!compile_warning)
+        return;
+
+    va_list a;
+    va_start(a, fmt);
+    compile_diagnostic("warning", fmt, a);
+    va_end(a);
+}
+
+void compile_ice(const char *fmt, ...) {
+    va_list a;
+    va_start(a, fmt);
+    compile_diagnostic("internal error", fmt, a);
+    va_end(a);
+
+    /* flush all streams */
+    fflush(NULL);
+    abort();
+}
+
+int compile_begin(bool dump) {
+    parse_init();
+
+    list_t *block = parse_run();
+    size_t  index = 0;
+
+    for (list_iterator_t *it = list_iterator(block); !list_iterator_end(it); index++) {
+        printf("# block %zu\n", index);
+        if (!dump) {
+            gen_toplevel(list_iterator_next(it));
+        } else {
+            printf("%s", ast_string(list_iterator_next(it)));
+        }
+    }
+    return true;
+}
+
+static bool parse_option(const char *optname, int *cargc, char ***cargv, char **out, int ds, bool split) {
+    int    argc = *cargc;
+    char **argv = *cargv;
+    size_t len  = strlen(optname);
+
+    if (strncmp(argv[0]+ds, optname, len))
+        return false;
+
+    /* it's --optname, check how the parameter is supplied */
+    if (argv[0][ds+len] == '=') {
+        *out = argv[0]+ds+len+1;
+        return true;
+    }
+
+    if (!split || argc < ds) /* no parameter was provided, or only single-arg form accepted */
+        return false;
+
+    /* using --opt param */
+    *out = argv[1];
+    --*cargc;
+    ++*cargv;
+
+    return true;
+}
+
+int main(int argc, char **argv) {
+    bool  dumpast  = false;
+    char *standard = NULL;
+
+    while (argc > 1) {
+        ++argv;
+        --argc;
+
+        if (argv[0][0] == '-') {
+            if (parse_option("std", &argc, &argv, &standard, 1, false))
+                continue;
+        }
+
+        if (!strcmp(*argv, "--dump-ast")) {
+            dumpast = true;
+            continue;
+        }
+
+        fprintf(stderr, "unknown option: %s\n", argv[argc-1]);
+        return EXIT_FAILURE;
+    }
+
+    if (standard) {
+        if      (!strcmp(standard, "licec")) opt_std_set(STANDARD_LICEC);
+        else if (!strcmp(standard, "gnuc"))  opt_std_set(STANDARD_GNUC);
+        else if (!strcmp(standard, "c90"))   opt_std_set(STANDARD_C90);
+        else if (!strcmp(standard, "c99"))   opt_std_set(STANDARD_C99);
+        else if (!strcmp(standard, "c11"))   opt_std_set(STANDARD_C11);
+        else if (!strcmp(standard, "kandr")) opt_std_set(STANDARD_KANDR);
+        else {
+            fprintf(stderr, "unknown standard: %s\n", standard);
+            return EXIT_FAILURE;
+        }
+    }
+
+    return compile_begin(dumpast);
+}