+111
@@ -0,0 +1,111 @@
|
|||||||
|
package lexer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
EOF = io.EOF // EOF marker
|
||||||
|
)
|
||||||
|
|
||||||
|
// Token type
|
||||||
|
type TokenType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
TokenError TokenType = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
// Token Position
|
||||||
|
type TokenPosition struct {
|
||||||
|
Line int
|
||||||
|
Row int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token
|
||||||
|
type Token interface {
|
||||||
|
Type() TokenType
|
||||||
|
String() string
|
||||||
|
Position() TokenPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
type token struct {
|
||||||
|
typ TokenType
|
||||||
|
pos TokenPosition
|
||||||
|
val string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewToken(typ TokenType, val []rune, pos TokenPosition) Token {
|
||||||
|
return &token{
|
||||||
|
typ: typ,
|
||||||
|
val: string(val),
|
||||||
|
pos: pos,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t token) Type() TokenType {
|
||||||
|
return t.typ
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t token) Position() TokenPosition {
|
||||||
|
return t.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t token) String() string {
|
||||||
|
return t.val
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorToken
|
||||||
|
type ErrorToken interface {
|
||||||
|
Token
|
||||||
|
Error() string
|
||||||
|
Unwrap() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorToken struct {
|
||||||
|
token
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrorToken(err error, pos TokenPosition) ErrorToken {
|
||||||
|
return &errorToken{
|
||||||
|
token: token{
|
||||||
|
typ: TokenError,
|
||||||
|
val: err.Error(),
|
||||||
|
pos: pos,
|
||||||
|
},
|
||||||
|
err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t errorToken) Error() string {
|
||||||
|
return t.err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t errorToken) Unwrap() error {
|
||||||
|
return t.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyntaxErrorToken
|
||||||
|
type SyntaxErrorToken struct {
|
||||||
|
ErrorToken
|
||||||
|
|
||||||
|
Cursor int
|
||||||
|
Buffer string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSyntaxErrorToken(msg string, pos TokenPosition, cur int, buffer []rune) *SyntaxErrorToken {
|
||||||
|
s := fmt.Sprintf("Syntax Error at %v.%v+%v", pos.Line, pos.Row, cur)
|
||||||
|
|
||||||
|
if len(msg) > 0 {
|
||||||
|
s = fmt.Sprintf("%s: %s", s, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SyntaxErrorToken{
|
||||||
|
ErrorToken: NewErrorToken(errors.New(s), pos),
|
||||||
|
|
||||||
|
Cursor: cur,
|
||||||
|
Buffer: string(buffer),
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user