class Fictive::Text::Compiler

Attributes

scanner[R]

Public Class Methods

new(input) click to toggle source
# File lib/fictive/text/compiler.rb, line 6
def initialize(input)
  @input = input
end

Public Instance Methods

process(symbol_table={}) click to toggle source
# File lib/fictive/text/compiler.rb, line 10
def process(symbol_table={})
  @symbol_table = symbol_table
  @scanner = StringScanner.new(@input)

  Fictive::Text::Node.new(*parse_fragments)
end

Private Instance Methods

parse_conditional() click to toggle source
# File lib/fictive/text/compiler.rb, line 61
def parse_conditional
  raise 'missing whitespace in conditional tag' unless scanner.scan(/\s+/)

  expression = parse_expression
  scanner.skip(/:/)
  scanner.skip(/\s/)
  consequent = scanner.scan_until(/\]/).gsub(/\]/, '')

  Fictive::Text::ConditionalNode.new(
    Fictive::Text::ExpressionNode.new(
      expression
    ),
    Fictive::Text::TextNode.new(consequent)
  )
end
parse_directive() click to toggle source
# File lib/fictive/text/compiler.rb, line 44
def parse_directive
  return parse_conditional if scanner.scan(/if/)

  raise 'Invalid syntax'
end
parse_expression() click to toggle source
# File lib/fictive/text/compiler.rb, line 77
def parse_expression
  Fictive::Text::TrueNode.new if scanner.scan(/true/)
end
parse_fragment() click to toggle source
# File lib/fictive/text/compiler.rb, line 27
def parse_fragment
  concat_fragment = scanner.scan_until(/{/)

  if concat_fragment
    Fictive::Text::Node.new(Fictive::Text::TextNode.new(concat_fragment.gsub(/{/, '')), parse_substitution)
  else
    concat_before_directive = scanner.scan_until(/\[/)

    if concat_before_directive
      Fictive::Text::Node.new(Fictive::Text::TextNode.new(concat_before_directive.gsub(/\[/, '')), parse_directive)
    else
      fragment = scanner.scan(/.+/)
      Fictive::Text::TextNode.new(fragment)
    end
  end
end
parse_fragments() click to toggle source
# File lib/fictive/text/compiler.rb, line 21
def parse_fragments
  fragments = []
  fragments << parse_fragment while !scanner.eos?
  fragments
end
parse_substitution() click to toggle source
# File lib/fictive/text/compiler.rb, line 50
def parse_substitution
  scanner.skip(/\s/)

  if reference = scanner.scan(/[A-Za-z0-9_\-!]+/)
    scanner.skip(/\s*}/)
    Fictive::Text::ReferenceNode.new(reference, @symbol_table)
  else
    raise 'Invalid syntax'
  end
end