diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4668c5ef..f29661c3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,9 +47,9 @@ jobs: run: | set -e check_dir() { # $1 is the file extension, $2 is the directory and $3 the max depth to check - result=$(find $2 -maxdepth ${3:-1000} -name "$1" -type f -exec egrep -l " +$" {} \;) + result=$(find $2 -maxdepth ${3:-1000} -name "$1" -type f -exec grep -E -Hn " +$" {} \;) if [ -n "$result" ]; then - echo "Trailing whitespace found in the following files:" + echo "Trailing whitespace found in the following locations:" echo "$result" exit 1 fi diff --git a/Makefile b/Makefile index b46951f1..dbfc6902 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ endif pnut-sh: pnut.c sh.c sh-runtime.c mkdir -p $(BUILD_DIR) - gcc $(BUILD_OPT_SH) pnut.c -o $(BUILD_DIR)/pnut-sh + gcc $(BUILD_OPT_SH) -g pnut.c -o $(BUILD_DIR)/pnut-sh pnut-sh.sh: pnut-sh ./$(BUILD_DIR)/pnut-sh $(BUILD_OPT_SH) pnut.c > $(BUILD_DIR)/pnut-sh.sh diff --git a/pnut.c b/pnut.c index addb5eaa..728542cf 100644 --- a/pnut.c +++ b/pnut.c @@ -38,6 +38,9 @@ #define OPTIMIZE_LONG_LINES #endif +// Uncomment to cause parse_error() to print which pnut function emitted the error +//#define DEBUG_SHOW_ERR_ORIGIN + // Use positional parameter directly for function parameters that are constants #define OPTIMIZE_CONSTANT_PARAM_not #define SUPPORT_ADDRESS_OF_OP_not @@ -2016,8 +2019,13 @@ void get_tok() { #endif +#ifdef __gcc__ +#define parse_error(msg, token) parse_error_internal(msg, token, __FILE__, __LINE__) +#else +#define parse_error(msg, token) parse_error_internal(msg, token, "probably pnut.c", -1) +#endif -void parse_error(char * msg, int token) { +void parse_error_internal(char * msg, int token, char * file, int line) { #ifdef NICE_ERR_MSG #define ANSI_RED "\x1b[31m" @@ -2053,8 +2061,17 @@ void parse_error(char * msg, int token) { putint(last_tok_column_number); putstr(ANSI_RESET"\n"); #else - fatal_error(msg); + putstr(msg); #endif + +#ifdef DEBUG_SHOW_ERR_ORIGIN + putstr("Note, error emitted from "); + putstr(file); + putstr(" line "); + putint(line); + putstr("\n"); +#endif + exit(1); } @@ -2148,8 +2165,19 @@ int parse_stars_for_type(int type) { return type; } +//defining a const after the * is valid c, ie +// const int * const foo; +void ignore_optional_const() { + if(tok == CONST_KW) { + //skip the const + get_tok(); + } +} + int parse_type_with_stars() { - return parse_stars_for_type(parse_type()); + int type = parse_stars_for_type(parse_type()); + ignore_optional_const(); + return type; } int is_type_starter(int tok) { @@ -2361,6 +2389,11 @@ ast parse_definition(int local) { ast tail = 0; ast current_declaration; + //Currently, static is just skipped + if(tok == STATIC_KW) { + get_tok(); + } + if (is_type_starter(tok)) { type = parse_type(); @@ -2376,6 +2409,7 @@ ast parse_definition(int local) { while (1) { this_type = parse_stars_for_type(type); + ignore_optional_const(); name = val; @@ -2705,9 +2739,6 @@ ast parse_cast_expression() { if (is_type_starter(tok)) { type = parse_type_with_stars(); - if (get_val(type) == 0 && get_op(type) == VOID_KW) - parse_error("variable with void type", tok); - expect_tok(')'); result = new_ast2(CAST, type, parse_cast_expression()); return result;