class Emfrp::CodegenContext

Constants

SymbolToStr

Public Class Methods

new(top) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 28
def initialize(top)
  @top = top
  @global_vars = []
  @funcs = []
  @structs = []
  @protos = []
  @static_protos = []
  @macros = []
  @init_stmts = []
  @templates = []
end

Public Instance Methods

code_generate(c_output, h_output, main_output, name) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 40
def code_generate(c_output, h_output, main_output, name)
  #  generate header-file
  h_output << "#ifndef #{name.upcase}_H\n"
  h_output << "#define #{name.upcase}_H\n\n"
  @protos.each do |x|
    h_output.puts x.to_s
  end
  h_output << "\n#endif /* end of include guard */\n"
  # generate library-file
  c_output.puts "#include \"#{name}.h\""
  c_output.puts "/* Primitive functions (Macros) */"
  @macros.each do |x|
    c_output.puts x.to_s
  end
  c_output.puts "/* Data types */"
  @structs.each do |x|
    c_output.puts x.to_s
  end
  c_output.puts "/* Global variables */"
  @global_vars.each do |x|
    c_output.puts x.to_s
  end
  c_output.puts "/* Static prototypes */"
  @static_protos.each do |x|
    c_output.puts x.to_s
  end
  c_output.puts "/* Functions, Constructors, GCMarkers, etc... */"
  @funcs.each do |x|
    c_output.puts x.to_s
  end
  # generate main-file
  main_output << "#include \"#{name}.h\"\n\n"
  main_output << "void Input(#{@top[:inputs].map{|x| "#{tref(x)}* #{x[:name][:desc]}"}.join(", ")}) {\n  /* Your code goes here... */\n}\n"
  main_output << "void Output(#{@top[:outputs].map{|x| "#{tref(x)}* #{x[:name][:desc]}"}.join(", ")}) {\n  /* Your code goes here... */\n}\n"
  main_output << "int main() {\n  Activate#{@top[:module_name][:desc]}();\n}\n"
end
constructor_name(name, utype) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 93
def constructor_name(name, utype)
  @top[:dict][:itype_space][utype.to_uniq_str].get[:tvalues].each do |tval|
    if tval[:name][:desc] == name
      return tval.constructor_name(self)
    end
  end
  raise "Assertion error: #{name} is not found"
end
define_func(type_str, name_str, params, accessor=:static, with_proto=true, &block) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 148
def define_func(type_str, name_str, params, accessor=:static, with_proto=true, &block)
  elements = []
  block.call(elements)
  case accessor
  when :none then deco = ""
  when :static then deco = "static "
  end
  define_proto(type_str, name_str, params.map(&:first), accessor) if with_proto
  @funcs << Block.new("#{deco}#{type_str} #{name_str}(#{params.map{|a, b| "#{a} #{b}"}.join(", ")}) {", elements, "}")
  return nil
end
define_global_var(type_str, name_str, initial_value_str=nil) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 140
def define_global_var(type_str, name_str, initial_value_str=nil)
  @global_vars << "#{type_str} #{name_str}" + (initial_value_str ? " = #{initial_value_str}" : "") + ";"
end
define_init_stmt(stmt) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 175
def define_init_stmt(stmt)
  @init_stmts << stmt
end
define_macro(name_str, params, body_str) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 144
def define_macro(name_str, params, body_str)
  @macros << "#define #{name_str}(#{params.join(", ")}) (#{body_str})"
end
define_proto(type_str, name_str, param_types, accessor=:static) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 160
def define_proto(type_str, name_str, param_types, accessor=:static)
  case accessor
  when :none then deco = ""
  when :static then deco = "static "
  when :extern then deco = "extern "
  end
  proto = "#{deco}#{type_str} #{name_str}(#{param_types.join(", ")});"
  if accessor == :static || accessor == :extern
    @static_protos << proto
  else
    @protos << proto
  end
  return nil
end
define_struct(kind_str, name_str, var_name_str, &block) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 179
def define_struct(kind_str, name_str, var_name_str, &block)
  elements = []
  block.call(elements)
  x = Block.new("#{kind_str} #{name_str}{", elements, "}#{var_name_str};")
  if name_str
    @structs << x
    return nil
  else
    return x
  end
end
escape_name(name) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 102
def escape_name(name)
  rexp = Regexp.new("[" + Regexp.escape(SymbolToStr.keys.join) + "]")
  name.gsub(rexp, SymbolToStr)
end
func_name(name, ret_utype, arg_utypes) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 81
def func_name(name, ret_utype, arg_utypes)
  case f = @top[:dict][:func_space][name].get
  when PrimFuncDef
    f.func_name(self)
  when FuncDef
    key = [ret_utype, *arg_utypes].map(&:to_uniq_str) + [name]
    @top[:dict][:ifunc_space][key].get.func_name(self)
  else
    raise "Assertion error: unexpected func type #{f.class}"
  end
end
init_stmts() click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 77
def init_stmts
  @init_stmts
end
make_block(head_str, elements, foot_str) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 191
def make_block(head_str, elements, foot_str)
  Block.new(head_str, elements, foot_str)
end
serial(key, id) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 129
def serial(key, id)
  @serials ||= Hash.new{|h, k| h[k] = []}
  @serials[key] << id unless @serials[key].find{|x| x == id}
  return @serials[key].index{|x| x == id}
end
tdef(x) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 107
def tdef(x)
  case x
  when Typing::UnionType
    key = x.to_uniq_str
    if @top[:dict][:type_space][key] && @top[:dict][:type_space][key].get.is_a?(PrimTypeDef)
      @top[:dict][:type_space][key].get
    elsif @top[:dict][:itype_space][key]
      @top[:dict][:itype_space][key].get
    else
      raise "Assertion error: itype #{x.to_uniq_str} is undefined"
    end
  when Syntax
    tdef(x[:typing])
  else
    raise "Assertion error"
  end
end
tref(x) click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 125
def tref(x)
  tdef(x).ref_name(self)
end
uniq_id_gen() click to toggle source
# File lib/emfrp/compile/c/codegen_context.rb, line 135
def uniq_id_gen
  @uniq_ids ||= (0..1000).to_a
  @uniq_ids.shift
end