Something went wrong. Try again.
🌱 A minimal programming language and compiler. git.urbach.dev/cli/q
high-performance programming-language compiler
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101package cli
import ( "errors" "fmt" "os" "os/exec" "strings"
"git.urbach.dev/cli/q/src/compiler" fe "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/go/color" "git.urbach.dev/go/color/ansi")
// Exit codes.const ( success = iota fail invalidArgs)
// exit returns the exit code depending on the error type.func exit(err error) int { if err == nil { return success }
var ( exit *exec.ExitError expectedParameter *ExpectedParameter unknownParameter *UnknownParameter invalidValue *InvalidValue multiError *compiler.MultiError )
if errors.As(err, &multiError) { for _, err := range multiError.Errors { showError(err) }
return fail }
showError(err)
if errors.As(err, &exit) { return exit.ExitCode() }
if errors.As(err, &expectedParameter) || errors.As(err, &unknownParameter) || errors.As(err, &invalidValue) { return invalidArgs }
return fail}
// showError shows an error on stderr.func showError(err error) { var fileError *fe.FileError
if errors.As(err, &fileError) { showFileError(fileError) } else { fmt.Fprintln(os.Stderr, err) }}
// showFileError shows an error on stderr with file, line and column information.func showFileError(fileError *fe.FileError) { line, offset := fileError.Line() indent := strings.Repeat(" ", offset) color.Redirect(os.Stderr) ansi.Reset.Printf("%s\n\n", fileError.Link()) source := fileError.Source() length := int(source.End() - source.Start())
if offset+length > len(line) { length = len(line) - offset }
if length > 0 { ansi.Reset.Printf(" %s", line[:offset]) ansi.Red.Print(line[offset : offset+length]) ansi.Reset.Println(line[offset+length:]) } else { ansi.Reset.Printf(" %s\n", line) }
ansi.Red.Printf("%s ┬\n", indent) ansi.Red.Printf("%s ╰─ ", indent) ansi.Reset.Printf("%s\n\n", fileError.Error()) ansi.Dim.Println(fileError.Stack())}
// invalid shows the help on stderr and returns exit code 2 (invalid parameters).func invalid() int { color.Redirect(os.Stderr) help() return invalidArgs}