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}, } }