github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/errors.go (about)

     1  package expressions
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/lmorg/murex/lang/expressions/symbols"
     8  	"github.com/lmorg/murex/utils/readline"
     9  )
    10  
    11  func raiseError(expression []rune, node *astNodeT, pos int, message string) error {
    12  	if node == nil {
    13  		if expression != nil {
    14  			if pos < 1 {
    15  				pos = 1
    16  			}
    17  
    18  			exprRune, exprPos := cropCodeInErrMsg(expression, pos)
    19  			expr := string(exprRune)
    20  
    21  			return fmt.Errorf("%s\nExpression: %s\n          : %s\nCharacter : %d",
    22  				message, expr,
    23  				strings.Repeat(" ", exprPos)+"^", pos)
    24  		}
    25  
    26  		exprRune, _ := cropCodeInErrMsg(expression, pos)
    27  		expr := string(exprRune)
    28  
    29  		return fmt.Errorf("%s\nExpression: %s", message, expr)
    30  	}
    31  
    32  	pos = node.pos
    33  	if node.pos < 0 {
    34  		pos = 0
    35  	}
    36  
    37  	if expression != nil {
    38  		exprRune, exprPos := cropCodeInErrMsg(expression, pos)
    39  		expr := string(exprRune)
    40  
    41  		return fmt.Errorf("%s\nExpression: %s\n          : %s\nCharacter : %d\nSymbol    : %s\nValue     : '%s'",
    42  			message, expr,
    43  			strings.Repeat(" ", exprPos)+"^", pos+1,
    44  			node.key.String(), node.Value())
    45  
    46  	} else {
    47  		return fmt.Errorf("%s at char %d\nSymbol    : %s\nValue     : '%s'",
    48  			message, pos+1, node.key.String(), node.Value())
    49  
    50  	}
    51  }
    52  
    53  var errMessage = map[symbols.Exp]string{
    54  	symbols.Undefined:        "parser error",
    55  	symbols.Unexpected:       "unexpected symbol",
    56  	symbols.SubExpressionEnd: "more closing parenthesis then opening parenthesis",
    57  	symbols.ObjectEnd:        "more closing curly braces then opening braces",
    58  	symbols.ArrayEnd:         "more closing square brackets then opening brackets",
    59  	symbols.InvalidHyphen:    "unexpected hyphen",
    60  }
    61  
    62  func cropCodeInErrMsg(code []rune, pos int) ([]rune, int) {
    63  	width := readline.GetTermWidth()
    64  	if width < 80 {
    65  		width = 80
    66  	}
    67  
    68  	r := make([]rune, len(code))
    69  	copy(r, code)
    70  	replaceRune(r, '\n', ' ')
    71  	replaceRune(r, '\r', ' ')
    72  	replaceRune(r, '\t', ' ')
    73  
    74  	if pos >= len(r) {
    75  		pos = len(r) - 1
    76  	}
    77  
    78  	if pos < 0 {
    79  		pos = 0
    80  	}
    81  
    82  	return _cropCodeInErrMsg(r, pos, width-20)
    83  }
    84  
    85  func _cropCodeInErrMsg(r []rune, pos, width int) ([]rune, int) {
    86  	switch {
    87  	case len(r) <= width:
    88  		return r, pos
    89  	case pos < width-2:
    90  		return r[:width], pos
    91  	case len(r)-pos < width:
    92  		return r[len(r)-width:], width - (len(r) - pos)
    93  	default:
    94  		w := width / 2
    95  		return r[pos-w : pos+w], w
    96  	}
    97  }
    98  
    99  func replaceRune(r []rune, find, replace rune) {
   100  	for i := range r {
   101  		if r[i] == find {
   102  			r[i] = replace
   103  		}
   104  	}
   105  }