Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bang/nobuild.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
PATH("..", "basm", "src", "verifier.c")
#define BANG_UNITS PATH("src", "bang_compiler.c"), \
PATH("src", "bang_lexer.c"), \
PATH("src", "bang_parser.c")
PATH("src", "bang_parser.c"), \
PATH("src", "bang_diag.c")
#define UNITS BM_UNITS, COMMON_UNITS, BASM_UNITS, BANG_UNITS
#define LIBS "-lm"

Expand Down
16 changes: 16 additions & 0 deletions bang/src/bang.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#define BANG_DEFAULT_STACK_SIZE 4096

// TODO(#483): move intersecting `bang run` and `bang build` flags to `bang`

static void build_usage(FILE *stream)
{
fprintf(stream, "Usage: bang build [OPTIONS] <input.bang>\n");
Expand All @@ -19,6 +21,7 @@ static void build_usage(FILE *stream)
fprintf(stream, " -t <target> Output target. Default is `bm`.\n");
fprintf(stream, " Provide `list` to get the list of all available targets.\n");
fprintf(stream, " -s <bytes> Local variables stack size in bytes. (default %zu)\n", (size_t) BANG_DEFAULT_STACK_SIZE);
fprintf(stream, " -werror Treat warnings as errors\n");
fprintf(stream, " -h Print this help to stdout\n");
}

Expand Down Expand Up @@ -53,6 +56,7 @@ static void run_usage(FILE *stream)
fprintf(stream, "OPTIONS:\n");
fprintf(stream, " -t Enable trace mode\n");
fprintf(stream, " -s <bytes> Local variables stack size in bytes. (default %zu)\n", (size_t) BANG_DEFAULT_STACK_SIZE);
fprintf(stream, " -werror Treat warnings as errors\n");
fprintf(stream, " -h Print this help to stdout\n");
}

Expand Down Expand Up @@ -90,7 +94,14 @@ static void run_subcommand(int argc, char **argv)
stack_size_cstr);
exit(1);
}
} else if (strcmp(flag, "-werror") == 0) {
bang.warnings_as_errors = true;
} else {
if (input_file_path != NULL) {
fprintf(stderr, "ERROR: input file path is already specified as `%s`. Multiple file paths are not supported yet\n", input_file_path);
exit(1);
}

input_file_path = flag;
}
}
Expand Down Expand Up @@ -231,6 +242,11 @@ static void build_subcommand(int argc, char **argv)
build_usage(stdout);
exit(0);
} else {
if (input_file_path != NULL) {
fprintf(stderr, "ERROR: input file path is already specified as `%s`. Multiple file paths are not supported yet\n", input_file_path);
exit(1);
}

input_file_path = flag;
}
}
Expand Down
15 changes: 9 additions & 6 deletions bang/src/bang_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,14 +719,17 @@ void compile_var_def_into_basm(Bang *bang, Basm *basm, Bang_Var_Def var_def, Ban

// Shadowed Var Warning
{
// TODO(#481): bang has no option to treat warnings as errors
Compiled_Var *shadowed_var = bang_get_compiled_var_by_name(bang, var_def.name);
if (shadowed_var) {
fprintf(stderr, Bang_Loc_Fmt": WARNING: variable `"SV_Fmt"` is shadowing another variable with the same name\n",
Bang_Loc_Arg(var_def.loc),
SV_Arg(var_def.name));
fprintf(stderr, Bang_Loc_Fmt": NOTE: the shadowed variable is located here\n",
Bang_Loc_Arg(shadowed_var->def.loc));
bang_diag_msg(var_def.loc, bang->warnings_as_errors ? BANG_DIAG_ERROR : BANG_DIAG_WARNING,
"variable `"SV_Fmt"` is shadowing another variable with the same name",
SV_Arg(var_def.name));
bang_diag_msg(shadowed_var->def.loc, BANG_DIAG_NOTE,
"the shadowed variable is located here");

if (bang->warnings_as_errors) {
exit(1);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions bang/src/bang_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ typedef struct {
size_t procs_count;

Bang_Loc entry_loc;

bool warnings_as_errors;
} Bang;

Compiled_Var *bang_get_compiled_var_by_name(Bang *bang, String_View name);
Expand Down
32 changes: 32 additions & 0 deletions bang/src/bang_diag.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include "./bang_diag.h"

const char *bang_diag_level_label(Bang_Diag_Level level)
{
switch (level) {
case BANG_DIAG_NOTE:
return "NOTE";
case BANG_DIAG_WARNING:
return "WARNING";
case BANG_DIAG_ERROR:
return "ERROR";
default:
assert(false && "unreachable");
exit(1);
}
}

void bang_diag_msg(Bang_Loc loc, Bang_Diag_Level level, const char *fmt, ...)
{
fprintf(stderr, Bang_Loc_Fmt": %s: ", Bang_Loc_Arg(loc), bang_diag_level_label(level));

va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);

fprintf(stderr, "\n");
}
31 changes: 31 additions & 0 deletions bang/src/bang_diag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef BANG_DIAG_H_
#define BANG_DIAG_H_

#include <stdlib.h>

#if defined(__GNUC__) || defined(__clang__)
// https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html
#define BANG_PRINTF_FORMAT(STRING_INDEX, FIRST_TO_CHECK) __attribute__ ((format (printf, STRING_INDEX, FIRST_TO_CHECK)))
#else
#define BANG_PRINTF_FORMAT(STRING_INDEX, FIRST_TO_CHECK)
#endif

typedef struct {
size_t row;
size_t col;
const char *file_path;
} Bang_Loc;

#define Bang_Loc_Fmt "%s:%zu:%zu"
#define Bang_Loc_Arg(loc) (loc).file_path, (loc).row, (loc).col

typedef enum {
BANG_DIAG_NOTE,
BANG_DIAG_WARNING,
BANG_DIAG_ERROR,
} Bang_Diag_Level;

const char *bang_diag_level_label(Bang_Diag_Level level);
void bang_diag_msg(Bang_Loc loc, Bang_Diag_Level level, const char *fmt, ...) BANG_PRINTF_FORMAT(3, 4);

#endif // BANG_DIAG_H_
10 changes: 1 addition & 9 deletions bang/src/bang_lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdlib.h>

#include "./sv.h"
#include "./bang_diag.h"

typedef enum {
BANG_TOKEN_KIND_NAME = 0,
Expand Down Expand Up @@ -31,15 +32,6 @@ typedef enum {

const char *bang_token_kind_name(Bang_Token_Kind kind);

typedef struct {
size_t row;
size_t col;
const char *file_path;
} Bang_Loc;

#define Bang_Loc_Fmt "%s:%zu:%zu"
#define Bang_Loc_Arg(loc) (loc).file_path, (loc).row, (loc).col

typedef struct {
Bang_Token_Kind kind;
String_View text;
Expand Down