seq-compiler 5.4.0

Compiler for the Seq programming language
Documentation
# Default Seq Lint Rules
#
# These patterns detect common inefficiencies and suggest improvements.
# Phase 1: Syntactic patterns (word sequence matching)

# =============================================================================
# Redundant Operations (no-ops)
# =============================================================================

[[lint]]
id = "redundant-dup-drop"
pattern = "dup drop"
replacement = ""
message = "`dup drop` has no effect - remove both words"
severity = "warning"

[[lint]]
id = "redundant-swap-swap"
pattern = "swap swap"
replacement = ""
message = "consecutive `swap swap` cancel out - remove both"
severity = "warning"

[[lint]]
id = "redundant-over-drop"
pattern = "over drop"
replacement = ""
message = "`over drop` has no effect - remove both words"
severity = "warning"

[[lint]]
id = "redundant-dup-nip"
pattern = "dup nip"
replacement = ""
message = "`dup nip` has no effect - remove both words"
severity = "warning"

[[lint]]
id = "redundant-rot-rot-rot"
pattern = "rot rot rot"
replacement = ""
message = "three `rot` calls cancel out - remove all three"
severity = "warning"

# =============================================================================
# Prefer Idiomatic Words
# =============================================================================

[[lint]]
id = "prefer-nip"
pattern = "swap drop"
replacement = "nip"
message = "prefer `nip` over `swap drop`"
severity = "hint"

[[lint]]
id = "prefer-tuck"
pattern = "swap over"
replacement = "tuck"
message = "prefer `tuck` over `swap over`"
severity = "hint"

[[lint]]
id = "prefer-2dup"
pattern = "over over"
replacement = "2dup"
message = "prefer `2dup` over `over over`"
severity = "hint"

# =============================================================================
# Potentially Suspicious Patterns
# =============================================================================

[[lint]]
id = "drop-drop-drop"
pattern = "drop drop drop"
replacement = ""
message = "dropping three values in a row - consider using `3drop` or refactoring to avoid excess stack values"
severity = "hint"

# NOTE: "immediate-drop" pattern ([ drop) removed - it incorrectly matches
# across statement boundaries. Will be re-added when quotation-specific
# linting is implemented in Phase 2.

# =============================================================================
# Unchecked Error Returns
# =============================================================================
# Operations that return (value Bool) or just Bool as a success flag
# should have their flags checked. Dropping the flag hides errors.
#
# Severity guide:
#   warning = data loss or silent corruption likely (I/O, channels, crypto)
#   hint    = may be intentional but worth reviewing (parsing, lookups)

# --- Channels ---

[[lint]]
id = "unchecked-chan-send"
pattern = "chan.send drop"
replacement = ""
message = "`chan.send` returns a success flag - dropping it hides send failures"
severity = "warning"

[[lint]]
id = "unchecked-chan-receive"
pattern = "chan.receive drop"
replacement = ""
message = "`chan.receive` returns (value Bool) - check the Bool before using the value"
severity = "warning"

# --- File I/O ---

[[lint]]
id = "unchecked-file-slurp"
pattern = "file.slurp drop"
replacement = ""
message = "`file.slurp` returns (content Bool) - check the Bool before using the content"
severity = "warning"

[[lint]]
id = "unchecked-file-spit"
pattern = "file.spit drop"
replacement = ""
message = "`file.spit` returns Bool success flag - dropping it hides write failures"
severity = "warning"

[[lint]]
id = "unchecked-file-append"
pattern = "file.append drop"
replacement = ""
message = "`file.append` returns Bool success flag - dropping it hides write failures"
severity = "warning"

[[lint]]
id = "unchecked-file-size"
pattern = "file.size drop"
replacement = ""
message = "`file.size` returns (Int Bool) - check the Bool before using the size"
severity = "hint"

[[lint]]
id = "unchecked-dir-list"
pattern = "dir.list drop"
replacement = ""
message = "`dir.list` returns (List Bool) - check the Bool before using the list"
severity = "hint"

# --- I/O ---

[[lint]]
id = "unchecked-read-line"
pattern = "io.read-line drop"
replacement = ""
message = "`io.read-line` returns (String Bool) - check the Bool before using the String"
severity = "hint"

# --- Integer Division ---

[[lint]]
id = "unchecked-div"
pattern = "i./ drop"
replacement = ""
message = "`i./` returns (Int Bool) - dropping the Bool hides division-by-zero"
severity = "warning"

[[lint]]
id = "unchecked-divide"
pattern = "i.divide drop"
replacement = ""
message = "`i.divide` returns (Int Bool) - dropping the Bool hides division-by-zero"
severity = "warning"

[[lint]]
id = "unchecked-mod"
pattern = "i.% drop"
replacement = ""
message = "`i.%` returns (Int Bool) - dropping the Bool hides division-by-zero"
severity = "warning"

[[lint]]
id = "unchecked-modulo"
pattern = "i.modulo drop"
replacement = ""
message = "`i.modulo` returns (Int Bool) - dropping the Bool hides division-by-zero"
severity = "warning"

# --- String Parsing ---

[[lint]]
id = "unchecked-string-to-int"
pattern = "string->int drop"
replacement = ""
message = "`string->int` returns (Int Bool) - check the Bool to detect parse failures"
severity = "hint"

[[lint]]
id = "unchecked-string-to-float"
pattern = "string->float drop"
replacement = ""
message = "`string->float` returns (Float Bool) - check the Bool to detect parse failures"
severity = "hint"

# --- Map/List Lookups ---

[[lint]]
id = "unchecked-map-get"
pattern = "map.get drop"
replacement = ""
message = "`map.get` returns (value Bool) - check the Bool before using the value"
severity = "hint"

[[lint]]
id = "unchecked-list-get"
pattern = "list.get drop"
replacement = ""
message = "`list.get` returns (value Bool) - check the Bool for out-of-bounds access"
severity = "hint"

[[lint]]
id = "unchecked-list-set"
pattern = "list.set drop"
replacement = ""
message = "`list.set` returns (List Bool) - check the Bool for out-of-bounds access"
severity = "hint"

# --- TCP Networking ---

[[lint]]
id = "unchecked-tcp-listen"
pattern = "tcp.listen drop"
replacement = ""
message = "`tcp.listen` returns (fd Bool) - check the Bool before using the file descriptor"
severity = "warning"

[[lint]]
id = "unchecked-tcp-accept"
pattern = "tcp.accept drop"
replacement = ""
message = "`tcp.accept` returns (fd Bool) - check the Bool before using the connection"
severity = "warning"

[[lint]]
id = "unchecked-tcp-read"
pattern = "tcp.read drop"
replacement = ""
message = "`tcp.read` returns (String Bool) - check the Bool before using the data"
severity = "warning"

[[lint]]
id = "unchecked-tcp-write"
pattern = "tcp.write drop"
replacement = ""
message = "`tcp.write` returns Bool success flag - dropping it hides write failures"
severity = "warning"

# --- OS Operations ---

[[lint]]
id = "unchecked-getenv"
pattern = "os.getenv drop"
replacement = ""
message = "`os.getenv` returns (String Bool) - check the Bool for missing env vars"
severity = "hint"

[[lint]]
id = "unchecked-path-parent"
pattern = "os.path-parent drop"
replacement = ""
message = "`os.path-parent` returns (String Bool) - check the Bool (root has no parent)"
severity = "hint"

# --- Regex ---

[[lint]]
id = "unchecked-regex-find"
pattern = "regex.find drop"
replacement = ""
message = "`regex.find` returns (String Bool) - check the Bool for no match or invalid regex"
severity = "hint"

[[lint]]
id = "unchecked-regex-replace"
pattern = "regex.replace drop"
replacement = ""
message = "`regex.replace` returns (String Bool) - check the Bool for invalid regex"
severity = "hint"

[[lint]]
id = "unchecked-regex-replace-all"
pattern = "regex.replace-all drop"
replacement = ""
message = "`regex.replace-all` returns (String Bool) - check the Bool for invalid regex"
severity = "hint"

# --- Encoding ---

[[lint]]
id = "unchecked-base64-decode"
pattern = "encoding.base64-decode drop"
replacement = ""
message = "`encoding.base64-decode` returns (String Bool) - check the Bool for invalid input"
severity = "hint"

[[lint]]
id = "unchecked-hex-decode"
pattern = "encoding.hex-decode drop"
replacement = ""
message = "`encoding.hex-decode` returns (String Bool) - check the Bool for invalid input"
severity = "hint"

# --- Crypto ---

[[lint]]
id = "unchecked-aes-encrypt"
pattern = "crypto.aes-gcm-encrypt drop"
replacement = ""
message = "`crypto.aes-gcm-encrypt` returns (String Bool) - check the Bool for encryption failures"
severity = "warning"

[[lint]]
id = "unchecked-aes-decrypt"
pattern = "crypto.aes-gcm-decrypt drop"
replacement = ""
message = "`crypto.aes-gcm-decrypt` returns (String Bool) - check the Bool for decryption failures (wrong key, tampered data)"
severity = "warning"

[[lint]]
id = "unchecked-ed25519-sign"
pattern = "crypto.ed25519-sign drop"
replacement = ""
message = "`crypto.ed25519-sign` returns (String Bool) - check the Bool for signing failures"
severity = "warning"

# --- Compression ---

[[lint]]
id = "unchecked-gunzip"
pattern = "compress.gunzip drop"
replacement = ""
message = "`compress.gunzip` returns (String Bool) - check the Bool for decompression failures"
severity = "hint"

[[lint]]
id = "unchecked-unzstd"
pattern = "compress.unzstd drop"
replacement = ""
message = "`compress.unzstd` returns (String Bool) - check the Bool for decompression failures"
severity = "hint"

# =============================================================================
# Weave/Generator Resource Leaks
# =============================================================================
# Weaves must be either resumed to completion OR explicitly cancelled.
# Dropping a WeaveHandle without doing either causes the coroutine to hang.

[[lint]]
id = "weave-immediate-drop"
pattern = "strand.weave drop"
replacement = ""
message = "`strand.weave` handle dropped immediately - weave will hang forever. Use `strand.weave-cancel` or resume to completion."
severity = "error"

[[lint]]
id = "unchecked-resume"
pattern = "strand.resume drop drop drop"
replacement = ""
message = "`strand.resume` returns (handle value Bool) - check the Bool to detect weave completion and avoid resource leaks"
severity = "warning"

[[lint]]
id = "unchecked-resume-result"
pattern = "strand.resume drop drop"
replacement = ""
message = "`strand.resume` returns (handle value Bool) - the Bool indicates if the weave has more values"
severity = "hint"