PreviousUpNext

15.4.210  src/lib/c-kit/src/parser/stuff/error.pkg

## error.pkg

# Compiled by:
#     src/lib/c-kit/src/parser/c-parser.sublib

###                         "Finally I'm becoming stupider no more."
###
###                                              -- Paul Erdos 



stipulate
    package fil =  file__premicrothread;                                # file__premicrothread  is from   src/lib/std/src/posix/file--premicrothread.pkg
    package f  =  sfprintf;                                             # sfprintf              is from   src/lib/src/sfprintf.pkg
    package pp =  old_prettyprinter;                                    # old_prettyprinter     is from   src/lib/prettyprint/big/src/old-prettyprinter.pkg
    package sm =  line_number_db;                                       # line_number_db        is from   src/lib/c-kit/src/parser/stuff/line-number-db.pkg
herein

    package   error
    : (weak)  Error                                                     # Error                 is from   src/lib/c-kit/src/parser/stuff/error.api
    {

        Error_State
            =
            ES 
              { out_strm:          fil::Output_Stream,
                num_errors:        Ref( Int ),
                num_warnings:      Ref( Int ),
                warnings_enabled:  Ref( Bool ),
                errors_enabled:    Ref( Bool ),
                errors_limit:      Int,
                warnings_limit:    Int
              };

        # Global error and warning count limits:
        #
        errors_limit   = REF 10;  #  flag for suppressing error messages 
        warnings_limit = REF 10;  #  flag for suppressing warning messages 

        # make an error state.  src is the source file name, dst is the
        # output state to report errors on, lnum and lpos are references
        # used to keep track of the current line number and starting
        # character positions of the scanned lines.
        #
        fun make_error_state (dst: fil::Output_Stream)
            =
            ES { out_strm         =>  dst,
                 num_errors       =>  REF 0,
                 num_warnings     =>  REF 0,
                 warnings_enabled =>  REF TRUE,
                 errors_enabled   =>  REF TRUE,
                 errors_limit     =>  *errors_limit,
                 warnings_limit   =>  *warnings_limit
               };

        fun inc (i: Ref( Int )) = { i := *i + 1; ();};
        fun dec (i: Ref( Int )) = { i := *i - 1; ();};

        # Curried version of fil::write:
        # 
        fun outputc outstrm strng
            =
            fil::write (outstrm, strng);

        # For reporting internal bugs:
        # 
        fun bug (ES { out_strm, ... } ) (msg: String) : Void
            =
            fil::write (out_strm, ("Compiler bug: " + msg + "\n"));

        # Print a warning/error message with location info:
        #
        fun say_error (es as ES { out_strm, ... }, loc, kind, msg)
            =
            f::fnprintf'  (outputc out_strm)  "%s: %s%s\n"  [
                f::STRING (sm::loc_to_string loc), f::STRING kind, f::STRING msg
            ];

        # Print a formatted warning/error message with location info:
        #
        fun fmt_error (es as ES { out_strm, ... }, loc, kind, fmt, items)
            =
            f::fnprintf'  (outputc out_strm)  ("%s: %s" + fmt + "\n")
                 ((f::STRING (sm::loc_to_string loc)) ! (f::STRING kind) ! items);

        # Print warning messages to the error stream:
        #
        fun warning (es as ES { num_warnings, warnings_limit, warnings_enabled, ... }, loc, msg)
            =
            if *warnings_enabled

                 say_error (es, loc, "warning: ", msg);
                 inc num_warnings;

                 if   (*num_warnings > warnings_limit)

                      warnings_enabled := FALSE;
                      say_error (es, loc, "warning: ", "additional warnings suppressed");
                 fi;
            fi;

        fun warningf (es as ES { num_warnings, warnings_limit, warnings_enabled, ... },
                      loc, fmt, items)
            = 
            if   (*warnings_enabled)

                 fmt_error (es, loc, "warning: ", fmt, items);
                 inc num_warnings;

                 if   (*num_warnings > warnings_limit)

                      warnings_enabled := FALSE;
                      say_error (es, loc, "warning: ", "additional warnings suppressed");
                 fi;
            fi;

        fun no_more_warnings (es as ES { warnings_enabled, ... } )
            = 
            {   warnings_enabled := FALSE;
                say_error (es, sm::UNKNOWN, "warning: ", "additional warnings suppressed.");
            };

        # hints - heuristic help for error messages;
        # Note: must be called before error call is generated.
        last_hint = REF (NULL:  Null_Or( String ));
        fun hint s = (last_hint := THE s);

        # Print error messages to the error stream:
        #
        fun error (es as ES { num_errors, errors_limit, errors_enabled, ... }, loc, msg)
            =
            if (*errors_enabled)

                 case *last_hint

                      THE s => { say_error (es, loc, "error: ", msg + "\n" + s);
                              last_hint := NULL;};

                      NULL => say_error (es, loc, "error: ", msg);
                 esac;

                 inc num_errors;

                 if   (*num_errors > errors_limit)

                      errors_enabled := FALSE;
                      say_error (es, loc, "warning: ", "additional errors suppressed.");
                 fi;
            fi;

        fun errorf (es as ES { num_errors, errors_limit, errors_enabled, ... }, loc, fmt, items)
            =
            if *errors_enabled

                 fmt_error (es, loc, "error: ", fmt, items);
                 inc num_errors;

                 if   (*num_errors > errors_limit)

                      errors_enabled := FALSE;
                      say_error (es, loc, "warning: ", "additional errors suppressed.");
                 fi;
            fi;

        fun no_more_errors (es as ES { errors_enabled, ... } )
            =
            {   errors_enabled := FALSE;
                say_error (es, sm::UNKNOWN, "warning: ", "additional errors suppressed.");
            };

        # Pretty-print an error message on the error stream:
        #
        fun prettyprint_error (es as ES { out_strm, num_errors, ... }, loc, prettyprint)
            =
            {   prettyprint_stream
                    =
                    pp::make_ppstream
                        {
                          consumer  =>  outputc out_strm,
                          flush     =>  \\ () = fil::flush out_strm,
                          close     =>  \\ () = ()
                        };

                inc num_errors;
                pp::begin_block prettyprint_stream pp::INCONSISTENT 0;
                pp::add_string prettyprint_stream
                    (f::sprintf' "Error %s: " [f::STRING (sm::loc_to_string loc)]);
                prettyprint prettyprint_stream;
                pp::add_newline prettyprint_stream;
                pp::end_block prettyprint_stream;
                pp::flush_ppstream prettyprint_stream;
            };

        fun err_stream (ES { out_strm, ... } )
            =
            out_strm;

        # Return count of errors reported on the state (since last reset):
        # 
        fun error_count (ES { num_errors, ... } )
            =
            *num_errors;

        # Return count of warnings reported on the state (since last reset):
        # 
        fun warning_count (ES { num_warnings, ... } )
            =
            *num_warnings;

        # Clear the error and warning counts, so that errorCount and
        # warningCount will return 0:
        #
        fun reset (ES { num_errors, num_warnings, ... } )
            =
            {   num_errors   := 0;
                num_warnings := 0;
            };

    };          #  error 
end;



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext