File: compiler.rb

package info (click to toggle)
ruby-hamlit 2.15.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,996 kB
  • sloc: ruby: 10,548; ansic: 536; sh: 23; makefile: 8
file content (97 lines) | stat: -rw-r--r-- 2,600 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# frozen_string_literal: true
require 'hamlit/compiler/children_compiler'
require 'hamlit/compiler/comment_compiler'
require 'hamlit/compiler/doctype_compiler'
require 'hamlit/compiler/script_compiler'
require 'hamlit/compiler/silent_script_compiler'
require 'hamlit/compiler/tag_compiler'
require 'hamlit/filters'
require 'hamlit/identity'

module Hamlit
  class Compiler
    def initialize(options = {})
      identity                = Identity.new
      @children_compiler      = ChildrenCompiler.new
      @comment_compiler       = CommentCompiler.new
      @doctype_compiler       = DoctypeCompiler.new(options)
      @filter_compiler        = Filters.new(options)
      @script_compiler        = ScriptCompiler.new(identity)
      @silent_script_compiler = SilentScriptCompiler.new
      @tag_compiler           = TagCompiler.new(identity, options)
    end

    def call(ast)
      return runtime_error(ast) if ast.is_a?(HamlError)
      compile(ast)
    rescue Error => e
      runtime_error(e)
    end

    private

    def compile(node)
      case node.type
      when :root
        compile_children(node)
      when :comment
        compile_comment(node)
      when :doctype
        compile_doctype(node)
      when :filter
        compile_filter(node)
      when :plain
        compile_plain(node)
      when :script
        compile_script(node)
      when :silent_script
        compile_silent_script(node)
      when :tag
        compile_tag(node)
      when :haml_comment
        [:multi]
      else
        raise InternalError.new("Unexpected node type: #{node.type}")
      end
    end

    def compile_children(node)
      @children_compiler.compile(node) { |n| compile(n) }
    end

    def compile_comment(node)
      @comment_compiler.compile(node) { |n| compile_children(n) }
    end

    def compile_doctype(node)
      @doctype_compiler.compile(node)
    end

    def compile_filter(node)
      @filter_compiler.compile(node)
    end

    def compile_plain(node)
      [:static, node.value[:text]]
    end

    def compile_script(node)
      @script_compiler.compile(node) { |n| compile_children(n) }
    end

    def compile_silent_script(node)
      @silent_script_compiler.compile(node) { |n| compile_children(n) }
    end

    def compile_tag(node)
      @tag_compiler.compile(node) { |n| compile_children(n) }
    end

    def runtime_error(error)
      [:multi].tap do |temple|
        error.line.times { temple << [:newline] } if error.line
        temple << [:code, %Q[raise #{error.class}.new(%q[#{error.message}], #{error.line.inspect})]]
      end
    end
  end
end