package shared import ( "fmt" "os" "strings" ) type Error struct { message string loc Location } func NewError(loc Location, message string, a ...any) Error { return Error{ message: fmt.Sprintf(message, a...), loc: loc, } } func (err Error) Error() string { f, e := os.ReadFile(err.loc.FilePath) if e != nil { return err.message } line := strings.Split(string(f), "\n")[err.loc.LC.Line-1] pointer := "" if err.loc.LC.Col == 1 { pointer = "^" + strings.Repeat("~", len(line)-1) } else { pointer = strings.Repeat("~", max(0, err.loc.LC.Col-2)) + "^" + strings.Repeat("~", len(line)-err.loc.LC.Col+1) } return fmt.Sprintf("%s:%d:%d\n%s\n%s\n\n%s", err.loc.FilePath, err.loc.LC.Line, err.loc.LC.Col, line, pointer, err.message) } type LineCol struct { Line int Col int } type Location struct { LC LineCol FilePath string } type Pair[T1 any, T2 any] struct { L T1 R T2 }