diff --git a/file/error.go b/file/error.go new file mode 100644 index 0000000..324ef89 --- /dev/null +++ b/file/error.go @@ -0,0 +1,72 @@ +package file + +import "fmt" + +type ErrorKind int + +const ( + ErrorKindError ErrorKind = iota + ErrorKindWarn +) + +type Error struct { + Location + width int + message string + kind ErrorKind +} + +// NewError creates a new error at the specified location. +func NewError ( + location Location, + width int, + message string, + kind ErrorKind, +) ( + err *Error, +) { + return &Error { + Location: location, + width: width, + message: message, + kind: kind, + } +} + +// Error returns a formatted error message as a string. +func (err Error) Error () (formattedMessage string) { + switch err.kind { + case ErrorKindError: + formattedMessage += "ERR" + case ErrorKindWarn: + formattedMessage += "!!!" + } + + // print information about the location of the mistake + if err.width > 0 { + formattedMessage += fmt.Sprint ( + " ", err.Location.row + 1, + ":", err.Location.column + 1) + } + formattedMessage += " in " + err.Location.file.path + "\n" + + if err.width > 0 { + // print erroneous line + formattedMessage += + err.Location.file.lines[err.Location.row] + "\n" + + // print an arrow with a tail spanning the width of the mistake + columnCountdown := err.Location.column + for columnCountdown > 0 { + formattedMessage += " " + columnCountdown -- + } + for err.width > 1 { + formattedMessage += "-" + } + formattedMessage += "-\n" + } + formattedMessage += err.message + "-\n" + + return +} diff --git a/file/file.go b/file/file.go index a1b4926..557be39 100644 --- a/file/file.go +++ b/file/file.go @@ -1,11 +1,8 @@ package file import "os" -import "log" import "bufio" -var logger = log.New(os.Stderr, "", 0) - // File represents a read only file that can print out formatted errors. type File struct { path string @@ -104,47 +101,6 @@ func (file *File) Close () { file.file.Close() } -// mistake prints an informational message about a mistake that the user made. -func (file *File) mistake (column, row, width int, message, symbol string) { - logger.Print(symbol) - - // print information about the location of the mistake - if width > 0 { - logger.Print(" ", row + 1, ":", column + 1) - } - logger.Println(" in", file.path) - - if width > 0 { - // print erroneous line - logger.Println(file.lines[row]) - - // print an arrow with a tail spanning the width of the mistake - for column > 0 { - logger.Print(" ") - column -- - } - for width > 1 { - logger.Print("-") - } - logger.Println("^") - } - logger.Println(message) -} - -// Error prints an error at row and column spanning width amount of runes, and -// a message describing the error. If width is zero, neither the line nor the -// location information is printed. -func (file *File) Error (column, row, width int, message string) { - file.mistake(column, row, width, message, "ERR") -} - -// Warn prints a warning at row and column spanning width amount of runes, and -// a message describing the error. If width is zero, neither the line nor the -// location information is printed. -func (file *File) Warn (column, row, width int, message string) { - file.mistake(column, row, width, message, "!!!") -} - // Location returns a location struct describing the current position inside of // the file. This can be stored and used to print errors. func (file *File) Location () (location Location) { diff --git a/file/location.go b/file/location.go index 68c48a0..acc65cf 100644 --- a/file/location.go +++ b/file/location.go @@ -7,13 +7,3 @@ type Location struct { row int column int } - -// Error prints an error at this location. -func (location Location) Error (width int, message string) { - location.file.Error(location.column, location.row, width, message) -} - -// Warn prints a warning at this location. -func (location Location) Warn (width int, message string) { - location.file.Warn(location.column, location.row, width, message) -}