Exception: Emfrp::CompileError

Inherits:
RuntimeError
  • Object
show all
Defined in:
lib/emfrp/compile_error.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message, code, *factors) ⇒ CompileError

Returns a new instance of CompileError.



7
8
9
10
11
# File 'lib/emfrp/compile_error.rb', line 7

def initialize(message, code, *factors)
  @message = message
  @code = message
  @factors = factors
end

Instance Attribute Details

#factorsObject (readonly)

Returns the value of attribute factors.



5
6
7
# File 'lib/emfrp/compile_error.rb', line 5

def factors
  @factors
end

#messageObject (readonly)

Returns the value of attribute message.



5
6
7
# File 'lib/emfrp/compile_error.rb', line 5

def message
  @message
end

Instance Method Details

#codeObject



13
14
15
# File 'lib/emfrp/compile_error.rb', line 13

def code
  @code
end

#collect_factor_tags(factor) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/emfrp/compile_error.rb', line 21

def collect_factor_tags(factor)
  case factor
  when Syntax
    if factor.has_key?(:start_pos)
      collect_factor_tags(factor.values) + [[factor[:start_pos], factor[:end_pos]]]
    else
      collect_factor_tags(factor.values)
    end
  when Array
    factor.flat_map{|x| collect_factor_tags(x)}
  else
    []
  end
end

#factor_name(factor) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/emfrp/compile_error.rb', line 54

def factor_name(factor)
  klass = factor.class.name.split("::").last
  if factor.is_a?(Syntax)
    name = factor.has_key?(:name) ? "`#{factor[:name][:desc]}`" : ""
  else
    name = factor.inspect
  end
  klass + " " + name
end

#find_factor_file_name(factor) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/emfrp/compile_error.rb', line 36

def find_factor_file_name(factor)
  case factor
  when Syntax
    if factor.has_key?(:start_pos)
      return factor[:start_pos][:document_name]
    else
      return find_factor_file_name(factor.values)
    end
  when Array
    factor.each do |x|
      if res = find_factor_file_name(x)
        return res
      end
    end
  end
  nil
end


88
89
90
91
92
93
# File 'lib/emfrp/compile_error.rb', line 88

def print_error(output_io, file_loader)
  output_io << "\e[31m[Error]\e[m: #{@message}"
  @factors.each do |factor|
    print_lexical_factor(factor, output_io, file_loader)
  end
end


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/emfrp/compile_error.rb', line 64

def print_lexical_factor(factor, output_io, file_loader)
  src_lines = nil
  unless factor_file_name = find_factor_file_name(factor)
    raise "assertion error: cannot detect file_name"
  end
  src_str = file_loader.get_src_from_full_path(factor_file_name)
  src_lines = src_str.each_line.to_a
  tags = collect_factor_tags(factor)
  spos = tags.map{|x| x[0]}.min{|a, b| tag_comp(a, b)}
  epos = tags.map{|x| x[1]}.max{|a, b| tag_comp(a, b)}
  line_nums = (spos[:line_number]..epos[:line_number]).to_a
  if line_nums.size == 1
    output_io << "#{factor_file_name}:#{line_nums[0]}:\n"
    output_io << "> " + src_lines[line_nums[0] - 1].chomp + "\n"
    output_io << "  " + " " * (spos[:column_number] - 1)
    output_io << ("^" * (epos[:column_number] - spos[:column_number] + 1)).colorize(:green) + "\n"
  else
    output_io << "#{factor_file_name}:#{line_nums.first}-#{line_nums.last}:\n"
    line_nums.each do |line_num|
      output_io << "> " + src_lines[line_num - 1]
    end
  end
end

#tag_comp(a, b) ⇒ Object



17
18
19
# File 'lib/emfrp/compile_error.rb', line 17

def tag_comp(a, b)
  [a[:line_number], a[:column_number]] <=> [b[:line_number], b[:column_number]]
end