token.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package muesli
  2. import (
  3. "fmt"
  4. )
  5. /* Position of a token in an input stream */
  6. type Position struct {
  7. FileName string
  8. Line int
  9. Column int
  10. }
  11. func (p Position) String() string {
  12. return fmt.Sprintf("%s:%d:%d", p.FileName, p.Line, p.Column)
  13. }
  14. /* Token Kind. Uses a rune to easily handle single character tokens. */
  15. type TokenKind rune
  16. const (
  17. TokenKindNone = TokenKind(0)
  18. TokenKindInteger = TokenKind('i')
  19. TokenKindFloat = TokenKind('f')
  20. TokenKindString = TokenKind('s')
  21. TokenKindSymbol = TokenKind('S')
  22. TokenKindBoolean = TokenKind('b')
  23. TokenKindNil = TokenKind('N')
  24. TokenKindWord = TokenKind('w')
  25. TokenKindType = TokenKind('t')
  26. TokenKindOperator = TokenKind('o')
  27. TokenKindGet = TokenKind('$')
  28. TokenKindSet = TokenKind('=')
  29. TokenKindOpenBlock = TokenKind('{')
  30. TokenKindCloseBlock = TokenKind('}')
  31. TokenKindOpenList = TokenKind('[')
  32. TokenKindCloseList = TokenKind(']')
  33. TokenKindOpenParen = TokenKind('(')
  34. TokenKindCloseParen = TokenKind(')')
  35. TokenKindError = TokenKind('!')
  36. TokenKindEOX = TokenKind('\n')
  37. TokenKindEOF = TokenKind(0x255)
  38. )
  39. /* Names of the different token types. */
  40. var TokenKindNames map[TokenKind]string = map[TokenKind]string{
  41. TokenKindNone: "None",
  42. TokenKindInteger: "Integer",
  43. TokenKindFloat: "Float",
  44. TokenKindSymbol: "Symbol",
  45. TokenKindString: "String",
  46. TokenKindBoolean: "Boolean",
  47. TokenKindNil: "Nil",
  48. TokenKindWord: "Word",
  49. TokenKindType: "Type",
  50. TokenKindOperator: "Operator",
  51. TokenKindGet: "Get",
  52. TokenKindSet: "Set",
  53. TokenKindOpenBlock: "OpenBlock",
  54. TokenKindCloseBlock: "CloseBlock",
  55. TokenKindOpenList: "OpenList",
  56. TokenKindCloseList: "CloseList",
  57. TokenKindOpenParen: "OpenParen",
  58. TokenKindCloseParen: "CloseParen",
  59. TokenKindError: "Error",
  60. TokenKindEOX: "EOX",
  61. TokenKindEOF: "EOF",
  62. }
  63. /* Reverse map of the names of the different token types. */
  64. var NamesTokenKind map[string] TokenKind = map[string]TokenKind{}
  65. func init () {
  66. for k, v := range TokenKindNames {
  67. NamesTokenKind[v] = k
  68. }
  69. }
  70. /* Transforms a token kind to a String */
  71. func (kind TokenKind) String() string {
  72. name, ok := TokenKindNames[kind]
  73. if !ok {
  74. return "Unknown TokenKind!"
  75. }
  76. return name
  77. }
  78. type Token struct {
  79. TokenKind
  80. Value
  81. Position
  82. }
  83. func (token Token) String() string {
  84. if token.Value == nil {
  85. return fmt.Sprintf("%s:%s:nil", token.Position.String(), token.TokenKind.String())
  86. }
  87. return fmt.Sprintf("%s:%s:%v", token.Position.String(), token.TokenKind.String(), token.Value)
  88. }
  89. func (token Token) Error() string {
  90. if token.TokenKind == TokenKindError {
  91. return token.Value.String()
  92. }
  93. return "No error"
  94. }
  95. /* Returns whether or not the token is the last to be expected,
  96. * that is either an error or EOF. */
  97. func (token Token) IsLast() bool {
  98. switch token.TokenKind {
  99. case TokenKindError, TokenKindEOF, TokenKindNone:
  100. return true
  101. default:
  102. return false
  103. }
  104. }
  105. /* Creates a new token. */
  106. func NewToken(kind TokenKind, val Value, pos Position) Token {
  107. return Token{kind, val, pos}
  108. }
  109. /* Creates a token with type TokenTypeNone */
  110. func NoToken() Token {
  111. return NewToken(TokenKindNone, NilValue, Position{})
  112. }
  113. func (token Token) IsNone() bool {
  114. return token.TokenKind == TokenKindNone
  115. }
  116. func (token Token) IsError() bool {
  117. return token.TokenKind == TokenKindError
  118. }