Alejandro Mery
3 years ago
1 changed files with 111 additions and 0 deletions
@ -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), |
||||
} |
||||
} |
Loading…
Reference in new issue