Class: Emfrp::MatchExp

Inherits:
Object
  • Object
show all
Defined in:
lib/emfrp/compile/c/syntax_exp_codegen.rb

Instance Method Summary collapse

Instance Method Details

#codegen(ct, stmts) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/emfrp/compile/c/syntax_exp_codegen.rb', line 53

def codegen(ct, stmts)
  vname = "_tmp%03d" % ct.uniq_id_gen
  stmts << "#{ct.tref(self)} #{vname};"
  left = self[:exp]
  if left.is_a?(VarRef)
    left_vname = left[:name][:desc]
  else
    left_vname = "_tmp%03d" % ct.uniq_id_gen
    stmts.unshift "#{ct.tref(left)} #{left_vname};"
    stmts.push "#{left_vname} = #{left.codegen(ct, stmts)};"
  end
  self[:cases].each_with_index do |c, i|
    then_stmts = []
    cond_exps = pattern_to_cond_exps(ct, left_vname, then_stmts, c, c[:pattern])
    cond_exp = cond_exps.size == 0 ? "1" : cond_exps.join(" && ")
    if c[:exp].is_a?(SkipExp)
      then_stmts << "return 0;"
    else
      then_stmts << "#{vname} = #{c[:exp].codegen(ct, then_stmts)};"
    end
    if i == 0
      stmts << ct.make_block("if (#{cond_exp}) {", then_stmts, "}")
    else
      stmts << ct.make_block("else if (#{cond_exp}) {", then_stmts, "}")
    end
  end
  return vname
end

#pattern_to_cond_exps(ct, receiver, stmts, case_def, pattern) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/emfrp/compile/c/syntax_exp_codegen.rb', line 82

def pattern_to_cond_exps(ct, receiver, stmts, case_def, pattern)
  if pattern[:ref]
    vname = case_def.var_name(ct, pattern[:ref][:desc])
    stmts << "#{ct.tref(pattern)} #{vname} = #{receiver};"
  end
  case pattern
  when ValuePattern
    conds = []
    type_def = ct.tdef(pattern)
    accessor = type_def[:static] ? "." : "->"
    if type_def[:tvalues].size > 1
      tvalue_id = type_def[:tvalues].index{|x| x[:name] == pattern[:name]}
      if type_def.enum?(ct)
        conds << "#{receiver} == #{tvalue_id}"
      else
        conds << "#{receiver}" + accessor + "tvalue_type == " + tvalue_id.to_s
      end
    end
    new_receiver = "#{receiver}" + accessor + "value." + pattern[:name][:desc]
    pattern[:args].each_with_index do |x, i|
      conds += pattern_to_cond_exps(ct, new_receiver + ".member#{i}", stmts, case_def, x)
    end
    return conds
  when IntegralPattern
    return ["#{receiver} == #{pattern[:val][:entity][:desc]}"]
  else
    return []
  end
end