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 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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, :'#'),
  43. Token.new(TokenKinds::OPERATOR, :and),
  44. Token.new(TokenKinds::OPERATOR, :or),
  45. Token.new(TokenKinds::OPERATOR, :not),
  46. Token.new(TokenKinds::EOF)
  47. ]
  48. )
  49. end
  50. it 'lexes punctuation' do
  51. expect(Lexer.new('{}()[];,.').scan_all).to eq(
  52. [
  53. Token.new(TokenKinds::LBRACE),
  54. Token.new(TokenKinds::RBRACE),
  55. Token.new(TokenKinds::LPAREN),
  56. Token.new(TokenKinds::RPAREN),
  57. Token.new(TokenKinds::LBRACKET),
  58. Token.new(TokenKinds::RBRACKET),
  59. Token.new(TokenKinds::SEMICOLON),
  60. Token.new(TokenKinds::COMMA),
  61. Token.new(TokenKinds::DOT),
  62. Token.new(TokenKinds::EOF)
  63. ]
  64. )
  65. end
  66. it 'lexes if elseif else' do
  67. expect(Lexer.new('if elseif else').scan_all).to eq(
  68. [
  69. Token.new(TokenKinds::IF),
  70. Token.new(TokenKinds::ELSEIF),
  71. Token.new(TokenKinds::ELSE),
  72. Token.new(TokenKinds::EOF)
  73. ]
  74. )
  75. end
  76. it 'lexes =' do
  77. expect(Lexer.new('=').scan_all).to eq(
  78. [Token.new(TokenKinds::EQUALS), Token.new(TokenKinds::EOF)]
  79. )
  80. end
  81. it 'lexes let' do
  82. expect(Lexer.new('let').scan_all).to eq(
  83. [Token.new(TokenKinds::LET), Token.new(TokenKinds::EOF)]
  84. )
  85. end
  86. it 'lexes identifiers' do
  87. expect(Lexer.new('x').scan_all).to eq(
  88. [Token.new(TokenKinds::IDENTIFIER, 'x'), Token.new(TokenKinds::EOF)]
  89. )
  90. end
  91. it 'lexes function' do
  92. expect(Lexer.new('function').scan_all).to eq(
  93. [Token.new(TokenKinds::FUNCTION), Token.new(TokenKinds::EOF)]
  94. )
  95. end
  96. it 'lexes class' do
  97. expect(Lexer.new('class').scan_all).to eq(
  98. [Token.new(TokenKinds::CLASS), Token.new(TokenKinds::EOF)]
  99. )
  100. end
  101. it 'lexes class names' do
  102. expect(Lexer.new('Class').scan_all).to eq(
  103. [Token.new(TokenKinds::CLASS_NAME, 'Class'), Token.new(TokenKinds::EOF)]
  104. )
  105. end
  106. it 'lexes public and private' do
  107. expect(Lexer.new('public private').scan_all).to eq(
  108. [
  109. Token.new(TokenKinds::PUBLIC),
  110. Token.new(TokenKinds::PRIVATE),
  111. Token.new(TokenKinds::EOF)
  112. ]
  113. )
  114. end
  115. it 'lexes hash' do
  116. expect(Lexer.new('{ :a => 1 }').scan_all).to eq(
  117. [
  118. Token.new(TokenKinds::LBRACE),
  119. Token.new(TokenKinds::ATOM, :a),
  120. Token.new(TokenKinds::ROCKET),
  121. Token.new(TokenKinds::NUMBER, 1.0),
  122. Token.new(TokenKinds::RBRACE),
  123. Token.new(TokenKinds::EOF)
  124. ]
  125. )
  126. end
  127. it 'lexes for' do
  128. expect(Lexer.new('for in').scan_all).to eq(
  129. [
  130. Token.new(TokenKinds::FOR),
  131. Token.new(TokenKinds::IN),
  132. Token.new(TokenKinds::EOF)
  133. ]
  134. )
  135. end
  136. it 'allows escaping quotes in strings' do
  137. expect(Lexer.new('"hello \"world\""').scan_all).to eq(
  138. [
  139. Token.new(TokenKinds::STRING, 'hello "world"'),
  140. Token.new(TokenKinds::EOF)
  141. ]
  142. )
  143. end
  144. it 'supports newlines and tabs in strings' do
  145. expect(Lexer.new('"hello\nworld" "hello\tworld"').scan_all).to eq(
  146. [
  147. Token.new(TokenKinds::STRING, "hello\nworld"),
  148. Token.new(TokenKinds::STRING, "hello\tworld"),
  149. Token.new(TokenKinds::EOF)
  150. ]
  151. )
  152. end
  153. it 'ignores comments' do
  154. expect(Lexer.new("// prints 5\nprint(5)").scan_all).to eq(
  155. [
  156. Token.new(TokenKinds::IDENTIFIER, 'print'),
  157. Token.new(TokenKinds::LPAREN),
  158. Token.new(TokenKinds::NUMBER, 5),
  159. Token.new(TokenKinds::RPAREN),
  160. Token.new(TokenKinds::EOF)
  161. ]
  162. )
  163. end
  164. end