2024-03-26 08:45:18 +01:00
|
|
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
|
|
// All rights reserved.
|
|
|
|
|
2024-03-26 07:00:53 +01:00
|
|
|
// token.go
|
|
|
|
package expr
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"slices"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Token struct {
|
2024-04-02 04:36:03 +02:00
|
|
|
row int
|
|
|
|
col int
|
2024-03-26 07:00:53 +01:00
|
|
|
Sym Symbol
|
|
|
|
source string
|
|
|
|
Value any
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tk *Token) DevString() string {
|
|
|
|
if tk.Value != nil {
|
|
|
|
return fmt.Sprintf("[%d]%q{%v}", tk.Sym, tk.source, tk.Value)
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("[%d]%q{}", tk.Sym, tk.source)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tk *Token) String() string {
|
|
|
|
if tk.Value != nil {
|
2024-04-13 04:33:59 +02:00
|
|
|
if s, ok := tk.Value.(string); ok {
|
|
|
|
return fmt.Sprintf("%q", s)
|
|
|
|
} else {
|
|
|
|
return fmt.Sprintf("%v", tk.Value)
|
|
|
|
}
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
return fmt.Sprintf("%s", tk.source)
|
|
|
|
}
|
|
|
|
|
2024-04-02 04:36:03 +02:00
|
|
|
func NewToken(row, col int, sym Symbol, source string) *Token {
|
|
|
|
return &Token{row: row, col: col, Sym: sym, source: source}
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
|
2024-04-02 04:36:03 +02:00
|
|
|
func NewValueToken(row, col int, sym Symbol, source string, value any) *Token {
|
|
|
|
return &Token{row: row, col: col, Sym: sym, source: source, Value: value}
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewErrorToken(row, col int, err error) *Token {
|
|
|
|
if err == io.EOF {
|
2024-05-04 18:47:00 +02:00
|
|
|
return NewToken(row, col, SymEos, "<EOF>")
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
2024-04-02 04:36:03 +02:00
|
|
|
return NewValueToken(row, col, SymError, fmt.Sprintf("[%d:%d]", row, col), err)
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tk *Token) IsEos() bool {
|
|
|
|
return tk.Sym == SymEos
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tk *Token) IsError() bool {
|
|
|
|
return tk.Sym == SymError
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tk *Token) IsTerm(termSymbols []Symbol) bool {
|
|
|
|
return tk.IsEos() || tk.IsError() || (termSymbols != nil && slices.Index(termSymbols, tk.Sym) >= 0)
|
|
|
|
}
|
2024-04-02 04:36:03 +02:00
|
|
|
|
2024-05-04 19:08:02 +02:00
|
|
|
func (tk *Token) IsSymbol(sym Symbol) bool {
|
|
|
|
return tk.Sym == sym
|
|
|
|
}
|
|
|
|
|
2024-04-02 04:36:03 +02:00
|
|
|
func (self *Token) Errorf(template string, args ...any) (err error) {
|
|
|
|
err = fmt.Errorf(fmt.Sprintf("[%d:%d] ", self.row, self.col)+template, args...)
|
|
|
|
return
|
|
|
|
}
|
2024-04-17 14:15:50 +02:00
|
|
|
|
|
|
|
func (self *Token) Error() (err error) {
|
|
|
|
if self.Sym == SymError {
|
|
|
|
if msg, ok := self.Value.(error); ok {
|
|
|
|
err = fmt.Errorf("[%d:%d] %v", self.row, self.col, msg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *Token) Errors(msg string) (err error) {
|
|
|
|
err = fmt.Errorf("[%d:%d] %v", self.row, self.col, msg)
|
|
|
|
return
|
|
|
|
}
|
2024-05-04 18:47:00 +02:00
|
|
|
|
|
|
|
func (self *Token) ErrorExpectedGot(symbol string) (err error) {
|
|
|
|
err = fmt.Errorf("[%d:%d] expected %q, got %q", self.row, self.col, symbol, self)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *Token) ErrorExpectedGotString(symbol, got string) (err error) {
|
|
|
|
err = fmt.Errorf("[%d:%d] expected %q, got %q", self.row, self.col, symbol, got)
|
|
|
|
return
|
|
|
|
}
|