Files

122 lines
2.8 KiB
Go
Raw Permalink Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
// Package token defines the lexical tokens of Go's Plan 9 assembler (GAsm)
// and the source positions attached to them. It has no dependencies and is
// shared by the lexer, parser, formatter, linter and language server.
package token
import "strconv"
// Kind classifies a lexical token.
type Kind int
// The token kinds. The zero value is Illegal so that an uninitialised Token
// is obviously invalid.
const (
Illegal Kind = iota
EOF
Newline
Comment
// Ident Literals and names.
Ident // instruction mnemonic, label, register or symbol name
Number // integer or floating-point literal (sign carried separately)
String // "..."
Rune // '.'
// LParen Punctuation and operators.
LParen // (
RParen // )
Comma // ,
Plus // +
Minus // -
Star // *
Slash // /
Colon // :
Dollar // $
LAngle // <
RAngle // >
LShift // <<
RShift // >>
Arrow // ->
At // @
Hash // #
Pipe // |
// Semicolon separates statements on one line (a Plan 9 statement
// terminator); Ampersand and Tilde are the expression operators & and ~
// of constant expressions. All three appear mostly inside macro bodies.
Semicolon // ;
Ampersand // &
Tilde // ~
)
var kindNames = map[Kind]string{
Illegal: "ILLEGAL",
EOF: "EOF",
Newline: "NEWLINE",
Comment: "COMMENT",
Ident: "IDENT",
Number: "NUMBER",
String: "STRING",
Rune: "RUNE",
LParen: "(",
RParen: ")",
Comma: ",",
Plus: "+",
Minus: "-",
Star: "*",
Slash: "/",
Colon: ":",
Dollar: "$",
LAngle: "<",
RAngle: ">",
LShift: "<<",
RShift: ">>",
Arrow: "->",
At: "@",
Hash: "#",
Pipe: "|",
Semicolon: ";",
Ampersand: "&",
Tilde: "~",
}
// String returns a human-readable name for the kind.
func (k Kind) String() string {
if s, ok := kindNames[k]; ok {
return s
}
return "Kind(" + strconv.Itoa(int(k)) + ")"
}
// Position is a byte offset plus one-based line and column within a file.
type Position struct {
Offset int // byte offset, zero-based
Line int // line number, one-based
Column int // column number, one-based (in runes)
}
// String renders the position as "line:column".
func (p Position) String() string {
return strconv.Itoa(p.Line) + ":" + strconv.Itoa(p.Column)
}
// IsValid reports whether the position carries a real line number.
func (p Position) IsValid() bool { return p.Line > 0 }
// Token is a single lexical token together with its literal text and span.
type Token struct {
Kind Kind
Text string
Pos Position // inclusive start
End Position // exclusive end
}
// String renders the token for diagnostics and debugging.
func (t Token) String() string {
return t.Pos.String() + " " + t.Kind.String() + " " + strconv.Quote(t.Text)
}