Files
wehub-resource-sync 95f0813436
build / build (push) Failing after 0s
nightly / nightly (push) Failing after 0s
build / snapshot (push) Failing after 0s
lint / lint (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 13:02:37 +08:00

233 lines
5.5 KiB
Go

// Package token provides the token types and structures for the VHS Tape
// language.
package token
import (
"strings"
)
// Type represents a token's type.
type Type string
// Token represents a lexer token.
type Token struct {
Type Type
Literal string
Line int
Column int
}
// Tokens for the VHS language.
const (
AT = "@"
EQUAL = "="
PLUS = "+"
PERCENT = "%"
SLASH = "/"
BACKSLASH = "\\"
DOT = "."
DASH = "-"
MINUS = "-"
RIGHT_BRACKET = "]"
LEFT_BRACKET = "["
CARET = "^"
EM = "EM"
MILLISECONDS = "MILLISECONDS"
MINUTES = "MINUTES"
PX = "PX"
SECONDS = "SECONDS"
EOF = "EOF"
ILLEGAL = "ILLEGAL"
ALT = "ALT"
BACKSPACE = "BACKSPACE"
CTRL = "CTRL"
DELETE = "DELETE"
END = "END"
ENTER = "ENTER"
ESCAPE = "ESCAPE"
HOME = "HOME"
INSERT = "INSERT"
PAGE_DOWN = "PAGE_DOWN"
PAGE_UP = "PAGE_UP"
SCROLL_DOWN = "SCROLL_DOWN"
SCROLL_UP = "SCROLL_UP"
SLEEP = "SLEEP"
SPACE = "SPACE"
TAB = "TAB"
SHIFT = "SHIFT"
COMMENT = "COMMENT"
NUMBER = "NUMBER"
STRING = "STRING"
JSON = "JSON"
REGEX = "REGEX"
BOOLEAN = "BOOLEAN"
DOWN = "DOWN"
LEFT = "LEFT"
RIGHT = "RIGHT"
UP = "UP"
HIDE = "HIDE"
OUTPUT = "OUTPUT"
REQUIRE = "REQUIRE"
SET = "SET"
SHOW = "SHOW"
SOURCE = "SOURCE"
TYPE = "TYPE"
SCREENSHOT = "SCREENSHOT"
COPY = "COPY"
PASTE = "PASTE"
SHELL = "SHELL"
ENV = "ENV"
FONT_FAMILY = "FONT_FAMILY"
FONT_SIZE = "FONT_SIZE"
FRAMERATE = "FRAMERATE"
PLAYBACK_SPEED = "PLAYBACK_SPEED"
HEIGHT = "HEIGHT"
WIDTH = "WIDTH"
LETTER_SPACING = "LETTER_SPACING"
LINE_HEIGHT = "LINE_HEIGHT"
TYPING_SPEED = "TYPING_SPEED"
PADDING = "PADDING"
THEME = "THEME"
LOOP_OFFSET = "LOOP_OFFSET"
MARGIN_FILL = "MARGIN_FILL"
MARGIN = "MARGIN"
WINDOW_BAR = "WINDOW_BAR"
WINDOW_BAR_SIZE = "WINDOW_BAR_SIZE"
BORDER_RADIUS = "CORNER_RADIUS"
WAIT = "WAIT"
WAIT_TIMEOUT = "WAIT_TIMEOUT"
WAIT_PATTERN = "WAIT_PATTERN"
CURSOR_BLINK = "CURSOR_BLINK"
)
// Keywords maps keyword strings to tokens.
var Keywords = map[string]Type{
"em": EM,
"px": PX,
"ms": MILLISECONDS,
"s": SECONDS,
"m": MINUTES,
"Set": SET,
"Sleep": SLEEP,
"Type": TYPE,
"Enter": ENTER,
"Space": SPACE,
"Backspace": BACKSPACE,
"Delete": DELETE,
"Insert": INSERT,
"Ctrl": CTRL,
"Alt": ALT,
"Shift": SHIFT,
"Down": DOWN,
"Left": LEFT,
"Right": RIGHT,
"Up": UP,
"PageUp": PAGE_UP,
"PageDown": PAGE_DOWN,
"ScrollUp": SCROLL_UP,
"ScrollDown": SCROLL_DOWN,
"Tab": TAB,
"Escape": ESCAPE,
"End": END,
"Hide": HIDE,
"Require": REQUIRE,
"Show": SHOW,
"Output": OUTPUT,
"Shell": SHELL,
"FontFamily": FONT_FAMILY,
"MarginFill": MARGIN_FILL,
"Margin": MARGIN,
"WindowBar": WINDOW_BAR,
"WindowBarSize": WINDOW_BAR_SIZE,
"BorderRadius": BORDER_RADIUS,
"FontSize": FONT_SIZE,
"Framerate": FRAMERATE,
"Height": HEIGHT,
"LetterSpacing": LETTER_SPACING,
"LineHeight": LINE_HEIGHT,
"PlaybackSpeed": PLAYBACK_SPEED,
"TypingSpeed": TYPING_SPEED,
"Padding": PADDING,
"Theme": THEME,
"Width": WIDTH,
"LoopOffset": LOOP_OFFSET,
"WaitTimeout": WAIT_TIMEOUT,
"WaitPattern": WAIT_PATTERN,
"Wait": WAIT,
"Source": SOURCE,
"CursorBlink": CURSOR_BLINK,
"true": BOOLEAN,
"false": BOOLEAN,
"Screenshot": SCREENSHOT,
"Copy": COPY,
"Paste": PASTE,
"Env": ENV,
}
// IsSetting returns whether a token is a setting.
func IsSetting(t Type) bool {
switch t {
case SHELL, FONT_FAMILY, FONT_SIZE, LETTER_SPACING, LINE_HEIGHT,
FRAMERATE, TYPING_SPEED, THEME, PLAYBACK_SPEED, HEIGHT, WIDTH,
PADDING, LOOP_OFFSET, MARGIN_FILL, MARGIN, WINDOW_BAR,
WINDOW_BAR_SIZE, BORDER_RADIUS, CURSOR_BLINK, WAIT_TIMEOUT, WAIT_PATTERN:
return true
default:
return false
}
}
// IsCommand returns whether the string is a command.
func IsCommand(t Type) bool {
switch t {
case TYPE, SLEEP,
UP, DOWN, RIGHT, LEFT, PAGE_UP, PAGE_DOWN, SCROLL_UP, SCROLL_DOWN,
ENTER, BACKSPACE, DELETE, TAB,
ESCAPE, HOME, INSERT, END, CTRL, SOURCE, SCREENSHOT, COPY, PASTE, WAIT:
return true
default:
return false
}
}
// IsModifier returns whether the token is a modifier.
func IsModifier(t Type) bool {
return t == ALT || t == SHIFT
}
// String converts a token to it's human readable string format.
func (t Type) String() string {
if IsCommand(t) || IsSetting(t) {
return ToCamel(string(t))
}
return string(t)
}
// ToCamel converts a snake_case string to CamelCase.
func ToCamel(s string) string {
parts := strings.Split(s, "_")
for i, p := range parts {
p = strings.ToUpper(p[:1]) + strings.ToLower(p[1:])
parts[i] = p
}
return strings.Join(parts, "")
}
// LookupIdentifier returns whether the identifier is a keyword.
// In `vhs`, there are no _actual_ identifiers, i.e. there are no variables.
// Instead, identifiers are simply strings (i.e. bare words).
func LookupIdentifier(ident string) Type {
if t, ok := Keywords[ident]; ok {
return t
}
return STRING
}