38 # [prefix, suffix] => [prefix, suffix]
39 ["@@" , "" ] => ["CV" , "" ],
40 ["@" , "" ] => ["IV" , "" ],
41 ["" , "!" ] => ["" , "_B" ],
42 ["" , "?" ] => ["" , "_Q" ],
43 ["" , "=" ] => ["" , "_E" ],
44 ["" , "" ] => ["" , "" ],
47 C_STR_LITERAL_RE = /"(?:[^\\\"]|\\.)*"/
55 paths.each {|path| read_preprocessed(presym_hash, path)}
56 presym_hash.keys.sort_by!{|sym| [c_literal_size(sym), sym]}
60 File.readlines(list_path, mode: "r:binary").each(&:chomp!)
63 def write_list(presyms)
64 _pp "GEN", list_path.relative_path
65 File.binwrite(list_path, presyms.join("\n") << "\n")
68 def write_id_header(presyms)
69 prefix_re = Regexp.union(*SYMBOL_TO_MACRO.keys.map(&:first).uniq)
70 suffix_re = Regexp.union(*SYMBOL_TO_MACRO.keys.map(&:last).uniq)
71 sym_re = /\A(#{prefix_re})?([\w&&\D]\w*)(#{suffix_re})?\z/o
72 _pp "GEN", id_header_path.relative_path
73 File.open(id_header_path, "w:binary") do |f|
74 f.puts "enum mruby_presym {"
75 presyms.each.with_index(1) do |sym, num|
76 if sym_re =~ sym && (affixes = SYMBOL_TO_MACRO[[$1, $3]])
77 f.puts " MRB_#{affixes * 'SYM'}__#{$2} = #{num},"
78 elsif name = OPERATORS[sym]
79 f.puts " MRB_OPSYM__#{name} = #{num},"
84 f.puts "#define MRB_PRESYM_MAX #{presyms.size}"
88 def write_table_header(presyms)
89 _pp "GEN", table_header_path.relative_path
90 File.open(table_header_path, "w:binary") do |f|
91 f.puts "static const uint16_t presym_length_table[] = {"
92 presyms.each{|sym| f.puts " #{sym.bytesize},\t/* #{sym} */"}
95 f.puts "static const char * const presym_name_table[] = {"
96 presyms.each{|sym| f.puts %| "#{sym}",|}
102 @list_path ||= "#{@build.build_dir}/presym".freeze
106 @header_dir ||= "#{@build.build_dir}/include/mruby/presym".freeze
110 @id_header_path ||= "#{header_dir}/id.h".freeze
113 def table_header_path
114 @table_header_path ||= "#{header_dir}/table.h".freeze
119 def read_preprocessed(presym_hash, path)
120 File.binread(path).scan(/<@! (.*?) !@>/) do |part,|
121 literals = part.scan(C_STR_LITERAL_RE)
122 presym_hash[literals.map{|l| l[1..-2]}.join] = true unless literals.empty?
126 def c_literal_size(literal_without_quote)
127 literal_without_quote.size # TODO: consider escape sequence