Class: Walrus::Grammar::Node

Inherits:
Object
  • Object
show all
Includes:
LocationTracking
Defined in:
lib/walrus/grammar/node.rb

Overview

Make subclasses of this for us in Abstract Syntax Trees (ASTs).

Instance Attribute Summary

Attributes included from LocationTracking

#outer_end, #outer_source_text, #outer_start, #source_text

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LocationTracking

#column_end, #column_end=, #column_start, #column_start=, #end, #end=, #line_end, #line_end=, #line_start, #line_start=, #rightmost?, #start, #start=

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”.

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/walrus/grammar/node.rb', line 33

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_sObject



25
26
27
# File 'lib/walrus/grammar/node.rb', line 25

def to_s
  @string_value
end