blob: 02532bfc5f84b37adb9d4a7c9f96ba3cc505cf5b [file] [log] [blame]
// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Package tok defines tokens that are produced by the Tint intrinsic definition
// lexer
package tok
import "fmt"
// Kind is an enumerator of token kinds
type Kind string
// Token enumerator types
const (
InvalidToken Kind = "<invalid>"
Identifier Kind = "ident"
Integer Kind = "integer"
Float Kind = "float"
String Kind = "string"
Match Kind = "match"
Import Kind = "import"
Implicit Kind = "implicit"
Function Kind = "fn"
Operator Kind = "op"
Constructor Kind = "ctor"
Converter Kind = "conv"
Type Kind = "type"
Enum Kind = "enum"
And Kind = "&"
AndAnd Kind = "&&"
Arrow Kind = "->"
Attr Kind = "@"
Assign Kind = "="
Colon Kind = ":"
Comma Kind = ","
Complement Kind = "~"
Divide Kind = "/"
Dot Kind = "."
Equal Kind = "=="
Ge Kind = ">="
Gt Kind = ">"
Lbrace Kind = "{"
Le Kind = "<="
Lparen Kind = "("
Lt Kind = "<"
Minus Kind = "-"
Modulo Kind = "%"
Not Kind = "!"
NotEqual Kind = "!="
Or Kind = "|"
OrOr Kind = "||"
Plus Kind = "+"
Rbrace Kind = "}"
Rparen Kind = ")"
Shl Kind = "<<"
Shr Kind = ">>"
Star Kind = "*"
Xor Kind = "^"
Lbracket Kind = "["
Rbracket Kind = "]"
)
// Invalid represents an invalid token
var Invalid = Token{Kind: InvalidToken}
// Location describes a rune location in the source code
type Location struct {
// 1-based line index
Line int
// 1-based column index
Column int
// 0-based rune index
Rune int
// Optional file path
Filepath string
}
// Format implements the fmt.Formatter interface
func (l Location) Format(w fmt.State, verb rune) {
if w.Flag('+') {
if l.Filepath != "" {
fmt.Fprintf(w, "%v:%v:%v[%v]", l.Filepath, l.Line, l.Column, l.Rune)
} else {
fmt.Fprintf(w, "%v:%v[%v]", l.Line, l.Column, l.Rune)
}
} else {
if l.Filepath != "" {
fmt.Fprintf(w, "%v:%v:%v", l.Filepath, l.Line, l.Column)
} else {
fmt.Fprintf(w, "%v:%v", l.Line, l.Column)
}
}
}
// Source describes a start and end range in the source code
type Source struct {
S, E Location
}
// IsValid returns true if the source is valid
func (s Source) IsValid() bool {
return s.S.Line != 0 && s.S.Column != 0 && s.E.Line != 0 && s.E.Column != 0
}
// Format implements the fmt.Formatter interface
func (s Source) Format(w fmt.State, verb rune) {
if w.Flag('+') {
fmt.Fprint(w, "[")
s.S.Format(w, verb)
fmt.Fprint(w, " - ")
s.E.Format(w, verb)
fmt.Fprint(w, "]")
} else {
s.S.Format(w, verb)
}
}
// Token describes a parsed token
type Token struct {
Kind Kind
Runes []rune
Source Source
}
// Format implements the fmt.Formatter interface
func (t Token) Format(w fmt.State, verb rune) {
fmt.Fprint(w, "[")
t.Source.Format(w, verb)
fmt.Fprint(w, " ")
fmt.Fprint(w, t.Kind)
fmt.Fprint(w, " ")
fmt.Fprint(w, string(t.Runes))
fmt.Fprint(w, "]")
}