class Emfrp::Top

Constants

ATTRS

Public Class Methods

new(*tops) click to toggle source
# File lib/emfrp/syntax.rb, line 116
def initialize(*tops)
  ATTRS.each do |a|
    self[a] = []
    tops.each do |h|
      self[a] += h[a] if h[a]
    end
  end
  self[:module_name] = tops.map{|x| x[:module_name]}.find{|x| x}
end

Public Instance Methods

add(d) click to toggle source
# File lib/emfrp/syntax.rb, line 126
def add(d)
  case d
  when DataDef then self[:datas] << d
  when FuncDef then self[:funcs] << d
  when TypeDef then self[:types] << d
  else raise "assertion error: unsupported Def-type"
  end
end
codegen(ct, ar) click to toggle source
# File lib/emfrp/compile/c/syntax_codegen.rb, line 6
def codegen(ct, ar)
  self[:dict][:itype_space].each do |k, v|
    v.get.struct_gen(ct)
    v.get.constructor_gen(ct)
    v.get.marker_gen(ct)
  end
  self[:inputs].each do |i|
    if i[:init_exp]
      i.init_func_gen(ct)
      ct.define_init_stmt "#{i.node_var_name(ct)}[last_side] = #{i.init_func_name(ct)}();"
    end
    i.node_var_gen(ct)
  end
  self[:dict][:sorted_nodes].each_with_index do |n, i|
    node = n.get
    node.func_gen(ct)
    node.node_var_gen(ct)
    if node[:init_exp]
      node.init_func_gen(ct)
      ct.define_init_stmt "#{node.node_var_name(ct)}[last_side] = #{node.init_func_name(ct)}();"
      t = ct.tdef(node)
      if t.is_a?(TypeDef) && !t.enum?(ct)
        ct.define_init_stmt "#{t.marker_func_name(ct)}(#{node.node_var_name(ct)}[last_side], #{ar.ref_pos_last(node) + 1});"
      end
    end
  end
  self[:dict][:ifunc_space].each do |k, v|
    v.get.codegen(ct)
  end
  self[:dict][:used_pfuncs].each do |v|
    v.get.codegen(ct)
  end
  self[:dict][:sorted_datas].reverse.each do |v|
    v.get.codegen(ct)
  end
  memory_gen(ct, ar)
  main_gen(ct, ar)
  io_proto_gen(ct)
end
io_proto_gen(ct) click to toggle source
# File lib/emfrp/compile/c/syntax_codegen.rb, line 110
def io_proto_gen(ct)
  ct.define_proto("void", "Input", self[:inputs].map{|x| ct.tref(x) + "*"}, :extern)
  ct.define_proto("void", "Output", self[:outputs].map{|x| ct.tref(x) + "*"}, :extern)
end
main_gen(ct, ar) click to toggle source
# File lib/emfrp/compile/c/syntax_codegen.rb, line 71
def main_gen(ct, ar)
  ct.define_func("void", "Activate" + self[:module_name][:desc], [], :none) do |x|
    x << "int current_side = 0, last_side = 1;"
    ct.define_init_stmt "Counter = NodeSize + 1;"
    ct.define_init_stmt "refreshMark();"
    ct.init_stmts.each do |i|
      x << i
    end
    stmts = []
    stmts << "Counter = 1;"
    inputs = self[:inputs].map{|x| "&#{x.node_var_name(ct)}[current_side]"}.join(", ")
    stmts << "Input(#{inputs});"
    self[:dict][:sorted_nodes].each do |n|
      node = n.get
      args = node[:params].map do |x|
        pn = self[:dict][:node_space][x[:name][:desc]].get
        "#{pn.node_var_name(ct)}[#{x[:last] ? "last_side" : "current_side"}]"
      end
      output_arg = "&#{node.node_var_name(ct)}[current_side]"
      stmts << "#{node.node_func_name(ct)}(#{[*args, output_arg].join(", ")});"
      t = ct.tdef(node)
      if t.is_a?(TypeDef) && !t.enum?(ct)
        mark_val = "Counter + #{ar.life_point(node)}"
        stmts << "#{t.marker_func_name(ct)}(#{node.node_var_name(ct)}[current_side], #{mark_val});"
      end
      stmts << "Counter++;"
    end
    outputs = self[:outputs].map do |x|
      node = self[:dict][:node_space][x[:name][:desc]].get
      "&#{node.node_var_name(ct)}[current_side]"
    end
    stmts << "Output(#{outputs.join(", ")});"
    stmts << "refreshMark();"
    stmts << "current_side ^= 1;"
    stmts << "last_side ^= 1;"
    x << ct.make_block("while (1) {", stmts, "}")
  end
end
memory_gen(ct, ar) click to toggle source
# File lib/emfrp/compile/c/syntax_codegen.rb, line 46
def memory_gen(ct, ar)
  max_memory = ar.requirement()
  max_memory.each do |t, i|
    t = t.get
    next if t[:static] || t.enum?(ct)
    ct.define_global_var("struct #{t.struct_name(ct)}", "#{t.memory_name(ct)}[#{i}]")
    ct.define_global_var("int", "#{t.memory_size_name(ct)}", "#{i}")
    ct.define_global_var("int", "#{t.memory_counter_name(ct)}", "0")
  end
  ct.define_global_var("int", "Counter", "1")
  ct.define_global_var("int", "NodeSize", "#{self[:dict][:sorted_nodes].size}")
  ct.define_func("void", "refreshMark", []) do |x|
    x << "int i;"
    max_memory.each do |t, i|
      t = t.get
      next if t[:static] || t.enum?(ct)
      mn = "#{t.memory_name(ct)}[i].mark"
      stmts = []
      stmts << "if (#{mn} < Counter) #{mn} = 0;"
      stmts << "else #{mn} -= Counter - 1;"
      x << ct.make_block("for (i = 0; i < #{t.memory_size_name(ct)}; i++) {", stmts, "}")
    end
  end
end