Chervil is a toy Lisp interpreter written in Ruby
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

parser.rb 1.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. module Chervil
  2. class Parser def initialize(lexer)
  3. @lexer = lexer
  4. @tree = Array.new
  5. @current_token = @lexer.get_next_token
  6. end
  7. def parse
  8. until @current_token.type == :eof
  9. @tree << expr
  10. end
  11. @tree
  12. end
  13. def expr
  14. if [:string, :number].include?(@current_token.type)
  15. constant
  16. elsif @current_token.type == :identifier
  17. identifier
  18. elsif @current_token.type == :lparen
  19. application
  20. end
  21. end
  22. def application
  23. eat(:lparen)
  24. if @current_token.type == :identifier && @current_token.value == 'define'
  25. eat(:identifier)
  26. name = identifier
  27. value = expr
  28. eat(:rparen)
  29. return AST::Definition.new(name, value)
  30. end
  31. expression = expr
  32. args = Array.new
  33. until @current_token.type == :rparen
  34. args << expr
  35. end
  36. eat(:rparen)
  37. AST::Application.new(expression, args)
  38. end
  39. def identifier
  40. identifier = eat(:identifier)
  41. AST::Identifier.new(identifier.value)
  42. end
  43. def constant
  44. case @current_token.type
  45. when :number
  46. token = eat(:number)
  47. AST::Number.new(token.value.to_f)
  48. when :string
  49. token = eat(:string)
  50. AST::String.new(token.value)
  51. end
  52. end
  53. def eat(type)
  54. if @current_token.type == type
  55. token = @current_token
  56. @current_token = @lexer.get_next_token
  57. token
  58. else
  59. raise "Expected #{type} but got #{@current_token.type}"
  60. end
  61. end
  62. end
  63. end