From 825c98523b8a03733579df33247ab87dae4e3408 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 1 Mar 2020 14:19:31 -0500 Subject: improved command line arguments for compiler (added -no-color) --- decls_cgen.c | 2 +- err.c | 88 ++++++++++++++++++++++++++++++++++++++++++++----- eval.c | 2 +- location.c | 82 --------------------------------------------- main.c | 40 +++++++++++++--------- tests/arr/arr.toc | 4 +-- tests/bf/bf.toc | 6 ++-- tests/params/params.toc | 2 +- toc.c | 1 - 9 files changed, 111 insertions(+), 116 deletions(-) delete mode 100644 location.c diff --git a/decls_cgen.c b/decls_cgen.c index e026584..0192ecf 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -144,7 +144,7 @@ static void cgen_fn_decl(CGenerator *g, FnExpr *f, Type *t) { cgen_ctype(g, &ctypes[0]); } - cgen_write(g, " const (*"); + cgen_write(g, " (* const "); cgen_fn_name(g, f); cgen_write(g, ")("); for (size_t i = 1; i < arr_len(fn_types); ++i) { diff --git a/err.c b/err.c index 0d8c09c..4c81c27 100644 --- a/err.c +++ b/err.c @@ -3,15 +3,6 @@ This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. You should have received a copy of the GNU General Public License along with toc. If not, see . */ -/* #define ERR_EMACS 1 */ - -#ifndef USE_COLORED_TEXT -#if ERR_EMACS -#define USE_COLORED_TEXT 0 -#else -#define USE_COLORED_TEXT 1 -#endif -#endif #define TEXT_ERR_START "\x1b[91m" #define TEXT_ERR_END "\x1b[0m" @@ -23,10 +14,89 @@ #define TEXT_IMPORTANT_START "\x1b[1m" #define TEXT_IMPORTANT_END "\x1b[0m" +#define TEXT_INDICATOR_START "\x1b[96m" +#define TEXT_INDICATOR_END "\x1b[0m" + #if defined(TOC_DEBUG) && __STDC_VERSION__ >= 199901 #define ERR_SHOW_SOURCE_LOCATION 1 #endif + +static void print_pos_highlight(FILE *out, ErrCtx *ctx, File *file, U32 start_pos, U32 end_pos) { + char *str = file->contents; + if (!str) { + return; + } + + char *start = str + start_pos; + char *line_start = start; + char *end = str + end_pos; + + /* go back to last newline / 0 byte */ + while (*line_start != '\0' && *line_start != '\n') --line_start; + if (line_start < start) ++line_start; + + /* skip space at start of line */ + while (isspace(*line_start) && line_start < end) + ++line_start; + + char *line_end = strchr(start, '\n'); + int has_newline = line_end != NULL; + if (!has_newline) + line_end = strchr(start, '\0'); + assert(line_end); + if (!line_start[0]) + fprintf(out, ""); + else { + /* write up to start of error */ + fwrite(line_start, 1, (size_t)(start - line_start), out); + if (ctx->color_enabled) + fprintf(out, TEXT_INDICATOR_START); + if (line_end < end) { + /* write error part (only go to end of line) */ + fwrite(start, 1, (size_t)(line_end - start), out); + if (ctx->color_enabled) + fprintf(out, TEXT_INDICATOR_END); + } else { + /* write error part */ + fwrite(start, 1, (size_t)(end - start), out); + if (ctx->color_enabled) + fprintf(out, TEXT_INDICATOR_END); + /* write rest of line */ + fwrite(end, 1, (size_t)(line_end - end), out); + } + } + fprintf(out, "\n"); +} + +static void print_location_highlight(FILE *out, Location where) { + if (where.start) { + ErrCtx *ctx = where.file->ctx; + print_pos_highlight(out, ctx, where.file, where.start->pos.start, where.end[-1].pos.end); + } + +} + +/* for debugging */ +static void fprint_location(FILE *out, Location location) { + if (location.start) { + fprintf(out, "Line %ld of %s: ", (long)location.start->pos.line, location.file->filename); + } else { + U32 line = location.simple_location.line; + if (line) + fprintf(out, "Line %lu of %s: ", (unsigned long)line, location.file->filename); + else + fprintf(out, "In file %s: ", location.file->filename); + return; + } + print_location_highlight(out, location); +} + +static void print_location(Location location) { + fprint_location(stdout, location); +} + + static inline const char *ordinals(size_t x) { switch (x % 10) { case 1: return "st"; diff --git a/eval.c b/eval.c index 5c687b2..0b73272 100644 --- a/eval.c +++ b/eval.c @@ -688,7 +688,7 @@ static Status eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void if (struct_type->kind == TYPE_STRUCT) { Value struc; if (!eval_expr(ev, dot_expr->binary.lhs, &struc)) - return NULL; + return false; void *struc_data; if (is_ptr) { struc_data = struc.ptr; diff --git a/location.c b/location.c deleted file mode 100644 index 12c932f..0000000 --- a/location.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2019, 2020 Leo Tenenbaum. - This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. - You should have received a copy of the GNU General Public License along with toc. If not, see . -*/ - -#define TEXT_INDICATOR_START "\x1b[96m" -#define TEXT_INDICATOR_END "\x1b[0m" - -static void print_pos_highlight(FILE *out, ErrCtx *ctx, File *file, U32 start_pos, U32 end_pos) { - char *str = file->contents; - if (!str) { - return; - } - - char *start = str + start_pos; - char *line_start = start; - char *end = str + end_pos; - - /* go back to last newline / 0 byte */ - while (*line_start != '\0' && *line_start != '\n') --line_start; - if (line_start < start) ++line_start; - - /* skip space at start of line */ - while (isspace(*line_start) && line_start < end) - ++line_start; - - char *line_end = strchr(start, '\n'); - int has_newline = line_end != NULL; - if (!has_newline) - line_end = strchr(start, '\0'); - assert(line_end); - if (!line_start[0]) - fprintf(out, ""); - else { - /* write up to start of error */ - fwrite(line_start, 1, (size_t)(start - line_start), out); - if (ctx->color_enabled) - fprintf(out, TEXT_INDICATOR_START); - if (line_end < end) { - /* write error part (only go to end of line) */ - fwrite(start, 1, (size_t)(line_end - start), out); - if (ctx->color_enabled) - fprintf(out, TEXT_INDICATOR_END); - } else { - /* write error part */ - fwrite(start, 1, (size_t)(end - start), out); - if (ctx->color_enabled) - fprintf(out, TEXT_INDICATOR_END); - /* write rest of line */ - fwrite(end, 1, (size_t)(line_end - end), out); - } - } - fprintf(out, "\n"); -} - -static void print_location_highlight(FILE *out, Location where) { - if (where.start) { - ErrCtx *ctx = where.file->ctx; - print_pos_highlight(out, ctx, where.file, where.start->pos.start, where.end[-1].pos.end); - } - -} - -/* for debugging */ -static void fprint_location(FILE *out, Location location) { - if (location.start) { - fprintf(out, "Line %ld of %s: ", (long)location.start->pos.line, location.file->filename); - } else { - U32 line = location.simple_location.line; - if (line) - fprintf(out, "Line %lu of %s: ", (unsigned long)line, location.file->filename); - else - fprintf(out, "In file %s: ", location.file->filename); - return; - } - print_location_highlight(out, location); -} - -static void print_location(Location location) { - fprint_location(stdout, location); -} diff --git a/main.c b/main.c index 15bd387..41114a0 100644 --- a/main.c +++ b/main.c @@ -8,13 +8,11 @@ /* TODO: -as #C int -make err_print and tokr_err return Status ---- constants in structs #if -#returns_code (function/struct body is a block, to be evaluated at compile time, which returns the actual statements -- you can use this for implementation of printf) variadic fns +#foreign variadic fns +#returns_code (function/struct body is a block, to be evaluated at compile time, which returns the actual statements -- you can use this for implementation of printf) switch to / add as an alternative: libffi --- @@ -73,27 +71,37 @@ int main(int argc, char **argv) { test_all(); #endif - const char *in_filename; - if (argc < 2) { + const char *in_filename = NULL; + const char *out_filename = "out.c"; + + ErrCtx err_ctx = {0}; + err_ctx.enabled = true; + err_ctx.color_enabled = true; + + for (int i = 1; i < argc; ++i) { + if (i > 1 && strs_equal(argv[i-1], "-o")) { + out_filename = argv[i]; + } else if ((i == 1 || argv[i-1][0] != '-') && argv[i][0] != '-') { + in_filename = argv[i]; + } else if (strs_equal(argv[i], "-no-color")) { + err_ctx.color_enabled = false; + } else { + fprintf(stderr, "Unrecognized option: %s.\n", argv[i]); + return EXIT_FAILURE; + } + } + + if (!in_filename) { #ifdef TOC_DEBUG in_filename = "test.toc"; #else fprintf(stderr, "Please specify an input file.\n"); return EXIT_FAILURE; #endif - } else { - in_filename = argv[1]; - } - const char *out_filename = "out.c"; - for (int i = 2; i < argc-1; ++i) { - if (strs_equal(argv[i], "-o")) - out_filename = argv[i+1]; } + Allocator main_allocr; allocr_create(&main_allocr); - ErrCtx err_ctx = {0}; - err_ctx.enabled = true; - err_ctx.color_enabled = true; File file = {0}; file.filename = in_filename; diff --git a/tests/arr/arr.toc b/tests/arr/arr.toc index a682283..eee514a 100644 --- a/tests/arr/arr.toc +++ b/tests/arr/arr.toc @@ -4,14 +4,14 @@ puti ::= fn(x: int) { extern int printf(const char *fmt, ...); #endif "); - #C("printf(\"%ld\\n\", (long)x)"); + #C("printf(\"%ld\\n\", (long)x);"); }; putf ::= fn(x: float) { #C("#ifndef __TINYC__ extern int printf(const char *fmt, ...); #endif "); - #C("printf(\"%f\\n\", (double)x)"); + #C("printf(\"%f\\n\", (double)x);"); }; // it would be nice if Arr.data.len == Arr.len (: but this will require some C code... diff --git a/tests/bf/bf.toc b/tests/bf/bf.toc index a3f731a..2331467 100644 --- a/tests/bf/bf.toc +++ b/tests/bf/bf.toc @@ -36,11 +36,11 @@ puti ::= fn(x: int) { extern int printf(const char *fmt, ...); #endif "); - #C("printf(\"%ld\\n\", x)"); + #C("printf(\"%ld\\n\", x);"); }; main ::= fn() { - #C("extern int putchar(int c)"); + #C("extern int putchar(int c);"); code := getstdin(); tape_sz := 3; tape := new(int, tape_sz); @@ -102,7 +102,7 @@ main ::= fn() { } } elif code[i] == '.' { c := tape[ptr] as char; - #C("putchar(c)"); + #C("putchar(c);"); } elif code[i] == ',' { // Input doesn't really work, because you // need to send an EOF to end the program. diff --git a/tests/params/params.toc b/tests/params/params.toc index 1946739..4d37cf1 100644 --- a/tests/params/params.toc +++ b/tests/params/params.toc @@ -11,7 +11,7 @@ puti ::= fn(x: int) { extern int printf(const char *fmt, ...); #endif "); - #C("printf(\"%ld\\n\", x)"); + #C("printf(\"%ld\\n\", x);"); }; diff --git a/toc.c b/toc.c index 4033181..0c15be9 100644 --- a/toc.c +++ b/toc.c @@ -124,7 +124,6 @@ static inline bool type_is_slicechar(Type *t) { #include "allocator.c" #include "misc.c" #include "data_structures.c" -#include "location.c" #include "err.c" static size_t compiler_alignof(Type *t); static size_t compiler_sizeof(Type *t); -- cgit v1.2.3