parser.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package glisp
  2. import (
  3. "errors"
  4. "fmt"
  5. "strconv"
  6. )
  7. type Parser struct {
  8. lexer *Lexer
  9. env *Glisp
  10. }
  11. var UnexpectedEnd error = errors.New("Unexpected end of input")
  12. const SliceDefaultCap = 10
  13. func ParseList(parser *Parser) (Sexp, error) {
  14. lexer := parser.lexer
  15. tok, err := lexer.PeekNextToken()
  16. if err != nil {
  17. return SexpNull, err
  18. }
  19. if tok.typ == TokenEnd {
  20. _, _ = lexer.GetNextToken()
  21. return SexpEnd, UnexpectedEnd
  22. }
  23. if tok.typ == TokenRParen {
  24. _, _ = lexer.GetNextToken()
  25. return SexpNull, nil
  26. }
  27. var start SexpPair
  28. expr, err := ParseExpression(parser)
  29. if err != nil {
  30. return SexpNull, err
  31. }
  32. start.head = expr
  33. tok, err = lexer.PeekNextToken()
  34. if err != nil {
  35. return SexpNull, err
  36. }
  37. if tok.typ == TokenDot {
  38. // eat up the dot
  39. _, _ = lexer.GetNextToken()
  40. expr, err = ParseExpression(parser)
  41. if err != nil {
  42. return SexpNull, err
  43. }
  44. // eat up the end paren
  45. tok, err = lexer.GetNextToken()
  46. if err != nil {
  47. return SexpNull, err
  48. }
  49. // make sure it was actually an end paren
  50. if tok.typ != TokenRParen {
  51. return SexpNull, errors.New("extra value in dotted pair")
  52. }
  53. start.tail = expr
  54. return start, nil
  55. }
  56. expr, err = ParseList(parser)
  57. if err != nil {
  58. return start, err
  59. }
  60. start.tail = expr
  61. return start, nil
  62. }
  63. func ParseArray(parser *Parser) (Sexp, error) {
  64. lexer := parser.lexer
  65. arr := make([]Sexp, 0, SliceDefaultCap)
  66. for {
  67. tok, err := lexer.PeekNextToken()
  68. if err != nil {
  69. return SexpEnd, err
  70. }
  71. if tok.typ == TokenEnd {
  72. return SexpEnd, UnexpectedEnd
  73. }
  74. if tok.typ == TokenRSquare {
  75. // pop off the ]
  76. _, _ = lexer.GetNextToken()
  77. break
  78. }
  79. expr, err := ParseExpression(parser)
  80. if err != nil {
  81. return SexpNull, err
  82. }
  83. arr = append(arr, expr)
  84. }
  85. return SexpArray(arr), nil
  86. }
  87. func ParseHash(parser *Parser) (Sexp, error) {
  88. lexer := parser.lexer
  89. arr := make([]Sexp, 0, SliceDefaultCap)
  90. for {
  91. tok, err := lexer.PeekNextToken()
  92. if err != nil {
  93. return SexpEnd, err
  94. }
  95. if tok.typ == TokenEnd {
  96. return SexpEnd, UnexpectedEnd
  97. }
  98. if tok.typ == TokenRCurly {
  99. // pop off the }
  100. _, _ = lexer.GetNextToken()
  101. break
  102. }
  103. expr, err := ParseExpression(parser)
  104. if err != nil {
  105. return SexpNull, err
  106. }
  107. arr = append(arr, expr)
  108. }
  109. var list SexpPair
  110. list.head = parser.env.MakeSymbol("hash")
  111. list.tail = MakeList(arr)
  112. return list, nil
  113. }
  114. func ParseExpression(parser *Parser) (Sexp, error) {
  115. lexer := parser.lexer
  116. env := parser.env
  117. tok, err := lexer.GetNextToken()
  118. if err != nil {
  119. return SexpEnd, err
  120. }
  121. switch tok.typ {
  122. case TokenLParen:
  123. return ParseList(parser)
  124. case TokenLSquare:
  125. return ParseArray(parser)
  126. case TokenLCurly:
  127. return ParseHash(parser)
  128. case TokenQuote:
  129. expr, err := ParseExpression(parser)
  130. if err != nil {
  131. return SexpNull, err
  132. }
  133. return MakeList([]Sexp{env.MakeSymbol("quote"), expr}), nil
  134. case TokenBacktick:
  135. expr, err := ParseExpression(parser)
  136. if err != nil {
  137. return SexpNull, err
  138. }
  139. return MakeList([]Sexp{env.MakeSymbol("syntax-quote"), expr}), nil
  140. case TokenTilde:
  141. expr, err := ParseExpression(parser)
  142. if err != nil {
  143. return SexpNull, err
  144. }
  145. return MakeList([]Sexp{env.MakeSymbol("unquote"), expr}), nil
  146. case TokenTildeAt:
  147. expr, err := ParseExpression(parser)
  148. if err != nil {
  149. return SexpNull, err
  150. }
  151. return MakeList([]Sexp{env.MakeSymbol("unquote-splicing"), expr}), nil
  152. case TokenSymbol:
  153. return env.MakeSymbol(tok.str), nil
  154. case TokenBool:
  155. return SexpBool(tok.str == "true"), nil
  156. case TokenDecimal:
  157. i, err := strconv.ParseInt(tok.str, 10, SexpIntSize)
  158. if err != nil {
  159. return SexpNull, err
  160. }
  161. return SexpInt(i), nil
  162. case TokenHex:
  163. i, err := strconv.ParseInt(tok.str, 16, SexpIntSize)
  164. if err != nil {
  165. return SexpNull, err
  166. }
  167. return SexpInt(i), nil
  168. case TokenOct:
  169. i, err := strconv.ParseInt(tok.str, 8, SexpIntSize)
  170. if err != nil {
  171. return SexpNull, err
  172. }
  173. return SexpInt(i), nil
  174. case TokenBinary:
  175. i, err := strconv.ParseInt(tok.str, 2, SexpIntSize)
  176. if err != nil {
  177. return SexpNull, err
  178. }
  179. return SexpInt(i), nil
  180. case TokenChar:
  181. return SexpChar(tok.str[0]), nil
  182. case TokenString:
  183. return SexpStr(tok.str), nil
  184. case TokenFloat:
  185. f, err := strconv.ParseFloat(tok.str, SexpFloatSize)
  186. if err != nil {
  187. return SexpNull, err
  188. }
  189. return SexpFloat(f), nil
  190. case TokenEnd:
  191. return SexpEnd, nil
  192. }
  193. return SexpNull, errors.New(fmt.Sprint("Invalid syntax, didn't know what to do with ", tok.typ, " ", tok))
  194. }
  195. func ParseTokens(env *Glisp, lexer *Lexer) ([]Sexp, error) {
  196. expressions := make([]Sexp, 0, SliceDefaultCap)
  197. parser := Parser{lexer, env}
  198. for {
  199. expr, err := ParseExpression(&parser)
  200. if err != nil {
  201. return expressions, err
  202. }
  203. if expr == SexpEnd {
  204. break
  205. }
  206. expressions = append(expressions, expr)
  207. }
  208. return expressions, nil
  209. }