A toy dynamic programming language written in Ruby
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

lexer_spec.rb 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. RSpec.describe Lexer do
  2. it 'lexes null' do
  3. expect(Lexer.new('null').scan_all).to eq(
  4. [Token.new(TokenKinds::NULL), Token.new(TokenKinds::EOF)]
  5. )
  6. end
  7. it 'lexes booleans' do
  8. expect(Lexer.new('true false').scan_all).to eq(
  9. [
  10. Token.new(TokenKinds::BOOLEAN, true),
  11. Token.new(TokenKinds::BOOLEAN, false),
  12. Token.new(TokenKinds::EOF)
  13. ]
  14. )
  15. end
  16. it 'lexes numbers' do
  17. expect(Lexer.new('1 2.3').scan_all).to eq(
  18. [
  19. Token.new(TokenKinds::NUMBER, 1.0),
  20. Token.new(TokenKinds::NUMBER, 2.3),
  21. Token.new(TokenKinds::EOF)
  22. ]
  23. )
  24. end
  25. it 'lexes strings' do
  26. expect(Lexer.new('"hello world"').scan_all).to eq(
  27. [Token.new(TokenKinds::STRING, 'hello world'), Token.new(TokenKinds::EOF)]
  28. )
  29. end
  30. it 'lexes operators' do
  31. expect(Lexer.new('+-*/<<=>>=== and or not').scan_all).to eq(
  32. [
  33. Token.new(TokenKinds::OPERATOR, :+),
  34. Token.new(TokenKinds::OPERATOR, :-),
  35. Token.new(TokenKinds::OPERATOR, :*),
  36. Token.new(TokenKinds::OPERATOR, :/),
  37. Token.new(TokenKinds::OPERATOR, :<),
  38. Token.new(TokenKinds::OPERATOR, :<=),
  39. Token.new(TokenKinds::OPERATOR, :>),
  40. Token.new(TokenKinds::OPERATOR, :>=),
  41. Token.new(TokenKinds::OPERATOR, :==),
  42. Token.new(TokenKinds::OPERATOR, :and),
  43. Token.new(TokenKinds::OPERATOR, :or),
  44. Token.new(TokenKinds::OPERATOR, :not),
  45. Token.new(TokenKinds::EOF)
  46. ]
  47. )
  48. end
  49. it 'lexes punctuation' do
  50. expect(Lexer.new('{}()[];,.').scan_all).to eq(
  51. [
  52. Token.new(TokenKinds::LBRACE),
  53. Token.new(TokenKinds::RBRACE),
  54. Token.new(TokenKinds::LPAREN),
  55. Token.new(TokenKinds::RPAREN),
  56. Token.new(TokenKinds::LBRACKET),
  57. Token.new(TokenKinds::RBRACKET),
  58. Token.new(TokenKinds::SEMICOLON),
  59. Token.new(TokenKinds::COMMA),
  60. Token.new(TokenKinds::DOT),
  61. Token.new(TokenKinds::EOF)
  62. ]
  63. )
  64. end
  65. it 'lexes if elseif else' do
  66. expect(Lexer.new('if elseif else').scan_all).to eq(
  67. [
  68. Token.new(TokenKinds::IF),
  69. Token.new(TokenKinds::ELSEIF),
  70. Token.new(TokenKinds::ELSE),
  71. Token.new(TokenKinds::EOF)
  72. ]
  73. )
  74. end
  75. it 'lexes =' do
  76. expect(Lexer.new('=').scan_all).to eq(
  77. [Token.new(TokenKinds::EQUALS), Token.new(TokenKinds::EOF)]
  78. )
  79. end
  80. it 'lexes let' do
  81. expect(Lexer.new('let').scan_all).to eq(
  82. [Token.new(TokenKinds::LET), Token.new(TokenKinds::EOF)]
  83. )
  84. end
  85. it 'lexes identifiers' do
  86. expect(Lexer.new('x').scan_all).to eq(
  87. [Token.new(TokenKinds::IDENTIFIER, 'x'), Token.new(TokenKinds::EOF)]
  88. )
  89. end
  90. it 'lexes function' do
  91. expect(Lexer.new('function').scan_all).to eq(
  92. [Token.new(TokenKinds::FUNCTION), Token.new(TokenKinds::EOF)]
  93. )
  94. end
  95. it 'lexes class' do
  96. expect(Lexer.new('class').scan_all).to eq(
  97. [Token.new(TokenKinds::CLASS), Token.new(TokenKinds::EOF)]
  98. )
  99. end
  100. it 'lexes class names' do
  101. expect(Lexer.new('Class').scan_all).to eq(
  102. [Token.new(TokenKinds::CLASS_NAME, 'Class'), Token.new(TokenKinds::EOF)]
  103. )
  104. end
  105. it 'lexes public and private' do
  106. expect(Lexer.new('public private').scan_all).to eq(
  107. [
  108. Token.new(TokenKinds::PUBLIC),
  109. Token.new(TokenKinds::PRIVATE),
  110. Token.new(TokenKinds::EOF)
  111. ]
  112. )
  113. end
  114. it 'lexes hash' do
  115. expect(Lexer.new('{ :a => 1 }').scan_all).to eq(
  116. [
  117. Token.new(TokenKinds::LBRACE),
  118. Token.new(TokenKinds::ATOM, :a),
  119. Token.new(TokenKinds::ROCKET),
  120. Token.new(TokenKinds::NUMBER, 1.0),
  121. Token.new(TokenKinds::RBRACE),
  122. Token.new(TokenKinds::EOF)
  123. ]
  124. )
  125. end
  126. it 'lexes for' do
  127. expect(Lexer.new('for in').scan_all).to eq(
  128. [
  129. Token.new(TokenKinds::FOR),
  130. Token.new(TokenKinds::IN),
  131. Token.new(TokenKinds::EOF)
  132. ]
  133. )
  134. end
  135. it 'allows escaping quotes in strings' do
  136. expect(Lexer.new('"hello \"world\""').scan_all).to eq(
  137. [
  138. Token.new(TokenKinds::STRING, 'hello "world"'),
  139. Token.new(TokenKinds::EOF)
  140. ]
  141. )
  142. end
  143. it 'supports newlines and tabs in strings' do
  144. expect(Lexer.new('"hello\nworld" "hello\tworld"').scan_all).to eq(
  145. [
  146. Token.new(TokenKinds::STRING, "hello\nworld"),
  147. Token.new(TokenKinds::STRING, "hello\tworld"),
  148. Token.new(TokenKinds::EOF)
  149. ]
  150. )
  151. end
  152. it 'ignores comments' do
  153. expect(Lexer.new("// prints 5\nprint(5)").scan_all).to eq(
  154. [
  155. Token.new(TokenKinds::IDENTIFIER, 'print'),
  156. Token.new(TokenKinds::LPAREN),
  157. Token.new(TokenKinds::NUMBER, 5),
  158. Token.new(TokenKinds::RPAREN),
  159. Token.new(TokenKinds::EOF)
  160. ]
  161. )
  162. end
  163. it 'lexes hashes' do
  164. expect(Lexer.new('#').scan_all).to eq(
  165. [Token.new(TokenKinds::HASH), Token.new(TokenKinds::EOF)]
  166. )
  167. end
  168. it 'lexes method and classmethod' do
  169. expect(Lexer.new('method classmethod').scan_all).to eq(
  170. [
  171. Token.new(TokenKinds::METHOD),
  172. Token.new(TokenKinds::CLASSMETHOD),
  173. Token.new(TokenKinds::EOF)
  174. ]
  175. )
  176. end
  177. end