namespace GolangLean

/-! # Token kinds — mirrors `go/token/token.go`.

This is a faithful Lean port of the Go reference scanner's token enumeration.
Comments next to each constructor cite the Go name where it differs in casing
or spelling. Source: `go-upstream/src/go/token/token.go`. -/

inductive Tok where
  -- Special
  | illegal
  | eof
  | comment
  -- Literals (carry their lexeme)
  | ident       (s : String)
  | intLit      (s : String)
  | floatLit    (s : String)
  | imagLit     (s : String)
  | charLit     (s : String)
  | stringLit   (s : String)
  -- Operators & punctuation
  | add | sub | mul | quo | rem
  | and | or  | xor | shl | shr | andNot
  | addAssign | subAssign | mulAssign | quoAssign | remAssign
  | andAssign | orAssign  | xorAssign | shlAssign | shrAssign | andNotAssign
  | landTok | lorTok | arrow | inc | dec
  | eql | lss | gtr | assign | not
  | neq | leq | geq | define | ellipsis
  | lparen | lbrack | lbrace | comma | period
  | rparen | rbrack | rbrace | semicolon | colon
  -- Keywords
  | breakK | caseK | chanK | constK | continueK
  | defaultK | deferK | elseK | fallthroughK | forK
  | funcK | goK | gotoK | ifK | importK
  | interfaceK | mapK | packageK | rangeK | returnK
  | selectK | structK | switchK | typeK | varK
  -- Tilde introduced for generics (Go 1.18)
  | tilde
  deriving Repr, BEq, Inhabited

/-- Source-position metadata attached to a token. -/
structure Pos where
  line : Nat
  col  : Nat
  off  : Nat
  deriving Repr, BEq, Inhabited

structure Token where
  tok : Tok
  pos : Pos
  deriving Repr, Inhabited

/-- Map a keyword spelling to its token, or `none` if it is just an identifier. -/
def keyword? : String → Option Tok
  | "break"        => some .breakK
  | "case"         => some .caseK
  | "chan"         => some .chanK
  | "const"        => some .constK
  | "continue"     => some .continueK
  | "default"      => some .defaultK
  | "defer"        => some .deferK
  | "else"         => some .elseK
  | "fallthrough"  => some .fallthroughK
  | "for"          => some .forK
  | "func"         => some .funcK
  | "go"           => some .goK
  | "goto"         => some .gotoK
  | "if"           => some .ifK
  | "import"       => some .importK
  | "interface"    => some .interfaceK
  | "map"          => some .mapK
  | "package"      => some .packageK
  | "range"        => some .rangeK
  | "return"       => some .returnK
  | "select"       => some .selectK
  | "struct"       => some .structK
  | "switch"       => some .switchK
  | "type"         => some .typeK
  | "var"          => some .varK
  | _              => none

end GolangLean
