Class: Walrus::Grammar::Node
- Inherits:
-
Object
- Object
- Walrus::Grammar::Node
- Includes:
- LocationTracking
- Defined in:
- lib/walrus/grammar/node.rb
Overview
Make subclasses of this for us in Abstract Syntax Trees (ASTs).
Class Method Summary collapse
-
.subclass(subclass_name, namespace = Walrus::Grammar, *results) ⇒ Object
Dynamically creates a Node descendant.
Instance Method Summary collapse
Class Method Details
.subclass(subclass_name, namespace = Walrus::Grammar, *results) ⇒ Object
Dynamically creates a Node descendant. subclass_name should be a Symbol or String containing the name of the subclass to be created. namespace should be the module in which the new subclass should be created; it defaults to Walrus::Grammar. results are optional symbols expected to be parsed when initializing an instance of the subclass. If no optional symbols are provided then a default initializer is created that expects a single parameter and stores a reference to it in an instance variable called “lexeme”.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/walrus/grammar/node.rb', line 27 def self.subclass(subclass_name, namespace = Walrus::Grammar, *results) raise ArgumentError if subclass_name.nil? # create new anonymous class with Node as superclass, assigning it to a constant effectively names the class new_class = namespace.const_set(subclass_name.to_s, Class.new(self)) # set up accessors for result in results new_class.class_eval { attr_reader result } end # set up initializer if results.length == 0 # default case, store sole parameter in "lexeme" new_class.class_eval { attr_reader :lexeme } initialize_body = "def initialize(lexeme)\n" initialize_body << "@string_value = lexeme.to_s\n" initialize_body << "@lexeme = lexeme\n" else initialize_body = "def initialize(#{results.collect { |symbol| symbol.to_s}.join(', ')})\n" initialize_body << "@string_value = \"\"\n" for result in results initialize_body << "@#{result.to_s} = #{result.to_s}\n" initialize_body << "@string_value << #{result.to_s}.to_s\n" end end initialize_body << "end\n" new_class.class_eval initialize_body new_class end |
Instance Method Details
#to_s ⇒ Object
19 20 21 |
# File 'lib/walrus/grammar/node.rb', line 19 def to_s @string_value end |