File is now capable of printing errors

This commit is contained in:
Sasha Koshka 2022-08-03 13:28:37 -04:00
parent 4d94e5738d
commit 64a8a2445a

View File

@ -1,23 +1,23 @@
package file package file
import "os" import "os"
import "path/filepath" import "log"
var logger = log.New(os.Stderr, "", 0)
// File represents a read only file that can print out formatted errors.
type File struct { type File struct {
path string path string
moduleName string
file *os.File file *os.File
currentLine int currentLine int
lines [][]byte lines [][]byte
} }
// Open opens the file specified by path and returns a new File struct. The // Open opens the file specified by path and returns a new File struct.
// module name is automatically inferred through hte file's parent directory.
func Open (path string) (file *File, err error) { func Open (path string) (file *File, err error) {
file = &File { file = &File {
path: path, path: path,
moduleName: filepath.Dir(path), lines: [][]byte { []byte { } },
lines: [][]byte { []byte { } },
} }
file.file, err = os.OpenFile(path, os.O_RDONLY, 0660) file.file, err = os.OpenFile(path, os.O_RDONLY, 0660)
@ -39,6 +39,7 @@ func (file *File) Stat () (fileInfo os.FileInfo, err error) {
func (file *File) Read (bytes []byte) (amountRead int, err error) { func (file *File) Read (bytes []byte) (amountRead int, err error) {
amountRead, err = file.file.Read(bytes) amountRead, err = file.file.Read(bytes)
// store the character in the file
for _, char := range bytes { for _, char := range bytes {
if char == '\n' { if char == '\n' {
file.lines = append(file.lines, []byte { }) file.lines = append(file.lines, []byte { })
@ -58,3 +59,44 @@ func (file *File) Read (bytes []byte) (amountRead int, err error) {
func (file *File) Close () { func (file *File) Close () {
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, "!!!")
}