| // 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" |
| 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 = "^" |
| ) |
| |
| // 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, "]") |
| } |