X-Git-Url: https://pd.if.org/git/?p=lice;a=blobdiff_plain;f=lice.c;fp=lice.c;h=3710307558ca3dbad6250e8647fcb63616a2490d;hp=0000000000000000000000000000000000000000;hb=686688990cde8ecd8d9423fde7f88b6ac6ac8a40;hpb=e8938573442eb3f5f550420ff3a0eb703730c1a3 diff --git a/lice.c b/lice.c new file mode 100644 index 0000000..3710307 --- /dev/null +++ b/lice.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include + +#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); +}