50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
package lang
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
type DiagnosticSeverity int
|
|
|
|
const (
|
|
DiagnosticError DiagnosticSeverity = 1
|
|
DiagnosticWarning DiagnosticSeverity = 2
|
|
)
|
|
|
|
type SourceSpan struct {
|
|
Start int
|
|
End int
|
|
}
|
|
|
|
type SemanticDiagnostic struct {
|
|
Code string
|
|
Message string
|
|
Severity DiagnosticSeverity
|
|
Span SourceSpan
|
|
}
|
|
|
|
func (diagnostic SemanticDiagnostic) Error() string { return diagnostic.Message }
|
|
|
|
var semanticOffsetPattern = regexp.MustCompile(`\sat\s(\d+)$`)
|
|
|
|
func diagnosticForError(code string, err error) SemanticDiagnostic {
|
|
span := SourceSpan{}
|
|
if match := semanticOffsetPattern.FindStringSubmatch(err.Error()); len(match) == 2 {
|
|
if offset, parseErr := strconv.Atoi(match[1]); parseErr == nil {
|
|
span = SourceSpan{Start: offset, End: offset + 1}
|
|
}
|
|
}
|
|
return SemanticDiagnostic{Code: code, Message: err.Error(), Severity: DiagnosticError, Span: span}
|
|
}
|
|
|
|
func undefinedDiagnostic(name string, position int) SemanticDiagnostic {
|
|
end := position + len(name)
|
|
return SemanticDiagnostic{
|
|
Code: "undefined-symbol",
|
|
Message: fmt.Sprintf("undefined identifier %s", name),
|
|
Severity: DiagnosticError,
|
|
Span: SourceSpan{Start: position, End: end},
|
|
}
|
|
}
|