1// Copyright 2021 The Tint Authors. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Package tok defines tokens that are produced by the Tint intrinsic definition 16// lexer 17package tok 18 19import "fmt" 20 21// Kind is an enumerator of token kinds 22type Kind string 23 24// Token enumerator types 25const ( 26 InvalidToken Kind = "<invalid>" 27 Identifier Kind = "ident" 28 Integer Kind = "integer" 29 String Kind = "string" 30 Match Kind = "match" 31 Function Kind = "fn" 32 Type Kind = "type" 33 Enum Kind = "enum" 34 Colon Kind = ":" 35 Comma Kind = "," 36 Lt Kind = "<" 37 Gt Kind = ">" 38 Lbrace Kind = "{" 39 Rbrace Kind = "}" 40 Ldeco Kind = "[[" 41 Rdeco Kind = "]]" 42 Lparen Kind = "(" 43 Rparen Kind = ")" 44 Or Kind = "|" 45 Arrow Kind = "->" 46) 47 48// Invalid represents an invalid token 49var Invalid = Token{Kind: InvalidToken} 50 51// Location describes a rune location in the source code 52type Location struct { 53 // 1-based line index 54 Line int 55 // 1-based column index 56 Column int 57 // 0-based rune index 58 Rune int 59 // Optional file path 60 Filepath string 61} 62 63// Format implements the fmt.Formatter interface 64func (l Location) Format(w fmt.State, verb rune) { 65 if w.Flag('+') { 66 if l.Filepath != "" { 67 fmt.Fprintf(w, "%v:%v:%v[%v]", l.Filepath, l.Line, l.Column, l.Rune) 68 } else { 69 fmt.Fprintf(w, "%v:%v[%v]", l.Line, l.Column, l.Rune) 70 } 71 } else { 72 if l.Filepath != "" { 73 fmt.Fprintf(w, "%v:%v:%v", l.Filepath, l.Line, l.Column) 74 } else { 75 fmt.Fprintf(w, "%v:%v", l.Line, l.Column) 76 } 77 } 78} 79 80// Source describes a start and end range in the source code 81type Source struct { 82 S, E Location 83} 84 85// IsValid returns true if the source is valid 86func (s Source) IsValid() bool { 87 return s.S.Line != 0 && s.S.Column != 0 && s.E.Line != 0 && s.E.Column != 0 88} 89 90// Format implements the fmt.Formatter interface 91func (s Source) Format(w fmt.State, verb rune) { 92 if w.Flag('+') { 93 fmt.Fprint(w, "[") 94 s.S.Format(w, verb) 95 fmt.Fprint(w, " - ") 96 s.E.Format(w, verb) 97 fmt.Fprint(w, "]") 98 } else { 99 s.S.Format(w, verb) 100 } 101} 102 103// Token describes a parsed token 104type Token struct { 105 Kind Kind 106 Runes []rune 107 Source Source 108} 109 110// Format implements the fmt.Formatter interface 111func (t Token) Format(w fmt.State, verb rune) { 112 fmt.Fprint(w, "[") 113 t.Source.Format(w, verb) 114 fmt.Fprint(w, " ") 115 fmt.Fprint(w, t.Kind) 116 fmt.Fprint(w, " ") 117 fmt.Fprint(w, string(t.Runes)) 118 fmt.Fprint(w, "]") 119} 120