Class: MRuby::Presym

Inherits:
#Object show all
Includes:
Rake::DSL
Defined in:
ext/enterprise_script_service/mruby/lib/mruby/presym.rb

Constant Summary collapse

OPERATORS =
{
  "!" => "not",
  "%" => "mod",
  "&" => "and",
  "*" => "mul",
  "+" => "add",
  "-" => "sub",
  "/" => "div",
  "<" => "lt",
  ">" => "gt",
  "^" => "xor",
  "`" => "tick",
  "|" => "or",
  "~" => "neg",
  "!=" => "neq",
  "!~" => "nmatch",
  "&&" => "andand",
  "**" => "pow",
  "+@" => "plus",
  "-@" => "minus",
  "<<" => "lshift",
  "<=" => "le",
  "==" => "eq",
  "=~" => "match",
  ">=" => "ge",
  ">>" => "rshift",
  "[]" => "aref",
  "||" => "oror",
  "<=>" => "cmp",
  "===" => "eqq",
  "[]=" => "aset",
}.freeze
SYMBOL_TO_MACRO =
{
#      Symbol      =>      Macro
# [prefix, suffix] => [prefix, suffix]
  ["@@"  , ""    ] => ["CV"  , ""    ],
  ["@"   , ""    ] => ["IV"  , ""    ],
  [""    , "!"   ] => [""    , "_B"  ],
  [""    , "?"   ] => [""    , "_Q"  ],
  [""    , "="   ] => [""    , "_E"  ],
  [""    , ""    ] => [""    , ""    ],
}.freeze
C_STR_LITERAL_RE =
/"(?:[^\\\"]|\\.)*"/

Instance Method Summary collapse

Constructor Details

#initialize(build) ⇒ Presym

Returns a new instance of Presym.



51
52
53
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 51

def initialize(build)
  @build = build
end

Instance Method Details

#header_dirObject



107
108
109
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 107

def header_dir;
  @header_dir ||= "#{@build.build_dir}/include/mruby/presym".freeze
end

#id_header_pathObject



111
112
113
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 111

def id_header_path
  @id_header_path ||= "#{header_dir}/id.h".freeze
end

#list_pathObject



103
104
105
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 103

def list_path
  @list_pat ||= "#{@build.build_dir}/presym".freeze
end

#read_listObject



61
62
63
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 61

def read_list
  File.readlines(list_path, mode: "r:binary").each(&:chomp!)
end

#scan(paths) ⇒ Object



55
56
57
58
59
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 55

def scan(paths)
  presym_hash = {}
  paths.each {|path| read_preprocessed(presym_hash, path)}
  presym_hash.keys.sort_by!{|sym| [c_literal_size(sym), sym]}
end

#table_header_pathObject



115
116
117
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 115

def table_header_path
  @table_header_path ||= "#{header_dir}/table.h".freeze
end

#write_id_header(presyms) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 70

def write_id_header(presyms)
  prefix_re = Regexp.union(*SYMBOL_TO_MACRO.keys.map(&:first).uniq)
  suffix_re = Regexp.union(*SYMBOL_TO_MACRO.keys.map(&:last).uniq)
  sym_re = /\A(#{prefix_re})?([\w&&\D]\w*)(#{suffix_re})?\z/o
  _pp "GEN", id_header_path.relative_path
  File.open(id_header_path, "w:binary") do |f|
    f.puts "enum mruby_presym {"
    presyms.each.with_index(1) do |sym, num|
      if sym_re =~ sym && (affixes = SYMBOL_TO_MACRO[[$1, $3]])
        f.puts "  MRB_#{affixes * 'SYM'}__#{$2} = #{num},"
      elsif name = OPERATORS[sym]
        f.puts "  MRB_OPSYM__#{name} = #{num},"
      end
    end
    f.puts "};"
    f.puts
    f.puts "#define MRB_PRESYM_MAX #{presyms.size}"
  end
end

#write_list(presyms) ⇒ Object



65
66
67
68
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 65

def write_list(presyms)
  _pp "GEN", list_path.relative_path
  File.binwrite(list_path, presyms.join("\n") << "\n")
end

#write_table_header(presyms) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
# File 'ext/enterprise_script_service/mruby/lib/mruby/presym.rb', line 90

def write_table_header(presyms)
  _pp "GEN", table_header_path.relative_path
  File.open(table_header_path, "w:binary") do |f|
    f.puts "static const uint16_t presym_length_table[] = {"
    presyms.each{|sym| f.puts "  #{sym.bytesize},\t/* #{sym} */"}
    f.puts "};"
    f.puts
    f.puts "static const char * const presym_name_table[] = {"
    presyms.each{|sym| f.puts %|  "#{sym}",|}
    f.puts "};"
  end
end