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
81
82
# 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[:binder].get.var_name(ct, 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, "}")
    elsif i == self[:cases].length - 1
      stmts << ct.make_block("else {", 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



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
111
112
# File 'lib/emfrp/compile/c/syntax_exp_codegen.rb', line 84

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_id == " + 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